#include "../BasicCompiler_Common/common.h" #include "Opcode.h" int GetFunctionType(int FuncNum){ switch(FuncNum){ case FUNC_LEN: return DEF_LONG; case FUNC_SIZEOF: return DEF_LONG; case FUNC_ADDRESSOF: case FUNC_VARPTR: return DEF_PTR_VOID; case FUNC_GETDOUBLE: return DEF_DOUBLE; case FUNC_GETSINGLE: return DEF_SINGLE; case FUNC_GETQWORD: return DEF_QWORD; case FUNC_GETDWORD: return DEF_DWORD; case FUNC_GETWORD: return DEF_WORD; case FUNC_GETBYTE: return DEF_BYTE; } return 0; } int GetFunctionFromName(char *FuncName){ if(lstrcmpi(FuncName,"Len")==0) return FUNC_LEN; if(lstrcmpi(FuncName,"AddressOf")==0) return FUNC_ADDRESSOF; if(lstrcmpi(FuncName,"SizeOf")==0) return FUNC_SIZEOF; if(lstrcmpi(FuncName,"VarPtr")==0) return FUNC_VARPTR; if(lstrcmpi(FuncName,"GetDouble")==0) return FUNC_GETDOUBLE; if(lstrcmpi(FuncName,"GetSingle")==0) return FUNC_GETSINGLE; if(lstrcmpi(FuncName,"GetQWord")==0) return FUNC_GETQWORD; if(lstrcmpi(FuncName,"GetDWord")==0) return FUNC_GETDWORD; if(lstrcmpi(FuncName,"GetWord")==0) return FUNC_GETWORD; if(lstrcmpi(FuncName,"GetByte")==0) return FUNC_GETBYTE; return 0; } void Opcode_Func_Len( const char *Parameter ){ int type,TypeSize; LONG_PTR lpIndex; BOOL bArrayHead; type=GetVarType(Parameter,&lpIndex,0); const char *tempParm=Parameter; char temporary[VN_SIZE]; char temp2[32]; if(type==-1){ sprintf(temporary,"_System_DummyStr2=%s",Parameter); OpcodeCalc(temporary); lstrcpy(temp2,"_System_DummyStr2"); tempParm=temp2; extern CClass *pobj_StringClass; type=DEF_OBJECT; lpIndex=(LONG_PTR)pobj_StringClass; } TYPEINFO TypeInfo={type,lpIndex}; if(IsStringObjectType(&TypeInfo)){ //Stringオブジェクトの場合 sprintf(temporary,"%s.Length",tempParm); int reg=REG_RAX; NumOpe(®,temporary,0,0,NULL,NULL); return; } int SubScripts[MAX_ARRAYDIM]; RELATIVE_VAR RelativeVar; if(!GetVarOffsetReadOnly(tempParm,&type,&RelativeVar,&lpIndex,SubScripts)) return; if(type&FLAG_PTR){ type&=~FLAG_PTR; bArrayHead=1; } else bArrayHead=0; TypeSize=GetTypeSize(type,lpIndex); if(bArrayHead) TypeSize*=JumpSubScripts(SubScripts); //mov rax,TypeSize op_mov_RV(sizeof(_int64),REG_RAX,TypeSize); return; } void Opcode_Func_AddressOf( const char *name ){ extern int cp; SUBINFO *psi; extern LONG_PTR ProcPtr_BaseIndex; if(ProcPtr_BaseIndex!=-1){ //左辺の型にのっとり、オーバーロードを解決 std::vector subs; GetOverloadSubHash( name, subs ); if( subs.size() == 0 ){ SetError(27,name,cp); return; } //オーバーロードを解決 extern PROCPTRINFO *pProcPtrInfo; psi=OverloadSolution(name,subs,pProcPtrInfo[ProcPtr_BaseIndex].pParmInfo,pProcPtrInfo[ProcPtr_BaseIndex].ParmNum,NULL); if(!psi){ SetError(27,name,cp); return; } } else{ psi=GetSubHash(name); if(!psi){ SetError(27,name,cp); return; } } if(psi->bVirtual){ /////////////////////////////// // 仮想関数の場合 // thisポインタをrcxにコピー /////////////////////////////// CClass *pobj_c; char ObjectName[VN_SIZE]; int RefType; SplitObjectName(name,ObjectName,&RefType); if(ObjectName[0]){ if(lstrcmpi(ObjectName,"Super")==0) goto InClassMember; else{ RELATIVE_VAR RelativeVar; int type; if(!GetVarOffsetReadOnly(ObjectName,&type,&RelativeVar,(LONG_PTR *)&pobj_c)) return; SetVarPtrToReg(REG_RCX,&RelativeVar); //参照タイプが整合しているかをチェック if(type!=RefType) SetError(104,ObjectName,cp); if(type==DEF_PTR_OBJECT){ //mov rcx,qword ptr[rcx] op_mov_RM(sizeof(_int64),REG_RCX,REG_RCX,0,MOD_BASE); } } } else{ InClassMember: //自身のオブジェクトのThisポインタをrcxにコピー SetThisPtrToReg(REG_RCX); pobj_c=pobj_CompilingClass; } //仮想関数(オブジェクトメソッド) //pObj->func_table->func1 // ->func2 // ->func3 //mov r11,qword ptr[rcx] op_mov_RM(sizeof(_int64),REG_R11,REG_RCX,0,MOD_BASE); int i2 = pobj_c->GetFuncNumInVtbl( psi ); //mov rax,qword ptr[r11+func_index] if(i2*PTR_SIZE<=0x7F){ op_mov_RM(sizeof(_int64),REG_RAX,REG_R11,i2*PTR_SIZE,MOD_BASE_DISP8); } else{ op_mov_RM(sizeof(_int64),REG_RAX,REG_R11,i2*PTR_SIZE,MOD_BASE_DISP32); } } else{ //一般の関数 //mov rax,ProcAddr op_mov_RV(sizeof(_int64),REG_RAX,0); obp-=sizeof(long); pobj_SubAddrSchedule->add(psi,0); obp+=sizeof(long); } psi->bUse=1; } void Opcode_Func_SizeOf( const char *Parameter ){ int type,size; LONG_PTR lpIndex; type=GetTypeFixed(Parameter,&lpIndex); size=GetTypeSize(type,lpIndex); //mov rax,size op_mov_RV(sizeof(_int64),REG_RAX,size); } void Opcode_Func_VarPtr( const char *Parameter, TYPEINFO &ReturnTypeInfo ){ RELATIVE_VAR RelativeVar; //変数のアドレスを取得 if(!GetVarOffsetReadOnly( Parameter, &ReturnTypeInfo.type, &RelativeVar, &ReturnTypeInfo.u.lpIndex )) return; PTR_LEVEL_UP( ReturnTypeInfo.type ); SetVarPtrToReg(REG_RAX,&RelativeVar); } void Opcode_Func_GetPtrData( const char *Parameter, const int type ){ int i2; int reg=REG_RAX; i2=NumOpe(®,Parameter,0,0,0); if(!IsWholeNumberType(i2)){ extern int cp; SetError(11,Parameter,cp); return; } if(type==DEF_DOUBLE){ //movlpd xmm0,qword ptr[rax] op_movlpd_RM(REG_XMM0,REG_RAX,0,MOD_BASE); } else if(type==DEF_SINGLE){ //movss xmm0,dword ptr[rax] op_movss_RM(REG_XMM0,REG_RAX,0,MOD_BASE); } else{ //mov rax,ptr[rax] op_mov_RM(GetTypeSize(type,-1),REG_RAX,REG_RAX,0,MOD_BASE); } } void Opcode_CallFunc( const char *Parameter, const int FuncNum, TYPEINFO &ReturnTypeInfo ){ switch(FuncNum){ case FUNC_LEN: Opcode_Func_Len(Parameter); ReturnTypeInfo.type = DEF_LONG; break; case FUNC_ADDRESSOF: Opcode_Func_AddressOf(Parameter); ReturnTypeInfo.type = DEF_PTR_VOID; break; case FUNC_SIZEOF: Opcode_Func_SizeOf(Parameter); ReturnTypeInfo.type = DEF_LONG; break; case FUNC_VARPTR: Opcode_Func_VarPtr( Parameter, ReturnTypeInfo ); break; case FUNC_GETDOUBLE: Opcode_Func_GetPtrData(Parameter,DEF_DOUBLE); ReturnTypeInfo.type = DEF_DOUBLE; break; case FUNC_GETSINGLE: Opcode_Func_GetPtrData(Parameter,DEF_SINGLE); ReturnTypeInfo.type = DEF_SINGLE; break; case FUNC_GETQWORD: Opcode_Func_GetPtrData(Parameter,DEF_QWORD); ReturnTypeInfo.type = DEF_QWORD; break; case FUNC_GETDWORD: Opcode_Func_GetPtrData(Parameter,DEF_DWORD); ReturnTypeInfo.type = DEF_DWORD; break; case FUNC_GETWORD: Opcode_Func_GetPtrData(Parameter,DEF_WORD); ReturnTypeInfo.type = DEF_WORD; break; case FUNC_GETBYTE: Opcode_Func_GetPtrData(Parameter,DEF_BYTE); ReturnTypeInfo.type = DEF_BYTE; break; } }