#include "../BasicCompiler_Common/common.h" #include "Opcode.h" void NewStringObject(int reg,LPSTR lpszText){ /////////////////////////////////////////////////////// // lpszTextを元にStringオブジェクトを生成し、 // オブジェクトポインタをregに格納する /////////////////////////////////////////////////////// ////////////////////////////////////////////////////// ///// レジスタ資源のバックアップ { BACKUP_REGISTER_RESOURCE ////////////////////////////////////////////////////// extern CClass *pobj_StringClass; int object_size; object_size=GetSizeOfClass(pobj_StringClass); //mov rcx,object_size op_mov_RV(sizeof(_int64),REG_RCX,object_size); //call calloc extern SUBINFO *pSub_calloc; op_call(pSub_calloc); //mov r11,rax op_mov_RR(REG_R11,REG_RAX); //mov qword ptr[rsp+offset],r11 ※スタックフレームを利用 pobj_sf->push(REG_R11); //mov rcx,rax op_mov_RR(REG_RCX,REG_RAX); //call constructor op_call(pobj_StringClass->ppobj_Method[pobj_StringClass->ConstructorMemberSubIndex]->psi); int i2; i2=AddDataTable(lpszText,lstrlen(lpszText)); //mov rax,i2 op_mov_RV(sizeof(_int64),REG_RAX,i2); obp-=sizeof(long); pobj_DataTableSchedule->add(); obp+=sizeof(long); //mov r11,qword ptr[rsp+offset] ※スタックフレームを利用 pobj_sf->ref(REG_R11); RELATIVE_VAR RelativeVar; RelativeVar.bOffsetOffset=0; RelativeVar.offset=0; RelativeVar.dwKind=VAR_DIRECTMEM; SetObjectVariableFromRax((LONG_PTR)pobj_StringClass,DEF_PTR_BYTE,-1,&RelativeVar,0); //mov r11,qword ptr[rsp+offset] ※スタックフレームを利用 pobj_sf->pop(REG_R11); ///////////////////////////////////////////// ////// レジスタ資源を復元 RESTORE_REGISTER_RESOURCE }//////////////////////////////////////////// //mov reg,r11 op_mov_RR(reg,REG_R11); } 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_mov64_ToReg_FromReg(UseReg,REG_RAX); } } } int NumOpe(int *pReg,const char *Command,int BaseType,LONG_PTR lpBaseIndex,LONG_PTR *plpIndex,BOOL *pbUseHeap){ extern HANDLE hHeap; int i,i2,i3,i4; char temporary[1024],temp2[1024],temp3[1024]; if(Command[0]=='\0'){ SetError(1,NULL,cp); return 0; } if(Command[0]==1&&Command[1]==ESC_NEW){ //New演算子(オブジェクト生成) return Operator_New(Command+2,plpIndex); } ///////////////////////////////// // 式要素を逆ポーランド式で取得 ///////////////////////////////// char *values[255]; long calc[255]; long stack[255]; int pnum; if(!GetNumOpeElements(Command,&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[255]; LONG_PTR index_stack[255]; BOOL bUseHeap[255]; _int64 i64data; int UseReg,XmmReg; BOOL bXmm; for(i=0,sp=0;iGetNextReg(); XmmReg=pobj_reg->GetNextXmmReg(); bXmm=0; char *term; term=values[i]; if(term[0]=='\"'){ //リテラル文字列 if(!RemoveStringQuotes(term)){ SetError(43,NULL,cp); goto error; } i3=lstrlen(term); StrLiteral: if(BaseType==DEF_OBJECT){ CClass *pobj_Class; pobj_Class=(CClass *)lpBaseIndex; TYPEINFO BaseTypeInfo = {BaseType,lpBaseIndex}; if(IsStringSubsituation(pobj_Class) || IsStringObjectType(&BaseTypeInfo)){ //要求タイプがオブジェクトであり、Stringの受け入れが可能な場合 //String型オブジェクトを生成 NewStringObject(UseReg,term); extern CClass *pobj_StringClass; type[sp]=DEF_OBJECT; index_stack[sp]=(LONG_PTR)pobj_StringClass; bUseHeap[sp]=1; bLiteralCalculation=0; if(bXmm) pobj_reg->LockXmmReg(); else pobj_reg->LockReg(); sp++; break; } } type[sp]=DEF_PTR_BYTE; bLiteralCalculation=0; i2=AddDataTable(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]))){ ////////////////// // 何らかの識別子 ////////////////////////////////////// // 関数(DLL、ユーザー定義、組み込み) ////////////////////////////////////// i2=GetCallProcName(term,temporary); if(term[i2]=='('){ i4=GetStringInPare_RemovePare(temp2,term+i2+1); int idProc; void *pInfo; idProc=GetProc(temporary,&pInfo); if(idProc){ //閉じカッコ")"に続く文字がNULLでないときはエラーにする if(term[i2+1+i4+1]!='\0') SetError(42,NULL,cp); ////////////////////////////////////////////////////// ///// レジスタ資源のバックアップ { BACKUP_REGISTER_RESOURCE ////////////////////////////////////////////////////// //////////////// // 呼び出し //////////////// i2=CallProc(idProc,pInfo,temporary,temp2,&index_stack[sp]); if(i2==-1){ //戻り値が存在しないとき for(i2=2;;i2++){ if(term[i2]=='('||term[i2]=='\0'){ term[i2]=0; break; } } SetError(38,term,cp); //レジスタ資源を復元 RESTORE_REGISTER_RESOURCE goto error; } ///////////////////// // 戻り値の処理 ///////////////////// //大きな型への暗黙の変換 type[sp]=AutoBigCast(BaseType,i2); bLiteralCalculation=0; SetUseRegFromRax(i2,UseReg,XmmReg); if(IsRealNumberType(i2)) bXmm=1; else bXmm=0; ///////////////////////////////////////////// ////// レジスタ資源を復元 RESTORE_REGISTER_RESOURCE }//////////////////////////////////////////// if(bXmm) pobj_reg->LockXmmReg(); else pobj_reg->LockReg(); if(i2==DEF_OBJECT){ //Object型が戻ったときはヒープ領域にインスタンスが格納されている //※後にfreeする必要あり bUseHeap[sp]=1; } sp++; break; } else if(GetConstCalcBuffer(temporary,temp2,temp3)){ ///////////////////////// // マクロ関数 ///////////////////////// //閉じカッコ")"に続く文字がNULLでないときはエラーにする if(term[i2+1+i4+1]!='\0') SetError(42,NULL,cp); //マクロ関数の場合 i2=NumOpe(&UseReg,temp3,0,0,&index_stack[sp]); if(!IS_LITERAL(index_stack[sp])){ //リテラル値ではなかったとき bLiteralCalculation=0; } type[sp]=i2; if(IsRealNumberType(i2)) pobj_reg->LockXmmReg(); else pobj_reg->LockReg(); sp++; break; } } //インデクサ(getアクセサ) char variable[VN_SIZE],array_element[VN_SIZE]; CClass *pobj_c; GetArrayElement(term,variable,array_element); if(array_element[0]){ i2=GetVarType(variable,(LONG_PTR *)&pobj_c,0); if(i2==DEF_OBJECT){ TYPEINFO RetTypeInfo; CallIndexerGetterProc(UseReg,pobj_c,variable,array_element,RetTypeInfo); type[sp]=RetTypeInfo.type; index_stack[sp]=RetTypeInfo.u.lpIndex; bLiteralCalculation=0; if(IsRealNumberType(RetTypeInfo.type)) pobj_reg->LockXmmReg(); else pobj_reg->LockReg(); sp++; break; } } RELATIVE_VAR RelativeVar; if(GetVarOffset( false, //エラー表示あり false, //読み込み専用 term, &i2,&RelativeVar,&index_stack[sp])){ ////////// // 変数 ////////// //大きな型への暗黙の変換 type[sp]=AutoBigCast(BaseType,i2); bLiteralCalculation=0; if(type[sp]!=i2){ //大きな型へ変換された場合(レジスタを0に初期化する) //xor reg,reg op_zero_reg(UseReg); } if(i2&FLAG_PTR){ //配列ポインタ type[sp]=GetPtrType(i2^FLAG_PTR,index_stack[sp]); SetVarPtrToReg(UseReg,&RelativeVar); } else if(IsRealNumberType(i2)){ //実数型 bXmm=1; if(i2==DEF_DOUBLE) SetXmmReg_DoubleVariable(&RelativeVar,XmmReg); if(i2==DEF_SINGLE) SetXmmReg_SingleVariable(&RelativeVar,XmmReg); } else if(IsWholeNumberType(i2)){ //整数型 SetReg_WholeVariable(i2,&RelativeVar,UseReg); } else if(i2==DEF_OBJECT){ //オブジェクト ポインタをUseRegへ格納 SetVarPtrToReg(UseReg,&RelativeVar); } else SetError(11,term,cp); if(bXmm==0&&UseReg==REG_R14){ //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用 pobj_sf->push(REG_R14); } if(bXmm&&XmmReg==REG_XMM4){ if(i2==DEF_DOUBLE){ //movsd qword ptr[rsp+offset],xmm4 ※スタックフレームを利用 pobj_sf->push(REG_XMM4,sizeof(double)); } if(i2==DEF_SINGLE){ //movss dword ptr[rsp+offset],xmm4 ※スタックフレームを利用 pobj_sf->push(REG_XMM4,sizeof(float)); } } if(bXmm) pobj_reg->LockXmmReg(); else pobj_reg->LockReg(); sp++; break; } ////////////// // 定数の場合 ////////////// i3 = CDBConst::obj.GetType(term); if(i3){ type[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; } } ////////////// // 型名の場合 ////////////// LONG_PTR lp; i3=GetTypeFixed(term,&lp); if(i3!=-1){ type[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)){ ////////////////////////////////////////////////////// ///// レジスタ資源のバックアップ { BACKUP_REGISTER_RESOURCE ////////////////////////////////////////////////////// TYPEINFO RetTypeInfo; CallPropertyMethod(term,NULL,&RetTypeInfo); //大きな型への暗黙の変換 type[sp]=AutoBigCast(BaseType,RetTypeInfo.type); index_stack[sp]=RetTypeInfo.u.lpIndex; bLiteralCalculation=0; SetUseRegFromRax(RetTypeInfo.type,UseReg,XmmReg); if(IsRealNumberType(type[sp])) bXmm=1; else bXmm=0; ///////////////////////////////////////////// ////// レジスタ資源を復元 RESTORE_REGISTER_RESOURCE }//////////////////////////////////////////// if(type[sp]==DEF_OBJECT){ //Object型が戻ったときはヒープ領域にインスタンスが格納されている //※後にfreeする必要あり bUseHeap[sp]=1; } if(bXmm) pobj_reg->LockXmmReg(); else pobj_reg->LockReg(); sp++; break; } //該当する識別子が見当たらないときはエラー扱いにする bError=1; SetError(3,term,cp); type[sp]=DEF_DOUBLE; } else{ //リテラル値 type[sp]=GetLiteralValue(term,&i64data,BaseType); Literal: if(type[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=AddDataTable((char *)&i64data,sizeof(_int64)); //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[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){ //push term op_push_value(i32data); } else{ i3=AddDataTable((char *)&i32data,sizeof(long)); //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,index_stack,&sp)) goto error; break; case CALC_NOT: //value[sp-1]=Not value[sp-1] //NOT演算子 if(!Calc_Not(type,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,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,&sp)) goto error; break; //算術演算 case CALC_ADDITION: case CALC_SUBTRACTION: case CALC_PRODUCT: if(!CalcTwoTerm_Arithmetic(idCalc,type,index_stack,&sp)) goto error; break; case CALC_MOD: //value[sp-2]%=value[sp-1] //剰余演算 if(!Calc_Mod(type,index_stack,&sp)) goto error; break; case CALC_QUOTIENT: //value[sp-2]/=value[sp-1]; //除算 if(!Calc_Divide(type,&sp,BaseType)) goto error; break; case CALC_INTQUOTIENT: //value[sp-2]/=value[sp-1] //整数除算 if(!Calc_IntDivide(type,index_stack,&sp)) goto error; break; case CALC_MINUSMARK: //value[sp-1]=-value[sp-1] //符号反転 if(!Calc_MinusMark(type,sp)) goto error; break; case CALC_POWER: //べき乗演算(浮動小数点演算のみ) if(!Calc_Power(type,&sp)) goto error; break; case CALC_AS: //キャスト if(!Calc_Cast(type,index_stack,&sp)) goto error; break; case CALC_BYVAL: //ポインタ型→参照型 if( PTR_LEVEL( type[sp-1] ) <= 0 ){ //ポインタ型ではないとき SetError( 3, NULL, cp ); goto error; } type[sp-1] = PTR_LEVEL_DOWN( type[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){ //右辺値が数値の定数式の場合 LONG_PTR lpClassIndex; i2=StaticCalculation(true, Command,BaseType,&i64data,&lpClassIndex); 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(IsRealNumberType(i2)){ if(IsRealNumberType(BaseType)) i2=BaseType; XmmReg=pobj_reg->LockXmmReg(); if(i2==DEF_DOUBLE){ i3=AddDataTable((char *)&i64data,sizeof(_int64)); //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(i2==DEF_SINGLE){ memcpy(&dbl,&i64data,sizeof(_int64)); float flt; int i32data; flt=(float)dbl; memcpy(&i32data,&flt,sizeof(long)); i3=AddDataTable((char *)&i32data,sizeof(long)); //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(!Is64Type(i2)){ //整数(符号有り/無し) i3=(long)i64data; if(GetTypeSize(i2,-1)==sizeof(char)) i3=i3&0x000000FF; if(GetTypeSize(i2,-1)==sizeof(short)) i3=i3&0x0000FFFF; i64data=(_int64)i3; } UseReg=pobj_reg->LockReg(); //mov reg,i64data op_mov64_ToReg(UseReg,i64data); } type[0]=i2; index_stack[0]=lpClassIndex; } else{ //右辺値が数値の定数式ではないとき if(IS_LITERAL(index_stack[0])) index_stack[0]=-1; } if(plpIndex) *plpIndex=index_stack[0]; if(pbUseHeap) *pbUseHeap=bUseHeap[0]; if(IsRealNumberType(type[0])) *pReg=pobj_reg->UnlockXmmReg(); else *pReg=pobj_reg->UnlockReg(); if(bInitRegSwitch){ //整合性をチェック(バグ回避) pobj_reg->bug_check(); //作業レジスタを解放 delete pobj_reg; pobj_reg=0; } int RetType; RetType=type[0]; goto finish; ////////////////// // エラー処理 ////////////////// error: *pobj_reg=objReg_Backup; if(bInitRegSwitch){ //作業レジスタを解放 delete pobj_reg; pobj_reg=0; } RetType=-1; goto finish; finish: for(i=0;i