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); } }
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())); }
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); }