在编译过程中表示和检查程序组件的一致性的可扩展类型***
技术领域
本发明涉及类型***,尤其涉及可扩展到新的和经更新的编程语言的类型***。
背景
类型***是在编程语言中用于协助检测和防止运行时出错的***。如果编程语言包含一组对于诸如变量、函数等对象声明的类型,且这些类型在以该语言编写的程序的编译期间对照一组规则来检查,则该编程语言是“类型化的”。如果以类型化语言编写的源代码违反了类型规则之一,则确定为编译器错误。
用于编译器的类型化的中间语言在过去几年中经受了研究团体的大量研究。它们增强了编译器的可靠性和健壮性,以及提供了一种跟踪和检查无用信息收集器所需的信息的***方法。其概念是具有一种在其上附加了类型且可以用类似于源程序的类型检查的方式来进行类型检查的中间表示。然而,类型化的中间语言更难以实现,因为在编译过程中把表示项的类型变得明确是必要的。
如果类型化的中间语言必须表示多个不同的高级编程语言,则它甚至更难以实现。不同的语言不仅具有不同的原语操作和类型,而且高级编程语言具有不同的类型化级别。例如,诸如汇编语言等某些语言一般是非类型化的。换言之,它们没有类型***。在类型化的语言中,某些是强类型化的,而其它是更松散地类型化的。例如,C++是一般被认为松类型化的语言,而ML或Pascal被认为是强类型化的语言。此外,松类型化的某些语言具有较小的语言子集,这些子集允许程序内的大部分代码段是强类型化的,而其它代码段是松类型化的。例如,C#和.NET中使用的微软中间语言(MSIL)允许这一类型化。因此,用于表示这些高级语言的任一种的类型化的中间语言必须能够表示不同的类型强度。同样,这一类型化的中间语言的类型***必须能够根据进行类型检查的代码的特征来实现不同的规则。
当贯穿整个编译过程降级类型化的中间语言时,会引发另一问题。语言的降级指的是将语言的形式从诸如程序员所编写的较高级形式改为诸如中间语言等较低级形式的过程。语言然后可从中间语言进一步降级到诸如机器相关的本机代码等接近于计算机执行的级别。为在编译过程中对被降级到不同级别的中间语言进行类型检查,必须对每一表示使用一组不同的规则。
创建类型化的中间语言的尝试通常无法解决上述问题。例如,Cedilla System的Special J编译器使用了一种类型化的中间语言。然而,这一编译器对于Java源语言是专用的,且因此不需要处理例如具有非类型安全代码的多种语言。另外,该编译器仅使用一组规则用于类型检查,且因此不能用于多个编译级别。在研究团体中,类型化的中间语言往往对源语言是高度专用的,因此难以为多个编译阶段工程实现(以及设计类型)。
概述
提供了一种用于检查各种形式的中间语言的一致性的类型表示、类型检查器、方法和编译器。具体地,类型化的中间语言适用于表示以多种(完全不同的)源语言编写的程序,这些源语言包括类型化的和非类型化的语言、松和强类型化的语言、以及带有和不带有无用信息收集的语言。另外,该类型检查器体系结构是可扩展的,以处置具有不同类型和原语操作的新语言。类型表示、类型检查器、方法和编译器包括各个方面。各个方面可分开且独立地使用,或者各个方面可以按各种组合和子组合来使用。
在一方面,提供了一种在编译器中对编程语言进行类型检查的方法。取一个或多个规则集作为对类型检查器的输入,类型检查器基于多个准则中的任何一个,或两个或多个的组合选择规则集中的一个或多个。在它们之中的是编译阶段、源语言、体系结构以及进行类型检查的语言中存在的类型化级别。语言然后使用所选择的一个或多个规则集进行类型检查。
在另一方面,提供了一种带有类型检查器的编译器,类型检查器基于多个准则中的任何一个,或两个或多个的组合构造一个或多个规则集。规则集可包括对应于强类型检查的一个规则集、对应于弱类型检查的一个规则集、对应于表示类型检查的一个规则集。弱规则集可允许类型化中的更多灵活性,诸如允许类型强制转换,而表示规则集可允许在中间程序表示的各部分中丢弃的类型信息。
在另一方面,提供了一种用于构造用于检查程序的中间表示的一致性的多个规则的编程接口。检查中间表示的一致性可包括向类型检查器提供多个规则,类型检查器基于预定准则向一个中间表示应用第一组规则,以及向另一中间表示应用第二组规则。
当参考附图阅读以下详细描述,可以清楚这些和其它方面。
附图简述
图1是通用编译过程的流程图。
图2是示出将源代码语句转换成高级表示,然后转换成机器相关的低级表示的表清单。
图3是示出用于在各个编译阶段对类型化的中间语言进行类型检查的编译器***的一个实施例的数据流程图。
图4是用于编译器***的类型检查器的框图。
图5是用于选择要由类型检查器应用的规则集的一种可能的过程的流程图。
图6是示出类型之间的分层关系的有向图。
图7是示出将类型添加到类型之间的分层关系的有向图。
图8是用于对照类型检查***中的类型规则检查指令的方法的流程图。
图9是担当类型检查***的一个实施例的操作环境的计算机***的示例的框图。
详细描述
提供了用于检查各种形式的中间语言的一致性的类型表示、类型检查器和编译器。类型检查器和编译器允许根据编程组件和/或编译阶段的源语言使用不同的类型和类型检查规则。例如,可能期望将高级优化器应用于以各种语言编写的程序。这些语言可具有不同的原语类型和原语操作。例如,一种语言可以包含用于复杂算术的类型和操作,而另一种语言可包含对计算机图形专用的类型和操作。通过允许由不同的类型***来参数化中间表示,优化器可用于具有不同原语类型和操作的语言。另一示例可包括其中某些组件以强类型化的语言子集来编写,而其它组件以非类型安全的完全语言来编写的程序。期望对于第一组组件进行更多的检错。这可以通过对不同的组件使用不同的类型检查规则来实现。又一示例是在编译期间丢弃类型信息。类型检查器和编译器可允许在较晚的阶段丢弃类型信息,而可在较早的阶段强迫维护精确的信息。这可以通过对不同的编译阶段结合不同的类型检查规则使用未知类型来实现。
图1示出了使用具有不同降级级别的类型化的中间语言来表示多种不同的源语言的***的通用编译过程。源代码100-106是以四种不同的源语言来编写的,这些源语言可以是类型化或不是类型化的,且具有不同的类型强度级别。例如,以C#编写的源代码100将比以C++编写的源代码106更强地类型化。源代码首先由读取器108处理并进入***。源语言然后被翻译成类型化的中间语言的高级中间表示(HIR)。HIR然后可在框110被可任选地分析并优化。HIR然后被翻译成类型2化的中间语言的中级中间表示(MIR)。该表示低于HIR,但是仍是机器无关的。在这一点上,MIR可如框112所示被可任选地分析并优化。MIR然后由代码生成在框114翻译成类型化的中间语言的机器相关的低级表示(LIR)。LIR然后可在框116被可任选地分析并优化,并在框118被提供给发放器。发放器将以表示读入***的原始源代码的多种格式120-126中的一种输出代码。贯穿整个过程,完成过程所必需的数据被储存在某一形式的持久存储器128中。
由此,该编译过程包括将中间语言指令从一个表示级别翻译成另一表示级别。例如,图2示出将源代码语句转换成HIR,以及将HIR转换成机器相关的LIR。源代码语句200可以用多种高级编程语言来编写。这些语言被设计成允许程序员以容易理解的方式读写代码。由此,允许程序员使用如“+”等字符用于加法,并允许使用更强大的形式,诸如添加如语句200中所示的两个以上操作数。
语句202-206是表示同一功能的语句200的HIR表示,但是以更接近于可由机器理解且仍是体系结构无关的格式来完成。语句202使用“ADD”命令来将第一和第二变量相加,并将结果赋值给第一临时变量t1。语句204然后使用另一“ADD”命令将t1与第三变量相加,并将结果赋值给第二临时变量t2。语句206然后使用“ASSIGN”指令将值t2赋值给结果变量z。
语句208-121是语句202-206的中间语言的LIR。语句208使用对x86体系结构专用的add指令将储存在指定寄存器处的两个变量的值相加,并将结果储存在被赋值给临时变量t1的寄存器中。语句210使用对x86体系结构专用的add指令来将值t1和储存在指定的寄存器处的第三变量相加,并将结果储存在被赋值给t2的指定寄存器(EAX)中。语句212然后使用对x86体系结构专用的move指令将储存在EAX中的值移至输出变量z。
为实现类型检查,类型化的中间语言包含显式或隐式表达的类型表示。显式类型表达式是直接在表示中声明的。例如,语句:
int a;
显式地将变量“a”定义为类型int。类型表示可通过为某些代码语句定义一默认类型来隐式地表达。例如,如果函数的默认返回类型是int,则语句:
f_start();
将声明没有任何形参并返回类型为int的值的函数f_start。
适用于多个表示级别处的多个编程语言的类型化的中间语言的类型表示的一个实施例在附录A中示出。应当注意,这仅是众多可能的实施例中的一个。
参考附录A,在类型类分层结构中定义了多个类型表示,使得各种语言的类型***可由类型化的中间语言来表示。抽象基类对于所有类型被定义为“Phx::Type”。该基类可包含例如“sizekind”中用于各种类型的大小信息,这些类型诸如实际、符号或未知(或可变)类型。基类也可包含“typekind”,以指定类型分类。另外,可提供外部类型,作为包装外部定义的类型的抽象类型,以提供从类型化的中间语言到原始源代码的反向映射。
在基类之下,被定义为“Phx::PtrType”的类可表示指针类型。也可定义各种指针。例如,受管的、已收集无用信息的指针(指向已收集无用信息的对象内的位置);受管的、未收集无用信息的指针(指向未收集无用信息的对象内的位置);非受管指针(诸如在以例如C++编写的代码中找到的);引用指针(指向已收集无用信息的对象的基类);以及空指针。
在分层结构中的同一级别处,被定义为“Phx::ContainerType”的类可表示容器类型,诸如包含内部成员的类型。内部成员可具有作用域、方法以及其它类型。被定义为“Phx::FuncType”的类可表示函数类型,包括任何必要的调用约定、形参列表和返回类型列表。同样,被定义为“Phx::UnmgdArrayType”的类可表示非受管的数组类型。在分层结构中的“Phx::ContainerType”下还可定义四个类。被定义为“Phx::ClassType”的类可表示类类型,被定义为“Phx::StructType”可表示结构类型,被定义为“Phx::InterfaceType”的类可表示接口类型,而被定义为“Phx::EnumType”的类可表示枚举类型。在分层结构中的“Phx:ClassType”下,被定义为“Phx::MgdArrayType”的另一个类可表示受管的数组类型。
在附录A所示的表示中,类“primtype”被定义为结构类型的特殊实例。“primtype”可包括诸如int、float、unknown(未知)、void、condition code(条件代码)、unsigned int(无符号整数)、xint等各种类型。这些表示可在类型化的中间语言的HIR和LIR中使用。
另外,目标专用的原语类型可被包括在类型表示中。某些语言具有复杂算术类型,如果类型***知道它们,则它们可被有效地处理。例如,考虑“MMX”指令。这一指令是被构建到某些版本的x86处理器中用于支持多媒体和通信数据类型上的单指令/多数据操作的一组外部指令集中的一个。类型***可被定制成以对类型表示的最小改变来识别并使用这些指令。
附录A中所示的类型表示的实施例也包括“unknown”类型,它可表示任何类型,并可任选地具有与其相关联的大小。大小是值的机器表示的大小。unknown类型允许编译器通过将类型信息从特定类型改变为unknown类型以受控的方式来丢弃类型信息。它允许编译器生成取决于所操纵的值的大小的代码,即使在类型是unknown的情况下。其它类型可使用unknown类型,因此unknown类型也允许部分类型信息的表示(其中某些但并非所有信息是已知的)。
例如,假定指向int类型的指针。在某一降级阶段,可能期望丢弃类型信息int。unknown类型允许编译器用unknown类型来替换int类型。类型检查器然后无需检查所关注的指针是否指向正确的类型。它本质上进行这样的冒险:即所指向的值将以在运行时不会不利地影响程序功能的方式来处理。
使用unknown类型的另一示例是用于为函数定义类型。如果调用具有指向unknwon的类型指针的形参的函数,其中形参先前已将类型指针指向int,则编译器必需相信传递了正确的类型。解除指针引用的结果可以已知或不是已知为int;然而,它可用作int。一个更复杂的示例是在虚拟函数调用从高级到低级中间表示的转换期间中间临时变量的引入。虚拟表(v表)在面向对象的语言中广泛用于实现虚拟调用。低级中间表示中作出虚拟函数调用的第一步是从存储器中取出对象的第一字段。第一字段包含指向v表的指针。取数据的结果然后被赋值给临时变量。构造临时变量的类型(表示指向v表的指针的类型,其中v表可具有许多字段)可以是复杂且难以表示的。相反,编译器可简单地向中间临时变量赋值“指向unknown的指针”。由此,对unknown类型的使用简化了较晚阶段的编译,在这些阶段中,保存详细类型信息是不必要的,或可能对编译器实现器表现出重大负担。
图3示出了用于在编译的各阶段对类型化的中间语言表示进行类型检查,并因此示出了在各个降低级别上对类型化的中间语言进行类型检查的编译器***的一个实施例。源代码300表示各种源语言中的任一种。源代码300被翻译成类型化的中间语言的HIR 302。通过这样做,源语言的类型表示被翻译成对于类型化的中间语言的内部类型表示。
如对于图1和2所解释的HIR贯穿整个编译过程被降级。为该图示的目的,示出了高(HIR)302、中(MIR)304以及低(LIR)306级表示。然而,该实施例不限于此。可对任意数量的编译阶段进行类型检查。
每一表示级别处的中间语言可以由类型检查器308进行类型检查。类型检查器308实现了用于向编译过程的每一阶段,并因此向中间语言的每一表示应用一个或多个规则集310的算法或过程。规则集310是为语言的各种属性,诸如源语言、编译阶段、何种类型化强度等设计的一组规则。
例如,假定源代码300包含以C++编程语言创作的代码。C++源代码300首先被翻译成类型化的中间语言的HIR 302。如有所需,在这一点上,类型检查器308可与HIR 302交互,以确定任何数量的属性。这些属性可包括编译阶段(HIR)、存在的源代码的类型(C++)、语言是否类型化(是)、是松类型化还是强类型化(松)等等。基于这些属性,类型检查器可选择一适当的规则集。一旦选择了一个规则集,类型检查器依照该规则集对HIR进行类型检查。一旦HIR被降级到MIR或LIR,将再次访问属性,并且相同或不同的规则集可以是适当的。
在一个实施例中,这些类型检查规则集可被提供给类型检查器。一个规则集可对应于“强”类型检查,诸如对C#或MSIL的类型检查是期望的。另一规则集可对应于“弱”类型检查,它可以是比“强”类型检查更松的类型检查。例如,弱类型检查规则集可以准许类型转换。类型强制转换是使一种类型的变量作为另一种类型来行动以供单次使用。例如,可使类型int的变量如char(字符)那样来行动。以下代码使用了类型转换来打印字母“P”。
int a;
a=80;
cout<<(char)a;
由此,即使“a”被定义为类型int,并被赋值80,但由于类型转换,cout语句将变量“a”作为类型char来对待,并因此显示“P”(ASCII值80)而非80。
最后,一个规则集可对应于“表示”检查。“表示”检查可允许中间程序表示的各部分中丢弃的类型信息,诸如通过使用unknown类型,并可包括指示这一类型信息何时被丢弃时或何时可用unknown类型替代另一类型时的规则。例如,返回类型Void的值的函数的结果可以禁止被赋值给unknown类型的变量。
另外,可在单个编译阶段使用一个以上规则集。例如,假定源代码300包含单个语言,但是包含强类型化的某些段和松类型化的某些段。类型检查器可对某些强类型化段的HIR使用一个规则集,并对松类型化的代码段使用另一规则集。
图4是在类似于图3所描述的编译器***中使用的类型检查器的框图。类型检查器400可接受对应于不同源语言和/或不同编译阶段的任意数量的规则集作为输入。在图4中,将四个规则集402-408提供给类型检查器400。规则集402表示用于具有强类型化语言的HIR的规则集,规则集404表示用于具有弱类型化语言的HIR的规则集,规则集406表示用于具有无类型化语言的HIR的规则集,而规则集408表示用于LIR的规则集。程序模块410表示具有HIR形式的强类型化的语言,而程序模块412表示在被降级到LIR之后的程序模块410。
类型检查器400基于正进行类型检查的程序模块的属性选择适当的规则集,并使用结合的过程或算法将所选择的规则集应用于程序模块。例如,类型检查器400可选择规则集402(表示用于具有强类型化语言的HIR的规则集),以对程序模块410(表示具有HIR形式的强类型化的语言)进行类型检查。随后,类型检查器400然后可选择规则集408(表示用于LIR的规则集),以对程序模块412(表示具有LIR形式的强类型化的语言)进行类型检查。
图5是用于选择由类型检查器应用的规则集的过程的一个可能实施例的流程图。在框500,类型检查器读入源代码的类型化中间表示的一个段,并且必需选择用于类型检查的规则集。判别框502确定类型化的中间语言是HIR、MIR还是LIR。
如果是HIR或MIR,则处理判别504以确定原始源代码是松类型化还是强类型化的。如果是松类型化的,则处理框506以选择对应于弱类型检查的规则集。如果是强类型化的,则处理框508以选择对应于强类型检查的规则集。
如果是LIR,则处理判别框510以选择对应于表示类型检查的规则集。应当注意,图5仅是一个实施例。可选择对应于且基于不同属性的任意数量的规则集。
所描述的类型检查***的规则集可被容易地扩展到完全新的语言,并也可被扩展到现有语言的新特征。例如,如果引入新的语言,则只需为该新语言创作新规则集。由于规则集与类型检查器或编译器本身是分离的,且被设计成接受规则集作为单独的实体,因此用于新语言的新规则集可被分发,而无需重新分发或更新现有的类型检查***或编译器。同样,如果新特征被添加到现有语言,诸如向C++添加XML支持,则在各编译阶段处对应于C++的规则集可被任意地动态重新配置以处理新特征。再一次,无需更新或分发新的核心***。
规则集也可允许对类型约束。例如,当类从另一类继承时是否允许对特定类型使用子类型化可以是在规则中描述的一个约束。另一约束可以是加框约束,诸如可能期望指示数据可被转换成包含数据的虚拟表。其它约束可包括大小约束,或指示相同原语类型的必要性的原语类型约束。与规则集的任何其它部分一样,新约束可如所需地添加。
由类型检查器使用的规则集可以通过用于创作规则集的应用程序编程接口来构造。该应用程序可构造规则,使得规则集在类型原语的分层结构中用分配给类型化中间语言的个别指令的规则来表示。分层结构可以用类型图的形式来表示,类型图明确地表达了与特定程序模块或编译单元有关的类型的各种元素。诸如符号和操作等IR元素与类型***的元素相关联。类型图节点描述了原语,并构造了类型及其关系,诸如组件、嵌套类型、函数签名、接口类型、分层结构元素以及诸如源名和对模块/汇编外部类型元素的引用等其它信息。
简单类型规则的一个示例如下:
ADD
N=add n,n
为本示例的目的,假定I是signed integer(带符号整数)类型,U是unsignedinteger类型,X是任一integer类型,F是float,N是上述的任一种。图6示出了这些类型之间的分层关系。类型N在分层结构的顶部。类型F和X从类型N向下分支以形成分层结构的后续层次。最后,类型U和I从X类型向下分支以形成分层结构的最低层。由此,对于“ADD”中间语言指令,依照该规则,仅类型N或分层结构中的较低层可由add指令来处理,且操作数在分层结构中必须不高于结果。例如,两个整数可相加,以产生整数(I=ADD i,i),或者一个整数和一个浮点数可相加以产生浮点数(F=ADD i,f)。然而,浮点数和整数不能相加来产生整数(I=ADD i,f)。
将类型原语表示为分层结构允许容易地改变规则集。在过去,类型规则通常在编程上使用源代码来表达。例如,类型检查器可包含实现类型检查器规则的大量开关语句。由此,改变规则要求修改类型检查器的源代码。然而,分层的规则集提供了更容易的可扩展性。考虑先前用于ADD指令的规则。如果开发者希望添加一个类型,例如复杂类型C,则可简单地在分层结构的N类型下方添加,如图7所示,且用于ADD指令的规则无需改变以如所需地运作。
用于在类型检查***中对照类型规则检查指令的一种方法在图8中示出。首先,对框800处理以在句法上检查指令。由此,考虑806处的指令,类型检查器确保依照用于ADD指令的类型规则存在正确数量的源和目标表达式(例如,在这一情况下,有2个源表达式以及1个目标表达式)。每一表达式(以及子表达式)可具有其上的中间表示的显式类型。在框802,类型检查器然后实际地验证e1、e2以及foo(e3)的显式类型符合用于ADD指令的类型规则。在框804,类型检查器在必要时遍历子层次以进一步对指令进行类型检查。例如,类型检查器可检查表达式e1、e2和foo(e3)与其显式类型相一致。例如,类型检查器可检查foo具有函数类型。它可检查函数类型的结果类型与foo(e3)上的显式类型相同。它还可检查有单个形参类型,以及类型e3与该类型相匹配。这确保对e3的调用的类型与类型规则相匹配。
图9示出了担当用于类型检查***的一个实施例的操作环境的计算机***的示例。计算机***包括个人计算机920,包括处理单元921、***存储器922以及将包括***存储器的各类***组件耦合至处理单元921的***总线923。***总线可以包括若干种总线结构类型的任一种,包括存储器总线或存储器控制器、***总线以及使用各类总线体系结构的局部总线,仅举几个例子,这类体系结构诸如PCI、VESA、微通道(MCA)、ISA和EISA。***存储器包括只读存储器(ROM)924和随机存取存储器(RAM)925。基本输入/输出***(BIOS)926,包含如在启动时协助在计算机920内的元件之间传输信息的基本例程,可储存在ROM 924中。个人计算机920也可包括硬盘驱动器927,例如用于对可移动磁盘929进行读写的磁盘驱动器928,以及例如用于读CD-ROM或对其它光介质进行读写的光盘驱动器930。硬盘驱动器927、磁盘驱动器928以及光盘驱动器930分别通过硬盘驱动器接口932、磁盘驱动器接口933和光盘驱动器接口939连接至***总线923。驱动器及其相关联的计算机可读介质为个人计算机920提供了数据、数据结构、计算机可执行指令(诸如动态链接库等程序模块以及可执行文件)等的非易失性存储。尽管对计算机可读介质的描述指的是硬盘、可移动磁盘以及CD,然而也可以包括计算机可读的其它类型的介质,包括盒式磁带、闪存卡、数字多功能盘、Bernoulli盒式磁盘、RAM、ROM等等。
多个程序模块可储存在驱动器和RAM 925中,包括操作***935、一个或多个应用程序936、其它程序模块937以及程序数据938。用户可以通过键盘940和定点设备(诸如鼠标942)向计算机920输入命令和信息。其它输入设备(未示出)可包括麦克风、操纵杆、游戏垫、圆盘式卫星天线、扫描仪等等。这些和其它输入设备通常通过耦合至***总线的串行端口接口949连接到处理单元921,但也可通过其它接口连接,如并行端口、游戏端口或通用串行总线(USB)。监视器947或另一显示设备也通过接口,如显示控制器或视频适配器948连接到***总线923。除监视器之外,个人计算机通常包括其它***输出设备(未示出),如扬声器和打印机。
个人计算机920可以使用到一个或多个远程计算机,如远程计算机949的逻辑连接在网络化环境中操作。远程计算机949可以是服务器、路由器、网络PC、对等设备或其它常见的网络节点,并通常包括许多或所有相对于个人计算机920所描述的元件,尽管在图9中仅示出了存储器存储设备950。图9描述的逻辑连接包括局域网(LAN)951和广域网(WAN)952。这类网络环境常见于办公室、企业范围计算机网络、内联网以及因特网。
当在LAN网络环境中使用时,计算机920通过网络接口或适配器953连接至局域网951。当在WAN网络环境中使用时,个人计算机920通常包括调制解调器954或用于通过广域网952,如因特网建立通信的其它装置。调制解调器954可以是内置或外置的,通过串行端口接口946连接至***总线923。在网络化环境中,相对于个人计算机920所描述的程序模块或其部分可储存在远程存储器存储设备中。可以理解,示出的网络连接是示例性的,也可以使用在计算机之间建立通信链路的其它手段。
示出并描述了所示实施例的原理之后,本领域的技术人员可以明白,可以在排列和细节上修改这些实施例而不脱离这些原理。
例如,此处的一个实施例描述了一个或多个规则集,它们可被提供给类型检查器或编译器,使得编译器或类型检查器基于进行类型检查的语言和/或编译阶段来选择一个或多个规则集以对语言进行类型检查。然而,作为替换,可将单个规则集提供给类型检查器或编译器,使得编译器或类型检查器在运行时静态或动态地、基于进行类型检查的语言和/或编译阶段从该单个规则集中构造一个或多个规则子集
鉴于许多可能的实施例,可以认识到,所示实施例仅包括示例,且不应当被认为是限制本发明的范围。相反,本发明由所附权利要求书来定义。因此,要求保护落入所附权利要求书的范围内的所有这样的实施例作为本发明。
附录A
//------------------------------------------------------------------------------//
//描述:
//
// IR类型
//
//
// 类型类分层结构 引入的描述和原语属性
// ---------------------- -----------------------------------
// Phx::Type -类型的抽象基类
// Phx::PtrType -指针类型
// Phx::ContainerType -容器类型(具有成员的类型)
// Phx::ClassType -类类型
// Phx::MgdArrayType -受管数组类型
// Phx::StructType -结构类型
// Phx::InterfaceType -接口类型
// Phx::EnumType -枚举类型
// Phx::FuncType -函数类型
// 属性:ArgTypes,ReturnType
//
// Phx::UnmgdArrayType -受管数组
// 属性:Dim,Referent
//
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//
// 描述:
//
// 用于IR类型的基类
//
//------------------------------------------------------------------------------
_abstract_public_gc
class Type:public Phx::Object
{
public:
//用于比较类型的函数
virtual Boolean IsAssignable(Phx::Type*srcType);
virtual Boolean IsEqual(Phx::Type*type);
public:
//公有属性
DEFINE_GET_PROPERTY(Phx::TypeKind, TypeKind, typeKind);
DEFINE_GET_PROPERTY(Phx::SizeKind, SizeKind, sizeKind);
DEFINE_GET_PROPERTY(Phx::BitSize, BitSize, bitSize);
DEFINE_GET_PROPERTY(Symbols::ConstSym*,ConstSym, constSym);
DEFINE_GET_PROPERTY(Phx::ExternalType*,ExternalType,externalType);
DEFINE_GET_PROPERTY(Phx::PrimTypeKindNum,PrimTypeKind,primTypeKind);
GET_PROPERTY(Phx::TypeSystem*,TypeSystem);
protected:
//受保护域
Phx::TypeKind typeKind; //type classification
Phx::SizeKind sizeKind; //size classification
Phx::BitSize bitSize; //size in bits when constant
Symbols::ConstSym* constSym; //size in bits when symbolic
Phx::PrimTypeKindNum primTypeKind;
Phx::ExternalType*externalType;//optionally null
};
//--------------------------------------------------------------
//
// 描述:
//
// 容器类型-用于具有成员的类型的抽象类
//
//--------------------------------------------------------------
_abstract_public_gc
class ContainerType:public QuantifiedType,public IScope
{
DEFINE_PROPERTY(Symbols::FieldSym*,FieldSymList,fieldSymList);
private:
//私有域
Symbols::FieldSym * fieldSymList;
};
//--------------------------------------------------------------
//
// 描述:
//
// 类容器类型
//
//--------------------------------------------------------------
_public_gc
class ClassType:public ContainerType
{
public:
//公有静态构造函数
static Phx::ClassType*New
(
Phx::TypeSystem* typeSystem,
Phx::BitSize bitSize,
Phx::ExternalType* externalType
);
public:
//公有属性
DEFINE_GET_PROPERTY(Phx::Type*,UnboxedType, unboxedType);
DEFINE_PROPERTY( ClassType*,ExtendsClassType,extendsClassType);
DEFINE_GET_PROPERTY(Phx::Collections::InterfaceTypeList*,
ExplicitlyImplements,explicitlyImplements);
protected:
//受保护属性
DEFINE_SET_PROPERTY(Phx::Collections::InterfaceTypeList*,
ExplicitlyImplements,explicitlyImplements);
private:
//私有域
Phx::Type* unboxedType;
Phx::ClassType* extendsClassType;
Phx::Collections::InterfaceTypeList*explicitlyImplements;
};
//---------------------------------------------------------------------------
//
//类:StructType
//
//描述:
//
// 结构类型
//
//
//---------------------------------------------------------------------------
_public_gc
class StructType:public ContainerType
{
public:
//公有静态构造函数
static Phx::StructType*New
(
Phx::TypeSystem* typeSystem,
Phx::BitSize bitSize,
Phx::ExternalType* externalType
);
public:
//公有属性
DEFINE_GET_PROPERTY(Phx::ClassType*,BoxedType,boxedType);
private:
//私有域
Phx::ClassType*boxedType;
};
//---------------------------------------------------------------------------
//
//类:PrimType
//
//描述:
//
// 原语类型
//
//---------------------------------------------------------------------------
_public_gc
class PrimType:public StructType
{
public:
//公有静态构造函数
static Phx::PrimType*
New
(
Phx::TypeSystem* typeSystem,
Phx::PrimTypeKindNum primTypeKind,
Phx::BitSize bitSize,
Phx::ExternalType* externalType
);
public:
//公有方法
static Phx::PrimType*
GetScratch
(
Phx::PrimType*type,
PrimTypeKindNum kind,
Phx::BitSize bitSize
);
Phx::PrimType*GetResized
(
Phx::BitSize bitSize
);
public:
//公有属性
DEFINE_GET_PROPERTY(Phx::TypeSystem*,TypeSystem,typeSystem);
private:
//私有域
Phx::TypeSystem* typeSystem;
};
//---------------------------------------------------------------------------
//
//类:InterfaceType
//
//描述:
//
// 接口类型
//
//---------------------------------------------------------------------------
_public_gc
class InterfaceType:public ContainerType
{
public:
//公有静态构造函数
static Phx::InterfaceType*New
(
Phx::TypeSystem* typeSystem,
Phx::ExternalType* externalType
);
public:
//公有属性
DEFINE_PROPERTY(Phx::ClassType*,ExtendsClassType,extendsClassType);
DEFINE_GET_PROPERTY(Phx::Collections::InterfaceTypeList*,
ExplicitlyImplements,explicitlyImplements);
protected:
//受保护属性
DEFINE_SET_PROPERTY(Phx::Collections::InterfaceTypeList*,
ExplicitlyImplements,explicitlyImplements);
private:
//私有域
Phx::ClassType* extendsClassType;
Phx::Collections::InterfaceTypeList*explicitlyImplements;
};
//---------------------------------------------------------------------------
//
//类:EnumType
//
// 描述、:
//
// 枚举类型
//
//---------------------------------------------------------------------------
_public_gc
class EnumType:public ContainerType
{
public:
// 公有静态构造函数
static Phx::EnumType*New
(
Phx::TypeSystem* typeSystem,
Phx::ExternalType* externalType,
Phx::Type* underLyingType
);
public:
//公有属性
DEFINE_GET_PROPERTY(Phx::ClassType*,BoxedType,boxedType);
DEFINE_GET_PROPERTY(Phx::Type*,UnderlyingType,underlyingType);
private:
//私有域
Phx::Type*underlyingType;
Phx::ClassType*boxedType;
};
//---------------------------------------------------------------------------
//
// 类:MgdArrayType
//
// 描述:
//
// 受管数组类型
//
//
//---------------------------------------------------------------------------
_public_gc
class MgdArrayType:public ClassType
{
public:
//公有静态构造函数
static Phx::MgdArrayType*New
(
Phx::TypeSystem* typeSystem,
Phx::ExternalType* externalType,
Phx::Type* elementType
);
public:
// 公有属性
DEFINE_GET_PROPERTY(Phx::Type*,ElementType,elementType);
private:
// 私有域
Phx::Type*elementType;
};
//------------------------------------------------------------
//
// 类:UnmgdArrayType
//
// 描述:
//
// 非受管数组类型
//
//
//------------------------------------------------------------
_public_gc
class UnmgdArrayType:public Type
{
public:
// 公有静态构造函数
static Phx::UnmgdArrayType* New
(
Phx::TypeSystem* typeSystem,
Phx::BitSize bitSize,
Phx::ExternalType* externalType,
Phx::Type* referentType
);
public:
// 公有属性
DEFINE_GET_PROPERTY(int, Dim, dim);
DEFINE_GET_PROPERTY(Phx::Type*,Referent, referent);
private:
// 私有域
int dim;
Phx::Type* referent;
};
//---------------------------------------------------------------------------
//
// 描述:
//
// 指针类型
//
//
//---------------------------------------------------------------------------
_public_gc
class PtrType:public Type
{
public:
//公有静态构造函数
static Phx::PtrType*New
(
Phx::TypeSystem* typeSystem,
Phx::PtrTypeKind ptrTypeKind,
Phx::BitSize bitSize,
Phx::Type* referent,
Phx::ExternalType* externalType
);
// 不带所指向的类型的构造函数
static Phx::PtrType*New
(
Phx::TypeSystem* typeSystem,
Phx::PtrTypeKind ptrTypeKind,
Phx::BitSize bitSize,
Phx::ExternalType* externalType
);
public:
//公有属性
DEFINE_GET_PROPERTY(Phx::PtrTypeKind,PtrTypeKind,ptrTypeKind);
DEFINE_GET_PROPERTY(Phx::Type*, Referent, referent);
private:
// 私有域
Phx::PtrTypeKind ptrTypeKind;
Phx::Type* referent;
};
//---------------------------------------------------------------------------
//
// 枚举:CallingConvention
//
// 描述:
//
// 表示调用约定类型的初步枚举
//
//---------------------------------------------------------------------------
BEGIN_ENUM(CallingConventionKind)
{
_Illegal=0,
CLRCall,
CDecl,
StdCall,
ThisCall,
FastCall
}
END_ENUM(CallingConventionKind);
//---------------------------------------------------------------------------
//
// 类:FuncType
//
// 描述
//
// 函数类型
//
//
//---------------------------------------------------------------------------
_public_gc
class FuncType:public QuantifiedType
{
public:
// 公有静态构造函数
public:
// 公有方法
Int32 CountArgs();
Int32 CountRets();
Int32 CountArgsForInstr();
Int32 CountRetsForInstr();
Int32 CountUserDefinedArgs();
Int32 CountUserDefinedRets();
Phx::FuncArg* GetNthArgFuncArg(Int32index);
Phx::FuncArg* GetNthRetFuncArg(Int32index);
Phx::FuncArg* GetNthArgFuncArgForInstr(Int32index);
Phx::FuncArg* GetNthRetFuncArgForInstr(Int32index);
Phx::FuncArg* GetNthUserDefinedArgFuncArg(Int32index);
Phx::FuncArg* GetNthUserDefinedRetFuncArg(Int32index);
Phx::Type* GetNthArgType(Int32index);
Phx::Type* GetNthRetType(Int32index);
Phx::Type* GetNthArgTypeForInstr(Int32index);
Phx::Type* GetNthRetTypeForInstr(Int32index);
Phx::Type* GetNthUserDefinedArgType(Int32index);
Phx::Type* GetNthUserDefinedRetType(Int32index);
public:
// 公有属性
DEFINE_GET_PROPERTY(Phx::CallingConventionKind, CallingConvention,callingConvention);
GET_PROPERTY(Phx::Type*, RetType);
// 如果该函数类型具有省略的函数形参则为真
GET_PROPERTY(Boolean, IsVarArgs);
GET_PROPERTY(Boolearn,IsInstanceMethod);
GET_PROPERTY(Boolean, IsClrCall);
GET_PROPERTY(Boolean, IsCDecl);
GET_PROPERTY(Boolean, IsStdCall);
GET_PROPERTY(Boolean, IsThisCall);
GET_PROPERTY(Boolean, IsFastCall);
// 如果该函数具有返回值则不为真
GET_PROPERTY(Boolean,ReturnsVoid);
protected:
// 受保护域
Phx::CallingConventionKind callingConvention;
Phx::FuncArg* argFuncArgs;
Phx::FuncArg* retFuncArgs;
};
//-----------------------------------------------------------------------
//
// 描述:
//
// 编译期间使用的全局类型***
//
//
//-----------------------------------------------------------------------
__public__gc
class TypeSystem:public Phx::Object
{
public:
// 公有静态构造函数
static TypeSystem*
New
(
Phx::BitSize regIntBitSize,
Phx::BitSize nativeIntBitSize,
Phx::BitSize nativePtrBitSize,
Phx::BitSize nativeFloatBitSize,
);
public:
// 公有方法
void Add(Type*type);
public:
// 创建的类型的列表
DEFINE_GET_PROPERTY(Phx::Type*,AllTypes, allTypes);
private:
// ***中所有类型的列表
Phx::Type*allTypes;
};
//---------------------------------------------------------------------------
//
// 描述:
//
// 描述类型的各种枚举
//
//---------------------------------------------------------------------------
// 用于IR类型的类和值类型
// 不同种类的类型
BEGIN_ENUM(TypeKind)
{
_Illegal=0,
Class,
Struct,
Interface,
Enum,
MgdArray,
UnmgdArray,
Ptr,
Func,
Variable,
Quantifier,
Application,
TypedRef,
}
END_ENUM(TypeKind);
// 不同种类的类型大小
BEGIN_ENUM(SizeKind)
{
_Illegal=0,
Constant,
Symbolic,
Unknown
}
END_ENUM(SizeKind);
//不同类型的指针
BEGIN_ENUM(PtrTypeKind)
{
_Illegal=0,
ObjPtr, //指向整个对象的_gc指针
MgdPtr, //指向内部对象的_gc指针
UnmgdPtr, //_nogc指针
NullPtr, //不指向任何内容的指针
NumPtrTypeKinds
}
END_ENUM(PtrTypeKind);
}