在編譯過程中表示和檢查程序組件的一致性的可擴展類型系統的製作方法
2023-06-21 07:00:46 1
專利名稱:在編譯過程中表示和檢查程序組件的一致性的可擴展類型系統的製作方法
技術領域:
本發明涉及類型系統,尤其涉及可擴展到新的和經更新的程式語言的類型系統。
背景類型系統是在程式語言中用於協助檢測和防止運行時出錯的系統。如果程式語言包含一組對於諸如變量、函數等對象聲明的類型,且這些類型在以該語言編寫的程序的編譯期間對照一組規則來檢查,則該程式語言是「類型化的」。如果以類型化語言編寫的原始碼違反了類型規則之一,則確定為編譯器錯誤。
用於編譯器的類型化的中間語言在過去幾年中經受了研究團體的大量研究。它們增強了編譯器的可靠性和健壯性,以及提供了一種跟蹤和檢查無用信息收集器所需的信息的系統方法。其概念是具有一種在其上附加了類型且可以用類似於源程序的類型檢查的方式來進行類型檢查的中間表示。然而,類型化的中間語言更難以實現,因為在編譯過程中把表示項的類型變得明確是必要的。
如果類型化的中間語言必須表示多個不同的高級程式語言,則它甚至更難以實現。不同的語言不僅具有不同的原語操作和類型,而且高級程式語言具有不同的類型化級別。例如,諸如彙編語言等某些語言一般是非類型化的。換言之,它們沒有類型系統。在類型化的語言中,某些是強類型化的,而其它是更鬆散地類型化的。例如,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元素與類型系統的元素相關聯。類型圖節點描述了原語,並構造了類型及其關係,諸如組件、嵌套類型、函數籤名、接口類型、分層結構元素以及諸如源名和對模塊/彙編外部類型元素的引用等其它信息。
簡單類型規則的一個示例如下ADDN=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_gcclass 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 classificationPhx::SizeKind sizeKind; //size classificationPhx::BitSize bitSize; //size in bits when constantSymbols::ConstSym* constSym;//size in bits when symbolicPhx::PrimTypeKindNum primTypeKind;Phx::ExternalType*externalType;//optionally null};//--------------------------------------------------------------//// 描述//// 容器類型-用於具有成員的類型的抽象類////--------------------------------------------------------------_abstract_public_gcclass ContainerTypepublic QuantifiedType,public IScope{DEFINE_PROPERTY(Symbols::FieldSym*,FieldSymList,fieldSymList);private//私有域Symbols::FieldSym * fieldSymList;};//--------------------------------------------------------------//// 描述//// 類容器類型////--------------------------------------------------------------_public_gcclass ClassTypepublic 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_gcclass StructTypepublic 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_gcclass PrimTypepublic StructType{public//公有靜態構造函數static Phx::PrimType*New(Phx::TypeSystem* typeSystem,Phx::PrimTypeKindNumprimTypeKind,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_gcclass InterfaceTypepublic 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_gcclass EnumTypepublic 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_gcclass MgdArrayTypepublic 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_gcclass UnmgdArrayTypepublic Type{public// 公有靜態構造函數static Phx::UnmgdArrayType* New(Phx::TypeSystem*typeSystem,Phx::BitSizebitSize,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_gcclass PtrTypepublic 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::BitSizebitSize,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_gcclass FuncTypepublic 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::CallingConventionKindcallingConvention;Phx::FuncArg* argFuncArgs;Phx::FuncArg* retFuncArgs;};//-----------------------------------------------------------------------//// 描述//// 編譯期間使用的全局類型系統//////-----------------------------------------------------------------------__public__gcclass TypeSystempublic Phx::Object{public// 公有靜態構造函數static TypeSystem*New(Phx::BitSizeregIntBitSize,Phx::BitSizenativeIntBitSize,Phx::BitSizenativePtrBitSize,Phx::BitSizenativeFloatBitSize,);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);}
權利要求
1.一種依照一個或多個規則集在編譯器中對程式語言進行類型檢查的方法,包括基於當前編譯階段選擇所述規則集的一個或多個;以及基於所選擇的一個或多個規則集對所述程式語言進行類型檢查。
2.如權利要求1所述的方法,其特徵在於,選擇所述規則集的一個或多個是基於所述程式語言的特徵而非所述編程階段。
3.如權利要求2所述的方法,其特徵在於,所述程式語言的特徵描述了所述語言的類型系統。
4.如權利要求1所述的方法,其特徵在於,對所述程式語言進行類型檢查包括對所述程式語言的多個中間表示的每一個進行類型檢查。
5.如權利要求4所述的方法,其特徵在於,所選擇的一個或多個規則集對每一表示是不同的。
6.如權利要求4所述的方法,其特徵在於,選擇所述規則集的一個或多個是基於進行類型檢查的表示的特徵而非所述編譯階段。
7.如權利要求1所述的方法,其特徵在於,所述程式語言包括指示所述程式語言的元素可以是多個類型中的一個。
8.如權利要求7所述的方法,其特徵在於,所述一個或多個規則集包含用於對指示所述程式語言的元素可以是多個類型中的一個的類型進行類型檢查的規則。
9.如權利要求1所述的方法,其特徵在於,所述一個或多個規則集包括分層格式的多個規則。
10.如權利要求1所述的方法,其特徵在於,所述一個或多個規則集包括對應於強類型檢查的一個規則集、對應於弱類型檢查的一個規則集、以及對應於表示類型檢查的一個規則集。
11.如權利要求10所述的方法,其特徵在於,所述表示類型檢查允許對所述程式語言的元素丟棄的類型信息。
12.如權利要求10所述的方法,其特徵在於,所述弱類型檢查允許類型強制轉換。
13.一種用於編譯以源語言編寫的原始碼的編譯器,包括多個類型規則;類型檢查器,它基於所述源語言從所述多個類型規則中選擇類型規則的子集來構造規則集。
14.如權利要求13所述的編譯器,其特徵在於,所述類型規則子集是基於所述原始碼的中間表示而非所述源語言來選擇的。
15.如權利要求13所述的編譯器,其特徵在於,所述類型規則的子集是基於編譯階段而非所述源語言來選擇的。
16.如權利要求13所述的編譯器,其特徵在於,構造三種規則集對應於強類型檢查的一個規則集、對應於弱類型檢查的一個規則集、以及對應於表示類型檢查的一個規則集。
17.如權利要求16所述的編譯器,其特徵在於,所述表示類型檢查允許對所述原始碼的元素丟棄的類型信息。
18.如權利要求16所述的編譯器,其特徵在於,所述弱類型檢查允許類型強制轉換。
19.一種用於對以多種源語言創作的原始碼進行類型檢查的類型檢查系統,包括多個規則集;以及類型檢查器,其中,所述類型檢查器選擇一個或多個規則集以在多個表示處應用於所述原始碼。
20.如權利要求19所述的系統,其特徵在於,所選擇的一個或多個規則集是基於所述源語言的一個或多個特徵來選擇的。
21.如權利要求19所述的系統,其特徵在於,所述類型檢查器是編譯器的一部分。
22.如權利要求19所述的系統,其特徵在於,所述多個規則集的每一個對應於特定的源語言。
23.如權利要求19所述的系統,其特徵在於,所述多個規則集的每一個對應於特定的類型檢查強度。
24.一種在編譯器中分析被表示為類型化的中間表示的原始碼的方法,包括基於所述類型化的中間表示從不同的規則集中選擇一個規則集;以及基於所選擇的規則集分析所述類型化的中間表示。
25.如權利要求24所述的方法,其特徵在於,選擇規則集是基於編譯過程中的一系列步驟中的哪一步驟產生的所述類型化的中間表示。
26.如權利要求24所述的方法,其特徵在於,選擇規則集是基於從其中產生所述類型化的中間表示的源語言。
27.如權利要求24所述的方法,其特徵在於,選擇規則集是基於處理器體系結構。
28.如權利要求24所述的方法,其特徵在於,選擇規則集是基於所述類型化的中間表示是表示驗證的還是未驗證的代碼。
29.如權利要求24所述的方法,其特徵在於,選擇規則集是基於所述類型化的中間表示是表示類型安全的代碼還是非類型安全的代碼。
30.如權利要求24所述的方法,其特徵在於,選擇規則集是基於所述類型化的中間表示是表示類型化的代碼還是非類型化的代碼。
31.如權利要求24所述的方法,其特徵在於,選擇規則集是基於所述類型化的中間表示是表示強類型化的代碼還是弱類型化的代碼。
32.一種包含用於實現如權利要求24所述的方法的計算機可執行指令的計算機可讀介質。
33.一種編程接口,包括用於構造用於檢查程序的中間表示的一致性的多個規則的裝置,其中,檢查所述程序的中間表示的一致性包括向類型檢查器提供多個規則,所述類型檢查器可用於將所述多個規則的第一集合應用於第一中間表示,並將所述多個規則的第二集合應用於第二中間表示。
34.一種包含用於實現如權利要求1所述的方法的計算機可執行指令的計算機可讀介質。
全文摘要
提供了用於各種形式的中間語言校驗的一致性的類型表示、類型檢查器和編譯器。在編譯器中對程式語言進行類型檢查是通過取一個或多個規則集作為對類型檢查器的輸入來實現的,類型檢查器基於多個準則中的任一個或兩個或多個的組合來選擇一個或多個規則集。它們之中有編譯階段、源語言、體系結構以及進行類型檢查的語言中存在的類型化級別。語言然後使用所選擇的一個或多個規則集來進行類型檢查。規則集可包括對應於強類型檢查的一個規則集、對應於弱類型檢查的一個規則集、以及對應於表示類型檢查的一個規則集。作為替換,可提供具有基於先前提到的準則的的任一個,或兩個或多個的組合從一較大的規則集在運行時選擇一個或多個規則集的類型檢查器的編譯器。
文檔編號G06FGK1875345SQ200480018112
公開日2006年12月6日 申請日期2004年5月21日 優先權日2003年6月27日
發明者M·R·普萊斯科, 小D·R·塔迪提 申請人:微軟公司