Reputation: 33
I'm using Mono cecil to auto implement the propertychanged interface. Everything was working fine, until today that i got the exception Common Language Runtime detected an invalid program. My mono cecil c# code is:
ILProcessor MSILWorker = prop.SetMethod.Body.GetILProcessor();
MSILWorker.Body.InitLocals = true;
MSILWorker.InsertBefore(MSILWorker.Body.Instructions[0], MSILWorker.Create(OpCodes.Nop));
MSILWorker.InsertBefore(MSILWorker.Body.Instructions[1], MSILWorker.Create(OpCodes.Ldarg_0));
Instruction propertyName = MSILWorker.Create(OpCodes.Ldflda, field);
MSILWorker.InsertBefore(MSILWorker.Body.Instructions[3], propertyName);
MSILWorker.InsertAfter(MSILWorker.Body.Instructions[4], MSILWorker.Create(OpCodes.Ldstr, prop.Name));
Instruction callRaisePropertyChanged = MSILWorker.Create(OpCodes.Call, method_reference);
MSILWorker.Replace(MSILWorker.Body.Instructions[6], callRaisePropertyChanged);
MSILWorker.InsertBefore(MSILWorker.Body.Instructions.Last(), MSILWorker.Create(OpCodes.Pop));
The Generated il code is:
.method public hidebysig newslot specialname virtual final
instance void set_CreateDate(valuetype [mscorlib]System.DateTime 'value') cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
// Code size 21 (0x15)
.maxstack 4
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldarg.0
IL_0003: ldflda valuetype [mscorlib]System.DateTime Framework.Data.Base.BaseEntity::'<CreateDate>k__BackingField'
IL_0008: ldarg.1
IL_0009: ldstr "CreateDate"
IL_000e: call instance void Framework.Data.Base.BaseEntity::SetField<valuetype [mscorlib]System.DateTime>(!!0&,
!!0,
string)
IL_0013: pop
IL_0014: ret
} // end of method BaseEntity::set_CreateDate
I've tried to compare with a property written in C# for another field, with exactly the same logic, and the generated IL code is:
.method public hidebysig newslot specialname virtual final
instance void set_LastModifiedDate(valuetype [mscorlib]System.DateTime 'value') cil managed
{
// Code size 21 (0x15)
.maxstack 8
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldarg.0
IL_0003: ldflda valuetype [mscorlib]System.DateTime Framework.Data.Base.BaseEntity::_LastModifiedDate
IL_0008: ldarg.1
IL_0009: ldstr "LastModifiedDate"
IL_000e: call instance void Framework.Data.Base.BaseEntity::SetField<valuetype [mscorlib]System.DateTime>(!!0&,
!!0,
string)
IL_0013: nop
IL_0014: ret
} // end of method BaseEntity::set_LastModifiedDate
Can someone help me? What am i doing wrong?
Thanks
Upvotes: 2
Views: 731
Reputation: 22261
Your stack is unbalanced. The C# generated example has a nop
at IL_0013 where you have a pop
.
My guess is that you are calling a void
method, and therefore don't need to discard a result.
Remove MSILWorker.InsertBefore(MSILWorker.Body.Instructions.Last(), MSILWorker.Create(OpCodes.Pop));
Upvotes: 4