private static void InsertCustomCodeCall( MethodDefinition method, MethodReference generatedTypeCtorRef, MethodReference generatedMethodRef, CilWorker cilWorker, Instruction instructionToInsertBefore, bool replaceMethod ) { bool hasReturnValue = (method.ReturnType.ReturnType.FullName != typeof(void).FullName); Instruction nop = cilWorker.Create(OpCodes.Nop); cilWorker.InsertBefore(instructionToInsertBefore, nop); // call ctor Instruction newGeneratedType = cilWorker.Create(OpCodes.Newobj, generatedTypeCtorRef); cilWorker.InsertBefore(instructionToInsertBefore, newGeneratedType); // load arguments on stack if any for (int i = 0; i < method.Parameters.Count; i++) { Instruction loadArg = cilWorker.Create(OpCodes.Ldarga_S, method.Parameters[i]); cilWorker.InsertBefore(instructionToInsertBefore, loadArg); } // call replacing method Instruction callGeneratedMethod = cilWorker.Create(OpCodes.Call, generatedMethodRef); cilWorker.InsertBefore(instructionToInsertBefore, callGeneratedMethod); if (hasReturnValue) { if (replaceMethod) { // add variable to list var generatedValueVar = new VariableDefinition(method.ReturnType.ReturnType); method.Body.Variables.Add(generatedValueVar); // assign to variable Instruction assignNewGeneratedValue = cilWorker.Create(OpCodes.Stloc, generatedValueVar); cilWorker.InsertBefore(instructionToInsertBefore, assignNewGeneratedValue); Instruction ldLoc = cilWorker.Create(OpCodes.Ldloc_0); Instruction brs = cilWorker.Create(OpCodes.Br_S, ldLoc); cilWorker.InsertBefore(instructionToInsertBefore, brs); cilWorker.InsertBefore(instructionToInsertBefore, ldLoc); } else { // remove value from stack Instruction pop = cilWorker.Create(OpCodes.Pop); cilWorker.InsertBefore(instructionToInsertBefore, pop); } } }
private void EnteringMethodInstruction(MethodDefinition method, CilWorker worker) { MethodReference enteringMethod = method.DeclaringType.Module.Import(typeof (Profiler).GetMethod("EnteringMethod")); worker.InsertBefore(method.Body.Instructions[0], worker.Create(OpCodes.Call, enteringMethod)); worker.InsertBefore(method.Body.Instructions[0], worker.Create(OpCodes.Ldstr, MethodName(method))); }