/// <summary> /// Generate the code which has to be inserted at the place of the filter specified by the visitor. /// </summary> /// <param name="visitor">The visitor.</param> /// <param name="filterAction">The filter action.</param> /// <param name="originalCall">The original call.</param> public override void Weave(ICecilInliningInstructionVisitor visitor, FilterAction filterAction, MethodDefinition originalCall) { MethodReference methodToCall; // Get JoinPointContext VariableDefinition jpcVar = visitor.CreateJoinPointContextLocal(); // Get the methodReference MethodReference methodReference = (MethodReference)originalCall; TypeDefinition parentType = CecilUtilities.ResolveTypeDefinition(visitor.Method.DeclaringType); // Get method to call methodToCall = GetMethodToCall(visitor, filterAction, parentType); if (methodToCall == null) { throw new ILWeaverException(String.Format(CultureInfo.CurrentCulture, Properties.Resources.AdviceMethodNotFound, getSelector(filterAction), getTarget(filterAction))); } // Set JoinPointContext WeaveStrategyUtilities.SetJoinPointContext(visitor, methodReference, filterAction); // Check if it is an innercall and set innercall context: if (getTarget(filterAction).Equals(FilterAction.InnerTarget)) { WeaveStrategyUtilities.SetInnerCall(visitor, methodToCall); } // Do the advice-call AdviceActionWeaveStrategy.CallAdvice(visitor, filterAction, parentType, methodToCall, jpcVar); // Add nop to enable debugging visitor.Instructions.Add(visitor.Worker.Create(OpCodes.Nop)); }
public override void Weave(ICecilInliningInstructionVisitor visitor, FilterAction filterAction, MethodDefinition originalCall) { // The method we have to call, an Execute(JoinPointContext) function. MethodReference methodToCall; // Create FilterAction object: FilterActionElement filterActionElement; filterActionElement = DefaultWeaveStrategy.GetFilterActionElement(visitor.WeaveConfiguration.FilterActions, filterAction.FullName); if (filterActionElement == null) { throw new ILWeaverException(string.Format(CultureInfo.CurrentCulture, Properties.Resources.CouldNotResolveFilterAction, filterAction.FullName)); } // Get JoinPointContext VariableDefinition jpcVar = null; if (filterActionElement.CreateJPC) { jpcVar = visitor.CreateJoinPointContextLocal(); } // Get the methodReference MethodReference methodReference = (MethodReference)originalCall; // TypeDefinition parentType = CecilUtilities.ResolveTypeDefinition(methodReference.DeclaringType); // Set JoinPointContext if (filterActionElement.CreateJPC) { WeaveStrategyUtilities.SetJoinPointContext(visitor, methodReference, filterAction); } TypeReference typeRef = CecilUtilities.ResolveType(filterAction.FullName, filterActionElement.Assembly, null); TypeDefinition typeDef = CecilUtilities.ResolveTypeDefinition(typeRef); MethodReference constructor = typeDef.Constructors.GetConstructor(false, new Type[0]); if (constructor == null) { throw new ILWeaverException(String.Format(CultureInfo.CurrentCulture, Properties.Resources.TypeNotFound, filterAction.FullName)); } constructor = visitor.TargetAssemblyDefinition.MainModule.Import(constructor); visitor.Instructions.Add(visitor.Worker.Create(OpCodes.Newobj, constructor)); // Get method to call methodToCall = CecilUtilities.ResolveMethod(typeDef, "Execute", new Type[] { typeof(JoinPointContext) }); // Check for null value if (methodToCall == null) { throw new ILWeaverException(String.Format(CultureInfo.CurrentCulture, Properties.Resources.AdviceMethodNotFound, "Execute", filterAction.FullName)); } methodToCall = visitor.TargetAssemblyDefinition.MainModule.Import(methodToCall); // Load the JoinPointObject as the parameter if required if (filterActionElement.CreateJPC) { visitor.Instructions.Add(visitor.Worker.Create(OpCodes.Ldloc, jpcVar)); } else { visitor.Instructions.Add(visitor.Worker.Create(OpCodes.Ldnull)); } // Do the call // We can safely emit a callvirt here. The JITter will make the right call. visitor.Instructions.Add(visitor.Worker.Create(OpCodes.Callvirt, methodToCall)); }