#include "../BasicCompiler_Common/common.h" #include "Opcode.h" void ChangeTypeToDouble_ToFpuReg(int OldType){ //現在のスタックの内容を実数レジスタに保存する //NumOpeの直後専用 if(OldType==DEF_DOUBLE){ //fld qword ptr[esp] op_fld_ptr_esp(DEF_DOUBLE); //add esp,8 op_add_esp(8); } else if(OldType==DEF_SINGLE){ //fld dword ptr[esp] op_fld_ptr_esp(DEF_SINGLE); //add esp,4 op_add_esp(4); } else if(OldType==DEF_LONG){ //fild dword ptr[esp] op_fld_ptr_esp(DEF_LONG); //add esp,4 op_add_esp(4); } else if(OldType==DEF_DWORD){ //pop eax op_pop(REG_EAX); //push 0 op_push_value(0); //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 ChangeTypeToDouble(int OldType){ //現在のスタックの内容をdouble型に変換する //NumOpeの直後専用 if(OldType==DEF_DOUBLE) return; else if(OldType==DEF_SINGLE){ //fld dword ptr[esp] op_fld_ptr_esp(DEF_SINGLE); //sub esp,4 op_sub_esp(4); //fstp qword ptr[esp] OpBuffer[obp++]=(char)0xDD; OpBuffer[obp++]=(char)0x1C; OpBuffer[obp++]=(char)0x24; } else if(OldType==DEF_INT64||OldType==DEF_QWORD){ //64ビット整数型 //fild qword ptr[esp] op_fld_ptr_esp(DEF_INT64); //fstp qword ptr[esp] OpBuffer[obp++]=(char)0xDD; OpBuffer[obp++]=(char)0x1C; OpBuffer[obp++]=(char)0x24; } else if(IsWholeNumberType(OldType)){ //その他整数型 if(IsSignedType(OldType)){ //符号あり if(OldType==DEF_INTEGER){ //pop eax op_pop(REG_EAX); //movsx eax,ax OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0xBF; OpBuffer[obp++]=(char)0xC0; //push eax op_push(REG_EAX); } else if(OldType==DEF_CHAR){ //pop eax op_pop(REG_EAX); //movsx eax,al OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0xBE; OpBuffer[obp++]=(char)0xC0; //push eax op_push(REG_EAX); } //fild dword ptr[esp] op_fld_ptr_esp(DEF_LONG); //sub esp,4 op_sub_esp(4); } else{ //符号なし //pop eax op_pop(REG_EAX); //push 0 op_push_value(0); //push eax op_push(REG_EAX); //fild qword ptr[esp] OpBuffer[obp++]=(char)0xDF; OpBuffer[obp++]=(char)0x2C; OpBuffer[obp++]=(char)0x24; } //fstp qword ptr[esp] OpBuffer[obp++]=(char)0xDD; OpBuffer[obp++]=(char)0x1C; OpBuffer[obp++]=(char)0x24; } else SetError(9,NULL,cp); } void ChangeTypeToSingle(int OldType){ //現在のスタックの内容をfloat型に変換する //NumOpeの直後専用 if(OldType==DEF_SINGLE) return; else if(OldType==DEF_DOUBLE){ //fld qword ptr[esp] op_fld_ptr_esp(DEF_DOUBLE); //add esp,4 op_add_esp(4); //fstp dword ptr[esp] OpBuffer[obp++]=(char)0xD9; OpBuffer[obp++]=(char)0x1C; OpBuffer[obp++]=(char)0x24; } else if(OldType==DEF_INT64||OldType==DEF_QWORD){ //64ビット整数型 //fild qword ptr[esp] op_fld_ptr_esp(DEF_INT64); //add esp,4 op_add_esp(4); //fstp dword ptr[esp] OpBuffer[obp++]=(char)0xD9; OpBuffer[obp++]=(char)0x1C; OpBuffer[obp++]=(char)0x24; } else if(IsWholeNumberType(OldType)){ //その他整数型 if(IsSignedType(OldType)){ //符号あり if(OldType==DEF_INTEGER){ //pop eax op_pop(REG_EAX); //movsx eax,ax OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0xBF; OpBuffer[obp++]=(char)0xC0; //push eax op_push(REG_EAX); } else if(OldType==DEF_CHAR){ //pop eax op_pop(REG_EAX); //movsx eax,al OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0xBE; OpBuffer[obp++]=(char)0xC0; //push eax op_push(REG_EAX); } //fild dword ptr[esp] op_fld_ptr_esp(DEF_LONG); } else{ //符号なし //fild dword ptr[esp] op_fld_ptr_esp(DEF_LONG); } //fstp dword ptr[esp] OpBuffer[obp++]=(char)0xD9; OpBuffer[obp++]=(char)0x1C; OpBuffer[obp++]=(char)0x24; } else SetError(9,NULL,cp); } void ChangeTypeToInt64(int OldType){ //現在のスタックの内容をInt64型に変換する //NumOpeの直後専用 if(Is64Type(OldType)) return; else if(OldType==DEF_DOUBLE){ //fld qword ptr[esp] op_fld_ptr_esp(DEF_DOUBLE); //fistp qword ptr[esp] fpu_cast(); OpBuffer[obp++]=(char)0xDF; OpBuffer[obp++]=(char)0x3C; OpBuffer[obp++]=(char)0x24; fpu_cast_end(); } else if(OldType==DEF_SINGLE){ //fld dword ptr[esp] op_fld_ptr_esp(DEF_SINGLE); //sub esp,4 op_sub_esp(4); //fistp qword ptr[esp] fpu_cast(); OpBuffer[obp++]=(char)0xDF; OpBuffer[obp++]=(char)0x3C; OpBuffer[obp++]=(char)0x24; fpu_cast_end(); } else if(IsWholeNumberType(OldType)){ //その他整数 if(IsSignedType(OldType)){ //符号あり //pop eax op_pop(REG_EAX); //cdq op_cdq(); //push edx op_push(REG_EDX); //push eax op_push(REG_EAX); } else{ //符号なし //pop eax op_pop(REG_EAX); //push 0 op_push_value(0); //push eax op_push(REG_EAX); } } else SetError(9,NULL,cp); } void ChangeTypeToLong(int OldType){ //現在のスタックの内容をLong型に変換する //NumOpeの直後専用 if(OldType==DEF_DOUBLE){ //fld qword ptr[esp] op_fld_ptr_esp(DEF_DOUBLE); //add esp,4 op_add_esp(4); //fistp dword ptr[esp] fpu_cast(); OpBuffer[obp++]=(char)0xDB; OpBuffer[obp++]=(char)0x1C; OpBuffer[obp++]=(char)0x24; fpu_cast_end(); } else if(OldType==DEF_SINGLE){ //fld dword ptr[esp] op_fld_ptr_esp(DEF_SINGLE); //fistp dword ptr[esp] fpu_cast(); OpBuffer[obp++]=(char)0xDB; OpBuffer[obp++]=(char)0x1C; OpBuffer[obp++]=(char)0x24; fpu_cast_end(); } else if(OldType==DEF_INT64||OldType==DEF_QWORD){ //pop eax op_pop(REG_EAX); //add esp,4 op_add_esp(4); //push eax op_push(REG_EAX); } } void ChangeTypeToInteger(int OldType){ //現在のスタックの内容をInteger型に変換する if(OldType==DEF_BYTE|| OldType==DEF_WORD||OldType==DEF_INTEGER) return; else if(OldType==DEF_CHAR){ //pop eax op_pop(REG_EAX); //movsx eax,al OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0xBE; OpBuffer[obp++]=(char)0xC0; //push eax op_push(REG_EAX); } else{ ChangeTypeToLong(OldType); //pop eax op_pop(REG_EAX); //and eax,0000FFFFh OpBuffer[obp++]=(char)0x25; *((long *)(OpBuffer+obp))=0x0000FFFF; obp+=sizeof(long); //push eax op_push(REG_EAX); } } void ChangeTypeToByte(int OldType){ //現在のスタックの内容をbyte型に変換する if(OldType==DEF_BYTE||OldType==DEF_CHAR) return; ChangeTypeToLong(OldType); //pop eax op_pop(REG_EAX); //and eax,000000FFh OpBuffer[obp++]=(char)0x25; *((long *)(OpBuffer+obp))=0x000000FF; obp+=sizeof(long); //push eax op_push(REG_EAX); } void OpcodeCalc(char *Command){ int i,i2,i3; char variable[VN_SIZE]; for(i=0;;i++){ if(Command[i]=='\"'){ //ダブルクォートは不正なのでエラー扱い variable[i]=0; SetError(3,variable,cp); return; } if(Command[i]=='('){ i2=GetStringInPare(variable+i,Command+i); i+=i2-1; continue; } if(Command[i]=='['){ i2=GetStringInBracket(variable+i,Command+i); i+=i2-1; continue; } if(Command[i]=='\0'){ /////////////////////////////////// // インクリメント・デクリメント /////////////////////////////////// if(i>2){ if(Command[i-2]=='+'&&Command[i-1]=='+'){ //インクリメント variable[i-2]=0; IncDec(CALC_ADDITION,variable,"1"); return; } else if(Command[i-2]=='-'&&Command[i-1]=='-'){ //デクリメント variable[i-2]=0; IncDec(CALC_SUBTRACTION,variable,"1"); return; } } //先端部分の識別子をエラーキーワードにする for(i=0;;i++){ if(!IsVariableChar(Command[i])){ variable[i]=0; break; } variable[i]=Command[i]; } LONG_PTR lp; if(GetVarType(variable,&lp,0)!=-1){ //変数リストに該当したとき SetError(1,NULL,cp); } else{ if(GetConstHash(variable)){ //定数リストに該当したとき SetError(1,NULL,cp); } else{ //変数リスト、定数リストに該当しないとき SetError(3,variable,cp); } } return; } i2=GetCalcId(Command+i,&i3); if(i2){ variable[i]=0; if(Command[i]=='=') break; if(Command[i+1+i3]=='='){ IncDec(i2,variable,Command+i+1+i3+1); return; } } variable[i]=Command[i]; } if(Command[i+1]=='\0'){ SetError(1,NULL,cp); return; } /////////////////////////////////////////////////////////////// // インデクサのsetアクセサ([]=演算子のオーバーロードに対応) /////////////////////////////////////////////////////////////// char ObjName[VN_SIZE],array_element[VN_SIZE]; CClass *pobj_c; GetArrayElement(variable,ObjName,array_element); if(array_element[0]){ i2=GetVarType(ObjName,(LONG_PTR *)&pobj_c,0); if(i2==DEF_OBJECT){ char temporary[VN_SIZE]; sprintf(temporary,"%s.%c%c%c",ObjName,1,ESC_OPERATOR,CALC_ARRAY_SET); char temp2[VN_SIZE]; sprintf(temp2,"%s,%s",array_element,Command+i+1); int idProc; void *pInfo; idProc=GetProc(temporary,&pInfo); if(idProc){ CallProc(idProc,pInfo,temporary,temp2,NULL); return; } } } //////////////////////////////////////// // 変数のタイプ型を識別して、演算を行う //////////////////////////////////////// int VarType,CalcType; LONG_PTR lpVarIndex,lpCalcIndex; RELATIVE_VAR VarRelativeVar; BOOL bCalcUseHeap; //型を識別 VarType=GetVarType(variable,&lpVarIndex,0); if(VarType==-1){ // プロパティ用のメソッドを呼び出す if(!CallPropertyMethod(variable,Command+i+1,NULL)){ //エラーを表示 GetVarType(variable,&lpVarIndex,1); } return; } extern LONG_PTR ProcPtr_BaseIndex; if(VarType==DEF_PTR_PROC) ProcPtr_BaseIndex=lpVarIndex; else ProcPtr_BaseIndex=-1; if(VarType==DEF_OBJECT){ //代入演算のオーバーロード オペレータに備える //変数アドレスを取得 if(!GetVarOffsetReadWrite( variable, &VarType, &VarRelativeVar, &lpVarIndex)) return; SetVarPtrToEax(&VarRelativeVar); //push eax op_push(REG_EAX); } //NumOpe...(スタックに答えが格納される) CalcType=NumOpe(Command+i+1,VarType,lpVarIndex,&lpCalcIndex,&bCalcUseHeap); if(VarType==-1||CalcType==-1) return; //変数アドレスを取得 if(!GetVarOffsetReadWrite( variable, &VarType, &VarRelativeVar, &lpVarIndex)) return; if(VarType&FLAG_PTR){ SetError(14,variable,cp); return; } if(VarType==DEF_OBJECT){ //オブジェクトインスタンスへの代入 SetObjectVariable(lpVarIndex,CalcType,lpCalcIndex,bCalcUseHeap); return; } if(CalcType==DEF_OBJECT){ //キャスト演算子のオーバーロードに対応する CallCastOperatorProc(CalcType,lpCalcIndex,bCalcUseHeap,VarType,lpVarIndex); } ///////////////////////////////// // 右辺、左辺の型チェックを行う ///////////////////////////////// CheckDifferentType(VarType,lpVarIndex,CalcType,lpCalcIndex,0,0); ///////////////////////////////////////////////// // スタックの内容を変数にコピーするコードを抽出 ///////////////////////////////////////////////// if(VarType==DEF_CHAR||VarType==DEF_BYTE){ //8ビット整数型変数へスタックの内容を格納する Set8Variable(CalcType,VarRelativeVar.dwKind,VarRelativeVar.offset,VarRelativeVar.bOffsetOffset); } else if(VarType==DEF_INTEGER||VarType==DEF_WORD){ //16ビット整数型変数へスタックの内容を格納する Set16Variable(CalcType,VarRelativeVar.dwKind,VarRelativeVar.offset,VarRelativeVar.bOffsetOffset); } else if(VarType==DEF_LONG||VarType==DEF_DWORD||IsPtrType(VarType)){ //32ビット整数型変数へスタックの内容を格納する if(VarType==DEF_LONG) SetLongVariable(CalcType,VarRelativeVar.dwKind,VarRelativeVar.offset,VarRelativeVar.bOffsetOffset); else SetDWordVariable(CalcType,VarRelativeVar.dwKind,VarRelativeVar.offset,VarRelativeVar.bOffsetOffset); } else if(VarType==DEF_INT64||VarType==DEF_QWORD){ //64ビット整数型変数へスタックの内容を格納する SetInt64Variable(CalcType,&VarRelativeVar); } else if(VarType==DEF_DOUBLE){ //Double型変数へスタックの内容を格納する SetDoubleVariable(CalcType,VarRelativeVar.dwKind,VarRelativeVar.offset,VarRelativeVar.bOffsetOffset); } else if(VarType==DEF_SINGLE){ //Single型変数へスタックの内容を格納する SetSingleVariable(CalcType,VarRelativeVar.dwKind,VarRelativeVar.offset,VarRelativeVar.bOffsetOffset); } }