尝试使用ildasm深入研究CIL代码,很明显CIL本身就是基于堆栈来支持像
这样的表达式IL_0001: ldc.i4.s 13 ; 1f 0d
IL_0003: stloc.0 ; 0a
IL_0004: ldc.i4.s 31 ; 1f 1f
IL_0006: stloc.1 ; 0b
IL_0007: ldloc.0 ; 06
IL_0008: ldloc.1 ; 07
IL_0009: add ; 58
使用float32
而不是int32
使用ldc.r4 <num>
执行相同操作,调用add
没有区别,因此让我想知道是否有不同类型的堆栈或如果只有一个堆栈,其中包含特定元素在堆栈中具有的元数据。是否有关于ECMA-335或其他地方的具体实施的信息?
答案 0 :(得分:8)
这在第I部分第12部分(来自例如此pdf)中有详细说明,该部分讨论了虚拟执行系统(VES):
如下所述,CIL指令不指定其操作数类型。相反,CLI保留 基于数据流的操作数类型跟踪,并由堆栈一致性要求辅助 如下面所描述的。例如,单个
add
指令将添加两个整数或两个浮点数 堆栈。
和
大多数处理数字的CIL指令都从评估堆栈中获取操作数 (参见§I.12.3.2.1),这些输入具有VES已知的关联类型。结果是, 像
add
这样的单个操作可以输入任何数字数据类型,但不是全部 指令可以处理操作数类型的所有组合。
I.12.1.4也更加详细。
答案 1 :(得分:5)
JIT推断出类型。无论如何,它必须执行此操作来键入检查您的程序。无需为其操作的类型参数化操作。堆栈的类型和大小可在IL指令序列中的任何位置计算。如果它们不可计算或模棱两可,则程序无法验证。
我相信Java IL的做法有所不同,但我可能会弄错。