2005-01-31 Zoltan Varga <vargaz@freemail.hu>
[mono.git] / mcs / class / corlib / System.Reflection.Emit / ILGenerator.cs
index 0c469c295e0b734f74d5e1eb9fc9eb521dd75bcd..b99186888fde6e57f31ef2f1b953d679ecf54171 100644 (file)
@@ -1,4 +1,27 @@
 
+//
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
 //
 // System.Reflection.Emit/ILGenerator.cs
 //
@@ -12,7 +35,6 @@ using System;
 using System.Collections;
 using System.Diagnostics.SymbolStore;
 using System.Runtime.InteropServices;
-using Mono.CSharp.Debugger;
 
 namespace System.Reflection.Emit {
 
@@ -71,6 +93,17 @@ namespace System.Reflection.Emit {
                        handlers [i].extype = null;
                }
 
+               internal void AddFault (int offset)
+               {
+                       int i;
+                       End (offset);
+                       add_block (offset);
+                       i = handlers.Length - 1;
+                       handlers [i].type = ILExceptionBlock.FAULT;
+                       handlers [i].start = offset;
+                       handlers [i].extype = null;
+               }
+
                internal void End (int offset)
                {
                        if (handlers == null)
@@ -122,6 +155,8 @@ namespace System.Reflection.Emit {
 
                int GetToken (MemberInfo member);
 
+               int GetToken (MethodInfo method, Type[] opt_param_types);
+
                int GetToken (SignatureHelper helper);
        }               
 
@@ -144,7 +179,7 @@ namespace System.Reflection.Emit {
                        public int maxStack; 
                }
                
-               static Type void_type = typeof (void);
+               static readonly Type void_type = typeof (void);
                #region Sync with reflection.h
                private byte[] code;
                private int code_len;
@@ -161,7 +196,6 @@ namespace System.Reflection.Emit {
                private LabelFixup[] fixups;
                private int num_fixups;
                internal Module module;
-               internal IMonoSymbolWriter sym_writer;
                private Stack scopes;
                private int cur_block;
                private Stack open_blocks;
@@ -181,8 +215,6 @@ namespace System.Reflection.Emit {
                        token_fixups = new ILTokenInfo [8];
                        num_token_fixups = 0;
                        module = m;
-                       if (module is ModuleBuilder)
-                               sym_writer = ((ModuleBuilder)module).symbol_writer;
                        open_blocks = new Stack ();
                        this.token_gen = token_gen;
                }
@@ -345,7 +377,7 @@ namespace System.Reflection.Emit {
                        if (open_blocks.Count <= 0)
                                throw new NotSupportedException ("Not in an exception block");
                        //System.Console.WriteLine ("Begin fault Block");
-                       //throw new NotImplementedException ();
+                       ex_handlers [cur_block].AddFault (code_len);
                }
                
                public virtual void BeginFinallyBlock()
@@ -358,17 +390,24 @@ namespace System.Reflection.Emit {
                }
                
                public virtual void BeginScope ()
-               {
-                       if (sym_writer != null) {
-                               if (scopes == null)
-                                       scopes = new Stack ();
-                               scopes.Push (sym_writer.OpenScope (code_len));
-                       }
-               }
+               { }
                
                public LocalBuilder DeclareLocal (Type localType)
+               {
+                       return DeclareLocal (localType, false);
+               }
+
+
+#if NET_2_0
+               public
+#else
+               internal
+#endif
+               LocalBuilder DeclareLocal (Type localType, bool pinned)
                {
                        LocalBuilder res = new LocalBuilder (localType, this);
+                       res.is_pinned = pinned;
+                       
                        if (locals != null) {
                                LocalBuilder[] new_l = new LocalBuilder [locals.Length + 1];
                                System.Array.Copy (locals, new_l, locals.Length);
@@ -378,7 +417,7 @@ namespace System.Reflection.Emit {
                                locals = new LocalBuilder [1];
                                locals [0] = res;
                        }
-                       res.position = (uint)(locals.Length - 1);
+                       res.position = (ushort)(locals.Length - 1);
                        return res;
                }
                
@@ -627,6 +666,20 @@ namespace System.Reflection.Emit {
                                cur_stack -= method.GetParameterCount ();
                }
 
+               private void Emit (OpCode opcode, MethodInfo method, int token)
+               {
+                       make_room (6);
+                       ll_emit (opcode);
+                       if (method.DeclaringType.Module == module)
+                               add_token_fixup (method);
+                       emit_int (token);
+                       if (method.ReturnType != void_type)
+                               cur_stack ++;
+
+                       if (opcode.StackBehaviourPop == StackBehaviour.Varpop)
+                               cur_stack -= method.GetParameterCount ();
+               }
+
                [CLSCompliant(false)]
                public void Emit (OpCode opcode, sbyte val)
                {
@@ -686,6 +739,10 @@ namespace System.Reflection.Emit {
                                if ((methodinfo.CallingConvention & CallingConventions.VarArgs)  == 0){
                                        throw new InvalidOperationException ("Method is not VarArgs method and optional types were passed");
                                }
+
+                               int token = token_gen.GetToken (methodinfo, optionalParamTypes);
+                               Emit (opcode, methodinfo, token);
+                               return;
                        }
                        Emit (opcode, methodinfo);
                }
@@ -765,14 +822,7 @@ namespace System.Reflection.Emit {
                }
 
                public virtual void EndScope ()
-               {
-                       if (sym_writer != null) {
-                               sym_writer.CloseScope (code_len);
-                               if (scopes == null)
-                                       throw new InvalidOperationException ();
-                               scopes.Pop ();
-                       }
-               }
+               { }
 
                public virtual void MarkLabel (Label loc)
                {
@@ -787,12 +837,7 @@ namespace System.Reflection.Emit {
 
                public virtual void MarkSequencePoint (ISymbolDocumentWriter document, int startLine,
                                                       int startColumn, int endLine, int endColumn)
-               {
-                       if (sym_writer == null)
-                               return;
-
-                       sym_writer.MarkSequencePoint (code_len, startLine, startColumn);
-               }
+               { }
 
                public virtual void ThrowException (Type exceptionType)
                {
@@ -830,5 +875,10 @@ namespace System.Reflection.Emit {
                                }
                        }
                }
+
+               internal static int Mono_GetCurrentOffset (ILGenerator ig)
+               {
+                       return ig.code_len;
+               }
        }
 }