#include "../BasicCompiler_Common/common.h" #include "Opcode.h" void NewStringObject(int reg, const char *str){ /////////////////////////////////////////////////////// // lpszTextを元にStringオブジェクトを生成し、 // オブジェクトポインタをregに格納する /////////////////////////////////////////////////////// ////////////////////////////////////////////////////// ///// レジスタ資源のバックアップ { BACKUP_REGISTER_RESOURCE ////////////////////////////////////////////////////// char *parameter = (char *)malloc( lstrlen( str ) + 32 ); sprintf( parameter, "\"%s\"%c%c*Char", str, 1, ESC_AS ); SetStringQuotes( parameter ); Operator_New( *pobj_DBClass->GetStringClassPtr(), "", parameter, Type( DEF_OBJECT, *pobj_DBClass->GetStringClassPtr() ) ); free( parameter ); //mov reg,rax op_mov_RR( reg, REG_RAX ); ///////////////////////////////////////////// ////// レジスタ資源を復元 RESTORE_REGISTER_RESOURCE }//////////////////////////////////////////// } void SetUseRegFromRax(int type,int UseReg,int XmmReg){ if(IsRealNumberType(type)){ //実数型 if(XmmReg==REG_XMM4){ if(type==DEF_DOUBLE){ //movsd qword ptr[rsp+offset],xmm0 ※スタックフレームを利用 pobj_sf->push(REG_XMM0,sizeof(double)); } if(type==DEF_SINGLE){ //movss dword ptr[rsp+offset],xmm0 ※スタックフレームを利用 pobj_sf->push(REG_XMM0,sizeof(float)); } } else{ if(type==DEF_DOUBLE){ //movsd xmm_reg,xmm0 op_movsd_RR(XmmReg,REG_XMM0); } else if(type==DEF_SINGLE){ //movss xmm_reg,xmm0 op_movss_RR(XmmReg,REG_XMM0); } } } else{ //整数型 if(UseReg==REG_R14){ //mov qword ptr[rsp+offset],rax ※スタックフレームを利用 pobj_sf->push(REG_RAX); } else{ //mov reg,rax op_mov_RR(UseReg,REG_RAX); } } } void ExtendRegToBigType( int reg, int bigBasicType, int baseBasicType ){ switch( Type::GetBasicSize( bigBasicType ) ){ case sizeof(_int64): ExtendTypeTo64(baseBasicType,reg); break; case sizeof(long): ExtendTypeTo32(baseBasicType,reg); break; case sizeof(short): ExtendTypeTo16(baseBasicType,reg); break; } } bool VarToReg( RELATIVE_VAR &relativeVar, const Type &baseType, Type &resultType ){ int UseReg=pobj_reg->GetNextReg(); int XmmReg=pobj_reg->GetNextXmmReg(); //大きな型への暗黙の変換 int bigType = AutoBigCast(baseType.GetBasicType(),resultType.GetBasicType()); if(resultType.GetBasicType()&FLAG_PTR){ //配列ポインタ resultType.SetBasicType( GetPtrType(resultType.GetBasicType()^FLAG_PTR) ); SetVarPtrToReg(UseReg,&relativeVar); } else if(resultType.IsReal()){ //実数型 if( resultType.IsDouble() ) SetXmmReg_DoubleVariable(&relativeVar,XmmReg); if( resultType.IsSingle() ) SetXmmReg_SingleVariable(&relativeVar,XmmReg); } else if( resultType.IsWhole() || resultType.IsObject()){ //整数型 SetReg_WholeVariable(resultType.GetBasicType(),&relativeVar,UseReg); } else if( resultType.IsStruct() ){ //構造体ポインタをUseRegへ格納(構造体は値型) SetVarPtrToReg(UseReg,&relativeVar); } else{ return false; } if( resultType.GetBasicType() != bigType ){ // 大きな型へ変換された場合 // ※レジスタの値をキャストする ExtendRegToBigType( UseReg, bigType, resultType.GetBasicType() ); resultType.SetBasicType( bigType ); } return true; } bool TermMemberOpe( const CClass &objClass, const Type &baseType, Type &resultType, const char *termFull, const char *termLeft, const char *member ){ int UseReg=pobj_reg->GetNextReg(); int XmmReg=pobj_reg->GetNextXmmReg(); if( GetMemberType( objClass, member, resultType, 0, false ) ){ // メンバが見つかったとき //オブジェクトポインタをr11にコピー op_mov_RR( REG_R11, UseReg ); RELATIVE_VAR relativeVar; relativeVar.dwKind=VAR_DIRECTMEM; if( !_member_offset( true, //エラー表示あり false, //読み込み専用 objClass, member,&relativeVar,resultType,0)){ return false; } if( !VarToReg( relativeVar, baseType, resultType ) ){ SetError(11,termFull,cp); } return true; } /////////////////////////////////////////////////////////////////// // 動的メソッドを検索 /////////////////////////////////////////////////////////////////// vector userProcs; char methodName[VN_SIZE], lpPtrOffset[VN_SIZE], parameter[VN_SIZE], dummy[1]; CClass::RefType refType; lstrcpy( methodName, member ); GetVarFormatString(methodName,parameter,lpPtrOffset,dummy,refType); objClass.EnumMethod( methodName, userProcs ); UserProc *pUserProc; if(userProcs.size()){ //オーバーロードを解決 pUserProc=OverloadSolutionWithStrParam(termFull,userProcs,parameter,termLeft); if( pUserProc ){ resultType = pUserProc->ReturnType(); ////////////////////////////////////////////////////// ///// レジスタ資源のバックアップ { BACKUP_REGISTER_RESOURCE ////////////////////////////////////////////////////// //オブジェクトポインタをスタックに入れておく //mov qword ptr[rsp+offset],reg ※スタックフレームを利用 pobj_sf->push( UseReg ); if( !Opcode_CallProc(parameter,pUserProc,PROCFLAG_NEW,termLeft,0 ) ){ //レジスタ資源を復元 RESTORE_REGISTER_RESOURCE return false; } pobj_sf->pop(); ///////////////////// // 戻り値の処理 ///////////////////// //大きな型への暗黙の変換 int bigType = AutoBigCast(baseType.GetBasicType(), resultType.GetBasicType() ); if( resultType.GetBasicType() != bigType ){ // 大きな型へ変換された場合 // ※レジスタの値をキャストする ExtendRegToBigType( REG_RAX, bigType, resultType.GetBasicType() ); resultType.SetBasicType( bigType ); } SetUseRegFromRax(resultType.GetBasicType(),UseReg,XmmReg); ///////////////////////////////////////////// ////// レジスタ資源を復元 RESTORE_REGISTER_RESOURCE }//////////////////////////////////////////// return true; } } return false; } bool TermOpe( const char *term, const Type &baseType, Type &resultType, bool &isLiteral, BOOL *pbUseHeap, bool isWantObject, bool *pIsClassName, bool isProcedureCallOnly ){ char parameter[VN_SIZE]; // Withを解決 char termFull[VN_SIZE]; if(term[0]=='.'){ GetWithName(termFull); lstrcat(termFull,term); } else lstrcpy(termFull,term); char termLeft[VN_SIZE]; lstrcpy(termLeft,termFull); // パース char member[VN_SIZE]; CClass::RefType refType; if( SplitMemberName( termFull, termLeft, member, refType ) ){ /////////////////////////////////////////////////////////////////// // オブジェクトとメンバに分解できるとき // termLeft.member /////////////////////////////////////////////////////////////////// isLiteral = false; // オブジェクト側の型を取得 bool isClassName = false; Type leftType; if( GetTermType( termLeft, leftType, isLiteral, &isClassName ) ){ if( isClassName == false && Smoothie::Meta::blittableTypes.IsExist( leftType ) ){ // 左側のオブジェクト部分がBlittable型のとき char temporary[VN_SIZE]; lstrcpy( temporary, termLeft ); sprintf( termLeft, "%s(%s)", Smoothie::Meta::blittableTypes.Find( leftType ).GetCreateStaticMethodFullName().c_str(), temporary ); } } if( !TermOpe( termLeft, baseType, leftType, isLiteral, pbUseHeap, true, &isClassName ) ){ goto globalArea; } if( isClassName ){ // 静的メンバ/メソッドの場合 goto globalArea; } if( !leftType.HasMember() ){ // メンバを持たない型の場合 return false; } return TermMemberOpe( leftType.GetClass(), baseType, resultType, termFull, termLeft, member ); } globalArea: ////////////////////////////////////////////// // クラス名かどうかをチェック(静的メンバ用) ////////////////////////////////////////////// if( pIsClassName ){ if( pobj_DBClass->Find( termFull ) ){ *pIsClassName = true; return true; } } ///////////////////////////////////////////////////////////////// // グローバル属性エリア ///////////////////////////////////////////////////////////////// int UseReg=pobj_reg->GetNextReg(); int XmmReg=pobj_reg->GetNextXmmReg(); if(lstrcmpi(termFull,"This")==0 && isProcedureCallOnly == false ){ //Thisオブジェクト resultType.SetType( DEF_OBJECT, pobj_CompilingClass ); SetThisPtrToReg( UseReg ); isLiteral = false; return true; } ////////////////////////////////////// // 関数(DLL、ユーザー定義、組み込み) ////////////////////////////////////// char procName[VN_SIZE]; char temporary[8192]; int i2=GetCallProcName(termFull,procName); if(termFull[i2]=='('){ int i4=GetStringInPare_RemovePare(parameter,termFull+i2+1); void *pInfo; int idProc=GetProc(procName,(void **)&pInfo); if(idProc){ //閉じカッコ")"に続く文字がNULLでないとき if(termFull[i2+1+i4+1]!='\0'){ SetError(42,NULL,cp); } ////////////////////////////////////////////////////// ///// レジスタ資源のバックアップ { BACKUP_REGISTER_RESOURCE ////////////////////////////////////////////////////// //////////////// // 呼び出し //////////////// CallProc(idProc,pInfo,procName,parameter,resultType); ///////////////////// // 戻り値の処理 ///////////////////// //大きな型への暗黙の変換 int bigType = AutoBigCast(baseType.GetBasicType(), resultType.GetBasicType() ); if( resultType.GetBasicType() != bigType ){ // 大きな型へ変換された場合 // ※レジスタの値をキャストする ExtendRegToBigType( REG_RAX, bigType, resultType.GetBasicType() ); resultType.SetBasicType( bigType ); } SetUseRegFromRax(resultType.GetBasicType(),UseReg,XmmReg); ///////////////////////////////////////////// ////// レジスタ資源を復元 RESTORE_REGISTER_RESOURCE }//////////////////////////////////////////// if(resultType.IsStruct()){ //構造体が戻ったときはヒープ領域にインスタンスが格納されている //※後にfreeする必要あり // TODO: 解放はGCに任せる *pbUseHeap = 1; } isLiteral = false; return true; } else if(GetConstCalcBuffer(procName,parameter,temporary)){ ///////////////////////// // マクロ関数 ///////////////////////// //閉じカッコ")"に続く文字がNULLでないときはエラーにする if(termFull[i2+1+i4+1]!='\0') SetError(42,NULL,cp); //マクロ関数の場合 NumOpe(&UseReg,temporary,Type(),resultType); if(!IS_LITERAL(resultType.GetIndex())){ //リテラル値ではなかったとき isLiteral = false; } return true; } } else if( isProcedureCallOnly ){ // 関数呼び出し以外は受け付けない return false; } //////////////////////////////// // インデクサ(getアクセサ) //////////////////////////////// char VarName[VN_SIZE],ArrayElements[VN_SIZE]; GetArrayElement(termFull,VarName,ArrayElements); if(ArrayElements[0]){ GetVarType(VarName,resultType,false); if( resultType.IsObject() ){ CallIndexerGetterProc(UseReg,&resultType.GetClass(),VarName,ArrayElements,resultType); isLiteral = false; return true; } } //////////////////////////////// // 変数 //////////////////////////////// RELATIVE_VAR relativeVar; if(GetVarOffset( false, //エラー表示なし false, //読み込み専用 termFull, &relativeVar,resultType)){ ////////// // 変数 ////////// if( !VarToReg( relativeVar, baseType, resultType ) ){ SetError(11,termFull,cp); } isLiteral = false; return true; } /* //////////////////////////////// // 型名 //////////////////////////////// if( Type::StringToType( termFull, resultType ) ){ resultType.SetBasicType( resultType.GetBasicType() | FLAG_CAST ); return true; }*/ ///////////////////////////////// // プロパティ用のメソッド ///////////////////////////////// //配列要素を排除 GetArrayElement(termFull,VarName,ArrayElements); if(GetSubHash(VarName,0)){ ////////////////////////////////////////////////////// ///// レジスタ資源のバックアップ { BACKUP_REGISTER_RESOURCE ////////////////////////////////////////////////////// CallPropertyMethod(termFull,NULL,resultType); //大きな型への暗黙の変換 int bigType = AutoBigCast(baseType.GetBasicType(), resultType.GetBasicType() ); if( resultType.GetBasicType() != bigType ){ // 大きな型へ変換された場合 // ※レジスタの値をキャストする ExtendRegToBigType( REG_RAX, bigType, resultType.GetBasicType() ); resultType.SetBasicType( bigType ); } SetUseRegFromRax(resultType.GetBasicType(),UseReg,XmmReg); ///////////////////////////////////////////// ////// レジスタ資源を復元 RESTORE_REGISTER_RESOURCE }//////////////////////////////////////////// if(resultType.IsStruct()){ //構造体が戻ったときはヒープ領域にインスタンスが格納されている //※後にfreeする必要あり // TODO: 解放はGCに任せる *pbUseHeap = 1; } isLiteral = false; return true; } return false; } bool NumOpe( int *pReg, const char *expression, const Type &baseType, Type &resultType, BOOL *pbUseHeap ){ int i,i2,i3; char temporary[1024],temp2[1024]; if(expression[0]=='\0'){ SetError(1,NULL,cp); return false; } if(expression[0]==1&& expression[1]==ESC_NEW ){ //New演算子(オブジェクト生成) if( !Operator_New( expression+2, baseType, resultType ) ){ return false; } //mov reg,rax op_mov_RR( *pReg, REG_RAX ); return true; } if( !baseType.IsNull() && expression[0] == '[' ){ // リテラル配列の場合 if( !baseType.IsPointer() ){ SetError(1,NULL,cp); return false; } Type tempBaseType( baseType ); tempBaseType.PtrLevelDown(); char *buffer = (char *)malloc( lstrlen( expression ) + 1 ); lstrcpy( buffer, expression ); RemoveStringBracket( buffer ); void *binary = malloc( 1 ); int num = 0; i = 0; while( buffer[i] ){ i = GetOneParameter( buffer, i, temporary ); if( buffer[i] == ',' ){ i++; } Type resultType; _int64 i64data; if( !StaticCalculation( true, temporary, tempBaseType.GetBasicType(), &i64data, resultType ) ){ return false; } if( !resultType.IsWhole() ){ // TODO: 実数に未対応 SetError(); return false; } binary = realloc( binary, ( num + 1 ) * tempBaseType.GetSize() ); memcpy( (char *)binary + (num * tempBaseType.GetSize()), &i64data, tempBaseType.GetSize() ); num++; } i2 = dataTable.AddBinary( binary, num * tempBaseType.GetSize() ); //mov reg,i2 op_mov_RV(sizeof(_int64),*pReg,i2); obp-=sizeof(long); pobj_DataTableSchedule->add(); obp+=sizeof(long); free( buffer ); resultType = baseType; return true; } ///////////////////////////////// // 式要素を逆ポーランド式で取得 ///////////////////////////////// char *values[255]; long calc[255]; long stack[255]; int pnum; if(!GetNumOpeElements(expression,&pnum,values,calc,stack)){ for(i=0;inum; //リテラル演算の場合を考慮した演算前のデータテーブルスケジュール位置 int Before_DataTableScheduleNum; Before_DataTableScheduleNum=pobj_DataTableSchedule->num; //リテラル演算の場合を考慮した演算前の再配置スケジュール CReloc *pobj_BackReloc; pobj_BackReloc=new CReloc(); pobj_BackReloc->copy(pobj_Reloc); //リテラル演算の場合を考慮した演算前のスタックフレームスケジュール位置 int Before_StackFrameScheduleNum; Before_StackFrameScheduleNum=pobj_sf->num; double dbl; int sp; int type_stack[255]; LONG_PTR index_stack[255]; bool isNothing_stack[255]; BOOL bUseHeap[255]; _int64 i64data; int UseReg,XmmReg; BOOL bXmm; for(i=0,sp=0;iIsEqualsOrSubClass( (CClass *)index_stack[sp-2] ) || ((CClass *)index_stack[sp-2])->IsEqualsOrSubClass( (CClass *)index_stack[sp-1] ) )){ // ダウンキャストを許可する } else{ //オーバーロードされたオペレータを呼び出す i2=CallOperatorProc(idCalc,baseType,type_stack,index_stack,bUseHeap,sp); if(i2==0){ if(idCalc==CALC_EQUAL) lstrcpy(temp2,"=="); else GetCalcName(idCalc,temp2); sprintf(temporary,"Operator %s",temp2); SetError(27,temporary,cp); goto error; } else if(i2==-1) goto error; continue; } } if(!CheckCalcType(idCalc,type_stack,sp)) goto error; } switch(idCalc){ //数値 case 0: index_stack[sp]=-1; isNothing_stack[sp] = false; bUseHeap[sp]=0; UseReg=pobj_reg->GetNextReg(); XmmReg=pobj_reg->GetNextXmmReg(); bXmm=0; char *term; term=values[i]; if( calc[i+1]%100 == CALC_AS ){ // As演算子の右辺値 //型名 if( Type::StringToType( term, resultType ) ){ resultType.SetBasicType( resultType.GetBasicType() | FLAG_CAST ); } else{ SetError(3, term, cp ); goto error; } type_stack[sp] = resultType.GetBasicType(); index_stack[sp] = resultType.GetIndex(); sp++; break; } if(term[0]=='\"'){ //リテラル文字列 if(!RemoveStringQuotes(term)){ SetError(43,NULL,cp); goto error; } i3=lstrlen(term); StrLiteral: if( baseType.IsObject() || baseType.IsNull() ){ //要求タイプがオブジェクト、または未定のとき //String型オブジェクトを生成 NewStringObject(UseReg,term); type_stack[sp]=DEF_OBJECT; index_stack[sp]=(LONG_PTR)pobj_DBClass->GetStringClassPtr(); bLiteralCalculation=0; if(bXmm) pobj_reg->LockXmmReg(); else pobj_reg->LockReg(); sp++; break; } type_stack[sp]=typeOfPtrChar; bLiteralCalculation=0; i2 = dataTable.AddString( term, i3 ); //mov reg,i2 op_mov_RV(sizeof(_int64),UseReg,i2); obp-=sizeof(long); pobj_DataTableSchedule->add(); obp+=sizeof(long); if(UseReg==REG_R14){ //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用 pobj_sf->push(REG_R14); } } else if((term[0]=='e'||term[0]=='E')&& (term[1]=='x'||term[1]=='X')&& term[2]=='\"'){ //拡張版リテラル文字列(エスケープシーケンス可能) if(!RemoveStringQuotes(term+2)){ SetError(43,NULL,cp); goto error; } i3=FormatString_EscapeSequence(term+2); term+=2; goto StrLiteral; } else if(IsVariableTopChar(term[0])|| term[0]=='*'|| (term[0]=='.'&&IsVariableTopChar(term[1]))){ ////////////////// // 何らかの識別子 bool isLiteral; if( TermOpe( term, baseType, resultType, isLiteral, &bUseHeap[sp] ) ){ if(resultType.IsNull()){ //戻り値が存在しないとき for(i2=0;;i2++){ if(term[i2]=='('||term[i2]=='\0'){ term[i2]=0; break; } } SetError(38,term,cp); goto error; } type_stack[sp] = resultType.GetBasicType(); index_stack[sp] = resultType.GetIndex(); if( !isLiteral ){ bLiteralCalculation=0; } if( resultType.GetBasicType() & FLAG_CAST ){ // 型名のみ SetError(); } else{ if( resultType.IsReal() == false && UseReg==REG_R14 ){ //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用 pobj_sf->push(REG_R14); } if( resultType.IsReal() && XmmReg==REG_XMM4 ){ if(resultType.IsDouble()){ //movsd qword ptr[rsp+offset],xmm4 ※スタックフレームを利用 pobj_sf->push(REG_XMM4,sizeof(double)); } if(resultType.IsSingle()){ //movss dword ptr[rsp+offset],xmm4 ※スタックフレームを利用 pobj_sf->push(REG_XMM4,sizeof(float)); } } if( resultType.IsReal() ){ pobj_reg->LockXmmReg(); } else{ pobj_reg->LockReg(); } } sp++; break; } // Nothing if( lstrcmp( term, "Nothing" ) == 0 ){ isNothing_stack[sp] = true; type_stack[sp] = DEF_OBJECT; if( baseType.IsObject() ){ index_stack[sp] = baseType.GetIndex(); } else{ index_stack[sp] = (LONG_PTR)pobj_DBClass->GetObjectClassPtr(); } bLiteralCalculation = 0; //xor reg,reg op_zero_reg( UseReg ); if(UseReg==REG_R14){ //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用 pobj_sf->push(REG_R14); } pobj_reg->LockReg(); sp++; break; } ////////////// // 定数の場合 ////////////// i3 = CDBConst::obj.GetBasicType(term); if(i3){ if( CDBConst::obj.IsStringPtr( term ) ){ //リテラル文字列 double dbl = CDBConst::obj.GetDoubleData(term); memcpy(&i64data,&dbl,sizeof(double)); //バイト数 i3=lstrlen((char *)i64data); memcpy(term,(char *)i64data,i3); term[i3]=0; goto StrLiteral; } type_stack[sp] = i3; if(IsRealNumberType(i3)){ //実数 double dbl = CDBConst::obj.GetDoubleData(term); memcpy(&i64data,&dbl,sizeof(double)); goto Literal; } else if(IsWholeNumberType(i3)){ //整数 i64data = CDBConst::obj.GetWholeData(term); goto Literal; } /*else if(i3==DEF_STRING){ //リテラル文字列 //バイト数 i3=(int)dbl; memcpy(term,temporary,i3); goto StrLiteral; }*/ else{ SetError(1,NULL,0); goto error; } } //該当する識別子が見当たらないときはエラー扱いにする bError=1; SetError(3,term,cp); type_stack[sp]=DEF_DOUBLE; } else{ //リテラル値 type_stack[sp]=GetLiteralValue(term,&i64data,baseType.GetBasicType()); Literal: if(type_stack[sp]==DEF_DOUBLE){ //64ビット浮動小数型 bXmm=1; if(XmmReg==REG_XMM4){ //mov r14,i64data op_mov64_ToReg(REG_R14,i64data); //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用 pobj_sf->push(REG_R14); } else{ i3 = dataTable.Add( i64data ); //movlpd xmm_reg,qword ptr[data table offset] OpBuffer[obp++]=(char)0x66; OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0x12; OpBuffer[obp++]=(char)(0x04 | REGISTER_OPERAND(XmmReg)<<3); OpBuffer[obp++]=(char)0x25; *((long *)(OpBuffer+obp))=i3; pobj_DataTableSchedule->add(); obp+=sizeof(long); } } else if(type_stack[sp]==DEF_SINGLE){ //32ビット浮動小数型 bXmm=1; float flt; int i32data; memcpy(&dbl,&i64data,sizeof(double)); flt=(float)dbl; memcpy(&i32data,&flt,sizeof(long)); if(XmmReg==REG_XMM4){ SetError(); // TODO: 未実装 //push term op_push_value(i32data); } else{ i3=dataTable.Add( i32data ); //movss xmm_reg,dword ptr[data table offset] OpBuffer[obp++]=(char)0xF3; OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0x10; OpBuffer[obp++]=(char)(0x04 | REGISTER_OPERAND(XmmReg)<<3); OpBuffer[obp++]=(char)0x25; *((long *)(OpBuffer+obp))=i3; pobj_DataTableSchedule->add(); obp+=sizeof(long); } } else{ //整数 index_stack[sp]=GetLiteralIndex(i64data); //mov reg,i64data op_mov64_ToReg(UseReg,i64data); if(UseReg==REG_R14){ //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用 pobj_sf->push(REG_R14); } } } if(bXmm) pobj_reg->LockXmmReg(); else pobj_reg->LockReg(); sp++; break; //論理演算子 case CALC_XOR: case CALC_OR: case CALC_AND: if(!CalcTwoTerm_Logical(idCalc,type_stack,index_stack,&sp)) goto error; break; case CALC_NOT: //value[sp-1]=Not value[sp-1] //NOT演算子 if(!Calc_Not(type_stack,sp)) goto error; break; //比較演算子 case CALC_PE: //value[sp-2] <= value[sp-1] case CALC_QE: //value[sp-2] >= value[sp-1] case CALC_P: //value[sp-2] < value[sp-1] case CALC_Q: //value[sp-2] > value[sp-1] case CALC_NOTEQUAL: //value[sp-2] <> value[sp-1] case CALC_EQUAL: //value[sp-2] = value[sp-1] if(!CalcTwoTerm_Relational(idCalc,type_stack,index_stack,&sp)) goto error; break; //ビットシフト case CALC_SHL: //value[sp-2] << value[sp-1] case CALC_SHR: //value[sp-2] >> value[sp-1] if(!Calc_Shift(idCalc,type_stack,&sp)) goto error; break; //算術演算 case CALC_ADDITION: case CALC_SUBTRACTION: case CALC_PRODUCT: if(!CalcTwoTerm_Arithmetic(idCalc,type_stack,index_stack,&sp)) goto error; break; case CALC_MOD: //value[sp-2]%=value[sp-1] //剰余演算 if(!Calc_Mod(type_stack,index_stack,&sp)) goto error; break; case CALC_QUOTIENT: //value[sp-2]/=value[sp-1]; //除算 if(!Calc_Divide(type_stack,&sp,baseType.GetBasicType())) goto error; break; case CALC_INTQUOTIENT: //value[sp-2]/=value[sp-1] //整数除算 if(!Calc_IntDivide(type_stack,index_stack,&sp)) goto error; break; case CALC_MINUSMARK: //value[sp-1]=-value[sp-1] //符号反転 if(!Calc_MinusMark(type_stack,sp)) goto error; break; case CALC_POWER: //べき乗演算(浮動小数点演算のみ) if(!Calc_Power(type_stack,&sp)) goto error; break; case CALC_AS: //キャスト if(!Calc_Cast(type_stack,index_stack,&sp)) goto error; break; case CALC_BYVAL: //ポインタ型→参照型 if( PTR_LEVEL( type_stack[sp-1] ) <= 0 ){ //ポインタ型ではないとき SetError( 3, NULL, cp ); goto error; } type_stack[sp-1] = PTR_LEVEL_DOWN( type_stack[sp-1] ); break; default: SetError(300,NULL,cp); goto error; } } if(bError) goto error; if(sp!=1){ SetError(1,NULL,cp); goto error; } if(bLiteralCalculation){ //右辺値が数値の定数式の場合 Type resultType; StaticCalculation(true, expression,baseType.GetBasicType(),&i64data,resultType); obp=BeforeObp; pobj_SubAddrSchedule->num=Before_ProcAddrScheduleNum; pobj_DataTableSchedule->num=Before_DataTableScheduleNum; pobj_Reloc->copy(pobj_BackReloc); pobj_sf->num=Before_StackFrameScheduleNum; *pobj_reg=objReg_Backup; if(resultType.IsReal()){ if(baseType.IsReal()) resultType=baseType; XmmReg=pobj_reg->LockXmmReg(); if(resultType.IsDouble()){ i3 = dataTable.Add( i64data ); //movlpd xmm_reg,qword ptr[data table offset] OpBuffer[obp++]=(char)0x66; OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0x12; OpBuffer[obp++]=(char)(0x04 | REGISTER_OPERAND(XmmReg)<<3); OpBuffer[obp++]=(char)0x25; *((long *)(OpBuffer+obp))=i3; pobj_DataTableSchedule->add(); obp+=sizeof(long); } if(resultType.IsSingle()){ memcpy(&dbl,&i64data,sizeof(_int64)); float flt; int i32data; flt=(float)dbl; memcpy(&i32data,&flt,sizeof(long)); i3 = dataTable.Add( i32data ); //movss xmm_reg,dword ptr[data table offset] OpBuffer[obp++]=(char)0xF3; OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0x10; OpBuffer[obp++]=(char)(0x04 | REGISTER_OPERAND(XmmReg)<<3); OpBuffer[obp++]=(char)0x25; *((long *)(OpBuffer+obp))=i3; pobj_DataTableSchedule->add(); obp+=sizeof(long); } } else{ if(!resultType.Is64()){ //整数(符号有り/無し) i3=(long)i64data; if(resultType.GetBasicSize()==sizeof(char)) i3=i3&0x000000FF; if(resultType.GetBasicSize()==sizeof(short)) i3=i3&0x0000FFFF; i64data=(_int64)i3; } UseReg=pobj_reg->LockReg(); //mov reg,i64data op_mov64_ToReg(UseReg,i64data); } type_stack[0]=resultType.GetBasicType(); index_stack[0]=resultType.GetIndex(); } else{ //右辺値が数値の定数式ではないとき if(IS_LITERAL(index_stack[0])) index_stack[0]=-1; } if(pbUseHeap) *pbUseHeap=bUseHeap[0]; if(IsRealNumberType(type_stack[0])) *pReg=pobj_reg->UnlockXmmReg(); else *pReg=pobj_reg->UnlockReg(); if(bInitRegSwitch){ //整合性をチェック(バグ回避) pobj_reg->bug_check(); //作業レジスタを解放 delete pobj_reg; pobj_reg=0; } resultType.SetType( type_stack[0], index_stack[0] ); bool isSuccessful = true; goto finish; ////////////////// // エラー処理 ////////////////// error: *pobj_reg=objReg_Backup; if(bInitRegSwitch){ //作業レジスタを解放 delete pobj_reg; pobj_reg=0; } isSuccessful = false; goto finish; finish: for(i=0;i