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

Last change on this file since 220 was 220, checked in by dai_9181, 17 years ago

[64bitコンパイラ] スタックフレームが128ビット境界ラインにならないバグを修正

File size: 26.5 KB
RevLine 
[206]1#include "stdafx.h"
2
[183]3#include <jenga/include/smoothie/Smoothie.h>
4#include <jenga/include/smoothie/LexicalAnalysis.h>
5
[169]6#include <Program.h>
[198]7#include <Compiler.h>
[183]8#include <LexicalScopingImpl.h>
[206]9#include <Class.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
[206]34 const UserProc *pBackUserProc = &UserProc::CompilingUserProc();
[75]35 UserProc::CompileStartForGlobalArea();
[3]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
[129]55 //_System_StartupProgramの呼び出し
[206]56 extern const UserProc *pSub_System_StartupProgram;
[129]57 op_call(pSub_System_StartupProgram);
58
[42]59 //クラスに属する静的メンバを定義
[198]60 compiler.GetMeta().GetClasses().InitStaticMember();
[42]61
[3]62 GetGlobalDataForDll();
63
64 //add rsp,スタックフレームサイズ
[220]65 op_add_RV(REG_RSP,pobj_sf->GetFrameSize(0));
[3]66
67 //スタックフレームスケジュール(subコマンドに渡す値)
[220]68 *((long *)(OpBuffer+StackFrameSchedule))=pobj_sf->GetFrameSize(0);
[3]69
[75]70 UserProc::CompileStartForUserProc( pBackUserProc );
[3]71 cp=BackCp;
72
73 //ret
[142]74 op_ret();
[3]75 }
[86]76 else if( userProc.GetName() == "_System_InitStaticLocalVariables" ){
[3]77 //静的ローカルオブジェクトのコンストラクタ呼び出し
78
79 //sub rsp,スタックフレームサイズ
80 int StackFrameSchedule;
81 op_sub_rsp(0xFFFFFFFF);
82 StackFrameSchedule=obp-sizeof(long);
83
[206]84 BOOST_FOREACH( Variable *pVar, compiler.GetMeta().GetGlobalVars() ){
[75]85 if(memicmp(pVar->GetName().c_str(),"Static%",7)==0){
[3]86 //コンストラクタ呼び出し
[206]87 if( pVar->GetType().IsObject() ){
[3]88
89 //エラー用
[75]90 cp=pVar->source_code_address;
[3]91
[50]92 CallConstructor(
[75]93 pVar->GetName().c_str(),
[206]94 pVar->GetSubscripts(),
95 pVar->GetType(),
96 pVar->GetParamStrForConstructor().c_str());
[3]97 }
98 }
99 }
100
101 //add rsp,スタックフレームサイズ
[220]102 op_add_RV(REG_RSP,pobj_sf->GetFrameSize(0));
[3]103
104 //スタックフレームスケジュール(subコマンドに渡す値)
[220]105 *((long *)(OpBuffer+StackFrameSchedule))=pobj_sf->GetFrameSize(0);
[3]106
107 //ret
[142]108 op_ret();
[3]109 }
[86]110 else if( userProc.GetName() == "_System_Call_Destructor_of_GlobalObject" ){
[3]111 //sub rsp,8(※RSPを16バイト境界にあわせるため)
112 op_sub_rsp(0x8);
113
114
[206]115 const UserProc *pBackUserProc = &UserProc::CompilingUserProc();
[75]116 UserProc::CompileStartForGlobalArea();
[3]117
[183]118 GetLexicalScopes().CallDestructorsOfScopeEnd();
[3]119
[75]120 UserProc::CompileStartForUserProc( pBackUserProc );
[3]121
122
123 //add rsp,8
[64]124 op_add_RV(REG_RSP,0x8);
[3]125
126 //ret
[142]127 op_ret();
[3]128 }
[86]129 else if( userProc.GetName() == "_System_GetSp" ){
[3]130 //mov rax,rsp
131 op_mov_RR(REG_RAX,REG_RSP);
132
133 //add rax,PTR_SIZE
[64]134 op_add_RV(REG_RAX,PTR_SIZE);
[3]135
136 //ret
[142]137 op_ret();
[3]138 }
[86]139 else if( userProc.GetName() == "_allrem" ){
[3]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 }
[86]148 else if( userProc.GetName() == "_allmul" ){
[3]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 }
[86]157 else if( userProc.GetName() == "_alldiv" ){
[3]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 }
[86]166 else if( userProc.GetName() == "_allshl" ){
[3]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 }
[86]175 else if( userProc.GetName() == "_allshr" ){
[3]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 }
[86]184 else if( userProc.GetName() == "_aullshr" ){
[3]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 }
[90]209 else{
210 SetError();
211 }
212}
[206]213void AutoGeneration(const UserProc &userProc){
[90]214 if( userProc.GetName() == "InitializeUserTypes"
[89]215 && userProc.HasParentClass()
[131]216 && userProc.GetParentClass().GetName() == "_System_TypeBase" ){
[89]217
[198]218 compiler.GetMeta().GetClasses().Compile_System_InitializeUserTypes();
[86]219 }
[95]220 else if( userProc.GetName() == "RegisterGlobalRoots"
221 && userProc.HasParentClass()
[131]222 && userProc.GetParentClass().GetName() == "_System_CGarbageCollection" ){
[95]223
224 Compile_AddGlobalRootsForGc();
225 }
[86]226 else{
227 SetError();
228 }
[3]229}
[206]230void _compile_proc(const UserProc *pUserProc){
[3]231 extern char *basbuf;
232 extern HANDLE hHeap;
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
[206]239 if( pUserProc->GetLocalVars().size() ){
[76]240 SetError();
241 return;
242 }
243
[206]244 trace_for_sourcecodestep( "★★★ " << pUserProc->GetFullName() << "のコンパイルを開始" );
245
[75]246 pUserProc->CompleteCompile();
[3]247
248 extern BOOL bSystemProc;
[75]249 if(memcmp(pUserProc->GetName().c_str(),"_System_",8)==0) bSystemProc=1;
[3]250 else bSystemProc=0;
251
252 extern BOOL bDebugSupportProc;
[75]253 if(memcmp(pUserProc->GetName().c_str(),"_DebugSys_",10)==0){
[3]254 if(!bDebugCompile){
255 return;
256 }
257 bDebugSupportProc=1;
258 }
259 else bDebugSupportProc=0;
260
[206]261 pUserProc->SetBeginOpAddress( obp );
[3]262
[89]263 //コンパイル中の関数が属するクラス
[206]264 compiler.pCompilingClass=pUserProc->GetParentClassPtr();
[89]265
266 //コンパイルスタートをクラス管理クラスに追加
[198]267 compiler.GetMeta().GetClasses().StartCompile( pUserProc );
[89]268
269 //コンパイル中の関数
270 UserProc::CompileStartForUserProc( pUserProc );
271
[101]272 // コンパイル中の関数が属する名前空間
[202]273 compiler.GetNamespaceSupporter().SetLivingNamespaceScopes( pUserProc->GetNamespaceScopes() );
[101]274
[108]275 // コンパイル中の関数でImportsされている名前空間
[202]276 compiler.GetNamespaceSupporter().SetImportedNamespaces( pUserProc->GetImportedNamespaces() );
[108]277
[75]278 if(pUserProc->IsSystem()){
[3]279 ////////////////////
280 // 特殊関数
281 ////////////////////
282
283 extern int AllLocalVarSize;
284 AllLocalVarSize=0;
285
286 //スタックフレーム管理用オブジェクトを初期化
287 extern CStackFrame *pobj_sf;
288 pobj_sf=new CStackFrame();
289
[86]290 SystemProc(*pUserProc);
[3]291
292 //スタックフレーム管理用オブジェクトを破棄
293 delete pobj_sf;
294 pobj_sf=0;
295
[206]296 pUserProc->SetEndOpAddress( obp );
[3]297 return;
298 }
299
[75]300 cp=pUserProc->GetCodePos();
[3]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 //レキシカルスコープ情報を初期化
[183]351 GetLexicalScopes().Init(obp);
[3]352
353
354 /////////////////////////////////////
355 // パラメータ用の変数データを考慮
356 /////////////////////////////////////
357
[75]358 //パラメータ用の変数データを考慮
359 for(i3=(int)pUserProc->RealParams().size()-1;i3>=0;i3--){
360 Parameter &param = *pUserProc->RealParams()[i3];
[3]361
[206]362 Variable *pVar = new Variable( param.GetVarName(), param, false, param.IsRef(), "" );
[3]363
[75]364 if( param.IsArray() ){
[206]365 pVar->SetArray( param.GetSubscripts() );
[3]366 }
367
[75]368 int varSize;
369 if( param.IsRef() == false && param.IsStruct() ){
[64]370 //構造体のByValパラメータ
[75]371 pVar->ThisIsParameter();
372 varSize=PTR_SIZE;
[3]373 }
374 else{
[75]375 if( param.IsArray() == false ){
376 varSize = pVar->GetMemorySize();
[3]377 }
378 else{
[75]379 varSize=PTR_SIZE;
[3]380 }
381 }
[75]382 AllLocalVarSize+=varSize;
[206]383 pVar->SetOffsetAddress( AllLocalVarSize );
[3]384
385 //レキシカルスコープ情報
[206]386 pVar->SetScopeLevel( GetLexicalScopes().GetNowLevel() );
387 pVar->SetScopeStartAddress( GetLexicalScopes().GetStartAddress() );
[75]388 pVar->bLiving=TRUE;
[3]389
[206]390 pUserProc->GetLocalVars().push_back( pVar );
[3]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
[75]405 for(i3=(int)pUserProc->RealParams().size()-1;i3>=0;i3--){
406 Parameter &param = *pUserProc->RealParams()[i3];
[3]407 if(i3==3){
[75]408 if(param.IsReal()&&param.IsRef() == false){
[3]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){
[75]418 if(param.IsReal()&&param.IsRef() == false){
[3]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){
[75]428 if(param.IsReal()&&param.IsRef() == false){
[3]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){
[75]438 if(param.IsReal()&&param.IsRef() == false){
[3]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
[75]470 if( !pUserProc->ReturnType().IsNull() ){
[3]471 //戻り値が存在するとき
472
[75]473 const char *temp = pUserProc->GetName().c_str();
474 if( temp[0]==1&&temp[1]==ESC_OPERATOR ){
475 temp = "_System_ReturnValue";
476 }
[3]477
[75]478 if( pUserProc->ReturnType().IsStruct() ){
[64]479 //戻り値用の構造体(値型)はパラメータで引き渡される
[3]480 }
481 else{
[89]482 if( pUserProc->ReturnType().IsObject() ){
[198]483 sprintf(temporary,"%s=Nothing%c%c%s",temp,1,ESC_AS, Compiler::TypeToString( pUserProc->ReturnType() ).c_str() );
[89]484 }
485 else{
486 //戻り値用の変数の定義
[198]487 sprintf(temporary,"%s%c%c%s",temp,1,ESC_AS, Compiler::TypeToString( pUserProc->ReturnType() ).c_str() );
[89]488 }
[40]489
[3]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
[64]502 op_mov_RR(REG_RCX,REG_RSP);
[3]503
504 //add rcx,スタックフレームサイズ+sizeof(_int64) ※ret用のサイズを考慮
[64]505 op_add_RV(REG_RCX,0);
[3]506 RspOffsetSchedule2=obp-sizeof(long);
507
508 //call _DebugSys_StartProc
[206]509 extern const UserProc *pSub_DebugSys_StartProc;
[3]510 op_call(pSub_DebugSys_StartProc);
511 }
512
[206]513 if(compiler.pCompilingClass){
514 if( pUserProc->GetName() == compiler.pCompilingClass->GetName() ){
[3]515 ////////////////////////////////////
516 // コンストラクタをコンパイルするとき
517 ////////////////////////////////////
518
[17]519 //コンストラクタのコンパイル開始を通知
[206]520 compiler.pCompilingClass->NotifyStartConstructorCompile();
[17]521
[27]522 //基底クラスかどうかの識別
523 //(継承元がインターフェイスの場合も基底クラスと見なす)
[3]524 BOOL bThisIsSuperClass;
[206]525 if( !compiler.pCompilingClass->HasSuperClass() ) bThisIsSuperClass=1;
526 else if( compiler.pCompilingClass->GetSuperClass().GetConstructorMethod() == NULL ){
[3]527 //インターフェイスを継承したときはコンストラクタを持たない
528 bThisIsSuperClass=1;
529 }
530 else bThisIsSuperClass=0;
531
532 if(!bThisIsSuperClass){
533 /* サブクラスコンストラクタをコンパイルしているときは、
[27]534 基底クラスのコンストラクタを呼び出す */
[3]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 }
[206]545 if( compiler.pCompilingClass->GetSuperClass().GetName() == temporary ){
[27]546 //基底クラスのコンストラクタを呼び出す
[3]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
[89]560 Type dummyType;
561 CallProc( PROC_DEFAULT
[206]562 , &compiler.pCompilingClass->GetSuperClass().GetConstructorMethod()->GetUserProc()
563 , compiler.pCompilingClass->GetSuperClass().GetConstructorMethod()->GetUserProc().GetName().c_str()
[89]564 , temporary
565 , dummyType );
[3]566 }
567 else{
[27]568 //基底クラスのコンストラクタを暗黙的に呼び出す
[3]569 Opcode_CallProc("",
[206]570 &compiler.pCompilingClass->GetSuperClass().GetConstructorMethod()->GetUserProc(),
[3]571 0,
572 "",
573 0);
574 }
575 }
576
577 //仮想関数テーブルを初期化
[206]578 if( compiler.pCompilingClass->IsExistVirtualFunctions()
579 && !compiler.pCompilingClass->IsAbstract() ){
[28]580 //関数テーブルに値をセット
[206]581 int offset = (int)compiler.pCompilingClass->GetVtblGlobalOffset();
[3]582
[28]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);
[3]588
[28]589 //Thisポインタをrcxにコピー
590 SetThisPtrToReg(REG_RCX);
[3]591
[28]592 //mov qword ptr[rcx],rax
593 op_mov_MR(sizeof(_int64),REG_RAX,REG_RCX,0,MOD_BASE);
[3]594 }
595 }
[75]596 else if( pUserProc->IsDestructor() ){
[18]597 //デストラクタをコンパイルしたとき
598
599 //デストラクタのコンパイル開始を通知
[206]600 compiler.pCompilingClass->NotifyStartDestructorCompile();
[18]601 }
[3]602 }
603
604 //////////////////////////////////////////
605 //////////////////////////////////////////
606 ////// プロシージャ内をコンパイル ////////
[90]607 if( pUserProc->IsAutoGeneration() ){
608 AutoGeneration( *pUserProc );
609 }
[75]610 else{
[90]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 }
[75]622 }
[3]623 //////////////////////////////////////////
624 //////////////////////////////////////////
625
[206]626 if( compiler.pCompilingClass ){
[17]627
[206]628 if( compiler.pCompilingClass->IsCompilingConstructor() ){
[17]629 // コンストラクタをコンパイルしていたとき
[18]630
[17]631 // コンストラクタのコンパイルが完了したことを通知
[206]632 compiler.pCompilingClass->NotifyFinishConstructorCompile();
[17]633 }
[75]634 else if( pUserProc->IsDestructor() ){
[3]635 ////////////////////////////////////
636 //デストラクタをコンパイルしたとき
637 ////////////////////////////////////
638
[18]639 // デストラクタのコンパイルが完了したことを通知
[206]640 compiler.pCompilingClass->NotifyFinishDestructorCompile();
[18]641
[206]642 if( compiler.pCompilingClass->HasSuperClass() ){
[3]643 /* サブクラスのデストラクタをコンパイルしているときは、
[27]644 基底クラスのデストラクタを呼び出す */
[3]645
[206]646 const CMethod *method = compiler.pCompilingClass->GetSuperClass().GetDestructorMethod();
[51]647 if( method ){
[3]648 Opcode_CallProc("",
[206]649 &method->GetUserProc(),
[3]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)の解放処理
[183]686 GetLexicalScopes().CallDestructorsOfScopeEnd();
[3]687
[34]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
[206]696 extern const UserProc *pSub_DebugSys_EndProc;
[34]697 op_call(pSub_DebugSys_EndProc);
698 }
699
[75]700 if( !pUserProc->ReturnType().IsNull() ){
[3]701 //////////////////////////////////
702 // 戻り値をraxまたはxmm0に設定
703 //////////////////////////////////
704
705 RELATIVE_VAR RelativeVar;
706
[75]707 const char *temp = pUserProc->GetName().c_str();
708 if( temp[0]==1 && temp[1]==ESC_OPERATOR ){
[3]709 temp="_System_ReturnValue";
[75]710 }
711 GetVarOffsetReadWrite(temp,&RelativeVar,Type());
[3]712
[75]713 i3=pUserProc->ReturnType().GetBasicType();
[3]714
[64]715 if(i3==DEF_OBJECT || i3==DEF_STRUCT){
[3]716 SetVarPtrToReg(REG_RAX,&RelativeVar);
[64]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 }
[3]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
[220]737 if( pUserProc->GetName() == "test" )
738 {
739 int test=0;
740 }
741
[3]742 //ローカル変数領域のサイズをスタックフレームに通知
[220]743 int localParmSize = AllLocalVarSize - BaseLocalVar;
744 int stackFrameSize = pobj_sf->GetFrameSize( AllLocalVarSize );
[3]745
746 //ローカル変数アドレススケジュール
747 for(i3=0;i3<LocalVarAddrScheduleNum;i3++){
[220]748 *((long *)(OpBuffer+pLocalVarAddrSchedule[i3])) += AllLocalVarSize + stackFrameSize;
[3]749 }
750 HeapDefaultFree(pLocalVarAddrSchedule);
[206]751 BOOST_FOREACH( Variable *pVar, pUserProc->GetLocalVars() ){
[3]752 //後にデバッグで利用する
[206]753 pVar->SetOffsetAddress(
[220]754 AllLocalVarSize + stackFrameSize - pVar->GetOffsetAddress()
[206]755 );
[3]756 }
757
758 //mov reg,qword ptr[rsp+offset] ※スタックフレームを利用
759 pobj_sf->pop(REG_R15);
760 pobj_sf->pop(REG_R14);
761 pobj_sf->pop(REG_R13);
762 pobj_sf->pop(REG_R12);
763 pobj_sf->pop(REG_RDI);
764 pobj_sf->pop(REG_RSI);
765 pobj_sf->pop(REG_RBX);
766
[220]767 int stackFrameAndLocalParamSize = localParmSize + stackFrameSize;
[3]768
769 //add rsp,スタックフレームサイズ
[220]770 op_add_rsp(stackFrameAndLocalParamSize);
[3]771
[142]772 //ret
773 op_ret();
[3]774
775
776 //デバッグ用
777 if(RspOffsetSchedule){
[220]778 *((long *)(OpBuffer+RspOffsetSchedule))=stackFrameAndLocalParamSize;
779 *((long *)(OpBuffer+RspOffsetSchedule2))=stackFrameAndLocalParamSize+sizeof(_int64);
[3]780 }
781
782
783 //スタックフレームスケジュール(subコマンド)
[220]784 *((long *)(OpBuffer+StackFrameSchedule))=stackFrameAndLocalParamSize;
[3]785
786 //スタックフレームスケジュールを実行
[220]787 pobj_sf->RunningSchedule( stackFrameSize );
[3]788 delete pobj_sf;
789 pobj_sf=0;
790
791
[206]792 pUserProc->SetEndOpAddress( obp );
[3]793
[75]794
795 //重複エラー情報管理のメモリを解放
796 for(i3=0;i3<SynonymErrorNum;i3++) HeapDefaultFree(SynonymErrorWords[i3]);
797 HeapDefaultFree(SynonymErrorWords);
[3]798}
[91]799
[206]800void CompileBufferInProcedure( const UserProc &userProc ){
[91]801 if( userProc.IsUsing() == false || userProc.IsCompiled() ) return;
802
803 _compile_proc( &userProc );
804
805 // ログを履く
806 char temporary[8192];
807 temporary[0]=0;
808 lstrcat( temporary, "------------------------------------------------------------------\n" );
[100]809 sprintf( temporary + lstrlen(temporary), "【 %s のコード情報】\n", userProc.GetName().c_str() );
[91]810 sprintf( temporary + lstrlen(temporary), "code size: %d bytes\n", userProc.GetCodeSize() );
811 lstrcat( temporary, "------------------------------------------------------------------\n" );
812 lstrcat( temporary, "\n" );
[169]813 trace_for_size( temporary );
[91]814}
[3]815void CompileLocal(){
816 extern BOOL bDll;
817 if(bDll){
818 //DLLの場合はグローバル変数を初期化するための関数を一番初めにコンパイルする
[206]819 const UserProc *pUserProc = GetSubHash("_System_InitDllGlobalVariables");
[75]820 if(pUserProc){
[91]821 CompileBufferInProcedure( *pUserProc );
[3]822 }
823 else SetError(300,NULL,cp);
824 }
825
[94]826 //_System_TypeBase_InitializeUserTypesは一番最後にコンパイル
[206]827 extern const UserProc *pSubStaticMethod_System_TypeBase_InitializeUserTypes;
[94]828 pSubStaticMethod_System_TypeBase_InitializeUserTypes->CompleteCompile();
829
[3]830 //_System_InitStaticLocalVariablesは一番最後にコンパイル
831 //※一般関数内の静的変数オブジェクトをすべて収集しなければならない
[206]832 extern const UserProc *pSub_System_InitStaticLocalVariables;
[75]833 pSub_System_InitStaticLocalVariables->CompleteCompile();
[3]834
835 //_System_Call_Destructor_of_GlobalObjectは一番最後にコンパイル
[206]836 extern const UserProc *pSub_System_Call_Destructor_of_GlobalObject;
[75]837 pSub_System_Call_Destructor_of_GlobalObject->CompleteCompile();
[3]838
[94]839repeat:
[206]840 compiler.GetMeta().GetUserProcs().Iterator_Reset();
841 while( compiler.GetMeta().GetUserProcs().Iterator_HasNext() )
842 {
843 UserProc *pUserProc = compiler.GetMeta().GetUserProcs().Iterator_GetNext();
844 CompileBufferInProcedure( *pUserProc );
[3]845 }
846
[94]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 //プロシージャコンパイルによって、プロシージャコンパイルが必要になる場合
[206]858
859 compiler.GetMeta().GetUserProcs().Iterator_Reset();
860 while( compiler.GetMeta().GetUserProcs().Iterator_HasNext() )
861 {
862 UserProc *pUserProc = compiler.GetMeta().GetUserProcs().Iterator_GetNext();
863 CompileBufferInProcedure( *pUserProc );
[3]864 }
865 }
866
867 //_System_InitStaticLocalVariablesは一番最後にコンパイル
[75]868 pSub_System_InitStaticLocalVariables->KillCompileStatus();
[91]869 CompileBufferInProcedure( *pSub_System_InitStaticLocalVariables );
[3]870
871 //_System_Call_Destructor_of_GlobalObjectは一番最後にコンパイル
[75]872 pSub_System_Call_Destructor_of_GlobalObject->KillCompileStatus();
[91]873 CompileBufferInProcedure( *pSub_System_Call_Destructor_of_GlobalObject );
[3]874}
Note: See TracBrowser for help on using the repository browser.