예제 #1
0
        private static void AddInterceptor(Instruction targetCall, MethodDefinition containerMethod, IMethodReference aspectMethod)
        {
            ToBeWeaved tbw = m_InterceptorsToWeave[targetCall] as ToBeWeaved;

            if (tbw == null)
            {
                m_InterceptorsToWeave[targetCall] = tbw = new ToBeWeaved(targetCall, containerMethod);
            }
            tbw.Interceptors.Add(aspectMethod);
        }
        private void AddInterceptor(Instruction targetCall, MethodDefinition targetMethod, IMethodReference aspectMethod)
        {
            ToBeWeaved tbw = Map[targetCall] as ToBeWeaved;

            if (tbw == null)
            {
                Map[targetCall] = tbw = new ToBeWeaved(targetCall, targetMethod);
            }
            tbw.Interceptors.Add(aspectMethod);
        }
예제 #3
0
        private static void PopulateInterceptor(ToBeWeaved tbw, Instruction call, MethodReference targetMethod, MethodDefinition tplMethod)
        {
            EmittingContext    ctx    = new EmittingContext(tplMethod);
            VariableDefinition tmpObj = null;
            int offset = 0;

            // Interceptor signature must be :
            if (call.OpCode == OpCodes.Newobj)
            {
                // new object -> static ctorDeclaringType interceptor(ctorParametersList);
                tplMethod.ReturnType.ReturnType = targetMethod.DeclaringType;
                ctx.Emit(OpCodes.Ldnull); // create a brand new object, don't initialize an existing one
            }
            else if (Cil.IsStatic(targetMethod))
            {
                // call static method  -> static methodReturnType interceptor(methodParametersList);
                tplMethod.ReturnType.ReturnType = targetMethod.ReturnType.ReturnType;
            }
            else
            {
                //call instance method  -> static methodReturnType interceptor(methodDeclaringType, methodParametersList);
                tplMethod.ReturnType.ReturnType = targetMethod.ReturnType.ReturnType;
                offset = 1;
                ctx.Emit(OpCodes.Ldarg_0); // load "this", which is the first parameter of the tplMethod
                if (!targetMethod.DeclaringType.IsValueType)
                {
                    tplMethod.Parameters.Add(new ParameterDefinition(targetMethod.DeclaringType));
                }
                else
                {
                    tplMethod.Parameters.Add(new ParameterDefinition(new ReferenceType(targetMethod.DeclaringType)));

                    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)));
                    tplMethod.Body.Variables.Add(tmpObj);
                    ctx.Emit(OpCodes.Stloc, tmpObj);
                    ctx.Emit(OpCodes.Ldloc, tmpObj);
                }
            }

            foreach (ParameterDefinition p in targetMethod.Parameters)
            {
                tplMethod.Parameters.Add(new ParameterDefinition(p.ParameterType));
            }

            ParameterDefinitionCollection tplParameters    = tplMethod.Parameters;
            ParameterDefinitionCollection targetParameters = targetMethod.Parameters;

            int nbParams = tplParameters.Count - offset;

            if (nbParams == 0)
            {
                // Load an empty array
                ctx.Emit(OpCodes.Ldnull);
            }
            else
            {
                // Instantiate an array of the right size
                VariableDefinition arrayDef = new VariableDefinition(Cil.GetTypeReference(typeof(object[])));
                tplMethod.Body.Variables.Add(arrayDef);

                ctx.Emit(OpCodes.Ldc_I4, nbParams);
                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 = tplParameters.Count - 1; i >= offset; i--)
                {
                    ctx.Emit(OpCodes.Ldloc, arrayDef);
                    ctx.Emit(OpCodes.Ldc_I4, i - offset);
                    ParameterDefinition p = tplParameters[i];
                    ctx.Emit(OpCodes.Ldarg, p);
                    Cil.BoxIfRequired(p.ParameterType, ctx);
                    ctx.Emit(OpCodes.Stelem_Ref);
                }
                ctx.Emit(OpCodes.Ldloc, arrayDef);
            }
            // end of reify parameters

            Cil.InvokeInterceptors(tplMethod, ctx, targetMethod, tbw.Interceptors);

            if (call.OpCode != OpCodes.Newobj)
            {
                Cil.UnboxIfRequired(targetMethod.ReturnType.ReturnType, ctx);
            }

            if (call.OpCode != OpCodes.Newobj && !Cil.IsStatic(targetMethod) && targetMethod.DeclaringType.IsValueType)
            {
                ctx.Emit(OpCodes.Ldarg_0);
                ctx.Emit(OpCodes.Ldloc, tmpObj);
                ctx.Emit(OpCodes.Unbox, targetMethod.DeclaringType);
                ctx.Emit(OpCodes.Ldobj, targetMethod.DeclaringType);
                ctx.Emit(OpCodes.Stobj, targetMethod.DeclaringType);
            }

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

            ctx.Emit(OpCodes.Ret);
        }
예제 #4
0
        private static void PopulateInterceptor(ToBeWeaved tbw, Instruction call, MethodReference targetMethod, MethodDefinition tplMethod) {
            EmittingContext ctx = new EmittingContext(tplMethod);
            VariableDefinition tmpObj = null;
            int offset = 0;

            // Interceptor signature must be : 
            if (call.OpCode == OpCodes.Newobj) { 
                // new object -> static ctorDeclaringType interceptor(ctorParametersList);
                tplMethod.ReturnType.ReturnType = targetMethod.DeclaringType;
                ctx.Emit(OpCodes.Ldnull); // create a brand new object, don't initialize an existing one
            } else if (Cil.IsStatic(targetMethod)) {  
                // call static method  -> static methodReturnType interceptor(methodParametersList);
                tplMethod.ReturnType.ReturnType = targetMethod.ReturnType.ReturnType;
            } else { 
                //call instance method  -> static methodReturnType interceptor(methodDeclaringType, methodParametersList);
                tplMethod.ReturnType.ReturnType = targetMethod.ReturnType.ReturnType;
                offset = 1;
                ctx.Emit(OpCodes.Ldarg_0); // load "this", which is the first parameter of the tplMethod
                if (!targetMethod.DeclaringType.IsValueType) {
                    tplMethod.Parameters.Add(new ParameterDefinition(targetMethod.DeclaringType));
                } else {
                    tplMethod.Parameters.Add(new ParameterDefinition(new ReferenceType(targetMethod.DeclaringType)));

                    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)));
                    tplMethod.Body.Variables.Add(tmpObj);
                    ctx.Emit(OpCodes.Stloc, tmpObj);
                    ctx.Emit(OpCodes.Ldloc, tmpObj);

                }
            } 

            foreach (ParameterDefinition p in targetMethod.Parameters)
                tplMethod.Parameters.Add(new ParameterDefinition(p.ParameterType));

            ParameterDefinitionCollection tplParameters = tplMethod.Parameters;
            ParameterDefinitionCollection targetParameters = targetMethod.Parameters;

            int nbParams = tplParameters.Count - offset;
            if (nbParams == 0)
                // Load an empty array
                ctx.Emit(OpCodes.Ldnull);
            else {
                // Instantiate an array of the right size
                VariableDefinition arrayDef = new VariableDefinition(Cil.GetTypeReference(typeof(object[])));
                tplMethod.Body.Variables.Add(arrayDef);

                ctx.Emit(OpCodes.Ldc_I4, nbParams);
                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 = tplParameters.Count - 1; i >= offset; i--) {
                    ctx.Emit(OpCodes.Ldloc, arrayDef);
                    ctx.Emit(OpCodes.Ldc_I4, i - offset);
                    ParameterDefinition p = tplParameters[i];
                    ctx.Emit(OpCodes.Ldarg, p);
                    Cil.BoxIfRequired(p.ParameterType, ctx);
                    ctx.Emit(OpCodes.Stelem_Ref);
                }
                ctx.Emit(OpCodes.Ldloc, arrayDef);
            }
            // end of reify parameters

            Cil.InvokeInterceptors(tplMethod, ctx, targetMethod, tbw.Interceptors);

            if (call.OpCode != OpCodes.Newobj)
                Cil.UnboxIfRequired(targetMethod.ReturnType.ReturnType, ctx);

            if (call.OpCode != OpCodes.Newobj && !Cil.IsStatic(targetMethod) && targetMethod.DeclaringType.IsValueType) {
                ctx.Emit(OpCodes.Ldarg_0);
                ctx.Emit(OpCodes.Ldloc, tmpObj);
                ctx.Emit(OpCodes.Unbox, targetMethod.DeclaringType);
                ctx.Emit(OpCodes.Ldobj, targetMethod.DeclaringType);
                ctx.Emit(OpCodes.Stobj, targetMethod.DeclaringType);
            }

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

            ctx.Emit(OpCodes.Ret);
        }
예제 #5
0
 private static void AddInterceptor(Instruction targetCall, MethodDefinition containerMethod, IMethodReference aspectMethod) {
     ToBeWeaved tbw = m_InterceptorsToWeave[targetCall] as ToBeWeaved;
     if (tbw == null)
         m_InterceptorsToWeave[targetCall] = tbw = new ToBeWeaved(targetCall, containerMethod);
     tbw.Interceptors.Add(aspectMethod);
 }
예제 #6
0
        private void PopulateInterceptor(ToBeWeaved tbw, Instruction fieldAccessInstruction, FieldReference field, MethodDefinition tplMethod)
        {
            tplMethod.ReturnType.ReturnType = IsGetter ? field.FieldType : Cil.GetTypeReference(typeof(void));

            bool isStaticField = fieldAccessInstruction.OpCode == OpCodes.Stsfld || fieldAccessInstruction.OpCode == OpCodes.Ldsfld;

            // The target object is already on the stack if we access an instance field
            if (!isStaticField)
                if (field.DeclaringType.IsValueType)
                    tplMethod.Parameters.Add(new ParameterDefinition(new ReferenceType(field.DeclaringType)));
                else
                    tplMethod.Parameters.Add(new ParameterDefinition(field.DeclaringType));

            // The value to assign is already on the stack as well
            if (!IsGetter)
                tplMethod.Parameters.Add(new ParameterDefinition(field.FieldType));

            EmittingContext ctx = new EmittingContext(tplMethod);

            VariableDefinition tmpObj = null;
            if (!isStaticField) {
                ctx.Emit(OpCodes.Ldarg_0); // load "this", which is the first parameter of the tplMethod

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

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

                if (!IsGetter) {
                    ctx.Emit(OpCodes.Ldarg, tplMethod.Parameters[1]);
                    Cil.BoxIfRequired(field.FieldType, ctx);
                }
            } else { // Static field
                if (!IsGetter) {
                    ctx.Emit(OpCodes.Ldarg, tplMethod.Parameters[0]);
                    Cil.BoxIfRequired(field.FieldType, ctx);
                }
            }

            // Pass the field representation as the last parameter
            ctx.Emit(OpCodes.Ldtoken, field);
            #if DOTNETTWO
            ctx.Emit(OpCodes.Ldtoken, field.DeclaringType);
            ctx.Emit(OpCodes.Call, Cil.GetGenericFieldFromHandle);
            #else
            ctx.Emit(OpCodes.Call, Cil.GetFieldFromHandle);
            #endif

            // Create the JoinPoint
            MethodReference joinPointFactory;
            OpCode opCode = fieldAccessInstruction.OpCode;
            if (opCode == OpCodes.Stsfld) joinPointFactory = Cil.StaticFieldSetterJoinPointFactory;
            else if (opCode == OpCodes.Ldsfld) joinPointFactory = Cil.StaticFieldGetterJoinPointFactory;
            else if (opCode == OpCodes.Stfld) joinPointFactory = Cil.FieldSetterJoinPointFactory;
            else if (opCode == OpCodes.Ldfld) joinPointFactory = Cil.FieldGetterJoinPointFactory;
            else throw new NotSupportedException("This kind of field accessor is not supported : " + opCode);

            ctx.Emit(OpCodes.Newobj, joinPointFactory);

            // Add each interceptor
            foreach (MethodReference aspectMethod in tbw.Interceptors) {
                ctx.Emit(OpCodes.Ldtoken, Cil.TargetMainModule.Import(aspectMethod));
                ctx.Emit(OpCodes.Call, Cil.GetMethodFromHandle);
                ctx.Emit(OpCodes.Call, Cil.AddInterceptorMethod);
            }

            // Invoke "proceed" on the joinpoint
            ctx.Emit(OpCodes.Call, Cil.ProceedMethod);
            Cil.UnboxIfRequired(tplMethod.ReturnType.ReturnType, ctx);

            if (! isStaticField && field.DeclaringType.IsValueType) { // Unbox and update "this"
                ctx.Emit(OpCodes.Ldarg_0);
                ctx.Emit(OpCodes.Ldloc, tmpObj);
                ctx.Emit(OpCodes.Unbox, field.DeclaringType);
                ctx.Emit(OpCodes.Ldobj, field.DeclaringType);
                ctx.Emit(OpCodes.Stobj, field.DeclaringType);
            }

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

            ctx.Emit(OpCodes.Ret);
        }
예제 #7
0
 private void AddInterceptor(Instruction targetCall, MethodDefinition targetMethod, IMethodReference aspectMethod)
 {
     ToBeWeaved tbw = Map[targetCall] as ToBeWeaved;
     if (tbw == null){
         Map[targetCall] = tbw = new ToBeWeaved(targetCall, targetMethod);
     }
     tbw.Interceptors.Add(aspectMethod);
 }
        private void PopulateInterceptor(ToBeWeaved tbw, Instruction fieldAccessInstruction, FieldReference field, MethodDefinition tplMethod)
        {
            tplMethod.ReturnType.ReturnType = IsGetter ? field.FieldType : Cil.GetTypeReference(typeof(void));

            bool isStaticField = fieldAccessInstruction.OpCode == OpCodes.Stsfld || fieldAccessInstruction.OpCode == OpCodes.Ldsfld;

            // The target object is already on the stack if we access an instance field
            if (!isStaticField)
            {
                if (field.DeclaringType.IsValueType)
                {
                    tplMethod.Parameters.Add(new ParameterDefinition(new ReferenceType(field.DeclaringType)));
                }
                else
                {
                    tplMethod.Parameters.Add(new ParameterDefinition(field.DeclaringType));
                }
            }

            // The value to assign is already on the stack as well
            if (!IsGetter)
            {
                tplMethod.Parameters.Add(new ParameterDefinition(field.FieldType));
            }

            EmittingContext ctx = new EmittingContext(tplMethod);

            VariableDefinition tmpObj = null;

            if (!isStaticField)
            {
                ctx.Emit(OpCodes.Ldarg_0); // load "this", which is the first parameter of the tplMethod

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

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

                if (!IsGetter)
                {
                    ctx.Emit(OpCodes.Ldarg, tplMethod.Parameters[1]);
                    Cil.BoxIfRequired(field.FieldType, ctx);
                }
            }
            else     // Static field
            {
                if (!IsGetter)
                {
                    ctx.Emit(OpCodes.Ldarg, tplMethod.Parameters[0]);
                    Cil.BoxIfRequired(field.FieldType, ctx);
                }
            }

            // Pass the field representation as the last parameter
            ctx.Emit(OpCodes.Ldtoken, field);
#if DOTNETTWO
            ctx.Emit(OpCodes.Ldtoken, field.DeclaringType);
            ctx.Emit(OpCodes.Call, Cil.GetGenericFieldFromHandle);
#else
            ctx.Emit(OpCodes.Call, Cil.GetFieldFromHandle);
#endif

            // Create the JoinPoint
            MethodReference joinPointFactory;
            OpCode          opCode = fieldAccessInstruction.OpCode;
            if (opCode == OpCodes.Stsfld)
            {
                joinPointFactory = Cil.StaticFieldSetterJoinPointFactory;
            }
            else if (opCode == OpCodes.Ldsfld)
            {
                joinPointFactory = Cil.StaticFieldGetterJoinPointFactory;
            }
            else if (opCode == OpCodes.Stfld)
            {
                joinPointFactory = Cil.FieldSetterJoinPointFactory;
            }
            else if (opCode == OpCodes.Ldfld)
            {
                joinPointFactory = Cil.FieldGetterJoinPointFactory;
            }
            else
            {
                throw new NotSupportedException("This kind of field accessor is not supported : " + opCode);
            }

            ctx.Emit(OpCodes.Newobj, joinPointFactory);

            // Add each interceptor
            foreach (MethodReference aspectMethod in tbw.Interceptors)
            {
                ctx.Emit(OpCodes.Ldtoken, Cil.TargetMainModule.Import(aspectMethod));
                ctx.Emit(OpCodes.Call, Cil.GetMethodFromHandle);
                ctx.Emit(OpCodes.Call, Cil.AddInterceptorMethod);
            }

            // Invoke "proceed" on the joinpoint
            ctx.Emit(OpCodes.Call, Cil.ProceedMethod);
            Cil.UnboxIfRequired(tplMethod.ReturnType.ReturnType, ctx);

            if (!isStaticField && field.DeclaringType.IsValueType)    // Unbox and update "this"
            {
                ctx.Emit(OpCodes.Ldarg_0);
                ctx.Emit(OpCodes.Ldloc, tmpObj);
                ctx.Emit(OpCodes.Unbox, field.DeclaringType);
                ctx.Emit(OpCodes.Ldobj, field.DeclaringType);
                ctx.Emit(OpCodes.Stobj, field.DeclaringType);
            }

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

            ctx.Emit(OpCodes.Ret);
        }