如何在CIL中处理堆栈上的不同类型

时间:2014-06-02 13:07:55

标签: .net types stack clr cil

尝试使用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或其他地方的具体实施的信息?

2 个答案:

答案 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的做法有所不同,但我可能会弄错。