I'm getting the following invalid IL emitted by Cecil:
IL_0001: ldfld 0
my code is something like:
var asm = AssemblyFactory.GetAssembly(this.GetType().Assembly.Location);
var interceptorRef =
asm.MainModule.TypeReferences.Add(typeof(IInterceptor));
foreach (var type in asm.Modules.Cast<ModuleDefinition>().SelectMany(a =>
a.Types.Cast<TypeDefinition>()))
{
// private IInterceptor __Interceptor;
var interceptorDef = new FieldDefinition("__Interceptor", interceptorRef,
Mono.Cecil.FieldAttributes.Private);
type.Fields.Add(interceptorDef);
var interceptorField = new FieldReference("__Interceptor", type,
interceptorRef);
foreach (var method in type.Methods.Cast<MethodDefinition>())
{
var il = method.Body.CilWorker;
var instructions = new List<Instruction>(new[]
{
// if (__Interceptor != null)
il.Create(OpCodes.Ldarg_0),
il.Create(OpCodes.Ldfld, interceptorField),
il.Create(OpCodes.Ldnull),
il.Create(OpCodes.Ceq),
il.Create(OpCodes.Brtrue_S, method.Body.Instructions[0]),
});
il.InsertRangeBefore(method.Body.Instructions[0], instructions);
}
}
which I expected would insert the following -incomplete- code into every
method:
if (this.__Interceptor != null)
{
}
alongside the addition of such a field to each class. the field is being
properly emitted.
For the following original method:
public string Echo(string message)
{
return message;
}
I'm getting the following re-written IL:
.method public hidebysig instance string
Echo(string message) cil managed
{
// Code size 18 (0x12)
.maxstack 3
.locals init ([0] string mock)
IL_0000: ldarg.0
IL_0001: ldfld 0
IL_0006: ldnull
IL_0007: ceq
IL_0009: brtrue.s IL_000b
IL_000b: nop
IL_000c: ldarg.1
IL_000d: stloc.0
IL_000e: br.s IL_0010
IL_0010: ldloc.0
IL_0011: ret
} // end of method InstrumentedClass::Echo
whereas the original IL was:
.method public hidebysig instance string
Echo(string message) cil managed
{
// Code size 7 (0x7)
.maxstack 1
.locals init (string V_0)
IL_0000: nop
IL_0001: ldarg.1
IL_0002: stloc.0
IL_0003: br.s IL_0005
IL_0005: ldloc.0
IL_0006: ret
} // end of method InstrumentedClass::Echo
the ldfld should look like:
IL_0004: ldfld class [Moq]Moq.Instrumentation.IInterceptor
Moq.Tests.Instrumentation.InvocationFixture::__Interceptor
any ideas on what I might be doing wrong?
Thanks in advance!
--
Daniel Cazzulino | Developer Lead | XML MVP | Clarius Consulting | +1
425.329.3471
--~--~---------~--~----~------------~-------~--~----~
--
mono-cecil
-~----------~----~----~----~------~----~------~--~---