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

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