#include "../BasicCompiler_Common/common.h" #include "Opcode.h" void SystemProc(char *name){ if(lstrcmp(name,"_System_GetEip")==0){ //mov rax,qword ptr[rsp] op_mov_RM(sizeof(_int64),REG_RAX,REG_RSP,0,MOD_BASE); //ret OpBuffer[obp++]=(char)0xC3; } else if(lstrcmp(name,"_System_InitDllGlobalVariables")==0){ //////////////////////////////////////// // DLLのグローバル領域をコンパイル //////////////////////////////////////// extern BOOL bDll; if(!bDll){ //ret OpBuffer[obp++]=(char)0xC3; return; } extern BOOL bCompilingGlobal; BOOL bBackCompilingGlobal; bBackCompilingGlobal=bCompilingGlobal; bCompilingGlobal=1; int BackCp; BackCp=cp; cp=-1; //sub rsp,スタックフレームサイズ int StackFrameSchedule; op_sub_rsp(0xFFFFFFFF); StackFrameSchedule=obp-sizeof(long); extern BOOL bDebugCompile; if(bDebugCompile){ //デバッグ用の変数を定義 DebugVariable(); } //GC用の変数を定義 InitGCVariables(); //クラスに属する静的メンバを定義 CMember::InitStaticMember(); GetGlobalDataForDll(); //add rsp,スタックフレームサイズ op_add64_value(REG_RSP,pobj_sf->GetFrameSize()); //スタックフレームスケジュール(subコマンドに渡す値) *((long *)(OpBuffer+StackFrameSchedule))=pobj_sf->GetFrameSize(); bCompilingGlobal=bBackCompilingGlobal; cp=BackCp; //ret OpBuffer[obp++]=(char)0xC3; } else if(lstrcmp(name,"_System_InitStaticLocalVariables")==0){ //静的ローカルオブジェクトのコンストラクタ呼び出し //sub rsp,スタックフレームサイズ int StackFrameSchedule; op_sub_rsp(0xFFFFFFFF); StackFrameSchedule=obp-sizeof(long); extern int MaxGlobalVarNum; extern VARIABLE *GlobalVar; int i; for(i=0;iGetFrameSize()); //スタックフレームスケジュール(subコマンドに渡す値) *((long *)(OpBuffer+StackFrameSchedule))=pobj_sf->GetFrameSize(); //ret OpBuffer[obp++]=(char)0xC3; } else if(lstrcmp(name,"_System_Call_Destructor_of_GlobalObject")==0){ //sub rsp,8(※RSPを16バイト境界にあわせるため) op_sub_rsp(0x8); extern BOOL bCompilingGlobal; BOOL bBackCompilingGlobal; bBackCompilingGlobal=bCompilingGlobal; bCompilingGlobal=1; obj_LexScopes.CallDestructorsOfScopeEnd(); bCompilingGlobal=bBackCompilingGlobal; //add rsp,8 op_add64_value(REG_RSP,0x8); //ret OpBuffer[obp++]=(char)0xC3; } else if(lstrcmp(name,"_System_GetSp")==0){ //mov rax,rsp op_mov_RR(REG_RAX,REG_RSP); //add rax,PTR_SIZE op_add64_value(REG_RAX,PTR_SIZE); //ret OpBuffer[obp++]=(char)0xC3; } else if(lstrcmp(name,"_allrem")==0){ //乗除演算用の特殊関数(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(lstrcmp(name,"_allmul")==0){ //乗算用の特殊関数(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(lstrcmp(name,"_alldiv")==0){ //除算用の特殊関数(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(lstrcmp(name,"_allshl")==0){ //符号あり左ビットシフト用の特殊関数(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(lstrcmp(name,"_allshr")==0){ //符号あり右ビットシフト用の特殊関数(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(lstrcmp(name,"_aullshr")==0){ //符号なし右ビットシフト用の特殊関数(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; } } void CompileBufferInProcedure(SUBINFO *psi){ extern char *basbuf; extern HANDLE hHeap; extern SUBINFO **ppSubHash; extern BOOL bDebugCompile; int i3,i4,i5,VarSize,BufferSize; char temporary[VN_SIZE]; BufferSize=128; if(psi->bUse==0||psi->bCompile) return; psi->bCompile=1; extern BOOL bSystemProc; if(memcmp(psi->name,"_System_",8)==0) bSystemProc=1; else bSystemProc=0; extern BOOL bDebugSupportProc; if(memcmp(psi->name,"_DebugSys_",10)==0){ if(!bDebugCompile){ psi->pVar=(VARIABLE *)HeapAlloc(hHeap,0,1); psi->VarNum=0; return; } bDebugSupportProc=1; } else bDebugSupportProc=0; psi->CompileAddress=obp; if(psi->bSystem){ //////////////////// // 特殊関数 //////////////////// extern int MaxLocalVarNum; extern int AllLocalVarSize; MaxLocalVarNum=0; AllLocalVarSize=0; //スタックフレーム管理用オブジェクトを初期化 extern CStackFrame *pobj_sf; pobj_sf=new CStackFrame(); SystemProc(psi->name); //スタックフレーム管理用オブジェクトを破棄 delete pobj_sf; pobj_sf=0; psi->EndOpAddr=obp; psi->pVar=(VARIABLE *)HeapAlloc(hHeap,0,1); psi->VarNum=0; return; } cp=psi->address; for(;;cp++){ if(IsCommandDelimitation(basbuf[cp])) break; } cp--; //プロシージャ抜け出しスケジュール(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; //ローカル変数に関する情報 extern VARIABLE *LocalVar; extern int MaxLocalVarNum; extern int AllLocalVarSize; LocalVar=(VARIABLE *)HeapAlloc(hHeap,0,sizeof(VARIABLE)); MaxLocalVarNum=0; AllLocalVarSize=0; //ローカル変数アドレススケジュール extern DWORD *pLocalVarAddrSchedule; extern int LocalVarAddrScheduleNum; pLocalVarAddrSchedule=(DWORD *)HeapAlloc(hHeap,0,1); LocalVarAddrScheduleNum=0; //レキシカルスコープ情報を初期化 obj_LexScopes.Init(obp); ///////////////////////////////////// // パラメータ用の変数データを考慮 ///////////////////////////////////// for(i3=psi->RealParmNum-1;i3>=0;i3--){ //変数データを追加 LocalVar=(VARIABLE *)HeapReAlloc(hHeap,0,LocalVar,(MaxLocalVarNum+1)*sizeof(VARIABLE)); lstrcpy(LocalVar[MaxLocalVarNum].name,psi->pRealParmInfo[i3].name); // TODO: パラメータのConst定義の指定が未完成 LocalVar[MaxLocalVarNum].bConst=false; LocalVar[MaxLocalVarNum].bArray=psi->pRealParmInfo[i3].bArray; memcpy(LocalVar[MaxLocalVarNum].SubScripts,psi->pRealParmInfo[i3].SubScripts,MAX_ARRAYDIM*sizeof(int)); LocalVar[MaxLocalVarNum].type=psi->pRealParmInfo[i3].type; if(LocalVar[MaxLocalVarNum].type==DEF_OBJECT){ if(psi->bExport) SetError(24,NULL,cp); } LocalVar[MaxLocalVarNum].u.index=psi->pRealParmInfo[i3].u.index; if(psi->pRealParmInfo[i3].bByVal&&psi->pRealParmInfo[i3].type==DEF_OBJECT){ //実態オブジェクトのByValパラメータ LocalVar[MaxLocalVarNum].fRef=REF_PARAMETER | OBJECT_PARAMETER; VarSize=PTR_SIZE; } else{ if(psi->pRealParmInfo[i3].bByVal&&psi->pRealParmInfo[i3].bArray==0){ LocalVar[MaxLocalVarNum].fRef=0; VarSize=GetTypeSize(LocalVar[MaxLocalVarNum].type,LocalVar[MaxLocalVarNum].u.index); if(VarSize%PTR_SIZE) VarSize+=PTR_SIZE-(VarSize%PTR_SIZE); } else{ LocalVar[MaxLocalVarNum].fRef=REF_PARAMETER; VarSize=PTR_SIZE; } } AllLocalVarSize+=VarSize; LocalVar[MaxLocalVarNum].offset=AllLocalVarSize; //レキシカルスコープ情報 LocalVar[MaxLocalVarNum].ScopeLevel=obj_LexScopes.GetNowLevel(); LocalVar[MaxLocalVarNum].ScopeStartAddress=obj_LexScopes.GetStartAddress(); LocalVar[MaxLocalVarNum].bLiving=TRUE; MaxLocalVarNum++; } //Thisポインタを示すローカルオフセット値をセット extern int LocalVar_ThisPtrOffset; LocalVar_ThisPtrOffset=AllLocalVarSize; //コンパイル中の関数が属するクラス pobj_CompilingClass=psi->pobj_ParentClass; //コンパイルスタートをクラス管理クラスに追加 pobj_DBClass->StartCompile( psi ); //コンパイル中の関数 extern SUBINFO *pCompilingSubInfo; pCompilingSubInfo=psi; //スタックフレーム管理用クラスを初期化 extern CStackFrame *pobj_sf; pobj_sf=new CStackFrame(); /////////////////////// // ここからコード生成 for(i3=psi->RealParmNum-1;i3>=0;i3--){ if(i3==3){ if(IsRealNumberType(psi->pRealParmInfo[i3].type)&&psi->pRealParmInfo[i3].bByVal){ //movsd qword ptr[rsp+0x20],xmm3 op_movsd_MR(REG_XMM3,REG_RSP,0x20,MOD_BASE_DISP32); } else{ //mov qword ptr[rsp+0x20],r9 op_mov_MR(sizeof(_int64),REG_R9,REG_RSP,0x20,MOD_BASE_DISP32); } } if(i3==2){ if(IsRealNumberType(psi->pRealParmInfo[i3].type)&&psi->pRealParmInfo[i3].bByVal){ //movsd qword ptr[rsp+0x18],xmm2 op_movsd_MR(REG_XMM2,REG_RSP,0x18,MOD_BASE_DISP32); } else{ //mov qword ptr[rsp+0x18],r8 op_mov_MR(sizeof(_int64),REG_R8,REG_RSP,0x18,MOD_BASE_DISP32); } } if(i3==1){ if(IsRealNumberType(psi->pRealParmInfo[i3].type)&&psi->pRealParmInfo[i3].bByVal){ //movsd qword ptr[rsp+0x10],xmm1 op_movsd_MR(REG_XMM1,REG_RSP,0x10,MOD_BASE_DISP32); } else{ //mov qword ptr[rsp+0x10],rdx op_mov_MR(sizeof(_int64),REG_RDX,REG_RSP,0x10,MOD_BASE_DISP32); } } if(i3==0){ if(IsRealNumberType(psi->pRealParmInfo[i3].type)&&psi->pRealParmInfo[i3].bByVal){ //movsd qword ptr[rsp+0x8],xmm0 op_movsd_MR(REG_XMM0,REG_RSP,0x8,MOD_BASE_DISP32); } else{ //mov qword ptr[rsp+0x8],rcx op_mov_MR(sizeof(_int64),REG_RCX,REG_RSP,0x8,MOD_BASE_DISP32); } } } //ret用のアドレスを考慮 AllLocalVarSize+=sizeof(_int64); //sub rsp,スタックフレームサイズ int StackFrameSchedule; op_sub_rsp(0xFFFFFFFF); StackFrameSchedule=obp-sizeof(long); //mov qword ptr[rsp+offset],reg ※スタックフレームを利用 pobj_sf->push(REG_RBX); pobj_sf->push(REG_RSI); pobj_sf->push(REG_RDI); pobj_sf->push(REG_R12); pobj_sf->push(REG_R13); pobj_sf->push(REG_R14); pobj_sf->push(REG_R15); //ローカル変数のベース値 int BaseLocalVar; BaseLocalVar=AllLocalVarSize; if(psi->ReturnType!=-1){ //戻り値が存在するとき char *temp; if(psi->name[0]==1&&psi->name[1]==ESC_OPERATOR) temp="_System_ReturnValue"; else temp=psi->name; if(psi->ReturnType==DEF_OBJECT && psi->isReturnRef == false){ //戻り値用オブジェクトのコンストラクタを呼び出す if(psi->u.Return_pobj_c->ConstructorMemberSubIndex!=-1){ sprintf(temporary,"%s.%s()",temp,psi->u.Return_pobj_c->name); OpcodeOthers(temporary); } } else{ //戻り値用の変数の定義 if( psi->isReturnRef ){ sprintf(temporary,"%c%c",1,ESC_BYREF); } else temporary[0]=0; sprintf(temporary+lstrlen(temporary),"%s%c%c",temp,1,ESC_AS); GetTypeName(psi->ReturnType,psi->u.ReturnIndex,temporary+lstrlen(temporary)); OpcodeDim(temporary,0); } } int RspOffsetSchedule=0; int RspOffsetSchedule2; if(bDebugCompile&&bDebugSupportProc==0){ //mov rdx, qword ptr[rsp+スタックフレームサイズ] op_mov_RM(sizeof(_int64),REG_RDX,REG_RSP,0,MOD_BASE_DISP32); RspOffsetSchedule=obp-sizeof(long); //mov rcx,rsp op_mov64_ToReg_FromReg(REG_RCX,REG_RSP); //add rcx,スタックフレームサイズ+sizeof(_int64) ※ret用のサイズを考慮 op_add64_value(REG_RCX,0); RspOffsetSchedule2=obp-sizeof(long); //call _DebugSys_StartProc extern SUBINFO *pSub_DebugSys_StartProc; op_call(pSub_DebugSys_StartProc); } if(pobj_CompilingClass){ if(lstrcmp(psi->name,pobj_CompilingClass->name)==0){ //////////////////////////////////// // コンストラクタをコンパイルするとき //////////////////////////////////// //コンストラクタのコンパイル開始を通知 pobj_CompilingClass->NotifyStartConstructorCompile(); //基底クラスかどうかの識別 //(継承元がインターフェイスの場合も基底クラスと見なす) BOOL bThisIsSuperClass; if(pobj_CompilingClass->pobj_InheritsClass==0) bThisIsSuperClass=1; else if(pobj_CompilingClass->pobj_InheritsClass->ConstructorMemberSubIndex==-1){ //インターフェイスを継承したときはコンストラクタを持たない 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); i3=pobj_CompilingClass->pobj_InheritsClass->ConstructorMemberSubIndex; Opcode_CallProc(temporary, pobj_CompilingClass->ppobj_Method[i3]->psi, 0, "", 0); } else{ //基底クラスのコンストラクタを暗黙的に呼び出す i3=pobj_CompilingClass->pobj_InheritsClass->ConstructorMemberSubIndex; Opcode_CallProc("", pobj_CompilingClass->ppobj_Method[i3]->psi, 0, "", 0); } } //実体クラスを持つメンバのコンストラクタ(引数有りを除く)を呼び出す int offset; int MemberTypeSize; int MemberObjectNum; if(pobj_CompilingClass->vtbl_num) offset=PTR_SIZE; else offset=0; for(i3=0;i3iMemberNum;i3++){ CMember *pMember = pobj_CompilingClass->ppobj_Member[i3]; MemberTypeSize= GetTypeSize(pMember->TypeInfo.type, pMember->TypeInfo.u.lpIndex); MemberObjectNum= JumpSubScripts(pMember->SubScripts); offset=GetSizeOfClassMember(pobj_CompilingClass,pMember->name,NULL); if(pMember->TypeInfo.type==DEF_OBJECT && pMember->IsRef() == false){ if(pMember->TypeInfo.u.pobj_Class->ConstructorMemberSubIndex!=-1){ i5=pMember->TypeInfo.u.pobj_Class->ConstructorMemberSubIndex; if(pMember->TypeInfo.u.pobj_Class->ppobj_Method[i5]->psi->RealParmNum==1){ //Thisポインタを第一引数に持ち合わせるため、引数なしの場合はこの値が1になる for(i4=0;i4TypeInfo.u.pobj_Class->ppobj_Method[i5]->psi); } } } } } //仮想関数テーブルを初期化 if(pobj_CompilingClass->vtbl_num&& pobj_CompilingClass->IsAbstract()==false){ //関数テーブルに値をセット offset=(int)pobj_CompilingClass->GetVtblGlobalOffset(); //mov rax,offset op_mov_RV(sizeof(_int64),REG_RAX,offset); obp-=sizeof(long); pobj_DataTableSchedule->add(); obp+=sizeof(long); //Thisポインタをrcxにコピー SetThisPtrToReg(REG_RCX); //mov qword ptr[rcx],rax op_mov_MR(sizeof(_int64),REG_RAX,REG_RCX,0,MOD_BASE); } } else if(psi->name[0]=='~'){ //デストラクタをコンパイルしたとき //デストラクタのコンパイル開始を通知 pobj_CompilingClass->NotifyStartDestructorCompile(); } } //コード生成中に関数の先頭領域にDimステートメントを再配置できるようにする extern int DimStatementInsertPoint; DimStatementInsertPoint=obp; ////////////////////////////////////////// ////////////////////////////////////////// ////// プロシージャ内をコンパイル //////// if(psi->dwType==SUBTYPE_SUB) CompileBuffer(ESC_ENDSUB,0); else if(psi->dwType==SUBTYPE_FUNCTION) CompileBuffer(ESC_ENDFUNCTION,0); else if(psi->dwType==SUBTYPE_MACRO) CompileBuffer(ESC_ENDMACRO,0); ////////////////////////////////////////// ////////////////////////////////////////// if( pobj_CompilingClass ){ if( pobj_CompilingClass->IsCompilingConstructor() ){ // コンストラクタをコンパイルしていたとき // コンストラクタのコンパイルが完了したことを通知 pobj_CompilingClass->NotifyFinishConstructorCompile(); } else if(psi->name[0]=='~'){ //////////////////////////////////// //デストラクタをコンパイルしたとき //////////////////////////////////// // デストラクタのコンパイルが完了したことを通知 pobj_CompilingClass->NotifyFinishDestructorCompile(); if(pobj_CompilingClass->pobj_InheritsClass){ /* サブクラスのデストラクタをコンパイルしているときは、 基底クラスのデストラクタを呼び出す */ i3=pobj_CompilingClass->pobj_InheritsClass->DestructorMemberSubIndex; if(i3!=-1){ Opcode_CallProc("", pobj_CompilingClass->ppobj_Method[i3]->psi, 0, "", 0); } } //実体クラスを持つメンバのデストラクタを呼び出す //※コンストラクタと逆順序で呼び出す int offset; int MemberTypeSize; int MemberObjectNum; 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=GetSizeOfClassMember(pobj_CompilingClass,pMember->name,NULL); if(pMember->TypeInfo.type==DEF_OBJECT && pMember->IsRef() == false){ if(pMember->TypeInfo.u.pobj_Class->DestructorMemberSubIndex!=-1){ for(i4=MemberObjectNum-1;i4>=0;i4--){ //Thisポインタをrcxにコピー SetThisPtrToReg(REG_RCX); //add rcx,offset op_add64_value(REG_RCX,offset+i4*MemberTypeSize); //call destructor i5=pMember->TypeInfo.u.pobj_Class->DestructorMemberSubIndex; op_call(pMember->TypeInfo.u.pobj_Class->ppobj_Method[i5]->psi); } } } } } } //ラベル用のメモリを解放 for(i3=0;i3ReturnType!=-1){ ////////////////////////////////// // 戻り値をraxまたはxmm0に設定 ////////////////////////////////// RELATIVE_VAR RelativeVar; LONG_PTR lpIndex; char *temp; if(psi->name[0]==1&&psi->name[1]==ESC_OPERATOR) temp="_System_ReturnValue"; else temp=psi->name; GetVarOffsetReadWrite(temp,&i3,&RelativeVar,&lpIndex); i3=psi->ReturnType; if(i3==DEF_OBJECT){ SetVarPtrToReg(REG_RAX,&RelativeVar); } else if(i3==DEF_DOUBLE){ //64ビット実数型 SetXmmReg_DoubleVariable(&RelativeVar,REG_XMM0); } else if(i3==DEF_SINGLE){ //32ビット実数型 SetXmmReg_SingleVariable(&RelativeVar,REG_XMM0); } else if(IsWholeNumberType(i3)){ //整数型 SetReg_WholeVariable(i3,&RelativeVar,REG_RAX); } else SetError(300,NULL,cp); } //ローカル変数領域のサイズをスタックフレームに通知 int iLocalParmSize; iLocalParmSize=AllLocalVarSize-BaseLocalVar; pobj_sf->SetLocalParmSize(iLocalParmSize); //ローカル変数アドレススケジュール for(i3=0;i3GetFrameSize(); } HeapDefaultFree(pLocalVarAddrSchedule); for(i3=0;i3GetFrameSize()-LocalVar[i3].offset; } //mov reg,qword ptr[rsp+offset] ※スタックフレームを利用 pobj_sf->pop(REG_R15); pobj_sf->pop(REG_R14); pobj_sf->pop(REG_R13); pobj_sf->pop(REG_R12); pobj_sf->pop(REG_RDI); pobj_sf->pop(REG_RSI); pobj_sf->pop(REG_RBX); int iStackFrameSize; iStackFrameSize=iLocalParmSize + pobj_sf->GetFrameSize(); //add rsp,スタックフレームサイズ op_add_rsp(iStackFrameSize); //ret 0 OpBuffer[obp++]=(char)0xC3; //デバッグ用 if(RspOffsetSchedule){ *((long *)(OpBuffer+RspOffsetSchedule))=iStackFrameSize; *((long *)(OpBuffer+RspOffsetSchedule2))=iStackFrameSize+sizeof(_int64); } //スタックフレームスケジュール(subコマンド) *((long *)(OpBuffer+StackFrameSchedule))=iStackFrameSize; //スタックフレームスケジュールを実行 pobj_sf->RunningSchedule(); delete pobj_sf; pobj_sf=0; psi->EndOpAddr=obp; psi->pVar=LocalVar; psi->VarNum=MaxLocalVarNum; //ローカル変数のネーム情報は後に解放する } void CompileLocal(){ extern SUBINFO **ppSubHash; int i2; SUBINFO *psi; extern BOOL bDll; if(bDll){ //DLLの場合はグローバル変数を初期化するための関数を一番初めにコンパイルする psi=GetSubHash("_System_InitDllGlobalVariables"); if(psi){ CompileBufferInProcedure(psi); } else SetError(300,NULL,cp); } //_System_InitStaticLocalVariablesは一番最後にコンパイル //※一般関数内の静的変数オブジェクトをすべて収集しなければならない extern SUBINFO *pSub_System_InitStaticLocalVariables; pSub_System_InitStaticLocalVariables->bCompile=1; //_System_Call_Destructor_of_GlobalObjectは一番最後にコンパイル extern SUBINFO *pSub_System_Call_Destructor_of_GlobalObject; pSub_System_Call_Destructor_of_GlobalObject->bCompile=1; Repeat: for(i2=0;i2pNextData; } } //プロシージャコンパイルによって、プロシージャコンパイルが必要になる場合 for(i2=0;i2bUse&&psi->bCompile==0&&psi->bVirtual==0){ goto Repeat; } psi=psi->pNextData; } } //_System_InitStaticLocalVariablesは一番最後にコンパイル pSub_System_InitStaticLocalVariables->bCompile=0; CompileBufferInProcedure(pSub_System_InitStaticLocalVariables); //_System_Call_Destructor_of_GlobalObjectは一番最後にコンパイル pSub_System_Call_Destructor_of_GlobalObject->bCompile=0; CompileBufferInProcedure(pSub_System_Call_Destructor_of_GlobalObject); }