/// <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> /// 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); }
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); }