我正在编写一个生成.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
答案 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
}
}