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

Last change on this file since 411 was 411, checked in by イグトランス (egtra), 16 years ago

UTF8Encoding(仮)の追加

File size: 5.5 KB
Line 
1'TODO: ローカルオブジェクト確保及び解放時にTryServiceに通知する必要がある。
2
3Class TryLayer
4Public
5 Const catchTable As *LONG_PTR
6 Const addressOfFinally As VoidPtr
7 Const basePtr As LONG_PTR
8 Const stackPtr As LONG_PTR
9
10 Const debugProcNum As DWord
11
12 Sub TryLayer( catchTable As *LONG_PTR, addressOfFinally As VoidPtr, basePtr As LONG_PTR, stackPtr As LONG_PTR )
13 This.catchTable = catchTable
14 This.addressOfFinally = addressOfFinally
15 This.basePtr = basePtr
16 This.stackPtr = stackPtr
17
18#ifdef _DEBUG
19 Dim ThreadNum As Long
20 ThreadNum=_DebugSys_GetThread()
21 If ThreadNum <> -1 Then
22 debugProcNum = _DebugSys_ProcNum[ThreadNum]
23 End If
24#endif
25 End Sub
26 Sub ~TryLayer()
27 End Sub
28
29 Sub FinishFinally()
30 Imports System.Threading
31 If Thread.CurrentThread().__IsThrowing() Then
32 Throw Thread.CurrentThread().__GetThrowintParamObject()
33 End If
34 End Sub
35
36 Function ResolveCatchesOverload( ex As Object ) As LONG_PTR
37 OutputDebugString("ResolveCatchesOverload: ")
38 OutputDebugString(ToTCStr(ex.ToString))
39 OutputDebugString(Ex"\r\n")
40 Dim defaultCatchCodePos = 0 As LONG_PTR
41 Dim pos = 0 As Long
42 While catchTable[pos]
43 ' パラメータのクラス名
44 Dim paramName = catchTable[pos] As *Char
45 pos ++
46
47 ' コード位置
48 Dim codePos = catchTable[pos] As LONG_PTR
49 pos ++
50
51 If paramName[0] = 0 Then
52 ' Default Catch
53 defaultCatchCodePos = codePos
54 End If
55
56 If Object.ReferenceEquals( ex, Nothing ) Then
57 ' パラメータなしのとき
58 If paramName[0] = 0 Then
59 ' マッチしたとき
60 Return codePos
61 End If
62 Else
63 If isCatchable(New String(paramName), ex.GetType()) Then
64' If lstrcmp( paramName, ex.GetType().FullName ) = 0 Then
65 ' マッチしたとき
66 Return codePos
67 End If
68 End If
69 Wend
70 Return defaultCatchCodePos
71 End Function
72Private
73 Function isCatchable(paramName As String, catchType As System.TypeInfo) As Boolean
74/* If Not String.IsNullOrEmpty(paramName) Then
75 Dim paramType = _System_TypeBase_Search(paramName)
76 isCatchable = ActiveBasic.Detail.IsBaseOf(catchType, paramType)
77 Else
78 isCatchable = False
79 End If
80/*/
81 isCatchable = False
82 While Not ActiveBasic.IsNothing(catchType)
83 Dim catchTypeName = catchType.FullName
84 If paramName = catchTypeName Then
85 isCatchable = True
86 Exit Function
87 End If
88 catchType = catchType.BaseType
89 Wend
90'*/
91 End Function
92End Class
93
94Class ExceptionService
95 ppTryLayers As **TryLayer
96 nTryLayers As Long
97
98 Sub FreeLocalObjects()
99 'TODO: 破棄されていないローカルオブジェクトを破棄
100 End Sub
101Public
102
103 Sub ExceptionService()
104 ppTryLayers = _System_malloc( 1 )
105 nTryLayers = 0
106 End Sub
107 Sub ~ExceptionService()
108 Dim i As Long
109 For i = 0 To ELM( nTryLayers )
110 Delete ppTryLayers[i]
111 Next
112 _System_free( ppTryLayers )
113 ppTryLayers = 0
114 End Sub
115
116 'Try
117 Function _BeginTryScope( catchTable As *LONG_PTR, addressOfFinally As VoidPtr, basePtr As LONG_PTR, stackPtr As LONG_PTR ) As TryLayer
118 ppTryLayers = _System_realloc( ppTryLayers, ( nTryLayers + 1 ) * SizeOf( *TryLayer ) )
119 ppTryLayers[nTryLayers] = New TryLayer( catchTable, addressOfFinally, basePtr, stackPtr )
120 nTryLayers++
121
122 Return ByVal ppTryLayers[nTryLayers-1]
123 End Function
124
125 Static Function BeginTryScope( catchTable As *LONG_PTR, addressOfFinally As VoidPtr, basePtr As LONG_PTR, stackPtr As LONG_PTR ) As TryLayer
126 Return _System_pobj_AllThreads->GetCurrentException()._BeginTryScope( catchTable, addressOfFinally, basePtr, stackPtr )
127 End Function
128
129 'End Try
130 Sub EndTryScope()
131 nTryLayers--
132 Delete ppTryLayers[nTryLayers]
133 End Sub
134
135 'Throw
136 Sub _Throw( ex As Object )
137 If nTryLayers <= 0 then
138 '例外処理スコープ制御が無効なとき
139
140 'TODO: 適切なエラー処理
141 MessageBox( NULL, ToTCStr(Ex"Catchされていない例外があります\r\n" + ex.ToString), NULL, MB_OK or MB_ICONEXCLAMATION )
142 Debug
143 Return
144 End If
145
146 ' スレッドへThrow処理を開始したことを通知
147 Imports System.Threading
148 Thread.CurrentThread().__Throw( ex )
149
150 '未解放なローカルオブジェクトを解放する
151 FreeLocalObjects()
152
153 Dim pTryLayer = ppTryLayers[nTryLayers - 1] As *TryLayer
154
155 Dim addressOfCatch = pTryLayer->ResolveCatchesOverload( ex ) As LONG_PTR
156 If addressOfCatch = NULL Then
157 ' Catchが定義されていないときはFinallyへ誘導
158 addressOfCatch = pTryLayer->addressOfFinally As LONG_PTR
159 End If
160
161
162 '--------------------------------------------------
163 ' スレッドのコンテキストを設定(Catchへ遷移する)
164 '--------------------------------------------------
165
166 Dim context As CONTEXT
167 context.ContextFlags = CONTEXT_CONTROL or CONTEXT_INTEGER
168 If GetThreadContext( GetCurrentThread(), context ) = 0 Then
169 ' TODO: エラー処理
170 debug
171 End If
172
173 '新しいip, sp, bpをセット
174#ifdef _WIN64
175 context.Rip = addressOfCatch As QWord
176 context.Rbp = pTryLayer->basePtr
177 context.Rsp = pTryLayer->stackPtr
178#else
179 context.Eip = addressOfCatch As DWord
180 context.Ebp = pTryLayer->basePtr
181 context.Esp = pTryLayer->stackPtr
182#endif
183
184#ifdef _DEBUG
185 Dim ThreadNum As Long
186 ThreadNum=_DebugSys_GetThread()
187 If ThreadNum <> -1 Then
188 _DebugSys_ProcNum[ThreadNum] = pTryLayer->debugProcNum-1
189 End If
190#endif
191
192 If SetThreadContext( GetCurrentThread(), context ) = 0 Then
193 OutputDebugString(Ex"レジスタ情報の設定に失敗しました。\r\n")
194 Return
195 End If
196 End Sub
197
198 Sub _ThrowWithParam( ex As Object )
199 _Throw( ex )
200 End Sub
201
202 Sub _ThrowNoneParam()
203 _Throw( Nothing )
204 End Sub
205
206 Sub FinishFinally()
207 Dim pTryLayer = ppTryLayers[nTryLayers - 1] As *TryLayer
208 pTryLayer->FinishFinally()
209 End Sub
210End Class
211
Note: See TracBrowser for help on using the repository browser.