/// <summary> /// Adds a prolog to the given method body. /// </summary> /// <param name="IL">The <see cref="CilWorker"/> that points to the given method body.</param> public void AddProlog(CilWorker IL) { MethodDefinition method = IL.GetMethod(); _surroundingImplementation = method.AddLocal <IAroundInvoke>(); _surroundingClassImplementation = method.AddLocal <IAroundInvoke>(); Instruction skipProlog = IL.Create(OpCodes.Nop); TypeDefinition declaringType = method.DeclaringType; ModuleDefinition module = declaringType.Module; TypeReference modifiableType = module.ImportType <IModifiableType>(); if (method.HasThis) { IL.Emit(OpCodes.Ldarg_0); IL.Emit(OpCodes.Isinst, modifiableType); IL.Emit(OpCodes.Brfalse, skipProlog); } IL.Emit(OpCodes.Ldloc, _interceptionDisabled); IL.Emit(OpCodes.Brtrue, skipProlog); // var provider = this.MethodReplacementProvider; if (_getMethodReplacementProvider != null) { _getMethodReplacementProvider.Emit(IL); } var getAroundInvokeProvider = new GetAroundInvokeProvider(_aroundInvokeProvider, _providerName); getAroundInvokeProvider.Emit(IL); // if (aroundInvokeProvider != null ) { Instruction skipGetSurroundingImplementation = IL.Create(OpCodes.Nop); var getSurroundingImplementationInstance = new GetSurroundingImplementationInstance(_aroundInvokeProvider, _invocationInfo, _surroundingImplementation, skipGetSurroundingImplementation); getSurroundingImplementationInstance.Emit(IL); // } IL.Append(skipGetSurroundingImplementation); var emitBeforeInvoke = new EmitBeforeInvoke(_invocationInfo, _surroundingClassImplementation, _surroundingImplementation, _registryType); emitBeforeInvoke.Emit(IL); IL.Append(skipProlog); }
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); }