Hi,
I'm writing a short method that should do as follows:
/* typeBuilder is a type in construction and contains a method,
mInfo, whose code I want to tweak. Specifically, I want to replace all
ldfld instructions with calls to given methods. */
public MethodBuilder InstrumentMethod(TypeBuilder typeBuilder,
MethodInfo mInfo) {
MethodBuilder mBuilder = typeBuilder.DefineMethod(/*...define
method with the same signature as mInfo...*/);
MethodDefinition mDef = /*...somehow get a MethodDefinition
for the MethodBuilder mBuilder...*/;
CilWorker worker = mDef.Body.CilWorker;
foreach (Instruction instr in method.Body.Instructions) {
// If it's a 'load field' instruction...
if (instr.OpCode == Mono.Cecil.Cil.OpCodes.Ldfld) {
// Get the info for the field.
FieldInfo fieldInfo = (FieldInfo) instr.Operand;
// Look for a method. The name of the method is
obtained from the field's name.
MethodInfo accessorInfo =
typeBuilder.GetMethod("get_" + field.Name);
MethodReference accessorRef = /*...somehow get a
MethodReference for accessorInfo...*/;
// Create an instruction that calls the accessor.
Instruction accessorCall =
worker.Create(OpCodes.Callvirt, accessorRef);
// Replace the ldfld instruction with the call to the
accessor.
worker.Replace(instr, accessorCall);
}
}
return mBuilder;
}
I can't seem to find any way to get the Cecil classes I need
(MethodDefinition and MethodReference) from the System.Reflection
classes (MethodInfo and MethodBuilder), or vice versa: I can't for
example create a method with Cecil and then extract its MethodBuilder,
which is what I have to return.
The questions (as seen in the code above) are:
1. How to get a MethodDefinition for the MethodBuilder mBuilder.
2. How to get a MethodReference for the MethodInfo accessorInfo.
In the second case I could also look for the method directly using
Cecil as opposed to doing this:
MethodInfo accessorInfo = typeBuilder.GetMethod("get_" +
field.Name);
...but I can't seem to find a way to do that without an
AssemblyDefinition, and since my assembly is still in creation and not
yet written to a .dll, I can't do this:
AssemblyFactory.GetAssembly("MyAssemblyInCreation.dll");
because the file doesn't exist.
Help, please? :)
Thanks.
--
--
mono-cecil