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

Last change on this file since 232 was 232, checked in by dai_9181, 17 years ago
File size: 27.3 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]
[226]17 compiler.codeGenerator.op_mov_RM(sizeof(_int64),REG_RAX,REG_RSP,0,MOD_BASE);
[3]18
19 //ret
[226]20 compiler.codeGenerator.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
[226]29 compiler.codeGenerator.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;
[226]43 compiler.codeGenerator.op_sub_rsp(0xFFFFFFFF);
[3]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;
[226]57 compiler.codeGenerator.op_call(pSub_System_StartupProgram);
[129]58
[42]59 //クラスに属する静的メンバを定義
[198]60 compiler.GetMeta().GetClasses().InitStaticMember();
[42]61
[3]62 GetGlobalDataForDll();
63
64 //add rsp,スタックフレームサイズ
[226]65 compiler.codeGenerator.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
[226]74 compiler.codeGenerator.op_ret();
[3]75 }
[86]76 else if( userProc.GetName() == "_System_InitStaticLocalVariables" ){
[3]77 //静的ローカルオブジェクトのコンストラクタ呼び出し
78
79 //sub rsp,スタックフレームサイズ
80 int StackFrameSchedule;
[226]81 compiler.codeGenerator.op_sub_rsp(0xFFFFFFFF);
[3]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,スタックフレームサイズ
[226]102 compiler.codeGenerator.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
[226]108 compiler.codeGenerator.op_ret();
[3]109 }
[86]110 else if( userProc.GetName() == "_System_Call_Destructor_of_GlobalObject" ){
[3]111 //sub rsp,8(※RSPを16バイト境界にあわせるため)
[226]112 compiler.codeGenerator.op_sub_rsp(0x8);
[3]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
[226]124 compiler.codeGenerator.op_add_RV(REG_RSP,0x8);
[3]125
126 //ret
[226]127 compiler.codeGenerator.op_ret();
[3]128 }
[86]129 else if( userProc.GetName() == "_System_GetSp" ){
[3]130 //mov rax,rsp
[226]131 compiler.codeGenerator.op_mov_RR(REG_RAX,REG_RSP);
[3]132
133 //add rax,PTR_SIZE
[226]134 compiler.codeGenerator.op_add_RV(REG_RAX,PTR_SIZE);
[3]135
136 //ret
[226]137 compiler.codeGenerator.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
[226]278 // コード生成対象を選択
279 compiler.codeGenerator.Select( (const_cast<UserProc *>(pUserProc))->GetNativeCode() );
280
[75]281 if(pUserProc->IsSystem()){
[3]282 ////////////////////
283 // 特殊関数
284 ////////////////////
285
286 extern int AllLocalVarSize;
287 AllLocalVarSize=0;
288
289 //スタックフレーム管理用オブジェクトを初期化
290 extern CStackFrame *pobj_sf;
291 pobj_sf=new CStackFrame();
292
[86]293 SystemProc(*pUserProc);
[3]294
295 //スタックフレーム管理用オブジェクトを破棄
296 delete pobj_sf;
297 pobj_sf=0;
298
[206]299 pUserProc->SetEndOpAddress( obp );
[3]300 return;
301 }
302
[75]303 cp=pUserProc->GetCodePos();
[3]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 extern DWORD dwContinueAddress;
341 dwContinueAddress=-1;
342
343 //ローカル変数に関する情報
344 extern int AllLocalVarSize;
345 AllLocalVarSize=0;
346
347 //ローカル変数アドレススケジュール
348 extern DWORD *pLocalVarAddrSchedule;
349 extern int LocalVarAddrScheduleNum;
350 pLocalVarAddrSchedule=(DWORD *)HeapAlloc(hHeap,0,1);
351 LocalVarAddrScheduleNum=0;
352
353 //レキシカルスコープ情報を初期化
[183]354 GetLexicalScopes().Init(obp);
[3]355
356
357 /////////////////////////////////////
358 // パラメータ用の変数データを考慮
359 /////////////////////////////////////
360
[75]361 //パラメータ用の変数データを考慮
362 for(i3=(int)pUserProc->RealParams().size()-1;i3>=0;i3--){
363 Parameter &param = *pUserProc->RealParams()[i3];
[3]364
[206]365 Variable *pVar = new Variable( param.GetVarName(), param, false, param.IsRef(), "" );
[3]366
[75]367 if( param.IsArray() ){
[206]368 pVar->SetArray( param.GetSubscripts() );
[3]369 }
370
[75]371 int varSize;
372 if( param.IsRef() == false && param.IsStruct() ){
[64]373 //構造体のByValパラメータ
[75]374 pVar->ThisIsParameter();
375 varSize=PTR_SIZE;
[3]376 }
377 else{
[75]378 if( param.IsArray() == false ){
379 varSize = pVar->GetMemorySize();
[3]380 }
381 else{
[75]382 varSize=PTR_SIZE;
[3]383 }
384 }
[75]385 AllLocalVarSize+=varSize;
[206]386 pVar->SetOffsetAddress( AllLocalVarSize );
[3]387
388 //レキシカルスコープ情報
[206]389 pVar->SetScopeLevel( GetLexicalScopes().GetNowLevel() );
390 pVar->SetScopeStartAddress( GetLexicalScopes().GetStartAddress() );
[75]391 pVar->bLiving=TRUE;
[3]392
[206]393 pUserProc->GetLocalVars().push_back( pVar );
[3]394 }
395
396 //Thisポインタを示すローカルオフセット値をセット
397 extern int LocalVar_ThisPtrOffset;
398 LocalVar_ThisPtrOffset=AllLocalVarSize;
399
400 //スタックフレーム管理用クラスを初期化
401 extern CStackFrame *pobj_sf;
402 pobj_sf=new CStackFrame();
403
404
405 ///////////////////////
406 // ここからコード生成
407
[75]408 for(i3=(int)pUserProc->RealParams().size()-1;i3>=0;i3--){
409 Parameter &param = *pUserProc->RealParams()[i3];
[3]410 if(i3==3){
[75]411 if(param.IsReal()&&param.IsRef() == false){
[3]412 //movsd qword ptr[rsp+0x20],xmm3
[226]413 compiler.codeGenerator.op_movsd_MR(REG_XMM3,REG_RSP,0x20,MOD_BASE_DISP32);
[3]414 }
415 else{
416 //mov qword ptr[rsp+0x20],r9
[226]417 compiler.codeGenerator.op_mov_MR(sizeof(_int64),REG_R9,REG_RSP,0x20,MOD_BASE_DISP32);
[3]418 }
419 }
420 if(i3==2){
[75]421 if(param.IsReal()&&param.IsRef() == false){
[3]422 //movsd qword ptr[rsp+0x18],xmm2
[226]423 compiler.codeGenerator.op_movsd_MR(REG_XMM2,REG_RSP,0x18,MOD_BASE_DISP32);
[3]424 }
425 else{
426 //mov qword ptr[rsp+0x18],r8
[226]427 compiler.codeGenerator.op_mov_MR(sizeof(_int64),REG_R8,REG_RSP,0x18,MOD_BASE_DISP32);
[3]428 }
429 }
430 if(i3==1){
[75]431 if(param.IsReal()&&param.IsRef() == false){
[3]432 //movsd qword ptr[rsp+0x10],xmm1
[226]433 compiler.codeGenerator.op_movsd_MR(REG_XMM1,REG_RSP,0x10,MOD_BASE_DISP32);
[3]434 }
435 else{
436 //mov qword ptr[rsp+0x10],rdx
[226]437 compiler.codeGenerator.op_mov_MR(sizeof(_int64),REG_RDX,REG_RSP,0x10,MOD_BASE_DISP32);
[3]438 }
439 }
440 if(i3==0){
[75]441 if(param.IsReal()&&param.IsRef() == false){
[3]442 //movsd qword ptr[rsp+0x8],xmm0
[226]443 compiler.codeGenerator.op_movsd_MR(REG_XMM0,REG_RSP,0x8,MOD_BASE_DISP32);
[3]444 }
445 else{
446 //mov qword ptr[rsp+0x8],rcx
[226]447 compiler.codeGenerator.op_mov_MR(sizeof(_int64),REG_RCX,REG_RSP,0x8,MOD_BASE_DISP32);
[3]448 }
449 }
450 }
451
452 //ret用のアドレスを考慮
453 AllLocalVarSize+=sizeof(_int64);
454
455 //sub rsp,スタックフレームサイズ
456 int StackFrameSchedule;
[226]457 compiler.codeGenerator.op_sub_rsp(0xFFFFFFFF);
[3]458 StackFrameSchedule=obp-sizeof(long);
459
460 //mov qword ptr[rsp+offset],reg ※スタックフレームを利用
461 pobj_sf->push(REG_RBX);
462 pobj_sf->push(REG_RSI);
463 pobj_sf->push(REG_RDI);
464 pobj_sf->push(REG_R12);
465 pobj_sf->push(REG_R13);
466 pobj_sf->push(REG_R14);
467 pobj_sf->push(REG_R15);
468
469 //ローカル変数のベース値
470 int BaseLocalVar;
471 BaseLocalVar=AllLocalVarSize;
472
[75]473 if( !pUserProc->ReturnType().IsNull() ){
[3]474 //戻り値が存在するとき
475
[75]476 const char *temp = pUserProc->GetName().c_str();
477 if( temp[0]==1&&temp[1]==ESC_OPERATOR ){
478 temp = "_System_ReturnValue";
479 }
[3]480
[75]481 if( pUserProc->ReturnType().IsStruct() ){
[64]482 //戻り値用の構造体(値型)はパラメータで引き渡される
[3]483 }
484 else{
[89]485 if( pUserProc->ReturnType().IsObject() ){
[198]486 sprintf(temporary,"%s=Nothing%c%c%s",temp,1,ESC_AS, Compiler::TypeToString( pUserProc->ReturnType() ).c_str() );
[89]487 }
488 else{
489 //戻り値用の変数の定義
[198]490 sprintf(temporary,"%s%c%c%s",temp,1,ESC_AS, Compiler::TypeToString( pUserProc->ReturnType() ).c_str() );
[89]491 }
[40]492
[3]493 OpcodeDim(temporary,0);
494 }
495 }
496
497 int RspOffsetSchedule=0;
498 int RspOffsetSchedule2;
499 if(bDebugCompile&&bDebugSupportProc==0){
500 //mov rdx, qword ptr[rsp+スタックフレームサイズ]
[226]501 compiler.codeGenerator.op_mov_RM(sizeof(_int64),REG_RDX,REG_RSP,0,MOD_BASE_DISP32);
[3]502 RspOffsetSchedule=obp-sizeof(long);
503
504 //mov rcx,rsp
[226]505 compiler.codeGenerator.op_mov_RR(REG_RCX,REG_RSP);
[3]506
507 //add rcx,スタックフレームサイズ+sizeof(_int64) ※ret用のサイズを考慮
[226]508 compiler.codeGenerator.op_add_RV(REG_RCX,0);
[3]509 RspOffsetSchedule2=obp-sizeof(long);
510
511 //call _DebugSys_StartProc
[206]512 extern const UserProc *pSub_DebugSys_StartProc;
[226]513 compiler.codeGenerator.op_call(pSub_DebugSys_StartProc);
[3]514 }
515
[206]516 if(compiler.pCompilingClass){
517 if( pUserProc->GetName() == compiler.pCompilingClass->GetName() ){
[3]518 ////////////////////////////////////
519 // コンストラクタをコンパイルするとき
520 ////////////////////////////////////
521
[17]522 //コンストラクタのコンパイル開始を通知
[206]523 compiler.pCompilingClass->NotifyStartConstructorCompile();
[17]524
[27]525 //基底クラスかどうかの識別
526 //(継承元がインターフェイスの場合も基底クラスと見なす)
[3]527 BOOL bThisIsSuperClass;
[206]528 if( !compiler.pCompilingClass->HasSuperClass() ) bThisIsSuperClass=1;
529 else if( compiler.pCompilingClass->GetSuperClass().GetConstructorMethod() == NULL ){
[3]530 //インターフェイスを継承したときはコンストラクタを持たない
531 bThisIsSuperClass=1;
532 }
533 else bThisIsSuperClass=0;
534
535 if(!bThisIsSuperClass){
536 /* サブクラスコンストラクタをコンパイルしているときは、
[27]537 基底クラスのコンストラクタを呼び出す */
[3]538
539 i3=cp+1;
540 while(IsCommandDelimitation(basbuf[i3])) i3++;
541 for(i4=0;;i3++,i4++){
542 if(!IsVariableChar(basbuf[i3])){
543 temporary[i4]=0;
544 break;
545 }
546 temporary[i4]=basbuf[i3];
547 }
[206]548 if( compiler.pCompilingClass->GetSuperClass().GetName() == temporary ){
[27]549 //基底クラスのコンストラクタを呼び出す
[3]550 cp=i3;
551 for(i4=0;;cp++,i4++){
552 if(IsCommandDelimitation(basbuf[cp])){
553 temporary[i4]=0;
554 break;
555 }
556 temporary[i4]=basbuf[cp];
557 }
558 if(!(temporary[0]=='('&&temporary[lstrlen(temporary)-1]==')')){
559 SetError(1,NULL,cp);
560 }
561 RemoveStringPare(temporary);
562
[89]563 Type dummyType;
564 CallProc( PROC_DEFAULT
[206]565 , &compiler.pCompilingClass->GetSuperClass().GetConstructorMethod()->GetUserProc()
566 , compiler.pCompilingClass->GetSuperClass().GetConstructorMethod()->GetUserProc().GetName().c_str()
[89]567 , temporary
568 , dummyType );
[3]569 }
570 else{
[27]571 //基底クラスのコンストラクタを暗黙的に呼び出す
[3]572 Opcode_CallProc("",
[206]573 &compiler.pCompilingClass->GetSuperClass().GetConstructorMethod()->GetUserProc(),
[3]574 0,
575 "",
576 0);
577 }
578 }
579
580 //仮想関数テーブルを初期化
[206]581 if( compiler.pCompilingClass->IsExistVirtualFunctions()
582 && !compiler.pCompilingClass->IsAbstract() ){
[28]583 //関数テーブルに値をセット
[206]584 int offset = (int)compiler.pCompilingClass->GetVtblGlobalOffset();
[3]585
[28]586 //mov rax,offset
[226]587 compiler.codeGenerator.op_mov_RV(sizeof(_int64),REG_RAX,offset);
[28]588 obp-=sizeof(long);
589 pobj_DataTableSchedule->add();
590 obp+=sizeof(long);
[3]591
[28]592 //Thisポインタをrcxにコピー
593 SetThisPtrToReg(REG_RCX);
[3]594
[28]595 //mov qword ptr[rcx],rax
[226]596 compiler.codeGenerator.op_mov_MR(sizeof(_int64),REG_RAX,REG_RCX,0,MOD_BASE);
[3]597 }
598 }
[75]599 else if( pUserProc->IsDestructor() ){
[18]600 //デストラクタをコンパイルしたとき
601
602 //デストラクタのコンパイル開始を通知
[206]603 compiler.pCompilingClass->NotifyStartDestructorCompile();
[18]604 }
[3]605 }
606
607 //////////////////////////////////////////
608 //////////////////////////////////////////
609 ////// プロシージャ内をコンパイル ////////
[90]610 if( pUserProc->IsAutoGeneration() ){
611 AutoGeneration( *pUserProc );
612 }
[75]613 else{
[90]614 if(pUserProc->IsMacro()){
615 CompileBuffer(ESC_ENDMACRO,0);
616 }
617 else{
618 if(pUserProc->IsSub()){
619 CompileBuffer(ESC_ENDSUB,0);
620 }
621 else if(pUserProc->IsFunction()){
622 CompileBuffer(ESC_ENDFUNCTION,0);
623 }
624 }
[75]625 }
[3]626 //////////////////////////////////////////
627 //////////////////////////////////////////
628
[206]629 if( compiler.pCompilingClass ){
[17]630
[206]631 if( compiler.pCompilingClass->IsCompilingConstructor() ){
[17]632 // コンストラクタをコンパイルしていたとき
[18]633
[17]634 // コンストラクタのコンパイルが完了したことを通知
[206]635 compiler.pCompilingClass->NotifyFinishConstructorCompile();
[17]636 }
[75]637 else if( pUserProc->IsDestructor() ){
[3]638 ////////////////////////////////////
639 //デストラクタをコンパイルしたとき
640 ////////////////////////////////////
641
[18]642 // デストラクタのコンパイルが完了したことを通知
[206]643 compiler.pCompilingClass->NotifyFinishDestructorCompile();
[18]644
[206]645 if( compiler.pCompilingClass->HasSuperClass() ){
[3]646 /* サブクラスのデストラクタをコンパイルしているときは、
[27]647 基底クラスのデストラクタを呼び出す */
[3]648
[206]649 const CMethod *method = compiler.pCompilingClass->GetSuperClass().GetDestructorMethod();
[51]650 if( method ){
[3]651 Opcode_CallProc("",
[206]652 &method->GetUserProc(),
[3]653 0,
654 "",
655 0);
656 }
657 }
658 }
659 }
660
661 //ラベル用のメモリを解放
662 for(i3=0;i3<MaxLabelNum;i3++){
663 if(pLabelNames[i3].pName) HeapDefaultFree(pLabelNames[i3].pName);
664 }
665 HeapDefaultFree(pLabelNames);
666
667 //Goto未知ラベルスケジュールを解放
668 for(i3=0;i3<GotoLabelScheduleNum;i3++){
669 if(pGotoLabelSchedule[i3].pName){
670 SetError(6,pGotoLabelSchedule[i3].pName,pGotoLabelSchedule[i3].now_cp);
671 HeapDefaultFree(pGotoLabelSchedule[i3].pName);
672 }
673 else{
674 sprintf(temporary,"%d",pGotoLabelSchedule[i3].line);
675 SetError(6,temporary,pGotoLabelSchedule[i3].now_cp);
676 }
677 }
678 HeapDefaultFree(pGotoLabelSchedule);
679
680 //With情報のメモリを解放
681 for(i3=0;i3<WithInfo.num;i3++){
682 SetError(22,"With",WithInfo.pWithCp[i3]);
683 HeapDefaultFree(WithInfo.ppName[i3]);
684 }
685 HeapDefaultFree(WithInfo.ppName);
686 HeapDefaultFree(WithInfo.pWithCp);
687
688 //ローカルオブジェクト(レキシカルスコープレベル=0)の解放処理
[183]689 GetLexicalScopes().CallDestructorsOfScopeEnd();
[3]690
[34]691 //プロシージャ抜け出しスケジュール(Exit Sub/Function)
692 for(i3=0;i3<ExitSubScheduleNum;i3++){
693 *((long *)(OpBuffer+pExitSubSchedule[i3]))=obp-(pExitSubSchedule[i3]+sizeof(long));
694 }
695 HeapDefaultFree(pExitSubSchedule);
696
697 if(bDebugCompile&&bDebugSupportProc==0){
698 //call _DebugSys_EndProc
[206]699 extern const UserProc *pSub_DebugSys_EndProc;
[226]700 compiler.codeGenerator.op_call(pSub_DebugSys_EndProc);
[34]701 }
702
[75]703 if( !pUserProc->ReturnType().IsNull() ){
[3]704 //////////////////////////////////
705 // 戻り値をraxまたはxmm0に設定
706 //////////////////////////////////
707
708 RELATIVE_VAR RelativeVar;
709
[75]710 const char *temp = pUserProc->GetName().c_str();
711 if( temp[0]==1 && temp[1]==ESC_OPERATOR ){
[3]712 temp="_System_ReturnValue";
[75]713 }
714 GetVarOffsetReadWrite(temp,&RelativeVar,Type());
[3]715
[75]716 i3=pUserProc->ReturnType().GetBasicType();
[3]717
[64]718 if(i3==DEF_OBJECT || i3==DEF_STRUCT){
[3]719 SetVarPtrToReg(REG_RAX,&RelativeVar);
[64]720 if( i3==DEF_OBJECT ){
721 //mov rax,qword ptr[rax]
[226]722 compiler.codeGenerator.op_mov_RM( sizeof(_int64), REG_RAX, REG_RAX, 0, MOD_BASE );
[64]723 }
[3]724 }
725 else if(i3==DEF_DOUBLE){
726 //64ビット実数型
727 SetXmmReg_DoubleVariable(&RelativeVar,REG_XMM0);
728 }
729 else if(i3==DEF_SINGLE){
730 //32ビット実数型
731 SetXmmReg_SingleVariable(&RelativeVar,REG_XMM0);
732 }
733 else if(IsWholeNumberType(i3)){
734 //整数型
735 SetReg_WholeVariable(i3,&RelativeVar,REG_RAX);
736 }
737 else SetError(300,NULL,cp);
738 }
739
740 //ローカル変数領域のサイズをスタックフレームに通知
[220]741 int localParmSize = AllLocalVarSize - BaseLocalVar;
[232]742 int stackFrameSize = pobj_sf->GetFrameSize( localParmSize );
[3]743
744 //ローカル変数アドレススケジュール
745 for(i3=0;i3<LocalVarAddrScheduleNum;i3++){
[220]746 *((long *)(OpBuffer+pLocalVarAddrSchedule[i3])) += AllLocalVarSize + stackFrameSize;
[3]747 }
748 HeapDefaultFree(pLocalVarAddrSchedule);
[206]749 BOOST_FOREACH( Variable *pVar, pUserProc->GetLocalVars() ){
[3]750 //後にデバッグで利用する
[206]751 pVar->SetOffsetAddress(
[220]752 AllLocalVarSize + stackFrameSize - pVar->GetOffsetAddress()
[206]753 );
[3]754 }
755
756 //mov reg,qword ptr[rsp+offset] ※スタックフレームを利用
757 pobj_sf->pop(REG_R15);
758 pobj_sf->pop(REG_R14);
759 pobj_sf->pop(REG_R13);
760 pobj_sf->pop(REG_R12);
761 pobj_sf->pop(REG_RDI);
762 pobj_sf->pop(REG_RSI);
763 pobj_sf->pop(REG_RBX);
764
[220]765 int stackFrameAndLocalParamSize = localParmSize + stackFrameSize;
[3]766
767 //add rsp,スタックフレームサイズ
[226]768 compiler.codeGenerator.op_add_rsp(stackFrameAndLocalParamSize);
[3]769
[142]770 //ret
[226]771 compiler.codeGenerator.op_ret();
[3]772
773
774 //デバッグ用
775 if(RspOffsetSchedule){
[220]776 *((long *)(OpBuffer+RspOffsetSchedule))=stackFrameAndLocalParamSize;
777 *((long *)(OpBuffer+RspOffsetSchedule2))=stackFrameAndLocalParamSize+sizeof(_int64);
[3]778 }
779
780
781 //スタックフレームスケジュール(subコマンド)
[220]782 *((long *)(OpBuffer+StackFrameSchedule))=stackFrameAndLocalParamSize;
[3]783
784 //スタックフレームスケジュールを実行
[220]785 pobj_sf->RunningSchedule( stackFrameSize );
[3]786 delete pobj_sf;
787 pobj_sf=0;
788
789
[206]790 pUserProc->SetEndOpAddress( obp );
[3]791
[75]792
793 //重複エラー情報管理のメモリを解放
794 for(i3=0;i3<SynonymErrorNum;i3++) HeapDefaultFree(SynonymErrorWords[i3]);
795 HeapDefaultFree(SynonymErrorWords);
[3]796}
[91]797
[206]798void CompileBufferInProcedure( const UserProc &userProc ){
[91]799 if( userProc.IsUsing() == false || userProc.IsCompiled() ) return;
800
801 _compile_proc( &userProc );
802
803 // ログを履く
804 char temporary[8192];
805 temporary[0]=0;
806 lstrcat( temporary, "------------------------------------------------------------------\n" );
[100]807 sprintf( temporary + lstrlen(temporary), "【 %s のコード情報】\n", userProc.GetName().c_str() );
[91]808 sprintf( temporary + lstrlen(temporary), "code size: %d bytes\n", userProc.GetCodeSize() );
809 lstrcat( temporary, "------------------------------------------------------------------\n" );
810 lstrcat( temporary, "\n" );
[169]811 trace_for_size( temporary );
[91]812}
[3]813void CompileLocal(){
814 extern BOOL bDll;
815 if(bDll){
816 //DLLの場合はグローバル変数を初期化するための関数を一番初めにコンパイルする
[206]817 const UserProc *pUserProc = GetSubHash("_System_InitDllGlobalVariables");
[75]818 if(pUserProc){
[91]819 CompileBufferInProcedure( *pUserProc );
[3]820 }
821 else SetError(300,NULL,cp);
822 }
823
[94]824 //_System_TypeBase_InitializeUserTypesは一番最後にコンパイル
[206]825 extern const UserProc *pSubStaticMethod_System_TypeBase_InitializeUserTypes;
[94]826 pSubStaticMethod_System_TypeBase_InitializeUserTypes->CompleteCompile();
827
[3]828 //_System_InitStaticLocalVariablesは一番最後にコンパイル
829 //※一般関数内の静的変数オブジェクトをすべて収集しなければならない
[206]830 extern const UserProc *pSub_System_InitStaticLocalVariables;
[75]831 pSub_System_InitStaticLocalVariables->CompleteCompile();
[3]832
833 //_System_Call_Destructor_of_GlobalObjectは一番最後にコンパイル
[206]834 extern const UserProc *pSub_System_Call_Destructor_of_GlobalObject;
[75]835 pSub_System_Call_Destructor_of_GlobalObject->CompleteCompile();
[3]836
[94]837repeat:
[206]838 compiler.GetMeta().GetUserProcs().Iterator_Reset();
839 while( compiler.GetMeta().GetUserProcs().Iterator_HasNext() )
840 {
841 UserProc *pUserProc = compiler.GetMeta().GetUserProcs().Iterator_GetNext();
842 CompileBufferInProcedure( *pUserProc );
[3]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 //プロシージャコンパイルによって、プロシージャコンパイルが必要になる場合
[206]856
857 compiler.GetMeta().GetUserProcs().Iterator_Reset();
858 while( compiler.GetMeta().GetUserProcs().Iterator_HasNext() )
859 {
860 UserProc *pUserProc = compiler.GetMeta().GetUserProcs().Iterator_GetNext();
861 CompileBufferInProcedure( *pUserProc );
[3]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.