Пример #1
0
        public void Cleanup()
        {
            foreach (DictionaryEntry entry in m_InterceptorsToWeave)
            {
                MethodDefinition containerMethod = entry.Key as MethodDefinition;
                TypeDefinition   containerType   = (TypeDefinition)containerMethod.DeclaringType;

                // Methods can be removed. In that case, they don't have a declaring type any more
                if (containerType != null)
                {
                    // Clone and rename the target method
                    MethodDefinition targetMethod = containerMethod.Clone();
                    targetMethod.Name                += Joinpoints.OperationJoinPoint.WrappedMethodSuffix + "Body_" + Cil.GetNextId();
                    targetMethod.IsNewSlot            = false;
                    targetMethod.IsFinal              = false;
                    targetMethod.IsRuntimeSpecialName = targetMethod.IsSpecialName = false;
                    containerType.Methods.Add(targetMethod);

                    // Clear containerMethod
                    containerMethod.Body.InitLocals = true;
                    containerMethod.Body.ExceptionHandlers.Clear();
                    containerMethod.Body.Variables.Clear();
                    containerMethod.Body.Instructions.Clear();

                    // Reify arguments and call interceptors in the original (now target) method
                    EmittingContext    ctx    = new EmittingContext(containerMethod);
                    VariableDefinition tmpObj = null;

                    if (!Cil.IsStatic(targetMethod))
                    {
                        ctx.Emit(OpCodes.Ldarg_0);

                        if (targetMethod.DeclaringType.IsValueType)
                        {
                            ctx.Emit(OpCodes.Ldobj, targetMethod.DeclaringType);
                            ctx.Emit(OpCodes.Box, targetMethod.DeclaringType);

                            // Tmp object to store boxed value types when passed along call interceptors and then unwrapped after calls
                            //tmpObj = new VariableDefinition(new ReferenceType(targetMethod.DeclaringType));
                            tmpObj = new VariableDefinition(Cil.GetTypeReference(typeof(object)));
                            containerMethod.Body.Variables.Add(tmpObj);
                            ctx.Emit(OpCodes.Stloc, tmpObj);
                            ctx.Emit(OpCodes.Ldloc, tmpObj);
                        }
                    }

                    VariableDefinition arrayDef = new VariableDefinition(Cil.GetTypeReference(typeof(object[])));
                    containerMethod.Body.Variables.Add(arrayDef);
                    ParameterDefinitionCollection containerParameters = containerMethod.Parameters;
                    ParameterDefinitionCollection targetParameters    = targetMethod.Parameters;

                    // Instantiate an array of the right size
                    ctx.Emit(OpCodes.Ldc_I4, containerParameters.Count);
                    ctx.Emit(OpCodes.Newarr, Cil.GetTypeReference(typeof(object)));
                    ctx.Emit(OpCodes.Stloc, arrayDef);

                    // Load the array with data coming from the current parameters
                    for (int i = containerParameters.Count - 1; i >= 0; i--)
                    {
                        ParameterDefinition p = containerParameters[i];
                        ctx.Emit(OpCodes.Ldloc, arrayDef);
                        ctx.Emit(OpCodes.Ldc_I4, i);
                        ctx.Emit(OpCodes.Ldarg, p);
                        Cil.BoxIfRequired(p.ParameterType, ctx);
                        ctx.Emit(OpCodes.Stelem_Ref);
                    }

                    // Pass real parameter values (taken from the stack) as the next parameter
                    ctx.Emit(OpCodes.Ldloc, arrayDef);
                    // end of Reify parameters

                    ArrayList interceptors = entry.Value as ArrayList;
                    Cil.InvokeInterceptors(containerMethod, ctx, targetMethod, interceptors);
                    Cil.UnboxIfRequired(targetMethod.ReturnType.ReturnType, ctx);

                    if (!Cil.IsStatic(targetMethod) && targetMethod.DeclaringType.IsValueType)
                    {
                        ctx.Emit(OpCodes.Ldarg_0);
                        ctx.Emit(OpCodes.Ldloc, tmpObj);
                        Cil.UnboxIfRequired(targetMethod.DeclaringType, ctx);
                        ctx.Emit(OpCodes.Stobj, targetMethod.DeclaringType);
                    }

                    // Cast (to satisfy PEVerify)
                    Cil.CastIfRequired(containerMethod.ReturnType.ReturnType, ctx);

                    ctx.Emit(OpCodes.Ret);
                }
            }
        }
Пример #2
0
        public void Cleanup()
        {
            Hashtable templateMethods             = new Hashtable();
            Hashtable templateMethodsInterceptors = new Hashtable();

            foreach (ToBeWeaved tbw in m_InterceptorsToWeave.Values)
            {
                Instruction      call            = tbw.TargetCall;
                MethodDefinition containerMethod = tbw.ContainerMethod;
                MethodReference  targetMethod    = (MethodReference)call.Operand;

                if (containerMethod != null && containerMethod.DeclaringType != null)
                {
                    MethodDefinition tplMethod = Cil.AspectTemplateCall.Clone();

                    tplMethod.Body.Instructions.Clear(); // remove ret
                    tplMethod.Name = targetMethod.Name + Joinpoints.OperationJoinPoint.WrappedMethodSuffix + "Call_" + Cil.GetNextId();
                    ((TypeDefinition)containerMethod.DeclaringType).Methods.Add(tplMethod);

                    PopulateInterceptor(tbw, call, targetMethod, tplMethod);

                    call.OpCode  = OpCodes.Call;
                    call.Operand = tplMethod;
                }
            }
        }
        public void Cleanup()
        {
            foreach (ToBeWeaved tbw in Map.Values)
            {
                Instruction      fieldAccessInstruction = tbw.TargetCall;
                MethodDefinition containerMethod        = tbw.ContainerMethod;
                FieldReference   field = (FieldReference)fieldAccessInstruction.Operand;

                MethodDefinition tplMethod = Cil.AspectTemplateCall.Clone();
                tplMethod.Name = field.Name + "_" + (IsGetter ? "Getter" : "Setter") + Cil.GetNextId();
                ((TypeDefinition)containerMethod.DeclaringType).Methods.Add(tplMethod);
                tplMethod.Body.InitLocals = true;
                tplMethod.Body.Instructions.Clear(); // remove ret

                // *** Inside interceptor ***
                PopulateInterceptor(tbw, fieldAccessInstruction, field, tplMethod);

                // Do nothing instead of the the previous behavior
                fieldAccessInstruction.OpCode  = OpCodes.Call;
                fieldAccessInstruction.Operand = tplMethod;
            }
        }