source: dev/trunk/abdev/BasicCompiler_Common/src/Exception.cpp@ 359

Last change on this file since 359 was 359, checked in by dai_9181, 16 years ago

例外処理機構実装中…

File size: 6.3 KB
Line 
1#include "stdafx.h"
2
3#ifdef _AMD64_
4#include "../../BasicCompiler64/opcode.h"
5#else
6#include "../../BasicCompiler32/opcode.h"
7#endif
8
9#include <Exception.h>
10
11namespace Exception{
12
13class TryScope
14{
15 bool isCatched;
16 bool isDefinedFinally;
17
18 std::vector<const PertialSchedule *> finallySchedules;
19 void JmpFinally()
20 {
21 finallySchedules.push_back(
22 compiler.codeGenerator.op_jmp( 0, sizeof(long), true )
23 );
24 }
25 void ResolveJmpFinally()
26 {
27 BOOST_FOREACH( const PertialSchedule *pPertialSchedule, finallySchedules )
28 {
29 compiler.codeGenerator.opfix_JmpPertialSchedule( pPertialSchedule );
30 }
31 }
32
33 const PertialSchedule *pPertialScheduleForFinallyAddress;
34
35public:
36 const PertialSchedule *pPertialScheduleForCatchAddress;
37 TryScope()
38 : isCatched( false )
39 , isDefinedFinally( false )
40 {
41 }
42 ~TryScope()
43 {
44 }
45
46 bool IsCatched() const
47 {
48 return isCatched;
49 }
50 bool IsDefinedFinally() const
51 {
52 return isDefinedFinally;
53 }
54
55 void RegistPertialScheduleForCatchAddress( const PertialSchedule *pPertialScheduleForCatchAddress )
56 {
57 this->pPertialScheduleForCatchAddress = pPertialScheduleForCatchAddress;
58 }
59 void RegistPertialScheduleForFinallyAddress( const PertialSchedule *pPertialScheduleForFinallyAddress )
60 {
61 this->pPertialScheduleForFinallyAddress = pPertialScheduleForFinallyAddress;
62 }
63 const PertialSchedule *GetPertialScheduleForFinallyAddress() const
64 {
65 return pPertialScheduleForFinallyAddress;
66 }
67
68
69
70 void Try()
71 {
72 }
73
74 void Catch()
75 {
76 if( isDefinedFinally )
77 {
78 SetError(71,NULL,cp);
79 return;
80 }
81
82 isCatched = true;
83
84 JmpFinally();
85 }
86 void Finally()
87 {
88 if( isDefinedFinally )
89 {
90 SetError(70,NULL,cp);
91 return;
92 }
93
94 isDefinedFinally = true;
95
96 ResolveJmpFinally();
97 }
98
99 void EndTry()
100 {
101 if( !isDefinedFinally )
102 {
103 Finally();
104 }
105 }
106};
107typedef std::vector<TryScope> TryScopes;
108
109TryScopes tryScopes;
110
111void TryCommand()
112{
113 if( UserProc::IsGlobalAreaCompiling() )
114 {
115 SetError();
116 }
117
118 tryScopes.push_back( TryScope() );
119 tryScopes.back().Try();
120
121 int backCp = cp;
122
123 char temporary[1024];
124 lstrcpy( temporary, "ExceptionService.BeginTryScope( _System_GetNowScopeCatchAddresses() As VoidPtr, _System_GetNowScopeFinallyAddresses() As VoidPtr, _System_GetBp() As LONG_PTR, _System_GetSp() As LONG_PTR )" );
125 MakeMiddleCode( temporary );
126 ChangeOpcode( temporary );
127
128 cp = backCp;
129}
130void CatchCommand( const char *parameter )
131{
132 if( tryScopes.size() == 0 )
133 {
134 SetError(1,NULL,cp);
135 return;
136 }
137
138 Type paramType;
139 if( parameter[0] )
140 {
141 char varName[VN_SIZE], typeName[VN_SIZE];
142 SplitSyntacticForAs( parameter, varName, typeName );
143 if( !typeName[0] )
144 {
145 SetError(72,NULL,cp);
146 }
147 else
148 {
149 if( !compiler.StringToType( typeName, paramType ) )
150 {
151 SetError(73,NULL,cp);
152 }
153 }
154 }
155
156 // パラメータの扱いが未完成
157
158 tryScopes.back().Catch();
159
160 // _System_GetNowScopeCatchAddressesを解決
161 compiler.codeGenerator.opfix( tryScopes.back().pPertialScheduleForCatchAddress, compiler.codeGenerator.GetNativeCodeSize() );
162}
163void FinallyCommand()
164{
165 tryScopes.back().Finally();
166
167 int backCp = cp;
168
169 char temporary[1024];
170 lstrcpy( temporary, "_System_pobj_AllThreads->GetCurrentException()->FinishFinally()" );
171 MakeMiddleCode( temporary );
172 ChangeOpcode( temporary );
173
174 cp = backCp;
175
176 //Tryスコープに入るときに引き渡されるパラメータ値を解決
177 compiler.codeGenerator.opfix( tryScopes.back().GetPertialScheduleForFinallyAddress(), compiler.codeGenerator.GetNativeCodeSize() );
178}
179void EndTryCommand()
180{
181 if( tryScopes.size() == 0 )
182 {
183 SetError(1,NULL,cp);
184 return;
185 }
186
187 int backCp = cp;
188
189 if( !tryScopes.back().IsCatched() )
190 {
191 // _System_GetNowScopeCatchAddressesを解決
192 compiler.codeGenerator.opfix( tryScopes.back().pPertialScheduleForCatchAddress, 0 );
193 }
194
195 if( !tryScopes.back().IsDefinedFinally() )
196 {
197 // Finallyが定義されていないときは空のFinallyを定義しておく
198 FinallyCommand();
199 }
200
201 char temporary[1024];
202 lstrcpy( temporary, "_System_pobj_AllThreads->GetCurrentException()->EndTryScope()" );
203 MakeMiddleCode( temporary );
204 ChangeOpcode( temporary );
205
206 cp = backCp;
207
208 tryScopes.back().EndTry();
209 tryScopes.pop_back();
210}
211
212void ThrowCommand( const char *Parameter )
213{
214 int backCp = cp;
215
216 char temporary[1024];
217 lstrcpy( temporary, "_System_pobj_AllThreads->GetCurrentException()->_Throw()" );
218 MakeMiddleCode( temporary );
219 ChangeOpcode( temporary );
220
221 cp = backCp;
222}
223
224void Opcode_Func_System_GetNowScopeCatchAddress()
225{
226 if( tryScopes.size() == 0 )
227 {
228 SetError(1,NULL,cp);
229 return;
230 }
231
232#ifdef _WIN64
233 //mov rax,catchAddress
234 const PertialSchedule *pPertialSchedule = compiler.codeGenerator.op_mov_RV( sizeof(long), REG_RAX, 0, Schedule::CatchAddress, true );
235#else
236 //mov eax,catchAddress
237 const PertialSchedule *pPertialSchedule = compiler.codeGenerator.op_mov_RV( REG_EAX, 0, Schedule::CatchAddress, true );
238#endif
239
240 tryScopes.back().RegistPertialScheduleForCatchAddress( pPertialSchedule );
241
242 /*
243 int dataTableOffset = compiler.GetObjectModule().dataTable.Add( static_cast<LONG_PTR>(0) );
244
245#ifdef _WIN64
246 //mov rax,dataTableOffset
247 compiler.codeGenerator.op_mov_RV( sizeof(_int64), REG_RAX, dataTableOffset, Schedule::DataTable);
248#else
249 //mov eax,dataTableOffset
250 compiler.codeGenerator.op_mov_RV( REG_EAX, dataTableOffset, Schedule::DataTable);
251#endif
252 */
253}
254
255void Opcode_Func_System_GetNowScopeFinallyAddress()
256{
257 if( tryScopes.size() == 0 )
258 {
259 SetError(1,NULL,cp);
260 return;
261 }
262
263#ifdef _WIN64
264 //mov rax,finallyAddress
265 const PertialSchedule *pPertialSchedule = compiler.codeGenerator.op_mov_RV( sizeof(long), REG_RAX, 0, Schedule::CatchAddress, true );
266#else
267 //mov eax,finallyAddress
268 const PertialSchedule *pPertialSchedule = compiler.codeGenerator.op_mov_RV( REG_EAX, 0, Schedule::CatchAddress, true );
269#endif
270
271 tryScopes.back().RegistPertialScheduleForFinallyAddress( pPertialSchedule );
272
273 /*
274 int dataTableOffset = compiler.GetObjectModule().dataTable.Add( static_cast<LONG_PTR>(0) );
275
276#ifdef _WIN64
277 //mov rax,dataTableOffset
278 compiler.codeGenerator.op_mov_RV( sizeof(_int64), REG_RAX, dataTableOffset, Schedule::DataTable);
279#else
280 //mov eax,dataTableOffset
281 compiler.codeGenerator.op_mov_RV( REG_EAX, dataTableOffset, Schedule::DataTable);
282#endif
283 */
284}
285
286
287} // Exception
Note: See TracBrowser for help on using the repository browser.