/// <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); }
/// <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); }
/// <summary> /// Initializes a new instance of the <see cref="InterceptAndSurroundMethodBody"/> class. /// </summary> /// <param name="emitter">The emitter that will instantiate the <see cref="IInvocationInfo"/> instance.</param> /// <param name="getInterceptionDisabled">The emitter that will determine whether or not method interception is enabled.</param> /// <param name="surroundMethodBody">The <see cref="ISurroundMethodBody"/> instance that will add the epilogs and prologs to the method body.</param> /// <param name="getInstanceMethodReplacementProvider">The emitter that will obtain the method replacement provider instance.</param> /// <param name="getClassMethodReplacementProvider">The emitter that will obtain the class-level method replacement provider instance.</param> /// <param name="addMethodReplacement">The instruction emitter that will add the call to obtain the method body replacement instance. </param> /// <param name="parameters">The parameters that describe the context of the method body rewrite.</param> public InterceptAndSurroundMethodBody(IEmitInvocationInfo emitter, IInstructionEmitter getInterceptionDisabled, ISurroundMethodBody surroundMethodBody, IInstructionEmitter getInstanceMethodReplacementProvider, IInstructionEmitter getClassMethodReplacementProvider, IInstructionEmitter addMethodReplacement, IMethodBodyRewriterParameters parameters) { _getInterceptionDisabled = getInterceptionDisabled; _surroundMethodBody = surroundMethodBody; _getInstanceMethodReplacementProvider = getInstanceMethodReplacementProvider; _getClassMethodReplacementProvider = getClassMethodReplacementProvider; _addMethodReplacement = addMethodReplacement; _parameters = parameters; _emitter = emitter; _interceptionDisabled = parameters.InterceptionDisabled; }
/// <summary> /// Initializes a new instance of the <see cref="InterceptAndSurroundMethodBody"/> class. /// </summary> /// <param name="emitter">The emitter that will instantiate the <see cref="IInvocationInfo"/> instance.</param> /// <param name="getInterceptionDisabled">The emitter that will determine whether or not method interception is enabled.</param> /// <param name="surroundMethodBody">The <see cref="ISurroundMethodBody"/> instance that will add the epilogs and prologs to the method body.</param> /// <param name="getInstanceMethodReplacementProvider">The emitter that will obtain the method replacement provider instance.</param> /// <param name="getClassMethodReplacementProvider">The emitter that will obtain the class-level method replacement provider instance.</param> /// <param name="addMethodReplacement">The instruction emitter that will add the call to obtain the method body replacement instance. </param> /// <param name="parameters">The parameters that describe the context of the method body rewrite.</param> public InterceptAndSurroundMethodBody(IEmitInvocationInfo emitter, IInstructionEmitter getInterceptionDisabled, ISurroundMethodBody surroundMethodBody, IInstructionEmitter getInstanceMethodReplacementProvider, IInstructionEmitter getClassMethodReplacementProvider, IInstructionEmitter addMethodReplacement, IMethodBodyRewriterParameters parameters) { _getInterceptionDisabled = getInterceptionDisabled; _surroundMethodBody = surroundMethodBody; _getInstanceMethodReplacementProvider = getInstanceMethodReplacementProvider; _getClassMethodReplacementProvider = getClassMethodReplacementProvider; _addMethodReplacement = addMethodReplacement; _parameters = parameters; _emitter = emitter; _interceptionDisabled = parameters.InterceptionDisabled; }
/// <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); }
/// <summary> /// Initializes the MethodBodyEmitter class. /// </summary> /// <param name="source"></param> public void Initialize(IServiceContainer source) { InvocationInfoEmitter = (IEmitInvocationInfo)source.GetService(typeof(IEmitInvocationInfo)); }
/// <summary> /// Initializes the MethodBodyEmitter class. /// </summary> /// <param name="source"></param> public void Initialize(IServiceContainer source) { InvocationInfoEmitter = (IEmitInvocationInfo) source.GetService(typeof (IEmitInvocationInfo)); }