使用Reflection.Emit在IL代码中出错

时间:2014-08-22 12:15:18

标签: c# reflection.emit il

我正在编写一个生成.NET IL的编译器。我正在使用C#/ Mono在Linux Mint上编写它。

我使用Reflection.Emit生成一些代码的问题。请原谅生成的代码中的可怕名称。以下是monodis输出的相关部分。

.method public static 
       default valuetype Argon.30 Argon.28313529 (valuetype Argon.35 A_0)  cil managed 
{
    // Method begins at RVA 0x215c
// Code size 73 (0x49)
.maxstack 10
.locals init (
    valuetype Argon.35  V_0,
    valuetype Argon.35  V_1)
IL_0000:  ldarg.0 
IL_0001:  stloc.0 
IL_0002:  ldloca.s 0
IL_0004:  ldc.i4.7 
IL_0005:  newobj instance void valuetype Argon.35::'.ctor'(int32)
IL_000a:  call instance valuetype Argon.35 valuetype Argon.35::'add'(valuetype Argon.35)
IL_000f:  stloc.0 
IL_0010:  ldloc.0 
IL_0011:  stloc.1 
IL_0012:  ldloca.s 1
IL_0014:  ldc.i4.2 
IL_0015:  newobj instance void valuetype Argon.35::'.ctor'(int32)
IL_001a:  call instance valuetype Argon.35 valuetype Argon.35::'sub'(valuetype Argon.35)
IL_001f:  stloc.0 
IL_0020:  ldsfld class Argon.747970655F30 Argon.747970655F30::'instance'
IL_0025:  call valuetype Argon.30 Argon.283129()
IL_002a:  pop 
IL_002b:  ldarg.0 
IL_002c:  call valuetype Argon.30 Argon.28313229(valuetype Argon.35)
IL_0031:  pop 
IL_0032:  ldstr " + 5 = "
IL_0037:  newobj instance void class Argon.32::'.ctor'(string)
IL_003c:  call valuetype Argon.30 Argon.28313129(class Argon.32)
IL_0041:  pop 
IL_0042:  ldloc.0 
IL_0043:  call valuetype Argon.30 Argon.28313229(valuetype Argon.35)
IL_0048:  ret 
} // end of global method Argon.28313529

当我在单声道中运行时,我收到以下错误。

System.InvalidProgramException:无效的IL代码:Argon.28313529(Argon.35):IL_0048:ret

在Microsoft .NET下运行此问题似乎没有问题。据我了解,这是因为单声道在优化之前执行了检查。

此外,以下版本的代码没有错误。

.method public static 
       default valuetype Argon.30 Argon.28313529 (valuetype Argon.35 A_0)  cil managed 
{
    // Method begins at RVA 0x215c
// Code size 46 (0x2e)
.maxstack 6
.locals init (
    valuetype Argon.35  V_0)
IL_0000:  ldarg.0 
IL_0001:  stloc.0 
IL_0002:  ldloca.s 0
IL_0004:  ldc.i4.7 
IL_0005:  newobj instance void valuetype Argon.35::'.ctor'(int32)
IL_000a:  call instance valuetype Argon.35 valuetype Argon.35::'add'(valuetype Argon.35)
IL_000f:  stloc.0 
IL_0010:  ldarg.0 
IL_0011:  call valuetype Argon.30 Argon.28313229(valuetype Argon.35)
IL_0016:  pop 
IL_0017:  ldstr " + 5 = "
IL_001c:  newobj instance void class Argon.32::'.ctor'(string)
IL_0021:  call valuetype Argon.30 Argon.28313129(class Argon.32)
IL_0026:  pop 
IL_0027:  ldloc.0 
IL_0028:  call valuetype Argon.30 Argon.28313229(valuetype Argon.35)
IL_002d:  ret 
} // end of global method Argon.28313529

2 个答案:

答案 0 :(得分:4)

除了Argon.747970655F30上的说明返回的IL_0020实例之外,您还要将Argon.30的实例放在IL_0043的堆栈上。 ?当你ret而不是一个时,这将在堆栈中留下2个项目。

答案 1 :(得分:4)

IL_0020上的指令使堆栈失衡,不应该发出。这看起来像是语言分析器中的错误。相当于不报告这种编码错误:

class Example {
    Example instance;
    static void Method() { }
    void Bug() {
        instance.Method();    // CS0176
    }
}