source: dev/trunk/abdev/BasicCompiler64/Compile_ProcOp.cpp@ 202

Last change on this file since 202 was 202, checked in by dai_9181, 17 years ago
File size: 26.2 KB
Line 
1#include <jenga/include/smoothie/Smoothie.h>
2#include <jenga/include/smoothie/LexicalAnalysis.h>
3
4#include <Program.h>
5#include <Compiler.h>
6#include <LexicalScopingImpl.h>
7#include <ClassImpl.h>
8#include <VariableImpl.h>
9
10#include "../BasicCompiler_Common/common.h"
11#include "Opcode.h"
12
13void SystemProc( const UserProc &userProc ){
14 if( userProc.GetName() == "_System_GetEip" ){
15 //mov rax,qword ptr[rsp]
16 op_mov_RM(sizeof(_int64),REG_RAX,REG_RSP,0,MOD_BASE);
17
18 //ret
19 op_ret();
20 }
21 else if( userProc.GetName() == "_System_InitDllGlobalVariables" ){
22 ////////////////////////////////////////
23 // DLLのグローバル領域をコンパイル
24 ////////////////////////////////////////
25 extern BOOL bDll;
26 if(!bDll){
27 //ret
28 op_ret();
29
30 return;
31 }
32
33 UserProc *pBackUserProc;
34 pBackUserProc = &UserProc::CompilingUserProc();
35 UserProc::CompileStartForGlobalArea();
36
37 int BackCp;
38 BackCp=cp;
39 cp=-1;
40
41 //sub rsp,スタックフレームサイズ
42 int StackFrameSchedule;
43 op_sub_rsp(0xFFFFFFFF);
44 StackFrameSchedule=obp-sizeof(long);
45
46 extern BOOL bDebugCompile;
47 if(bDebugCompile){
48 //デバッグ用の変数を定義
49 DebugVariable();
50 }
51
52 //GC用の変数を定義
53 InitGCVariables();
54
55 //_System_StartupProgramの呼び出し
56 extern UserProc *pSub_System_StartupProgram;
57 op_call(pSub_System_StartupProgram);
58
59 //クラスに属する静的メンバを定義
60 compiler.GetMeta().GetClasses().InitStaticMember();
61
62 GetGlobalDataForDll();
63
64 //add rsp,スタックフレームサイズ
65 op_add_RV(REG_RSP,pobj_sf->GetFrameSize());
66
67 //スタックフレームスケジュール(subコマンドに渡す値)
68 *((long *)(OpBuffer+StackFrameSchedule))=pobj_sf->GetFrameSize();
69
70 UserProc::CompileStartForUserProc( pBackUserProc );
71 cp=BackCp;
72
73 //ret
74 op_ret();
75 }
76 else if( userProc.GetName() == "_System_InitStaticLocalVariables" ){
77 //静的ローカルオブジェクトのコンストラクタ呼び出し
78
79 //sub rsp,スタックフレームサイズ
80 int StackFrameSchedule;
81 op_sub_rsp(0xFFFFFFFF);
82 StackFrameSchedule=obp-sizeof(long);
83
84 BOOST_FOREACH( Variable *pVar, globalVars ){
85 if(memicmp(pVar->GetName().c_str(),"Static%",7)==0){
86 //コンストラクタ呼び出し
87 if( pVar->IsObject() ){
88
89 //エラー用
90 cp=pVar->source_code_address;
91
92 CallConstructor(
93 pVar->GetName().c_str(),
94 pVar->GetSubScriptsPtr(),
95 *pVar,
96 pVar->paramStrForConstructor.c_str());
97 }
98 }
99 }
100
101 //add rsp,スタックフレームサイズ
102 op_add_RV(REG_RSP,pobj_sf->GetFrameSize());
103
104 //スタックフレームスケジュール(subコマンドに渡す値)
105 *((long *)(OpBuffer+StackFrameSchedule))=pobj_sf->GetFrameSize();
106
107 //ret
108 op_ret();
109 }
110 else if( userProc.GetName() == "_System_Call_Destructor_of_GlobalObject" ){
111 //sub rsp,8(※RSPを16バイト境界にあわせるため)
112 op_sub_rsp(0x8);
113
114
115 UserProc *pBackUserProc;
116 pBackUserProc = &UserProc::CompilingUserProc();
117 UserProc::CompileStartForGlobalArea();
118
119 GetLexicalScopes().CallDestructorsOfScopeEnd();
120
121 UserProc::CompileStartForUserProc( pBackUserProc );
122
123
124 //add rsp,8
125 op_add_RV(REG_RSP,0x8);
126
127 //ret
128 op_ret();
129 }
130 else if( userProc.GetName() == "_System_GetSp" ){
131 //mov rax,rsp
132 op_mov_RR(REG_RAX,REG_RSP);
133
134 //add rax,PTR_SIZE
135 op_add_RV(REG_RAX,PTR_SIZE);
136
137 //ret
138 op_ret();
139 }
140 else if( userProc.GetName() == "_allrem" ){
141 //乗除演算用の特殊関数(64ビット整数対応)
142 BYTE Buffer_allrem[]={
143 0x53,0x57,0x33,0xFF,0x8B,0x44,0x24,0x10,0x0B,0xC0,0x7D,0x14,0x47,0x8B,0x54,0x24,0x0C,0xF7,0xD8,0xF7,0xDA,0x83,0xD8,0x00,0x89,0x44,0x24,0x10,0x89,0x54,0x24,0x0C,0x8B,0x44,0x24,0x18,0x0B,0xC0,0x7D,0x13,0x8B,0x54,0x24,0x14,0xF7,0xD8,0xF7,0xDA,0x83,0xD8,0x00,0x89,0x44,0x24,0x18,0x89,0x54,0x24,0x14,0x0B,0xC0,0x75,0x1B,0x8B,0x4C,0x24,0x14,0x8B,0x44,0x24,0x10,0x33,0xD2,0xF7,0xF1,0x8B,0x44,0x24,0x0C,0xF7,0xF1,0x8B,0xC2,0x33,0xD2,0x4F,0x79,0x4E,0xEB,0x53,0x8B,0xD8,0x8B,0x4C,0x24,0x14,0x8B,0x54,0x24,0x10,0x8B,0x44,0x24,0x0C,0xD1,0xEB,0xD1,0xD9,0xD1,0xEA,0xD1,0xD8,0x0B,0xDB,0x75,0xF4,0xF7,0xF1,0x8B,0xC8,0xF7,0x64,0x24,0x18,0x91,0xF7,0x64,0x24,0x14,0x03,0xD1,0x72,0x0E,0x3B,0x54,0x24,0x10,0x77,0x08,0x72,0x0E,0x3B,0x44,0x24,0x0C,0x76,0x08,0x2B,0x44,0x24,0x14,0x1B,0x54,0x24,0x18,0x2B,0x44,0x24,0x0C,0x1B,0x54,0x24,0x10,0x4F,0x79,0x07,0xF7,0xDA,0xF7,0xD8,0x83,0xDA,0x00,0x5F,0x5B,0xC2,0x10,0x00
144 };
145
146 memcpy(OpBuffer+obp,Buffer_allrem,178);
147 obp+=178;
148 }
149 else if( userProc.GetName() == "_allmul" ){
150 //乗算用の特殊関数(64ビット整数対応)
151 BYTE Buffer_allmul[]={
152 0x8B,0x44,0x24,0x08,0x8B,0x4C,0x24,0x10,0x0B,0xC8,0x8B,0x4C,0x24,0x0C,0x75,0x09,0x8B,0x44,0x24,0x04,0xF7,0xE1,0xC2,0x10,0x00,0x53,0xF7,0xE1,0x8B,0xD8,0x8B,0x44,0x24,0x08,0xF7,0x64,0x24,0x14,0x03,0xD8,0x8B,0x44,0x24,0x08,0xF7,0xE1,0x03,0xD3,0x5B,0xC2,0x10,0x00
153 };
154
155 memcpy(OpBuffer+obp,Buffer_allmul,52);
156 obp+=52;
157 }
158 else if( userProc.GetName() == "_alldiv" ){
159 //除算用の特殊関数(64ビット整数対応)
160 BYTE Buffer_alldiv[]={
161 0x57,0x56,0x53,0x33,0xFF,0x8B,0x44,0x24,0x14,0x0B,0xC0,0x7D,0x14,0x47,0x8B,0x54,0x24,0x10,0xF7,0xD8,0xF7,0xDA,0x83,0xD8,0x00,0x89,0x44,0x24,0x14,0x89,0x54,0x24,0x10,0x8B,0x44,0x24,0x1C,0x0B,0xC0,0x7D,0x14,0x47,0x8B,0x54,0x24,0x18,0xF7,0xD8,0xF7,0xDA,0x83,0xD8,0x00,0x89,0x44,0x24,0x1C,0x89,0x54,0x24,0x18,0x0B,0xC0,0x75,0x18,0x8B,0x4C,0x24,0x18,0x8B,0x44,0x24,0x14,0x33,0xD2,0xF7,0xF1,0x8B,0xD8,0x8B,0x44,0x24,0x10,0xF7,0xF1,0x8B,0xD3,0xEB,0x41,0x8B,0xD8,0x8B,0x4C,0x24,0x18,0x8B,0x54,0x24,0x14,0x8B,0x44,0x24,0x10,0xD1,0xEB,0xD1,0xD9,0xD1,0xEA,0xD1,0xD8,0x0B,0xDB,0x75,0xF4,0xF7,0xF1,0x8B,0xF0,0xF7,0x64,0x24,0x1C,0x8B,0xC8,0x8B,0x44,0x24,0x18,0xF7,0xE6,0x03,0xD1,0x72,0x0E,0x3B,0x54,0x24,0x14,0x77,0x08,0x72,0x07,0x3B,0x44,0x24,0x10,0x76,0x01,0x4E,0x33,0xD2,0x8B,0xC6,0x4F,0x75,0x07,0xF7,0xDA,0xF7,0xD8,0x83,0xDA,0x00,0x5B,0x5E,0x5F,0xC2,0x10,0x00
162 };
163
164 memcpy(OpBuffer+obp,Buffer_alldiv,170);
165 obp+=170;
166 }
167 else if( userProc.GetName() == "_allshl" ){
168 //符号あり左ビットシフト用の特殊関数(64ビット整数対応)
169 BYTE Buffer_allshl[]={
170 0x80,0xF9,0x40,0x73,0x15,0x80,0xF9,0x20,0x73,0x06,0x0F,0xA5,0xC2,0xD3,0xE0,0xC3,0x8B,0xD0,0x33,0xC0,0x80,0xE1,0x1F,0xD3,0xE2,0xC3,0x33,0xC0,0x33,0xD2,0xC3
171 };
172
173 memcpy(OpBuffer+obp,Buffer_allshl,31);
174 obp+=31;
175 }
176 else if( userProc.GetName() == "_allshr" ){
177 //符号あり右ビットシフト用の特殊関数(64ビット整数対応)
178 BYTE Buffer_allshr[]={
179 0x80,0xF9,0x40,0x73,0x16,0x80,0xF9,0x20,0x73,0x06,0x0F,0xAD,0xD0,0xD3,0xFA,0xC3,0x8B,0xC2,0xC1,0xFA,0x1F,0x80,0xE1,0x1F,0xD3,0xF8,0xC3,0xC1,0xFA,0x1F,0x8B,0xC2,0xC3
180 };
181
182 memcpy(OpBuffer+obp,Buffer_allshr,33);
183 obp+=33;
184 }
185 else if( userProc.GetName() == "_aullshr" ){
186 //符号なし右ビットシフト用の特殊関数(64ビット整数対応)
187 BYTE Buffer_aullshr[]={
188 0x80,0xF9,0x40, //cmp cl,40h
189 0x73,0x15, //jae RETZERO (0040d71a)
190 0x80,0xF9,0x20, //cmp cl,20h
191 0x73,0x06, //jae MORE32 (0040d710)
192 0x0F,0xAD,0xD0, //shrd eax,edx,cl
193 0xD3,0xEA, //shr edx,cl
194 0xC3, //ret
195 //MORE32:
196 0x8B,0xC2, //mov eax,edx
197 0x33,0xD2, //xor edx,edx
198 0x80,0xE1,0x1F, //and cl,1Fh
199 0xD3,0xE8, //shr eax,cl
200 0xC3, //ret
201 //RETZERO:
202 0x33,0xC0, //xor eax,eax
203 0x33,0xD2, //xor edx,edx
204 0xC3 //ret
205 };
206
207 memcpy(OpBuffer+obp,Buffer_aullshr,31);
208 obp+=31;
209 }
210 else{
211 SetError();
212 }
213}
214void AutoGeneration(UserProc &userProc){
215 if( userProc.GetName() == "InitializeUserTypes"
216 && userProc.HasParentClass()
217 && userProc.GetParentClass().GetName() == "_System_TypeBase" ){
218
219 compiler.GetMeta().GetClasses().Compile_System_InitializeUserTypes();
220 }
221 else if( userProc.GetName() == "RegisterGlobalRoots"
222 && userProc.HasParentClass()
223 && userProc.GetParentClass().GetName() == "_System_CGarbageCollection" ){
224
225 Compile_AddGlobalRootsForGc();
226 }
227 else{
228 SetError();
229 }
230}
231void _compile_proc(UserProc *pUserProc){
232 extern char *basbuf;
233 extern HANDLE hHeap;
234 extern GlobalProc **ppSubHash;
235 extern BOOL bDebugCompile;
236 int i3,i4;
237 char temporary[VN_SIZE];
238
239 if( pUserProc->IsUsing() == false || pUserProc->IsCompiled() ) return;
240
241 if( pUserProc->localVars.size() ){
242 SetError();
243 return;
244 }
245
246 pUserProc->CompleteCompile();
247
248 extern BOOL bSystemProc;
249 if(memcmp(pUserProc->GetName().c_str(),"_System_",8)==0) bSystemProc=1;
250 else bSystemProc=0;
251
252 extern BOOL bDebugSupportProc;
253 if(memcmp(pUserProc->GetName().c_str(),"_DebugSys_",10)==0){
254 if(!bDebugCompile){
255 return;
256 }
257 bDebugSupportProc=1;
258 }
259 else bDebugSupportProc=0;
260
261 pUserProc->beginOpAddress=obp;
262
263 //コンパイル中の関数が属するクラス
264 Smoothie::Temp::pCompilingClass=pUserProc->GetParentClassPtr();
265
266 //コンパイルスタートをクラス管理クラスに追加
267 compiler.GetMeta().GetClasses().StartCompile( pUserProc );
268
269 //コンパイル中の関数
270 UserProc::CompileStartForUserProc( pUserProc );
271
272 // コンパイル中の関数が属する名前空間
273 compiler.GetNamespaceSupporter().SetLivingNamespaceScopes( pUserProc->GetNamespaceScopes() );
274
275 // コンパイル中の関数でImportsされている名前空間
276 compiler.GetNamespaceSupporter().SetImportedNamespaces( pUserProc->GetImportedNamespaces() );
277
278 if(pUserProc->IsSystem()){
279 ////////////////////
280 // 特殊関数
281 ////////////////////
282
283 extern int AllLocalVarSize;
284 AllLocalVarSize=0;
285
286 //スタックフレーム管理用オブジェクトを初期化
287 extern CStackFrame *pobj_sf;
288 pobj_sf=new CStackFrame();
289
290 SystemProc(*pUserProc);
291
292 //スタックフレーム管理用オブジェクトを破棄
293 delete pobj_sf;
294 pobj_sf=0;
295
296 pUserProc->endOpAddress=obp;
297 return;
298 }
299
300 cp=pUserProc->GetCodePos();
301 for(;;cp++){
302 if(IsCommandDelimitation(basbuf[cp])) break;
303 }
304 cp--;
305
306 //プロシージャ抜け出しスケジュール(Exit Sub/Function)
307 extern DWORD *pExitSubSchedule;
308 extern int ExitSubScheduleNum;
309 pExitSubSchedule=(DWORD *)HeapAlloc(hHeap,0,1);
310 ExitSubScheduleNum=0;
311
312 //ラベル用のメモリを確保
313 extern LABEL *pLabelNames;
314 extern int MaxLabelNum;
315 pLabelNames=(LABEL *)HeapAlloc(hHeap,0,1);
316 MaxLabelNum=0;
317
318 //Gotoラベルスケジュール
319 extern GOTOLABELSCHEDULE *pGotoLabelSchedule;
320 extern int GotoLabelScheduleNum;
321 pGotoLabelSchedule=(GOTOLABELSCHEDULE *)HeapAlloc(hHeap,0,1);
322 GotoLabelScheduleNum=0;
323
324 //With情報のメモリを確保
325 extern WITHINFO WithInfo;
326 WithInfo.ppName=(char **)HeapAlloc(hHeap,0,1);
327 WithInfo.pWithCp=(int *)HeapAlloc(hHeap,0,1);
328 WithInfo.num=0;
329
330 //重複エラー情報管理のメモリを確保
331 extern char **SynonymErrorWords;
332 extern int SynonymErrorNum;
333 SynonymErrorNum=0;
334 SynonymErrorWords=(char **)HeapAlloc(hHeap,0,1);
335
336 //Continueアドレスを初期化
337 extern DWORD dwContinueAddress;
338 dwContinueAddress=-1;
339
340 //ローカル変数に関する情報
341 extern int AllLocalVarSize;
342 AllLocalVarSize=0;
343
344 //ローカル変数アドレススケジュール
345 extern DWORD *pLocalVarAddrSchedule;
346 extern int LocalVarAddrScheduleNum;
347 pLocalVarAddrSchedule=(DWORD *)HeapAlloc(hHeap,0,1);
348 LocalVarAddrScheduleNum=0;
349
350 //レキシカルスコープ情報を初期化
351 GetLexicalScopes().Init(obp);
352
353
354 /////////////////////////////////////
355 // パラメータ用の変数データを考慮
356 /////////////////////////////////////
357
358 //パラメータ用の変数データを考慮
359 for(i3=(int)pUserProc->RealParams().size()-1;i3>=0;i3--){
360 Parameter &param = *pUserProc->RealParams()[i3];
361
362 Variable *pVar = new VariableImpl( param.GetVarName(), param, false, param.IsRef() );
363
364 if( param.IsArray() ){
365 pVar->SetArray( param.GetSubScriptsPtr() );
366 }
367
368 int varSize;
369 if( param.IsRef() == false && param.IsStruct() ){
370 //構造体のByValパラメータ
371 pVar->ThisIsParameter();
372 varSize=PTR_SIZE;
373 }
374 else{
375 if( param.IsArray() == false ){
376 varSize = pVar->GetMemorySize();
377 }
378 else{
379 varSize=PTR_SIZE;
380 }
381 }
382 AllLocalVarSize+=varSize;
383 pVar->offset=AllLocalVarSize;
384
385 //レキシカルスコープ情報
386 pVar->ScopeLevel=GetLexicalScopes().GetNowLevel();
387 pVar->ScopeStartAddress=GetLexicalScopes().GetStartAddress();
388 pVar->bLiving=TRUE;
389
390 pUserProc->localVars.push_back( pVar );
391 }
392
393 //Thisポインタを示すローカルオフセット値をセット
394 extern int LocalVar_ThisPtrOffset;
395 LocalVar_ThisPtrOffset=AllLocalVarSize;
396
397 //スタックフレーム管理用クラスを初期化
398 extern CStackFrame *pobj_sf;
399 pobj_sf=new CStackFrame();
400
401
402 ///////////////////////
403 // ここからコード生成
404
405 for(i3=(int)pUserProc->RealParams().size()-1;i3>=0;i3--){
406 Parameter &param = *pUserProc->RealParams()[i3];
407 if(i3==3){
408 if(param.IsReal()&&param.IsRef() == false){
409 //movsd qword ptr[rsp+0x20],xmm3
410 op_movsd_MR(REG_XMM3,REG_RSP,0x20,MOD_BASE_DISP32);
411 }
412 else{
413 //mov qword ptr[rsp+0x20],r9
414 op_mov_MR(sizeof(_int64),REG_R9,REG_RSP,0x20,MOD_BASE_DISP32);
415 }
416 }
417 if(i3==2){
418 if(param.IsReal()&&param.IsRef() == false){
419 //movsd qword ptr[rsp+0x18],xmm2
420 op_movsd_MR(REG_XMM2,REG_RSP,0x18,MOD_BASE_DISP32);
421 }
422 else{
423 //mov qword ptr[rsp+0x18],r8
424 op_mov_MR(sizeof(_int64),REG_R8,REG_RSP,0x18,MOD_BASE_DISP32);
425 }
426 }
427 if(i3==1){
428 if(param.IsReal()&&param.IsRef() == false){
429 //movsd qword ptr[rsp+0x10],xmm1
430 op_movsd_MR(REG_XMM1,REG_RSP,0x10,MOD_BASE_DISP32);
431 }
432 else{
433 //mov qword ptr[rsp+0x10],rdx
434 op_mov_MR(sizeof(_int64),REG_RDX,REG_RSP,0x10,MOD_BASE_DISP32);
435 }
436 }
437 if(i3==0){
438 if(param.IsReal()&&param.IsRef() == false){
439 //movsd qword ptr[rsp+0x8],xmm0
440 op_movsd_MR(REG_XMM0,REG_RSP,0x8,MOD_BASE_DISP32);
441 }
442 else{
443 //mov qword ptr[rsp+0x8],rcx
444 op_mov_MR(sizeof(_int64),REG_RCX,REG_RSP,0x8,MOD_BASE_DISP32);
445 }
446 }
447 }
448
449 //ret用のアドレスを考慮
450 AllLocalVarSize+=sizeof(_int64);
451
452 //sub rsp,スタックフレームサイズ
453 int StackFrameSchedule;
454 op_sub_rsp(0xFFFFFFFF);
455 StackFrameSchedule=obp-sizeof(long);
456
457 //mov qword ptr[rsp+offset],reg ※スタックフレームを利用
458 pobj_sf->push(REG_RBX);
459 pobj_sf->push(REG_RSI);
460 pobj_sf->push(REG_RDI);
461 pobj_sf->push(REG_R12);
462 pobj_sf->push(REG_R13);
463 pobj_sf->push(REG_R14);
464 pobj_sf->push(REG_R15);
465
466 //ローカル変数のベース値
467 int BaseLocalVar;
468 BaseLocalVar=AllLocalVarSize;
469
470 if( !pUserProc->ReturnType().IsNull() ){
471 //戻り値が存在するとき
472
473 const char *temp = pUserProc->GetName().c_str();
474 if( temp[0]==1&&temp[1]==ESC_OPERATOR ){
475 temp = "_System_ReturnValue";
476 }
477
478 if( pUserProc->ReturnType().IsStruct() ){
479 //戻り値用の構造体(値型)はパラメータで引き渡される
480 }
481 else{
482 if( pUserProc->ReturnType().IsObject() ){
483 sprintf(temporary,"%s=Nothing%c%c%s",temp,1,ESC_AS, Compiler::TypeToString( pUserProc->ReturnType() ).c_str() );
484 }
485 else{
486 //戻り値用の変数の定義
487 sprintf(temporary,"%s%c%c%s",temp,1,ESC_AS, Compiler::TypeToString( pUserProc->ReturnType() ).c_str() );
488 }
489
490 OpcodeDim(temporary,0);
491 }
492 }
493
494 int RspOffsetSchedule=0;
495 int RspOffsetSchedule2;
496 if(bDebugCompile&&bDebugSupportProc==0){
497 //mov rdx, qword ptr[rsp+スタックフレームサイズ]
498 op_mov_RM(sizeof(_int64),REG_RDX,REG_RSP,0,MOD_BASE_DISP32);
499 RspOffsetSchedule=obp-sizeof(long);
500
501 //mov rcx,rsp
502 op_mov_RR(REG_RCX,REG_RSP);
503
504 //add rcx,スタックフレームサイズ+sizeof(_int64) ※ret用のサイズを考慮
505 op_add_RV(REG_RCX,0);
506 RspOffsetSchedule2=obp-sizeof(long);
507
508 //call _DebugSys_StartProc
509 extern UserProc *pSub_DebugSys_StartProc;
510 op_call(pSub_DebugSys_StartProc);
511 }
512
513 if(Smoothie::Temp::pCompilingClass){
514 if( pUserProc->GetName() == Smoothie::Temp::pCompilingClass->GetName() ){
515 ////////////////////////////////////
516 // コンストラクタをコンパイルするとき
517 ////////////////////////////////////
518
519 //コンストラクタのコンパイル開始を通知
520 Smoothie::Temp::pCompilingClass->NotifyStartConstructorCompile();
521
522 //基底クラスかどうかの識別
523 //(継承元がインターフェイスの場合も基底クラスと見なす)
524 BOOL bThisIsSuperClass;
525 if(Smoothie::Temp::pCompilingClass->pobj_InheritsClass==0) bThisIsSuperClass=1;
526 else if( Smoothie::Temp::pCompilingClass->pobj_InheritsClass->GetConstructorMethod() == NULL ){
527 //インターフェイスを継承したときはコンストラクタを持たない
528 bThisIsSuperClass=1;
529 }
530 else bThisIsSuperClass=0;
531
532 if(!bThisIsSuperClass){
533 /* サブクラスコンストラクタをコンパイルしているときは、
534 基底クラスのコンストラクタを呼び出す */
535
536 i3=cp+1;
537 while(IsCommandDelimitation(basbuf[i3])) i3++;
538 for(i4=0;;i3++,i4++){
539 if(!IsVariableChar(basbuf[i3])){
540 temporary[i4]=0;
541 break;
542 }
543 temporary[i4]=basbuf[i3];
544 }
545 if( Smoothie::Temp::pCompilingClass->pobj_InheritsClass->GetName() == temporary ){
546 //基底クラスのコンストラクタを呼び出す
547 cp=i3;
548 for(i4=0;;cp++,i4++){
549 if(IsCommandDelimitation(basbuf[cp])){
550 temporary[i4]=0;
551 break;
552 }
553 temporary[i4]=basbuf[cp];
554 }
555 if(!(temporary[0]=='('&&temporary[lstrlen(temporary)-1]==')')){
556 SetError(1,NULL,cp);
557 }
558 RemoveStringPare(temporary);
559
560 Type dummyType;
561 CallProc( PROC_DEFAULT
562 , Smoothie::Temp::pCompilingClass->pobj_InheritsClass->GetConstructorMethod()->pUserProc
563 , Smoothie::Temp::pCompilingClass->pobj_InheritsClass->GetConstructorMethod()->pUserProc->GetName().c_str()
564 , temporary
565 , dummyType );
566 }
567 else{
568 //基底クラスのコンストラクタを暗黙的に呼び出す
569 Opcode_CallProc("",
570 Smoothie::Temp::pCompilingClass->pobj_InheritsClass->GetConstructorMethod()->pUserProc,
571 0,
572 "",
573 0);
574 }
575 }
576
577 //仮想関数テーブルを初期化
578 if( Smoothie::Temp::pCompilingClass->IsExistVirtualFunctions()
579 && !Smoothie::Temp::pCompilingClass->IsAbstract() ){
580 //関数テーブルに値をセット
581 int offset = (int)Smoothie::Temp::pCompilingClass->GetVtblGlobalOffset();
582
583 //mov rax,offset
584 op_mov_RV(sizeof(_int64),REG_RAX,offset);
585 obp-=sizeof(long);
586 pobj_DataTableSchedule->add();
587 obp+=sizeof(long);
588
589 //Thisポインタをrcxにコピー
590 SetThisPtrToReg(REG_RCX);
591
592 //mov qword ptr[rcx],rax
593 op_mov_MR(sizeof(_int64),REG_RAX,REG_RCX,0,MOD_BASE);
594 }
595 }
596 else if( pUserProc->IsDestructor() ){
597 //デストラクタをコンパイルしたとき
598
599 //デストラクタのコンパイル開始を通知
600 Smoothie::Temp::pCompilingClass->NotifyStartDestructorCompile();
601 }
602 }
603
604 //////////////////////////////////////////
605 //////////////////////////////////////////
606 ////// プロシージャ内をコンパイル ////////
607 if( pUserProc->IsAutoGeneration() ){
608 AutoGeneration( *pUserProc );
609 }
610 else{
611 if(pUserProc->IsMacro()){
612 CompileBuffer(ESC_ENDMACRO,0);
613 }
614 else{
615 if(pUserProc->IsSub()){
616 CompileBuffer(ESC_ENDSUB,0);
617 }
618 else if(pUserProc->IsFunction()){
619 CompileBuffer(ESC_ENDFUNCTION,0);
620 }
621 }
622 }
623 //////////////////////////////////////////
624 //////////////////////////////////////////
625
626 if( Smoothie::Temp::pCompilingClass ){
627
628 if( Smoothie::Temp::pCompilingClass->IsCompilingConstructor() ){
629 // コンストラクタをコンパイルしていたとき
630
631 // コンストラクタのコンパイルが完了したことを通知
632 Smoothie::Temp::pCompilingClass->NotifyFinishConstructorCompile();
633 }
634 else if( pUserProc->IsDestructor() ){
635 ////////////////////////////////////
636 //デストラクタをコンパイルしたとき
637 ////////////////////////////////////
638
639 // デストラクタのコンパイルが完了したことを通知
640 Smoothie::Temp::pCompilingClass->NotifyFinishDestructorCompile();
641
642 if(Smoothie::Temp::pCompilingClass->pobj_InheritsClass){
643 /* サブクラスのデストラクタをコンパイルしているときは、
644 基底クラスのデストラクタを呼び出す */
645
646 const CMethod *method = Smoothie::Temp::pCompilingClass->pobj_InheritsClass->GetDestructorMethod();
647 if( method ){
648 Opcode_CallProc("",
649 method->pUserProc,
650 0,
651 "",
652 0);
653 }
654 }
655 }
656 }
657
658 //ラベル用のメモリを解放
659 for(i3=0;i3<MaxLabelNum;i3++){
660 if(pLabelNames[i3].pName) HeapDefaultFree(pLabelNames[i3].pName);
661 }
662 HeapDefaultFree(pLabelNames);
663
664 //Goto未知ラベルスケジュールを解放
665 for(i3=0;i3<GotoLabelScheduleNum;i3++){
666 if(pGotoLabelSchedule[i3].pName){
667 SetError(6,pGotoLabelSchedule[i3].pName,pGotoLabelSchedule[i3].now_cp);
668 HeapDefaultFree(pGotoLabelSchedule[i3].pName);
669 }
670 else{
671 sprintf(temporary,"%d",pGotoLabelSchedule[i3].line);
672 SetError(6,temporary,pGotoLabelSchedule[i3].now_cp);
673 }
674 }
675 HeapDefaultFree(pGotoLabelSchedule);
676
677 //With情報のメモリを解放
678 for(i3=0;i3<WithInfo.num;i3++){
679 SetError(22,"With",WithInfo.pWithCp[i3]);
680 HeapDefaultFree(WithInfo.ppName[i3]);
681 }
682 HeapDefaultFree(WithInfo.ppName);
683 HeapDefaultFree(WithInfo.pWithCp);
684
685 //ローカルオブジェクト(レキシカルスコープレベル=0)の解放処理
686 GetLexicalScopes().CallDestructorsOfScopeEnd();
687
688 //プロシージャ抜け出しスケジュール(Exit Sub/Function)
689 for(i3=0;i3<ExitSubScheduleNum;i3++){
690 *((long *)(OpBuffer+pExitSubSchedule[i3]))=obp-(pExitSubSchedule[i3]+sizeof(long));
691 }
692 HeapDefaultFree(pExitSubSchedule);
693
694 if(bDebugCompile&&bDebugSupportProc==0){
695 //call _DebugSys_EndProc
696 extern UserProc *pSub_DebugSys_EndProc;
697 op_call(pSub_DebugSys_EndProc);
698 }
699
700 if( !pUserProc->ReturnType().IsNull() ){
701 //////////////////////////////////
702 // 戻り値をraxまたはxmm0に設定
703 //////////////////////////////////
704
705 RELATIVE_VAR RelativeVar;
706
707 const char *temp = pUserProc->GetName().c_str();
708 if( temp[0]==1 && temp[1]==ESC_OPERATOR ){
709 temp="_System_ReturnValue";
710 }
711 GetVarOffsetReadWrite(temp,&RelativeVar,Type());
712
713 i3=pUserProc->ReturnType().GetBasicType();
714
715 if(i3==DEF_OBJECT || i3==DEF_STRUCT){
716 SetVarPtrToReg(REG_RAX,&RelativeVar);
717 if( i3==DEF_OBJECT ){
718 //mov rax,qword ptr[rax]
719 op_mov_RM( sizeof(_int64), REG_RAX, REG_RAX, 0, MOD_BASE );
720 }
721 }
722 else if(i3==DEF_DOUBLE){
723 //64ビット実数型
724 SetXmmReg_DoubleVariable(&RelativeVar,REG_XMM0);
725 }
726 else if(i3==DEF_SINGLE){
727 //32ビット実数型
728 SetXmmReg_SingleVariable(&RelativeVar,REG_XMM0);
729 }
730 else if(IsWholeNumberType(i3)){
731 //整数型
732 SetReg_WholeVariable(i3,&RelativeVar,REG_RAX);
733 }
734 else SetError(300,NULL,cp);
735 }
736
737 //ローカル変数領域のサイズをスタックフレームに通知
738 int iLocalParmSize;
739 iLocalParmSize=AllLocalVarSize-BaseLocalVar;
740 pobj_sf->SetLocalParmSize(iLocalParmSize);
741
742 //ローカル変数アドレススケジュール
743 for(i3=0;i3<LocalVarAddrScheduleNum;i3++){
744 *((long *)(OpBuffer+pLocalVarAddrSchedule[i3]))+=AllLocalVarSize+pobj_sf->GetFrameSize();
745 }
746 HeapDefaultFree(pLocalVarAddrSchedule);
747 BOOST_FOREACH( Variable *pVar, pUserProc->localVars ){
748 //後にデバッグで利用する
749 pVar->offset = AllLocalVarSize + pobj_sf->GetFrameSize() - pVar->offset;
750 }
751
752 //mov reg,qword ptr[rsp+offset] ※スタックフレームを利用
753 pobj_sf->pop(REG_R15);
754 pobj_sf->pop(REG_R14);
755 pobj_sf->pop(REG_R13);
756 pobj_sf->pop(REG_R12);
757 pobj_sf->pop(REG_RDI);
758 pobj_sf->pop(REG_RSI);
759 pobj_sf->pop(REG_RBX);
760
761 int iStackFrameSize;
762 iStackFrameSize=iLocalParmSize + pobj_sf->GetFrameSize();
763
764 //add rsp,スタックフレームサイズ
765 op_add_rsp(iStackFrameSize);
766
767 //ret
768 op_ret();
769
770
771 //デバッグ用
772 if(RspOffsetSchedule){
773 *((long *)(OpBuffer+RspOffsetSchedule))=iStackFrameSize;
774 *((long *)(OpBuffer+RspOffsetSchedule2))=iStackFrameSize+sizeof(_int64);
775 }
776
777
778 //スタックフレームスケジュール(subコマンド)
779 *((long *)(OpBuffer+StackFrameSchedule))=iStackFrameSize;
780
781 //スタックフレームスケジュールを実行
782 pobj_sf->RunningSchedule();
783 delete pobj_sf;
784 pobj_sf=0;
785
786
787 pUserProc->endOpAddress=obp;
788
789
790 //重複エラー情報管理のメモリを解放
791 for(i3=0;i3<SynonymErrorNum;i3++) HeapDefaultFree(SynonymErrorWords[i3]);
792 HeapDefaultFree(SynonymErrorWords);
793}
794
795void CompileBufferInProcedure( UserProc &userProc ){
796 if( userProc.IsUsing() == false || userProc.IsCompiled() ) return;
797
798 _compile_proc( &userProc );
799
800 // ログを履く
801 char temporary[8192];
802 temporary[0]=0;
803 lstrcat( temporary, "------------------------------------------------------------------\n" );
804 sprintf( temporary + lstrlen(temporary), "【 %s のコード情報】\n", userProc.GetName().c_str() );
805 sprintf( temporary + lstrlen(temporary), "code size: %d bytes\n", userProc.GetCodeSize() );
806 lstrcat( temporary, "------------------------------------------------------------------\n" );
807 lstrcat( temporary, "\n" );
808 trace_for_size( temporary );
809}
810void CompileLocal(){
811 extern GlobalProc **ppSubHash;
812 int i2;
813
814 extern BOOL bDll;
815 if(bDll){
816 //DLLの場合はグローバル変数を初期化するための関数を一番初めにコンパイルする
817 UserProc *pUserProc=GetSubHash("_System_InitDllGlobalVariables");
818 if(pUserProc){
819 CompileBufferInProcedure( *pUserProc );
820 }
821 else SetError(300,NULL,cp);
822 }
823
824 //_System_TypeBase_InitializeUserTypesは一番最後にコンパイル
825 extern UserProc *pSubStaticMethod_System_TypeBase_InitializeUserTypes;
826 pSubStaticMethod_System_TypeBase_InitializeUserTypes->CompleteCompile();
827
828 //_System_InitStaticLocalVariablesは一番最後にコンパイル
829 //※一般関数内の静的変数オブジェクトをすべて収集しなければならない
830 extern UserProc *pSub_System_InitStaticLocalVariables;
831 pSub_System_InitStaticLocalVariables->CompleteCompile();
832
833 //_System_Call_Destructor_of_GlobalObjectは一番最後にコンパイル
834 extern UserProc *pSub_System_Call_Destructor_of_GlobalObject;
835 pSub_System_Call_Destructor_of_GlobalObject->CompleteCompile();
836
837repeat:
838 GlobalProc *pGlobalProc;
839 for(i2=0;i2<MAX_HASH;i2++){
840 pGlobalProc=ppSubHash[i2];
841 while(pGlobalProc){
842 CompileBufferInProcedure( *pGlobalProc );
843 pGlobalProc=pGlobalProc->pNextData;
844 }
845 }
846
847 if( IsNeedProcCompile() ){
848 //プロシージャコンパイルによって、プロシージャコンパイルが必要になる場合
849 goto repeat;
850 }
851
852 //_System_TypeBase_InitializeUserTypesは最後のほうでコンパイル
853 pSubStaticMethod_System_TypeBase_InitializeUserTypes->KillCompileStatus();
854 CompileBufferInProcedure( *pSubStaticMethod_System_TypeBase_InitializeUserTypes );
855
856 if( IsNeedProcCompile() ){
857 //プロシージャコンパイルによって、プロシージャコンパイルが必要になる場合
858 for(i2=0;i2<MAX_HASH;i2++){
859 pGlobalProc=ppSubHash[i2];
860 while(pGlobalProc){
861 CompileBufferInProcedure( *pGlobalProc );
862 pGlobalProc=pGlobalProc->pNextData;
863 }
864 }
865 }
866
867 //_System_InitStaticLocalVariablesは一番最後にコンパイル
868 pSub_System_InitStaticLocalVariables->KillCompileStatus();
869 CompileBufferInProcedure( *pSub_System_InitStaticLocalVariables );
870
871 //_System_Call_Destructor_of_GlobalObjectは一番最後にコンパイル
872 pSub_System_Call_Destructor_of_GlobalObject->KillCompileStatus();
873 CompileBufferInProcedure( *pSub_System_Call_Destructor_of_GlobalObject );
874}
Note: See TracBrowser for help on using the repository browser.