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
RevLine 
[58]1'TODO: ローカルオブジェクト確保及び解放時にTryServiceに通知する必要がある。
2
3Class TryLayer
4Public
[374]5 Const catchTable As *LONG_PTR
6 Const addressOfFinally As VoidPtr
[372]7 Const basePtr As LONG_PTR
8 Const stackPtr As LONG_PTR
[374]9
[249]10 Const debugProcNum As DWord
[58]11
[374]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
[372]15 This.basePtr = basePtr
16 This.stackPtr = stackPtr
[249]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
[58]25 End Sub
26 Sub ~TryLayer()
27 End Sub
[374]28
29 Sub FinishFinally()
[411]30 Imports System.Threading
[374]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
[411]37 OutputDebugString("ResolveCatchesOverload: ")
38 OutputDebugString(ToTCStr(ex.ToString))
39 OutputDebugString(Ex"\r\n")
[374]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
[388]63 If isCatchable(New String(paramName), ex.GetType()) Then
64' If lstrcmp( paramName, ex.GetType().FullName ) = 0 Then
[374]65 ' マッチしたとき
66 Return codePos
67 End If
68 End If
69 Wend
70 Return defaultCatchCodePos
71 End Function
[411]72Private
[388]73 Function isCatchable(paramName As String, catchType As System.TypeInfo) As Boolean
[411]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/*/
[388]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
[411]90'*/
[388]91 End Function
[58]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
[374]117 Function _BeginTryScope( catchTable As *LONG_PTR, addressOfFinally As VoidPtr, basePtr As LONG_PTR, stackPtr As LONG_PTR ) As TryLayer
[58]118 ppTryLayers = _System_realloc( ppTryLayers, ( nTryLayers + 1 ) * SizeOf( *TryLayer ) )
[374]119 ppTryLayers[nTryLayers] = New TryLayer( catchTable, addressOfFinally, basePtr, stackPtr )
[58]120 nTryLayers++
121
[249]122 Return ByVal ppTryLayers[nTryLayers-1]
123 End Function
124
[374]125 Static Function BeginTryScope( catchTable As *LONG_PTR, addressOfFinally As VoidPtr, basePtr As LONG_PTR, stackPtr As LONG_PTR ) As TryLayer
[411]126 Return _System_pobj_AllThreads->GetCurrentException()._BeginTryScope( catchTable, addressOfFinally, basePtr, stackPtr )
[373]127 End Function
128
[58]129 'End Try
130 Sub EndTryScope()
131 nTryLayers--
132 Delete ppTryLayers[nTryLayers]
133 End Sub
134
135 'Throw
[374]136 Sub _Throw( ex As Object )
[58]137 If nTryLayers <= 0 then
138 '例外処理スコープ制御が無効なとき
139
140 'TODO: 適切なエラー処理
[411]141 MessageBox( NULL, ToTCStr(Ex"Catchされていない例外があります\r\n" + ex.ToString), NULL, MB_OK or MB_ICONEXCLAMATION )
[388]142 Debug
[58]143 Return
144 End If
145
[374]146 ' スレッドへThrow処理を開始したことを通知
[411]147 Imports System.Threading
[374]148 Thread.CurrentThread().__Throw( ex )
149
[58]150 '未解放なローカルオブジェクトを解放する
151 FreeLocalObjects()
152
[374]153 Dim pTryLayer = ppTryLayers[nTryLayers - 1] As *TryLayer
[58]154
[374]155 Dim addressOfCatch = pTryLayer->ResolveCatchesOverload( ex ) As LONG_PTR
[375]156 If addressOfCatch = NULL Then
[374]157 ' Catchが定義されていないときはFinallyへ誘導
158 addressOfCatch = pTryLayer->addressOfFinally As LONG_PTR
159 End If
[58]160
[374]161
[58]162 '--------------------------------------------------
163 ' スレッドのコンテキストを設定(Catchへ遷移する)
164 '--------------------------------------------------
165
[373]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
[372]172
[373]173 '新しいip, sp, bpをセット
[58]174#ifdef _WIN64
[374]175 context.Rip = addressOfCatch As QWord
176 context.Rbp = pTryLayer->basePtr
177 context.Rsp = pTryLayer->stackPtr
[58]178#else
[374]179 context.Eip = addressOfCatch As DWord
180 context.Ebp = pTryLayer->basePtr
181 context.Esp = pTryLayer->stackPtr
[58]182#endif
[249]183
184#ifdef _DEBUG
185 Dim ThreadNum As Long
186 ThreadNum=_DebugSys_GetThread()
187 If ThreadNum <> -1 Then
[374]188 _DebugSys_ProcNum[ThreadNum] = pTryLayer->debugProcNum-1
[249]189 End If
190#endif
[373]191
192 If SetThreadContext( GetCurrentThread(), context ) = 0 Then
[58]193 OutputDebugString(Ex"レジスタ情報の設定に失敗しました。\r\n")
194 Return
195 End If
196 End Sub
197
[374]198 Sub _ThrowWithParam( ex As Object )
199 _Throw( ex )
[58]200 End Sub
[374]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
[58]210End Class
211
Note: See TracBrowser for help on using the repository browser.