/// <summary> /// Creates a CIL method body from a dynamic method. /// </summary> /// <param name="method">The method that owns the method body.</param> /// <param name="dynamicMethodObj">The Dynamic Method/Delegate/DynamicResolver.</param> /// <param name="operandResolver"> /// The object instance to use for resolving operands of an instruction in the /// method body. /// </param> /// <param name="importer"> /// The object instance to use for importing operands of an instruction in the /// method body. /// </param> /// <returns>The method body.</returns> public static CilMethodBody FromDynamicMethod( MethodDefinition method, object dynamicMethodObj, ICilOperandResolver operandResolver = null, ReferenceImporter importer = null) { if (!(method.Module is SerializedModuleDefinition module)) { throw new ArgumentException("Method body should reference a serialized module."); } var result = new CilMethodBody(method); operandResolver ??= new CilOperandResolver(method.Module, result); importer ??= new ReferenceImporter(method.Module); dynamicMethodObj = DynamicMethodHelper.ResolveDynamicResolver(dynamicMethodObj); //Get Runtime Fields var code = FieldReader.ReadField <byte[]>(dynamicMethodObj, "m_code"); var scope = FieldReader.ReadField <object>(dynamicMethodObj, "m_scope"); var tokenList = FieldReader.ReadField <List <object> >(scope, "m_tokens"); var localSig = FieldReader.ReadField <byte[]>(dynamicMethodObj, "m_localSignature"); var ehHeader = FieldReader.ReadField <byte[]>(dynamicMethodObj, "m_exceptionHeader"); var ehInfos = FieldReader.ReadField <IList <object> >(dynamicMethodObj, "m_exceptions"); // Read raw instructions. var reader = new ByteArrayReader(code); var disassembler = new CilDisassembler(reader); result.Instructions.AddRange(disassembler.ReadAllInstructions()); //Local Variables DynamicMethodHelper.ReadLocalVariables(result, method, localSig); //Exception Handlers DynamicMethodHelper.ReadReflectionExceptionHandlers(result, ehInfos, ehHeader, importer); // Resolve all operands. foreach (var instruction in result.Instructions) { instruction.Operand = DynamicMethodHelper.ResolveOperandReflection(module.ReaderContext, result, instruction, operandResolver, tokenList, importer) ?? instruction.Operand; } return(result); }
/// <inheritdoc /> public override object ResolveMember(MetadataToken token) { switch (token.Table) { case TableIndex.TypeDef: var type = _tokens[(int)token.Rid]; if (type is RuntimeTypeHandle runtimeTypeHandle) { return(_importer.ImportType(Type.GetTypeFromHandle(runtimeTypeHandle))); } break; case TableIndex.Field: var field = _tokens[(int)token.Rid]; if (field is null) { return(null); } if (field is RuntimeFieldHandle runtimeFieldHandle) { return(_importer.ImportField(FieldInfo.GetFieldFromHandle(runtimeFieldHandle))); } if (field.GetType().FullName == "System.Reflection.Emit.GenericFieldInfo") { bool result = FieldReader.TryReadField <RuntimeFieldHandle>(field, "m_field", out var mField); var ctx = FieldReader.ReadField <RuntimeTypeHandle>(field, "m_context"); return(_importer.ImportField(FieldInfo.GetFieldFromHandle(result ? mField : FieldReader.ReadField <RuntimeFieldHandle>(field, "m_fieldHandle"), ctx))); } break; case TableIndex.Method: case TableIndex.MemberRef: var obj = _tokens[(int)token.Rid]; if (obj is RuntimeMethodHandle methodHandle) { return(_importer.ImportMethod(MethodBase.GetMethodFromHandle(methodHandle))); } if (obj.GetType().FullName == "System.Reflection.Emit.GenericMethodInfo") { var context = FieldReader.ReadField <RuntimeTypeHandle>(obj, "m_context"); bool hasHandle = FieldReader.TryReadField <RuntimeMethodHandle>(obj, "m_method", out var mMethod); var mHandle = FieldReader.ReadField <RuntimeMethodHandle>(obj, "m_methodHandle"); var method = MethodBase.GetMethodFromHandle( hasHandle ? mMethod : mHandle, context); return(_importer.ImportMethod(method)); } if (obj.GetType().FullName == "System.Reflection.Emit.VarArgMethod") { return(_importer.ImportMethod(FieldReader.ReadField <MethodInfo>(obj, "m_method"))); } break; case TableIndex.StandAloneSig: var reader = ByteArrayDataSource.CreateReader((byte[])_tokens[(int)token.Rid]); return(CallingConventionSignature.FromReader(new BlobReadContext(_readerContext), ref reader)); } return(token); }