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

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