We need you! We're working hard on the next version of Developer Fusion - Let us know what you think we should be up to!

The Labs \ Source Viewer \ SSCLI \ System.Reflection.Emit \ GenericMethodInfo

  1. // ==++==
  2. //
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. //
  14. // ==--==
  15. namespace System.Reflection.Emit
  16. {
  17.    
  18.     using System;
  19.     using System.Globalization;
  20.     using TextWriter = System.IO.TextWriter;
  21.     using System.Diagnostics.SymbolStore;
  22.     using System.Runtime.InteropServices;
  23.     using System.Reflection;
  24.     using System.Collections;
  25.     using System.Security.Permissions;
  26.    
  27.     internal class DynamicILGenerator : ILGenerator
  28.     {
  29.        
  30.         internal DynamicScope m_scope;
  31.         private int m_methodSigToken;
  32.        
  33.         unsafe internal DynamicILGenerator(DynamicMethod method, byte[] methodSignature, int size) : base(method, size)
  34.         {
  35.             m_scope = new DynamicScope();
  36.             m_methodSigToken = m_scope.GetTokenFor(methodSignature);
  37.         }
  38.        
  39.        
  40.         unsafe internal RuntimeMethodHandle GetCallableMethod(void* module)
  41.         {
  42.             return new RuntimeMethodHandle(ModuleHandle.GetDynamicMethod(module, m_methodBuilder.Name, (byte[])m_scope[m_methodSigToken], new DynamicResolver(this)));
  43.         }
  44.        
  45.         // *** ILGenerator api ***
  46.        
  47.         public override LocalBuilder DeclareLocal(Type localType, bool pinned)
  48.         {
  49.             LocalBuilder localBuilder;
  50.             if (localType == null)
  51.                 throw new ArgumentNullException("localType");
  52.             if (localType.GetType() != typeof(RuntimeType))
  53.                 throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"));
  54.             localBuilder = new LocalBuilder(m_localCount, localType, m_methodBuilder);
  55.             // add the localType to local signature
  56.             m_localSignature.AddArgument(localType, pinned);
  57.             m_localCount++;
  58.             return localBuilder;
  59.         }
  60.        
  61.         //
  62.         //
  63.         // Token resolution calls
  64.         //
  65.         //
  66.         public override void Emit(OpCode opcode, MethodInfo meth)
  67.         {
  68.             if (meth == null)
  69.                 throw new ArgumentNullException("meth");
  70.            
  71.             int stackchange = 0;
  72.             int tempVal = 0;
  73.             DynamicMethod dynMeth = DynamicMethod.AsDynamicMethod(meth);
  74.             if (dynMeth == null) {
  75.                 if (!(meth is RuntimeMethodInfo))
  76.                     throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeMethodInfo"), "meth");
  77.                
  78.                 if (meth.DeclaringType != null && (meth.DeclaringType.IsGenericType || meth.DeclaringType.IsArray))
  79.                     tempVal = m_scope.GetTokenFor(meth.MethodHandle, meth.DeclaringType.TypeHandle);
  80.                 else
  81.                     tempVal = m_scope.GetTokenFor(meth.MethodHandle);
  82.             }
  83.             else {
  84.                 // rule out not allowed operations on DynamicMethods
  85.                 if (opcode.Equals(OpCodes.Ldtoken) || opcode.Equals(OpCodes.Ldftn) || opcode.Equals(OpCodes.Ldvirtftn)) {
  86.                     throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOpCodeOnDynamicMethod"));
  87.                 }
  88.                 tempVal = m_scope.GetTokenFor(dynMeth);
  89.             }
  90.            
  91.             EnsureCapacity(7);
  92.             InternalEmit(opcode);
  93.            
  94.             if (opcode.m_push == StackBehaviour.Varpush && meth.ReturnType != typeof(void)) {
  95.                 stackchange++;
  96.             }
  97.             if (opcode.m_pop == StackBehaviour.Varpop) {
  98.                 stackchange -= meth.GetParametersNoCopy().Length;
  99.             }
  100.             // Pop the "this" parameter if the method is non-static,
  101.             // and the instruction is not newobj/ldtoken/ldftn.
  102.             if (!meth.IsStatic && !(opcode.Equals(OpCodes.Newobj) || opcode.Equals(OpCodes.Ldtoken) || opcode.Equals(OpCodes.Ldftn))) {
  103.                 stackchange--;
  104.             }
  105.            
  106.             UpdateStackSize(opcode, stackchange);
  107.            
  108.             m_length = PutInteger4(tempVal, m_length, m_ILStream);
  109.         }
  110.        
  111.         [System.Runtime.InteropServices.ComVisible(true)]
  112.         public override void Emit(OpCode opcode, ConstructorInfo con)
  113.         {
  114.             if (con == null || !(con is RuntimeConstructorInfo))
  115.                 throw new ArgumentNullException("con");
  116.             if (con.DeclaringType != null && con.DeclaringType.IsGenericType)
  117.                 Emit(opcode, con.MethodHandle, con.DeclaringType.TypeHandle);
  118.             else
  119.                 Emit(opcode, con.MethodHandle);
  120.         }
  121.        
  122.         public void Emit(OpCode opcode, RuntimeMethodHandle meth)
  123.         {
  124.             if (meth.IsNullHandle())
  125.                 throw new ArgumentNullException("meth");
  126.            
  127.             // need to sort out the stack size story
  128.             //int stackchange = 0;
  129.             int tempVal = m_scope.GetTokenFor(meth);
  130.             EnsureCapacity(7);
  131.             InternalEmit(opcode);
  132.            
  133.             // need to sort out the stack size story
  134.             /*
  135.             if (opcode.m_push == StackBehaviour.Varpush
  136.                 && meth.ReturnType != typeof(void)) { stackchange++; }
  137.             if (opcode.m_pop  == StackBehaviour.Varpop) {
  138.               stackchange -= meth.GetParametersNoCopy().Length; }
  139.             if (!meth.IsStatic && !(opcode.Equals(OpCodes.Newobj))) {stackchange--; }
  140.            
  141.             UpdateStackSize(opcode, stackchange);
  142.             */           
  143.             // need to sort out the stack size story
  144. UpdateStackSize(opcode, 1);
  145.            
  146.             m_length = PutInteger4(tempVal, m_length, m_ILStream);
  147.         }
  148.        
  149.         public void Emit(OpCode opcode, RuntimeMethodHandle meth, RuntimeTypeHandle typeContext)
  150.         {
  151.             if (meth.IsNullHandle())
  152.                 throw new ArgumentNullException("meth");
  153.             if (typeContext.IsNullHandle())
  154.                 throw new ArgumentNullException("typeContext");
  155.            
  156.             // need to sort out the stack size story
  157.             //int stackchange = 0;
  158.             int tempVal = m_scope.GetTokenFor(meth, typeContext);
  159.             EnsureCapacity(7);
  160.             InternalEmit(opcode);
  161.            
  162.             // need to sort out the stack size story
  163.             /*
  164.             if (opcode.m_push == StackBehaviour.Varpush
  165.                 && meth.ReturnType != typeof(void)) { stackchange++; }
  166.             if (opcode.m_pop  == StackBehaviour.Varpop) {
  167.               stackchange -= meth.GetParametersNoCopy().Length; }
  168.             if (!meth.IsStatic && !(opcode.Equals(OpCodes.Newobj))) {stackchange--; }
  169.            
  170.             UpdateStackSize(opcode, stackchange);
  171.             */           
  172.             // need to sort out the stack size story
  173. UpdateStackSize(opcode, 1);
  174.            
  175.             m_length = PutInteger4(tempVal, m_length, m_ILStream);
  176.         }
  177.        
  178.         public override void Emit(OpCode opcode, Type type)
  179.         {
  180.             if (type == null)
  181.                 throw new ArgumentNullException("type");
  182.             Emit(opcode, type.TypeHandle);
  183.         }
  184.        
  185.         public void Emit(OpCode opcode, RuntimeTypeHandle typeHandle)
  186.         {
  187.             if (typeHandle.IsNullHandle())
  188.                 throw new ArgumentNullException("typeHandle");
  189.            
  190.             int tempVal = m_scope.GetTokenFor(typeHandle);
  191.             EnsureCapacity(7);
  192.             InternalEmit(opcode);
  193.             m_length = PutInteger4(tempVal, m_length, m_ILStream);
  194.         }
  195.        
  196.         public override void Emit(OpCode opcode, FieldInfo field)
  197.         {
  198.             if (field == null)
  199.                 throw new ArgumentNullException("field");
  200.             if (!(field is RuntimeFieldInfo))
  201.                 throw new ArgumentNullException("field");
  202.             Emit(opcode, field.FieldHandle);
  203.         }
  204.        
  205.         public void Emit(OpCode opcode, RuntimeFieldHandle fieldHandle)
  206.         {
  207.             if (fieldHandle.IsNullHandle())
  208.                 throw new ArgumentNullException("fieldHandle");
  209.            
  210.             int tempVal = m_scope.GetTokenFor(fieldHandle);
  211.             EnsureCapacity(7);
  212.             InternalEmit(opcode);
  213.             m_length = PutInteger4(tempVal, m_length, m_ILStream);
  214.         }
  215.        
  216.         public override void Emit(OpCode opcode, string str)
  217.         {
  218.             if (str == null)
  219.                 throw new ArgumentNullException("str");
  220.            
  221.             int tempVal = AddStringLiteral(str);
  222.             tempVal = tempVal | 1879048192;
  223.             EnsureCapacity(7);
  224.             InternalEmit(opcode);
  225.             m_length = PutInteger4(tempVal, m_length, m_ILStream);
  226.         }
  227.        
  228.         //
  229.         //
  230.         // Signature related calls (vararg, calli)
  231.         //
  232.         //
  233.         public override void EmitCalli(OpCode opcode, CallingConventions callingConvention, Type returnType, Type[] parameterTypes, Type[] optionalParameterTypes)
  234.         {
  235.             int stackchange = 0;
  236.             SignatureHelper sig;
  237.             if (optionalParameterTypes != null)
  238.                 if ((callingConvention & CallingConventions.VarArgs) == 0)
  239.                
  240.                     throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotAVarArgCallingConvention"));
  241.            
  242.             sig = GetMemberRefSignature(callingConvention, returnType, parameterTypes, optionalParameterTypes);
  243.            
  244.             EnsureCapacity(7);
  245.             Emit(OpCodes.Calli);
  246.            
  247.             // The opcode passed in must be the calli instruction.
  248.             BCLDebug.Assert(opcode.Equals(OpCodes.Calli), "Unexpected opcode passed to EmitCalli.");
  249.             // If there is a non-void return type, push one.
  250.             if (returnType != typeof(void))
  251.                 stackchange++;
  252.             // Pop off arguments if any.
  253.             if (parameterTypes != null)
  254.                 stackchange -= parameterTypes.Length;
  255.             // Pop off vararg arguments.
  256.             if (optionalParameterTypes != null)
  257.                 stackchange -= optionalParameterTypes.Length;
  258.             // Pop the this parameter if the method has a this parameter.
  259.             if ((callingConvention & CallingConventions.HasThis) == CallingConventions.HasThis)
  260.                 stackchange--;
  261.             // Pop the native function pointer.
  262.             stackchange--;
  263.             UpdateStackSize(opcode, stackchange);
  264.            
  265.             int token = AddSignature(sig.GetSignature(true));
  266.             m_length = PutInteger4(token, m_length, m_ILStream);
  267.         }
  268.        
  269.         public override void EmitCalli(OpCode opcode, CallingConvention unmanagedCallConv, Type returnType, Type[] parameterTypes)
  270.         {
  271.             int stackchange = 0;
  272.             int cParams = 0;
  273.             int i;
  274.             SignatureHelper sig;
  275.            
  276.             // The opcode passed in must be the calli instruction.
  277.             BCLDebug.Assert(opcode.Equals(OpCodes.Calli), "Unexpected opcode passed to EmitCalli.");
  278.             if (parameterTypes != null)
  279.                 cParams = parameterTypes.Length;
  280.            
  281.             sig = SignatureHelper.GetMethodSigHelper(unmanagedCallConv, returnType);
  282.            
  283.             if (parameterTypes != null)
  284.                 for (i = 0; i < cParams; i++)
  285.                     sig.AddArgument(parameterTypes[i]);
  286.            
  287.             // If there is a non-void return type, push one.
  288.             if (returnType != typeof(void))
  289.                 stackchange++;
  290.            
  291.             // Pop off arguments if any.
  292.             if (parameterTypes != null)
  293.                 stackchange -= cParams;
  294.            
  295.             // Pop the native function pointer.
  296.             stackchange--;
  297.             UpdateStackSize(opcode, stackchange);
  298.            
  299.             EnsureCapacity(7);
  300.             Emit(OpCodes.Calli);
  301.             int token = AddSignature(sig.GetSignature(true));
  302.             m_length = PutInteger4(token, m_length, m_ILStream);
  303.         }
  304.        
  305.         public override void EmitCall(OpCode opcode, MethodInfo methodInfo, Type[] optionalParameterTypes)
  306.         {
  307.             int tk;
  308.             int stackchange = 0;
  309.            
  310.             if (methodInfo == null)
  311.                 throw new ArgumentNullException("methodInfo");
  312.            
  313.             if (methodInfo.ContainsGenericParameters)
  314.                 throw new ArgumentException(Environment.GetResourceString("Argument_GenericsInvalid"), "methodInfo");
  315.            
  316.             if (methodInfo.DeclaringType != null && methodInfo.DeclaringType.ContainsGenericParameters)
  317.                 throw new ArgumentException(Environment.GetResourceString("Argument_GenericsInvalid"), "methodInfo");
  318.            
  319.             tk = GetMemberRefToken(methodInfo, optionalParameterTypes);
  320.            
  321.             EnsureCapacity(7);
  322.             InternalEmit(opcode);
  323.            
  324.             // The opcode must be one of call, callvirt, or newobj.
  325.             BCLDebug.Assert(opcode.Equals(OpCodes.Call) || opcode.Equals(OpCodes.Callvirt) || opcode.Equals(OpCodes.Newobj), "Unexpected opcode passed to EmitCall.");
  326.            
  327.             // Push the return value if there is one.
  328.             if (methodInfo.ReturnType != typeof(void))
  329.                 stackchange++;
  330.             // Pop the parameters.
  331.             stackchange -= methodInfo.GetParameterTypes().Length;
  332.             // Pop the this parameter if the method is non-static and the
  333.             // instruction is not newobj.
  334.             if (!(methodInfo is SymbolMethod) && methodInfo.IsStatic == false && !(opcode.Equals(OpCodes.Newobj)))
  335.                 stackchange--;
  336.             // Pop the optional parameters off the stack.
  337.             if (optionalParameterTypes != null)
  338.                 stackchange -= optionalParameterTypes.Length;
  339.             UpdateStackSize(opcode, stackchange);
  340.            
  341.             m_length = PutInteger4(tk, m_length, m_ILStream);
  342.         }
  343.        
  344.         public override void Emit(OpCode opcode, SignatureHelper signature)
  345.         {
  346.             int stackchange = 0;
  347.             if (signature == null)
  348.                 throw new ArgumentNullException("signature");
  349.            
  350.             EnsureCapacity(7);
  351.             InternalEmit(opcode);
  352.            
  353.             // The only IL instruction that has VarPop behaviour, that takes a
  354.             // Signature token as a parameter is calli. Pop the parameters and
  355.             // the native function pointer. To be conservative, do not pop the
  356.             // this pointer since this information is not easily derived from
  357.             // SignatureHelper.
  358.             if (opcode.m_pop == StackBehaviour.Varpop) {
  359.                 BCLDebug.Assert(opcode.Equals(OpCodes.Calli), "Unexpected opcode encountered for StackBehaviour VarPop.");
  360.                 // Pop the arguments..
  361.                 stackchange -= signature.ArgumentCount;
  362.                 // Pop native function pointer off the stack.
  363.                 stackchange--;
  364.                 UpdateStackSize(opcode, stackchange);
  365.             }
  366.            
  367.             int token = AddSignature(signature.GetSignature(true));
  368.             ;
  369.             m_length = PutInteger4(token, m_length, m_ILStream);
  370.         }
  371.        
  372.         //
  373.         //
  374.         // Exception related generation
  375.         //
  376.         //
  377.         public override Label BeginExceptionBlock()
  378.         {
  379.             return base.BeginExceptionBlock();
  380.         }
  381.        
  382.         public override void EndExceptionBlock()
  383.         {
  384.             base.EndExceptionBlock();
  385.         }
  386.        
  387.         public override void BeginExceptFilterBlock()
  388.         {
  389.             throw new NotSupportedException(Environment.GetResourceString("InvalidOperation_NotAllowedInDynamicMethod"));
  390.         }
  391.        
  392.         public override void BeginCatchBlock(Type exceptionType)
  393.         {
  394.             if (m_currExcStackCount == 0)
  395.                 throw new NotSupportedException(Environment.GetResourceString("Argument_NotInExceptionBlock"));
  396.            
  397.             __ExceptionInfo current = m_currExcStack[m_currExcStackCount - 1];
  398.            
  399.             if (current.GetCurrentState() == __ExceptionInfo.State_Filter) {
  400.                 if (exceptionType != null) {
  401.                     throw new ArgumentException(Environment.GetResourceString("Argument_ShouldNotSpecifyExceptionType"));
  402.                 }
  403.                
  404.                 this.Emit(OpCodes.Endfilter);
  405.             }
  406.             else {
  407.                 // execute this branch if previous clause is Catch or Fault
  408.                 if (exceptionType == null) {
  409.                     throw new ArgumentNullException("exceptionType");
  410.                 }
  411.                
  412.                 if (exceptionType.GetType() != typeof(RuntimeType))
  413.                     throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"));
  414.                
  415.                 Label endLabel = current.GetEndLabel();
  416.                 this.Emit(OpCodes.Leave, endLabel);
  417.                
  418.                 // if this is a catch block the exception will be pushed on the stack and we need to update the stack info
  419.                 UpdateStackSize(OpCodes.Nop, 1);
  420.             }
  421.            
  422.             current.MarkCatchAddr(m_length, exceptionType);
  423.            
  424.            
  425.             // this is relying on too much implementation details of the base and so it's highly breaking
  426.             // Need to have a more integreted story for exceptions
  427.             current.m_filterAddr[current.m_currentCatch - 1] = m_scope.GetTokenFor(exceptionType.TypeHandle);
  428.         }
  429.        
  430.         public override void BeginFaultBlock()
  431.         {
  432.             throw new NotSupportedException(Environment.GetResourceString("InvalidOperation_NotAllowedInDynamicMethod"));
  433.         }
  434.        
  435.         public override void BeginFinallyBlock()
  436.         {
  437.             base.BeginFinallyBlock();
  438.         }
  439.        
  440.         //
  441.         //
  442.         // debugger related calls.
  443.         //
  444.         //
  445.         public override void UsingNamespace(string ns)
  446.         {
  447.             throw new NotSupportedException(Environment.GetResourceString("InvalidOperation_NotAllowedInDynamicMethod"));
  448.         }
  449.        
  450.         public override void MarkSequencePoint(ISymbolDocumentWriter document, int startLine, int startColumn, int endLine, int endColumn)
  451.         {
  452.             throw new NotSupportedException(Environment.GetResourceString("InvalidOperation_NotAllowedInDynamicMethod"));
  453.         }
  454.        
  455.         public override void BeginScope()
  456.         {
  457.             throw new NotSupportedException(Environment.GetResourceString("InvalidOperation_NotAllowedInDynamicMethod"));
  458.         }
  459.        
  460.         public override void EndScope()
  461.         {
  462.             throw new NotSupportedException(Environment.GetResourceString("InvalidOperation_NotAllowedInDynamicMethod"));
  463.         }
  464.        
  465.         //
  466.         // private implementation
  467.         //
  468.         internal override int GetMaxStackSize()
  469.         {
  470.             return m_maxStackSize;
  471.         }
  472.        
  473.         internal override int GetMemberRefToken(MethodBase methodInfo, Type[] optionalParameterTypes)
  474.         {
  475.             Type[] parameterTypes;
  476.            
  477.             if (optionalParameterTypes != null)
  478.                 if ((methodInfo.CallingConvention & CallingConventions.VarArgs) == 0)
  479.                
  480.                     throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotAVarArgCallingConvention"));
  481.            
  482.             if (!(methodInfo is RuntimeMethodInfo) && DynamicMethod.AsDynamicMethod(methodInfo) == null)
  483.                 throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeMethodInfo"), "methodInfo");
  484.            
  485.             ParameterInfo[] paramInfo = methodInfo.GetParametersNoCopy();
  486.             if (paramInfo != null && paramInfo.Length != 0) {
  487.                 parameterTypes = new Type[paramInfo.Length];
  488.                 for (int i = 0; i < paramInfo.Length; i++) {
  489.                     parameterTypes[i] = paramInfo[i].ParameterType;
  490.                 }
  491.             }
  492.             else
  493.                 parameterTypes = null;
  494.            
  495.             SignatureHelper sig = GetMemberRefSignature(methodInfo.CallingConvention, methodInfo.GetReturnType(), parameterTypes, optionalParameterTypes);
  496.             return m_scope.GetTokenFor(new VarArgMethod(methodInfo as MethodInfo, sig));
  497.         }
  498.        
  499.         internal override SignatureHelper GetMemberRefSignature(CallingConventions call, Type returnType, Type[] parameterTypes, Type[] optionalParameterTypes)
  500.         {
  501.             int cParams;
  502.             int i;
  503.             SignatureHelper sig;
  504.             if (parameterTypes == null)
  505.                 cParams = 0;
  506.             else
  507.                 cParams = parameterTypes.Length;
  508.             sig = SignatureHelper.GetMethodSigHelper(call, returnType);
  509.             for (i = 0; i < cParams; i++)
  510.                 sig.AddArgument(parameterTypes[i]);
  511.             if (optionalParameterTypes != null && optionalParameterTypes.Length != 0) {
  512.                 // add the sentinel
  513.                 sig.AddSentinel();
  514.                 for (i = 0; i < optionalParameterTypes.Length; i++)
  515.                     sig.AddArgument(optionalParameterTypes[i]);
  516.             }
  517.             return sig;
  518.         }
  519.        
  520.         private int AddStringLiteral(string s)
  521.         {
  522.             int token = m_scope.GetTokenFor(s);
  523.             return token | 1879048192;
  524.         }
  525.        
  526.         private int AddSignature(byte[] sig)
  527.         {
  528.             int token = m_scope.GetTokenFor(sig);
  529.             return token | 285212672;
  530.         }
  531.        
  532.     }
  533.    
  534.     internal class DynamicResolver : Resolver
  535.     {
  536.         #region Private Data Members
  537.         private __ExceptionInfo[] m_exceptions;
  538.         private byte[] m_exceptionHeader;
  539.         private DynamicMethod m_method;
  540.         private byte[] m_code;
  541.         private byte[] m_localSignature;
  542.         private int m_stackSize;
  543.         private DynamicScope m_scope;
  544.         #endregion
  545.        
  546.         #region Internal Methods
  547.         internal DynamicResolver(DynamicILGenerator ilGenerator)
  548.         {
  549.             m_stackSize = ilGenerator.GetMaxStackSize();
  550.             m_exceptions = ilGenerator.GetExceptions();
  551.             m_code = ilGenerator.BakeByteArray();
  552.             m_localSignature = ilGenerator.m_localSignature.InternalGetSignatureArray();
  553.             m_scope = ilGenerator.m_scope;
  554.            
  555.             m_method = (DynamicMethod)ilGenerator.m_methodBuilder;
  556.             m_method.m_resolver = this;
  557.         }
  558.        
  559.         internal DynamicResolver(DynamicILInfo dynamicILInfo)
  560.         {
  561.             m_stackSize = dynamicILInfo.MaxStackSize;
  562.             m_code = dynamicILInfo.Code;
  563.             m_localSignature = dynamicILInfo.LocalSignature;
  564.             m_exceptionHeader = dynamicILInfo.Exceptions;
  565.             //m_exceptions = dynamicILInfo.Exceptions;
  566.             m_scope = dynamicILInfo.DynamicScope;
  567.            
  568.             m_method = dynamicILInfo.DynamicMethod;
  569.             m_method.m_resolver = this;
  570.         }
  571.        
  572.         //
  573.         //
  574.         ~DynamicResolver()
  575.         {
  576.             DynamicMethod method = m_method;
  577.            
  578.             if (method == null)
  579.                 return;
  580.            
  581.             if (method.m_method.IsNullHandle())
  582.                 return;
  583.            
  584.             DestroyScout scout = null;
  585.             try {
  586.                 scout = new DestroyScout();
  587.             }
  588.             catch {
  589.                 // We go over all DynamicMethodDesc during AppDomain shutdown and make sure
  590.                 // that everything associated with them is released. So it is ok to skip reregistration
  591.                 // for finalization during appdomain shutdown
  592.                 if (!Environment.HasShutdownStarted && !AppDomain.CurrentDomain.IsFinalizingForUnload()) {
  593.                     // Try again later.
  594.                     GC.ReRegisterForFinalize(this);
  595.                 }
  596.                 return;
  597.             }
  598.            
  599.             // We can never ever have two active destroy scouts for the same method. We need to initialize the scout
  600.             // outside the try/reregister block to avoid possibility of reregistration for finalization with active scout.
  601.             scout.m_method = method.m_method;
  602.         }
  603.        
  604.         private class DestroyScout
  605.         {
  606.             internal RuntimeMethodHandle m_method;
  607.            
  608.             ~DestroyScout()
  609.             {
  610.                 if (m_method.IsNullHandle())
  611.                     return;
  612.                
  613.                 // It is not safe to destroy the method if the managed resolver is alive.
  614.                 if (m_method.GetResolver() != null) {
  615.                     if (!Environment.HasShutdownStarted && !AppDomain.CurrentDomain.IsFinalizingForUnload()) {
  616.                         // Somebody might have been holding a reference on us via weak handle.
  617.                         // We will keep trying. It will be hopefully released eventually.
  618.                         GC.ReRegisterForFinalize(this);
  619.                     }
  620.                     return;
  621.                 }
  622.                
  623.                 m_method.Destroy();
  624.             }
  625.         }
  626.        
  627.         // Keep in sync with vm/dynamicmethod.h
  628.         internal enum SecurityControlFlags
  629.         {
  630.             SkipVisibilityChecks = 1
  631.         }
  632.        
  633.         internal override void GetJitContext(ref int securityControlFlags, ref RuntimeTypeHandle typeOwner)
  634.         {
  635.             securityControlFlags = (m_method.m_skipVisibility) ? (int)SecurityControlFlags.SkipVisibilityChecks : 0;
  636.             typeOwner = (m_method.m_typeOwner != null) ? m_method.m_typeOwner.TypeHandle : RuntimeTypeHandle.EmptyHandle;
  637.         }
  638.        
  639.         internal override byte[] GetCodeInfo(ref int stackSize, ref int initLocals, ref int EHCount)
  640.         {
  641.             stackSize = m_stackSize;
  642.             if (m_exceptionHeader != null && m_exceptionHeader.Length != 0) {
  643.                 if (m_exceptionHeader.Length < 4)
  644.                     throw new FormatException();
  645.                
  646.                 byte header = m_exceptionHeader[0];
  647.                
  648.                 // Fat
  649.                 if ((header & 64) != 0) {
  650.                     byte[] size = new byte[4];
  651.                     for (int q = 0; q < 3; q++)
  652.                         size[q] = m_exceptionHeader[q + 1];
  653.                     EHCount = (BitConverter.ToInt32(size, 0) - 4) / 24;
  654.                 }
  655.                 else
  656.                     EHCount = (m_exceptionHeader[1] - 2) / 12;
  657.             }
  658.             else {
  659.                 EHCount = ILGenerator.CalculateNumberOfExceptions(m_exceptions);
  660.             }
  661.             initLocals = (m_method.InitLocals) ? 1 : 0;
  662.             return m_code;
  663.         }
  664.        
  665.         internal override byte[] GetLocalsSignature()
  666.         {
  667.             return m_localSignature;
  668.         }
  669.        
  670.         unsafe internal override byte[] GetRawEHInfo()
  671.         {
  672.             return m_exceptionHeader;
  673.         }
  674.        
  675.         unsafe internal override void GetEHInfo(int excNumber, void* exc)
  676.         {
  677.             CORINFO_EH_CLAUSE* exception = (CORINFO_EH_CLAUSE*)exc;
  678.             for (int i = 0; i < m_exceptions.Length; i++) {
  679.                 int excCount = m_exceptions[i].GetNumberOfCatches();
  680.                 if (excNumber < excCount) {
  681.                     // found the right exception block
  682.                     exception->Flags = m_exceptions[i].GetExceptionTypes()[excNumber];
  683.                     exception->Flags |= Resolver.COR_ILEXCEPTION_CLAUSE_MUST_CACHE_CLASS;
  684.                     exception->TryOffset = m_exceptions[i].GetStartAddress();
  685.                     if ((exception->Flags & __ExceptionInfo.Finally) != __ExceptionInfo.Finally)
  686.                         exception->TryLength = m_exceptions[i].GetEndAddress() - exception->TryOffset;
  687.                     else
  688.                         exception->TryLength = m_exceptions[i].GetFinallyEndAddress() - exception->TryOffset;
  689.                     exception->HandlerOffset = m_exceptions[i].GetCatchAddresses()[excNumber];
  690.                     exception->HandlerLength = m_exceptions[i].GetCatchEndAddresses()[excNumber] - exception->HandlerOffset;
  691.                     // this is cheating because the filter address is the token of the class only for light code gen
  692.                     exception->ClassTokenOrFilterOffset = m_exceptions[i].GetFilterAddresses()[excNumber];
  693.                     break;
  694.                 }
  695.                 excNumber -= excCount;
  696.             }
  697.         }
  698.        
  699.         internal override string GetStringLiteral(int token)
  700.         {
  701.             return m_scope.GetString(token);
  702.         }
  703.        
  704.         internal override int IsValidToken(int token)
  705.         {
  706.             return (m_scope[token] != null) ? 1 : 0;
  707.         }
  708.        
  709.         unsafe internal override void* GetInstantiationInfo(int token)
  710.         {
  711.             GenericMethodInfo gmi = m_scope[token] as GenericMethodInfo;
  712.             if (gmi != null) {
  713.                 return (void*)gmi.m_context.Value;
  714.             }
  715.             return null;
  716.         }
  717.        
  718.         unsafe internal override void* ResolveToken(int token)
  719.         {
  720.             object handle = m_scope[token];
  721.            
  722.             if (handle is RuntimeTypeHandle) {
  723.                 RuntimeTypeHandle typeHandle = (RuntimeTypeHandle)handle;
  724.                 return (void*)typeHandle.Value;
  725.             }
  726.             else if (handle is RuntimeMethodHandle) {
  727.                 RuntimeMethodHandle methodHandle = (RuntimeMethodHandle)handle;
  728.                 return (void*)methodHandle.Value;
  729.             }
  730.             else if (handle is RuntimeFieldHandle) {
  731.                 RuntimeFieldHandle fieldHandle = (RuntimeFieldHandle)handle;
  732.                 return (void*)fieldHandle.Value;
  733.             }
  734.             else if (handle is DynamicMethod) {
  735.                 DynamicMethod dynMeth = (DynamicMethod)handle;
  736.                 RuntimeMethodHandle methodHandle = dynMeth.GetMethodDescriptor();
  737.                 return (void*)methodHandle.Value;
  738.             }
  739.             else if (handle is GenericMethodInfo) {
  740.                 GenericMethodInfo gmi = (GenericMethodInfo)handle;
  741.                 return (void*)gmi.m_method.Value;
  742.             }
  743.             else if (handle is VarArgMethod) {
  744.                 VarArgMethod vaMeth = (VarArgMethod)handle;
  745.                 DynamicMethod dm = vaMeth.m_method as DynamicMethod;
  746.                 if (dm == null)
  747.                     return (void*)vaMeth.m_method.MethodHandle.Value;
  748.                 else
  749.                     return (void*)dm.GetMethodDescriptor().Value;
  750.             }
  751.            
  752.             return null;
  753.         }
  754.        
  755.         internal override byte[] ResolveSignature(int token, int fromMethod)
  756.         {
  757.             return m_scope.ResolveSignature(token, fromMethod);
  758.         }
  759.        
  760.         unsafe internal override int ParentToken(int token)
  761.         {
  762.             RuntimeTypeHandle owner = RuntimeTypeHandle.EmptyHandle;
  763.            
  764.             object handle = m_scope[token];
  765.            
  766.             if (handle is RuntimeMethodHandle) {
  767.                 RuntimeMethodHandle method = (RuntimeMethodHandle)handle;
  768.                 owner = method.GetDeclaringType();
  769.             }
  770.             else if (handle is RuntimeFieldHandle) {
  771.                 RuntimeFieldHandle field = (RuntimeFieldHandle)handle;
  772.                 owner = field.GetApproxDeclaringType();
  773.             }
  774.             else if (handle is DynamicMethod) {
  775.                 DynamicMethod dynMeth = (DynamicMethod)handle;
  776.                 owner = dynMeth.m_method.GetDeclaringType();
  777.             }
  778.             else if (handle is GenericMethodInfo) {
  779.                 GenericMethodInfo gmi = (GenericMethodInfo)handle;
  780.                 owner = gmi.m_context;
  781.             }
  782.             else if (handle is VarArgMethod) {
  783.