#include "../BasicCompiler_Common/common.h" #include "Opcode.h" int GetFunctionType(int FuncNum){ switch(FuncNum){ case FUNC_CUDBL: return DEF_DOUBLE; case FUNC_FIX: case FUNC_LEN: return DEF_LONG; case FUNC_ADDRESSOF: case FUNC_SIZEOF: case FUNC_VARPTR: return DEF_DWORD; 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,"CUDbl")==0) return FUNC_CUDBL; if(lstrcmpi(FuncName,"Fix")==0) return FUNC_FIX; 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_Fix(char *Parameter){ int i; i=NumOpe(Parameter,0,0,0); if(i==DEF_DOUBLE){ //fld qword ptr[esp] op_fld_ptr_esp(DEF_DOUBLE); //fnstcw word ptr[esp] OpBuffer[obp++]=(char)0xD9; OpBuffer[obp++]=(char)0x3C; OpBuffer[obp++]=(char)0x24; //mov ax,word ptr[esp] OpBuffer[obp++]=(char)0x66; OpBuffer[obp++]=(char)0x8B; OpBuffer[obp++]=(char)0x04; OpBuffer[obp++]=(char)0x24; //or ah,0Ch OpBuffer[obp++]=(char)0x80; OpBuffer[obp++]=(char)0xCC; OpBuffer[obp++]=(char)0x0C; //mov word ptr[esp-2],ax OpBuffer[obp++]=(char)0x66; OpBuffer[obp++]=(char)0x89; OpBuffer[obp++]=(char)0x44; OpBuffer[obp++]=(char)0x24; OpBuffer[obp++]=(char)0xFE; //fldcw word ptr[esp-2] OpBuffer[obp++]=(char)0xD9; OpBuffer[obp++]=(char)0x6C; OpBuffer[obp++]=(char)0x24; OpBuffer[obp++]=(char)0xFE; //fistp dword ptr[esp+4] OpBuffer[obp++]=(char)0xDB; OpBuffer[obp++]=(char)0x5C; OpBuffer[obp++]=(char)0x24; OpBuffer[obp++]=(char)0x04; //fldcw word ptr[esp] OpBuffer[obp++]=(char)0xD9; OpBuffer[obp++]=(char)0x2C; OpBuffer[obp++]=(char)0x24; //add esp,4 op_add_esp(4); } else if(i==DEF_SINGLE){ //fld dword ptr[esp] op_fld_ptr_esp(DEF_SINGLE); //sub esp,4 op_sub_esp(4); //fnstcw word ptr[esp] OpBuffer[obp++]=(char)0xD9; OpBuffer[obp++]=(char)0x3C; OpBuffer[obp++]=(char)0x24; //mov ax,word ptr[esp] OpBuffer[obp++]=(char)0x66; OpBuffer[obp++]=(char)0x8B; OpBuffer[obp++]=(char)0x04; OpBuffer[obp++]=(char)0x24; //or ah,0Ch OpBuffer[obp++]=(char)0x80; OpBuffer[obp++]=(char)0xCC; OpBuffer[obp++]=(char)0x0C; //mov word ptr[esp-2],ax OpBuffer[obp++]=(char)0x66; OpBuffer[obp++]=(char)0x89; OpBuffer[obp++]=(char)0x44; OpBuffer[obp++]=(char)0x24; OpBuffer[obp++]=(char)0xFE; //fldcw word ptr[esp-2] OpBuffer[obp++]=(char)0xD9; OpBuffer[obp++]=(char)0x6C; OpBuffer[obp++]=(char)0x24; OpBuffer[obp++]=(char)0xFE; //fistp dword ptr[esp+4] OpBuffer[obp++]=(char)0xDB; OpBuffer[obp++]=(char)0x5C; OpBuffer[obp++]=(char)0x24; OpBuffer[obp++]=(char)0x04; //fldcw word ptr[esp] OpBuffer[obp++]=(char)0xD9; OpBuffer[obp++]=(char)0x2C; OpBuffer[obp++]=(char)0x24; //add esp,4 op_add_esp(4); } else if(Is64Type(i)){ //pop eax op_pop(REG_EAX); //add esp,4 op_add_esp(4); //push eax op_push(REG_EAX); } //pop eax op_pop(REG_EAX); } void Opcode_Func_CUDbl(char *Parameter){ int i; i=NumOpe(Parameter,0,0,0); ChangeTypeToLong(i); //pop eax op_pop(REG_EAX); //push 0 OpBuffer[obp++]=(char)0x6A; OpBuffer[obp++]=(char)0x00; //push eax op_push(REG_EAX); //fild qword ptr[esp] OpBuffer[obp++]=(char)0xDF; OpBuffer[obp++]=(char)0x2C; OpBuffer[obp++]=(char)0x24; //add esp,8 op_add_esp(8); } void Opcode_Func_Len(char *Parameter){ int type,TypeSize; LONG_PTR lpIndex; BOOL bArrayHead; type=GetVarType(Parameter,&lpIndex,0); 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オブジェクトの場合 char temporary[VN_SIZE]; sprintf(temporary,"%s.Length",tempParm); NumOpe(temporary,0,0,NULL,NULL); //pop eax op_pop(REG_EAX); return; } int SubScripts[MAX_ARRAYDIM]; RELATIVE_VAR RelativeVar; if(!GetVarOffset(1,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 eax,TypeSize OpBuffer[obp++]=(char)0xB8; *((long *)(OpBuffer+obp))=TypeSize; obp+=sizeof(long); } void Opcode_Func_AddressOf(char *name){ extern int cp; SUBINFO *psi; extern LONG_PTR ProcPtr_BaseIndex; if(ProcPtr_BaseIndex!=-1){ //左辺の型にのっとり、オーバーロードを解決 SUBINFO **ppsi; int num; ppsi=GetOverloadSubHash(name,&num); if(!num){ HeapDefaultFree(ppsi); SetError(27,name,cp); return; } //オーバーロードを解決 extern PROCPTRINFO *pProcPtrInfo; psi=OverloadSolution(name,ppsi,num,pProcPtrInfo[ProcPtr_BaseIndex].pParmInfo,pProcPtrInfo[ProcPtr_BaseIndex].ParmNum,NULL); HeapDefaultFree(ppsi); 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; GetObjectName(name,ObjectName,&RefType); if(ObjectName[0]){ if(lstrcmpi(ObjectName,"Super")==0) goto InClassMember; else{ RELATIVE_VAR RelativeVar; int type; if(!GetVarOffset(1,ObjectName,&type,&RelativeVar,(LONG_PTR *)&pobj_c)) return; SetVarPtrToEax(&RelativeVar); //mov ecx,eax op_mov_RR(REG_ECX,REG_EAX); //参照タイプが整合しているかをチェック if(type!=RefType) SetError(104,ObjectName,cp); if(type==DEF_PTR_OBJECT){ //mov ecx,dword ptr[ecx] op_mov_RM(sizeof(long),REG_ECX,REG_ECX,0,MOD_BASE); } } } else{ InClassMember: //自身のオブジェクトのThisポインタをrcxにコピー SetThisPtrToReg(REG_RCX); pobj_c=pobj_CompilingClass; } //仮想関数(オブジェクトメソッド) //pObj->func_table->func1 // ->func2 // ->func3 //mov edx,dword ptr[ecx] OpBuffer[obp++]=(char)0x8B; OpBuffer[obp++]=(char)0x11; int i,i2; for(i=0,i2=0;iiMethodNum;i++){ if(pobj_c->ppobj_Method[i]->psi==psi) break; if(pobj_c->ppobj_Method[i]->psi->bVirtual) i2++; } //mov eax,dword ptr[edx+func_index] if(i2*PTR_SIZE<=0x7F){ op_mov_RM(sizeof(long),REG_EAX,REG_EDX,i2*PTR_SIZE,MOD_BASE_DISP8); } else{ op_mov_RM(sizeof(long),REG_EAX,REG_EDX,i2*PTR_SIZE,MOD_BASE_DISP32); } } else{ //一般の関数 //mov eax,ProcAddr OpBuffer[obp++]=(char)0xB8; pobj_SubAddrSchedule->add(psi,0); obp+=sizeof(long); } psi->bUse=1; } void Opcode_Func_SizeOf(char *Parameter){ int type,size; LONG_PTR lpIndex; type=GetTypeFixed(Parameter,&lpIndex); if(type==-1){ extern int cp; SetError(3,Parameter,cp); return; } size=GetTypeSize(type,lpIndex); //mov eax,size OpBuffer[obp++]=(char)0xB8; *((long *)(OpBuffer+obp))=size; obp+=sizeof(long); } void Opcode_Func_VarPtr(char *Parameter){ int type; RELATIVE_VAR RelativeVar; //変数のアドレスを取得 if(!GetVarOffset(1,Parameter,&type,&RelativeVar,0)) return; SetVarPtrToEax(&RelativeVar); } void Opcode_Func_GetPtrData(char *Parameter,int type){ int i2; i2=NumOpe(Parameter,0,0,0); ChangeTypeToLong(i2); if(type==DEF_DOUBLE){ //pop eax op_pop(REG_EAX); //fld qword ptr[eax] OpBuffer[obp++]=(char)0xDD; OpBuffer[obp++]=(char)0x00; } else if(type==DEF_SINGLE||type==DEF_DWORD){ //pop eax op_pop(REG_EAX); //mov eax,dword ptr[eax] OpBuffer[obp++]=(char)0x8B; OpBuffer[obp++]=(char)0x00; } else if(type==DEF_QWORD){ //pop ecx op_pop(REG_ECX); //mov eax,dword ptr[ecx] op_mov_RM(sizeof(long),REG_EAX,REG_ECX,0,MOD_BASE); //mov edx,dword ptr[ecx+sizeof(long)] op_mov_RM(sizeof(long),REG_EDX,REG_ECX,sizeof(long),MOD_BASE_DISP8); } else if(type==DEF_WORD){ //pop ebx op_pop(REG_EBX); //xor eax,eax OpBuffer[obp++]=(char)0x33; OpBuffer[obp++]=(char)0xC0; //mov ax,word ptr[ebx] OpBuffer[obp++]=(char)0x66; OpBuffer[obp++]=(char)0x8B; OpBuffer[obp++]=(char)0x03; } else if(type==DEF_BYTE){ //pop ebx op_pop(REG_EBX); //xor eax,eax OpBuffer[obp++]=(char)0x33; OpBuffer[obp++]=(char)0xC0; //mov al,byte ptr[ebx] OpBuffer[obp++]=(char)0x8A; OpBuffer[obp++]=(char)0x03; } } int Opcode_CallFunc(char *Parameter,int FuncNum){ switch(FuncNum){ case FUNC_FIX: Opcode_Func_Fix(Parameter); return DEF_LONG; case FUNC_CUDBL: Opcode_Func_CUDbl(Parameter); return DEF_DOUBLE; case FUNC_LEN: Opcode_Func_Len(Parameter); return DEF_LONG; case FUNC_ADDRESSOF: Opcode_Func_AddressOf(Parameter); return DEF_PTR_VOID; case FUNC_SIZEOF: Opcode_Func_SizeOf(Parameter); return DEF_LONG; case FUNC_VARPTR: Opcode_Func_VarPtr(Parameter); return DEF_PTR_VOID; case FUNC_GETDOUBLE: Opcode_Func_GetPtrData(Parameter,DEF_DOUBLE); return DEF_DOUBLE; case FUNC_GETSINGLE: Opcode_Func_GetPtrData(Parameter,DEF_SINGLE); return DEF_SINGLE; case FUNC_GETQWORD: Opcode_Func_GetPtrData(Parameter,DEF_QWORD); return DEF_QWORD; case FUNC_GETDWORD: Opcode_Func_GetPtrData(Parameter,DEF_DWORD); return DEF_DWORD; case FUNC_GETWORD: Opcode_Func_GetPtrData(Parameter,DEF_WORD); return DEF_WORD; case FUNC_GETBYTE: Opcode_Func_GetPtrData(Parameter,DEF_BYTE); return DEF_BYTE; } return 0; }