#include "../BasicCompiler_Common/common.h" #include "Opcode.h" void PushReturnValue(int type){ //関数の戻り値をスタックへプッシュする //※この処理内では、esi、ediは使用不可 if(type==DEF_OBJECT || type==DEF_STRUCT){ //push eax op_push(REG_EAX); } else if(type==DEF_DOUBLE){ //sub esp,8 op_sub_esp(8); //fstp qword ptr[esp] OpBuffer[obp++]=(char)0xDD; OpBuffer[obp++]=(char)0x1C; OpBuffer[obp++]=(char)0x24; } else if(type==DEF_SINGLE){ //sub esp,4 op_sub_esp(4); //fstp dword ptr[esp] OpBuffer[obp++]=(char)0xD9; OpBuffer[obp++]=(char)0x1C; OpBuffer[obp++]=(char)0x24; } else if(type==DEF_INT64||type==DEF_QWORD){ //push edx op_push(REG_EDX); //push eax op_push(REG_EAX); } else if(type==DEF_LONG){ //push eax op_push(REG_EAX); } else if(type==DEF_INTEGER || (isUnicode&&type==DEF_CHAR)){ //movsx ebx,ax OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0xBF; OpBuffer[obp++]=(char)0xD8; //push ebx op_push(REG_EBX); } else if(type==DEF_SBYTE || (isUnicode==false&&type==DEF_CHAR)){ //movsx ebx,al OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0xBE; OpBuffer[obp++]=(char)0xD8; //push ebx op_push(REG_EBX); } else if(type==DEF_DWORD||type==DEF_WORD||type==DEF_BYTE||type==DEF_BOOLEAN|| IsPtrType(type)){ //push eax op_push(REG_EAX); } else{ SetError(); } } void NewStringObject( const char *str ){ /////////////////////////////////////////////////////// // lpszTextを元にStringオブジェクトを生成し、 // オブジェクトポインタをregに格納する /////////////////////////////////////////////////////// char *parameter = (char *)malloc( lstrlen( str ) + 32 ); sprintf( parameter, "\"%s\"%c%c*Char", str, 1, ESC_AS ); SetStringQuotes( parameter ); extern CClass *pobj_StringClass; Operator_New( *pobj_StringClass, "", parameter, Type( DEF_OBJECT, *pobj_StringClass ) ); free( parameter ); } bool NumOpe( const char *expression, const Type &baseType, Type &resultType, BOOL *pbUseHeap ){ int i,i2,i3,i4; char temporary[1024],temp2[1024],temp3[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; } 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); double dbl; int sp; int type_stack[255]; LONG_PTR index_stack[255]; BOOL bUseHeap[255]; _int64 i64data; for(i=0,sp=0;iadd(); obp+=sizeof(long); } 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]))){ ////////////////// // 何らかの識別子 ////////////////////////////////////// // 関数(DLL、ユーザー定義、組み込み) ////////////////////////////////////// i2=GetCallProcName(term,temporary); if(term[i2]=='('){ i4=GetStringInPare_RemovePare(temp2,term+i2+1); void *pInfo; int idProc=GetProc(temporary,(void **)&pInfo); Type resultType; if(idProc){ //閉じカッコ")"に続く文字がNULLでないとき if(term[i2+1+i4+1]!='\0'){ if( term[i2+1+i4+1] == '.' || term[i2+1+i4+1] == 1 && term[i2+1+i4+2] == ESC_PSMEM ){ goto NonProc; } else{ SetError(42,NULL,cp); } } //////////////// // 呼び出し //////////////// CallProc(idProc,pInfo,temporary,temp2,resultType); if(resultType.IsNull()){ //戻り値が存在しないとき for(i2=2;;i2++){ if(term[i2]=='('||term[i2]=='\0'){ term[i2]=0; break; } } SetError(38,term,cp); goto error; } ///////////////////// // 戻り値の処理 ///////////////////// //大きな型への暗黙の変換 type_stack[sp]=AutoBigCast(baseType.GetBasicType(),resultType.GetBasicType()); index_stack[sp] = resultType.GetIndex(); bLiteralCalculation=0; //スタックへプッシュ PushReturnValue( resultType.GetBasicType() ); if( Is64Type(type_stack[sp]) && resultType.IsWhole() && resultType.GetBasicSize() <= sizeof(long) ){ //必要に応じて64ビット拡張 ExtendStackTo64( resultType.GetBasicType() ); } if( resultType.IsStruct() ){ //構造体が戻ったときはヒープ領域にインスタンスが格納されている //※後にfreeする必要あり bUseHeap[sp]=1; } sp++; break; } else if(GetConstCalcBuffer(temporary,temp2,temp3)){ ///////////////////////// // マクロ関数 ///////////////////////// //閉じカッコ")"に続く文字がNULLでないときはエラーにする if(term[i2+1+i4+1]!='\0') SetError(42,NULL,cp); //マクロ関数の場合 NumOpe(temp3,Type(),resultType); if(!IS_LITERAL(resultType.GetIndex())){ //リテラル値ではなかったとき bLiteralCalculation=0; } type_stack[sp] = resultType.GetBasicType(); index_stack[sp] = resultType.GetIndex(); sp++; break; } } NonProc: //インデクサ(getアクセサ) char variable[VN_SIZE],array_element[VN_SIZE]; GetArrayElement(term,variable,array_element); if(array_element[0]){ Type resultType; GetVarType(variable,resultType,0); if( resultType.IsObject() ){ CallIndexerGetterProc(&resultType.GetClass(),variable,array_element,resultType); type_stack[sp]=resultType.GetBasicType(); index_stack[sp]=resultType.GetIndex(); bLiteralCalculation=0; //push eax op_push(REG_EAX); sp++; break; } } // Nothing if( lstrcmp( term, "Nothing" ) == 0 ){ type_stack[sp] = DEF_OBJECT; if( baseType.IsObject() ){ index_stack[sp] = baseType.GetIndex(); } else{ index_stack[sp] = (LONG_PTR)pobj_DBClass->GetObjectClass(); } bLiteralCalculation = 0; //push 0 op_push_V( 0 ); sp++; break; } if( (string)term=="value"){ int test=0; } RELATIVE_VAR RelativeVar; Type varType; if(GetVarOffset( false, //エラー表示あり false, //読み込み専用 term, &RelativeVar,varType)){ ////////// // 変数 ////////// //大きな型への暗黙の変換 type_stack[sp]=AutoBigCast(baseType.GetBasicType(),varType.GetBasicType()); index_stack[sp] = varType.GetIndex(); bLiteralCalculation=0; if(varType.GetBasicType()&FLAG_PTR){ //配列ポインタ type_stack[sp]=GetPtrType(varType.GetBasicType()^FLAG_PTR); SetVarPtrToEax(&RelativeVar); //push eax op_push(REG_EAX); } else if( varType.IsStruct() ){ //構造体ポインタをeaxへ格納(構造体は値型) SetVarPtrToEax(&RelativeVar); //push eax op_push(REG_EAX); } else if( varType.GetBasicSize() == sizeof(_int64) ){ //64ビット型 PushDoubleVariable(&RelativeVar); } else if( varType.GetBasicSize() == sizeof(long) ){ //32ビット型 PushLongVariable(&RelativeVar); } else if( varType.IsInteger() ){ PushIntegerVariable(&RelativeVar); } else if( varType.IsWord() ){ PushWordVariable(&RelativeVar); } else if( varType.IsSByte() ){ PushCharVariable(&RelativeVar); } else if( varType.IsByte() || varType.IsBoolean() ){ PushByteVariable(&RelativeVar); } else SetError(11,term,cp); if( Is64Type(type_stack[sp]) && varType.IsWhole() && varType.GetBasicSize()<=sizeof(long)){ //必要に応じて64ビット拡張 ExtendStackTo64( varType.GetBasicType() ); } sp++; break; } ////////////// // 定数の場合 ////////////// i3 = CDBConst::obj.GetType(term); if(i3){ 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(300,NULL,cp); goto error; } } ////////////// // 型名の場合 ////////////// LONG_PTR lp; i3=GetTypeFixed(term,&lp); if(i3!=-1){ type_stack[sp]=i3|FLAG_CAST; index_stack[sp]=lp; sp++; break; } ///////////////////////////////// // プロパティ用のメソッド ///////////////////////////////// //配列要素を排除 char VarName[VN_SIZE],ArrayElements[VN_SIZE]; GetArrayElement(term,VarName,ArrayElements); if(GetSubHash(VarName,0)){ Type resultType; CallPropertyMethod(term,NULL,resultType); //大きな型への暗黙の変換 type_stack[sp]=AutoBigCast(baseType.GetBasicType(),resultType.GetBasicType()); index_stack[sp]=resultType.GetIndex(); bLiteralCalculation=0; //スタックへプッシュ PushReturnValue( resultType.GetBasicType() ); if(type_stack[sp]==DEF_STRUCT){ //構造体が戻ったときはヒープ領域にインスタンスが格納されている //※後にfreeする必要あり bUseHeap[sp]=1; } sp++; break; } //該当する識別子が見当たらないときはエラー扱いにする 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_INT64|| type_stack[sp]==DEF_QWORD|| type_stack[sp]==DEF_DOUBLE){ //64ビット(符号有り整数/実数) //push HILONG(dbl) op_push_V((long)*(long *)(((char *)(&i64data))+4)); //push LOLONG(dbl) op_push_V(*(long *)(&i64data)); } else if(type_stack[sp]==DEF_SINGLE){ //single実数 float flt; memcpy(&dbl,&i64data,sizeof(double)); flt=(float)dbl; memcpy(&i3,&flt,sizeof(long)); //push term op_push_V(i3); } else{ //その他 //push term op_push_V((long)i64data); if((long)i64data==0) index_stack[sp]=LITERAL_NULL; } //リテラル値の種類 if(Is64Type(type_stack[sp])==0&&IsRealNumberType(type_stack[sp])==0){ //整数(符号有り/無し) index_stack[sp]=GetLiteralIndex(i64data); } } sp++; break; //論理演算子 case CALC_XOR: //value[sp-2] xor= value[sp-1] //xor演算 if(!Calc_Xor(type_stack,index_stack,&sp)) goto error; break; case CALC_OR: //value[sp-2] or= value[sp-1] //or演算 if(!Calc_Or(type_stack,index_stack,&sp)) goto error; break; case CALC_AND: //value[sp-2] and= value[sp-1] //and演算 if(!Calc_And(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] if(!Calc_Relation_PE(type_stack,index_stack,&sp)) goto error; break; case CALC_QE: //value[sp-2]>=value[sp-1] if(!Calc_Relation_QE(type_stack,index_stack,&sp)) goto error; break; case CALC_P: //value[sp-2]value[sp-1] if(!Calc_Relation_Q(type_stack,index_stack,&sp)) goto error; break; case CALC_NOTEQUAL: //value[sp-2]<>value[sp-1] if(!Calc_Relation_NotEqual(type_stack,&sp)) goto error; break; case CALC_EQUAL: //value[sp-2]=value[sp-1] if(!Calc_Relation_Equal(type_stack,&sp)) goto error; break; //ビットシフト case CALC_SHL: //value[sp-2]=value[sp-2]<>value[sp-1] if(!Calc_SHR(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,&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; index_stack[sp-1]=-1; 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); if( resultType.GetBasicSize() == sizeof(_int64) ){ //64ビット(符号有り整数/実数) //push HILONG(i64data) op_push_V((long)*(long *)(((char *)(&i64data))+4)); //push LOLONG(i64data) op_push_V(*(long *)(&i64data)); } else if( resultType.IsSingle() ){ //single実数 memcpy(&dbl,&i64data,sizeof(_int64)); float flt; flt=(float)dbl; memcpy(&i3,&flt,sizeof(long)); //push flt op_push_V(i3); } else{ //整数(符号有り/無し) i3=(long)i64data; if(resultType.GetBasicSize()==sizeof(char)) i3=i3&0x000000FF; if(resultType.GetBasicSize()==sizeof(short)) i3=i3&0x0000FFFF; //push term op_push_V(i3); } 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]; resultType.SetType( type_stack[0], index_stack[0] ); bool isSuccessful = true; goto finish; error: isSuccessful = false; goto finish; finish: for(i=0;i