因為在開發
CMinus的過程中為了異常處理(最終沒有實現進CMinus),曾經學習了一下
怎么用匯編語言寫try-catch,因此這個CPU相關的處理方法就被我偷了哈,實現在了
NativeX的虛擬機里。
在NativeX里面,try-catch和throw非常簡單。throw你可以加一個值當異常數據,也可以不加(不會修改上次的異常數據,可以當rethrow用)。catch的話沒辦法跟C++一樣根據類型來判斷,因此我會給你一個異常數據的指針,你自己看著辦哈,因為NativeX跟C一樣沒有RTTI。因此throw就很簡單了,就是恢復棧頂和棧底指針之后跳轉到最近的異常處理程序里面去。try和catch就是用來創建和銷毀異常處理程序的。所有的異常處理程序構成了一個鏈表,這個鏈表被我記在了堆棧里面,而最近的異常處理節點的指針則被我放在了整個堆??丶淖铐敳浚釉诤竺娴氖钱惓ο蟮臄祿D忝看蝨hrow的東西的尺寸可以不同,因此占用的“堆棧最頂部空間”也不同。當然如果你函數遞歸太深而導致棧頂覆蓋了異常對象的數據區域時,就會觸發“堆棧溢出”事件。在NativeX里面堆棧溢出代表你這程序已經廢了,因此這個是不能catch的,虛擬機返回給宿主程序一個信號然后就停止執行了。
我們來看一個簡單的例子,如何throw之后把異常對象的返回給函數,首先是代碼:
1 /*NativeX Code*/
2 unit nativex_program_generated;
3 function int32 main()
4 {
5 (result = 10s32);
6 try
7 Throw();
8 catch
9 (result = ( * cast<int32*>(exception)));
10 }
11
12 function void Throw()
13 throw 20s32;
main函數首先將函數返回值設置成10,然后調用throw函數。throw函數會把20給throw出來,然后main函數catch了,把結果返回。NativeX使用了關鍵字exception來表達異常對象的地址。當然你如果要throw各種不同的東西的話,你得自己做標記(親自實現RTTI)了。好了,我們看看產生的指令:
1 // unit nativex_program_generated;
2 0: stack_reserve 0
3 1: stack_reserve 0
4 2: ret 0
5 // function int32 main()
6 3: stack_reserve 0
7 // (result = 10s32);
8 4: push s32 10
9 5: resptr
10 6: write s32
11 // try
12 7: exception_handler_push 14
13 // Throw();
14 8: stack_reserve 1
15 9: stack_top 0
16 10: call 20 1
17 11: stack_reserve -1
18 // try
19 12: exception_handler_pop
20 13: jump 18 1
21 14: exception_handler_pop
22 // (result = ( * cast<int32*>(exception)));
23 15: exception_object_address
24 16: resptr
25 17: copymem 4
26 // function int32 main()
27 18: stack_reserve 0
28 19: ret 0
29 // function void Throw()
30 20: stack_reserve 0
31 // throw 20s32;
32 21: exception_object_reserve 4
33 22: push s32 20
34 23: exception_object_address
35 24: write s32
36 25: exception_raise
37 // function void Throw()
38 26: stack_reserve 0
39 27: ret 0
try首先會將catch之后的第一個指令給exception_handler_push了,在try的結尾當然要取消掉這個異常處理函數了,因此pop一下,然后jump到catch后面。當然catch的第一件事也是exception_handler_pop。exception_object_reserve在棧頂預留指定的空間來存放異常對象,exception_object_address則是獲得異常對象的地址,exception_raise就是跳轉到最近的異常處理函數了。raise不會把異常處理函數的記錄給pop掉,所以要靠catch自己去pop。
NativeX已經完成了,接下來就可以開始打造周邊工具了哇哈哈。將來的目標是將類似C#和Javascript的語言都編譯到NativeX上,然后為這三類語言寫很多語法分析器,然后他們就變成很多語言了。當然這些語言只是demo。
Vczh Library++的目的是提供實現編譯器的中間每一層的類庫,因此想干嘛就可以干嘛了哈。
posted on 2010-08-28 01:14
陳梓瀚(vczh) 閱讀(3492)
評論(9) 編輯 收藏 引用 所屬分類:
VL++3.0開發紀事