Пример #1
0
        internal void Generate()
        {
            var mainType = _module.MainType;

            var proxyMethod = (BuildMethod)mainType.Methods.Add();

            proxyMethod.Name            = _random.NextString(12, true);
            proxyMethod.Visibility      = MethodVisibilityFlags.Assembly;
            proxyMethod.IsStatic        = true;
            proxyMethod.IsHideBySig     = true;
            proxyMethod.ReturnType.Type = TypeReference.GetPrimitiveType(PrimitiveTypeCode.Void, _module.Assembly);

            var methodBody   = new MethodBody();
            var instructions = methodBody.Instructions;

            foreach (var startupMethod in _startupMethods)
            {
                instructions.Add(new Instruction(OpCodes.Call, startupMethod.ToReference(startupMethod.Module)));
            }

            instructions.Add(new Instruction(OpCodes.Ret));

            methodBody.Build(proxyMethod);

            // Call proxy method from <Module>.cctor
            GenerateGlobalCCtor(proxyMethod);
        }
Пример #2
0
        private void Generate(MethodReference methodRef, MethodReference proxyMethodRef, OpCode opCode)
        {
            var method = _mainType.Methods.Add();

            method.Name        = proxyMethodRef.Name;
            method.Visibility  = MethodVisibilityFlags.Assembly;
            method.IsStatic    = true;
            method.IsHideBySig = true;

            // Return type
            {
                var returnType = method.ReturnType;
                returnType.Type = proxyMethodRef.ReturnType;
            }

            // Parameters
            {
                var parameters = method.Parameters;

                foreach (var argumentType in proxyMethodRef.Arguments)
                {
                    var parameter = parameters.Add();
                    parameter.Type = argumentType;
                }
            }

            // Body
            {
                int paramCount = proxyMethodRef.Arguments.Count;

                var methodBody = new MethodBody();
                methodBody.MaxStackSize = paramCount;
                methodBody.InitLocals   = true;

                // Instructions
                {
                    var instructions = methodBody.Instructions;

                    for (int i = 0; i < paramCount; i++)
                    {
                        instructions.Add(Instruction.GetLdarg(i));
                    }

                    instructions.Add(new Instruction(opCode, methodRef));
                    instructions.Add(new Instruction(OpCodes.Ret));
                }

                methodBody.Build(method);
            }
        }
Пример #3
0
        /// <summary>
        /// static LoadStrings() : [mscorlib]System.Void
        /// </summary>
        private void LoadStrings(MethodDeclaration method)
        {
            method.Name        = "LoadStrings";
            method.Visibility  = MethodVisibilityFlags.Assembly;
            method.IsStatic    = true;
            method.IsHideBySig = true;

            // Return type
            {
                var returnType = method.ReturnType;
                returnType.Type =
                    TypeReference.GetPrimitiveType(PrimitiveTypeCode.Void, _module.Assembly);
            }

            // Body
            {
                var methodBody = new MethodBody();
                methodBody.MaxStackSize = 5;
                methodBody.InitLocals   = true;

                // Local variables
                {
                    var localVariables = methodBody.LocalVariables;
                    localVariables.Add(
                        new ArrayType(
                            TypeReference.GetPrimitiveType(PrimitiveTypeCode.UInt8, _module.Assembly)));
                    localVariables.Add(
                        TypeReference.GetPrimitiveType(PrimitiveTypeCode.Int32, _module.Assembly));
                    localVariables.Add(
                        new TypeReference("Encoding", "System.Text",
                                          AssemblyReference.GetMscorlib(_module.Assembly), false));
                    localVariables.Add(
                        TypeReference.GetPrimitiveType(PrimitiveTypeCode.Int32, _module.Assembly));
                }

                // Instructions
                {
                    var instructions = methodBody.Instructions;
                    instructions.Add(new Instruction(OpCodes.Ldc_I4, (int)_dataID));
                    instructions.Add(new Instruction(OpCodes.Call,
                                                     new MethodReference(
                                                         "GetData",
                                                         new TypeReference(_mainType.Name, _mainType.Namespace, false),
                                                         new CallSite(
                                                             false,
                                                             false,
                                                             MethodCallingConvention.Default,
                                                             new ArrayType(
                                                                 TypeReference.GetPrimitiveType(PrimitiveTypeCode.UInt8, _module.Assembly)),
                                                             new TypeSignature[]
                    {
                        TypeReference.GetPrimitiveType(PrimitiveTypeCode.Int32, _module.Assembly),
                    },
                                                             -1,
                                                             0))));
                    instructions.Add(new Instruction(OpCodes.Stloc_0));
                    instructions.Add(new Instruction(OpCodes.Ldc_I4_0));
                    instructions.Add(new Instruction(OpCodes.Stloc_1));
                    instructions.Add(new Instruction(OpCodes.Call,
                                                     new MethodReference(
                                                         "get_UTF8",
                                                         new TypeReference("Encoding", "System.Text",
                                                                           AssemblyReference.GetMscorlib(_module.Assembly), false),
                                                         new CallSite(
                                                             false,
                                                             false,
                                                             MethodCallingConvention.Default,
                                                             new TypeReference("Encoding", "System.Text",
                                                                               AssemblyReference.GetMscorlib(_module.Assembly), false),
                                                             new TypeSignature[0],
                                                             -1,
                                                             0))));
                    instructions.Add(new Instruction(OpCodes.Stloc_2));
                    instructions.Add(new Instruction(OpCodes.Ldc_I4, (int)_strings.Count));
                    instructions.Add(new Instruction(OpCodes.Newarr,
                                                     TypeReference.GetPrimitiveType(PrimitiveTypeCode.String, _module.Assembly)));
                    instructions.Add(new Instruction(OpCodes.Stsfld,
                                                     new FieldReference(
                                                         "Strings",
                                                         new ArrayType(
                                                             TypeReference.GetPrimitiveType(PrimitiveTypeCode.String, _module.Assembly)),
                                                         new TypeReference(_mainType.Name, _mainType.Namespace, false))));
                    instructions.Add(new Instruction(OpCodes.Ldc_I4_0));
                    instructions.Add(new Instruction(OpCodes.Stloc_3));
                    instructions.Add(new Instruction(OpCodes.Br_S, (sbyte)20));
                    instructions.Add(new Instruction(OpCodes.Ldsfld,
                                                     new FieldReference(
                                                         "Strings",
                                                         new ArrayType(
                                                             TypeReference.GetPrimitiveType(PrimitiveTypeCode.String, _module.Assembly)),
                                                         new TypeReference(_mainType.Name, _mainType.Namespace, false))));
                    instructions.Add(new Instruction(OpCodes.Ldloc_3));
                    instructions.Add(new Instruction(OpCodes.Ldloc_0));
                    instructions.Add(new Instruction(OpCodes.Ldloca_S, (byte)1));
                    instructions.Add(new Instruction(OpCodes.Ldloc_2));
                    instructions.Add(new Instruction(OpCodes.Call,
                                                     new MethodReference(
                                                         "ReadStringIntern",
                                                         new TypeReference(_mainType.Name, _mainType.Namespace, false),
                                                         new CallSite(
                                                             false,
                                                             false,
                                                             MethodCallingConvention.Default,
                                                             TypeReference.GetPrimitiveType(PrimitiveTypeCode.String, _module.Assembly),
                                                             new TypeSignature[]
                    {
                        new ArrayType(
                            TypeReference.GetPrimitiveType(PrimitiveTypeCode.UInt8, _module.Assembly)),
                        new ByRefType(
                            TypeReference.GetPrimitiveType(PrimitiveTypeCode.Int32, _module.Assembly)),
                        new TypeReference("Encoding", "System.Text",
                                          AssemblyReference.GetMscorlib(_module.Assembly), false),
                    },
                                                             -1,
                                                             0))));
                    instructions.Add(new Instruction(OpCodes.Stelem_Ref));
                    instructions.Add(new Instruction(OpCodes.Ldloc_3));
                    instructions.Add(new Instruction(OpCodes.Ldc_I4_1));
                    instructions.Add(new Instruction(OpCodes.Add));
                    instructions.Add(new Instruction(OpCodes.Stloc_3));
                    instructions.Add(new Instruction(OpCodes.Ldloc_3));
                    instructions.Add(new Instruction(OpCodes.Ldc_I4, (int)_strings.Count));
                    instructions.Add(new Instruction(OpCodes.Blt_S, (sbyte)-28));
                    instructions.Add(new Instruction(OpCodes.Ret));
                }

                methodBody.Build(method);
            }
        }
        /// <summary>
        /// static GetMergedAssemblyNames() : [mscorlib]System.String[]
        /// </summary>
        private void GetMergedAssemblyNames(MethodDeclaration method)
        {
            method.Name        = "GetMergedAssemblyNames";
            method.Visibility  = MethodVisibilityFlags.Assembly;
            method.IsStatic    = true;
            method.IsHideBySig = true;

            // Return type
            {
                var returnType = method.ReturnType;
                returnType.Type =
                    new ArrayType(
                        TypeReference.GetPrimitiveType(PrimitiveTypeCode.String, _module.Assembly));
            }

            // Body
            {
                var methodBody = new MethodBody();
                methodBody.MaxStackSize = 5;
                methodBody.InitLocals   = true;

                // Local variables
                {
                    var localVariables = methodBody.LocalVariables;
                    localVariables.Add(
                        new ArrayType(
                            TypeReference.GetPrimitiveType(PrimitiveTypeCode.UInt8, _module.Assembly)));
                    localVariables.Add(
                        new TypeReference("Encoding", "System.Text",
                                          AssemblyReference.GetMscorlib(_module.Assembly), false));
                    localVariables.Add(
                        TypeReference.GetPrimitiveType(PrimitiveTypeCode.Int32, _module.Assembly));
                    localVariables.Add(
                        TypeReference.GetPrimitiveType(PrimitiveTypeCode.Int32, _module.Assembly));
                    localVariables.Add(
                        new ArrayType(
                            TypeReference.GetPrimitiveType(PrimitiveTypeCode.String, _module.Assembly)));
                    localVariables.Add(
                        TypeReference.GetPrimitiveType(PrimitiveTypeCode.Int32, _module.Assembly));
                    localVariables.Add(
                        TypeReference.GetPrimitiveType(PrimitiveTypeCode.Object, _module.Assembly));
                }

                // Exception handlers
                {
                    var exceptionHandlers = methodBody.ExceptionHandlers;
                    exceptionHandlers.Add(
                        new ExceptionHandler(
                            ExceptionHandlerType.Finally,
                            20, 82, 102, 8, 0));
                }

                // Instructions
                {
                    var instructions = methodBody.Instructions;
                    instructions.Add(new Instruction(OpCodes.Ldsfld,
                                                     new FieldReference(
                                                         "_mergedAssemblyNames",
                                                         new ArrayType(
                                                             TypeReference.GetPrimitiveType(PrimitiveTypeCode.String, _module.Assembly)),
                                                         new TypeReference(_mainType.Name, _mainType.Namespace, false))));
                    instructions.Add(new Instruction(OpCodes.Brtrue_S, (sbyte)103));
                    instructions.Add(new Instruction(OpCodes.Ldsfld,
                                                     new FieldReference(
                                                         "_mergeLockObject",
                                                         TypeReference.GetPrimitiveType(PrimitiveTypeCode.Object, _module.Assembly),
                                                         new TypeReference(_mainType.Name, _mainType.Namespace, false))));
                    instructions.Add(new Instruction(OpCodes.Dup));
                    instructions.Add(new Instruction(OpCodes.Stloc_S, (byte)6));
                    instructions.Add(new Instruction(OpCodes.Call,
                                                     new MethodReference(
                                                         "Enter",
                                                         new TypeReference("Monitor", "System.Threading",
                                                                           AssemblyReference.GetMscorlib(_module.Assembly), false),
                                                         new CallSite(
                                                             false,
                                                             false,
                                                             MethodCallingConvention.Default,
                                                             TypeReference.GetPrimitiveType(PrimitiveTypeCode.Void, _module.Assembly),
                                                             new TypeSignature[]
                    {
                        TypeReference.GetPrimitiveType(PrimitiveTypeCode.Object, _module.Assembly),
                    },
                                                             -1,
                                                             0))));
                    instructions.Add(new Instruction(OpCodes.Ldsfld,
                                                     new FieldReference(
                                                         "_mergedAssemblyNames",
                                                         new ArrayType(
                                                             TypeReference.GetPrimitiveType(PrimitiveTypeCode.String, _module.Assembly)),
                                                         new TypeReference(_mainType.Name, _mainType.Namespace, false))));
                    instructions.Add(new Instruction(OpCodes.Brtrue_S, (sbyte)73));
                    instructions.Add(new Instruction(OpCodes.Ldc_I4, (int)_dataID));
                    instructions.Add(new Instruction(OpCodes.Call,
                                                     new MethodReference(
                                                         "GetData",
                                                         new TypeReference(_mainType.Name, _mainType.Namespace, false),
                                                         new CallSite(
                                                             false,
                                                             false,
                                                             MethodCallingConvention.Default,
                                                             new ArrayType(
                                                                 TypeReference.GetPrimitiveType(PrimitiveTypeCode.UInt8, _module.Assembly)),
                                                             new TypeSignature[]
                    {
                        TypeReference.GetPrimitiveType(PrimitiveTypeCode.Int32, _module.Assembly),
                    },
                                                             -1,
                                                             0))));
                    instructions.Add(new Instruction(OpCodes.Stloc_0));
                    instructions.Add(new Instruction(OpCodes.Call,
                                                     new MethodReference(
                                                         "get_UTF8",
                                                         new TypeReference("Encoding", "System.Text",
                                                                           AssemblyReference.GetMscorlib(_module.Assembly), false),
                                                         new CallSite(
                                                             false,
                                                             false,
                                                             MethodCallingConvention.Default,
                                                             new TypeReference("Encoding", "System.Text",
                                                                               AssemblyReference.GetMscorlib(_module.Assembly), false),
                                                             new TypeSignature[0],
                                                             -1,
                                                             0))));
                    instructions.Add(new Instruction(OpCodes.Stloc_1));
                    instructions.Add(new Instruction(OpCodes.Ldc_I4_0));
                    instructions.Add(new Instruction(OpCodes.Stloc_2));
                    instructions.Add(new Instruction(OpCodes.Ldloc_0));
                    instructions.Add(new Instruction(OpCodes.Ldloca_S, (byte)2));
                    instructions.Add(new Instruction(OpCodes.Call,
                                                     new MethodReference(
                                                         "Read7BitEncodedInt",
                                                         new TypeReference(_mainType.Name, _mainType.Namespace, false),
                                                         new CallSite(
                                                             false,
                                                             false,
                                                             MethodCallingConvention.Default,
                                                             TypeReference.GetPrimitiveType(PrimitiveTypeCode.Int32, _module.Assembly),
                                                             new TypeSignature[]
                    {
                        new ArrayType(
                            TypeReference.GetPrimitiveType(PrimitiveTypeCode.UInt8, _module.Assembly)),
                        new ByRefType(
                            TypeReference.GetPrimitiveType(PrimitiveTypeCode.Int32, _module.Assembly)),
                    },
                                                             -1,
                                                             0))));
                    instructions.Add(new Instruction(OpCodes.Stloc_3));
                    instructions.Add(new Instruction(OpCodes.Ldloc_3));
                    instructions.Add(new Instruction(OpCodes.Newarr,
                                                     TypeReference.GetPrimitiveType(PrimitiveTypeCode.String, _module.Assembly)));
                    instructions.Add(new Instruction(OpCodes.Stloc_S, (byte)4));
                    instructions.Add(new Instruction(OpCodes.Ldc_I4_0));
                    instructions.Add(new Instruction(OpCodes.Stloc_S, (byte)5));
                    instructions.Add(new Instruction(OpCodes.Br_S, (sbyte)20));
                    instructions.Add(new Instruction(OpCodes.Ldloc_S, (byte)4));
                    instructions.Add(new Instruction(OpCodes.Ldloc_S, (byte)5));
                    instructions.Add(new Instruction(OpCodes.Ldloc_0));
                    instructions.Add(new Instruction(OpCodes.Ldloca_S, (byte)2));
                    instructions.Add(new Instruction(OpCodes.Ldloc_1));
                    instructions.Add(new Instruction(OpCodes.Call,
                                                     new MethodReference(
                                                         "ReadString",
                                                         new TypeReference(_mainType.Name, _mainType.Namespace, false),
                                                         new CallSite(
                                                             false,
                                                             false,
                                                             MethodCallingConvention.Default,
                                                             TypeReference.GetPrimitiveType(PrimitiveTypeCode.String, _module.Assembly),
                                                             new TypeSignature[]
                    {
                        new ArrayType(
                            TypeReference.GetPrimitiveType(PrimitiveTypeCode.UInt8, _module.Assembly)),
                        new ByRefType(
                            TypeReference.GetPrimitiveType(PrimitiveTypeCode.Int32, _module.Assembly)),
                        new TypeReference("Encoding", "System.Text",
                                          AssemblyReference.GetMscorlib(_module.Assembly), false),
                    },
                                                             -1,
                                                             0))));
                    instructions.Add(new Instruction(OpCodes.Stelem_Ref));
                    instructions.Add(new Instruction(OpCodes.Ldloc_S, (byte)5));
                    instructions.Add(new Instruction(OpCodes.Ldc_I4_1));
                    instructions.Add(new Instruction(OpCodes.Add));
                    instructions.Add(new Instruction(OpCodes.Stloc_S, (byte)5));
                    instructions.Add(new Instruction(OpCodes.Ldloc_S, (byte)5));
                    instructions.Add(new Instruction(OpCodes.Ldloc_3));
                    instructions.Add(new Instruction(OpCodes.Blt_S, (sbyte)-25));
                    instructions.Add(new Instruction(OpCodes.Ldloc_S, (byte)4));
                    instructions.Add(new Instruction(OpCodes.Stsfld,
                                                     new FieldReference(
                                                         "_mergedAssemblyNames",
                                                         new ArrayType(
                                                             TypeReference.GetPrimitiveType(PrimitiveTypeCode.String, _module.Assembly)),
                                                         new TypeReference(_mainType.Name, _mainType.Namespace, false))));
                    instructions.Add(new Instruction(OpCodes.Leave_S, (sbyte)8));
                    instructions.Add(new Instruction(OpCodes.Ldloc_S, (byte)6));
                    instructions.Add(new Instruction(OpCodes.Call,
                                                     new MethodReference(
                                                         "Exit",
                                                         new TypeReference("Monitor", "System.Threading",
                                                                           AssemblyReference.GetMscorlib(_module.Assembly), false),
                                                         new CallSite(
                                                             false,
                                                             false,
                                                             MethodCallingConvention.Default,
                                                             TypeReference.GetPrimitiveType(PrimitiveTypeCode.Void, _module.Assembly),
                                                             new TypeSignature[]
                    {
                        TypeReference.GetPrimitiveType(PrimitiveTypeCode.Object, _module.Assembly),
                    },
                                                             -1,
                                                             0))));
                    instructions.Add(new Instruction(OpCodes.Endfinally));
                    instructions.Add(new Instruction(OpCodes.Ldsfld,
                                                     new FieldReference(
                                                         "_mergedAssemblyNames",
                                                         new ArrayType(
                                                             TypeReference.GetPrimitiveType(PrimitiveTypeCode.String, _module.Assembly)),
                                                         new TypeReference(_mainType.Name, _mainType.Namespace, false))));
                    instructions.Add(new Instruction(OpCodes.Ret));
                }

                methodBody.Build(method);
            }
        }
        /// <summary>
        /// static OnMergedAssemblyResolve([mscorlib]System.Object, [mscorlib]System.ResolveEventArgs) : [mscorlib]System.Reflection.Assembly
        /// </summary>
        private void OnMergedAssemblyResolve(MethodDeclaration method)
        {
            method.Name        = "OnMergedAssemblyResolve";
            method.Visibility  = MethodVisibilityFlags.Assembly;
            method.IsStatic    = true;
            method.IsHideBySig = true;

            // Return type
            {
                var returnType = method.ReturnType;
                returnType.Type =
                    new TypeReference("Assembly", "System.Reflection",
                                      AssemblyReference.GetMscorlib(_module.Assembly), false);
            }

            // Parameters
            {
                var parameters = method.Parameters;

                // sender : [mscorlib]System.Object
                var parameter = parameters.Add();
                parameter.Type =
                    TypeReference.GetPrimitiveType(PrimitiveTypeCode.Object, _module.Assembly);

                // args : [mscorlib]System.ResolveEventArgs
                parameter      = parameters.Add();
                parameter.Type =
                    new TypeReference("ResolveEventArgs", "System",
                                      AssemblyReference.GetMscorlib(_module.Assembly), false);
            }

            // Body
            {
                var methodBody = new MethodBody();
                methodBody.MaxStackSize = 2;
                methodBody.InitLocals   = true;

                // Local variables
                {
                    var localVariables = methodBody.LocalVariables;
                    localVariables.Add(
                        new ArrayType(
                            TypeReference.GetPrimitiveType(PrimitiveTypeCode.String, _module.Assembly)));
                    localVariables.Add(
                        TypeReference.GetPrimitiveType(PrimitiveTypeCode.String, _module.Assembly));
                    localVariables.Add(
                        TypeReference.GetPrimitiveType(PrimitiveTypeCode.Int32, _module.Assembly));
                }

                // Instructions
                {
                    var instructions = methodBody.Instructions;
                    instructions.Add(new Instruction(OpCodes.Call,
                                                     new MethodReference(
                                                         "GetMergedAssemblyNames",
                                                         new TypeReference(_mainType.Name, _mainType.Namespace, false),
                                                         new CallSite(
                                                             false,
                                                             false,
                                                             MethodCallingConvention.Default,
                                                             new ArrayType(
                                                                 TypeReference.GetPrimitiveType(PrimitiveTypeCode.String, _module.Assembly)),
                                                             new TypeSignature[0],
                                                             -1,
                                                             0))));
                    instructions.Add(new Instruction(OpCodes.Stloc_0));
                    instructions.Add(new Instruction(OpCodes.Ldarg_1));
                    instructions.Add(new Instruction(OpCodes.Callvirt,
                                                     new MethodReference(
                                                         "get_Name",
                                                         new TypeReference("ResolveEventArgs", "System",
                                                                           AssemblyReference.GetMscorlib(_module.Assembly), false),
                                                         new CallSite(
                                                             true,
                                                             false,
                                                             MethodCallingConvention.Default,
                                                             TypeReference.GetPrimitiveType(PrimitiveTypeCode.String, _module.Assembly),
                                                             new TypeSignature[0],
                                                             -1,
                                                             0))));
                    instructions.Add(new Instruction(OpCodes.Call,
                                                     new MethodReference(
                                                         "GetAssemblyName",
                                                         new TypeReference(_mainType.Name, _mainType.Namespace, false),
                                                         new CallSite(
                                                             false,
                                                             false,
                                                             MethodCallingConvention.Default,
                                                             TypeReference.GetPrimitiveType(PrimitiveTypeCode.String, _module.Assembly),
                                                             new TypeSignature[]
                    {
                        TypeReference.GetPrimitiveType(PrimitiveTypeCode.String, _module.Assembly),
                    },
                                                             -1,
                                                             0))));
                    instructions.Add(new Instruction(OpCodes.Stloc_1));
                    instructions.Add(new Instruction(OpCodes.Ldc_I4_0));
                    instructions.Add(new Instruction(OpCodes.Stloc_2));
                    instructions.Add(new Instruction(OpCodes.Br_S, (sbyte)21));
                    instructions.Add(new Instruction(OpCodes.Ldloc_0));
                    instructions.Add(new Instruction(OpCodes.Ldloc_2));
                    instructions.Add(new Instruction(OpCodes.Ldelem_Ref));
                    instructions.Add(new Instruction(OpCodes.Ldloc_1));
                    instructions.Add(new Instruction(OpCodes.Call,
                                                     new MethodReference(
                                                         "op_Equality",
                                                         TypeReference.GetPrimitiveType(PrimitiveTypeCode.String, _module.Assembly),
                                                         new CallSite(
                                                             false,
                                                             false,
                                                             MethodCallingConvention.Default,
                                                             TypeReference.GetPrimitiveType(PrimitiveTypeCode.Boolean, _module.Assembly),
                                                             new TypeSignature[]
                    {
                        TypeReference.GetPrimitiveType(PrimitiveTypeCode.String, _module.Assembly),
                        TypeReference.GetPrimitiveType(PrimitiveTypeCode.String, _module.Assembly),
                    },
                                                             -1,
                                                             0))));
                    instructions.Add(new Instruction(OpCodes.Brfalse_S, (sbyte)6));
                    instructions.Add(new Instruction(OpCodes.Call,
                                                     new MethodReference(
                                                         "GetExecutingAssembly",
                                                         new TypeReference("Assembly", "System.Reflection",
                                                                           AssemblyReference.GetMscorlib(_module.Assembly), false),
                                                         new CallSite(
                                                             false,
                                                             false,
                                                             MethodCallingConvention.Default,
                                                             new TypeReference("Assembly", "System.Reflection",
                                                                               AssemblyReference.GetMscorlib(_module.Assembly), false),
                                                             new TypeSignature[0],
                                                             -1,
                                                             0))));
                    instructions.Add(new Instruction(OpCodes.Ret));
                    instructions.Add(new Instruction(OpCodes.Ldloc_2));
                    instructions.Add(new Instruction(OpCodes.Ldc_I4_1));
                    instructions.Add(new Instruction(OpCodes.Add));
                    instructions.Add(new Instruction(OpCodes.Stloc_2));
                    instructions.Add(new Instruction(OpCodes.Ldloc_2));
                    instructions.Add(new Instruction(OpCodes.Ldloc_0));
                    instructions.Add(new Instruction(OpCodes.Ldlen));
                    instructions.Add(new Instruction(OpCodes.Conv_I4));
                    instructions.Add(new Instruction(OpCodes.Blt_S, (sbyte)-27));
                    instructions.Add(new Instruction(OpCodes.Ldnull));
                    instructions.Add(new Instruction(OpCodes.Ret));
                }

                methodBody.Build(method);
            }
        }
        /// <summary>
        /// static MergeInitialize() : [mscorlib]System.Void
        /// </summary>
        private void MergeInitialize(MethodDeclaration method)
        {
            method.Name        = "MergeInitialize";
            method.Visibility  = MethodVisibilityFlags.Assembly;
            method.IsStatic    = true;
            method.IsHideBySig = true;

            // Return type
            {
                var returnType = method.ReturnType;
                returnType.Type =
                    TypeReference.GetPrimitiveType(PrimitiveTypeCode.Void, _module.Assembly);
            }

            // Body
            {
                var methodBody = new MethodBody();
                methodBody.MaxStackSize = 8;
                methodBody.InitLocals   = true;

                // Instructions
                {
                    var instructions = methodBody.Instructions;
                    instructions.Add(new Instruction(OpCodes.Call,
                                                     new MethodReference(
                                                         "get_CurrentDomain",
                                                         new TypeReference("AppDomain", "System",
                                                                           AssemblyReference.GetMscorlib(_module.Assembly), false),
                                                         new CallSite(
                                                             false,
                                                             false,
                                                             MethodCallingConvention.Default,
                                                             new TypeReference("AppDomain", "System",
                                                                               AssemblyReference.GetMscorlib(_module.Assembly), false),
                                                             new TypeSignature[0],
                                                             -1,
                                                             0))));
                    instructions.Add(new Instruction(OpCodes.Ldnull));
                    instructions.Add(new Instruction(OpCodes.Ldftn,
                                                     new MethodReference(
                                                         "OnMergedAssemblyResolve",
                                                         new TypeReference(_mainType.Name, _mainType.Namespace, false),
                                                         new CallSite(
                                                             false,
                                                             false,
                                                             MethodCallingConvention.Default,
                                                             new TypeReference("Assembly", "System.Reflection",
                                                                               AssemblyReference.GetMscorlib(_module.Assembly), false),
                                                             new TypeSignature[]
                    {
                        TypeReference.GetPrimitiveType(PrimitiveTypeCode.Object, _module.Assembly),
                        new TypeReference("ResolveEventArgs", "System",
                                          AssemblyReference.GetMscorlib(_module.Assembly), false),
                    },
                                                             -1,
                                                             0))));
                    instructions.Add(new Instruction(OpCodes.Newobj,
                                                     new MethodReference(
                                                         CodeModelUtils.MethodConstructorName,
                                                         new TypeReference("ResolveEventHandler", "System",
                                                                           AssemblyReference.GetMscorlib(_module.Assembly), false),
                                                         new CallSite(
                                                             true,
                                                             false,
                                                             MethodCallingConvention.Default,
                                                             TypeReference.GetPrimitiveType(PrimitiveTypeCode.Void, _module.Assembly),
                                                             new TypeSignature[]
                    {
                        TypeReference.GetPrimitiveType(PrimitiveTypeCode.Object, _module.Assembly),
                        TypeReference.GetPrimitiveType(PrimitiveTypeCode.IntPtr, _module.Assembly),
                    },
                                                             -1,
                                                             0))));
                    instructions.Add(new Instruction(OpCodes.Callvirt,
                                                     new MethodReference(
                                                         "add_AssemblyResolve",
                                                         new TypeReference("AppDomain", "System",
                                                                           AssemblyReference.GetMscorlib(_module.Assembly), false),
                                                         new CallSite(
                                                             true,
                                                             false,
                                                             MethodCallingConvention.Default,
                                                             TypeReference.GetPrimitiveType(PrimitiveTypeCode.Void, _module.Assembly),
                                                             new TypeSignature[]
                    {
                        new TypeReference("ResolveEventHandler", "System",
                                          AssemblyReference.GetMscorlib(_module.Assembly), false),
                    },
                                                             -1,
                                                             0))));
                    instructions.Add(new Instruction(OpCodes.Ret));
                }

                methodBody.Build(method);
            }
        }
Пример #7
0
        private void ChangeProxyMethod(BuildType type, ProxyBuildMethod proxyMethod)
        {
            var overridenMethod = proxyMethod.OverridenMethod;
            var calledMethod    = proxyMethod.CalledMethod;

            var method = type.Methods.Add();

            method.Name        = _nameGenerator.GenerateUniqueString();
            method.Visibility  = MethodVisibilityFlags.Private;
            method.HasThis     = true;
            method.IsHideBySig = true;
            method.IsVirtual   = true;
            method.IsNewSlot   = true;
            method.IsFinal     = true;
            method.CallConv    = overridenMethod.CallConv;

            // Return type
            {
                var returnType = method.ReturnType;
                returnType.Type = overridenMethod.ReturnType.ToSignature(type.Module);
            }

            // Parameters
            foreach (var overridenMethodParameter in overridenMethod.Parameters)
            {
                var parameter = method.Parameters.Add();
                parameter.Name       = overridenMethodParameter.Name;
                parameter.IsIn       = overridenMethodParameter.IsIn;
                parameter.IsOut      = overridenMethodParameter.IsOut;
                parameter.IsOptional = overridenMethodParameter.IsOptional;
                parameter.IsLcid     = overridenMethodParameter.IsLcid;
                parameter.Type       = overridenMethodParameter.Type.ToSignature(type.Module);
            }

            // GenericParameters
            foreach (var interfaceGenericParameter in overridenMethod.GenericParameters)
            {
                var genericParameter = method.GenericParameters.Add();
                genericParameter.Name     = interfaceGenericParameter.Name;
                genericParameter.Variance = interfaceGenericParameter.Variance;
                genericParameter.DefaultConstructorConstraint = interfaceGenericParameter.DefaultConstructorConstraint;
                genericParameter.ReferenceTypeConstraint      = interfaceGenericParameter.ReferenceTypeConstraint;
                genericParameter.ValueTypeConstraint          = interfaceGenericParameter.ValueTypeConstraint;

                // Constraints
                foreach (var constraintType in interfaceGenericParameter.Constraints)
                {
                    genericParameter.Constraints.Add(constraintType.ToSignature(type.Module));
                }
            }

            // Body
            {
                var methodBody = new MethodBody();

                // Instructions
                var instructions = methodBody.Instructions;

                methodBody.MaxStackSize = method.Parameters.Count + 2;                 // this + parameters + return

                // Load this
                instructions.Add(Instruction.GetLdarg(0));

                // Load parameters
                for (int i = 0; i < method.Parameters.Count; i++)
                {
                    instructions.Add(Instruction.GetLdarg(i + 1));
                }

                var calledMethodSig = calledMethod.ToSignature(type.Module);
                if (calledMethod.GenericParameters.Count > 0)
                {
                    var genericArguments = new TypeSignature[calledMethod.GenericParameters.Count];
                    for (int i = 0; i < genericArguments.Length; i++)
                    {
                        genericArguments[i] = new GenericParameterType(true, i);
                    }

                    calledMethodSig = new GenericMethodReference((MethodReference)calledMethodSig, genericArguments);
                }

                // Call method
                instructions.Add(new Instruction(
                                     calledMethod.IsVirtual ? OpCodes.Callvirt : OpCodes.Call,
                                     calledMethodSig));

                instructions.Add(new Instruction(OpCodes.Ret));

                methodBody.Build(method);
            }

            // Add override.
            method.Overrides.Add(overridenMethod.ToReference(type.Module));
        }
        /// <summary>
        /// static InitializeMethodPointers() : [mscorlib]System.Void
        /// </summary>
        private void GenerateInitializeMethod()
        {
            var method = _mainType.Methods.Add();

            method.Name        = "InitializeMethodPointers";
            method.Visibility  = MethodVisibilityFlags.Assembly;
            method.IsStatic    = true;
            method.IsHideBySig = true;

            // Return type
            {
                var returnType = method.ReturnType;
                returnType.Type =
                    TypeReference.GetPrimitiveType(PrimitiveTypeCode.Void, _module.Assembly);
            }

            // Body
            {
                var methodBody = new MethodBody();
                methodBody.MaxStackSize = 7;
                methodBody.InitLocals   = true;

                // Local variables
                {
                    var localVariables = methodBody.LocalVariables;
                    localVariables.Add(
                        new TypeReference("Module", "System.Reflection",
                                          AssemblyReference.GetMscorlib(_module.Assembly), false));
                    localVariables.Add(
                        TypeReference.GetPrimitiveType(PrimitiveTypeCode.Int32, _module.Assembly));
                    localVariables.Add(
                        new ArrayType(
                            TypeReference.GetPrimitiveType(PrimitiveTypeCode.UInt8, _module.Assembly)));
                    localVariables.Add(
                        new ArrayType(
                            TypeReference.GetPrimitiveType(PrimitiveTypeCode.Type, _module.Assembly)));
                    localVariables.Add(
                        TypeReference.GetPrimitiveType(PrimitiveTypeCode.Int32, _module.Assembly));
                    localVariables.Add(
                        TypeReference.GetPrimitiveType(PrimitiveTypeCode.Int32, _module.Assembly));
                    localVariables.Add(
                        TypeReference.GetPrimitiveType(PrimitiveTypeCode.Object, _module.Assembly));
                    localVariables.Add(
                        new TypeReference("RuntimeMethodHandle", "System",
                                          AssemblyReference.GetMscorlib(_module.Assembly), true));
                }

                // Exception handlers
                {
                    var exceptionHandlers = methodBody.ExceptionHandlers;
                    exceptionHandlers.Add(
                        new ExceptionHandler(
                            ExceptionHandlerType.Finally,
                            44, 64, 108, 8, 0));
                }

                // Instructions
                {
                    var instructions = methodBody.Instructions;
                    instructions.Add(new Instruction(OpCodes.Ldtoken,
                                                     new TypeReference(_mainType.Name, _mainType.Namespace, false)));
                    instructions.Add(new Instruction(OpCodes.Call,
                                                     new MethodReference(
                                                         "GetTypeFromHandle",
                                                         TypeReference.GetPrimitiveType(PrimitiveTypeCode.Type, _module.Assembly),
                                                         new CallSite(
                                                             false,
                                                             false,
                                                             MethodCallingConvention.Default,
                                                             TypeReference.GetPrimitiveType(PrimitiveTypeCode.Type, _module.Assembly),
                                                             new TypeSignature[]
                    {
                        new TypeReference("RuntimeTypeHandle", "System",
                                          AssemblyReference.GetMscorlib(_module.Assembly), true),
                    },
                                                             -1,
                                                             0))));
                    instructions.Add(new Instruction(OpCodes.Callvirt,
                                                     new MethodReference(
                                                         "get_Module",
                                                         TypeReference.GetPrimitiveType(PrimitiveTypeCode.Type, _module.Assembly),
                                                         new CallSite(
                                                             true,
                                                             false,
                                                             MethodCallingConvention.Default,
                                                             new TypeReference("Module", "System.Reflection",
                                                                               AssemblyReference.GetMscorlib(_module.Assembly), false),
                                                             new TypeSignature[0],
                                                             -1,
                                                             0))));
                    instructions.Add(new Instruction(OpCodes.Stloc_0));
                    instructions.Add(new Instruction(OpCodes.Ldc_I4, (int)_signatures.Length));
                    instructions.Add(new Instruction(OpCodes.Stloc_1));
                    instructions.Add(new Instruction(OpCodes.Ldloc_1));
                    instructions.Add(new Instruction(OpCodes.Ldc_I4_4));
                    instructions.Add(new Instruction(OpCodes.Mul));
                    instructions.Add(new Instruction(OpCodes.Newarr,
                                                     TypeReference.GetPrimitiveType(PrimitiveTypeCode.UInt8, _module.Assembly)));
                    instructions.Add(new Instruction(OpCodes.Stloc_2));
                    instructions.Add(new Instruction(OpCodes.Ldsfld,
                                                     new FieldReference(
                                                         "_dataLockObject",
                                                         TypeReference.GetPrimitiveType(PrimitiveTypeCode.Object, _module.Assembly),
                                                         new TypeReference(_mainType.Name, _mainType.Namespace, false))));
                    instructions.Add(new Instruction(OpCodes.Dup));
                    instructions.Add(new Instruction(OpCodes.Stloc_S, (byte)6));
                    instructions.Add(new Instruction(OpCodes.Call,
                                                     new MethodReference(
                                                         "Enter",
                                                         new TypeReference("Monitor", "System.Threading",
                                                                           AssemblyReference.GetMscorlib(_module.Assembly), false),
                                                         new CallSite(
                                                             false,
                                                             false,
                                                             MethodCallingConvention.Default,
                                                             TypeReference.GetPrimitiveType(PrimitiveTypeCode.Void, _module.Assembly),
                                                             new TypeSignature[]
                    {
                        TypeReference.GetPrimitiveType(PrimitiveTypeCode.Object, _module.Assembly),
                    },
                                                             -1,
                                                             0))));
                    instructions.Add(new Instruction(OpCodes.Ldtoken,
                                                     new TypeReference(_mainType.Name, _mainType.Namespace, false)));
                    instructions.Add(new Instruction(OpCodes.Call,
                                                     new MethodReference(
                                                         "GetTypeFromHandle",
                                                         TypeReference.GetPrimitiveType(PrimitiveTypeCode.Type, _module.Assembly),
                                                         new CallSite(
                                                             false,
                                                             false,
                                                             MethodCallingConvention.Default,
                                                             TypeReference.GetPrimitiveType(PrimitiveTypeCode.Type, _module.Assembly),
                                                             new TypeSignature[]
                    {
                        new TypeReference("RuntimeTypeHandle", "System",
                                          AssemblyReference.GetMscorlib(_module.Assembly), true),
                    },
                                                             -1,
                                                             0))));
                    instructions.Add(new Instruction(OpCodes.Callvirt,
                                                     new MethodReference(
                                                         "get_Assembly",
                                                         TypeReference.GetPrimitiveType(PrimitiveTypeCode.Type, _module.Assembly),
                                                         new CallSite(
                                                             true,
                                                             false,
                                                             MethodCallingConvention.Default,
                                                             new TypeReference("Assembly", "System.Reflection",
                                                                               AssemblyReference.GetMscorlib(_module.Assembly), false),
                                                             new TypeSignature[0],
                                                             -1,
                                                             0))));
                    instructions.Add(new Instruction(OpCodes.Ldstr, _resourceStorage.ResourceName));
                    instructions.Add(new Instruction(OpCodes.Callvirt,
                                                     new MethodReference(
                                                         "GetManifestResourceStream",
                                                         new TypeReference("Assembly", "System.Reflection",
                                                                           AssemblyReference.GetMscorlib(_module.Assembly), false),
                                                         new CallSite(
                                                             true,
                                                             false,
                                                             MethodCallingConvention.Default,
                                                             new TypeReference("Stream", "System.IO",
                                                                               AssemblyReference.GetMscorlib(_module.Assembly), false),
                                                             new TypeSignature[]
                    {
                        TypeReference.GetPrimitiveType(PrimitiveTypeCode.String, _module.Assembly),
                    },
                                                             -1,
                                                             0))));
                    instructions.Add(new Instruction(OpCodes.Stsfld,
                                                     new FieldReference(
                                                         "_dataStream",
                                                         new TypeReference("Stream", "System.IO",
                                                                           AssemblyReference.GetMscorlib(_module.Assembly), false),
                                                         new TypeReference(_mainType.Name, _mainType.Namespace, false))));
                    instructions.Add(new Instruction(OpCodes.Ldsfld,
                                                     new FieldReference(
                                                         "_dataStream",
                                                         new TypeReference("Stream", "System.IO",
                                                                           AssemblyReference.GetMscorlib(_module.Assembly), false),
                                                         new TypeReference(_mainType.Name, _mainType.Namespace, false))));
                    instructions.Add(new Instruction(OpCodes.Ldc_I4, (int)_dataOffset));
                    instructions.Add(new Instruction(OpCodes.Conv_I8));
                    instructions.Add(new Instruction(OpCodes.Callvirt,
                                                     new MethodReference(
                                                         "set_Position",
                                                         new TypeReference("Stream", "System.IO",
                                                                           AssemblyReference.GetMscorlib(_module.Assembly), false),
                                                         new CallSite(
                                                             true,
                                                             false,
                                                             MethodCallingConvention.Default,
                                                             TypeReference.GetPrimitiveType(PrimitiveTypeCode.Void, _module.Assembly),
                                                             new TypeSignature[]
                    {
                        TypeReference.GetPrimitiveType(PrimitiveTypeCode.Int64, _module.Assembly),
                    },
                                                             -1,
                                                             0))));
                    instructions.Add(new Instruction(OpCodes.Ldsfld,
                                                     new FieldReference(
                                                         "_dataStream",
                                                         new TypeReference("Stream", "System.IO",
                                                                           AssemblyReference.GetMscorlib(_module.Assembly), false),
                                                         new TypeReference(_mainType.Name, _mainType.Namespace, false))));
                    instructions.Add(new Instruction(OpCodes.Ldloc_2));
                    instructions.Add(new Instruction(OpCodes.Ldc_I4_0));
                    instructions.Add(new Instruction(OpCodes.Ldloc_2));
                    instructions.Add(new Instruction(OpCodes.Ldlen));
                    instructions.Add(new Instruction(OpCodes.Conv_I4));
                    instructions.Add(new Instruction(OpCodes.Callvirt,
                                                     new MethodReference(
                                                         "Read",
                                                         new TypeReference("Stream", "System.IO",
                                                                           AssemblyReference.GetMscorlib(_module.Assembly), false),
                                                         new CallSite(
                                                             true,
                                                             false,
                                                             MethodCallingConvention.Default,
                                                             TypeReference.GetPrimitiveType(PrimitiveTypeCode.Int32, _module.Assembly),
                                                             new TypeSignature[]
                    {
                        new ArrayType(
                            TypeReference.GetPrimitiveType(PrimitiveTypeCode.UInt8, _module.Assembly)),
                        TypeReference.GetPrimitiveType(PrimitiveTypeCode.Int32, _module.Assembly),
                        TypeReference.GetPrimitiveType(PrimitiveTypeCode.Int32, _module.Assembly),
                    },
                                                             -1,
                                                             0))));
                    instructions.Add(new Instruction(OpCodes.Pop));
                    instructions.Add(new Instruction(OpCodes.Leave_S, (sbyte)8));
                    instructions.Add(new Instruction(OpCodes.Ldloc_S, (byte)6));
                    instructions.Add(new Instruction(OpCodes.Call,
                                                     new MethodReference(
                                                         "Exit",
                                                         new TypeReference("Monitor", "System.Threading",
                                                                           AssemblyReference.GetMscorlib(_module.Assembly), false),
                                                         new CallSite(
                                                             false,
                                                             false,
                                                             MethodCallingConvention.Default,
                                                             TypeReference.GetPrimitiveType(PrimitiveTypeCode.Void, _module.Assembly),
                                                             new TypeSignature[]
                    {
                        TypeReference.GetPrimitiveType(PrimitiveTypeCode.Object, _module.Assembly),
                    },
                                                             -1,
                                                             0))));
                    instructions.Add(new Instruction(OpCodes.Endfinally));
                    instructions.Add(new Instruction(OpCodes.Ldloc_1));
                    instructions.Add(new Instruction(OpCodes.Newarr,
                                                     TypeReference.GetPrimitiveType(PrimitiveTypeCode.IntPtr, _module.Assembly)));
                    instructions.Add(new Instruction(OpCodes.Stsfld,
                                                     new FieldReference(
                                                         "MethodPointers",
                                                         new ArrayType(
                                                             TypeReference.GetPrimitiveType(PrimitiveTypeCode.IntPtr, _module.Assembly)),
                                                         new TypeReference(_mainType.Name, _mainType.Namespace, false))));
                    instructions.Add(new Instruction(OpCodes.Ldsfld,
                                                     new FieldReference(
                                                         "EmptyTypes",
                                                         new ArrayType(
                                                             TypeReference.GetPrimitiveType(PrimitiveTypeCode.Type, _module.Assembly)),
                                                         TypeReference.GetPrimitiveType(PrimitiveTypeCode.Type, _module.Assembly))));
                    instructions.Add(new Instruction(OpCodes.Stloc_3));
                    instructions.Add(new Instruction(OpCodes.Ldc_I4_0));
                    instructions.Add(new Instruction(OpCodes.Stloc_S, (byte)4));
                    instructions.Add(new Instruction(OpCodes.Ldc_I4_0));
                    instructions.Add(new Instruction(OpCodes.Stloc_S, (byte)5));
                    instructions.Add(new Instruction(OpCodes.Br_S, (sbyte)92));
                    instructions.Add(new Instruction(OpCodes.Ldsfld,
                                                     new FieldReference(
                                                         "MethodPointers",
                                                         new ArrayType(
                                                             TypeReference.GetPrimitiveType(PrimitiveTypeCode.IntPtr, _module.Assembly)),
                                                         new TypeReference(_mainType.Name, _mainType.Namespace, false))));
                    instructions.Add(new Instruction(OpCodes.Ldloc_S, (byte)5));
                    instructions.Add(new Instruction(OpCodes.Ldelema,
                                                     TypeReference.GetPrimitiveType(PrimitiveTypeCode.IntPtr, _module.Assembly)));
                    instructions.Add(new Instruction(OpCodes.Ldloc_0));
                    instructions.Add(new Instruction(OpCodes.Ldloc_2));
                    instructions.Add(new Instruction(OpCodes.Ldloc_S, (byte)4));
                    instructions.Add(new Instruction(OpCodes.Dup));
                    instructions.Add(new Instruction(OpCodes.Ldc_I4_1));
                    instructions.Add(new Instruction(OpCodes.Add));
                    instructions.Add(new Instruction(OpCodes.Stloc_S, (byte)4));
                    instructions.Add(new Instruction(OpCodes.Ldelem_U1));
                    instructions.Add(new Instruction(OpCodes.Ldloc_2));
                    instructions.Add(new Instruction(OpCodes.Ldloc_S, (byte)4));
                    instructions.Add(new Instruction(OpCodes.Dup));
                    instructions.Add(new Instruction(OpCodes.Ldc_I4_1));
                    instructions.Add(new Instruction(OpCodes.Add));
                    instructions.Add(new Instruction(OpCodes.Stloc_S, (byte)4));
                    instructions.Add(new Instruction(OpCodes.Ldelem_U1));
                    instructions.Add(new Instruction(OpCodes.Ldc_I4_8));
                    instructions.Add(new Instruction(OpCodes.Shl));
                    instructions.Add(new Instruction(OpCodes.Or));
                    instructions.Add(new Instruction(OpCodes.Ldloc_2));
                    instructions.Add(new Instruction(OpCodes.Ldloc_S, (byte)4));
                    instructions.Add(new Instruction(OpCodes.Dup));
                    instructions.Add(new Instruction(OpCodes.Ldc_I4_1));
                    instructions.Add(new Instruction(OpCodes.Add));
                    instructions.Add(new Instruction(OpCodes.Stloc_S, (byte)4));
                    instructions.Add(new Instruction(OpCodes.Ldelem_U1));
                    instructions.Add(new Instruction(OpCodes.Ldc_I4_S, (byte)16));
                    instructions.Add(new Instruction(OpCodes.Shl));
                    instructions.Add(new Instruction(OpCodes.Or));
                    instructions.Add(new Instruction(OpCodes.Ldloc_2));
                    instructions.Add(new Instruction(OpCodes.Ldloc_S, (byte)4));
                    instructions.Add(new Instruction(OpCodes.Dup));
                    instructions.Add(new Instruction(OpCodes.Ldc_I4_1));
                    instructions.Add(new Instruction(OpCodes.Add));
                    instructions.Add(new Instruction(OpCodes.Stloc_S, (byte)4));
                    instructions.Add(new Instruction(OpCodes.Ldelem_U1));
                    instructions.Add(new Instruction(OpCodes.Ldc_I4_S, (byte)24));
                    instructions.Add(new Instruction(OpCodes.Shl));
                    instructions.Add(new Instruction(OpCodes.Or));
                    instructions.Add(new Instruction(OpCodes.Ldloc_3));
                    instructions.Add(new Instruction(OpCodes.Ldloc_3));
                    instructions.Add(new Instruction(OpCodes.Callvirt,
                                                     new MethodReference(
                                                         "ResolveMethod",
                                                         new TypeReference("Module", "System.Reflection",
                                                                           AssemblyReference.GetMscorlib(_module.Assembly), false),
                                                         new CallSite(
                                                             true,
                                                             false,
                                                             MethodCallingConvention.Default,
                                                             new TypeReference("MethodBase", "System.Reflection",
                                                                               AssemblyReference.GetMscorlib(_module.Assembly), false),
                                                             new TypeSignature[]
                    {
                        TypeReference.GetPrimitiveType(PrimitiveTypeCode.Int32, _module.Assembly),
                        new ArrayType(
                            TypeReference.GetPrimitiveType(PrimitiveTypeCode.Type, _module.Assembly)),
                        new ArrayType(
                            TypeReference.GetPrimitiveType(PrimitiveTypeCode.Type, _module.Assembly)),
                    },
                                                             -1,
                                                             0))));
                    instructions.Add(new Instruction(OpCodes.Callvirt,
                                                     new MethodReference(
                                                         "get_MethodHandle",
                                                         new TypeReference("MethodBase", "System.Reflection",
                                                                           AssemblyReference.GetMscorlib(_module.Assembly), false),
                                                         new CallSite(
                                                             true,
                                                             false,
                                                             MethodCallingConvention.Default,
                                                             new TypeReference("RuntimeMethodHandle", "System",
                                                                               AssemblyReference.GetMscorlib(_module.Assembly), true),
                                                             new TypeSignature[0],
                                                             -1,
                                                             0))));
                    instructions.Add(new Instruction(OpCodes.Stloc_S, (byte)7));
                    instructions.Add(new Instruction(OpCodes.Ldloca_S, (byte)7));
                    instructions.Add(new Instruction(OpCodes.Call,
                                                     new MethodReference(
                                                         "GetFunctionPointer",
                                                         new TypeReference("RuntimeMethodHandle", "System",
                                                                           AssemblyReference.GetMscorlib(_module.Assembly), true),
                                                         new CallSite(
                                                             true,
                                                             false,
                                                             MethodCallingConvention.Default,
                                                             TypeReference.GetPrimitiveType(PrimitiveTypeCode.IntPtr, _module.Assembly),
                                                             new TypeSignature[0],
                                                             -1,
                                                             0))));
                    instructions.Add(new Instruction(OpCodes.Stobj,
                                                     TypeReference.GetPrimitiveType(PrimitiveTypeCode.IntPtr, _module.Assembly)));
                    instructions.Add(new Instruction(OpCodes.Ldloc_S, (byte)5));
                    instructions.Add(new Instruction(OpCodes.Ldc_I4_1));
                    instructions.Add(new Instruction(OpCodes.Add));
                    instructions.Add(new Instruction(OpCodes.Stloc_S, (byte)5));
                    instructions.Add(new Instruction(OpCodes.Ldloc_S, (byte)5));
                    instructions.Add(new Instruction(OpCodes.Ldloc_1));
                    instructions.Add(new Instruction(OpCodes.Blt_S, (sbyte)-97));
                    instructions.Add(new Instruction(OpCodes.Ret));
                }

                methodBody.Build(method);
            }
        }