#include "stdafx.h" #include "Opcode.h" void SystemProc( const UserProc &userProc ){ if( userProc.GetName() == "_System_GetEip" ){ //mov eax,dword ptr[esp] compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EAX, REG_ESP, 0, MOD_BASE ); //ret compiler.codeGenerator.op_ret(); } else if( userProc.GetName() == "_System_InitDllGlobalVariables" ){ //////////////////////////////////////// // DLLのグローバル領域をコンパイル //////////////////////////////////////// if( !compiler.IsDll() ){ //ret compiler.codeGenerator.op_ret(); return; } const UserProc *pBackUserProc; pBackUserProc = &compiler.GetCompilingUserProc(); compiler.StartGlobalAreaCompile(); int BackCp; BackCp=cp; cp=-1; if( compiler.IsDebug() ) { //デバッグ用の変数を定義 DebugVariable(); } //GC用の変数を定義 InitGCVariables(); //_System_StartupProgramの呼び出し extern const UserProc *pSub_System_StartupProgram; compiler.codeGenerator.op_call(pSub_System_StartupProgram); //クラスに属する静的メンバを定義 ActiveBasic::Compiler::ProcedureGenerator::Generate_InitStaticMember( compiler.GetObjectModule().meta.GetClasses() ); GetGlobalDataForDll(); compiler.SetCompilingUserProc( pBackUserProc ); cp=BackCp; //ret compiler.codeGenerator.op_ret(); } else if( userProc.GetName() == "_System_InitStaticLocalVariables" ){ //静的ローカルオブジェクトのコンストラクタ呼び出し BOOST_FOREACH( Variable *pVar, compiler.GetObjectModule().meta.GetGlobalVars() ){ if(memicmp(pVar->GetName().c_str(),"Static%",7)==0){ //コンストラクタ呼び出し if( pVar->GetType().IsObject() ){ //エラー用 cp=pVar->source_code_address; CallConstructor( pVar->GetName().c_str(), pVar->GetSubscripts(), pVar->GetType(), pVar->GetParamStrForConstructor().c_str()); } } } //ret compiler.codeGenerator.op_ret(); } else if( userProc.GetName() == "_System_Call_Destructor_of_GlobalObject" ){ const UserProc *pBackUserProc; pBackUserProc = &compiler.GetCompilingUserProc(); compiler.StartGlobalAreaCompile(); compiler.codeGenerator.lexicalScopes.CallDestructorsOfScopeEnd(); compiler.SetCompilingUserProc( pBackUserProc ); //ret compiler.codeGenerator.op_ret(); } else if( userProc.GetName() == "_allrem" ){ //乗除演算用の特殊関数(64ビット整数対応) BYTE Buffer_allrem[]={ 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 }; compiler.codeGenerator.PutOld( NativeCode( (const char *)Buffer_allrem, 178 ) ); } else if( userProc.GetName() == "_aullrem" ){ //乗除演算用の特殊関数(64ビット整数対応) BYTE Buffer_aullrem[]={ 0x53,0x8B,0x44,0x24,0x14,0x0B,0xC0,0x75,0x18,0x8B,0x4C,0x24,0x10,0x8B, 0x44,0x24,0x0C,0x33,0xD2,0xF7,0xF1,0x8B,0x44,0x24,0x08,0xF7,0xF1,0x8B, 0xC2,0x33,0xD2,0xEB,0x50,0x8B,0xC8,0x8B,0x5C,0x24,0x10,0x8B,0x54,0x24, 0x0C,0x8B,0x44,0x24,0x08,0xD1,0xE9,0xD1,0xDB,0xD1,0xEA,0xD1,0xD8,0x0B, 0xC9,0x75,0xF4,0xF7,0xF3,0x8B,0xC8,0xF7,0x64,0x24,0x14,0x91,0xF7,0x64, 0x24,0x10,0x03,0xD1,0x72,0x0E,0x3B,0x54,0x24,0x0C,0x77,0x08,0x72,0x0E, 0x3B,0x44,0x24,0x08,0x76,0x08,0x2B,0x44,0x24,0x10,0x1B,0x54,0x24,0x14, 0x2B,0x44,0x24,0x08,0x1B,0x54,0x24,0x0C,0xF7,0xDA,0xF7,0xD8,0x83,0xDA, 0x00,0x5B,0xC2,0x10,0x00 }; compiler.codeGenerator.PutOld( NativeCode( (const char *)Buffer_aullrem, 117 ) ); } else if( userProc.GetName() == "_allmul" ){ //乗算用の特殊関数(64ビット整数対応) BYTE Buffer_allmul[]={ 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 }; compiler.codeGenerator.PutOld( NativeCode( (const char *)Buffer_allmul, 52 ) ); } else if( userProc.GetName() == "_alldiv" ){ //除算用の特殊関数(64ビット整数対応) BYTE Buffer_alldiv[]={ 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 }; compiler.codeGenerator.PutOld( NativeCode( (const char *)Buffer_alldiv, 170 ) ); } else if( userProc.GetName() == "_aulldiv" ){ //整数除算用の特殊関数(64ビット整数対応) BYTE Buffer_aulldiv[]={ 0x53,0x56,0x8B,0x44,0x24,0x18,0x0B,0xC0,0x75,0x18,0x8B,0x4C,0x24,0x14, 0x8B,0x44,0x24,0x10,0x33,0xD2,0xF7,0xF1,0x8B,0xD8,0x8B,0x44,0x24,0x0C, 0xF7,0xF1,0x8B,0xD3,0xEB,0x41,0x8B,0xC8,0x8B,0x5C,0x24,0x14,0x8B,0x54, 0x24,0x10,0x8B,0x44,0x24,0x0C,0xD1,0xE9,0xD1,0xDB,0xD1,0xEA,0xD1,0xD8, 0x0B,0xC9,0x75,0xF4,0xF7,0xF3,0x8B,0xF0,0xF7,0x64,0x24,0x18,0x8B,0xC8, 0x8B,0x44,0x24,0x14,0xF7,0xE6,0x03,0xD1,0x72,0x0E,0x3B,0x54,0x24,0x10, 0x77,0x08,0x72,0x07,0x3B,0x44,0x24,0x0C,0x76,0x01,0x4E,0x33,0xD2,0x8B, 0xC6,0x5E,0x5B,0xC2,0x10,0x00 }; compiler.codeGenerator.PutOld( NativeCode( (const char *)Buffer_aulldiv, 104 ) ); } else if( userProc.GetName() == "_allshl" ){ //符号あり左ビットシフト用の特殊関数(64ビット整数対応) BYTE Buffer_allshl[]={ 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 }; compiler.codeGenerator.PutOld( NativeCode( (const char *)Buffer_allshl, 31 ) ); } else if( userProc.GetName() == "_allshr" ){ //符号あり右ビットシフト用の特殊関数(64ビット整数対応) BYTE Buffer_allshr[]={ 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 }; compiler.codeGenerator.PutOld( NativeCode( (const char *)Buffer_allshr, 33 ) ); } else if( userProc.GetName() == "_aullshr" ){ //符号なし右ビットシフト用の特殊関数(64ビット整数対応) BYTE Buffer_aullshr[]={ 0x80,0xF9,0x40, //cmp cl,40h 0x73,0x15, //jae RETZERO (0040d71a) 0x80,0xF9,0x20, //cmp cl,20h 0x73,0x06, //jae MORE32 (0040d710) 0x0F,0xAD,0xD0, //shrd eax,edx,cl 0xD3,0xEA, //shr edx,cl 0xC3, //ret //MORE32: 0x8B,0xC2, //mov eax,edx 0x33,0xD2, //xor edx,edx 0x80,0xE1,0x1F, //and cl,1Fh 0xD3,0xE8, //shr eax,cl 0xC3, //ret //RETZERO: 0x33,0xC0, //xor eax,eax 0x33,0xD2, //xor edx,edx 0xC3 //ret }; compiler.codeGenerator.PutOld( NativeCode( (const char *)Buffer_aullshr, 31 ) ); } else{ compiler.errorMessenger.OutputFatalError(); } } void AutoGeneration( const UserProc &userProc){ if( userProc.GetName() == "InitializeUserTypes" && userProc.HasParentClass() && userProc.GetParentClass().GetName() == "_System_TypeBase" ) { ActiveBasic::Compiler::ProcedureGenerator::Generate_System_InitializeUserTypes( compiler.GetObjectModule().meta.GetClasses() ); } else if( userProc.GetName() == "InitializeUserTypesForBaseType" && userProc.HasParentClass() && userProc.GetParentClass().GetName() == "_System_TypeBase" ) { ActiveBasic::Compiler::ProcedureGenerator::Generate_System_InitializeUserTypesForBaseType( compiler.GetObjectModule().meta.GetClasses() ); } else if( userProc.GetName() == "RegisterGlobalRoots" && userProc.HasParentClass() && userProc.GetParentClass().GetName() == "_System_CGarbageCollection" ){ Compile_AddGlobalRootsForGc(); } else if( userProc.GetName() == compiler.globalAreaProcName ){ //////////////////////////////////////// // グローバル領域をコンパイル //////////////////////////////////////// UserProc::pGlobalProc = &userProc; const UserProc *pBackUserProc = &compiler.GetCompilingUserProc(); compiler.StartGlobalAreaCompile(); int BackCp = cp; cp=-1; //クラスに属する静的メンバを定義 ActiveBasic::Compiler::ProcedureGenerator::Generate_InitStaticMember( compiler.GetObjectModule().meta.GetClasses() ); //グローバル実行領域をコンパイル開始 CompileBuffer(0,0); //Goto未知ラベルスケジュールが存在したらエラーにする BOOST_FOREACH( const GotoLabelSchedule *pGotoLabelSchedule, compiler.codeGenerator.gotoLabelSchedules ) { if(pGotoLabelSchedule->GetName().size()>0){ compiler.errorMessenger.Output(6,pGotoLabelSchedule->GetName(),pGotoLabelSchedule->GetSourceCodePos()); } else{ char temporary[255]; sprintf(temporary,"%d",pGotoLabelSchedule->GetLineNum()); compiler.errorMessenger.Output(6,temporary,pGotoLabelSchedule->GetSourceCodePos()); } } compiler.SetCompilingUserProc( pBackUserProc ); cp=BackCp; } else if( userProc.HasParentClass() && userProc.IsCastOperator() && userProc.ReturnType().IsInterface() ) { // インターフェイス型にキャストするためのメソッド int vtblMasterListIndex = userProc.GetParentClass().GetVtblMasterListIndex( &userProc.ReturnType().GetClass() ); char temporary[1024]; sprintf( temporary, "Return New %s(ObjPtr( This ),Get_LONG_PTR( (Get_LONG_PTR( ObjPtr(This)+SizeOf(VoidPtr) ) + SizeOf(LONG_PTR)*%d) As VoidPtr ) As VoidPtr )", userProc.ReturnType().GetClass().GetName().c_str(), vtblMasterListIndex ); MakeMiddleCode( temporary ); ChangeOpcode( temporary ); } else{ compiler.errorMessenger.OutputFatalError(); } } void _compile_proc(const UserProc *pUserProc) { extern char *basbuf; extern HANDLE hHeap; int i3,i4,BaseOffset; char temporary[VN_SIZE]; if( pUserProc->GetLocalVars().size() ){ compiler.errorMessenger.OutputFatalError(); return; } trace_for_sourcecodestep( "★★★ " << pUserProc->GetFullName() << "のコンパイルを開始" ); pUserProc->CompleteCompile(); extern BOOL bSystemProc; if(memcmp(pUserProc->GetName().c_str(),"_System_",8)==0) bSystemProc=1; else bSystemProc=0; extern BOOL bDebugSupportProc; if(memcmp(pUserProc->GetName().c_str(),"_DebugSys_",10)==0) { if( !compiler.IsDebug() ) { return; } bDebugSupportProc=1; } else bDebugSupportProc=0; if( pUserProc->GetCodeSize() != 0 || pUserProc->GetNativeCode().GetSize() != 0 ) { // 既にコード生成が行われている場合はエラー compiler.errorMessenger.OutputFatalError(); } compiler.StartProcedureCompile( pUserProc ); if(pUserProc->IsSystem()){ //////////////////// // 特殊関数 //////////////////// extern int AllLocalVarSize; AllLocalVarSize=0; SystemProc(*pUserProc); return; } if( !pUserProc->IsAutoGeneration() ) { cp=pUserProc->GetCodePos(); for(;;cp++){ if(IsCommandDelimitation(basbuf[cp])) break; } cp--; } //ローカル変数に関する情報 extern int AllLocalVarSize; AllLocalVarSize=0; //パラメータ用の変数データを考慮 for(i3=(int)pUserProc->RealParams().size()-1;i3>=0;i3--){ Parameter ¶m = *pUserProc->RealParams()[i3]; Variable *pVar = new Variable( ActiveBasic::Compiler::LexicalAnalyzer::FullNameToSymbol( param.GetVarName().c_str() ), param, false, param.IsRef(), "", false ); if( param.IsArray() ){ pVar->SetArray( param.GetSubscripts() ); } int varSize; if( param.IsRef() == false && param.IsStruct() ){ //構造体のByValパラメータ pVar->ThisIsParameter(); varSize=PTR_SIZE; } else{ if( param.IsArray() == false ){ varSize = pVar->GetMemorySize(); } else{ varSize=PTR_SIZE; } } AllLocalVarSize+=varSize; pVar->SetOffsetAddress( AllLocalVarSize ); //レキシカルスコープ情報 pVar->SetScopeLevel( compiler.codeGenerator.lexicalScopes.GetNowLevel() ); pVar->SetScopeStartAddress( compiler.codeGenerator.lexicalScopes.GetStartAddress() ); pVar->isLiving = true; pUserProc->GetLocalVars().push_back( pVar ); } //Thisポインタを示すローカルオフセット値をセット extern int LocalVar_ThisPtrOffset; LocalVar_ThisPtrOffset=AllLocalVarSize; BaseOffset=AllLocalVarSize; //ret用のアドレスを考慮 AllLocalVarSize+=sizeof(long); /////////////////////// // ここからコード生成 //sub esp,AllLocalVarSize(スケジュール) const PertialSchedule *pAllLocalVarPertialSchedule = compiler.codeGenerator.op_sub_esp( 0, true ); //push ebp compiler.codeGenerator.op_push(REG_EBP); //mov ebp,esp compiler.codeGenerator.op_mov_RR( REG_EBP, REG_ESP ); //push ebx compiler.codeGenerator.op_push(REG_EBX); //push esi compiler.codeGenerator.op_push( REG_ESI ); //push edi compiler.codeGenerator.op_push( REG_EDI ); if( !pUserProc->ReturnType().IsNull() ){ //戻り値が存在するとき const char *temp = pUserProc->GetName().c_str(); if( temp[0]==1&&temp[1]==ESC_OPERATOR ){ temp = "_System_ReturnValue"; } if( pUserProc->ReturnType().IsStruct() ){ //戻り値用の構造体(値型)はパラメータで引き渡される } else{ if( pUserProc->ReturnType().IsObject() ){ sprintf(temporary,"%s=Nothing%c%c%s",temp,1,ESC_AS, compiler.TypeToString( pUserProc->ReturnType() ).c_str() ); } else{ //戻り値用の変数の定義 sprintf(temporary,"%s%c%c%s",temp,1,ESC_AS, compiler.TypeToString( pUserProc->ReturnType() ).c_str() ); } OpcodeDim(temporary,0); } } //プロシージャ抜け出しスケジュール(Exit Sub/Function) compiler.codeGenerator.exitSubCodePositions.clear(); //ラベル管理オブジェクトを初期化 compiler.codeGenerator.gotoLabels.clear(); //Gotoラベルスケジュール compiler.codeGenerator.gotoLabelSchedules.clear(); //With情報のメモリを確保 extern WITHINFO WithInfo; WithInfo.ppName=(char **)HeapAlloc(hHeap,0,1); WithInfo.pWithCp=(int *)HeapAlloc(hHeap,0,1); WithInfo.num=0; // 重複エラー情報をクリア compiler.errorMessenger.ClearSynonymKeyWords(); //Continueアドレスを初期化 compiler.codeGenerator.ClearContinueArea(); //レキシカルスコープ情報を初期化 compiler.codeGenerator.lexicalScopes.Init( compiler.codeGenerator.GetNativeCodeSize() ); const PertialSchedule *pEspOffsetPertialSchedule = NULL; if( compiler.IsDebug() && bDebugSupportProc == 0 ) { //push dword ptr[ebp+(AllLocalVarSize-BaseOffset)](スケジュール) pEspOffsetPertialSchedule = compiler.codeGenerator.op_push_M( REG_EBP, 0, Schedule::None, true ); //push dword ptr[ebp](以前のebp) compiler.codeGenerator.op_push_M( REG_EBP ); //call _DebugSys_StartProc extern const UserProc *pSub_DebugSys_StartProc; compiler.codeGenerator.op_call(pSub_DebugSys_StartProc); } if( compiler.IsCompilingClass() ){ if( pUserProc->GetName() == compiler.GetCompilingClass().GetName() ){ //////////////////////////////////// // コンストラクタをコンパイルするとき //////////////////////////////////// //コンストラクタのコンパイル開始を通知 compiler.GetCompilingClass().NotifyStartConstructorCompile(); //基底クラスかどうかの識別 //(継承元がインターフェイスの場合も基底クラスと見なす) BOOL bThisIsSuperClass; if( !compiler.GetCompilingClass().HasSuperClass() ) bThisIsSuperClass=1; else if( compiler.GetCompilingClass().GetSuperClass().GetConstructorMethod() == NULL ){ //インターフェイスを継承したときはコンストラクタを持たない bThisIsSuperClass=1; } else bThisIsSuperClass=0; if(!bThisIsSuperClass){ /* サブクラスコンストラクタをコンパイルしているときは、 基底クラスのコンストラクタを呼び出す */ i3=cp+1; while(IsCommandDelimitation(basbuf[i3])) i3++; for(i4=0;;i3++,i4++){ if(!IsVariableChar(basbuf[i3])){ temporary[i4]=0; break; } temporary[i4]=basbuf[i3]; } if( compiler.GetCompilingClass().GetSuperClass().GetName() == temporary ){ //基底クラスのコンストラクタを呼び出す cp=i3; for(i4=0;;cp++,i4++){ if(IsCommandDelimitation(basbuf[cp])){ temporary[i4]=0; break; } temporary[i4]=basbuf[cp]; } if(!(temporary[0]=='('&&temporary[lstrlen(temporary)-1]==')')){ compiler.errorMessenger.Output(1,NULL,cp); } RemoveStringPare(temporary); Type dummyType; CallProc( PROC_DEFAULT , &compiler.GetCompilingClass().GetSuperClass().GetConstructorMethod()->GetUserProc() , compiler.GetCompilingClass().GetSuperClass().GetConstructorMethod()->GetUserProc().GetName().c_str() , temporary , Type() // baseTypeはなし , dummyType ); } else{ //基底クラスのコンストラクタを暗黙的に呼び出す Opcode_CallProc("", &compiler.GetCompilingClass().GetSuperClass().GetConstructorMethod()->GetUserProc(), 0, "" ); } } } else if( pUserProc->IsDestructor() ){ //デストラクタをコンパイルしたとき //デストラクタのコンパイル開始を通知 compiler.GetCompilingClass().NotifyStartDestructorCompile(); } } ////////////////////////////////////////// ////////////////////////////////////////// ////// プロシージャ内をコンパイル //////// if( pUserProc->IsAutoGeneration() ){ AutoGeneration( *pUserProc ); } else{ if(pUserProc->IsMacro()){ CompileBuffer(ESC_ENDMACRO,0); } else{ if(pUserProc->IsSub()){ CompileBuffer(ESC_ENDSUB,0); } else if(pUserProc->IsFunction()){ CompileBuffer(ESC_ENDFUNCTION,0); } } } ////////////////////////////////////////// ////////////////////////////////////////// if( compiler.IsCompilingClass() ){ if( compiler.GetCompilingClass().IsCompilingConstructor() ){ // コンストラクタをコンパイルしていたとき // コンストラクタのコンパイルが完了したことを通知 compiler.GetCompilingClass().NotifyFinishConstructorCompile(); } else if( pUserProc->IsDestructor() ){ //////////////////////////////////// //デストラクタをコンパイルしたとき //////////////////////////////////// // デストラクタのコンパイルが完了したことを通知 compiler.GetCompilingClass().NotifyFinishDestructorCompile(); if( compiler.GetCompilingClass().HasSuperClass() ){ /* サブクラスのデストラクタをコンパイルしているときは、 基底クラスのデストラクタを呼び出す */ const CMethod *method = compiler.GetCompilingClass().GetSuperClass().GetDestructorMethod(); if( method ){ Opcode_CallProc("", &method->GetUserProc(), 0, "" ); } } } } //With情報のメモリを解放 for(i3=0;i3ReturnType().IsNull() ){ //戻り値をeax、edxに設定 RELATIVE_VAR RelativeVar; const char *temp = pUserProc->GetName().c_str(); if( temp[0]==1 && temp[1]==ESC_OPERATOR ){ temp="_System_ReturnValue"; } GetVarOffsetReadWrite(temp,&RelativeVar,Type()); const Type &returnType = pUserProc->ReturnType(); if( returnType.IsObject() || returnType.IsStruct() ) { SetVarPtrToEax(&RelativeVar); if( returnType.IsObject() ) { //mov eax,dword ptr[eax] compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EAX, REG_EAX, 0, MOD_BASE ); } } else if( returnType.IsReal() ) { //fld qword ptr[ebp+offset] compiler.codeGenerator.localVarPertialSchedules.push_back( compiler.codeGenerator.op_fld_base_offset( returnType.GetBasicType(), REG_EBP, RelativeVar.offset, Schedule::None, true ) ); } else if( returnType.Is64() ) { //mov eax,dword ptr[ebp+offset] compiler.codeGenerator.localVarPertialSchedules.push_back( compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EAX, REG_EBP, RelativeVar.offset, MOD_BASE_DISP32, Schedule::None, true ) ); //mov edx,dword ptr[ebp+offset+sizeof(long)] compiler.codeGenerator.localVarPertialSchedules.push_back( compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EDX, REG_EBP, RelativeVar.offset+sizeof(long), MOD_BASE_DISP32, Schedule::None, true ) ); } else if( returnType.GetSize() == sizeof(long) ) { //mov eax,dword ptr[ebp+offset] compiler.codeGenerator.localVarPertialSchedules.push_back( compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EAX, REG_EBP, RelativeVar.offset, MOD_BASE_DISP32, Schedule::None, true ) ); } else if( returnType.GetSize() == sizeof(short) ) { //xor eax,eax(eaxを0に初期化する) compiler.codeGenerator.op_zero_reg(REG_EAX); //mov ax,word ptr[ebp+offset] compiler.codeGenerator.localVarPertialSchedules.push_back( compiler.codeGenerator.op_mov_RM( sizeof(short), REG_EAX, REG_EBP, RelativeVar.offset, MOD_BASE_DISP32, Schedule::None, true ) ); } else if( returnType.GetSize() == sizeof(char) ) { //xor eax,eax(eaxを0に初期化する) compiler.codeGenerator.op_zero_reg(REG_EAX); //mov al,byte ptr[ebp+offset] compiler.codeGenerator.localVarPertialSchedules.push_back( compiler.codeGenerator.op_mov_RM( sizeof(char), REG_EAX, REG_EBP, RelativeVar.offset, MOD_BASE_DISP32, Schedule::None, true ) ); } else { compiler.errorMessenger.OutputFatalError(); } } //ローカル変数アドレススケジュール BOOST_FOREACH( const PertialSchedule *pPertialSchedule, compiler.codeGenerator.localVarPertialSchedules ) { compiler.codeGenerator.opfix_offset( pPertialSchedule, AllLocalVarSize ); } compiler.codeGenerator.localVarPertialSchedules.clear(); BOOST_FOREACH( Variable *pVar, pUserProc->GetLocalVars() ){ //後にデバッグで利用する pVar->SetOffsetAddress( AllLocalVarSize - pVar->GetOffsetAddress() ); } //push ebp、ret用のアドレスを考慮 AllLocalVarSize-=sizeof(long)*2; //ローカル変数用メモリを確保するためのスケジュール(subコマンド) compiler.codeGenerator.opfix( pAllLocalVarPertialSchedule, AllLocalVarSize - BaseOffset ); //pop edi compiler.codeGenerator.op_pop( REG_EDI ); //pop esi compiler.codeGenerator.op_pop( REG_ESI ); //pop ebx compiler.codeGenerator.op_pop(REG_EBX); if( compiler.IsDebug() ) { //cmp esp,ebp compiler.codeGenerator.op_cmp_RR( REG_ESP, REG_EBP ); //je 6(次のcallとbreakpointを飛び越す) compiler.codeGenerator.op_je( 6 ); //call _esp_error extern const UserProc *pSub_esp_error; compiler.codeGenerator.op_call( pSub_esp_error ); breakpoint; } //mov esp,ebp compiler.codeGenerator.op_mov_RR( REG_ESP, REG_EBP ); //pop ebp compiler.codeGenerator.op_pop(REG_EBP); //add esp AllLocalVarSize compiler.codeGenerator.op_add_esp(AllLocalVarSize-BaseOffset); if( BaseOffset==0 || pUserProc->IsCdecl() ){ //ret compiler.codeGenerator.op_ret(); } else{ //ret BaseOffset(パラメータ分のスタック領域を解放) compiler.codeGenerator.op_ret( (_int16)BaseOffset ); } compiler.FinishProcedureCompile(); //ローカル変数のネーム情報は後に解放する }