#include "../BasicCompiler_Common/common.h" #include "Opcode.h" //変数 VARIABLE *GlobalVar; int MaxGlobalVarNum; int AllGlobalVarSize; int AllInitGlobalVarSize; VARIABLE *LocalVar; int MaxLocalVarNum; int AllLocalVarSize; void SetRelativeOffset(int *pType,LONG_PTR lpIndex,RELATIVE_VAR *pRelativeVar,char *lpPtrOffset){ int i2; PushLongVariable(pRelativeVar); i2=NumOpe(lpPtrOffset,0,0,0); ChangeTypeToLong(i2); //pop ebx op_pop(REG_EBX); if(PTR_LEVEL(*pType)){ *pType = PTR_LEVEL_DOWN( *pType ); i2=GetTypeSize(*pType,lpIndex); if(i2>=2){ //imul ebx,i2 op_imul_RV( REG_EBX, i2 ); } } 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(int *SubScripts,char *array,int type,LONG_PTR lpIndex){ extern HANDLE hHeap; int i,i2,i3,i4,TypeSize; 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--){ TYPEINFO TypeInfo; BOOL bUseHeap; TypeInfo.type=NumOpe(pParm[i],DEF_LONG,-1,&TypeInfo.u.lpIndex,&bUseHeap); if(TypeInfo.type==DEF_OBJECT){ //キャスト演算子のオーバーロードに対応する CallCastOperatorProc( TypeInfo.type,TypeInfo.u.lpIndex, bUseHeap,DEF_LONG,-1); TypeInfo.type=DEF_LONG; } ChangeTypeToLong(TypeInfo.type); //pop eax op_pop(REG_EAX); for(i2=i+1,i4=1;i2GetMemberOffset( VarName, &i ); if(i==pobj_c->iMemberNum){ if(isErrorEnabled) SetError(103,VarName,cp); return 0; } CMember *pMember=pobj_c->ppobj_Member[i]; //アクセシビリティをチェック if(pobj_c==pobj_CompilingClass){ //同一クラスオブジェクトの場合はプライベートアクセスを容認する if(pMember->dwAccess==ACCESS_NON){ if(isErrorEnabled) SetError(107,VarName,cp); return 0; } } else{ if((bPrivateAccess==0&&pMember->dwAccess==ACCESS_PRIVATE)|| pMember->dwAccess==ACCESS_NON){ if(isErrorEnabled) SetError(107,VarName,cp); return 0; } else if(bPrivateAccess==0&&pMember->dwAccess==ACCESS_PROTECTED){ if(isErrorEnabled) SetError(108,VarName,cp); return 0; } } //Const定義の場合は書き込みアクセスを制限する //※コンストラクタをコンパイル中の場合は例外的に許可する if( pMember->IsConst() && //定数メンバである isWriteAccess && //書き込みアクセスを要求されている pobj_c->IsCompilingConstructor() == false //コンストラクタ コンパイル中を除く ){ //Const定義の変数に書き込みアクセスをしようとした場合 SetError(61,VarName,cp); } *pType=pMember->TypeInfo.type; *plpNestIndex=pMember->TypeInfo.u.lpIndex; //ポインタ変数の場合 if(IsPtrType(*pType)){ if(pMember->SubScripts[0]==-1){ lstrcpy(lpPtrOffset,array); array[0]=0; } } else{ if(lpPtrOffset[0]){ if(isErrorEnabled) SetError(16,member,cp); return 0; } } 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,*pType,pMember->TypeInfo.u.lpIndex)) if(isErrorEnabled) SetError(14,member,cp); } else if(pMember->SubScripts[0]!=-1){ *pType|=FLAG_PTR; } if(NestMember[0]){ //入れ子構造の場合 if(*pType==DEF_OBJECT || *pType==DEF_STRUCT){ if( refType != CClass::Dot ){ if(isErrorEnabled) SetError(104,member,cp); return 0; } if( *pType==DEF_OBJECT ){ // 参照内容へのポインタを抽出 SetRelativeOffset( *pRelativeVar ); } } else if(*pType==DEF_PTR_OBJECT||*pType==DEF_PTR_STRUCT){ //構造体ポインタ型メンバ変数 if(lpPtrOffset[0]){ //pObj[n].member if( ( *pType==DEF_PTR_OBJECT||*pType==DEF_PTR_STRUCT )&& refType != CClass::Dot ){ if(isErrorEnabled) SetError(104,member,cp); return 0; } //直接参照に切り替え SetRelativeOffset(pType,*plpNestIndex,pRelativeVar,lpPtrOffset); pRelativeVar->dwKind=VAR_DIRECTMEM; lpPtrOffset[0]=0; } else{ //pObj->member if( ( *pType==DEF_PTR_OBJECT||*pType==DEF_PTR_STRUCT )&& refType != CClass::Pointer ){ if(isErrorEnabled) SetError(104,member,cp); return 0; } SetRelativeOffset( *pRelativeVar ); } } else if(*pType==MAKE_PTR_TYPE(DEF_OBJECT,2) || *pType==MAKE_PTR_TYPE(DEF_STRUCT,2)){ //構造体ポインタのポインタ型メンバ変数 if(lpPtrOffset[0]){ //ppObj[n]->member if( refType != CClass::Pointer ){ if(isErrorEnabled) SetError(104,member,cp); return 0; } //直接参照に切り替え SetRelativeOffset(pType,*plpNestIndex,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 0; } } if(!GetMemberOffset( isErrorEnabled, isWriteAccess, pMember->TypeInfo.u.pobj_Class, NestMember, pType, pRelativeVar, plpNestIndex, 0)) return 0; } if(lpPtrOffset[0]){ SetRelativeOffset(pType,*plpNestIndex,pRelativeVar,lpPtrOffset); pRelativeVar->dwKind=VAR_DIRECTMEM; } return 1; } void GetWithName(char *buffer){ extern WITHINFO WithInfo; int i; buffer[0]=0; for(i=0;idwKind=VAR_DIRECTMEM; //////////////// // 呼び出し //////////////// *pType=CallProc(idProc,pInfo,VarName,array,&lpIndex); //戻り値をecxにコピー op_mov_RR( REG_ECX, REG_EAX ); LONG_PTR lp2; if(!GetMemberOffset( isErrorEnabled, isWriteAccess, (CClass *)lpIndex, member,pType,pRelativeVar,&lp2,0)) return 0; if(plpIndex) *plpIndex=lp2; return 1; } } lstrcpy(VarName,variable); GetVarFormatString(VarName,array,lpPtrOffset,member,refType); int *pSubScripts; bool bConst; if(bCompilingGlobal==0){ //////////////////// // ローカル変数 //////////////////// for(i=MaxLocalVarNum-1;i>=0;i--){ //レキシカルスコープを考慮してバックサーチ if( LocalVar[i].bLiving //現在のスコープで有効なもの && LocalVar[i].ScopeLevel <= obj_LexScopes.GetNowLevel() //現在のスコープレベルを超さないもの(Returnによる解放処理中を考慮) ){ if(lstrcmp(VarName,LocalVar[i].name)==0) break; } } if(i>=0){ //ポインタ変数の場合 if(IsPtrType(LocalVar[i].type)){ if(LocalVar[i].SubScripts[0]==-1){ lstrcpy(lpPtrOffset,array); array[0]=0; } } else{ if(lpPtrOffset[0]){ SetError(16,variable,cp); pRelativeVar->dwKind=NON_VAR; return 0; } } pRelativeVar->offset=-LocalVar[i].offset; pRelativeVar->bOffsetOffset=0; if(LocalVar[i].fRef) pRelativeVar->dwKind=VAR_REFLOCAL; else pRelativeVar->dwKind=VAR_LOCAL; *pType=LocalVar[i].type; lpIndex=LocalVar[i].u.index; if(plpIndex) *plpIndex=lpIndex; pSubScripts=LocalVar[i].SubScripts; bConst = LocalVar[i].bConst; goto ok; } } if(pobj_CompilingClass){ ////////////////////// // クラスメンバの参照 ////////////////////// if(lstrcmpi(variable,"This")==0){ //Thisオブジェクト //Thisポインタをecxにコピー SetThisPtrToReg(REG_ECX); *pType=DEF_OBJECT; pRelativeVar->dwKind=VAR_DIRECTMEM; if(plpIndex) *plpIndex=(LONG_PTR)pobj_CompilingClass; return 1; } if(_memicmp(variable,"This.",5)==0){ //Thisオブジェクトのメンバを参照するとき SlideString(variable+5,-5); lstrcpy(VarName,variable); } else{ //クラス内メンバを参照するとき(通常) for(i=0;iiMemberNum;i++){ if(lstrcmp(VarName,pobj_CompilingClass->ppobj_Member[i]->name)==0) break; } if(i==pobj_CompilingClass->iMemberNum) goto NonClassMember; } //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(!GetMemberOffset( isErrorEnabled, isWriteAccess, pobj_CompilingClass, variable, pType, pRelativeVar, &lpIndex,1)) return 0; if(plpIndex) *plpIndex=lpIndex; return 1; } NonClassMember: ////////////////////////// // 静的ローカル変数 // ※"Static.Object.Method.Variable" ////////////////////////// char temporary[VN_SIZE]; extern SubInfo *pCompilingSubInfo; if(pCompilingSubInfo){ GetNowStaticVarFullName(VarName,temporary); for(i=0;iname,VarName); for(i=0;i=0;i--){ //レキシカルスコープを考慮してバックサーチ if( GlobalVar[i].bLiving //現在のスコープで有効なもの && GlobalVar[i].ScopeLevel <= obj_LexScopes.GetNowLevel() //現在のスコープレベルを超さないもの(Returnによる解放処理中を考慮) ){ if(lstrcmp(VarName,GlobalVar[i].name)==0) break; } } if(i>=0){ goto GlobalOk; } if(isErrorEnabled) SetError(3,variable,cp); pRelativeVar->dwKind=NON_VAR; return 0; GlobalOk: //ポインタ変数の場合 if(IsPtrType(GlobalVar[i].type)){ if(GlobalVar[i].SubScripts[0]==-1){ lstrcpy(lpPtrOffset,array); array[0]=0; } } else{ if(lpPtrOffset[0]){ SetError(16,variable,cp); pRelativeVar->dwKind=NON_VAR; return 0; } } pRelativeVar->offset=GlobalVar[i].offset; pRelativeVar->bOffsetOffset=0; if(GlobalVar[i].fRef){ // 参照型 pRelativeVar->dwKind = VAR_REFGLOBAL; } else pRelativeVar->dwKind=VAR_GLOBAL; *pType=GlobalVar[i].type; lpIndex=GlobalVar[i].u.index; if(plpIndex) *plpIndex=lpIndex; pSubScripts=GlobalVar[i].SubScripts; bConst = GlobalVar[i].bConst; ok: if( bConst && isWriteAccess ){ //Const定義の変数に書き込みアクセスをしようとした場合 if( *pType == DEF_OBJECT ){ //オブジェクト定数 SetError(130, VarName, cp ); } else{ //一般のConst変数 SetError(61,VarName,cp); } } if(array[0]==0&&pSubScripts[0]!=-1){ //配列の先頭ポインタを示す場合 *pType|=FLAG_PTR; if(pss) memcpy(pss,pSubScripts,MAX_ARRAYDIM); return 1; } 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,*pType,lpIndex)){ SetError(14,variable,cp); pRelativeVar->dwKind=NON_VAR; return 0; } } if(member[0]){ if(*pType==DEF_OBJECT || *pType==DEF_STRUCT){ //実態オブジェクトのメンバを参照(obj.member) if( refType != CClass::Dot ){ SetError(104,VarName,cp); pRelativeVar->dwKind=NON_VAR; return 0; } if( *pType==DEF_OBJECT ){ // 参照内容へのポインタを抽出 SetRelativeOffset( *pRelativeVar ); } } else if(*pType==DEF_PTR_OBJECT || *pType==DEF_PTR_STRUCT){ //ポインタオブジェクトが示すメンバを参照 if(lpPtrOffset[0]){ //pObj[n].member if( refType != CClass::Dot ){ SetError(104,VarName,cp); pRelativeVar->dwKind=NON_VAR; return 0; } SetRelativeOffset(pType,lpIndex,pRelativeVar,lpPtrOffset); pRelativeVar->dwKind=VAR_DIRECTMEM; } else{ //pObj->member if( refType != CClass::Pointer ){ SetError(104,VarName,cp); pRelativeVar->dwKind=NON_VAR; return 0; } SetVarPtrToEax(pRelativeVar); pRelativeVar->dwKind=VAR_DIRECTMEM; //mov ecx,dword ptr[eax] OpBuffer[obp++]=(char)0x8B; OpBuffer[obp++]=(char)0x08; } } else if(*pType==MAKE_PTR_TYPE(DEF_OBJECT,2) || *pType==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 0; } SetRelativeOffset(pType,lpIndex,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 0; } } else{ SetError(102,VarName,cp); pRelativeVar->dwKind=NON_VAR; return 0; } LONG_PTR lp2; if(!GetMemberOffset( isErrorEnabled, isWriteAccess, (CClass *)lpIndex, member,pType,pRelativeVar,&lp2,0)) return 0; if(plpIndex) *plpIndex=lp2; return 1; } if(lpPtrOffset[0]){ SetRelativeOffset(pType,lpIndex,pRelativeVar,lpPtrOffset); pRelativeVar->dwKind=VAR_DIRECTMEM; } return 1; } BOOL SetInitGlobalData(int offset,int type,LONG_PTR lpIndex,int *SubScripts,char *InitBuf){ extern BYTE *initGlobalBuf; int i,i2,i3,TypeSize; char temporary[VN_SIZE]; if(InitBuf[0]=='['){ SlideString(InitBuf+1,-1); InitBuf[lstrlen(InitBuf)-1]=0; TypeSize=GetTypeSize(type,lpIndex); if(SubScripts[0]!=-1){ TypeSize*=JumpSubScripts(SubScripts+1); i=0; i2=0; while(1){ if(SubScripts[0]iMemberNum;i2++){ i=GetOneParameter(InitBuf,i,temporary); i3=pobj_c->GetMemberOffset( pobj_c->ppobj_Member[i2]->name, NULL ); if(!SetInitGlobalData(offset+i3, pobj_c->ppobj_Member[i2]->TypeInfo.type, pobj_c->ppobj_Member[i2]->TypeInfo.u.lpIndex, pobj_c->ppobj_Member[i2]->SubScripts, temporary)) return 0; if(InitBuf[i]=='\0') break; } if(i2+1!=pobj_c->iMemberNum){ SetError(41,0,cp); return 0; } return 1; } SetError(41,0,cp); return 0; } /////////////////////////////////////// // 単発式([]で囲まれていない) /////////////////////////////////////// if( type == DEF_OBJECT || type == DEF_STRUCT ){ //オブジェクトまたは構造体の場合はありえない SetError(300,NULL,cp); return 0; } if(SubScripts[0]!=-1){ SetError(41,0,cp); return 0; } double dbl; _int64 i64data; int CalcType; LONG_PTR lpCalcIndex; CalcType=StaticCalculation(true, InitBuf,type,&i64data,&lpCalcIndex); if(IsRealNumberType(CalcType)){ memcpy(&dbl,&i64data,sizeof(double)); i64data=(_int64)dbl; } else dbl=(double)i64data; //型チェック CheckDifferentType( type, lpIndex, CalcType, lpCalcIndex, 0,0); if(type==DEF_DOUBLE) *(double *)(initGlobalBuf+offset)=(double)dbl; else if(type==DEF_SINGLE) *(float *)(initGlobalBuf+offset)=(float)dbl; else if(type==DEF_INT64||type==DEF_QWORD) *(_int64 *)(initGlobalBuf+offset)=i64data; else if(type==DEF_LONG||type==DEF_DWORD||IsPtrType(type)){ if(type==typeOfPtrChar&&lpCalcIndex==LITERAL_STRING){ //文字列定数のとき 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==DEF_INTEGER||type==DEF_WORD || (isUnicode&&type==DEF_CHAR)) *(WORD *)(initGlobalBuf+offset)=(WORD)i64data; else if(type==DEF_SBYTE||type==DEF_BYTE||type==DEF_BOOLEAN || (isUnicode==false&&type==DEF_CHAR)) *(BYTE *)(initGlobalBuf+offset)=(BYTE)i64data; //String型が未完成 return 1; } BOOL InitLocalVar(int offset,int type,LONG_PTR lpIndex,int *SubScripts,char *InitBuf){ int i,i2,i3,TypeSize; char temporary[VN_SIZE]; if(InitBuf[0]=='['){ SlideString(InitBuf+1,-1); InitBuf[lstrlen(InitBuf)-1]=0; TypeSize=GetTypeSize(type,lpIndex); if(SubScripts[0]!=-1){ TypeSize*=JumpSubScripts(SubScripts+1); i=0; i2=0; while(1){ if(SubScripts[0]iMemberNum;i2++){ i=GetOneParameter(InitBuf,i,temporary); i3 = pobj_c->GetMemberOffset( pobj_c->ppobj_Member[i2]->name, NULL ); if(!InitLocalVar(offset+i3, pobj_c->ppobj_Member[i2]->TypeInfo.type, pobj_c->ppobj_Member[i2]->TypeInfo.u.lpIndex, pobj_c->ppobj_Member[i2]->SubScripts, temporary)) return 0; if(InitBuf[i]=='\0') break; } if(i2+1!=pobj_c->iMemberNum){ SetError(41,0,cp); return 0; } return 1; } SetError(41,0,cp); return 0; } /////////////////////////////////////// // 単発式([]で囲まれていない) /////////////////////////////////////// if(SubScripts[0]!=-1){ SetError(41,0,cp); return 0; } double dbl; _int64 i64data; int CalcType; LONG_PTR lpCalcIndex; CalcType=StaticCalculation(false, InitBuf,type,&i64data,&lpCalcIndex); if(!CalcType){ //動的データだった場合 return 0; } if(IsRealNumberType(CalcType)){ memcpy(&dbl,&i64data,sizeof(double)); i64data=(_int64)dbl; } else dbl=(double)i64data; //型チェック CheckDifferentType( type, lpIndex, CalcType, lpCalcIndex, 0,0); if(type==DEF_DOUBLE){ //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==DEF_SINGLE){ 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==DEF_INT64||type==DEF_QWORD){ //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==DEF_LONG||type==DEF_DWORD||IsPtrType(type)){ if(type==typeOfPtrChar&&lpCalcIndex==LITERAL_STRING){ //文字列定数のとき 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==DEF_INTEGER||type==DEF_WORD || (isUnicode&&type==DEF_CHAR)){ //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==DEF_SBYTE||type==DEF_BYTE||type==DEF_BOOLEAN || (isUnicode==false&&type==DEF_CHAR)){ //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); } //String型が未完成 return 1; } void dim(bool isRef, char *VarName,int *SubScripts,TYPEINFO &TypeInfo,int TypeSize,char *InitBuf,char *ConstractParameter,DWORD dwFlags){ extern BOOL bCompilingGlobal; if(bCompilingGlobal){ ///////////////////////// // グローバル変数 ///////////////////////// AddGlobalVariable(isRef,VarName,SubScripts,&TypeInfo,TypeSize,InitBuf,ConstractParameter,dwFlags); } else{ ///////////////// // ローカル変数 ///////////////// int i2,i3; for(i2=0;i2fRef = REF_VARIABLE; TypeSize = PTR_SIZE; } else pVar->fRef=0; for(i2=1,i3=0;i3<255;i3++){ //配列要素数 pVar->SubScripts[i3]=SubScripts[i3]; if(SubScripts[i3]==-1) break; i2*=SubScripts[i3]+1; } int VarSize=TypeSize*i2; if(VarSize%4) VarSize+=4-(VarSize%4); //変数データを追加 lstrcpy(pVar->name,VarName); if(dwFlags & DIMFLAG_CONST) pVar->bConst = true; else pVar->bConst = false; if(SubScripts[0]==-1) pVar->bArray=0; else pVar->bArray=1; pVar->type=TypeInfo.type; pVar->u.index=TypeInfo.u.lpIndex; AllLocalVarSize+=VarSize; pVar->offset=AllLocalVarSize; //レキシカルスコープ pVar->ScopeLevel=obj_LexScopes.GetNowLevel(); pVar->ScopeStartAddress=obj_LexScopes.GetStartAddress(); pVar->bLiving=TRUE; if(InitBuf[0]){ //初期代入時のみ、書き込みアクセスを許可する bool bConstBack = pVar->bConst; pVar->bConst = false; int result = 0; if( pVar->type != DEF_OBJECT ){ result = InitLocalVar(-pVar->offset, pVar->type, pVar->u.index, pVar->SubScripts, InitBuf); } if(!result){ //動的な式だった場合は代入演算を行う char temporary[8192]; sprintf(temporary,"%s=%s",VarName,InitBuf); OpcodeCalc(temporary); } pVar->bConst = bConstBack; } else{ //push 0 op_push_V(0); //push VarSize op_push_V(VarSize); //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; DECLAREINFO *pdi; pdi=GetDeclareHash("FillMemory"); pdi->bUse=1; pobj_ImportAddrSchedule->add(pdi); obp+=sizeof(long); } } //New呼び出し if(TypeInfo.type==DEF_OBJECT&&(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( *TypeInfo.u.pobj_Class, objectSize, ConstractParameter, TypeInfo ); //pop eax op_pop( REG_EAX ); int type; LONG_PTR lpIndex; RELATIVE_VAR RelativeVar; GetVarOffset( true, false, VarName, &type, &RelativeVar, &lpIndex ); if( RelativeVar.dwKind == VAR_DIRECTMEM ){ SetError(); } SetVariableFromEax( DEF_OBJECT, DEF_OBJECT, &RelativeVar ); } if(TypeInfo.type==DEF_OBJECT){ if(TypeInfo.u.pobj_Class->IsAbstract()){ //抽象クラスだったとき SetError(125,TypeInfo.u.pobj_Class->name,cp); } } } void dim(char *Parameter,DWORD dwFlags){ extern BOOL bCompilingGlobal; extern HANDLE hHeap; int i2; char VarName[VN_SIZE]; //参照型かどうか bool isRef = false; i2 = 0; if( Parameter[i2] == 1 && Parameter[i2+1] == ESC_BYREF ){ //参照型 isRef = true; Parameter += 2; } if(dwFlags & DIMFLAG_CONST){ ////////////////////////////////// // 定数変数の場合を考慮 ////////////////////////////////// for(;;i2++){ if(Parameter[i2] == '=' || Parameter[i2] == 1 && Parameter[i2] == ESC_AS || Parameter[i2] =='('){ VarName[i2] = 0; break; } VarName[i2] = Parameter[i2]; } //定数と2重定義されていないる場合は抜け出す if(CDBConst::obj.GetType(VarName)){ return; } //定数マクロとして定義されている場合は抜け出す if(GetConstHash(VarName)){ return; } } //構文を解析 int SubScripts[MAX_ARRAYDIM]; TYPEINFO TypeInfo; char InitBuf[8192]; char ConstractParameter[VN_SIZE]; if(!GetDimentionFormat(Parameter, isRef, VarName,SubScripts,&TypeInfo,InitBuf,ConstractParameter)) return; //定数と2重定義されていないかを調べる if(CDBConst::obj.GetType(VarName)){ SetError(15,VarName,cp); return; } //定数マクロとして定義されている場合 if(GetConstHash(VarName)){ SetError(15,VarName,cp); return; } //タイプサイズを取得 int TypeSize; TypeSize=GetTypeSize(TypeInfo.type,TypeInfo.u.lpIndex); if(dwFlags&DIMFLAG_STATIC){ if(bCompilingGlobal){ SetError(60,NULL,cp); return; } ///////////////////// // Static変数 // ※"Static.Object.Method.Variable" ///////////////////// char temporary[VN_SIZE]; GetNowStaticVarFullName(VarName,temporary); dim( isRef,temporary,SubScripts,TypeInfo,TypeSize,InitBuf,ConstractParameter,dwFlags ); /* Note: 静的変数のコンストラクタ呼び出しは _System_InitStaticLocalVariables関数内で一括して行う */ } else{ dim( isRef,VarName,SubScripts,TypeInfo,TypeSize,InitBuf,ConstractParameter,dwFlags ); } } void OpcodeDim(char *Parameter,DWORD dwFlags){ int i,i2,i3,IsStr=0; char temporary[8192]; for(i=0,i2=0;;i++,i2++){ if(Parameter[i]=='\"') IsStr^=1; if(Parameter[i]=='('&&IsStr==0){ i3=GetStringInPare(temporary+i2,Parameter+i); i+=i3-1; i2+=i3-1; continue; } if(Parameter[i]=='['&&IsStr==0){ i3=GetStringInBracket(temporary+i2,Parameter+i); i+=i3-1; i2+=i3-1; continue; } if((Parameter[i]==','&&IsStr==0)|| Parameter[i]=='\0'){ temporary[i2]=0; dim(temporary,dwFlags); if(Parameter[i]=='\0') break; i2=-1; continue; } temporary[i2]=Parameter[i]; } } 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; } }