xaviergxf
xaviergxf

Reputation: 33

Why i'm getting the exception: Common Language Runtime detected an invalid program

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

Answers (1)

Mitch
Mitch

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

Related Questions