/// <summary>
        /// Saves the current <see cref="IExceptionHandlerInfo"/> instance.
        /// </summary>
        /// <param name="targetMethod">The target method.</param>
        /// <param name="emitter">The <see cref="IEmitInvocationInfo"/> instance that will emit the current method context.</param>
        private void SaveExceptionInfo(MethodDefinition targetMethod, IEmitInvocationInfo emitter)
        {
            var IL     = targetMethod.GetILGenerator();
            var module = IL.GetModule();

            emitter.Emit(targetMethod, targetMethod, _invocationInfo);
            IL.Emit(OpCodes.Ldloc, _exception);
            IL.Emit(OpCodes.Ldloc, _invocationInfo);

            var exceptionInfoConstructor = module.ImportConstructor <ExceptionHandlerInfo>(
                typeof(Exception),
                typeof(IInvocationInfo));

            IL.Emit(OpCodes.Newobj, exceptionInfoConstructor);
            IL.Emit(OpCodes.Stloc, _exceptionInfo);

            var returnType = targetMethod.ReturnType.ReturnType;

            if (returnType == _voidType || _returnValue == null)
            {
                return;
            }

            // exceptionInfo.ReturnValue = returnValue;
            var setReturnValue = module.ImportMethod <IExceptionHandlerInfo>("set_ReturnValue");

            IL.Emit(OpCodes.Ldloc, _exceptionInfo);
            IL.Emit(OpCodes.Ldloc, _returnValue);
            IL.Emit(OpCodes.Callvirt, setReturnValue);
        }
Beispiel #2
0
        /// <summary>
        /// Emits the IL instructions that will store information about the method <paramref name="targetMethod">currently being executed</paramref>
        /// and stores the results into the <paramref name="invocationInfo">variable.</paramref>
        /// </summary>
        /// <param name="emitter">The <see cref="IEmitInvocationInfo"/> instance.</param>
        /// <param name="method">The method whose implementation will be intercepted.</param>
        /// <param name="targetMethod">The actual method that will contain the resulting instructions.</param>
        /// <param name="invocationInfo">The <see cref="VariableDefinition">local variable</see> that will store the current <see cref="IInvocationInfo"/> instance.</param>
        public static void Emit(this IEmitInvocationInfo emitter, MethodInfo method, MethodDefinition targetMethod, VariableDefinition invocationInfo)
        {
            var module            = targetMethod.DeclaringType.Module;
            var interceptedMethod = module.Import(method);

            emitter.Emit(targetMethod, interceptedMethod, invocationInfo);
        }
Beispiel #3
0
        public void Rewrite(MethodDefinition method, CilWorker IL,
                            IEnumerable <Instruction> oldInstructions)
        {
            var targetMethod = _parameters.TargetMethod;
            var worker       = targetMethod.GetILGenerator();
            var module       = worker.GetModule();

            _getInterceptionDisabled.Emit(worker);

            // Construct the InvocationInfo instance
            var skipInvocationInfo = worker.Create(OpCodes.Nop);

            worker.Emit(OpCodes.Ldloc, _parameters.InterceptionDisabled);
            worker.Emit(OpCodes.Brtrue, skipInvocationInfo);


            var interceptedMethod = targetMethod;

            _emitter.Emit(targetMethod, interceptedMethod, _parameters.InvocationInfo);


            var skipGetReplacementProvider = IL.Create(OpCodes.Nop);

            // var provider = this.MethodReplacementProvider;
            //IL.Emit(OpCodes.Ldloc, _interceptionDisabled);
            //IL.Emit(OpCodes.Brtrue, skipGetReplacementProvider);
            _getInstanceMethodReplacementProvider.Emit(IL);
            _surroundMethodBody.AddProlog(worker);
            IL.Append(skipGetReplacementProvider);

            worker.Append(skipInvocationInfo);

            _getClassMethodReplacementProvider.Emit(worker);



            var returnType = targetMethod.ReturnType.ReturnType;

            _addMethodReplacement.Emit(worker);

            // Save the return value
            TypeReference voidType = module.Import(typeof(void));

            _surroundMethodBody.AddEpilog(worker);

            if (returnType != voidType)
            {
                worker.Emit(OpCodes.Ldloc, _parameters.ReturnValue);
            }

            worker.Emit(OpCodes.Ret);
        }
        /// <summary>
        /// Saves the current <see cref="IExceptionHandlerInfo"/> instance.
        /// </summary>
        /// <param name="targetMethod">The target method.</param>
        /// <param name="emitter">The <see cref="IEmitInvocationInfo"/> instance that will emit the current method context.</param>
        private void SaveExceptionInfo(MethodDefinition targetMethod, IEmitInvocationInfo emitter)
        {
            var IL = targetMethod.GetILGenerator();
            var module = IL.GetModule();

            emitter.Emit(targetMethod, targetMethod, _invocationInfo);
            IL.Emit(OpCodes.Ldloc, _exception);
            IL.Emit(OpCodes.Ldloc, _invocationInfo);

            var exceptionInfoConstructor = module.ImportConstructor<ExceptionHandlerInfo>(
                typeof (Exception),
                typeof (IInvocationInfo));
            IL.Emit(OpCodes.Newobj, exceptionInfoConstructor);
            IL.Emit(OpCodes.Stloc, _exceptionInfo);

            var returnType = targetMethod.ReturnType.ReturnType;
            if (returnType == _voidType || _returnValue == null)
                return;

            // exceptionInfo.ReturnValue = returnValue;
            var setReturnValue = module.ImportMethod<IExceptionHandlerInfo>("set_ReturnValue");
            IL.Emit(OpCodes.Ldloc, _exceptionInfo);
            IL.Emit(OpCodes.Ldloc, _returnValue);
            IL.Emit(OpCodes.Callvirt, setReturnValue);
        }