#include "../BasicCompiler_Common/common.h" #include "Opcode.h" void SystemProc( const UserProc &userProc ){ if( userProc.GetName() == "_System_GetEip" ){ //mov eax,dword ptr[esp] OpBuffer[obp++]=(char)0x8B; OpBuffer[obp++]=(char)0x04; OpBuffer[obp++]=(char)0x24; //ret OpBuffer[obp++]=(char)0xC3; } else if( userProc.GetName() == "_System_InitDllGlobalVariables" ){ //////////////////////////////////////// // DLLのグローバル領域をコンパイル //////////////////////////////////////// extern BOOL bDll; if(!bDll){ //ret OpBuffer[obp++]=(char)0xC3; return; } UserProc *pBackUserProc; pBackUserProc = &UserProc::CompilingUserProc(); UserProc::CompileStartForGlobalArea(); int BackCp; BackCp=cp; cp=-1; extern BOOL bDebugCompile; if(bDebugCompile){ //デバッグ用の変数を定義 DebugVariable(); } //GC用の変数を定義 InitGCVariables(); //クラスに属する静的メンバを定義 CMember::InitStaticMember(); GetGlobalDataForDll(); UserProc::CompileStartForUserProc( pBackUserProc ); cp=BackCp; //ret OpBuffer[obp++]=(char)0xC3; } else if( userProc.GetName() == "_System_InitStaticLocalVariables" ){ //静的ローカルオブジェクトのコンストラクタ呼び出し foreach( Variable *pVar, globalVars ){ if(memicmp(pVar->GetName().c_str(),"Static%",7)==0){ //コンストラクタ呼び出し if( pVar->IsObject() ){ //エラー用 cp=pVar->source_code_address; CallConstructor( pVar->GetName().c_str(), pVar->GetSubScriptsPtr(), *pVar, pVar->paramStrForConstructor.c_str()); } } } //ret OpBuffer[obp++]=(char)0xC3; } else if( userProc.GetName() == "_System_Call_Destructor_of_GlobalObject" ){ UserProc *pBackUserProc; pBackUserProc = &UserProc::CompilingUserProc(); UserProc::CompileStartForGlobalArea(); obj_LexScopes.CallDestructorsOfScopeEnd(); UserProc::CompileStartForUserProc( pBackUserProc ); //ret OpBuffer[obp++]=(char)0xC3; } else if( userProc.GetName() == "_System_GetSp" ){ //mov eax,esp op_mov_RR(REG_EAX,REG_ESP); //add eax,PTR_SIZE op_add_RV8(REG_EAX,PTR_SIZE); //ret OpBuffer[obp++]=(char)0xC3; } 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 }; memcpy(OpBuffer+obp,Buffer_allrem,178); obp+=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 }; memcpy(OpBuffer+obp,Buffer_aullrem,117); obp+=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 }; memcpy(OpBuffer+obp,Buffer_allmul,52); obp+=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 }; memcpy(OpBuffer+obp,Buffer_alldiv,170); obp+=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 }; memcpy(OpBuffer+obp,Buffer_aulldiv,104); obp+=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 }; memcpy(OpBuffer+obp,Buffer_allshl,31); obp+=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 }; memcpy(OpBuffer+obp,Buffer_allshr,33); obp+=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 }; memcpy(OpBuffer+obp,Buffer_aullshr,31); obp+=31; } else{ SetError(); } } void AutoGeneration(UserProc &userProc){ if( userProc.GetName() == "InitializeUserTypes" && userProc.HasParentClass() && (string)userProc.GetParentClass().name == "_System_TypeBase" ){ pobj_DBClass->Compile_System_InitializeUserTypes(); } else if( userProc.GetName() == "RegisterGlobalRoots" && userProc.HasParentClass() && (string)userProc.GetParentClass().name == "_System_CGarbageCollection" ){ Compile_AddGlobalRootsForGc(); } else{ SetError(); } } void _compile_proc(UserProc *pUserProc){ extern char *basbuf; extern HANDLE hHeap; extern GlobalProc **ppSubHash; extern BOOL bDebugCompile; int i3,i4,LocalVarSchedule,EspOffsetSchedule,BaseOffset; char temporary[VN_SIZE]; if( pUserProc->IsUsing() == false || pUserProc->IsCompiled() ) return; if( pUserProc->localVars.size() ){ SetError(); return; } 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(!bDebugCompile){ return; } bDebugSupportProc=1; } else bDebugSupportProc=0; pUserProc->beginOpAddress=obp; //コンパイル中の関数が属するクラス pobj_CompilingClass=pUserProc->GetParentClassPtr(); //コンパイルスタートをクラス管理クラスに追加 pobj_DBClass->StartCompile( pUserProc ); //コンパイル中の関数 UserProc::CompileStartForUserProc( pUserProc ); // コンパイル中の関数が属する名前空間 Smoothie::Lexical::liveingNamespaceScopes = pUserProc->GetNamespaceScopes(); // コンパイル中の関数でImportsされている名前空間 Smoothie::Meta::importedNamespaces = pUserProc->GetImportedNamespaces(); if(pUserProc->IsSystem()){ //////////////////// // 特殊関数 //////////////////// extern int AllLocalVarSize; AllLocalVarSize=0; SystemProc(*pUserProc); pUserProc->endOpAddress=obp; return; } cp=pUserProc->GetCodePos(); for(;;cp++){ if(IsCommandDelimitation(basbuf[cp])) break; } cp--; //ローカル変数に関する情報 extern int AllLocalVarSize; AllLocalVarSize=0; //ローカル変数アドレススケジュール extern DWORD *pLocalVarAddrSchedule; extern int LocalVarAddrScheduleNum; pLocalVarAddrSchedule=(DWORD *)HeapAlloc(hHeap,0,1); LocalVarAddrScheduleNum=0; //パラメータ用の変数データを考慮 for(i3=(int)pUserProc->RealParams().size()-1;i3>=0;i3--){ Parameter ¶m = *pUserProc->RealParams()[i3]; Variable *pVar = new Variable( param.GetVarName(), param, false, param.IsRef() ); if( param.IsArray() ){ pVar->SetArray( param.GetSubScriptsPtr() ); } 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->offset=AllLocalVarSize; //レキシカルスコープ情報 pVar->ScopeLevel=obj_LexScopes.GetNowLevel(); pVar->ScopeStartAddress=obj_LexScopes.GetStartAddress(); pVar->bLiving=TRUE; pUserProc->localVars.push_back( pVar ); } //Thisポインタを示すローカルオフセット値をセット extern int LocalVar_ThisPtrOffset; LocalVar_ThisPtrOffset=AllLocalVarSize; BaseOffset=AllLocalVarSize; //ret用のアドレスを考慮 AllLocalVarSize+=sizeof(long); /////////////////////// // ここからコード生成 //sub esp,AllLocalVarSize(スケジュール) op_sub_esp(0xFFFFFFFF); LocalVarSchedule=obp-sizeof(long); //push ebp op_push(REG_EBP); //mov ebp,esp OpBuffer[obp++]=(char)0x8B; OpBuffer[obp++]=(char)0xEC; //push ebx op_push(REG_EBX); //push esi OpBuffer[obp++]=(char)0x56; //push edi OpBuffer[obp++]=(char)0x57; 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, pUserProc->ReturnType().ToString().c_str() ); } else{ //戻り値用の変数の定義 sprintf(temporary,"%s%c%c%s",temp,1,ESC_AS, pUserProc->ReturnType().ToString().c_str() ); } OpcodeDim(temporary,0); } } //プロシージャ抜け出しスケジュール(Exit Sub/Function) extern DWORD *pExitSubSchedule; extern int ExitSubScheduleNum; pExitSubSchedule=(DWORD *)HeapAlloc(hHeap,0,1); ExitSubScheduleNum=0; //ラベル用のメモリを確保 extern LABEL *pLabelNames; extern int MaxLabelNum; pLabelNames=(LABEL *)HeapAlloc(hHeap,0,1); MaxLabelNum=0; //Gotoラベルスケジュール extern GOTOLABELSCHEDULE *pGotoLabelSchedule; extern int GotoLabelScheduleNum; pGotoLabelSchedule=(GOTOLABELSCHEDULE *)HeapAlloc(hHeap,0,1); GotoLabelScheduleNum=0; //With情報のメモリを確保 extern WITHINFO WithInfo; WithInfo.ppName=(char **)HeapAlloc(hHeap,0,1); WithInfo.pWithCp=(int *)HeapAlloc(hHeap,0,1); WithInfo.num=0; //重複エラー情報管理のメモリを確保 extern char **SynonymErrorWords; extern int SynonymErrorNum; SynonymErrorNum=0; SynonymErrorWords=(char **)HeapAlloc(hHeap,0,1); //Continueアドレスを初期化 extern DWORD dwContinueAddress; dwContinueAddress=-1; if(bDebugCompile&&bDebugSupportProc==0){ //push dword ptr[ebp+(AllLocalVarSize-BaseOffset)](スケジュール) OpBuffer[obp++]=(char)0xFF; OpBuffer[obp++]=(char)0xB5; EspOffsetSchedule=obp; obp+=sizeof(long); //push dword ptr[ebp](以前のebp) OpBuffer[obp++]=(char)0xFF; OpBuffer[obp++]=(char)0x75; OpBuffer[obp++]=(char)0x00; //call _DebugSys_StartProc extern UserProc *pSub_DebugSys_StartProc; op_call(pSub_DebugSys_StartProc); } if(pobj_CompilingClass){ if( pUserProc->GetName() == pobj_CompilingClass->name ){ //////////////////////////////////// // コンストラクタをコンパイルするとき //////////////////////////////////// //コンストラクタのコンパイル開始を通知 pobj_CompilingClass->NotifyStartConstructorCompile(); //基底クラスかどうかの識別 //(継承元がインターフェイスの場合も基底クラスと見なす) BOOL bThisIsSuperClass; if(pobj_CompilingClass->pobj_InheritsClass==0) bThisIsSuperClass=1; else if( pobj_CompilingClass->pobj_InheritsClass->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(lstrcmp(temporary, pobj_CompilingClass->pobj_InheritsClass->name)==0){ //基底クラスのコンストラクタを呼び出す 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]==')')){ SetError(1,NULL,cp); } RemoveStringPare(temporary); Type dummyType; CallProc( PROC_DEFAULT , pobj_CompilingClass->pobj_InheritsClass->GetConstructorMethod()->pUserProc , pobj_CompilingClass->pobj_InheritsClass->GetConstructorMethod()->pUserProc->GetName().c_str() , temporary , dummyType ); } else{ //基底クラスのコンストラクタを暗黙的に呼び出す Opcode_CallProc("", pobj_CompilingClass->pobj_InheritsClass->GetConstructorMethod()->pUserProc, 0, "", 0); } } //新しいオブジェクト領域は0で初期化されているため、Nothingを明示的に代入する必要はない /* //実体クラスを持つメンバのコンストラクタ(引数有りを除く)を呼び出す for(i3=0;i3iMemberNum;i3++){ CMember *pMember = pobj_CompilingClass->ppobj_Member[i3]; if(pMember->IsObject()){ // オブジェクトメンバを発見したとき sprintf(temporary, "This.%s=Nothing", pMember->name ); OpcodeCalc( temporary ); } } */ //仮想関数テーブルを初期化 if(pobj_CompilingClass->vtbl_num&& pobj_CompilingClass->IsAbstract()==false){ //関数テーブルに値をセット int offset = (int)pobj_CompilingClass->GetVtblGlobalOffset(); //mov eax,offset OpBuffer[obp++]=(char)0xB8; *((long *)(OpBuffer+obp))=offset; pobj_DataTableSchedule->add(); obp+=sizeof(long); //Thisポインタをecxにコピー SetThisPtrToReg(REG_ECX); //mov dword ptr[ecx],eax OpBuffer[obp++]=(char)0x89; OpBuffer[obp++]=(char)0x01; } } else if( pUserProc->IsDestructor() ){ //デストラクタをコンパイルしたとき //デストラクタのコンパイル開始を通知 pobj_CompilingClass->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( pobj_CompilingClass ){ if( pobj_CompilingClass->IsCompilingConstructor() ){ // コンストラクタをコンパイルしていたとき // コンストラクタのコンパイルが完了したことを通知 pobj_CompilingClass->NotifyFinishConstructorCompile(); } else if( pUserProc->IsDestructor() ){ //////////////////////////////////// //デストラクタをコンパイルしたとき //////////////////////////////////// // デストラクタのコンパイルが完了したことを通知 pobj_CompilingClass->NotifyFinishDestructorCompile(); if(pobj_CompilingClass->pobj_InheritsClass){ /* サブクラスのデストラクタをコンパイルしているときは、 基底クラスのデストラクタを呼び出す */ CMethod *method = pobj_CompilingClass->pobj_InheritsClass->GetDestructorMethod(); if( method ){ Opcode_CallProc("", method->pUserProc, 0, "", 0); } } //実体クラスを持つメンバのデストラクタ呼び出しはGCに任せる /* //※コンストラクタと逆順序で呼び出す int offset; int MemberTypeSize; int MemberObjectNum; offset=GetTypeSize(DEF_OBJECT,(LONG_PTR)pobj_CompilingClass); for(i3=pobj_CompilingClass->iMemberNum-1;i3>=0;i3--){ CMember *pMember = pobj_CompilingClass->ppobj_Member[i3]; MemberTypeSize= GetTypeSize(pMember->TypeInfo.type, pMember->TypeInfo.u.lpIndex); MemberObjectNum= JumpSubScripts(pMember->SubScripts); offset-=MemberTypeSize*MemberObjectNum; if(pMember->TypeInfo.type==DEF_OBJECT){ CMethod *method = pMember->TypeInfo.u.pobj_Class->GetDestructorMethod(); if( method ){ for(i4=MemberObjectNum-1;i4>=0;i4--){ //Thisポインタをecxにコピー SetThisPtrToReg(REG_ECX); //add ecx,offset OpBuffer[obp++]=(char)0x81; OpBuffer[obp++]=(char)0xC1; *((long *)(OpBuffer+obp))=offset+i4*MemberTypeSize; obp+=sizeof(long); //push ecx op_push(REG_ECX); //call destructor op_call( method->pUserProc ); } } } }*/ } } //ラベル用のメモリを解放 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()); i3=pUserProc->ReturnType().GetBasicType(); if(i3==DEF_OBJECT || i3==DEF_STRUCT){ SetVarPtrToEax(&RelativeVar); if( i3==DEF_OBJECT ){ //mov eax,dword ptr[eax] op_mov_RM( sizeof(long), REG_EAX, REG_EAX, 0, MOD_BASE ); } } else if(i3==DEF_DOUBLE){ //fld qword ptr[ebp+offset] OpBuffer[obp++]=(char)0xDD; OpBuffer[obp++]=(char)0x85; *((long *)(OpBuffer+obp))=RelativeVar.offset; AddLocalVarAddrSchedule(); obp+=sizeof(long); } else if(i3==DEF_SINGLE){ //fld dword ptr[ebp+offset] OpBuffer[obp++]=(char)0xD9; OpBuffer[obp++]=(char)0x85; *((long *)(OpBuffer+obp))=RelativeVar.offset; AddLocalVarAddrSchedule(); obp+=sizeof(long); } else if(i3==DEF_INT64||i3==DEF_QWORD){ //mov eax,dword ptr[ebp+offset] OpBuffer[obp++]=(char)0x8B; OpBuffer[obp++]=(char)0x85; *((long *)(OpBuffer+obp))=RelativeVar.offset; AddLocalVarAddrSchedule(); obp+=sizeof(long); //mov edx,dword ptr[ebp+offset+sizeof(long)] OpBuffer[obp++]=(char)0x8B; OpBuffer[obp++]=(char)0x95; *((long *)(OpBuffer+obp))=RelativeVar.offset+sizeof(long); AddLocalVarAddrSchedule(); obp+=sizeof(long); } else if(i3==DEF_LONG||i3==DEF_DWORD|| IsPtrType(i3)){ //mov eax,dword ptr[ebp+offset] OpBuffer[obp++]=(char)0x8B; OpBuffer[obp++]=(char)0x85; *((long *)(OpBuffer+obp))=RelativeVar.offset; AddLocalVarAddrSchedule(); obp+=sizeof(long); } else if(i3==DEF_INTEGER||i3==DEF_WORD || (isUnicode&&i3==DEF_CHAR)){ //xor eax,eax(eaxを0に初期化する) op_zero_reg(REG_EAX); //mov ax,word ptr[ebp+offset] OpBuffer[obp++]=(char)0x66; OpBuffer[obp++]=(char)0x8B; OpBuffer[obp++]=(char)0x85; *((long *)(OpBuffer+obp))=RelativeVar.offset; AddLocalVarAddrSchedule(); obp+=sizeof(long); } else if(i3==DEF_SBYTE||i3==DEF_BYTE||i3==DEF_BOOLEAN || (isUnicode==false&&i3==DEF_CHAR)){ //xor eax,eax(eaxを0に初期化する) op_zero_reg(REG_EAX); //mov al,byte ptr[ebp+offset] OpBuffer[obp++]=(char)0x8A; OpBuffer[obp++]=(char)0x85; *((long *)(OpBuffer+obp))=RelativeVar.offset; AddLocalVarAddrSchedule(); obp+=sizeof(long); } } //ローカル変数アドレススケジュール for(i3=0;i3localVars ){ //後にデバッグで利用する pVar->offset = AllLocalVarSize - pVar->offset; } //push ebp、ret用のアドレスを考慮 AllLocalVarSize-=sizeof(long)*2; //ローカル変数用メモリを確保するためのスケジュール(subコマンド) *((long *)(OpBuffer+LocalVarSchedule))=AllLocalVarSize-BaseOffset; //pop edi OpBuffer[obp++]=(char)0x5F; //pop esi OpBuffer[obp++]=(char)0x5E; //pop ebx op_pop(REG_EBX); if(bDebugCompile){ //cmp esp,ebp op_cmp_RR( REG_ESP, REG_EBP ); //jz 6(次のcallとbreakpointを飛び越す) OpBuffer[obp++]=(char)0x74; OpBuffer[obp++]=(char)0x06; //call _esp_error extern UserProc *pSub_esp_error; op_call( pSub_esp_error ); breakpoint; } //mov esp,ebp OpBuffer[obp++]=(char)0x8B; OpBuffer[obp++]=(char)0xE5; //pop ebp op_pop(REG_EBP); //add esp AllLocalVarSize op_add_esp(AllLocalVarSize-BaseOffset); if( BaseOffset==0 || pUserProc->IsCdecl() ){ //ret 0 OpBuffer[obp++]=(char)0xC3; } else{ //ret BaseOffset(パラメータ分のスタック領域を解放) OpBuffer[obp++]=(char)0xC2; *((_int16 *)(OpBuffer+obp))=(_int16)BaseOffset; obp+=sizeof(_int16); } pUserProc->endOpAddress=obp; //重複エラー情報管理のメモリを解放 for(i3=0;i3CompleteCompile(); //_System_InitStaticLocalVariablesは一番最後にコンパイル //※一般関数内の静的変数オブジェクトをすべて収集しなければならない extern UserProc *pSub_System_InitStaticLocalVariables; pSub_System_InitStaticLocalVariables->CompleteCompile(); //_System_Call_Destructor_of_GlobalObjectは一番最後にコンパイル extern UserProc *pSub_System_Call_Destructor_of_GlobalObject; pSub_System_Call_Destructor_of_GlobalObject->CompleteCompile(); repeat: GlobalProc *pGlobalProc; for(i2=0;i2pNextData; } } if( IsNeedProcCompile() ){ //プロシージャコンパイルによって、プロシージャコンパイルが必要になる場合 goto repeat; } //_System_TypeBase_InitializeUserTypesは最後のほうでコンパイル pSubStaticMethod_System_TypeBase_InitializeUserTypes->KillCompileStatus(); CompileBufferInProcedure( *pSubStaticMethod_System_TypeBase_InitializeUserTypes ); if( IsNeedProcCompile() ){ //プロシージャコンパイルによって、プロシージャコンパイルが必要になる場合 for(i2=0;i2pNextData; } } } //_System_InitStaticLocalVariablesは一番最後にコンパイル pSub_System_InitStaticLocalVariables->KillCompileStatus(); CompileBufferInProcedure( *pSub_System_InitStaticLocalVariables ); //_System_Call_Destructor_of_GlobalObjectは一番最後にコンパイル pSub_System_Call_Destructor_of_GlobalObject->KillCompileStatus(); CompileBufferInProcedure( *pSub_System_Call_Destructor_of_GlobalObject ); }