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

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