source: trunk/Include/system/exception.ab@ 373

Last change on this file since 373 was 373, checked in by dai, 16 years ago

Try-Catchを試験的に実装。
(まだ下記の動作しか実装していません)
・Try
・Catch(パラメータ無し)
・Throw(パラメータ無し)

File size: 3.2 KB
Line 
1'TODO: ローカルオブジェクト確保及び解放時にTryServiceに通知する必要がある。
2
3Class TryLayer
4Public
5 Const addressOfCatch As VoidPtr
6 Const basePtr As LONG_PTR
7 Const stackPtr As LONG_PTR
8 Const debugProcNum As DWord
9
10 Sub TryLayer( addressOfCatch As VoidPtr, basePtr As LONG_PTR, stackPtr As LONG_PTR )
11 This.addressOfCatch = addressOfCatch
12 This.basePtr = basePtr
13 This.stackPtr = stackPtr
14
15#ifdef _DEBUG
16 Dim ThreadNum As Long
17 ThreadNum=_DebugSys_GetThread()
18 If ThreadNum <> -1 Then
19 debugProcNum = _DebugSys_ProcNum[ThreadNum]
20 End If
21#endif
22 End Sub
23 Sub ~TryLayer()
24 End Sub
25End Class
26
27Class ExceptionService
28 ppTryLayers As **TryLayer
29 nTryLayers As Long
30
31 Sub FreeLocalObjects()
32 'TODO: 破棄されていないローカルオブジェクトを破棄
33 End Sub
34Public
35
36 Sub ExceptionService()
37 ppTryLayers = _System_malloc( 1 )
38 nTryLayers = 0
39 End Sub
40 Sub ~ExceptionService()
41 Dim i As Long
42 For i = 0 To ELM( nTryLayers )
43 Delete ppTryLayers[i]
44 Next
45 _System_free( ppTryLayers )
46 ppTryLayers = 0
47 End Sub
48
49 'Try
50 Function _BeginTryScope( addressOfCatch As VoidPtr, basePtr As LONG_PTR, stackPtr As LONG_PTR ) As TryLayer
51 ppTryLayers = _System_realloc( ppTryLayers, ( nTryLayers + 1 ) * SizeOf( *TryLayer ) )
52 ppTryLayers[nTryLayers] = New TryLayer( addressOfCatch, basePtr, stackPtr )
53 nTryLayers++
54
55 Return ByVal ppTryLayers[nTryLayers-1]
56 End Function
57
58 Static Function BeginTryScope( addressOfCatch As VoidPtr, basePtr As LONG_PTR, stackPtr As LONG_PTR ) As TryLayer
59 Return _System_pobj_AllThreads->GetCurrentException()->_BeginTryScope( addressOfCatch, basePtr, stackPtr )
60 End Function
61
62 'End Try
63 Sub EndTryScope()
64 nTryLayers--
65 Delete ppTryLayers[nTryLayers]
66 End Sub
67
68 'Throw
69 Sub _Throw()
70 If nTryLayers <= 0 then
71 '例外処理スコープ制御が無効なとき
72
73 'TODO: 適切なエラー処理
74 MessageBox( NULL, "例外", "", MB_OK or MB_ICONEXCLAMATION )
75
76 Return
77 End If
78
79 '未解放なローカルオブジェクトを解放する
80 FreeLocalObjects()
81
82
83
84 '--------------------------------------------------
85 ' スレッドのコンテキストを設定(Catchへ遷移する)
86 '--------------------------------------------------
87
88 Dim context As CONTEXT
89 context.ContextFlags = CONTEXT_CONTROL or CONTEXT_INTEGER
90 If GetThreadContext( GetCurrentThread(), context ) = 0 Then
91 ' TODO: エラー処理
92 debug
93 End If
94
95 '新しいip, sp, bpをセット
96#ifdef _WIN64
97 context.Rip = ppTryLayers[nTryLayers - 1]->addressOfCatch As QWord
98 context.Rbp = ppTryLayers[nTryLayers - 1]->basePtr
99 context.Rsp = ppTryLayers[nTryLayers - 1]->stackPtr
100#else
101 context.Eip = ppTryLayers[nTryLayers - 1]->addressOfCatch As DWord
102 context.Ebp = ppTryLayers[nTryLayers - 1]->basePtr
103 context.Esp = ppTryLayers[nTryLayers - 1]->stackPtr
104#endif
105
106#ifdef _DEBUG
107 Dim ThreadNum As Long
108 ThreadNum=_DebugSys_GetThread()
109 If ThreadNum <> -1 Then
110 _DebugSys_ProcNum[ThreadNum] = ppTryLayers[nTryLayers - 1]->debugProcNum-1
111 End If
112#endif
113
114 If SetThreadContext( GetCurrentThread(), context ) = 0 Then
115 OutputDebugString(Ex"レジスタ情報の設定に失敗しました。\r\n")
116 Return
117 End If
118 End Sub
119
120 Sub _Throw( msg As String )
121 _Throw()
122 End Sub
123End Class
124
Note: See TracBrowser for help on using the repository browser.