#include "../BasicCompiler_Common/common.h" #include "Opcode.h" //変数 Variables globalVars; int AllGlobalVarSize; int AllInitGlobalVarSize; int AllLocalVarSize; void SetRelativeOffset( Type &resultType, RELATIVE_VAR *pRelativeVar,const char *lpPtrOffset){ PushLongVariable(pRelativeVar); Type type; NumOpe( lpPtrOffset, Type(), type ); ChangeTypeToLong( type.GetBasicType() ); //pop ebx op_pop(REG_EBX); if( resultType.PtrLevel() ){ resultType.PtrLevelDown(); int typeSize = resultType.GetSize(); if(typeSize>=2){ //imul ebx,i2 op_imul_RV( REG_EBX, typeSize ); } } else{ //エラー SetError(1,NULL,cp); return; } //pop ecx op_pop(REG_ECX); //add ecx,ebx OpBuffer[obp++]=(char)0x03; OpBuffer[obp++]=(char)0xCB; } void SetRelativeOffset( RELATIVE_VAR &relativeVar ){ if(relativeVar.dwKind==VAR_DIRECTMEM){ //mov ecx,dword ptr[ecx] op_mov_RM( sizeof(long), REG_ECX, REG_ECX, 0, MOD_BASE ); } else{ //直接参照に切り替え SetVarPtrToEax(&relativeVar); relativeVar.dwKind=VAR_DIRECTMEM; //mov ecx,dword ptr[eax] op_mov_RM( sizeof(long), REG_ECX, REG_EAX, 0, MOD_BASE ); } } bool GetArrayOffset(const int *SubScripts,char *array, const Type &type){ extern HANDLE hHeap; int i,i2,i3,i4; char temporary[VN_SIZE],*pParm[MAX_PARMS]; for(i=0,i2=0,i3=0;;i++,i2++){ if(array[i]=='('){ i4=GetStringInPare(temporary+i2,array+i); i+=i4-1; i2+=i4-1; continue; } if(array[i]=='['){ i4=GetStringInBracket(temporary+i2,array+i); i+=i4-1; i2+=i4-1; continue; } if(array[i]==','||array[i]=='\0'){ if(SubScripts[i3]==-1){ for(i3--;i3>=0;i3--) HeapDefaultFree(pParm[i3]); return 0; } temporary[i2]=0; pParm[i3]=(char *)HeapAlloc(hHeap,0,lstrlen(temporary)+1); lstrcpy(pParm[i3],temporary); i3++; if(array[i]=='\0'){ if(SubScripts[i3]!=-1){ for(i3--;i3>=0;i3--) HeapDefaultFree(pParm[i3]); return 0; } break; } i2=-1; continue; } temporary[i2]=array[i]; } //push ecx op_push(REG_ECX); //push 0 op_push_V(0); for(i=i3-1;i>=0;i--){ Type tempType; BOOL bUseHeap; NumOpe( pParm[i], Type( DEF_LONG ), tempType, &bUseHeap ); if( tempType.IsObject() ){ //キャスト演算子のオーバーロードに対応する CallCastOperatorProc( tempType, bUseHeap, Type(DEF_LONG) ); tempType.SetBasicType( DEF_LONG ); } ChangeTypeToLong( tempType.GetBasicType() ); //pop eax op_pop(REG_EAX); for(i2=i+1,i4=1;i2dwAccess==ACCESS_NON){ if(isErrorEnabled) SetError(107,VarName,cp); return false; } } else{ if((bPrivateAccess==0&&pMember->dwAccess==ACCESS_PRIVATE)|| pMember->dwAccess==ACCESS_NON){ if(isErrorEnabled) SetError(107,VarName,cp); return false; } else if(bPrivateAccess==0&&pMember->dwAccess==ACCESS_PROTECTED){ if(isErrorEnabled) SetError(108,VarName,cp); return false; } } //Const定義の場合は書き込みアクセスを制限する //※コンストラクタをコンパイル中の場合は例外的に許可する if( pMember->IsConst() && //定数メンバである isWriteAccess && //書き込みアクセスを要求されている objClass.IsCompilingConstructor() == false //コンストラクタ コンパイル中を除く ){ //Const定義の変数に書き込みアクセスをしようとした場合 SetError(61,VarName,cp); } resultType = *pMember; //ポインタ変数の場合 if( resultType.IsPointer() ){ if(pMember->SubScripts[0]==-1){ lstrcpy(lpPtrOffset,array); array[0]=0; } } else{ if(lpPtrOffset[0]){ if(isErrorEnabled) SetError(16,member,cp); return false; } } if(offset){ //add ecx,offset OpBuffer[obp++]=(char)0x81; OpBuffer[obp++]=(char)0xC1; *((long *)(OpBuffer+obp))=offset; obp+=sizeof(long); } if(array[0]){ //配列オフセット if(!GetArrayOffset(pMember->SubScripts,array,*pMember)){ if(isErrorEnabled) SetError(14,member,cp); } } else if(pMember->SubScripts[0]!=-1){ resultType.SetBasicType( resultType.GetBasicType() | FLAG_PTR ); } if(NestMember[0]){ //入れ子構造の場合 if( resultType.IsObject() || resultType.IsStruct() ){ if( refType != CClass::Dot ){ if(isErrorEnabled) SetError(104,member,cp); return false; } if( resultType.IsObject() ){ // 参照内容へのポインタを抽出 SetRelativeOffset( *pRelativeVar ); } } else if( resultType.IsObjectPtr() || resultType.IsStructPtr() ){ //構造体ポインタ型メンバ変数 if(lpPtrOffset[0]){ //pObj[n].member if( ( resultType.IsObjectPtr() || resultType.IsStructPtr() ) && refType != CClass::Dot ){ if(isErrorEnabled) SetError(104,member,cp); return false; } //直接参照に切り替え SetRelativeOffset(resultType,pRelativeVar,lpPtrOffset); pRelativeVar->dwKind=VAR_DIRECTMEM; lpPtrOffset[0]=0; } else{ //pObj->member if( ( resultType.IsObjectPtr() || resultType.IsStructPtr() ) && refType != CClass::Pointer ){ if(isErrorEnabled) SetError(104,member,cp); return false; } SetRelativeOffset( *pRelativeVar ); } } else if( resultType.GetBasicType() == MAKE_PTR_TYPE(DEF_OBJECT,2) || resultType.GetBasicType() == MAKE_PTR_TYPE(DEF_STRUCT,2)){ //構造体ポインタのポインタ型メンバ変数 if(lpPtrOffset[0]){ //ppObj[n]->member if( refType != CClass::Pointer ){ if(isErrorEnabled) SetError(104,member,cp); return false; } //直接参照に切り替え SetRelativeOffset(resultType,pRelativeVar,lpPtrOffset); pRelativeVar->dwKind=VAR_DIRECTMEM; lpPtrOffset[0]=0; //mov ecx,dword ptr[ecx] OpBuffer[obp++]=(char)0x8B; OpBuffer[obp++]=(char)0x09; } else{ if(isErrorEnabled) SetError(104,member,cp); return false; } } if(!_member_offset( isErrorEnabled, isWriteAccess, pMember->GetClass(), NestMember, pRelativeVar, resultType, 0)) return false; } if(lpPtrOffset[0]){ SetRelativeOffset(resultType,pRelativeVar,lpPtrOffset); pRelativeVar->dwKind=VAR_DIRECTMEM; } return true; } int LocalVar_ThisPtrOffset; void SetThisPtrToReg(int reg){ //自身のオブジェクトのThisポインタをregにコピー RELATIVE_VAR RelativeVar; RelativeVar.dwKind=VAR_LOCAL; RelativeVar.bOffsetOffset=0; RelativeVar.offset=-LocalVar_ThisPtrOffset; SetReg_WholeVariable(DEF_PTR_VOID,&RelativeVar,reg); } bool GetVarOffset(bool isErrorEnabled,bool isWriteAccess,const char *NameBuffer,RELATIVE_VAR *pRelativeVar,Type &resultType,int *pss){ int i; char variable[VN_SIZE]; if(NameBuffer[0]=='.'){ GetWithName(variable); lstrcat(variable,NameBuffer); } else lstrcpy(variable,NameBuffer); // 名前空間を分離 char namespaceStr[VN_SIZE]="", simpleName[VN_SIZE]; Smoothie::Meta::namespaceScopesCollection.SplitNamespace( variable, namespaceStr, simpleName ); // 先頭オブジェクトまたはクラス名と入れ子メンバに分割 CClass::RefType refType; char member[VN_SIZE],array[VN_SIZE],lpPtrOffset[VN_SIZE]; GetVarFormatString(simpleName,array,lpPtrOffset,member,refType); // 名前空間を分離していた場合は結合 char VarName[VN_SIZE]; if( namespaceStr[0] ){ sprintf( VarName, "%s.%s", namespaceStr, simpleName ); } else{ lstrcpy( VarName, simpleName ); } const int *pSubScripts; bool bConst = false; if( UserProc::IsLocalAreaCompiling() ){ ////////////////// // ローカル変数 ////////////////// const Variable *pVar = UserProc::CompilingUserProc().localVars.BackSearch( VarName ); if( pVar ){ //ポインタ変数の場合 if( pVar->IsPointer() ){ if( !pVar->IsArray() ){ lstrcpy(lpPtrOffset,array); array[0]=0; } } else{ if(lpPtrOffset[0]){ SetError(16,variable,cp); pRelativeVar->dwKind=NON_VAR; return false; } } pRelativeVar->offset=-pVar->offset; pRelativeVar->bOffsetOffset=0; if( pVar->IsRef() ){ // 参照型 pRelativeVar->dwKind = VAR_REFLOCAL; } else pRelativeVar->dwKind=VAR_LOCAL; resultType = *pVar; pSubScripts=pVar->GetSubScriptsPtr(); bConst = pVar->IsConst(); goto ok; } } if(pobj_CompilingClass){ ////////////////////// // クラスメンバの参照 ////////////////////// if(lstrcmpi(variable,"This")==0){ //Thisオブジェクト //Thisポインタをecxにコピー SetThisPtrToReg(REG_ECX); pRelativeVar->dwKind=VAR_DIRECTMEM; resultType.SetType( DEF_OBJECT, pobj_CompilingClass ); return true; } if(memicmp(variable,"This.",5)==0){ //Thisオブジェクトのメンバを参照するとき SlideString(variable+5,-5); lstrcpy(VarName,variable); } else{ //クラス内メンバを参照するとき(通常) for(i=0;iiMemberNum;i++){ if( pobj_CompilingClass->ppobj_Member[i]->GetName() == VarName ){ break; } } if(i==pobj_CompilingClass->iMemberNum) goto NonClassMember; } //Const修飾子のメソッド内でメンバ書き込みアクセスが発生したとき //(コンストラクタ、デストラクタ内を除く) const CMethod *pMethod = pobj_DBClass->GetNowCompilingMethodInfo(); if( isWriteAccess && pMethod->IsConst() && pobj_CompilingClass->IsCompilingConstructor() == false && pobj_CompilingClass->IsCompilingDestructor() == false ){ SetError(131, NULL, cp ); } ///////////////////////////// // thisポインタをecxにセット //Thisポインタをecxにコピー SetThisPtrToReg(REG_ECX); pRelativeVar->dwKind=VAR_DIRECTMEM; if(!_member_offset( isErrorEnabled, isWriteAccess, *pobj_CompilingClass, variable, pRelativeVar, resultType,1)) return false; return true; } NonClassMember: { const Variable *pVar; ////////////////////////// // 静的ローカル変数 // ※"Static.Object.Method.Variable" ////////////////////////// char temporary[VN_SIZE]; if( UserProc::IsLocalAreaCompiling() ){ GetNowStaticVarFullName(VarName,temporary); pVar = globalVars.Find( temporary ); if( pVar ){ goto GlobalOk; } } ////////////////////////// // クラスの静的メンバ ////////////////////////// if(member[0]){ lstrcpy(temporary,member); // TODO: 名前空間を考慮したコードになっていない char tempMember[VN_SIZE]; char tempArray[VN_SIZE]; { CClass::RefType refType; GetVarFormatString(temporary,tempArray,lpPtrOffset,tempMember, refType ); } int typeDefIndex = Smoothie::Meta::typeDefs.GetIndex( VarName ); if( typeDefIndex != -1 ){ // TypeDef後の型名だったとき lstrcpy( VarName, Smoothie::Meta::typeDefs[typeDefIndex].GetBaseName().c_str() ); } char temp2[VN_SIZE]; sprintf(temp2,"%s.%s",VarName,temporary); pVar = globalVars.Find( temp2 ); if( pVar ){ lstrcpy(member,tempMember); lstrcpy(array,tempArray); goto GlobalOk; } } if(pobj_CompilingClass){ //自身のクラスから静的メンバを参照する場合 char temp2[VN_SIZE]; sprintf(temp2,"%s.%s",pobj_CompilingClass->GetName().c_str(),VarName); pVar = globalVars.Find( temp2 ); if( pVar ){ goto GlobalOk; } } ///////////////////// // グローバル変数 ///////////////////// pVar = globalVars.BackSearch( VarName ); if( pVar ){ goto GlobalOk; } if(isErrorEnabled) SetError(3,variable,cp); pRelativeVar->dwKind=NON_VAR; return false; GlobalOk: //ポインタ変数の場合 if( pVar->IsPointer() ){ if( !pVar->IsArray() ){ lstrcpy(lpPtrOffset,array); array[0]=0; } } else{ if(lpPtrOffset[0]){ SetError(16,variable,cp); pRelativeVar->dwKind=NON_VAR; return false; } } pRelativeVar->offset=pVar->offset; pRelativeVar->bOffsetOffset=0; if( pVar->IsRef() ){ // 参照型 pRelativeVar->dwKind = VAR_REFGLOBAL; } else pRelativeVar->dwKind=VAR_GLOBAL; resultType = *pVar; pSubScripts=pVar->GetSubScriptsPtr(); bConst = pVar->IsConst(); } ok: if( bConst && isWriteAccess ){ //Const定義の変数に書き込みアクセスをしようとした場合 if( resultType.IsObject() ){ //オブジェクト定数 SetError(130, VarName, cp ); } else{ //一般のConst変数 SetError(61,VarName,cp); } } if(array[0]==0&&pSubScripts[0]!=-1){ //配列の先頭ポインタを示す場合 resultType.SetBasicType( resultType.GetBasicType() | FLAG_PTR ); if(pss) memcpy(pss,pSubScripts,MAX_ARRAYDIM); return true; } if(array[0]||member[0]){ //xor ecx,ecx(ecxを0に初期化する) //※ecxは変数ベースアドレスからの相対オフセットを示す op_zero_reg(REG_ECX); pRelativeVar->bOffsetOffset=1; } if(array[0]){ if(!GetArrayOffset(pSubScripts,array,resultType)){ SetError(14,variable,cp); pRelativeVar->dwKind=NON_VAR; return false; } } if(member[0]){ if( resultType.IsObject() || resultType.IsStruct() ){ //実態オブジェクトのメンバを参照(obj.member) if( refType != CClass::Dot ){ SetError(104,VarName,cp); pRelativeVar->dwKind=NON_VAR; return false; } if( resultType.IsObject() ){ // 参照内容へのポインタを抽出 SetRelativeOffset( *pRelativeVar ); } } else if( resultType.IsObjectPtr() || resultType.IsStructPtr() ){ //ポインタオブジェクトが示すメンバを参照 if(lpPtrOffset[0]){ //pObj[n].member if( refType != CClass::Dot ){ SetError(104,VarName,cp); pRelativeVar->dwKind=NON_VAR; return false; } SetRelativeOffset(resultType,pRelativeVar,lpPtrOffset); pRelativeVar->dwKind=VAR_DIRECTMEM; } else{ //pObj->member if( refType != CClass::Pointer ){ SetError(104,VarName,cp); pRelativeVar->dwKind=NON_VAR; return false; } SetVarPtrToEax(pRelativeVar); pRelativeVar->dwKind=VAR_DIRECTMEM; //mov ecx,dword ptr[eax] OpBuffer[obp++]=(char)0x8B; OpBuffer[obp++]=(char)0x08; } } else if( resultType.GetBasicType()==MAKE_PTR_TYPE(DEF_OBJECT,2) || resultType.GetBasicType()==MAKE_PTR_TYPE(DEF_STRUCT,2)){ //ポインタオブジェクトが示すメンバを参照 if(lpPtrOffset[0]){ //ppObj[n]->member if( refType != CClass::Pointer ){ SetError(104,VarName,cp); pRelativeVar->dwKind=NON_VAR; return false; } SetRelativeOffset(resultType,pRelativeVar,lpPtrOffset); pRelativeVar->dwKind=VAR_DIRECTMEM; SetVarPtrToEax(pRelativeVar); //mov ecx,dword ptr[eax] OpBuffer[obp++]=(char)0x8B; OpBuffer[obp++]=(char)0x08; } else{ SetError(104,VarName,cp); pRelativeVar->dwKind=NON_VAR; return false; } } else{ SetError(102,VarName,cp); pRelativeVar->dwKind=NON_VAR; return false; } if(!_member_offset( isErrorEnabled, isWriteAccess, resultType.GetClass(), member,pRelativeVar,resultType,0)) return false; return true; } if(lpPtrOffset[0]){ SetRelativeOffset(resultType,pRelativeVar,lpPtrOffset); pRelativeVar->dwKind=VAR_DIRECTMEM; } return true; } bool SetInitGlobalData(int offset,const Type &type,const int *SubScripts,char *InitBuf){ extern BYTE *initGlobalBuf; int i,i2,i3; char temporary[VN_SIZE]; if(InitBuf[0]=='['){ SlideString(InitBuf+1,-1); InitBuf[lstrlen(InitBuf)-1]=0; int typeSize = type.GetSize(); if(SubScripts[0]!=-1){ typeSize*=JumpSubScripts(SubScripts+1); i=0; i2=0; while(1){ if(SubScripts[0]GetName().c_str(), NULL ); if(!SetInitGlobalData(offset+i3, *objClass.ppobj_Member[i2], objClass.ppobj_Member[i2]->SubScripts, temporary)) return false; if(InitBuf[i]=='\0') break; } if(i2+1!=objClass.iMemberNum){ SetError(41,0,cp); return false; } return true; } SetError(41,0,cp); return false; } /////////////////////////////////////// // 単発式([]で囲まれていない) /////////////////////////////////////// if( type.IsObject() || type.IsStruct() ){ //オブジェクトまたは構造体の場合はありえない SetError(300,NULL,cp); return false; } if(SubScripts[0]!=-1){ SetError(41,0,cp); return false; } double dbl; _int64 i64data; Type calcType; if( !StaticCalculation(false, InitBuf,type.GetBasicType(),&i64data,calcType) ){ //動的データだった場合 return false; } if( calcType.IsReal() ){ memcpy(&dbl,&i64data,sizeof(double)); i64data=(_int64)dbl; } else dbl=(double)i64data; //型チェック CheckDifferentType( type, calcType, 0,0); if( type.IsDouble() ){ *(double *)(initGlobalBuf+offset)=(double)dbl; } else if( type.IsSingle() ){ *(float *)(initGlobalBuf+offset)=(float)dbl; } else if( type.Is64() ){ *(_int64 *)(initGlobalBuf+offset)=i64data; } else if( type.IsLong() || type.IsDWord() || type.IsPointer() ){ if(type.GetBasicType()==typeOfPtrChar){ //文字列定数のとき char *temp; temp=(char *)i64data; i2=dataTable.AddString(temp,lstrlen(temp)); HeapDefaultFree(temp); //mov eax,DataPos OpBuffer[obp++]=(char)0xB8; *((long *)(OpBuffer+obp))=(long)i2; pobj_DataTableSchedule->add(); obp+=sizeof(long); //mov dword ptr[offset],eax OpBuffer[obp++]=(char)0xA3; *((long *)(OpBuffer+obp))=offset; pobj_GlobalVarSchedule->add(); obp+=sizeof(long); } else{ *(DWORD *)(initGlobalBuf+offset)=(DWORD)i64data; } } else if( type.IsWord() || type.IsInteger() ){ *(WORD *)(initGlobalBuf+offset)=(WORD)i64data; } else if( type.IsSByte() || type.IsByte() || type.IsBoolean() ){ *(BYTE *)(initGlobalBuf+offset)=(BYTE)i64data; } return true; } bool InitLocalVar(int offset,const Type &type,const int *SubScripts,char *InitBuf){ int i,i2,i3; char temporary[VN_SIZE]; if(InitBuf[0]=='['){ SlideString(InitBuf+1,-1); InitBuf[lstrlen(InitBuf)-1]=0; int typeSize = type.GetSize(); if(SubScripts[0]!=-1){ typeSize*=JumpSubScripts(SubScripts+1); i=0; i2=0; while(1){ if(SubScripts[0]GetName().c_str(), NULL ); if(!InitLocalVar(offset+i3, *objClass.ppobj_Member[i2], objClass.ppobj_Member[i2]->SubScripts, temporary)) return false; if(InitBuf[i]=='\0') break; } if(i2+1!=objClass.iMemberNum){ SetError(41,0,cp); return 0; } return true; } SetError(41,0,cp); return false; } /////////////////////////////////////// // 単発式([]で囲まれていない) /////////////////////////////////////// if(SubScripts[0]!=-1){ SetError(41,0,cp); return false; } double dbl; _int64 i64data; Type calcType; if( !StaticCalculation(false, InitBuf,type.GetBasicType(),&i64data,calcType) ){ //動的データだった場合 return false; } if( calcType.IsReal() ){ memcpy(&dbl,&i64data,sizeof(double)); i64data=(_int64)dbl; } else dbl=(double)i64data; //型チェック CheckDifferentType( type, calcType, 0,0); if( type.IsDouble() ){ //mov eax,HILONG(dbl) OpBuffer[obp++]=(char)0xB8; *((long *)(OpBuffer+obp))=(long)*(long *)(((char *)(&dbl))+4); obp+=sizeof(long); //mov dword ptr[ebp+offset+sizeof(long)],eax OpBuffer[obp++]=(char)0x89; OpBuffer[obp++]=(char)0x85; *((long *)(OpBuffer+obp))=offset+sizeof(long); AddLocalVarAddrSchedule(); obp+=sizeof(long); //mov eax,LOLONG(dbl) OpBuffer[obp++]=(char)0xB8; *((long *)(OpBuffer+obp))=*(long *)(&dbl); obp+=sizeof(long); //mov dword ptr[ebp+offset],eax OpBuffer[obp++]=(char)0x89; OpBuffer[obp++]=(char)0x85; *((long *)(OpBuffer+obp))=offset; AddLocalVarAddrSchedule(); obp+=sizeof(long); } else if( type.IsSingle() ){ float flt; flt=(float)dbl; //mov eax,InitValue OpBuffer[obp++]=(char)0xB8; *((long *)(OpBuffer+obp))=*(long *)&flt; obp+=sizeof(long); //mov dword ptr[ebp+offset],eax OpBuffer[obp++]=(char)0x89; OpBuffer[obp++]=(char)0x85; *((long *)(OpBuffer+obp))=offset; AddLocalVarAddrSchedule(); obp+=sizeof(long); } else if( type.Is64() ){ //mov eax,HILONG(i64data) OpBuffer[obp++]=(char)0xB8; *((long *)(OpBuffer+obp))=(long)*(long *)(((char *)(&i64data))+4); obp+=sizeof(long); //mov dword ptr[ebp+offset+sizeof(long)],eax OpBuffer[obp++]=(char)0x89; OpBuffer[obp++]=(char)0x85; *((long *)(OpBuffer+obp))=offset+sizeof(long); AddLocalVarAddrSchedule(); obp+=sizeof(long); //mov eax,LOLONG(i64data) OpBuffer[obp++]=(char)0xB8; *((long *)(OpBuffer+obp))=*(long *)(&i64data); obp+=sizeof(long); //mov dword ptr[ebp+offset],eax OpBuffer[obp++]=(char)0x89; OpBuffer[obp++]=(char)0x85; *((long *)(OpBuffer+obp))=offset; AddLocalVarAddrSchedule(); obp+=sizeof(long); } else if( type.IsDWord() || type.IsLong() || type.IsPointer() ){ if(type.GetBasicType()==typeOfPtrChar){ //文字列定数のとき char *temp; temp=(char *)i64data; i2=dataTable.AddString(temp,lstrlen(temp)); HeapDefaultFree(temp); //mov eax,DataPos OpBuffer[obp++]=(char)0xB8; *((long *)(OpBuffer+obp))=(long)i2; pobj_DataTableSchedule->add(); obp+=sizeof(long); } else{ //mov eax,InitValue OpBuffer[obp++]=(char)0xB8; *((long *)(OpBuffer+obp))=(long)i64data; obp+=sizeof(long); } //mov dword ptr[ebp+offset],eax OpBuffer[obp++]=(char)0x89; OpBuffer[obp++]=(char)0x85; *((long *)(OpBuffer+obp))=offset; AddLocalVarAddrSchedule(); obp+=sizeof(long); } else if( type.IsWord() || type.IsInteger() ){ //mov ax,InitValue OpBuffer[obp++]=(char)0x66; OpBuffer[obp++]=(char)0xB8; *((WORD *)(OpBuffer+obp))=(WORD)i64data; obp+=sizeof(WORD); //mov word ptr[ebp+offset],ax OpBuffer[obp++]=(char)0x66; OpBuffer[obp++]=(char)0x89; OpBuffer[obp++]=(char)0x85; *((long *)(OpBuffer+obp))=offset; AddLocalVarAddrSchedule(); obp+=sizeof(long); } else if( type.IsSByte() || type.IsByte() || type.IsBoolean() ){ //mov byte ptr[ebp+offset],InitValue OpBuffer[obp++]=(char)0xC6; OpBuffer[obp++]=(char)0x85; *((long *)(OpBuffer+obp))=offset; AddLocalVarAddrSchedule(); obp+=sizeof(long); *((BYTE *)(OpBuffer+obp))=(BYTE)i64data; obp+=sizeof(BYTE); } return true; } void dim( char *VarName,int *SubScripts,Type &type,char *InitBuf,char *ConstractParameter,DWORD dwFlags){ if( UserProc::IsGlobalAreaCompiling() ){ ///////////////////////// // グローバル変数 ///////////////////////// AddGlobalVariable(VarName,SubScripts,type,InitBuf,ConstractParameter,dwFlags); } else{ ///////////////// // ローカル変数 ///////////////// if( UserProc::CompilingUserProc().localVars.DuplicateCheck( VarName ) ){ //2重定義のエラー SetError(15,VarName,cp); return; } bool isConst = ( dwFlags & DIMFLAG_CONST ) ? true:false; Variable *pVar = new Variable( VarName, type, isConst ); if( SubScripts[0] != -1 ){ //配列あり pVar->SetArray( SubScripts ); } //コンストラクタ用パラメータ pVar->paramStrForConstructor = ConstractParameter; //レキシカルスコープ pVar->ScopeLevel=obj_LexScopes.GetNowLevel(); pVar->ScopeStartAddress=obj_LexScopes.GetStartAddress(); pVar->bLiving=TRUE; //エラー用 pVar->source_code_address=cp; // 変数を追加 UserProc::CompilingUserProc().localVars.push_back( pVar ); //アラインメントを考慮 if( pVar->IsStruct() ){ int alignment = pVar->GetClass().iAlign; if( alignment ){ if( AllLocalVarSize % alignment ){ AllLocalVarSize += alignment - (AllLocalVarSize % alignment); } } if( alignment == PTR_SIZE*2 ){ // ポインタに要するサイズよりも一回り大きなアラインメントが指定されているとき // (例:CONTEXT構造体など) // 呼び出し側のオフセットズレを考慮する if( 0 == ( UserProc::CompilingUserProc().RealParams().GetMemorySize() + PTR_SIZE/*ret分*/ ) % alignment ){ AllLocalVarSize += PTR_SIZE; } } } AllLocalVarSize += pVar->GetMemorySize(); pVar->offset = AllLocalVarSize; //レキシカルスコープ pVar->ScopeLevel=obj_LexScopes.GetNowLevel(); pVar->ScopeStartAddress=obj_LexScopes.GetStartAddress(); pVar->bLiving=TRUE; if(InitBuf[0]){ //初期代入時のみ、書き込みアクセスを許可する if( isConst ){ pVar->ConstOff(); } int result = 0; if( !pVar->IsObject() ){ result = InitLocalVar(-pVar->offset, *pVar, pVar->GetSubScriptsPtr(), InitBuf); } if(!result){ //動的な式だった場合は代入演算を行う char temporary[8192]; sprintf(temporary,"%s=%s",VarName,InitBuf); OpcodeCalc(temporary); } if( isConst ){ pVar->ConstOn(); } } else{ //push 0 op_push_V(0); //push VarSize op_push_V( pVar->GetMemorySize() ); //mov eax,ebp OpBuffer[obp++]=(char)0x8B; OpBuffer[obp++]=(char)0xC5; //add eax,offset OpBuffer[obp++]=(char)0x05; *((long *)(OpBuffer+obp))=-pVar->offset; AddLocalVarAddrSchedule(); obp+=sizeof(long); //push eax op_push(REG_EAX); //call FillMemory OpBuffer[obp++]=(char)0xFF; OpBuffer[obp++]=(char)0x15; DllProc *pDllProc = GetDeclareHash("FillMemory"); pDllProc->Using(); pobj_ImportAddrSchedule->add(pDllProc); obp+=sizeof(long); } } //New呼び出し if( type.IsObject() &&(dwFlags&DIMFLAG_NONCALL_CONSTRACTOR)==0&&InitBuf[0]=='\0'){ char objectSize[255]; if( SubScripts[0] == -1 ){ objectSize[0] = 0; } else{ if( SubScripts[1] != -1 ){ SetError(300,NULL,cp); } sprintf( objectSize, "%d", SubScripts[0] ); } Operator_New( type.GetClass(), objectSize, ConstractParameter, type ); //pop eax op_pop( REG_EAX ); RELATIVE_VAR RelativeVar; GetVarOffset( true, false, VarName, &RelativeVar, Type() ); if( RelativeVar.dwKind == VAR_DIRECTMEM ){ SetError(); } SetVariableFromEax( DEF_OBJECT, DEF_OBJECT, &RelativeVar ); } } void SetVarPtrToEax(RELATIVE_VAR *pRelativeVar){ if(pRelativeVar->dwKind==VAR_GLOBAL){ if(pRelativeVar->bOffsetOffset){ //lea eax,dword ptr[ecx+offset] OpBuffer[obp++]=(char)0x8D; OpBuffer[obp++]=(char)0x81; *((long *)(OpBuffer+obp))=pRelativeVar->offset; pobj_GlobalVarSchedule->add(); obp+=sizeof(long); } else{ //mov eax,offset OpBuffer[obp++]=(char)0xB8; *((long *)(OpBuffer+obp))=pRelativeVar->offset; pobj_GlobalVarSchedule->add(); obp+=sizeof(long); } } else if(pRelativeVar->dwKind==VAR_REFGLOBAL){ if(pRelativeVar->bOffsetOffset){ //mov eax,ecx OpBuffer[obp++]=(char)0x8B; OpBuffer[obp++]=(char)0xC1; //add eax,dword ptr[offset] op_add_RM( sizeof(long), REG_EAX, REG_NON, (int)pRelativeVar->offset, MOD_DISP32 ); } else{ //mov eax,dword ptr[offset] op_mov_RM( sizeof(long), REG_EAX, REG_NON, (int)pRelativeVar->offset, MOD_DISP32 ); } obp-=sizeof(long); pobj_GlobalVarSchedule->add(); obp+=sizeof(long); } else if(pRelativeVar->dwKind==VAR_LOCAL){ if(pRelativeVar->bOffsetOffset){ //add ecx,offset OpBuffer[obp++]=(char)0x81; OpBuffer[obp++]=(char)0xC1; *((long *)(OpBuffer+obp))=pRelativeVar->offset; AddLocalVarAddrSchedule(); obp+=sizeof(long); //lea eax,dword ptr[ebp+ecx] OpBuffer[obp++]=(char)0x8D; OpBuffer[obp++]=(char)0x44; OpBuffer[obp++]=(char)0x0D; OpBuffer[obp++]=(char)0x00; } else{ //lea eax,dword ptr[ebp+offset] OpBuffer[obp++]=(char)0x8D; OpBuffer[obp++]=(char)0x85; *((long *)(OpBuffer+obp))=pRelativeVar->offset; AddLocalVarAddrSchedule(); obp+=sizeof(long); } } else if(pRelativeVar->dwKind==VAR_REFLOCAL){ if(pRelativeVar->bOffsetOffset){ //mov eax,ecx OpBuffer[obp++]=(char)0x8B; OpBuffer[obp++]=(char)0xC1; //add eax,dword ptr[ebp+offset] OpBuffer[obp++]=(char)0x03; OpBuffer[obp++]=(char)0x85; *((long *)(OpBuffer+obp))=pRelativeVar->offset; AddLocalVarAddrSchedule(); obp+=sizeof(long); } else{ //mov eax,dword ptr[ebp+offset] OpBuffer[obp++]=(char)0x8B; OpBuffer[obp++]=(char)0x85; *((long *)(OpBuffer+obp))=pRelativeVar->offset; AddLocalVarAddrSchedule(); obp+=sizeof(long); } } else if(pRelativeVar->dwKind==VAR_DIRECTMEM){ //mov eax,ecx OpBuffer[obp++]=(char)0x8B; OpBuffer[obp++]=(char)0xC1; } } void SetVarPtrToReg(int reg,RELATIVE_VAR *pRelativeVar){ if( reg != REG_EAX ){ SetError(); //TODO: 未完成 } SetVarPtrToEax( pRelativeVar ); } bool Compile_AddGlobalRootsForGc(){ UserProc *pUserProc_AddGlobalRootPtr = GetClassMethod( "_System_CGarbageCollection", "AddGlobalRootPtr" ); if( !pUserProc_AddGlobalRootPtr ){ SetError(3, "_System_CGarbageCollection.AddGlobalRootPtr", -1 ); return false; } BOOST_FOREACH( const Variable *pVar, globalVars ){ if( pVar->IsObject() || pVar->IsPointer() || pVar->IsStruct() ){ // オブジェクトまたはポインタだったとき // ※構造体も含む(暫定対応) // 変数領域に要するLONG_PTR単位の個数を引き渡す op_push_V( pVar->GetMemorySize()/PTR_SIZE ); ///////////////////////////// // ルートポインタを引き渡す //mov eax,offset op_mov_RV(REG_EAX,(int)pVar->offset); obp-=sizeof(long); pobj_GlobalVarSchedule->add(); obp+=sizeof(long); //push eax op_push( REG_EAX ); // ///////////////////////////// ///////////////////////////// // Thisポインタを引き渡す SetThisPtrToReg(REG_EAX); //push eax op_push( REG_EAX ); // ///////////////////////////// // call AddGlobalRootPtr op_call( pUserProc_AddGlobalRootPtr ); ReallocNativeCodeBuffer(); } } return true; }