在IL代码中使用reflect . emit出错

本文关键字:reflect emit 出错 IL 代码 | 更新日期: 2023-09-27 18:19:03

我正在编写一个生成。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

当我在mono中运行时,我得到以下错误:

系统。InvalidProgramException: Invalid IL code in:Argon.28313529(aragon .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

在IL代码中使用reflect . emit出错

除了指令在IL_0043返回的Argon.30实例外,您不是把Argon.747970655F30的实例放在IL_0020的堆栈上吗?这将在堆栈上留下2项,当你ret,而不是一个。

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

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