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); }
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); }
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); }
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 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); }
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); }