예제 #1
0
        /// <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));
        }
예제 #2
0
        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));
        }