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