source: dev/trunk/ab5.0/abdev/compiler_x64/Compile_ProcOp.cpp@ 768

Last change on this file since 768 was 768, checked in by dai, 15 years ago

[750]をx64版にマージ

File size: 19.9 KB
RevLine 
[206]1#include "stdafx.h"
2
[3]3#include "Opcode.h"
4
[86]5void SystemProc( const UserProc &userProc ){
6 if( userProc.GetName() == "_System_GetEip" ){
[3]7 //mov rax,qword ptr[rsp]
[226]8 compiler.codeGenerator.op_mov_RM(sizeof(_int64),REG_RAX,REG_RSP,0,MOD_BASE);
[3]9
10 //ret
[226]11 compiler.codeGenerator.op_ret();
[3]12 }
[86]13 else if( userProc.GetName() == "_System_InitDllGlobalVariables" ){
[3]14 ////////////////////////////////////////
15 // DLLのグローバル領域をコンパイル
16 ////////////////////////////////////////
[266]17 if(!compiler.IsDll()){
[3]18 //ret
[226]19 compiler.codeGenerator.op_ret();
[3]20
21 return;
22 }
23
24 int BackCp;
25 BackCp=cp;
26 cp=-1;
27
28 //sub rsp,スタックフレームサイズ
[255]29 const PertialSchedule *pStackFramePertialSchedule = compiler.codeGenerator.op_sub_rsp( 0, true );
[3]30
[460]31 if( compiler.IsDebug() )
32 {
[3]33 //デバッグ用の変数を定義
34 DebugVariable();
35 }
36
37 //GC用の変数を定義
38 InitGCVariables();
39
[129]40 //_System_StartupProgramの呼び出し
[206]41 extern const UserProc *pSub_System_StartupProgram;
[226]42 compiler.codeGenerator.op_call(pSub_System_StartupProgram);
[129]43
[42]44 //クラスに属する静的メンバを定義
[584]45 ActiveBasic::Compiler::ProcedureGenerator::Generate_InitStaticMember(
46 compiler.GetObjectModule().meta.GetClasses()
47 );
[42]48
[3]49 GetGlobalDataForDll();
50
51 //add rsp,スタックフレームサイズ
[226]52 compiler.codeGenerator.op_add_RV(REG_RSP,pobj_sf->GetFrameSize(0));
[3]53
54 //スタックフレームスケジュール(subコマンドに渡す値)
[255]55 compiler.codeGenerator.opfix( pStackFramePertialSchedule, pobj_sf->GetFrameSize(0) );
[3]56
57 cp=BackCp;
58
59 //ret
[226]60 compiler.codeGenerator.op_ret();
[3]61 }
[86]62 else if( userProc.GetName() == "_System_InitStaticLocalVariables" ){
[3]63 //静的ローカルオブジェクトのコンストラクタ呼び出し
64
65 //sub rsp,スタックフレームサイズ
[255]66 const PertialSchedule *pStackFramePertialSchedule = compiler.codeGenerator.op_sub_rsp( 0, true );
[3]67
[768]68 foreach( Variable *pVar, compiler.GetObjectModule().meta.GetGlobalVars() ){
69
70
71
[75]72 if(memicmp(pVar->GetName().c_str(),"Static%",7)==0){
[3]73 //コンストラクタ呼び出し
[206]74 if( pVar->GetType().IsObject() ){
[3]75
76 //エラー用
[75]77 cp=pVar->source_code_address;
[3]78
[50]79 CallConstructor(
[75]80 pVar->GetName().c_str(),
[206]81 pVar->GetSubscripts(),
82 pVar->GetType(),
83 pVar->GetParamStrForConstructor().c_str());
[3]84 }
85 }
86 }
87
88 //add rsp,スタックフレームサイズ
[226]89 compiler.codeGenerator.op_add_RV(REG_RSP,pobj_sf->GetFrameSize(0));
[3]90
91 //スタックフレームスケジュール(subコマンドに渡す値)
[255]92 compiler.codeGenerator.opfix( pStackFramePertialSchedule, pobj_sf->GetFrameSize(0) );
[3]93
94 //ret
[226]95 compiler.codeGenerator.op_ret();
[3]96 }
[643]97 else if( userProc.GetName() == "_System_Call_Destructor_of_GlobalObject" )
98 {
[3]99 //sub rsp,8(※RSPを16バイト境界にあわせるため)
[226]100 compiler.codeGenerator.op_sub_rsp(0x8);
[254]101 compiler.codeGenerator.lexicalScopes.CallDestructorsOfScopeEnd();
[3]102
103 //add rsp,8
[226]104 compiler.codeGenerator.op_add_RV(REG_RSP,0x8);
[3]105
106 //ret
[226]107 compiler.codeGenerator.op_ret();
[3]108 }
[90]109 else{
[468]110 compiler.errorMessenger.OutputFatalError();
[90]111 }
112}
[206]113void AutoGeneration(const UserProc &userProc){
[90]114 if( userProc.GetName() == "InitializeUserTypes"
[89]115 && userProc.HasParentClass()
[353]116 && userProc.GetParentClass().GetName() == "_System_TypeBase" )
117 {
[584]118 ActiveBasic::Compiler::ProcedureGenerator::Generate_System_InitializeUserTypes(
119 compiler.GetObjectModule().meta.GetClasses()
120 );
[86]121 }
[355]122 else if( userProc.GetName() == "InitializeUserTypesForBaseType"
123 && userProc.HasParentClass()
124 && userProc.GetParentClass().GetName() == "_System_TypeBase" )
125 {
[584]126 ActiveBasic::Compiler::ProcedureGenerator::Generate_System_InitializeUserTypesForBaseType(
127 compiler.GetObjectModule().meta.GetClasses()
128 );
[355]129 }
[95]130 else if( userProc.GetName() == "RegisterGlobalRoots"
131 && userProc.HasParentClass()
[353]132 && userProc.GetParentClass().GetName() == "_System_CGarbageCollection" )
133 {
134 Compile_AddGlobalRootsForGc();
[95]135 }
[711]136 else if( userProc.GetName() == compiler.GetGlobalAreaProcName() )
[643]137 {
[309]138 ////////////////////////////////////////
139 // グローバル領域をコンパイル
140 ////////////////////////////////////////
141
[364]142 UserProc::pGlobalProc = &userProc;
143
[309]144 int BackCp = cp;
145 cp=-1;
146
147 //クラスに属する静的メンバを定義
[584]148 ActiveBasic::Compiler::ProcedureGenerator::Generate_InitStaticMember(
149 compiler.GetObjectModule().meta.GetClasses()
150 );
[309]151
152 //グローバル実行領域をコンパイル開始
153 CompileBuffer(0,0);
154
155 //Goto未知ラベルスケジュールが存在したらエラーにする
[768]156 foreach( const GotoLabelSchedule *pGotoLabelSchedule, compiler.codeGenerator.gotoLabelSchedules )
[309]157 {
158 if(pGotoLabelSchedule->GetName().size()>0){
[468]159 compiler.errorMessenger.Output(6,pGotoLabelSchedule->GetName(),pGotoLabelSchedule->GetSourceCodePos());
[309]160 }
161 else{
162 char temporary[255];
163 sprintf(temporary,"%d",pGotoLabelSchedule->GetLineNum());
[468]164 compiler.errorMessenger.Output(6,temporary,pGotoLabelSchedule->GetSourceCodePos());
[309]165 }
166 }
167
168 cp=BackCp;
169 }
[350]170 else if( userProc.HasParentClass()
171 && userProc.IsCastOperator()
172 && userProc.ReturnType().IsInterface() )
173 {
174 // インターフェイス型にキャストするためのメソッド
175
176 int vtblMasterListIndex = userProc.GetParentClass().GetVtblMasterListIndex( &userProc.ReturnType().GetClass() );
177
178 char temporary[1024];
179 sprintf( temporary,
[370]180 "Return New %s(ObjPtr( This ),Get_LONG_PTR( (Get_LONG_PTR( ObjPtr(This)+SizeOf(VoidPtr) ) + SizeOf(LONG_PTR)*%d) As VoidPtr ) As VoidPtr )",
[729]181 compiler.TypeToString( userProc.ReturnType() ).c_str(),
[350]182 vtblMasterListIndex
183 );
184 MakeMiddleCode( temporary );
185
186 ChangeOpcode( temporary );
187 }
[86]188 else{
[468]189 compiler.errorMessenger.OutputFatalError();
[86]190 }
[3]191}
[206]192void _compile_proc(const UserProc *pUserProc){
[3]193 extern char *basbuf;
194 extern HANDLE hHeap;
[76]195 int i3,i4;
[3]196 char temporary[VN_SIZE];
197
[206]198 if( pUserProc->GetLocalVars().size() ){
[468]199 compiler.errorMessenger.OutputFatalError();
[76]200 return;
201 }
202
[633]203 trace_for_sourcecodestep( "★★★ " << FormatEscapeSequenceStringToDefaultString( pUserProc->GetFullName() ) << "のコンパイルを開始" );
[206]204
[75]205 pUserProc->CompleteCompile();
[3]206
207 extern BOOL bDebugSupportProc;
[75]208 if(memcmp(pUserProc->GetName().c_str(),"_DebugSys_",10)==0){
[460]209 if( !compiler.IsDebug() )
210 {
[3]211 return;
212 }
213 bDebugSupportProc=1;
214 }
215 else bDebugSupportProc=0;
216
[584]217 compiler.StartProcedureCompile( pUserProc );
[89]218
[643]219 if(pUserProc->IsAutoGenerationSystem()){
[3]220 ////////////////////
221 // 特殊関数
222 ////////////////////
223
224 extern int AllLocalVarSize;
225 AllLocalVarSize=0;
226
227 //スタックフレーム管理用オブジェクトを初期化
[308]228 extern StackFrame *pobj_sf;
229 pobj_sf=new StackFrame();
[3]230
[86]231 SystemProc(*pUserProc);
[3]232
233 //スタックフレーム管理用オブジェクトを破棄
234 delete pobj_sf;
235 pobj_sf=0;
236
237 return;
238 }
239
[353]240 if( !pUserProc->IsAutoGeneration() )
241 {
[643]242 // 対象のソースコードを含むオブジェクトモジュールのインデックスを指定する
243 // ※テンプレート展開がされている場合、対象のソースコードが現在のオブジェクトモジュールではない場合がある
244 compiler.SetCurrentRelationalObjectModuleIndexForSource( pUserProc->GetSourceCodePosition().GetRelationalObjectModuleIndex() );
245 basbuf = const_cast<char *>(compiler.GetCurrentSource().GetBuffer());
246
[633]247 cp=pUserProc->GetSourceCodePosition().GetPos();
[353]248 for(;;cp++){
249 if(IsCommandDelimitation(basbuf[cp])) break;
250 }
251 cp--;
[3]252 }
253
254 //プロシージャ抜け出しスケジュール(Exit Sub/Function)
[254]255 compiler.codeGenerator.exitSubCodePositions.clear();
[3]256
257 //ラベル用のメモリを確保
[262]258 compiler.codeGenerator.gotoLabels.clear();
[3]259
260 //Gotoラベルスケジュール
[254]261 compiler.codeGenerator.gotoLabelSchedules.clear();
[3]262
[685]263 //With情報を初期化
264 extern WithInfos withInfos;
265 withInfos.clear();
[3]266
267 //Continueアドレスを初期化
[242]268 compiler.codeGenerator.ClearContinueArea();
[3]269
270 //ローカル変数に関する情報
271 extern int AllLocalVarSize;
272 AllLocalVarSize=0;
273
274 //レキシカルスコープ情報を初期化
[308]275 compiler.codeGenerator.lexicalScopes.Init( compiler.codeGenerator.GetNativeCodeSize() );
[3]276
277
278 /////////////////////////////////////
279 // パラメータ用の変数データを考慮
280 /////////////////////////////////////
281
[75]282 //パラメータ用の変数データを考慮
283 for(i3=(int)pUserProc->RealParams().size()-1;i3>=0;i3--){
284 Parameter &param = *pUserProc->RealParams()[i3];
[3]285
[584]286 Variable *pVar = new Variable(
287 ActiveBasic::Compiler::LexicalAnalyzer::FullNameToSymbol( param.GetVarName().c_str() ),
288 param,
289 false,
290 param.IsRef(),
291 "",
292 false
293 );
[3]294
[75]295 if( param.IsArray() ){
[206]296 pVar->SetArray( param.GetSubscripts() );
[3]297 }
298
[75]299 int varSize;
300 if( param.IsRef() == false && param.IsStruct() ){
[64]301 //構造体のByValパラメータ
[677]302 pVar->ThisIsByValStructParameter();
[75]303 varSize=PTR_SIZE;
[3]304 }
305 else{
[75]306 if( param.IsArray() == false ){
307 varSize = pVar->GetMemorySize();
[3]308 }
309 else{
[75]310 varSize=PTR_SIZE;
[3]311 }
312 }
[75]313 AllLocalVarSize+=varSize;
[206]314 pVar->SetOffsetAddress( AllLocalVarSize );
[3]315
316 //レキシカルスコープ情報
[254]317 pVar->SetScopeLevel( compiler.codeGenerator.lexicalScopes.GetNowLevel() );
318 pVar->SetScopeStartAddress( compiler.codeGenerator.lexicalScopes.GetStartAddress() );
[392]319 pVar->isLiving = true;
[3]320
[206]321 pUserProc->GetLocalVars().push_back( pVar );
[3]322 }
323
324 //Thisポインタを示すローカルオフセット値をセット
325 extern int LocalVar_ThisPtrOffset;
326 LocalVar_ThisPtrOffset=AllLocalVarSize;
327
328 //スタックフレーム管理用クラスを初期化
[308]329 extern StackFrame *pobj_sf;
330 pobj_sf=new StackFrame();
[3]331
332
333 ///////////////////////
334 // ここからコード生成
335
[75]336 for(i3=(int)pUserProc->RealParams().size()-1;i3>=0;i3--){
337 Parameter &param = *pUserProc->RealParams()[i3];
[3]338 if(i3==3){
[75]339 if(param.IsReal()&&param.IsRef() == false){
[3]340 //movsd qword ptr[rsp+0x20],xmm3
[226]341 compiler.codeGenerator.op_movsd_MR(REG_XMM3,REG_RSP,0x20,MOD_BASE_DISP32);
[3]342 }
343 else{
344 //mov qword ptr[rsp+0x20],r9
[226]345 compiler.codeGenerator.op_mov_MR(sizeof(_int64),REG_R9,REG_RSP,0x20,MOD_BASE_DISP32);
[3]346 }
347 }
348 if(i3==2){
[75]349 if(param.IsReal()&&param.IsRef() == false){
[3]350 //movsd qword ptr[rsp+0x18],xmm2
[226]351 compiler.codeGenerator.op_movsd_MR(REG_XMM2,REG_RSP,0x18,MOD_BASE_DISP32);
[3]352 }
353 else{
354 //mov qword ptr[rsp+0x18],r8
[226]355 compiler.codeGenerator.op_mov_MR(sizeof(_int64),REG_R8,REG_RSP,0x18,MOD_BASE_DISP32);
[3]356 }
357 }
358 if(i3==1){
[75]359 if(param.IsReal()&&param.IsRef() == false){
[3]360 //movsd qword ptr[rsp+0x10],xmm1
[226]361 compiler.codeGenerator.op_movsd_MR(REG_XMM1,REG_RSP,0x10,MOD_BASE_DISP32);
[3]362 }
363 else{
364 //mov qword ptr[rsp+0x10],rdx
[226]365 compiler.codeGenerator.op_mov_MR(sizeof(_int64),REG_RDX,REG_RSP,0x10,MOD_BASE_DISP32);
[3]366 }
367 }
368 if(i3==0){
[75]369 if(param.IsReal()&&param.IsRef() == false){
[3]370 //movsd qword ptr[rsp+0x8],xmm0
[226]371 compiler.codeGenerator.op_movsd_MR(REG_XMM0,REG_RSP,0x8,MOD_BASE_DISP32);
[3]372 }
373 else{
374 //mov qword ptr[rsp+0x8],rcx
[226]375 compiler.codeGenerator.op_mov_MR(sizeof(_int64),REG_RCX,REG_RSP,0x8,MOD_BASE_DISP32);
[3]376 }
377 }
378 }
379
380 //ret用のアドレスを考慮
381 AllLocalVarSize+=sizeof(_int64);
382
383 //sub rsp,スタックフレームサイズ
[255]384 const PertialSchedule *pStackFramePertialSchedule = compiler.codeGenerator.op_sub_rsp( 0, true );
[3]385
386 //mov qword ptr[rsp+offset],reg ※スタックフレームを利用
387 pobj_sf->push(REG_RBX);
388 pobj_sf->push(REG_RSI);
389 pobj_sf->push(REG_RDI);
390 pobj_sf->push(REG_R12);
391 pobj_sf->push(REG_R13);
392 pobj_sf->push(REG_R14);
393 pobj_sf->push(REG_R15);
394
395 //ローカル変数のベース値
396 int BaseLocalVar;
397 BaseLocalVar=AllLocalVarSize;
398
[75]399 if( !pUserProc->ReturnType().IsNull() ){
[3]400 //戻り値が存在するとき
401
[75]402 const char *temp = pUserProc->GetName().c_str();
403 if( temp[0]==1&&temp[1]==ESC_OPERATOR ){
404 temp = "_System_ReturnValue";
405 }
[3]406
[75]407 if( pUserProc->ReturnType().IsStruct() ){
[64]408 //戻り値用の構造体(値型)はパラメータで引き渡される
[3]409 }
410 else{
[89]411 if( pUserProc->ReturnType().IsObject() ){
[308]412 sprintf(temporary,"%s=Nothing%c%c%s",temp,1,ESC_AS, compiler.TypeToString( pUserProc->ReturnType() ).c_str() );
[89]413 }
414 else{
415 //戻り値用の変数の定義
[308]416 sprintf(temporary,"%s%c%c%s",temp,1,ESC_AS, compiler.TypeToString( pUserProc->ReturnType() ).c_str() );
[89]417 }
[40]418
[3]419 OpcodeDim(temporary,0);
420 }
421 }
422
[255]423 const PertialSchedule *pRspOffsetPertialSchedule1 = NULL;
424 const PertialSchedule *pRspOffsetPertialSchedule2 = NULL;
[460]425 if( compiler.IsDebug() && bDebugSupportProc == 0 )
426 {
[3]427 //mov rdx, qword ptr[rsp+スタックフレームサイズ]
[255]428 pRspOffsetPertialSchedule1 = compiler.codeGenerator.op_mov_RM(sizeof(_int64),REG_RDX,REG_RSP,0,MOD_BASE_DISP32, Schedule::None, true );
[3]429
430 //mov rcx,rsp
[226]431 compiler.codeGenerator.op_mov_RR(REG_RCX,REG_RSP);
[3]432
433 //add rcx,スタックフレームサイズ+sizeof(_int64) ※ret用のサイズを考慮
[255]434 pRspOffsetPertialSchedule2 = compiler.codeGenerator.op_add_RV(REG_RCX,0, Schedule::None, true );
[3]435
436 //call _DebugSys_StartProc
[206]437 extern const UserProc *pSub_DebugSys_StartProc;
[226]438 compiler.codeGenerator.op_call(pSub_DebugSys_StartProc);
[3]439 }
440
[584]441 if( compiler.IsCompilingClass() ){
442 if( pUserProc->GetName() == compiler.GetCompilingClass().GetName() ){
[3]443 ////////////////////////////////////
444 // コンストラクタをコンパイルするとき
445 ////////////////////////////////////
446
[17]447 //コンストラクタのコンパイル開始を通知
[584]448 compiler.GetCompilingClass().NotifyStartConstructorCompile();
[17]449
[704]450 if( compiler.GetCompilingClass().HasSuperClass() )
451 {
[3]452 /* サブクラスコンストラクタをコンパイルしているときは、
[27]453 基底クラスのコンストラクタを呼び出す */
[3]454
455 i3=cp+1;
456 while(IsCommandDelimitation(basbuf[i3])) i3++;
457 for(i4=0;;i3++,i4++){
458 if(!IsVariableChar(basbuf[i3])){
459 temporary[i4]=0;
460 break;
461 }
462 temporary[i4]=basbuf[i3];
463 }
[584]464 if( compiler.GetCompilingClass().GetSuperClass().GetName() == temporary ){
[27]465 //基底クラスのコンストラクタを呼び出す
[3]466 cp=i3;
467 for(i4=0;;cp++,i4++){
468 if(IsCommandDelimitation(basbuf[cp])){
469 temporary[i4]=0;
470 break;
471 }
472 temporary[i4]=basbuf[cp];
473 }
474 if(!(temporary[0]=='('&&temporary[lstrlen(temporary)-1]==')')){
[468]475 compiler.errorMessenger.Output(1,NULL,cp);
[3]476 }
477 RemoveStringPare(temporary);
478
[704]479
480 ////////////////////////
481 // オーバーロードを解決
482 ////////////////////////
483
484 std::vector<const UserProc *> subs;
485 compiler.GetCompilingClass().GetSuperClass().GetDynamicMethods().Enum( compiler.GetCompilingClass().GetSuperClass().GetName().c_str(), subs );
486
487 const UserProc *pUserProc = NULL;
488 if( subs.size() > 0 )
489 {
490 //オーバーロードを解決
491 pUserProc=OverloadSolutionWithStrParam( compiler.GetCompilingClass().GetSuperClass().GetName().c_str(),
492 subs,temporary,"");
493 }
494 if( !pUserProc )
495 {
496 compiler.errorMessenger.Output(1,NULL,cp);
497 }
498 else
499 {
500 Type dummyType;
501 CallProc( PROC_DEFAULT
502 , pUserProc
503 , pUserProc->GetName().c_str()
504 , temporary
505 , Type() // baseTypeはなし
506 , dummyType
507 , true
508 , PROCFLAG_PERMIT_CONSTRUCTOR
509 );
510 }
[3]511 }
512 else{
[704]513 if( compiler.GetCompilingClass().GetSuperClass().GetConstructorMethod() != NULL )
514 {
515 // 基底クラスがデフォルトコンストラクタを保有するとき
516
517 // 基底クラスのコンストラクタを暗黙的に呼び出す
518 Opcode_CallProc("",
519 &compiler.GetCompilingClass().GetSuperClass().GetConstructorMethod()->GetUserProc(),
520 PROCFLAG_PERMIT_CONSTRUCTOR,
521 ""
522 );
523 }
[3]524 }
525 }
526 }
[75]527 else if( pUserProc->IsDestructor() ){
[18]528 //デストラクタをコンパイルしたとき
529
530 //デストラクタのコンパイル開始を通知
[584]531 compiler.GetCompilingClass().NotifyStartDestructorCompile();
[18]532 }
[3]533 }
534
535 //////////////////////////////////////////
536 //////////////////////////////////////////
537 ////// プロシージャ内をコンパイル ////////
[90]538 if( pUserProc->IsAutoGeneration() ){
539 AutoGeneration( *pUserProc );
540 }
[75]541 else{
[90]542 if(pUserProc->IsMacro()){
543 CompileBuffer(ESC_ENDMACRO,0);
544 }
545 else{
546 if(pUserProc->IsSub()){
547 CompileBuffer(ESC_ENDSUB,0);
548 }
549 else if(pUserProc->IsFunction()){
550 CompileBuffer(ESC_ENDFUNCTION,0);
551 }
552 }
[75]553 }
[3]554 //////////////////////////////////////////
555 //////////////////////////////////////////
556
[584]557 if( compiler.IsCompilingClass() ){
[17]558
[584]559 if( compiler.GetCompilingClass().IsCompilingConstructor() ){
[17]560 // コンストラクタをコンパイルしていたとき
[18]561
[17]562 // コンストラクタのコンパイルが完了したことを通知
[584]563 compiler.GetCompilingClass().NotifyFinishConstructorCompile();
[17]564 }
[75]565 else if( pUserProc->IsDestructor() ){
[3]566 ////////////////////////////////////
567 //デストラクタをコンパイルしたとき
568 ////////////////////////////////////
569
[18]570 // デストラクタのコンパイルが完了したことを通知
[584]571 compiler.GetCompilingClass().NotifyFinishDestructorCompile();
[18]572
[584]573 if( compiler.GetCompilingClass().HasSuperClass() ){
[3]574 /* サブクラスのデストラクタをコンパイルしているときは、
[27]575 基底クラスのデストラクタを呼び出す */
[3]576
[584]577 const CMethod *method = compiler.GetCompilingClass().GetSuperClass().GetDestructorMethod();
[51]578 if( method ){
[3]579 Opcode_CallProc("",
[206]580 &method->GetUserProc(),
[704]581 PROCFLAG_PERMIT_DESTRUCTOR,
[308]582 "");
[3]583 }
584 }
585 }
586 }
587
[366]588 // Tryスコープの検証
589 Exception::InspectTryScope();
590
[3]591 //ローカルオブジェクト(レキシカルスコープレベル=0)の解放処理
[254]592 compiler.codeGenerator.lexicalScopes.CallDestructorsOfScopeEnd();
[3]593
[34]594 //プロシージャ抜け出しスケジュール(Exit Sub/Function)
[254]595 compiler.codeGenerator.ResolveExitSubSchedule();
[34]596
[460]597 if( compiler.IsDebug() && bDebugSupportProc == 0 )
598 {
[34]599 //call _DebugSys_EndProc
[206]600 extern const UserProc *pSub_DebugSys_EndProc;
[226]601 compiler.codeGenerator.op_call(pSub_DebugSys_EndProc);
[34]602 }
603
[75]604 if( !pUserProc->ReturnType().IsNull() ){
[3]605 //////////////////////////////////
606 // 戻り値をraxまたはxmm0に設定
607 //////////////////////////////////
608
609 RELATIVE_VAR RelativeVar;
610
[75]611 const char *temp = pUserProc->GetName().c_str();
612 if( temp[0]==1 && temp[1]==ESC_OPERATOR ){
[3]613 temp="_System_ReturnValue";
[75]614 }
615 GetVarOffsetReadWrite(temp,&RelativeVar,Type());
[3]616
[316]617 const Type &returnType = pUserProc->ReturnType();
618 if( returnType.IsObject() || returnType.IsStruct() )
619 {
[3]620 SetVarPtrToReg(REG_RAX,&RelativeVar);
[316]621 if( returnType.IsObject() )
622 {
[64]623 //mov rax,qword ptr[rax]
[226]624 compiler.codeGenerator.op_mov_RM( sizeof(_int64), REG_RAX, REG_RAX, 0, MOD_BASE );
[64]625 }
[3]626 }
[316]627 else if( returnType.IsDouble() )
628 {
[3]629 //64ビット実数型
630 SetXmmReg_DoubleVariable(&RelativeVar,REG_XMM0);
631 }
[316]632 else if( returnType.IsSingle() )
633 {
[3]634 //32ビット実数型
635 SetXmmReg_SingleVariable(&RelativeVar,REG_XMM0);
636 }
[316]637 else if( returnType.IsWhole() )
638 {
[3]639 //整数型
[318]640 SetReg_WholeVariable(returnType,&RelativeVar,REG_RAX);
[3]641 }
[468]642 else compiler.errorMessenger.Output(300,NULL,cp);
[3]643 }
644
645 //ローカル変数領域のサイズをスタックフレームに通知
[220]646 int localParmSize = AllLocalVarSize - BaseLocalVar;
[232]647 int stackFrameSize = pobj_sf->GetFrameSize( localParmSize );
[3]648
649 //ローカル変数アドレススケジュール
[768]650 foreach( const PertialSchedule *pPertialSchedule, compiler.codeGenerator.localVarPertialSchedules )
[254]651 {
[255]652 compiler.codeGenerator.opfix_offset( pPertialSchedule, AllLocalVarSize + stackFrameSize );
[3]653 }
[254]654 compiler.codeGenerator.localVarPertialSchedules.clear();
[768]655 foreach( Variable *pVar, pUserProc->GetLocalVars() ){
[3]656 //後にデバッグで利用する
[206]657 pVar->SetOffsetAddress(
[220]658 AllLocalVarSize + stackFrameSize - pVar->GetOffsetAddress()
[206]659 );
[3]660 }
661
662 //mov reg,qword ptr[rsp+offset] ※スタックフレームを利用
663 pobj_sf->pop(REG_R15);
664 pobj_sf->pop(REG_R14);
665 pobj_sf->pop(REG_R13);
666 pobj_sf->pop(REG_R12);
667 pobj_sf->pop(REG_RDI);
668 pobj_sf->pop(REG_RSI);
669 pobj_sf->pop(REG_RBX);
670
[220]671 int stackFrameAndLocalParamSize = localParmSize + stackFrameSize;
[3]672
673 //add rsp,スタックフレームサイズ
[226]674 compiler.codeGenerator.op_add_rsp(stackFrameAndLocalParamSize);
[3]675
[142]676 //ret
[226]677 compiler.codeGenerator.op_ret();
[3]678
679
680 //デバッグ用
[255]681 if( pRspOffsetPertialSchedule1 ){
682 compiler.codeGenerator.opfix( pRspOffsetPertialSchedule1, stackFrameAndLocalParamSize );
683 compiler.codeGenerator.opfix( pRspOffsetPertialSchedule2, stackFrameAndLocalParamSize + sizeof(_int64) );
[3]684 }
685
686
687 //スタックフレームスケジュール(subコマンド)
[255]688 compiler.codeGenerator.opfix( pStackFramePertialSchedule, stackFrameAndLocalParamSize );
[3]689
690 //スタックフレームスケジュールを実行
[220]691 pobj_sf->RunningSchedule( stackFrameSize );
[3]692 delete pobj_sf;
693 pobj_sf=0;
694
695
[584]696 compiler.FinishProcedureCompile();
697
698
699 //ローカル変数のネーム情報は後に解放する
[3]700}
Note: See TracBrowser for help on using the repository browser.