ECMA335 (CLI) 标准 读书笔记——总结CLI类型系统(上)

    看到类型系统的概述时,就忍不住按图索骥,想搞清楚CLI如何定义的整个类型系统。于是翻遍了整个标准,将类型系统中最核心的、与运行平台密切相关的类型定义与说明整理了出来,以供理清思路。

 

    标准的第四部指出,CLI的核心是Kernel Profile,而Kernel ProfileRuntime infrastructure libraryBase Class Library (BCL) 组成。

 

·         Runtime infrastructure library CLI提供了编译器需要的服务和从特定格式的文件流中动态调用类型的能力,CLI规范的第二部中指定了这些特定的文件格式。

·         BCL是现代编程语言的一个简单的运行时库,它作为C#语言运行时库的标准,同时也作为CLI标准库的一部分。它提供了类型来描述CLI的内建数据类型,简单的文件存取,定制属性,安全属性,字符串处理,格式化,流,集合等等。

  

这里我们可以看出支持CLI核心特征的Runtime infrastructure library主要由指令系统构成,而BCL则主要由类型系统构成。所以我们研究CLI的核心就要从它的指令系统和类型系统入手。

 

我们先来总结一下CLI的类型系统。

通用类型系统的概述请参考:ECMA- 335(CLI)标准 读书笔记(第一部:概念和架构 8~8.2

类型分为值类型和引用类型。

值类型分为内建值类型和用户定义类型。

引用类型分为自描述、接口、指针和内建引用类型。

 

类型系统里最核心的是内建类型,包括内建值类型和引用类型。其它的特征则可以根据不同的系统平台要求在实现时进行裁减。

 

第二部 7 类型和签名

元数据提供了定义和引用类型的机制。第10章描述了与类型定义相关的元数据,这里不区分类型是类,接口还是值类型。

用于引用类型的机制分为以下两部分:

·         用户定义类型的逻辑描述,该类型被引用但没定义在当前模块中,它们被存储于元数据的表中(22.38章)。

·         编码一个或更多类型引用的签名,除了多种修饰语外。语法非终结符的Type描述了签名中的独特入口。签名的编码在23.1.16章详述。

7.1 内建类型

下面的表详细列出了CLI中所有的内建类型(包括指针类型):

Type ::=

Description

Clause

‘!’ Int32

Generic parameter in a type definition, accessed by index from 0

9.1

| ‘!!’ Int32

Generic parameter in a method definition, accessed by index from 0

9.2

| bool

Boolean

7.2

| char

16-bit Unicode code point

7.2

| class TypeReference

User defined reference type

7.3

| float32

32-bit floating-point number

7.2

| float64

64-bit floating-point number

7.2

| int8

Signed 8-bit integer

7.2

| int16

Signed 16-bit integer

7.2

| int32

Signed 32-bit integer

7.2

| int64

Signed 64-bit integer

7.2

| method CallConv Type ‘*’

‘(’ Parameters ‘)’

Method pointer

14.5

| native int

32- or 64-bit signed integer whose size is platform-specific

7.2

| native unsigned int

32- or 64-bit unsigned integer whose size is platform-specific

7.2

| object

See System. Object in Partition IV

 

| string

See System.String in Partition IV

 

| Type ‘&’

Managed pointer to Type. Type shall not be a managed pointer type or typedref

14.4

| Type ‘*’

Unmanaged pointer to Type

14.4

| Type ‘<’ GenArgs ‘>’

Instantiation of generic type

9.4

| Type ‘[’ [ Bound [ ‘,’ Bound ]*] ‘]’

Array of Type with optional rank (number of dimensions) and bounds.

14.1and 14.2

| Type modopt ‘(’ TypeReference ‘)’

Custom modifier that can be ignored by the caller.

7.1.1

| Type modreq ‘(’ TypeReference ‘)’

Custom modifier that the caller shall understand.

7.1.1

| Type pinned

For local variables only. The garbage collector shall not move the referenced value.

7.1.2

| typedref

Typed reference (i.e., a value of type System.TypedReference), created by mkrefany and used by refanytype or refanyval.

7.2

| valuetype TypeReference

(Unboxed) user defined value type

13

| unsigned int8

Unsigned 8-bit integer

7.2

|  unsigned intl6

Unsigned l6-bit integer

7.2

|  unsigned int32

Unsigned 32-bit integer

7.2 

|  unsigned int64

Unsigned 64-bit integer

7.2 

|  void

No type. Only allowed as a return type or as part of void *

7.2

 

7.4 本地数据类型

CLI的一些实现将运行于现有的操作系统或运行时平台上,这些平台指定的数据类型要执行某些特定的功能。元数据允许通过指定CLI的内建和用户定义类型如何被转换成本地数据或者从本地数据转换过来的方式,与这些本地数据类型进行交互。这些转换信息能被(使用关键词marshal)用于:

  • 方法的返回类型,规定了一个本地数据类型实际被返回的和应该被转换回指定的CLI数据类型。
  • 方法的参数,规定了被调用者提供的CLI数据类型应该被转换成指定的本地数据类型。(如果参数通过引用传递,更新的值应该在调用结束后,从本地数据类型被转换回CLI类型。)
  • 用户定义类型字段,规定了任何企图传递包含该字段的对象的时候,平台方法都应该作一份这个对象的拷贝,用指定的本地数据类型替换这些字段。(如果对象通过引用被传递,更新的值应该在调用结束后被转换回来。)

下面的表中列出了CLI支持的所有本地类型,并提供了每个类型的描述。(更多完整的描述请看第四部分中enum的定义System.Runtime.Interopservices.UnmanagedType,它提供了用于编码这些类型的实际值。)所有0-63的编码值被保留用于向后兼容所有已经存在的CLI的执行。64-127的值被留作将来用于这个和相关标准上。

NativeType ::=

Description

Name in the class

library enum type

UnmanagedType

‘[’ ‘]’

Native array. Type and size are determined at runtime from the actual marshaled array.

LPArray

|bool

Boolean. 4-byte integer value where any non- zero value represents TRUE, and 0 represents FALSE.

Bool

| float32

32-bit floating-point number.

R4

| float64

64-bit floating-point number.

R8

| [unsigned] int

Signed or unsigned integer, sized to hold a pointer on the platform

SysUInt or SysInt

| [unsigned] int8

Signed or unsigned 8-bit integer

U1 or I1

| [unsigned] int16

Signed or unsigned 16-bit integer

U2 or I2

| [unsigned] int32

Signed or unsigned 32-bit integer

U4 or I4

| [unsigned] int64

Signed or unsigned 64-bit integer

U8 or I8

|lpstr

A pointer to a null-terminated array of ANSI characters. The code page is implementation- specific.

LPStr

|lpwstr

A pointer to a null-terminated array of Unicode characters. The character encoding is implementation-specific.

LPWStr

| method

A function pointer.

FunctionPtr

| NativeType ‘[’ ‘]’

Array of NativeType. The length is determined at runtime by the size of the actual marshaled array.

LPArray

| NativeType ‘[’ Int32 ‘]’

Array of Native Type of length lnt32.

LPArray

| NativeType

‘[’ ‘+’ Int32 ‘]’

Array of NativeType with runtime supplied element size. The int32 specifies a parameter to the current method (counting from parameter number 0) that, at runtime, will contain the size of an element of the array in bytes. Can only be applied to methods, not fields.

LPArray

| NativeType

‘[’ Int32 ‘+’ Int32 ‘]’

Array of NativeType with runtime supplied element size. The first int32 specifies the number of elements in the array. The second 1nt32 specifies which parameter to the current method (counting from parameter number 0) will specify the additional number of elements in the array. Can only be applied to methods, not fields

LPArray

 

[例子:

.method int32 M1( int32 marshal(int32), bool[] marshal(bool[5]) )

方法 M1 带了两个参数: 一个int32和一个带有5 bool的数组.

.method int32 M2( int32 marshal(int32), bool[] marshal(bool[+1]) )

方法M2带了两个参数: 一个 int32和一个 bool型数组: 数组元素的个数由第一个参数的值给定。

.method int32 M3( int32 marshal(int32), bool[] marshal(bool[7+1]) )

方法M3带了两个参数: 一个int32和一个 bool型数组: 数组元素的个数由第一个参数的值加上7给定.]

 

接下篇:ECMA-335 (CLI) 标准 读书笔记——总结CLI类型系统(下)

原文地址:https://www.cnblogs.com/cubean/p/1706657.html