欧美在线观看视频网站,亚洲熟妇色自偷自拍另类,啪啪伊人网,中文字幕第13亚洲另类,中文成人久久久久影院免费观看 ,精品人妻人人做人人爽,亚洲a视频

增量連接系統(tǒng)的制作方法

文檔序號:6408217閱讀:327來源:國知局
專利名稱:增量連接系統(tǒng)的制作方法
技術(shù)領(lǐng)域
本發(fā)明涉及計算機輔助軟件工程(CASE),尤其涉及面向人的目標編程系統(tǒng)(HOOPS),該系統(tǒng)為計算機程序建立提供了交互和動態(tài)環(huán)境。面向人的目標編程系統(tǒng)(HOOPS)使程序員得以由優(yōu)化增量編譯程序而對計算機程序中的微小的顆粒源碼進行編輯。本發(fā)明的主題是一增量連接程序,它在HOOPS中操作以生成由一個輸入程序所用的文件。本發(fā)明是以使用通用的面向目標編程的(OOP)語言、C++作為最佳實施例的,但其原理也適用于面向目標的以及過程計算機編程語言,本發(fā)明亦可用于建立使用常規(guī)的和OOP語言的程序。
OOP是建立用戶使用方便的以及智能計算機軟件的最佳環(huán)境。OOP的要素是數(shù)據(jù)密封性(data encapsulation),繼承性(inheritance)以及多形性(Polymorphism)。這些元素可以用于產(chǎn)生圖形用戶接口(GUI),尤其是產(chǎn)生具有圖符、鼠標光標以及選項單視窗環(huán)境的為特征的。所構(gòu)成的GUI。雖然這三種要素屬OOP語言所共有,但在實施方式上大部分OOP語言彼此間有很大的區(qū)別。
OOP語言的例子包括Smalltalk、目標Pascal和C++。Smalltalk實際上不止是一種語言,更準確地講,它應(yīng)該被認為一種編程環(huán)境。該語言是在70年代早期施樂普拉阿圖研究中心(PARC)的研究部開發(fā)的。在該語言中,一個信息被送到一個目標以對其進本身行評價。信息完成的任務(wù)類似于在常規(guī)編程語言中的功能調(diào)用。程序員無需關(guān)心數(shù)據(jù)類型而只須關(guān)心生成正確順序的信息及使用正確的信息。Object Pas-cal是用于蘋果公司的Machintesh 計算機上的語言,蘋果公司在Pascal語言的設(shè)計者一尼古拉斯·沃斯(Niklaus.With)—的合作下開發(fā)出了Object Paseal語言。C++語言則是由斯托斯特拉普(Bjarne Stroustrup)在1983年在AT&T貝爾實驗室開發(fā)而成的,它出C語言的擴展。C++的主要概念是分類,它是用戶定義型的。分類提供了面向目標的編程特性。C++模型與C模型相兼容而且可隨意聯(lián)接,從而現(xiàn)有的C程序庫可由C++程序所用。最廣泛使用的基于目標和面向目標的編程語言源于60年代由挪威的戴沃(O-J.Dah1)梅·阿漢(B.Myhrhaug)以及耐·培得(K.Nygard)所開發(fā)的Simula語言。有關(guān)OOP的信息可參見布克(Grady Booch)所著的“Object Oriented Design with Applications”(Benjimin/Cum-mings Publishing Co.,Inc.,Readwood city,California,1991)。
運行一個計算機程序的完整過程涉及把程序員寫出的源碼譯為機器可執(zhí)行的格式,通常稱為目標碼,然后再執(zhí)行該目標碼。翻譯的過程是由編譯程序或解釋程序完成。在解釋程序中,翻譯是隨程序的運行而進行的;而在編譯程序中,則是在運行該程序之前就進行翻譯并將結(jié)果作為目標碼存貯起來。也就是說,在一般的編譯和執(zhí)行系統(tǒng)中,翻譯和執(zhí)行是分開進行的,即編譯只進行一次。而在解釋系統(tǒng)中,例如Smalltalk解釋程序,兩者是順序進行。因為直到一個目標被實現(xiàn)之前,編程環(huán)境的性質(zhì)不允許指定專用寄存器或地址空間,所以,Smalltalk需要解釋程序。
一個編譯程序包括三部分;詞法分析程序,語法分析程序,以及代碼生成程序。詞法分析程序的輸入是代表高級語言程序的一序列字符。詞法分析程序?qū)⒃撔蛄蟹譃橐粋€標記序列以輸入到語法分析程序。語法分析程序進而將該序列標記分為指令并利用語法規(guī)則的數(shù)據(jù)庫來確定是否每條指令的語法正確與否。若不正確,則產(chǎn)生錯誤信息。若正確,則指令被分解為一基本指令系列。這些基本指令被送至代碼生成程序以產(chǎn)生低級語言。代碼生成程序本身通常又分為三部分;中間代碼生成,代碼優(yōu)化,以及代碼生成?;径?,代碼生成程序接收來自語法分析程序的輸出并生成機器語言碼。
為有助于軟件開發(fā)而開發(fā)出了增量編譯程序,其中,編譯程序在批處理操作中生成用于接收的一條語句或一組語句的代碼,而與稍后生成的用于其他語句的代碼無關(guān)。增量編譯的優(yōu)點在于只有被一轉(zhuǎn)變所影響的代碼才被編譯。這一行為導(dǎo)致了極快的編譯和調(diào)試代碼的周期。
優(yōu)化編譯程序產(chǎn)生高度優(yōu)化的目標碼。從而在許多情況下使得在源級進行調(diào)試比一個非優(yōu)化編譯程序更困難。這一問題源于這一事實,即雖然一個例行程序?qū)⒈痪幾g以給出適當?shù)拇鸢?,但計算該答案的確切方式可能與源碼中描述的大相徑庭。優(yōu)化編譯程序可以實現(xiàn)的一些事情,包括刪除被確認屬不會影響最終結(jié)果的代碼或變量,將非變量代碼移出循環(huán),合成公用碼,在變量不再需要時重新使用分配給這些變量的寄存器等等。如此,源碼到目標碼或目標碼到源碼的映射在給定某些優(yōu)化時可能會有困難。由于變量的值可能并非在例行程序中任意位置處總是可用的,所以可能難于校驗變量的值。在優(yōu)化代碼中修改變量值既使不是完全不可能,也是尤為困難。除非專門說明為易失的,否則編譯程序會“記住”分配給變量的值并可能在以后的代碼中不再讀該變量而使用“已知”的值。因此,在該值中的改變產(chǎn)生了錯誤的程序結(jié)果。
雖然在先有技術(shù)的計算機程序設(shè)置、測試以及開發(fā)中有許多優(yōu)點,但已知的軟件開發(fā)工具仍給程序員帶來極大負擔,從而通常要求有直覺的洞悉力。其次,常規(guī)的面向批處理的編程系統(tǒng)需要很長的編輯——編譯——測試周期,這對編程的創(chuàng)造性行為帶來的極大的不利影響。
一旦在常規(guī)編程系統(tǒng)中完成了編譯,稱為裝入程序的程序?qū)?zhí)行裝入和連接編輯這樣兩個功能。該裝入處理包括獲取可重新定位的機器碼,修改可重新定位的地址,并把存儲器中修改后的數(shù)據(jù)和指令放入適當?shù)奈恢谩6B接編輯程序則從幾個有可能重新定位的機器碼的文件中生成一個程序。這些文件可以是幾個不同編譯的結(jié)果。
因此,本發(fā)明的一個目的是提供一種增量連接程序,該增量連接程序在用于建立計算機程序的面向人的交互動態(tài)處理中操作。
在交互動態(tài)的建立過程中,程序建立可由增量程序模式(稱為項目Project)和三個主要功能性交互而成。一個程序被成型為語義單元,該語義單元被稱之為成分并由稱為特性的命名數(shù)據(jù)項目表構(gòu)成。不是象常規(guī)系統(tǒng)那樣把程序作為一個松散的文件集合存儲起來。本發(fā)明的面向人的目標編程系統(tǒng)把項目中有關(guān)程序的所有信息存起來。本發(fā)明的計算機程序的建立有助于使程序員的生產(chǎn)力大為提高。
根據(jù)本發(fā)明,提供了一種增量連接程序,它在HOOPS運行并且其功能連到現(xiàn)有的執(zhí)行程序,從而避免對一組完整的目標文件進行再處理。在本發(fā)明的實施中,計算機程序被成型為一個部件集,為計算機程序提供模型的部件被存儲以便在建立處理中被存取。存儲的部件被依序存取,而且用一個編譯程序計算與每個部件關(guān)聯(lián)的相關(guān)性以開發(fā)一個相關(guān)性表。然后,根據(jù)相關(guān)性表編譯部件以產(chǎn)生一個更新過的目標模型。最后,更新的目標模型通過對現(xiàn)有可執(zhí)行文件的更新而被連接。
本發(fā)明的最佳實施例以C++完成的并用C++C以及匯編語言進行的程序建立,這些語言是當前最流行使用的。本發(fā)明的程序的建立一般可用這三種語言完成。雖然本發(fā)明本身是以面向目標的編程語言寫成的面向目標的程序,但其并不僅限于以面向目標的程序語言建立程序。本發(fā)明可同樣用于以過程語言建立程序。進而,本發(fā)明不限于C++語言,它也可由其他編程語言實現(xiàn)。而且本發(fā)明不限于只用于這三種語言;也就是說,本發(fā)明的原理可用于更為一般應(yīng)用的面向人的目標編程系統(tǒng)。
上述的以及其它目的,所涉及的方面及其優(yōu)點可從下面參考附圖對本發(fā)明的最佳實施例的詳細敘述有更好的理解。其中,

圖1展示了一種可以支持高分辨率圖形顯示設(shè)備和光標指示設(shè)備(例如鼠標器)的常規(guī)計算機系統(tǒng),本發(fā)明即可在該系統(tǒng)上實施;圖2是圖1所示計算機系統(tǒng)的主要部件框圖;圖3是構(gòu)成一個程序的部件集的概念形式框圖;圖4是本發(fā)明的原理功能框圖;圖5A到圖5D為通過建立狀態(tài)(BuildState)寄存編輯變化的邏輯流程圖;圖6是根據(jù)本發(fā)明在建立處理操作的第一階段確定可能的部件的邏輯流程圖;圖7是根據(jù)本發(fā)明在建立處理操作的第二階段對界面進行處理的邏輯流程圖;圖8是根據(jù)本發(fā)明在建立處理操作的第三階段對實施進行處理的邏輯流程圖;圖9是根據(jù)本發(fā)明由編譯程序調(diào)用的獲取說明(GetDedaration)功能的邏輯流程圖;圖10A和10B展示了有條件地編譯功能(CorditionallyCompile function)的邏輯流程圖;圖11是使用本發(fā)明時表示一個通常數(shù)目的窺視窗口的計算機屏幕的圖示表示;圖12展示了根據(jù)本發(fā)明的計算機屏幕的圖示表示,該表示展示了一個瀏覽窗(Browser)接通時的情況;圖13展示了圖12中瀏覽窗線路接通時計算機屏幕的圖示表示;圖14展示了樹狀窺視窗中部分擴展的項目的計算機屏幕圖示表示;圖15至圖18展示了在編譯一個部件的處理過程中顯示的一些屏幕;圖19展示了根據(jù)一個最佳實施例的內(nèi)部和交叉庫調(diào)用;圖20展示了根據(jù)一個最佳實施例的一組安排分類(fix-up dasses);圖21展示根據(jù)一個最佳實施例的一個連接區(qū);圖22展示根據(jù)一個最佳實施例的目標碼存儲;圖23展示根據(jù)一個最佳實施例的裝入庫;圖24展示根據(jù)一個最佳實施的裝入模塊的存儲器映射;圖25展示根據(jù)一個最佳實施例的不同類型的基準以及這些基準的連接程序的修改;以及圖26,27,28和29是流程圖,示明了根據(jù)一個最佳實施例的與連接關(guān)聯(lián)的邏輯。
參照圖1,示出了一個常規(guī)計算機10。該計算機10包括一系統(tǒng)單元12,一個高分辨率顯示設(shè)備14,例如一個陰極射線管(CRT)或者一個液晶顯示器(LCD)。除去要求用于顯示視窗系統(tǒng)通常是圖形用戶界面需要高分辨率這一點十分重要以外,這種顯示類型并不重要。用戶對計算機的輸入由鍵盤16以及光標指示設(shè)備,例如鼠標器18完成。鼠標器18與鍵盤16相連并進而與系統(tǒng)依次相連。而且鼠標器18可連到系統(tǒng)單元12的一個專用或串行口。圖1所示的計算機是Ap-ple Machintosh(蘋果計算機的注冊商標)以IBM PS/2。其他機型可包括各種工作站,例如IBM RISC System/6000以及Sun Microsystems計算機。
圖2更為詳細地展示了圖1所示計算機的基本部件。系統(tǒng)單元12包括一個連到總線24上的中央處理單元(CPU)21,隨機存取存儲器(RAM)22,以及只讀存儲器(ROM)23。CPU21可以是任何商業(yè)化的微處理器,例如Motorpla 68030和68040(它們通常用于Apple Maethintosh 計算機中)或In-tel 80386及80486(它們通常用在IBM PS/2計算機中)。其他微處理器,例如RISC(用于減少指令集計算機)微處理器(通常用于工作站)也可使用。ROM24存儲用于CPU的基本微碼,包括基本輸入/輸出系統(tǒng)(BIOS)。計算機系統(tǒng)10的操作系統(tǒng)(OS)也可存在ROM24中,或者把OS作為初始程序裝入(IPL)的一部分存入RAM22中。RAM22也用于存儲部分應(yīng)用程序以及執(zhí)行該程序過程中生成的臨時數(shù)據(jù)總線24可以是Apple NuBus,IBM MicroChannel或工業(yè)標準之一的總線。例如ISA(工業(yè)標準適配器)或EISA(擴展的工業(yè)標準適配器)。
與總線24相連的還有多個輸入/輸出(I/O)適配器,包括一個用戶接口適配器25以及一個I/O適配器26。鍵盤16與用戶接口適配器25相連,而I/O適配器26與軟盤驅(qū)動器27和硬盤驅(qū)動器28相連。軟盤驅(qū)動器27允許把數(shù)據(jù)和程序讀寫到可擦除介質(zhì),而硬盤驅(qū)動器28通常存儲頁入頁出RAM22的數(shù)據(jù)和程序。顯示設(shè)備14通過顯示適配器29而與總線24相連。通訊適配器30為網(wǎng)絡(luò)提供接口。其他支持電路(未示出)為集成電路芯片,它們被連到總線24和/或CPU21。這些芯片包括例如控制總線24上的信息量的總線主控芯片??偩€24在某些計算機中可以是雙總線;一個數(shù)據(jù)總線和一個允許在圖形用戶界面中需要的高速顯示操作的顯示總線。
定義程序如在本發(fā)明中所敘述的,一個HOOPS程序包括一個叫做“項目”的不可建立的部件以及一個“可建立的部件”的集合。不可建立的組成,部分亦可被存儲,但在本敘述中,只要到不合格的部件,就是指一個“可建立的部件”,不可建立的部件在建立操作中將不被編譯。
部件一個部件有一個唯一的標識并被命名。不同的部件由稱為ID的不同形式的唯一標識符加以區(qū)分。有一個稱為空ID(NullID),它不屬于任何部件。該ID在一個部件生成時被賦予而且在該部件存在期間不會改變。若一個部件被刪除了,它的ID不會再被使用。實際中,ID通常是數(shù)字的。
一個部件也有一個“名字”,它包括一串沒有白空格的文本。不同部件不必須要求有不同名字??梢垣@得包括所有部件的表(可能是空的),其中所有部件的名字與某些給定文本串相吻合。一個部件的名字可以在該部件存在期間被改變?nèi)我獯巍?br> 每個可建立的部件件都與特定的計算機語言相關(guān)。實踐中,計算機語言通常由一串文本標識。每一計算機語言有一個與其相關(guān)的編譯程序以供當以該語言編譯任何部件所用,實際上,可能使一種給定的計算機語言與不止一個編譯程序相關(guān)聯(lián)。在本例中,部件必須記錄語言以及標識該特定編譯程序的某些方式。
一種特定的語言有一與之相關(guān)的特定的部件種類集合以及一特定的特性實施集,通??赡苊恳环N類都不同。如此,在一特定語言中的區(qū)別語義元素可以根據(jù)需要以不同方式進行組合。
部件有“建立狀態(tài)(Build States)”。“建立狀態(tài)”是來自“不要編譯”(Never Compile)、“已編譯的”(Compiled)、“需要編譯”(NeedTo Compile),“不確定”(Uncertain),“被編譯”(Be-ing Compiled),“編譯錯誤”(CompileError),以及“不確定錯誤”(UncertainError)的表中的一個取值。實際中,這些值通常是數(shù)碼,每個部件有稱為“界面建立狀態(tài)(Interface BuildState)”和“實施建立狀態(tài)(Implementation Build State)”的一對?!敖顟B(tài)”無論是可建立的或不可建立的,每個部件都有這兩個建立狀態(tài)。對不可建立的部件而言,這些建立狀態(tài)都是“不可編譯”的。
“建立狀態(tài)”可被存取和改變??梢园岩粋€部件的”建立狀態(tài)”再次設(shè)置到同一值并且不會導(dǎo)致任何影響。改變一個“建立狀態(tài)”可能完好地定義邊界效應(yīng),便如改變有同樣或不同部件的一特性的“建立狀態(tài)”,或者例如從一個有改變的表或一個有錯誤的表中加入或刪除等此參考項。
部件用于表達語義語言元素。表達的方式取決于將被模塊化的特定計算機語言。例如在C++中,由部件表達的語言元素表格包括全局數(shù)據(jù),全局功能,分類,數(shù)據(jù)成員,成員功能,typedef,Rnums,仿真程序,宏指令,“或”運算以及結(jié)構(gòu)。通常,每個語義元素將有一相關(guān)聯(lián)的區(qū)別種類。
特性一個部件包括一個命名的“特性”(Property)集合。一個特性表示與該部件有關(guān)的一些數(shù)據(jù)。在給定部件的ID和特性名之后,可以存取和檢索這些數(shù)據(jù)。特性名字通常由標識名字的數(shù)字(有時稱為記號)在內(nèi)部表示。也有不屬于特性的區(qū)別特性名,叫做“空特性”(NullProperty)。
與一給定特性相關(guān)的數(shù)據(jù)對不同的的部件而言是不是的。改變一個部件給定特性的數(shù)據(jù)并不意味著改變用于任何其他部件的同一特性的數(shù)據(jù)。但是,有可能在一個部件的一個特性中的改變會導(dǎo)致同一或另一部件的另一特性的改變。
“引用(reference)”包括一個ID和一個特性名。一個引用唯一地標識特定的部分的特性數(shù)據(jù)。一個引用通常被松散地使用,就象它是部件和/或與之相關(guān)的特性。實際上,一個引用通常包含不在程序建立過程中直接使用的其他信息,從而標識該特性中的哪種數(shù)據(jù)版本及哪種數(shù)據(jù)子節(jié)將被引用。
所有部件必須有特性“名(Name)”和“貯存器(Container)”,該特性“名”存有部件的名字?!百A存器”特性則包含了其中的特性名為“空特性”的一個單一引用。從任一部件開始并相繼由貯存器ID引用的部件取代前一部件將總是最終導(dǎo)致“項目部件”(Projeet Component)。該項目的“貯存器ID”是“空ID(NullID)”。如此,所有部件在項目中被描述。
建立特性(亦稱為部件建立表)以建立順序記錄最后建立中被正確編譯的特性表。相同的特性應(yīng)該在該表中最多出現(xiàn)一次。建立特性用于測試和調(diào)試。
項目部件一個項目是一個附帶有特性“變化表(Changalist)”和“錯誤表(ErrorList)”的部件。特性變化表是一個引用用。這些引用描述部件以及最后一次建立以來發(fā)生了改變的特性。實際上,“變化表”可以由某種可以有效建立一個程序的過程中有效地存儲的多個表來表示。特性“錯誤表”也是一個引用表。這些引用描述在最后程序建立過程中列為有錯誤的部件。這些引用都有“錯誤”特性。與每個引用相關(guān)的是一個數(shù)碼鍵,它用于關(guān)聯(lián)特定的“錯誤”特性以確定一個專用消息的位置以及部件特定特性的一個特定子范圍。
可建立部件一個可建立部件必須有這些特性?!罢f明(Declaration)“目標碼(ObjectCode)”、“客戶(Clients)”、“源引用(Source Ref-erence)”、“錯誤”,并可有這些特性“界面(Interface)”、“實施(Implementation)”以及“成員(members)”。
“說明”特性表示用于編譯程序的一個數(shù)據(jù)高速緩沖存儲器。它可能在部件已被編譯之前是空的。實際上,它可被認為是編譯程序符號表的入口,盡管存儲的狀況可能與編譯程序的內(nèi)部情況不同。
“目標碼”特性表示了用于該部件的可執(zhí)行碼,它可能在部件被編譯前是空的,或者由于沒有目標碼與該部件相關(guān)而是空的。實際上,它通常提供一個手段指向?qū)嶋H碼所存之處。
“客戶”和“源引用”特性是一對集合。它們包括一個引用和一個“相關(guān)性(dependency)”。一個相關(guān)性是一個變化表。變化可以表示為從一個區(qū)別的有限表串中選取的一個文本串。一個稱為“公開(Pubpic)”的區(qū)別的變化用來區(qū)分只在實施特性性中對部件的引用,這與界面特性中的應(yīng)用相反。一個相關(guān)性可表示為一個位向量,其中若第n位的變化在表中表示,則該位向量的第n位為“1”,否則為“0”。
錯誤特性包括一個三個一組的表。每一組包括一個“鍵”,一個特性名,以及一個信息,一個鍵即為一個數(shù)碼標識。一個給定鍵在特定的“錯誤”特性中在一個時刻只出現(xiàn)一次,該特性名通常是“界面”或“實施”。該信息則是文本或/和圖形的某些部分。
“界面”和“實施”特性表示部件的源文本。該源文本可作為記號而不是作為文本存起來并在需要時以不同形式訪問。由這些特性表示的文本可通過編程環(huán)境中的人工編輯而予改變。一種可能性是把界面數(shù)據(jù)作為結(jié)構(gòu)區(qū)存起來,而從結(jié)構(gòu)區(qū)中,源文本可按需要重新構(gòu)造。
“成員”特性是引用集合(可能空的),每一引用用于“項目”中的每個部件,而“項目”將該部件作為其貯存器。
屬性一個部件有多個“屬性”。一個屬性為“真”或“假”。實際上,一個屬性通常是由存儲器的單比特值所表示的,由數(shù)字“1”和“0”表示的一個該屬性的真或假。所有部件都有“是可建立的(IsBuildable)”屬性。若該屬性為“真”,則該部件是可建立的;否則便為不可建立的。一個部件可能總是不可建立的或暫時不可建立的(因為某些暫時條件的作用)。
可建立的部件也有“在內(nèi)部(Isinline)”屬性。當該屬性為“真”時,該部件的“實施”是公開的,這意味著另外的部件可以依賴于實施的改變。若其為“假”,則實施改變將不會導(dǎo)致其他部件改變。
可建立的部件還有“合成(IsSynthetic)”屬性。這一屬性對于在編譯程序在建立處理過程中生成的部件來說為“真”。而對程序員人工生成的部件為“假”。提供合成部件是使編譯程序生成與系統(tǒng)設(shè)定語言元素對應(yīng)的部件,系統(tǒng)需要設(shè)置語言元素,但其不必由程序員直接生成,實際上有可能將“合成”屬性從“真”改為“假”,例如當一個合成的部件被人工編輯時,但從“假”到“真”的反向改變是絕不允許的。合成部件通常沒有“界面”或“實施”特性,但無論在何種情況下,合成部件都使“界面”和“實施建立狀態(tài)”被編譯。
類別每一部件都有一“類別”(Kind)”。一個類別是指把部件劃分為例如共有同樣特性或同樣語言特定行為的各個組的一個文本串。大部分類別是專用于一種特定的計算機語言并用于指定語義區(qū)別語言元素。
然而,有一些是由系統(tǒng)定義的類別,它們分別為“項目”,“庫”,以及“貯存器”。這些類別只用于不可建立的部件。“項目”類別是“項目”部件的類別。“庫”類別則是用于連接到目標碼的一個外部塊(例如一個共同庫或應(yīng)用程序)的部件的集合。類別“貯存器”則應(yīng)用于把其他部件分組歸類以便組織的部件。實際上,類別通常在內(nèi)部由數(shù)碼表示。
圖3提供了包括一個系列的部件31的程序的概念性的圖示。每個部件由一組特性組成,這組特性分為兩部分,即稱為界面的外部可見(公開)部分311以及實施(專用)部分312。如圖3所示,部件只依賴于另一個部件的界面。在一個項目中的所有部件被組織成樹狀結(jié)構(gòu),其底部為根的部件32(稱為項目部件)。如同本技術(shù)領(lǐng)域的一般技術(shù)人員可知的那樣,部件本身不必包含實體,但可以包括指向?qū)嶋H碼的存儲位置的指針。然而,這一樹結(jié)構(gòu)表達方式在展示一個程序的構(gòu)成上是有用的,因此,類似的樹結(jié)構(gòu)表示被用于其后所述的用戶屏幕之一。
圖4是一框圖,示出了本發(fā)明的三個主要功能性。它們是數(shù)據(jù)庫41,編譯程序42,以及建立處理43。數(shù)據(jù)庫41包括一組構(gòu)成部分,圖中所示為一個項目部件411和一個可建立的部件集412。該可建立的部件集合412成型為將被建立的一個程序。編譯程序42計算數(shù)據(jù)庫41的部件的相關(guān)性。建立處理43利用部件特性和編譯程序生成的相關(guān)性來建立該程序。
程序員可用編輯程序44改變該程序。編輯程序必須能夠生成及刪除這些部件,尤其是能夠進行剪切、復(fù)制、粘貼和移動這些部件。編輯程序必須可以改變“界面”和“實施”特性中的數(shù)據(jù),其方式通常是由對文本直接地進行修改。然而,其他更為結(jié)構(gòu)化的途經(jīng)(例如從選項屏進行選擇)亦可采用。實際上,編輯程序44通常可以包括多個編輯程序,每個用于每種“界面”或“實施”特性,或甚至可能為特性中的數(shù)據(jù)的子區(qū)配置編輯程序。
寄存編輯改變的方法參見圖5A到圖5D,其中示出了與增量建立有關(guān)的編輯程序44所執(zhí)行的邏輯功能流程圖。對于可建立的非合成部件,“建立狀態(tài)”限于在建立處理之外的“編譯的值”和“需要編譯”值。若“界面”特性未出現(xiàn),則“界面建立狀態(tài)”是“編譯的”。若“實施”特性未出現(xiàn),則“實施建立狀態(tài)”是“編譯的”。圖5A中展示了各種編輯狀態(tài)變化。在500處,當系統(tǒng)標識了一個“生成部件”、“再命名部件”、“粘貼部件”、或’編輯界面”命令之時,控制則進到功能框510對界面變化進行處理。該變化的詳細邏輯示于圖5B中。
圖5B中,處理始于判別框511,在該處,進行測試以確定界面建立狀態(tài)是否為“需要編譯”。若是,則控制通過514進行繼續(xù)編輯。這些動作發(fā)生在編輯過程中而不是在建立過程中,下一動作很可能是另一編輯動作。若否,則在功能框512處把界面建立狀態(tài)設(shè)置成“需要編譯”并因此更新界面變化表。然后,在功能框5B處完成實施被改變和貯存器被改變的處理。實施被改變操作的細節(jié)示于圖5C中而貯存器被改變的操作細節(jié)示于圖5D中。
圖5C示出了與實施被改變有關(guān)的詳細過程。判別框571進行測試以確定是否實施建立狀態(tài)已設(shè)定為“需要編譯”。若是,控制通過572進行繼續(xù)編輯。若否,則在功能框573處把實施建立狀態(tài)設(shè)為等于“需要編譯”且實施變化表被因此而更新。然后,控制通過574返回。
圖5D示出了與貯存器改變操作有關(guān)的詳細邏輯。功能框542處將進行測試以確定該變量是否為可建立。若是,則在功能框543處由部件的貯存器按圖5B討論的細節(jié)調(diào)用被改變的界面,然后,控制通過544返回。
若“編輯實施”命令在圖5A的560處被檢測到,則處理按照功能框570所示和圖5C的討論執(zhí)行實施被改變的動作。
若在圖5A和530處檢測到“刪除部件”的命令,則用于部件A的貯存器被改變處理起始于功能框540,其細節(jié)示于圖5D中,然后,貯存器A被刪除且控制由550返回。
若在圖5A的580處檢測到一個“移動”部件命令,則部件A的貯存器被改變處理起始于功能框590并詳細示于圖5D中。然后,部件的貯存器被設(shè)定于等于新的貯存器,且對于部件A的界面已改變的處理詳細示于圖5B中。最后,處理由595返回。
確定一個建立的組成部的方法在建立一個程序的過程中,“項目”組成部維持著稱之為編譯表的專用引用表。有一個“界面編譯表”和一個“實施編譯表”?!绊椖俊边€維持一個叫做“內(nèi)部錯誤表”的專用引用表。實際上,這些表的每一個可由不止一個表實際地表示,以提高效率。
圖6展示的處理中,對于“項目”的“改變表”中的每個引用(如功能框601所示)從該表的前部選中一個引用。若在表上有多上引用,處理由框602所示完成。若引用是一個界面,如在框603所制定的,則將該引用的復(fù)制放在“界面編譯表”中并且在601繼續(xù)處理之前,在功能框604處把“加客戶(AddClients)”功能調(diào)用到該引用。若其特性名不是“界面”,則其特性名為“實施”,如框605所示,此時,由判別框606進行測試以確定是否為“在內(nèi)部”(IsInLine)屬性為真。若是,則將引用的復(fù)制放入“界面編譯表”并在框601的處理繼續(xù)之前在功能框607“界面編譯表”并在框601的處理繼續(xù)之前在功能框607處從該引用中調(diào)用“加客戶”功能。否則,其特性名肯定是“實施”且其“在內(nèi)部”屬性肯定為“假”,而且在框601的處理繼續(xù)之前,該引用的復(fù)制功能框608放在“實施編譯表”中。
“生成編譯表”功能的偽代碼如下
<pre listing-type="program-listing"><![CDATA[  CreateCompileLists( ){   for each A in ChangeList{   if(A.PropertyName==Interface){   InterfaceCompileList.Add(A);   AddClients(A);   }   else if(A.PropertyName==Implementation){   if(IsInLine==True){   InterfaceCompileList.Add(A);   AddClients(A);   }   else if(IsInLine==False){  ImplementationCompileList.Add(A);  }   }   }   }]]></pre>“加客戶”功能負責參數(shù)中每個引用,適當?shù)匾蛻舨z查引用,并在其“建立狀態(tài)”被編譯時,把該引參的“建立狀態(tài)”設(shè)為“不確定”,把該引用的復(fù)制加到適當?shù)摹熬幾g表”,并在該引用中調(diào)用“加客戶”。這一處理稱為生成“改變表”的“客戶封閉(dient Closure)”。該“客戶封閉”表示需要作為一個建立的結(jié)果而被再次編譯的那些部件的子集。實際上,由建立過程的編譯程序生成的相關(guān)性及變化用于避免在“客戶封閉”中編譯過多的部件。
以下是“加客戶”的偽碼功能
<pre listing-type="program-listing"><![CDATA[  AddClients(A){   for each B in A.ClientList{    if(B.BuildState==Compiled){  B.SetBuildState(Uncertain);   if(B.PropertyName==Interface){  InterfaceCompileList.Add(B);  AddClients(B);   }   else if(B.PropertyName==Implementation){  ImplementationCompileList.Add(B);  AddClients(B);   }   }  } }]]></pre>處理“界面”的方法這是“建立”處理的第二階段。在“界面編譯表”用于項的可能的“建立狀態(tài)”是“已編譯”、“正被編譯”、“需要編譯”、“不確定”、“編譯錯誤”或“不確定錯誤”?!敖缑婢幾g表”被處理直到空了為止,如圖7的流程圖所示。處理始于701處,在該處,從“界面編譯表”的前部選中一個引用。如果在表上沒有更多的引用,便在框702處完成處理。如框703所示,若與該引用相關(guān)聯(lián)的構(gòu)成部分的界面“建立狀態(tài)”是已編譯的,“編譯錯誤”或“不確定錯誤”的,則從表的前部去除該引用并且在框701中繼續(xù)處理。若與該引用相關(guān)的構(gòu)成部分的界面“建立狀態(tài)”是“已被編譯”或“需要編譯”,如框704所示,則部件的“建立狀態(tài)”在框705中被設(shè)置為“已被編譯”。然后,在部件的“界面”調(diào)用“編譯”功能(它調(diào)用編譯程序42)。該功能將返回到“異常中止”值,“完成”值和“錯誤”值之一。若在框706處返回“異常中止”值,則處理在框701處繼續(xù)。若返回框707的“完成”值,則部件的“界面建立狀態(tài)”被設(shè)為“編譯的”且在處理在框701處繼續(xù)之前,在框708處將把引用從表的前部去除掉。若返回的值是框709處的“錯誤”,則該部件的“界面建立狀態(tài)”設(shè)定為“編譯錯誤”,從表的前部去掉該引用,并在701處繼續(xù)處理之前,在功能框710中的部件調(diào)用“傳播錯誤”功能。若與該引用相關(guān)聯(lián)的“界面建立狀態(tài)”為“不確定”,如框711所示,則該部件的“建立狀態(tài)”在功能框712處設(shè)為“已被編譯”。然后在該部件的“界面”上調(diào)用“有條件地編譯”功能(可以調(diào)用也可以不調(diào)用編譯程序42)。該功能也返回到“異常中止”值,“完成”值和“錯誤”值之一。若返回到“異常中止”值,則在步驟701處的處理繼續(xù)進行。若返回到框713處的“完成”值,則在功能框708中從表的前部去掉該引用并繼續(xù)進行框701處的處理。若返回框714處的“錯誤”值,則從表的前部去掉該引用并在框701的處理繼續(xù)進行之前,在功能框715中的部件里調(diào)用該“傳播錯誤”功能。
用于“處理界面”功能的偽碼如下<pre listing-type="program-listing"><![CDATA[ProcessInterfaces( ){  until((A=InterfaceCompileList.First)==NIL){  state=A.BuildState;  if(A=Compiled_CompileError_Uncertainerror){   InterfaceCompileLrst.RemoveFirst( );  }  else if(A=BeingCompiled_NeedToCompile){   A.SetBuildState(BeingCompiled);   value=Compile(A);   if(value==Abort){   continue;   }   else if(value==Done){   A.SetBuildState(Compiled);   InterfaceCompileList.RemoveFirst( );   }   else if(value==Error){   A.SetBuildState(CompileError);   InterfaceCompileList.RemoveFirst( );   PropagateError(A);   }  }  else if(A=Uncertain){   A.SetBuildState(BeingCompiled);   value=ConditionallyCompile(A);  if(value==Abort){   continue;} else if(value==Done){  A.SetBuildState(Compiled);   InterfaceCompileList.RemoveFirst( ); } else if(value==Error){   A.SetBuildState(UncertainError);   InterfaceCompileList.RemoveFirst( );   PropagateError(A); } } }}]]></pre>
“傳播錯誤”功能是把一個與部件對應(yīng)的引用加到“項目”的“內(nèi)部錯誤表”中并對部件的“客戶”表中的每個引用執(zhí)行如下若該引用的“建立狀態(tài)”是“編譯錯誤”或“不確定錯誤”,處理繼續(xù)下一個引用。若該引用的“建立狀態(tài)”是“需要編譯”,處理把它的“建立狀態(tài)”設(shè)為“編譯錯誤”,并將引用把加到“內(nèi)部錯誤表”,并在繼續(xù)下一引用之前為引用調(diào)用“傳播錯誤”。若引用的“建立狀態(tài)”為“不確定”,則處理把其“建立狀態(tài)”設(shè)到“不確定錯誤”,把引用加到“內(nèi)部錯誤表”,并在繼續(xù)下一引用之前在引用上調(diào)用“傳播錯誤”。
“傳播錯誤”功能的偽碼如下<pre listing-type="program-listing"><![CDATA[  PropagateError(A){   for each B in A.ClientList{   state=B.BuildState;   if(state==CompileError_UncertainError)[  continue;   }   else if(state==NeedToCompile){   B.SetBuildState(CompileError){   InternalErrorList.Add(B);   PropagateError(B);   }   else if(state==Uncertain){   B.SetBuildState(UncertainError);   InternalErrorList.Add(B);   PropagateError(B);}   }   }]]></pre>處理“實施”的方法這是“建立”處理的第三階段,如圖8的流程圖所示,在“實施編譯”表中的每個引用都被處理。該處理始于801處,在該處,從實施編譯表的前部選中一個引用。若無更多的引用,在框802處完成處理。若該引用的“建立狀態(tài)”為“不確定”,如框803所示,則在框801繼續(xù)處理之前在功能框804中把“建立狀態(tài)”設(shè)置為“已編譯的”。若該引用的“建立狀態(tài)”是“需要編譯”,如框805所示,則在功能框806處編譯該部件。從編譯程序42返回的值可能是“完成”和“錯誤”。若在框807處返回值是“完成,則在框801繼續(xù)處理之前,在功能框804中把該引用的“建立狀態(tài)”設(shè)為“已編譯的”。若把框808中返回的值為“錯誤”,則將該引用的“建立狀態(tài)”設(shè)定為“編輯錯誤”并在框801繼續(xù)處理之前,在功能框809的部件中調(diào)用“傳播錯誤”功能。若該引用的’建立狀態(tài)”是“編譯錯誤”或“不確定錯誤”,將不作任何事。應(yīng)注意,“實施”的處理在這一階段順序獨立的,因為相關(guān)性只可以在其內(nèi)部屬性是“真”而且已被處理過的“界面”或“實施”中。
“處理實施”的偽碼如下
<pre listing-type="program-listing"><![CDATA[ProcessImplementations( ){ for each A in ImplementationCompileList{ state=A.BuildState; if(A=Uncertain){   A.SetBuildState(Compiled); } else if(A=NeedToCompile){   value=Compile(A);   if(value==Done){   A.SetBuildState(Compiled);   }   else if(value==Error){   A.SetBuildState(CompileError);   PropagateError(A);   } } else if(A=CompileError_UncertainError){ } }}]]></pre>
支持建立處理的編譯程序編譯程序42通過“編譯”功能而被調(diào)用,兩者亦可作為替代命令使用。編譯程序42處理源文本并標識可能的外部部件的名字。編輯程序42下一步獲取所有部件的引用表。該編輯程序可用語言專用知識(例如部件類別)從該表中刪除這些引用。編譯程序然后為文本標識的每個外部部件調(diào)用“獲得說明(GetDealaration)”功能。在調(diào)用編譯程序之前,該“編譯”功能清除一切現(xiàn)存的錯誤。這也將清除任何來自“錯誤”特性的錯誤消息并從“項目”的的“錯誤表”特性中去除任何引用。
編譯程序首先調(diào)用“獲得說明”功能,如圖9的流程圖所示?!矮@得說明”功能返回到“異常中止”值、“完成”值、“循環(huán)相關(guān)性”值或“錯誤”值的其中之一,并可返回“說明”的數(shù)據(jù)。處理起始于框901,在該處,每個引用的“建立狀態(tài)”被檢查。若沒有更多的引用要處理,便在框920處完成處理并返回。若該部件的“建立狀態(tài)”在框903處為“編譯的”,則功能返回到“完成”,如框904所示,而且在框901繼續(xù)處理之前,存儲的“說明”數(shù)據(jù)也被返回。若部件的“建立狀態(tài)”在框905處示為“需要編輯”或“不確定”,則相應(yīng)于該部件的引用在功能框906中被加到“界面編譯表”的前部,并在框901繼續(xù)其處理之前,該功能返回到功能框907的“異常中止”。“說明”數(shù)據(jù)在這一情況下不返回,若部件的“建立狀態(tài)”為框908所示的“被編輯”,則在框901繼續(xù)處理之前,功能將去往功能框909處的“循環(huán)相關(guān)性”。“說明”數(shù)據(jù)在這一情況下亦不返回。若部件的“建立狀態(tài)”是框910所示的“編輯錯誤”或“不確定錯誤”,則在框901繼續(xù)其處理之前,功能返回到功能框911的“錯誤”。在這種情況下亦無“說明”數(shù)據(jù)返回。
“獲得說明”功能的偽碼如下<pre listing-type="program-listing"><![CDATA[  value GetDeclaration(A,Declaration){   Declaration=NIL;   state=A.BuildState;   if(state==Compiled){   Declaration=CurrentDeclaration( );   return(Done);   }   else if(state==NeedToCompile_Uncertain){   InterfaceCompileList.AddToFront(A);   return(Abort);   }   else if(state==BeingCompiled){   return(Circulardependency);   }   else if(state==CompileError_UncertainError){   return(Error);   }  }]]></pre>
在調(diào)用“獲得說明”功能之后,編譯程序繼續(xù)進行如下的過程。若返回值為“異常中止”,則編輯程序必須中止處理并返回到“異常中止”值。一個替代實施方案是要編譯程序在編譯該返回的部件之后,中止編譯,放棄或重新啟動編輯程序。這會要求編譯程序再次進入。但若不是這樣的話,就不會有上述的重大變化。若返回的值是“編譯的”,則編譯程序可繼續(xù)其處理。若采用“說明”,則將構(gòu)成“源引用相關(guān)性”,而且編譯程序會保持追蹤相關(guān)性及其性質(zhì)。若返回值是“循環(huán)相關(guān)性”或“錯誤”,則編譯程序必須中止處理。在部件上調(diào)用“設(shè)置錯誤(Set Error)”功能,并返回“錯誤”值。編譯程序可以選擇繼續(xù)處理以便在結(jié)束之前發(fā)現(xiàn)更多可能的錯誤。
若對“獲得說明”的調(diào)用返回到“編譯的”,則編譯程序?qū)⒁猿R?guī)方式繼續(xù)處理源文本。若在處理過程中遇到任何錯誤,編輯程序?qū)⒄{(diào)用部件的“設(shè)置錯誤”功能并返回“錯誤”值,若沒有遇到錯誤,則編譯程序返回“完成”值。若編譯程序已經(jīng)在對一個界面進行處理,則它將存貯該“說明”特性的新值。
處理“錯誤”的方法在編譯程序被調(diào)用以編譯一個“界面”或“實施”之前,清除所有現(xiàn)有的“錯誤”。這將保證所有的錯誤消息被更新。由于“界面”和“實施”之前的內(nèi)部相關(guān)性以及這樣的事實,即錯誤是可傳播的,所以將不可能在同一建立上在“界面”和“實施”上同時得到編譯程序錯誤。
當編譯程序遇到錯誤時,它調(diào)用傳送與錯誤有關(guān)的信息的功能“設(shè)置錯誤”,該信息包括錯誤的位置,以及描述錯誤的消息和返回到的錯誤組成部。該信息存儲在“錯誤”特性和部件的正確源特性(“界面”或“實施”)之中。一個引用也存在允許對所有錯誤進行方便地存取的“項目”所維護的總錯誤表中。
錯誤將傳播到任意相關(guān)部件以便這些部件無需在其后被編譯。因為這些編譯已知將會失敗。進而,遇到錯誤后將繼續(xù)建立并盡可能多正確建立那些本身并無明顯錯誤的部件或與錯誤部件有關(guān)聯(lián)的部件。
“設(shè)置錯誤”功能獲取由編輯程序42傳給它的錯誤消息并在相應(yīng)于適當特性(“界面”或“實施)的部件的“錯誤”特性中生成一個入口,它還在與該錯誤對應(yīng)的“項目”的“錯誤表特性”中生成一個入口。以這一方式生成的兩個入口共享同一鍵,以致它們保持“連接”。這一功能通常還用一個“粘性標志”把錯誤的位置記錄在程序源之中。該“粘性標志”在稍后的用戶編輯過程中一直附屬到字符的相同范圍。
若編譯程序成功地完成了源文本的處理,則其將產(chǎn)生目標碼并將其通過“連接程序”功能進行增量連接。而且,目標碼可存到建立處理結(jié)束并以常規(guī)方式連接。
編譯程序現(xiàn)在將更新部件的“源引用(SourceRefRerence)1特性以及每個“源引用”的“客戶”特性。對每一個引用,例如部件A的“源引用”特性中的部件B,將必須有一與部件B的“客戶”特性中的部件A相對應(yīng)的引用(它具有同樣的相關(guān)性信息)。
編輯程序?qū)⑸梢粋€“變化”以描述“說明”如何從其當前值改變的,編輯程序?qū)⒃诓考险{(diào)用傳播改變(PropagateChange)功能并把計算出來的改變傳播給該部件。該編譯程序然后將設(shè)定“說明”的新值?!皞鞑ジ淖儭钡墓δ芘c針對部件的“客戶”表中的每個引用的相關(guān)性的變化吻合。若該吻合指示引用的部件已為改變所影響,且其“建立狀態(tài)”不是“編譯錯誤”或“不確定錯誤”,則其“建立狀態(tài)”設(shè)為“需要編譯”。
有可能要編譯程序使用“設(shè)置錯誤”功能以發(fā)布告警信息或不同格式的建議。在這種情況下,若只有告警信息返回,則“編譯”功能應(yīng)返回到“完成”。告警信息將被加到“錯誤”特性且引用將被加到“項目錯誤表”特性。否則編譯將被認為是成功的。適當?shù)摹敖顟B(tài)”將被設(shè)置為“編輯的”,而且將無錯誤被傳播。若只發(fā)布了告警或建議,則程序?qū)⒈煌耆丶罢_地建立。
“有條件地編譯”一個部件的處理圖10A和10B示出了“有條件編譯”功能的流程圖,其中進行了引用,在部件的“源引用用”中的每個部件B在框1001處進行處理。則對部件B的處理結(jié)束而處理去往圖10B以編譯組成部件A。部件B的“建立狀態(tài)”是“被編譯”或“需要編譯”,如框1003所示,則該部件的“建立狀態(tài)”被設(shè)定為“被編譯”且該部件在功能框1004中被編譯。該編譯功能可以返回到“完成”值,“異常中止”值和“錯誤”值其中之一。若返回框1005的“完成”值,處理將繼續(xù)在框1001處進行。
若返回值是框1006的“異常中止”,則功能中止且“異常中止”返回到框1007。若返回值是框1008中的“錯誤”,則原始部件的“建立狀態(tài)”被設(shè)置為“不確定錯誤”,功能被停止且“錯誤”返回到功能框1009中。若部件B的“建立狀態(tài)”是“不確定”,如框1010所示,則“建立狀態(tài)”被設(shè)定為“被編譯”且該部件在功能框1011中被有條件地編譯。再一次,“有條件地編譯”功能可以返到“完成”,“異常中止”或’錯誤”值之一。若“完成”值返回框1005,處理在框1001處繼續(xù)。若“錯誤”返回到框1012,則部件的“建立狀態(tài)”被設(shè)為“不確定錯誤”,從“界面編譯表”中去除部件A,并在功能結(jié)束之前在功能框1014中調(diào)用“傳播錯誤”功能。若返回框1015的“異常中止”,則在功能結(jié)束之前“異常中止”返回框1007。
現(xiàn)在再來看圖10B,若所有引用已被處理過,則它們的“建立狀態(tài)”都是“編譯的”。但是,“源引用”之一可能在對這一點的處理過程中已經(jīng)把一個變化傳播到部件,所以它的“建立狀態(tài)”可以是“被編譯”或“需要編譯”。因此,部件A的“建立狀態(tài)”在框1016中決定。若框1017處指出該“建立狀態(tài)”是“需要編譯”,則該“編譯狀態(tài)”被設(shè)定為“被編輯”且部件A在功能框1018中被編譯。編譯程序可返回到“錯誤”或“完成”。注意“異常中止”不會發(fā)生,因為所有的’源引用”都在這一階段被編譯了。若“錯誤”去往框1019,則“建立狀態(tài)”設(shè)為“編譯錯誤”而且“錯誤”返回到功能框1020。若“完成”去往框1021,則“建立狀態(tài)”設(shè)為“編譯的”且“完成”去往功能框1023。若部件A的“建立狀態(tài)”是“被編譯”,如框1024所示,則“建立狀態(tài)”被設(shè)為“編譯的”而且“完成”去往功能框1023。
“有條件地編譯”功能的偽碼如下<pre listing-type="program-listing"><![CDATA[  value ConditionallyCompile(A){   for each B in A.SourceReference{   state=B.BuildState;   if(state==NeedToCompile_BeingCompiled){   B.SetBuildState(BeingCompiled);   value=Compile(B);   if(value==Done){   continue;   }   else if(value==Abort){  return(Abort);   }   else if(value==Error){  A.SetBuildState(UncertainError);  return(Error);   }   }else if(state==Uncertain);   A.SetBuildState(BeingCompiled);   value=ConditionallyCompile(A);   if(value==Done){   continue;   }   else if(value==Abort){   return(Abort);   }   else if(value==Error){   A.SetBuildState(UncertainError);   InterfaceCompileList.Remove(A);   PropagateError(A);  } } }state=A.BuildState;if(state==NeedToCompile){ A.SetBuildState(Being Compiled); value=Compile(A); if(value==Done){  A.SetBuildState(Compiled);  return(Done); }elseif(value==Error){   A.SetBuildState(CompileError);     return(Error);   }  }  A.SetBuildState(Compiled);  return(Done); } }]]></pre>后處理錯誤的方法后處理錯誤的方法是“建立”處理的第四階段。若在建立過程中發(fā)生了任何錯誤,則“后處理錯誤”(PostPro-cessingErrors)功能便在建立結(jié)束時被調(diào)用。對每個在“內(nèi)部錯誤表”中的引用而言,若引用的“建立狀態(tài)”是“編譯錯誤”,則“建立狀態(tài)”改變成“需要編譯”,若引用的“建立狀態(tài)”是“不確定錯誤”,則“建立狀態(tài)”被改變?yōu)椤耙丫幾g的”。
當所有在“內(nèi)部錯誤表”上的引用已處理完畢后,該表的所有入口被消除。為便于程序員,若“項目”的錯誤表包含任何入口,則將在“項目”的“錯誤表”上開一個視窗或瀏覽窗。
“后處理錯誤”功能的偽碼如下<pre listing-type="program-listing"><![CDATA[  PostProcessErrors( ){   for each A in InternalErrorList{   state=A.BuildState;   if(state==CompileError){ A.SetBuildState(NeedToCompile);   }   else if(state==UncertainError){  A.SetBuildState(Compiled);   }   }   InternalErrorList.ClearAll( );   if(ErrorList.Count?。?){   OpenErrorWindow( );   }   }]]></pre>使用面向人的目標編程系統(tǒng)(HOOPS)根據(jù)本發(fā)明的面向人的目標編程系統(tǒng)(HOOPS)可通過進入一個項目名或現(xiàn)有的項目名來從計算機開始,這要取決于是否要建立新的程序或建立現(xiàn)存的程序。當HOOPS開始時,視窗被打開并顯示一個與圖11所示屏幕類似的初始屏面。該HOOPS打開的初始視窗顯示了“項目”部件的“成員”特性以及其直接成員。雖然它初始只顯示了直接成員,但同樣的視窗用于顯示始于項目部件處的每個部件。在圖11的示例中,一個叫做“工資單(Pagroll)”的“項目”已被輸入。
窺視窗窺視窗是用于顯示一個部件特定特性的圖形展示。但是,在顯示該特性的處理過程中,可能會要求窺視窗顯示輔助信息,它們包括從其他特性而來的數(shù)據(jù)。一個窺視窗有一輸入和輸出。該輸入指至少一個部件和特性,也可以指定該特性的信息的子范圍。該輸出至少指一個部件。它亦可指定一個特性以及該特性數(shù)據(jù)的一個子范圍。該輸出可響應(yīng)于用戶操作及系統(tǒng)中的狀態(tài)變化而隨時改變。
窺視窗表是一個窺視窗說明的命名表,其中,每個說明定義一個窺視窗名字及實施分類。有一個叫做空窺視窗表的區(qū)別窺視窗表,它不包含窺視窗說明。窺視窗表名字與每個特性關(guān)聯(lián)。特性可以被表中指定的任意窺視窗顯示。若一個特性與空窺視窗表關(guān)聯(lián),則不會有該特性的窺視窗,而且該特性被認為是不可顯示的。一個最佳窺視窗將與每個特性關(guān)聯(lián)該最佳窺視窗必須在與特性相關(guān)聯(lián)的窺視窗表中指定的窺視窗之中。一個最佳特性與要被窺視的部件關(guān)聯(lián)。
窗格(Paue)一個窺視窗顯示在一窗格中。窗格有一輸入和輸出。該輸入指定至少一個部件。它亦可指定部件的一個特性和特性的數(shù)據(jù)的一個子范圍。其輸出指定至少一個部件并可指定一個特性和該特性數(shù)據(jù)的一個子范圍。該輸出可響應(yīng)用戶動作及系統(tǒng)內(nèi)的狀態(tài)改變而隨時改變。
一個窗格確定了它的窺視窗輸入,該輸入一般是從該窗格的輸入中導(dǎo)出而來的。它可動態(tài)地根據(jù)系統(tǒng)狀態(tài)或靜態(tài)地改變窗格的實施而從窗格到窗格進行變化。在最簡導(dǎo)出中,窺視窗的輸入與窗格的輸入相等。類似地窗格的輸出來自于對窺視窗格輸出的導(dǎo)出。該求導(dǎo)出的性質(zhì)從窗格到窗格不同,它或者動態(tài)地取決于系統(tǒng)狀態(tài),或者靜態(tài)地由窗格實施的變化而定。在最簡導(dǎo)出中,一個窗格的輸出等于其窺視窗的輸出。
視窗窗格顯示于視窗之中。視窗被細分為一個或多個窗格。在一個視窗中的窗格數(shù)量及大小可由用戶動態(tài)地控制。一個最佳實施例在每個窗格中提供窗格劃分程序控制以簡化多窗格的生成和管理。該控制用于把一個單個的窗格分為一個或多個窗格。
圖12示出了根據(jù)本發(fā)明的一個瀏覽窗。在HOOPS中的每個視窗都是瀏覽窗。瀏覽窗是暫時可見的和編輯工具,用于查看“項目”中的信息。只要在視窗中的關(guān)閉圖符1210上按一下,即可在任意時刻刪除瀏覽窗。任何在測覽窗中對“項目”所做的改變都被自動保存起來。一個瀏覽窗有一個項目根部件1200,它在打開時被指定。一個存貯器部件的實例展示于1202處,一個選擇的部件示于1203處,一個窗格特性上托選擇屏控制1220以及一個擴展或壓縮控制示于1204。該控制可使用戶把一個窗格導(dǎo)向一個特定的特性。輸入部件的特性2130在窗格1260中顯示。而且每個窗格1260顯示一個特性窺視窗1205或是空白的,如1260所示。新窗格由在一個窗格右上角中選擇一個劃分圖符1250的方式而加到一個瀏覽窗中。窗格劃分控制1250允許用戶將一個窗格分為兩個并控制其幾何尺寸。也有一個窗格和測覽窗放大/縮小框1242和1243,它們使得用戶可以動態(tài)地放大/縮小一個窗格以使完全充滿視窗,并使得用戶將窗格恢復(fù)至其原有尺寸。水平和垂直卷動控制1252被提供以便卷動位于一個窗格中的窺視窗。窗格標題框1241顯示部件的名字及由該窗格顯示的特性。窺視窗選項屏1251提供用于使用戶選擇用于顯示選定特性的窺視窗。
綜合考慮三個因素,以使確定由一個窗格顯示的專用窺視窗。它們是部件,該部分的特性,以及該特性的窺視窗。部件由窗格的輸入導(dǎo)出而來。特性亦來自對窗格的導(dǎo)出,或來自一個用戶的替換。若該窗格輸入指定了輸入部件的一個專用特性,則該特性按該特性關(guān)聯(lián)的窺視窗表所定義的來確定一組合格的窺視窗。若該窗格輸入未指定一個特性,則將被顯示的特性是部件的系統(tǒng)設(shè)定特性。
用戶可以通過選擇用于觀察或把一個窗格固定到一專用特性的另一輸入部件特性的方式而替換選定的特性。當固定后,該窗格顯示固定的特性而與輸入部件無關(guān)。當一個窗格的部件或特性變化時,一個新窺視窗在該窗格中顯示。該窺視窗是特性的系統(tǒng)設(shè)定窺視窗;然而,用戶可以順序改變該窺視窗成為在與顯示特性關(guān)聯(lián)的窺視窗表中列出任何項。
當生成一個新窗格時,系統(tǒng)設(shè)置的“連線(Wiring)”從分裂成新方格的方格中生成?!斑B線”是在一個窗格之間的邏輯關(guān)系。一個窗格可以有零個或一個連線輸入及零個或多個連線作為輸出,但連線不可以形成回路。當在一個窗格中選擇了一個部件時,該選擇被轉(zhuǎn)換成對項目中部件的一個引用并成為一個對來自該窗格的任何連線的目的的新輸入。通過從選項屏條選擇的瀏覽窗選項屏中的“Turn on Wiring”(接通連線)可接通連線,從而產(chǎn)生圖13的疊加圖形連線的顯示。采用這一顯示,可能通過在新輸入位置按下鼠標器并將其拉至目標窗格的方式改變兩個窗格之間的連線。
在許多窺視窗中(例如“成員”,“客戶”以及“引用”),部件可由它們的名字以及圖符(它們由部件類別區(qū)分)所區(qū)別,在其他窺視窗中,一個部件的名字只出現(xiàn)在本文中,例如在“源”或“資料”中部件層次可由擴展和縮滅在“成員”特性窺視窗中的貯存器部件從而產(chǎn)生一個“樹”視圖的方式進行測覽,圖14便展示了該例子。一個部件的子樹的一級可通過按一下部件的循環(huán)雙態(tài)開關(guān)的方式加以擴散或縮滅。當通過按一下圖符或在文本顯示中選擇其名字的方式在一個窺視窗中選擇一個部件時,在總選項屏條中的“特性”選擇屏被調(diào)整以列出部件的類型。任何部件的任何特性可以通過在一個窺視窗中選擇該部件并然后從“特性(Property)”選項屏中選中一個特性的方式進行視查。這會打開一個包括一個窺視窗的新瀏覽窗,該窺視窗顯示選定部件的選中特性。
通過指定任何處生成新部件以及該部件類別,可在一個“成員”或“界面”窺視窗中生成部件。該新部件的位置由選擇一個現(xiàn)有的部件或在部件之間放入一插入點的方式而予指定。生成的部件的類別通過從“New”窺視窗選項屏中選擇選項屏項所決定。所有編輯都自動存儲。只有已改變的部件以及受改變所影響的客戶才被編譯。重新編譯的部件可通過從“Build”選項屏中選中的“Show Components Build”選項屏項進行觀看。為了觀看從最后建立以來的改變的部件,要從“Build”選項屏中選擇“Sleow Compenents Changed”。通過從“Build”選項屏中選擇“Build”,可對一個程序進行編譯和連接?!癇uild &amp; Run”選項屏也運行該程序。
圖15至18展示了在編輯一個部件的處理過程中顯示的一些屏面。圖15示了一個“main”功能的“實施”的源碼顯示。在圖16中,功能“main”已由把“numberDisks”從“7”改變“9”的方式進行了編輯。若程序員現(xiàn)在從圖17中示出的“Build”選項屏中選擇“Show Components Changed”則圖18所示的瀏覽窗便會出現(xiàn)。在“Implementation Changes”窺視窗中(在右側(cè)),功能“main”被顯示,指示改變已發(fā)生。
面向目標連接本敘述列出了HOOPS連接程序的重要特性,它提供了一個最佳實施例的運行時間環(huán)境的背景以及提供連接出現(xiàn)的上下文的HOOPS數(shù)據(jù)庫。最后,有關(guān)HOOPS編譯程序HOOPS數(shù)據(jù)庫,以及系統(tǒng)裝入程序的連接和交互的討論將參照一個最佳實施例進行。
連接程序特性·連接發(fā)生在編譯處理過程中,沒有其它的連接通路。
·在建立過程中,只有最新被編譯的功能和數(shù)據(jù)才被再次連接。
·在增量發(fā)展過程中,某些共享的庫空間被用于換取速度。
·編譯程序與部件和特性交互以產(chǎn)生全部目標碼和其他連接信息。
·當一個程序可交付使用時,一個“出版”步驟將去除增量發(fā)展過程中用過的多余的空間和信息,并程序與HOOPS分離開。
·一個“快速出版(QuickPublish)”步驟將從用于與其他程序共享的HOOPS中把該程序快速地分離出來,或移至另一機器。
·連接程序可是擴充的,因為該編譯程序可以指定該連接程序通常不處理的新安排。
·一個中止的程序可被修改然后再恢復(fù)執(zhí)行而無須被再次裝入(有些變化將要求裝入)。
連接程序在HOOPS內(nèi)操作并生成由裝入程序使用的文件。為了理解連接程序技巧,重要的是要理解運行時間系統(tǒng)和HOOPS的獨特之處。
一個可執(zhí)行的文件與運行時間的交互在其他運行時間系統(tǒng)中大不相同。通常,一個裝入程序必須理解可執(zhí)行文件格式。該可執(zhí)行文件已知描述該程序各個方面(例如所需存儲器量,主地址,任何在裝入時刻需要的再定位信息,以及任何在可執(zhí)行文件中組裝的調(diào)試信息)的字段。在一個最佳實施例的運行時間中,裝入程序通過一個抽象“T裝入模塊(TLaodModule)”分類界面與該可執(zhí)行文件交互。該“T裝入模塊”為所有裝入操作提供協(xié)議,例如,象指定存儲器要求,建立元數(shù)據(jù)信息以及連接其他共用庫的操作都由“T裝入模塊”的方法提供。借助這一方式,一個裝入模塊可以有許多方式響應(yīng)裝入請求。
運行時間定義提供了共用庫,并允許在裝入時刻解決交叉庫調(diào)用。由于庫可以在任何存儲位置裝入,所有碼必須是位置獨立的,或必須在裝入時刻被修補。除了位置獨立碼之外,必須在裝入時刻解決對其他庫的調(diào)用。這是由于靜態(tài)連接程序不知道存儲器中的外部庫的定位或相對位移是什么。
雖然每個“T裝入模塊”分類可以許多不同方式實施交叉庫調(diào)用,標準方式則是要通過在裝入時刻修補過的連接區(qū)轉(zhuǎn)移,該連接區(qū)作為在兩個庫之間的間接轉(zhuǎn)移表。一個外部調(diào)用將轉(zhuǎn)移子程序返回(JSR)到該連接區(qū),然后該連接區(qū)將轉(zhuǎn)移(JMP)到調(diào)用的功能。內(nèi)部調(diào)用可以直接轉(zhuǎn)移并程序返回到該調(diào)用的功能。一個內(nèi)部和交叉庫調(diào)用的實例示于圖19中并說明如下。
對f1( )1900的調(diào)用是一個內(nèi)部調(diào)用,所以JSR直接去往f1( )1910。對f2( )1920的調(diào)用是一個交叉庫調(diào)用,因此調(diào)用去往裝入時刻修補的外部連接區(qū)1930。
HOOPS環(huán)境還提供了連接程序的唯一的上下文聯(lián)系。一個程序被展示為一個部件集合。每個部件有一組相關(guān)的特性。在每個部件的編譯過程中,編譯程序?qū)⑸珊痛鎯τ糜谠摬考奶匦?。HOOPS建立處理對部件的建立排序,以致于所有界面說明在實施(定義)之前便被編譯。
一個HOOPS項目可以包括幾個庫部件。所有源部件都是這些庫部件之一的成員。每個庫部件表示一個共用庫建立。
綜觀為了支持增量連接并使最終應(yīng)用程序成為最小最快,生成了兩種不同的裝入模塊。在開發(fā)過程中,HOOPS生成和修改了一個“T增量裝入模塊(T incremental Load Module)”。有一個第二文件,“T標準裝入模塊(TStfandardLoadModule)在出版應(yīng)用程序之前生成。
一個最佳實施例公開了在開發(fā)過程中建立和更新代碼的途徑。把一個“T增量裝入模塊”轉(zhuǎn)換成“T標準裝入模塊”涉及一個多余的“出版”步驟。該步驟與一個常規(guī)的連接步驟很類似,其中,每個功能或數(shù)據(jù)項將被再定位和修補。但是,直到裝入時刻才解決外部引用。
編譯程序交互隨著編譯程序生成一個部件的代碼,該碼由用于修補目標碼的一組安排傳到目標碼特性。每個編譯的部件使其目標碼特性裝滿。編譯程序使用一個“目標組”模塊。即一個部件可以由多種類型的目標碼組成。例如,一個功能可能也有一個與其相關(guān)的專用靜態(tài)數(shù)據(jù)區(qū)以及用于該靜態(tài)數(shù)據(jù)區(qū)的解除程序順序。一個靜態(tài)數(shù)據(jù)項可能有一個構(gòu)成程序以及與之相關(guān)的解除程序順序以便在運行時刻將其初始化。
例如,假設(shè)下列部件被編譯TFoo∷Print( )Static int times Called=0cout&lt;&lt;“Hello world”&lt;&lt;timesCalled&lt;&lt;“\n”;timesCalled++;}該編譯程序?qū)⑸蓛刹糠帜繕舜a并將它們與部件TFoo∷Print相關(guān)。將有用于功能的目標碼,以及4字節(jié)的專用數(shù)據(jù)用于靜態(tài)變量timesCalled。
有些看起來就象下文Object code property of TFoo∷Print-code0x0000 LINK A6,#00x0004 MOVE.LA5,--(A7)0x0006 PEA L10x000A MOVE.L&lt;timesCalled&gt;,--(A7)0x000E PEA L20x0012 MOVE.Lcout,--(A7)0x0016 BSR &lt;operator&lt;&lt;(char*)&gt;
0x001C ADDQ.L#8,A70x001E MOVE.LD0,--(A7)0x0020 BSR &lt;operator&lt;&lt;(int)&gt;
0x0026 ADDQ.L#8,A70x0028 MOVE.LD0,--(A7)0x002A BSR &lt;operator(char*)&gt;0x0030 ADDQ.L #8,A70x0032 ADDQ.L #1,&lt;timesCalled&gt;0x0034 UNLK A60x0036 RTSL1DB "\n"L2DB "Hello world"Object code property of TFoo∷Print-data00000000 00000000與目標碼一起,編譯程序?qū)⒄f明由于該碼被重新定位而必須采用的不同安排。這些可能看起來象refererce to times CalledOffset 0x0creference to CoutOffset 0x14reference to ostream∷Operator&lt;&lt;(Coust char*)Offset 0x18referenee to Ostream∷Operator&lt;&lt;(int)Offset 0x22refereace to Ostream∷Operator&lt;&lt;(Const Char*)Off-set 0x2creference to times Called Offset 0x34注意安排可以指定對與同一部件(專用靜態(tài)變量timesCalled)的目標的其他部分的引用,或者對其他部件(例如Cout0的引用。
當編輯程序已經(jīng)完全指定了完整的數(shù)據(jù)集和與一個部件相關(guān)安排時,目標碼特性重新對所有部分定位并在同樣時刻將其連接起來。在所有部件被編譯后沒有第二個連接通路。隨著每個部分新編譯,它也被完全連接。
安排表連接實質(zhì)上是一個通過安排表反復(fù)進行并以適當方式修補代碼的過程。通過一個分類層級指定不同類型的安排(fixup),每種安排都知道如何計算修補值。例如,一個PC相關(guān)安排知道其必須計算其定位地址和引用的部件之間的差值。一個絕對安排知道必須延遲計算直到裝入時刻。雖然連接程序指定了一組安排分類,但新的編譯程序可以指定新型安排。圖20示出了根據(jù)最佳實施例的一組安排分類。
地址計算當每個部件被編譯時進行連接的主要問題是其引用的一些部件可能未經(jīng)編譯。
每個源部件正好是一個庫部件的一個成員。與每個庫部件相關(guān)的是一個裝入模塊特性。該裝入模塊特性清除屬于該共用庫的所有部件的空間。由于一個安排準備計算一個修補值,它詢問一個部件的地址的裝入模塊特性。該裝入模塊特性檢查是否該模塊已為編譯。若是,則返回該部件的地址。若否,則裝入模塊特性根據(jù)該部件的類型執(zhí)行兩個動作。
若該部件的類型是數(shù)據(jù)部件,則返回到恒定地址。若其為一功能部件則為該功能生成一個連接區(qū),并返回到該連接區(qū)的地址。
目標布局如前所述,當每個部件被編譯時,它分配一個在共享庫中的位置。隨著其完成,某些多余的工作必須完成以便所有引用是一致的。
若該部件是一數(shù)據(jù)部件,所有它的客戶都被告知它所處的位置。某些客戶可能開始已與假設(shè)地連接,所以這一處理必須清除所有客戶并為其提供正確地址。若該部件為一功能部件,則該功能的連接區(qū)為新地址所更析。應(yīng)當注意,這兩種途經(jīng)提供了對功能的間接存取和對數(shù)據(jù)的直接存取。
此外,分配有多余空間,以便目標碼未來的更新尤其可能使用同樣區(qū)域。多出12%提供給功能而多出25%供給大數(shù)據(jù)目標。
連接區(qū)如上所述,當為了一個功能的地址而請求裝入模塊特性的時候,該特性將給出該連接區(qū)的地址。這意味著每個功能引用都是間接的,圖21展示了根據(jù)一個最佳實施例的連接區(qū)。
應(yīng)當注意,不僅內(nèi)部庫間接通過內(nèi)部連接區(qū)調(diào)用,而且交叉庫也通過庫的內(nèi)部連接區(qū)對功能進行間接調(diào)用9即對庫B中f2的調(diào)用(2100,2110,2115及2120)這必須完成以便f2可以在無需更新其內(nèi)部和外部客戶的情況下改變位置,并保持一致性從而使功能指針之類的項正確地工作。此外,所有虛擬表功能指針也將指向內(nèi)部連接區(qū)。
任何被引用的但未定義的功能將指向一個通用“未實施( )(Unimplemented( ))”功能。由于所有未編譯的功能指向“未實施( )”。因而程序員不必生成存根模塊功能從而簡化了裝入和運行部分應(yīng)用程序。
具有內(nèi)部連接區(qū)的另一好處是提供了一個對所有功能的渠道。在開發(fā)過程中,內(nèi)部連接區(qū)可用于需要功能追蹤的活動(例如調(diào)試或性能監(jiān)測)。
增量連接前述討論已對增量連接的詳細討論奠定了基礎(chǔ),當一個部件被再編譯時,新部件的尺寸將與舊部件的尺寸進行比較以確定是否新部件符合現(xiàn)有定位。若符合,則存在諸位置,并通過它的安排表將語新部件造代,隨即完成聯(lián)接。
若新部件的目標碼必須被重新定位,則以前的空間被注以廢棄標記,而新目標碼被定位到一個新區(qū)域。然后安排表被迭代。若該部件是一功能,則更新連接入口。連接然后完成。但是,若部件是一數(shù)據(jù)項,則該部件必須在客戶表上迭代并更新該部件的引用。然后該數(shù)據(jù)的連接才告完成。
應(yīng)注意起始連接和增量連接按照同樣步驟進行。在增量更新中唯一多出的步驟是處理何時一個數(shù)據(jù)項必須改變定位。
目標碼存儲目標碼和裝入模塊特性是通常的部件特性。它們象所有其他特性一樣,存在HOOPS的數(shù)據(jù)庫中。但是,目標碼特性描述目標碼但不包含實際位。實際位存在由裝入模塊特性所有的段中。該裝入模塊特性有四個不同的段,它們包括碼、未初始化碼、初始化碼以及連接區(qū)。
圖22展示了根據(jù)最佳實施例的目標碼存儲。每個圖形目標220有一個關(guān)聯(lián)的裝入模塊特性2250,它包括與圖形目標2210,2220,2230和2240相關(guān)聯(lián)的單獨的目標碼。由于所有碼在編譯時都被連接,并且提供了對于改變和增量建立的支持,因而裝入模塊特性維護了位于每個段中心所有目標的映射。它還償試保持用于增長的多余空間。該多作空間會浪費一些虛擬存儲空間,但并不占用后備存儲器或?qū)嶋H存儲器。若在反復(fù)改變和建立一個應(yīng)用程序的處理過程中,該多余空間被消耗的情況,則將分配其他空間,受到影響的段必須被重新定位而且所有對于該段的出入引用必須被更新。
圖23示出了根據(jù)最佳實施例的裝入庫。空白區(qū)段2300,2100,2320和2330代表自由空間。該庫為未初始化數(shù)據(jù)2340,初始化數(shù)據(jù)2350,代碼2360和連接區(qū)2370提供了四個段。在HOOPS中,這些段沒有空間關(guān)系。連接使用將被裝入的關(guān)系的內(nèi)容而非可能在HOOPS本身內(nèi)具有的關(guān)系。
裝入為了運行一個程序,裝入程序必須有一個數(shù)據(jù)流式“T裝入模塊”分類。在建立程序過程中,生成一個數(shù)據(jù)流式“T裝入模塊”,當裝入時,把生成的段裝入HOOPS,沒被裝入的應(yīng)用程序和HOOPS共用。這提供了兩個好處首先,它大大減少了必須復(fù)制的工作量,其次,它使程序在裝入時進行增量更新。
由于裝入程序需要一個數(shù)據(jù)流式“T裝入模塊”分類,而且“T增量裝入模塊(Tincremental Load Module)要減少流入的信息量,因此,必須寫出從開始到結(jié)束數(shù)據(jù)流。這意味著對于一個程序中心大部分改變,“T增量裝入模塊”將不必是再被數(shù)據(jù)流化的。通過使用共享堆陳該“T增量裝入模塊”從HOOPS中得到所有映射信息,否則,任何數(shù)據(jù)定位中心的改變或功能尺寸的改變都需要建立一個新的“T增量裝入模塊”并被數(shù)據(jù)流化。圖24是一個根據(jù)一個最佳實施例的裝入模塊的存儲映射。
增量更新增量連接簡化了對一個裝入庫的修改且無需從執(zhí)行中將其去除。這要求在HOOPS中所做的改變在運行應(yīng)用程序的地址空間中反映出來,這是通過把庫作為共用段的方式處理的。在HOOPS一例進行的任何修改將在運行程序側(cè)反映出來。應(yīng)記住,在HOOPS一側(cè),段被解釋為HOOPS數(shù)據(jù)庫的一部分,而在應(yīng)用程序一側(cè),它只是包含目標碼的一個段。
進行程序修改的模式如下調(diào)試程序首先停止執(zhí)行;然后編譯修改后的功能,并把修改后的功能裝入不同位置,雖然它們也符合其現(xiàn)有位置;再對內(nèi)部連接區(qū)進行更新;然后繼續(xù)該程序。若一個修改的功能在棧上有效,則舊版本將執(zhí)行直到該功能的下一調(diào)用。一個替代方案是在有效功能被修改時取消該程序。
出版一個程序當一個應(yīng)用程序發(fā)行時,連接程序?qū)阉心繕舜a復(fù)制到數(shù)據(jù)庫外面的一個文件中,隨著段被復(fù)制到一個外部文件,連接程序?qū)λ泄δ苓M行再定位及修補。此外,所有內(nèi)部調(diào)用將成為直接調(diào)用,且內(nèi)部連接區(qū)將被去除。除了連接和重新對目標碼定位之外,連接程序必須包括虛擬表生成所需的元數(shù)據(jù)。應(yīng)注意,這一步驟基本是一個連接而不涉及編譯程序。
還需要第二種出版方式,該方式叫做快速出版。一個快速出版把需要的段從數(shù)據(jù)庫復(fù)制到一個外部文件。第二出版的目的是支持交叉開發(fā)或共享工作的快速換向。
實施細節(jié)分類定義<pre listing-type="program-listing"><![CDATA[  enum EObjectKind {kCode,kData,  kStaticCtor,kStaticDtor};  class TObjectPropertypublic TProperty{  public   TObjectProperty( );   virtual   ~TObjectProperty( );  //Compiler Interface   virtual void WriteBits(EObjectKind   whichOne,LinkSize length,  void*theBits,unsigned shortalignment);   virtualvoidAdoptFixup(EObjectKindwhichOne,TFixup*theFixup);// Getting/Setting   void*   CopyBits(EObijectKind whichOne)const;   LinkOffset GetOffset(EObjectKindwhichOne)const;   LinkSize   GetLength(EObjectKind whichOne)const;   ELinkSegment   GetLinkSegment(EObjectKind whichOne)const;   Boolean   Contains(EObjectKind whichOne)const;   virtual EObjectKind GetPublicKind( )const=0;// Linking   virtual void GetLocation(EObjectKindwhichOne,TLocation&amp;fillInLocation)const;   TIterator*CreateFixupIterator( )const;};   The object code property delegates the fixup work toindividual fixup objects.   class TFixup {   public   void DoFixup(void*moduleBase)=0;   private   TComponent*fReference;   longfOffset;   };]]></pre>
從T Fixup衍生出來的分類為TPcRelative Fixup,Tabso-luteFixup以及TDataRelativeFixup,每一安排分類都清楚如何對其類型進行適當?shù)男扪a,這與常規(guī)的編譯程序/連接程序交互全然不同,在常規(guī)編程程序/連接程序交互時,連接程序必須對不同的位進行解釋以決定要采取何種行動。這一方式另一優(yōu)點在于用于一個新結(jié)構(gòu)的新編譯程序不必擔心一個安排類型不為連接程序所支持。
引用類別連接程序必須處理4類引用。它們是碼對碼,碼對數(shù)據(jù),數(shù)據(jù)對碼,以及數(shù)據(jù)對數(shù)據(jù)。每類引用被處理(對68K而言)的方式敘述如下碼對碼例如Foo( );編譯程序根據(jù)文本以兩種不同方式處理這一情況。它可go pc-relative to Foo( ),或可把Foo( )的地址裝入,并直接去往一個寄存器。任何內(nèi)部調(diào)用都可選用其中一種方式,連接程序?qū)⒖偸菆蟾孢B接區(qū)的地址,交叉庫調(diào)用必須使用裝入地址的方式,這些將用絕對地址,這些絕對地址則在裝入時刻被修補。
碼對數(shù)據(jù)例如gValue=1;編譯程序產(chǎn)生一個對于gValue的Pc-relative存取,但是,其gValue在一個不同的共用庫中時,編譯程序?qū)⒆詣由梢粋€間接引用。連接程序?qū)⒉东@該間接引用并提供一個在裝入時刻由外部地址修補過的本地地址。
數(shù)據(jù)對碼和數(shù)據(jù)對數(shù)據(jù)例如(數(shù)據(jù)對數(shù)據(jù))Void(*pfn)( )=&amp;Foo;例如(數(shù)據(jù)對數(shù)據(jù))int&amp;pi=i;由于這兩種引用都需要絕對地址,它們將在裝入時被處理。在裝入時刻修補數(shù)據(jù)引用就象修補外部引用一樣。
圖25表示了在每類引用中發(fā)生的情況。若一個外部庫要引用同樣的部件,該庫將在裝入時刻接收幾個GetExpor-tadres( )調(diào)用。響應(yīng)于GetExportaddress( )調(diào)用,一個庫將返回到功能的內(nèi)部連接區(qū)地址以及數(shù)據(jù)的實地址。這使得當庫在被裝載時,功能在附近移動。
圖26,27,28和29是示明與一最佳實施例相關(guān)的邏輯的流程圖。圖26展示了控制的“整個流程,處理起始于2602,該處,建立操作按前述那樣被初始化且處理去往功能框2610以供編譯。這一處理始于功能框2630,在那里,目標碼被接受且收集部件的安排,然后,在功能框2640處存儲目標碼并在功能框2650處為新改變的目標模型進行安排,與功能框2640關(guān)聯(lián)的處理詳細示于圖27中,而與功能框2650的細節(jié)示于圖28和29中。
圖27是一流程圖,示出了與根據(jù)本發(fā)明的目標碼存儲關(guān)聯(lián)的邏輯。處理始于2700并立即去往判別框2710以確定是否這是一個起始存儲操作。若是,則存儲按功能框2740所示分配,一個入口在功能框2744中示出的映射中生成或更新,其細節(jié)示于圖29中,然后該目標在功能框2750處存儲。若另一分量在該目標被編譯之前已引用了該目標,則發(fā)生更新。判別框2710將決定是否這是一個更新操作。然后在判別框2720處進行測試以確定是否該碼與現(xiàn)有位置吻合。若是,則在功能框2750處存儲該目標,若否,則在功能框2730處消除現(xiàn)有的存儲,并在判別框2760處進行另一測試以確定是否該數(shù)據(jù)為目標數(shù)據(jù)。若是,則在功能框2762處分配存儲,并在功能框2770中在所示的映射中生成入口或更新入口,其細節(jié)示于圖29中,并且在功能框2750處存儲該目標。
圖28展示了安排處理以及與獲取一個引用目標的地址關(guān)聯(lián)的處理的詳細邏輯。執(zhí)行安排的處理始于2800并馬上去往功能框2810獲取一個引用目標的地址。然后,在判別框2820處,進行測試以確定是否需要絕對安排。若是,則在功能框2830處為一個裝入操作注釋該絕對安排,若否,則用功能框2840所示的相關(guān)位置修補該碼。獲取引用目標地址的處理始于功能框2850,在判別框2860處立即進行測試以確定是否一個目標已在映射之中。若是,則地址返回到功能框2880,若否,則在功能框2744所示的映射中行成或更新一個入口,其細節(jié)示于圖29,然后地址返回到功能框2880。
圖29是根據(jù)本發(fā)明在一個映射中生成或更新一個入口的邏輯。處理始于2900并立即去往判別框2910以確定是否一個目標已在該映射之中,若目標存在,則在判別框2930處進行測試以確定目標是否為數(shù)據(jù)。若是數(shù)據(jù),則映射為功能框2940所示之新地址所更新。否則,由功能框2920中所示之新地址更新轉(zhuǎn)移位置。若目標不在映射中,則在判別框2950處進行另一測試以確定是否該目標是數(shù)據(jù),若是,則由功能框2960所示之適當?shù)刂飞梢粋€映射,若否,則由功能框2980所示之連接區(qū)生成一個對于以后定義的位置的轉(zhuǎn)移位置,并由連接區(qū)地址將一入口收入該映射中。
雖然本發(fā)明以實施例方式敘述了本發(fā)明,但本發(fā)明領(lǐng)域的一般技術(shù)人員可了解本發(fā)明的基本原理并可據(jù)其進行修改和變型,本發(fā)明的范圍受權(quán)利要求保護。
權(quán)利要求
1一種連接計算機程序的方法,其特征在于包括以下步驟(a)將一個計算機程序模式成一個部件的集合;(b)在一存儲器中存儲這些部件;(c)訪問所存儲的部件并計算與每個部件關(guān)聯(lián)的相關(guān)性以生成一個相關(guān)性表;(d)根據(jù)該相關(guān)性表編譯部件以生成一個更新的目標模塊;以及(e)通過更新一個現(xiàn)有的可執(zhí)行文件來連接該更新的目標模塊。
2權(quán)利要求1所述的方法,其中,連接該更新的目標模塊的步驟與編譯部件的步驟并行發(fā)生。
3權(quán)利要求1所述的方法,其中,只有更新的目標模塊被連接。
4權(quán)利要求1所述的方法,包括在存儲器中把目標碼作為部件特性存儲的步驟。
5權(quán)利要求1所述的方法,包括存儲一個包括連接信息的數(shù)據(jù)庫的步驟。
6權(quán)利要求1所述的方法,包括在連接操作完成時釋放存儲的步驟。
7權(quán)利要求1所述的方法,還包括以下步驟(a)在存儲器中存儲一個外部連接區(qū);以及(b)由外部調(diào)用信息在裝入時刻修補該外部連接區(qū)。
8一種用于連接計算機程序的裝置,特征在于包括(a)用于將計算機程序成型為一個部件集合的裝置;(b)用于在存儲器中存儲部件的裝置;(c)用于訪問存儲的部件并計算與每個部件關(guān)聯(lián)的相關(guān)性以生成一個相關(guān)性表的裝置;(d)用于根據(jù)該相關(guān)性表的編譯部件以生成一個更新的目標模塊的裝置;以及(e)用于通過更新一個現(xiàn)有的可執(zhí)行文件來連接該更新的目標模塊的裝置。
9權(quán)利要求8所述裝置,其中所述用于連接更新的目標模塊的裝置與用于編譯部件的裝置并行工作。
10權(quán)利要求8所述裝置,其中所述用于連接的裝置只連接更新的目標模塊。
11權(quán)利要求8所述裝置,還包括用于把目標碼作為部件特性存在存儲器中的裝置。
12權(quán)利要求8所述裝置,還包括用于存儲包括連接信息的數(shù)據(jù)庫的裝置。
13權(quán)利要求8所述裝置,還包括在連接操作結(jié)束時釋放存儲的裝置。
14權(quán)利要求8所述的裝置,還包括(a)用于在存儲器中存儲外部連接區(qū)的裝置;以及(b)用于在裝入時刻由外部調(diào)用信息修補該外部連接區(qū)的裝置。
15一種用于連接計算機程序的方法,其特征在于包括(a)將計算機程序模式成為一個部件的一個集合;(b)在存儲器中存儲部件;(c)訪問所存儲的部件并計算每個部件的相關(guān)性以生成一個相關(guān)性表;(d)根據(jù)該相關(guān)性表編譯部件以生成一個更新的目標模塊;(e)通過更新一個現(xiàn)有的可執(zhí)行文件來連接更新的目標模塊;以及(f)更新一個裝入的可執(zhí)行文件。
16權(quán)利要求15所述的方法,還包括存儲目標模塊以簡化可執(zhí)行文件的自連接的步驟。
17權(quán)利要求16所述的方法,還包括在存儲目標模塊時進行目標自連接的步驟。
全文摘要
一個面向人的目標編程系統(tǒng)提供了一個交互和動態(tài)的處理以助于計算機程序的增量建立,該增量建立簡化了諸如操作系統(tǒng)以及有圖形用戶界面的大的應(yīng)用程序之類的復(fù)雜計算機程序的開發(fā)。一個程序被成型為一個稱為部件的單元集。一個部件表示一個象分類或功能性之類的可編譯語言成分。三個主要的功能性是數(shù)據(jù)庫,編譯程序和建立處理。一個增量連接程序在建立處理中操作以生成由裝入程序所用的文件。
文檔編號G06F9/445GK1102934SQ94190010
公開日1995年5月24日 申請日期1994年1月6日 優(yōu)先權(quán)日1993年6月28日
發(fā)明者羅杰·P·勞倫斯, 約翰·R·丹斯 申請人:塔里根特公司
網(wǎng)友詢問留言 已有0條留言
  • 還沒有人留言評論。精彩留言會獲得點贊!
1
梧州市| 五华县| 亳州市| 德钦县| 大丰市| 昌邑市| 丹江口市| 内乡县| 昌图县| 莱阳市| 舞阳县| 宝山区| 玛沁县| 福贡县| 陵水| 肥东县| 鄂尔多斯市| 黑龙江省| 金山区| 贞丰县| 新密市| 建平县| 江门市| 桦川县| 定日县| 肥西县| 佛山市| 桂阳县| 冀州市| 沂源县| 郁南县| 丰原市| 山东省| 微山县| 常熟市| 阿坝县| 东山县| 若尔盖县| 河北省| 昆明市| 大宁县|