如何在 CIL 中的堆栈上处理不同的类型
Posted
技术标签:
【中文标题】如何在 CIL 中的堆栈上处理不同的类型【英文标题】:How are different types handled on the stack in CIL 【发布时间】:2014-07-22 14:47:28 【问题描述】:使用 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
使用ldc.r4 <num>
对float32
执行相同操作而不是int32
特定元素在堆栈上的类型的元数据。是否有关于 ECMA-335 或其他地方的具体实现的任何信息?
【问题讨论】:
次要注意:add
实际上有 3 个操作码,但这些是关于 行为(溢出/签名),而不是类型.正如usr
正确指出的那样:JIT 知道来自 IL 的类型。
【参考方案1】:
第 I 部分第 12 部分(例如来自 pdf)专门讨论了这一点,其中讨论了虚拟执行系统 (VES):
如下所述,CIL 指令不指定其操作数类型。相反,CLI 保留 基于数据流和堆栈一致性要求的操作数类型的跟踪 如下面所描述的。例如,单个
add
指令将添加两个整数或两个浮点数 堆栈。
还有:
大多数处理数字的 CIL 指令从计算堆栈中获取操作数 (参见 §I.12.3.2.1),并且这些输入具有 VES 已知的关联类型。因此, 像
add
这样的单个操作可以有任何数字数据类型的输入,尽管不是全部 指令可以处理操作数类型的所有组合。
I.12.1.4 的细节也相当多。
【讨论】:
【参考方案2】:JIT 推断类型。无论如何,它必须这样做才能对您的程序进行类型检查。不需要为它们操作的类型参数化操作。堆栈的类型和大小可在 IL 指令序列中的任何位置计算。如果它们不可计算或不明确,则程序是无法验证的。
我相信 Java IL 做这件事的方式不同,但我可能弄错了。
【讨论】:
以上是关于如何在 CIL 中的堆栈上处理不同的类型的主要内容,如果未能解决你的问题,请参考以下文章