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

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