Example #1
0
        /// <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);
        }