Esempio n. 1
0
        private void EmitILForMethod(ILGenerator ilGenerator, Instruction instruction, MemberInfo memberInfo, bool overrideVirtual = false)
        {
            MethodInfo methodInfo = memberInfo as MethodInfo;

            if (PoseContext.StubCache.TryGetValue(methodInfo, out DynamicMethod stub))
            {
                ilGenerator.Emit(OpCodes.Ldtoken, methodInfo);
                ilGenerator.Emit(OpCodes.Ldtoken, methodInfo.DeclaringType);
                ilGenerator.Emit(OpCodes.Call, stub);
                return;
            }

            MethodBody methodBody = methodInfo.GetMethodBody();

            if (methodBody == null && !methodInfo.IsAbstract)
            {
                ilGenerator.Emit(instruction.OpCode, methodInfo);
                return;
            }

            if (instruction.OpCode == OpCodes.Call || instruction.OpCode == OpCodes.Callvirt)
            {
                stub = instruction.OpCode == OpCodes.Call || overrideVirtual?
                       Stubs.GenerateStubForMethod(methodInfo) : Stubs.GenerateStubForVirtualMethod(methodInfo);

                ilGenerator.Emit(OpCodes.Ldtoken, methodInfo);
                ilGenerator.Emit(OpCodes.Ldtoken, methodInfo.DeclaringType);
                ilGenerator.Emit(OpCodes.Call, stub);
                PoseContext.StubCache.TryAdd(methodInfo, stub);
            }
            else if (instruction.OpCode == OpCodes.Ldftn)
            {
                stub = Stubs.GenerateStubForMethodPointer(methodInfo);
                ilGenerator.Emit(OpCodes.Ldtoken, methodInfo);
                ilGenerator.Emit(OpCodes.Ldtoken, methodInfo.DeclaringType);
                ilGenerator.Emit(OpCodes.Call, stub);
                PoseContext.StubCache.TryAdd(methodInfo, stub);
            }
            else
            {
                ilGenerator.Emit(instruction.OpCode, methodInfo);
            }
        }
Esempio n. 2
0
        private void EmitILForConstructor(ILGenerator ilGenerator, Instruction instruction, MemberInfo memberInfo)
        {
            ConstructorInfo constructorInfo = memberInfo as ConstructorInfo;
            MethodBody      methodBody      = constructorInfo.GetMethodBody();

            if (methodBody == null)
            {
                ilGenerator.Emit(instruction.OpCode, constructorInfo);
                return;
            }

            if (instruction.OpCode != OpCodes.Newobj && instruction.OpCode != OpCodes.Call)
            {
                ilGenerator.Emit(instruction.OpCode, constructorInfo);
                return;
            }

            ilGenerator.Emit(OpCodes.Ldtoken, constructorInfo);
            ilGenerator.Emit(OpCodes.Ldtoken, constructorInfo.DeclaringType);
            ilGenerator.Emit(OpCodes.Call, Stubs.GenerateStubForConstructor(constructorInfo, instruction.OpCode, constructorInfo.IsForValueType()));
        }
Esempio n. 3
0
        private void EmitILForConstructor(ILGenerator ilGenerator, Instruction instruction, ConstructorInfo constructorInfo)
        {
            if (constructorInfo.InCoreLibrary())
            {
                // Don't attempt to rewrite unaccessible constructors in System.Private.CoreLib/mscorlib
                if (!constructorInfo.DeclaringType.IsPublic)
                {
                    goto forward;
                }
                if (!constructorInfo.IsPublic && !constructorInfo.IsFamily && !constructorInfo.IsFamilyOrAssembly)
                {
                    goto forward;
                }
            }

            if (instruction.OpCode == OpCodes.Call)
            {
                ilGenerator.Emit(OpCodes.Call, Stubs.GenerateStubForDirectCall(constructorInfo));
                return;
            }

            if (instruction.OpCode == OpCodes.Newobj)
            {
                ilGenerator.Emit(OpCodes.Call, Stubs.GenerateStubForObjectInitialization(constructorInfo));
                return;
            }

            if (instruction.OpCode == OpCodes.Ldftn)
            {
                ilGenerator.Emit(OpCodes.Call, Stubs.GenerateStubForDirectLoad(constructorInfo));
                return;
            }

            // If we get here, then we haven't accounted for an opcode.
            // Throw exception to make this obvious.
            throw new NotSupportedException(instruction.OpCode.Name);

forward:
            ilGenerator.Emit(instruction.OpCode, constructorInfo);
        }