CIL评估堆栈可以包含值类型吗?

时间:2013-11-22 17:56:16

标签: .net clr cil value-type

我对值类型和CIL评估堆栈有点困惑。 ECMA-335,分区III,§1.1表示CLI处理这些“基本CLI类型”:

  
      
  • 完整数值类型的子集(int32,int64,native int和F)。

  •   
  • 对象引用(O),不区分引用的对象类型。

  •   
  • 指针类型(native unsigned int和&),没有区分指向的类型。

  •   

Partition II,§12.1还提供了一个类似的列表,它排除了值类型,并声明:

  

但是,CLI在其操作中仅支持存储在其评估堆栈-int32,int64和native int上的值的这些类型的子集。

除了通过托管指针类型之外,没有提及任何值类型。然而,ldfld的规范说:

  

ldfld指令将字段的值推入堆栈   OBJ。 obj应该是一个对象(类型O),一个托管指针(类型&),一个   非托管指针(类型为native int),或值类型的实例

这是否意味着值类型可以直接在评估堆栈上推送(而不是通过托管指针)?如果是这样,我可以假设被推送的值类型是原始的成员副本(例如,字段值)吗?

3 个答案:

答案 0 :(得分:2)

参见III.1.1的介绍(强调我的):

  

虽然CTS定义了富类型系统,但CLS指定了一个   可用于语言互操作性的子集,CLI本身   处理更简单的类型。 这些类型包括   用户定义的值类型和内置类型的子集。该   子集,统称为“基本CLI类型”,包含   以下类型:

答案 1 :(得分:1)

是的,ldfld肯定会将值类型值复制到eval堆栈上。 “基本CLR类型”是可以作为其操作的操作数出现的类型。例如,查看表III.2,显示您希望某种操作数可用于 add 指令。只是int32,int64,native int,F,O和&出现在那里。

此外,C#需要强制转换将添加到字节值的结果复制回byte类型的核心原因。不是基本的CLR类型,因此它转换为int32并生成int32结果。将它装回一个字节是一个非平凡的转换。

答案 2 :(得分:1)

ISO/IEC 23271:2012的第I.12.3.2.1节(CLI规范)声明如下:

  

虽然CLI通常支持§I.12.1中描述的完整类型集,但CLI以特殊方式处理评估堆栈。虽然一些JIT编译器可能会更详细地跟踪堆栈上的类型,但CLI只要求值为以下值之一:

     
      
  • int64,一个8字节有符号整数
  •   
  • int32,一个4字节有符号整数
  •   
  • native int,一个4或8字节的有符号整数,以较方便的目标架构为准。
  •   
  • F,浮点值(float32,float64或底层硬件支持的其他表示形式)
  •   
  • &,托管指针
  •   
  • O,一个对象引用
  •   
  • *,一个“瞬态指针”,只能在单个方法的主体中使用,指向已知在非托管内存中的值(有关更多详细信息,请参阅CIL指令集规范)。 *类型在CLI内部生成;它们不是由用户创建的。
  •   
  • 用户定义的值类型
  •   

所以,是的,评估堆栈可以包含值类型。并且复制了该值类型。