Represents a method body rewriter that surrounds a method body with the necessary prolog and epilogs that enable method body interception.
Inheritance: IMethodBodyRewriter
示例#1
0
        /// <summary>
        /// Rewrites the instructions in the target method body.
        /// </summary>
        /// <param name="method">The target method.</param>
        /// <param name="IL">The <see cref="CilWorker"/> instance that represents the method body.</param>
        /// <param name="oldInstructions">The IL instructions of the original method body.</param>
        protected override void RewriteMethodBody(MethodDefinition method, CilWorker IL,
                                                  IEnumerable <Instruction> oldInstructions)
        {
            if (IsExcluded(method))
            {
                AddOriginalInstructions(IL, oldInstructions);
                return;
            }

            VariableDefinition interceptionDisabled      = method.AddLocal <bool>();
            VariableDefinition invocationInfo            = method.AddLocal <IInvocationInfo>();
            VariableDefinition aroundInvokeProvider      = method.AddLocal <IAroundInvokeProvider>();
            VariableDefinition methodReplacementProvider = method.AddLocal <IMethodReplacementProvider>();


            VariableDefinition returnValue = method.AddLocal <object>();
            VariableDefinition classMethodReplacementProvider = method.AddLocal <IMethodReplacementProvider>();

            Func <ModuleDefinition, MethodReference> getInstanceMethodReplacementProviderMethod =
                module => module.Import(typeof(IMethodReplacementHost).GetMethod("get_MethodBodyReplacementProvider"));

            var parameters = new MethodBodyRewriterParameters(IL,
                                                              oldInstructions,
                                                              interceptionDisabled,
                                                              invocationInfo, returnValue,
                                                              methodReplacementProvider,
                                                              aroundInvokeProvider,
                                                              classMethodReplacementProvider,
                                                              getInstanceMethodReplacementProviderMethod,
                                                              typeof(AroundMethodBodyRegistry));

            var emitter = new InvocationInfoEmitter(true);

            IInstructionEmitter getMethodReplacementProvider =
                new GetMethodReplacementProvider(methodReplacementProvider, method,
                                                 getInstanceMethodReplacementProviderMethod);

            IInstructionEmitter getInterceptionDisabled           = new GetInterceptionDisabled(parameters);
            ISurroundMethodBody surroundMethodBody                = new SurroundMethodBody(parameters, "AroundMethodBodyProvider");
            IInstructionEmitter getClassMethodReplacementProvider = new GetClassMethodReplacementProvider(parameters,
                                                                                                          module =>
                                                                                                          module.Import(
                                                                                                              typeof(
                                                                                                                  MethodBodyReplacementProviderRegistry
                                                                                                                  ).
                                                                                                              GetMethod
                                                                                                                  ("GetProvider")));
            IInstructionEmitter addMethodReplacement = new AddMethodReplacementImplementation(parameters);

            var rewriter = new InterceptAndSurroundMethodBody(emitter, getInterceptionDisabled, surroundMethodBody,
                                                              getMethodReplacementProvider,
                                                              getClassMethodReplacementProvider, addMethodReplacement,
                                                              parameters);

            // Determine whether or not the method should be intercepted
            rewriter.Rewrite(method, IL, oldInstructions);
        }
示例#2
0
        /// <summary>
        /// Rewrites the instructions in the target method body.
        /// </summary>
        /// <param name="method">The target method.</param>
        /// <param name="IL">The <see cref="CilWorker"/> instance that represents the method body.</param>
        /// <param name="oldInstructions">The IL instructions of the original method body.</param>
        protected override void RewriteMethodBody(MethodDefinition method, CilWorker IL, IEnumerable<Instruction> oldInstructions)
        {
            var interceptionDisabled = method.AddLocal<bool>();
            var invocationInfo = method.AddLocal<IInvocationInfo>();
            var aroundInvokeProvider = method.AddLocal<IAroundInvokeProvider>();
            var methodReplacementProvider = method.AddLocal<IMethodReplacementProvider>();

            var returnValue = method.AddLocal<object>();
            var classMethodReplacementProvider = method.AddLocal<IMethodReplacementProvider>();

            Func<ModuleDefinition, MethodReference> getInstanceMethodReplacementProviderMethod =
                module => module.Import(typeof(IMethodReplacementHost).GetMethod("get_MethodBodyReplacementProvider"));

            var parameters = new MethodBodyRewriterParameters(IL,
                oldInstructions,
                interceptionDisabled,
                invocationInfo, returnValue,
                aroundInvokeProvider,
                methodReplacementProvider,
                classMethodReplacementProvider,
                getInstanceMethodReplacementProviderMethod,
                typeof(AroundMethodBodyRegistry));

            var emitter = new InvocationInfoEmitter(true);

            IInstructionEmitter getMethodReplacementProvider = new GetMethodReplacementProvider(methodReplacementProvider, method,
                getInstanceMethodReplacementProviderMethod);

            IInstructionEmitter getInterceptionDisabled = new GetInterceptionDisabled(parameters);
            ISurroundMethodBody surroundMethodBody = new SurroundMethodBody(parameters);
            IInstructionEmitter getClassMethodReplacementProvider = new GetClassMethodReplacementProvider(parameters, module =>
                module.Import(typeof(MethodBodyReplacementProviderRegistry).GetMethod("GetProvider")));
            IInstructionEmitter addMethodReplacement = new AddMethodReplacementImplementation(parameters);

            var rewriter = new InterceptAndSurroundMethodBody(emitter, getInterceptionDisabled, surroundMethodBody, getMethodReplacementProvider, getClassMethodReplacementProvider, addMethodReplacement, parameters);

            // Determine whether or not the method should be intercepted
            rewriter.Rewrite(method, IL, oldInstructions);
        }