Changeset 34 in dev for BasicCompiler_Common
- Timestamp:
- Jan 14, 2007, 6:11:23 AM (18 years ago)
- Location:
- BasicCompiler_Common
- Files:
-
- 1 added
- 2 deleted
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
BasicCompiler_Common/Compile.cpp
r26 r34 14 14 LABEL *pLabelNames; 15 15 int MaxLabelNum; 16 17 //ループごとのスケジュール18 DWORD *pExitWhileSchedule; //ExitWhileスケジュール19 int ExitWhileScheduleNum;20 DWORD *pExitForSchedule; //ExitForスケジュール21 int ExitForScheduleNum;22 DWORD *pExitDoSchedule; //ExitDoスケジュール23 int ExitDoScheduleNum;24 16 25 17 //Continueアドレス … … 176 168 break; 177 169 case ESC_EXITWHILE: 178 OpcodeExitWhile();170 obj_LexScopes.ExitWhile(); 179 171 break; 180 172 case ESC_EXITFOR: 181 OpcodeExitFor();173 obj_LexScopes.ExitFor(); 182 174 break; 183 175 case ESC_EXITDO: 184 OpcodeExitDo();176 obj_LexScopes.ExitDo(); 185 177 break; 186 178 case ESC_CONTINUE: -
BasicCompiler_Common/LexicalScoping.cpp
r5 r34 9 9 CLexicalScopes obj_LexScopes; 10 10 11 12 CScope::CScope( int level, int addr, SCOPE_TYPE TypeOfStatement ){ 13 this->level = level; 14 this->StartAddress = addr; 15 this->TypeOfStatement = TypeOfStatement; 16 17 pBreakSchedule = (DWORD *)malloc( 1 ); 18 nBreakSchedule = 0; 19 } 20 CScope::~CScope(){ 21 free( pBreakSchedule ); 22 } 23 24 int CScope::GetStartAddress(){ 25 return StartAddress; 26 } 27 SCOPE_TYPE CScope::GetTypeOfStatement(){ 28 return TypeOfStatement; 29 } 30 31 void CScope::Break(){ 32 //未解放のローカルオブジェクトを解放する 33 obj_LexScopes.CallDestructorsOfReturn( level ); 34 35 //jmp ...(Next addr) 36 OpBuffer[obp++]=(char)0xE9; 37 38 pBreakSchedule=(DWORD *)realloc( pBreakSchedule, ( nBreakSchedule + 1 ) * sizeof(DWORD) ); 39 pBreakSchedule[nBreakSchedule]=obp; 40 nBreakSchedule++; 41 42 obp+=sizeof(long); 43 } 44 void CScope::RunScheduleOfBreak(){ 45 for(int i=0;i<nBreakSchedule;i++){ 46 *((long *)(OpBuffer+pBreakSchedule[i]))=obp-(pBreakSchedule[i]+sizeof(long)); 47 } 48 } 49 50 51 CScope *CLexicalScopes::SearchScope( SCOPE_TYPE TypeOfStatement ){ 52 for( int i = level; i>=0; i-- ){ 53 if( ppScopes[i]->GetTypeOfStatement() == TypeOfStatement ){ 54 return ppScopes[i]; 55 } 56 } 57 return NULL; 58 } 59 11 60 CLexicalScopes::CLexicalScopes(){ 61 ppScopes = (CScope **)malloc( 1 ); 12 62 level=0; 13 63 } 14 64 CLexicalScopes::~CLexicalScopes(){ 65 free( ppScopes ); 15 66 } 16 67 void CLexicalScopes::Init(int addr){ 17 level=0; 18 StartAddresses[level]=addr; 19 } 20 void CLexicalScopes::LevelUp(int addr){ 68 // TODO: エラーチェック 69 70 level = -1; 71 Start( addr, SCOPE_TYPE_BASE ); 72 } 73 void CLexicalScopes::Start( int addr, SCOPE_TYPE TypeOfStatement ){ 21 74 level++; 22 StartAddresses[level]=addr; 23 } 24 void CLexicalScopes::LevelDown(void){ 25 //デストラクタを呼ぶ 26 CallDestrouctorsOfScope(); 27 28 //スコープレベルを下げる 29 level--; 30 if(level<0){ 75 ppScopes = (CScope **)realloc( ppScopes, ( level + 1 ) * sizeof( CScope * ) ); 76 ppScopes[level] = new CScope( level, addr, TypeOfStatement ); 77 } 78 void CLexicalScopes::End(){ 79 if( level <= 0 ){ 31 80 SetError(300,NULL,cp); 32 81 return; 33 82 } 83 84 //デストラクタを呼ぶ 85 CallDestructorsOfScopeEnd(); 34 86 35 87 extern BOOL bCompilingGlobal; … … 51 103 } 52 104 105 //使用済みローカル変数の生存チェックを外す 53 106 for(int i=0;i<num;i++){ 54 if(pVar[i].bLiving&&pVar[i].ScopeLevel==level +1){107 if(pVar[i].bLiving&&pVar[i].ScopeLevel==level){ 55 108 pVar[i].bLiving=0; 56 109 extern int obp; … … 58 111 } 59 112 } 60 } 61 62 int CLexicalScopes::GetNowLevel(void){ 113 114 115 //スコープ抜け出しスケジュール 116 ppScopes[level]->RunScheduleOfBreak(); 117 118 119 //スコープレベルを下げる 120 delete ppScopes[level]; 121 level--; 122 } 123 124 void CLexicalScopes::ExitFor(){ 125 CScope *pScope = SearchScope( SCOPE_TYPE_FOR ); 126 if( !pScope ){ 127 SetError(12,"Exit For",cp); 128 return; 129 } 130 131 pScope->Break(); 132 } 133 void CLexicalScopes::ExitWhile(){ 134 CScope *pScope = SearchScope( SCOPE_TYPE_WHILE ); 135 if( !pScope ){ 136 SetError(12,"Exit While",cp); 137 return; 138 } 139 140 pScope->Break(); 141 } 142 void CLexicalScopes::ExitDo(){ 143 CScope *pScope = SearchScope( SCOPE_TYPE_DO ); 144 if( !pScope ){ 145 SetError(12,"Exit Do",cp); 146 return; 147 } 148 149 pScope->Break(); 150 } 151 152 int CLexicalScopes::GetNowLevel(){ 63 153 return level; 64 154 } 65 int CLexicalScopes::GetStartAddress(void){ 66 return StartAddresses[level]; 67 } 155 void CLexicalScopes::SetNowLevel( int level ){ 156 this->level = level; 157 } 158 int CLexicalScopes::GetStartAddress(){ 159 return ppScopes[level]->GetStartAddress(); 160 } 161 162 163 // スコープ終了時のデストラクタ呼び出し 164 void CLexicalScopes::CallDestructorsOfScopeEnd(){ 165 extern BOOL bCompilingGlobal; 166 VARIABLE *pVar; 167 int num; 168 if(bCompilingGlobal){ 169 //グローバルオブジェクトの解放処理 170 extern VARIABLE *GlobalVar; 171 extern int MaxGlobalVarNum; 172 pVar=GlobalVar; 173 num=MaxGlobalVarNum; 174 } 175 else{ 176 //ローカルオブジェクトの解放処理 177 extern VARIABLE *LocalVar; 178 extern int MaxLocalVarNum; 179 pVar=LocalVar; 180 num=MaxLocalVarNum; 181 } 182 183 184 int i3,i4,i5; 185 int indexSystemGC=-1; 186 for( i3 = num - 1; i3 >= 0; i3-- ){ //確保したのと逆順序で解放するため、バックサーチにする 187 188 if( bCompilingGlobal && GetNowLevel() == 0 ){ 189 if(lstrcmp(pVar[i3].name,"_System_GC")==0){ 190 indexSystemGC=i3; 191 continue; 192 } 193 } 194 195 //同一レベルのレキシカルスコープのみを検知 196 if(!pVar[i3].bLiving) continue; 197 if( pVar[i3].ScopeLevel != GetNowLevel() ) continue; 198 199 if(pVar[i3].type==DEF_OBJECT&&pVar[i3].fRef&OBJECT_PARAMETER){ 200 //実態オブジェクトのパラメータを持つとき 201 202 //デストラクタを呼び出す 203 i5=pVar[i3].u.pobj_c->DestructorMemberSubIndex; 204 if(i5!=-1) 205 Opcode_CallProc("",pVar[i3].u.pobj_c->ppobj_Method[i5]->psi,0,pVar[i3].name,DEF_OBJECT); 206 207 //メモリを解放する 208 209 #ifdef _AMD64_ 210 //x64ビットコード 211 212 //mov rcx,qword ptr[rsp+offset] 213 op_mov_RM(sizeof(_int64),REG_RCX,REG_RSP, 214 -pVar[i3].offset, 215 MOD_BASE_DISP32); 216 obp-=sizeof(long); 217 AddLocalVarAddrSchedule(); 218 obp+=sizeof(long); 219 #else 220 //x86コード 221 222 //mov ecx,dword ptr[ebp+offset] 223 op_mov_RM(sizeof(long),REG_ECX,REG_EBP,-pVar[i3].offset,MOD_BASE_DISP32); 224 obp-=sizeof(long); 225 AddLocalVarAddrSchedule(); 226 obp+=sizeof(long); 227 228 //push ecx 229 op_push(REG_ECX); 230 #endif 231 232 //call free 233 extern SUBINFO *pSub_free; 234 op_call(pSub_free); 235 236 237 if(bCompilingGlobal){ 238 //ここには来ないハズ 239 SetError(300,NULL,cp); 240 } 241 } 242 else if(pVar[i3].type==DEF_OBJECT&&pVar[i3].fRef==0){ 243 //デストラクタの呼び出し 244 i5=pVar[i3].u.pobj_c->DestructorMemberSubIndex; 245 if(i5!=-1){ 246 int ss[MAX_ARRAYDIM]; 247 memset(ss,0,MAX_ARRAYDIM*sizeof(int)); 248 if(pVar[i3].SubScripts[0]!=-1){ 249 while(1){ 250 for(i4=0;;i4++){ 251 if(pVar[i3].SubScripts[i4]==-1) break; 252 253 if(ss[i4]>pVar[i3].SubScripts[i4]){ 254 ss[i4]=0; 255 ss[i4+1]++; 256 } 257 else break; 258 } 259 if(pVar[i3].SubScripts[i4]==-1) break; 260 char temporary[VN_SIZE]; 261 sprintf(temporary,"%s[%d",pVar[i3].name,ss[0]); 262 for(i4=1;;i4++){ 263 if(pVar[i3].SubScripts[i4]==-1) break; 264 265 sprintf(temporary+lstrlen(temporary),",%d",ss[i4]); 266 } 267 lstrcat(temporary,"]"); 268 Opcode_CallProc("",pVar[i3].u.pobj_c->ppobj_Method[i5]->psi,0,temporary,DEF_OBJECT); 269 270 ss[0]++; 271 272 273 //ネイティブコードバッファの再確保 274 extern int obp_AllocSize; 275 if(obp_AllocSize<obp+8192){ 276 obp_AllocSize+=8192; 277 OpBuffer=(char *)HeapReAlloc(hHeap,0,OpBuffer,obp_AllocSize); //matea 278 } 279 } 280 } 281 else{ 282 Opcode_CallProc("",pVar[i3].u.pobj_c->ppobj_Method[i5]->psi,0,pVar[i3].name,DEF_OBJECT); 283 } 284 } 285 } 286 } 287 288 if(indexSystemGC!=-1){ 289 //_System_GCオブジェクトのデストラクタの呼び出し処理 290 i3=pVar[indexSystemGC].u.pobj_c->DestructorMemberSubIndex; 291 if(i3!=-1){ 292 Opcode_CallProc("",pVar[indexSystemGC].u.pobj_c->ppobj_Method[i3]->psi,0,pVar[indexSystemGC].name,DEF_OBJECT); 293 } 294 } 295 } 296 297 // Returnステートメントで発行されるデストラクタを生成 298 void CLexicalScopes::CallDestructorsOfReturn( int BaseLevel ){ 299 //現在のスコープレベルを退避 300 int backupScopeLevel = GetNowLevel(); 301 302 for( int i = GetNowLevel(); i >= BaseLevel; i-- ){ 303 SetNowLevel( i ); 304 305 CallDestructorsOfScopeEnd(); 306 } 307 308 //現在のスコープレベルを復元 309 SetNowLevel( backupScopeLevel ); 310 } -
BasicCompiler_Common/LexicalScoping.h
r4 r34 1 1 2 2 3 enum SCOPE_TYPE{ 4 //ベース 5 SCOPE_TYPE_BASE, 6 7 //分岐 8 SCOPE_TYPE_IF, 9 10 //ループ 11 SCOPE_TYPE_DO, 12 SCOPE_TYPE_FOR, 13 SCOPE_TYPE_WHILE, 14 15 //ケース分け 16 SCOPE_TYPE_SELECT, 17 }; 18 19 class CScope{ 20 int level; 21 int StartAddress; 22 SCOPE_TYPE TypeOfStatement; 23 24 DWORD *pBreakSchedule; 25 int nBreakSchedule; 26 27 public: 28 CScope( int level, int addr, SCOPE_TYPE TypeOfStatement ); 29 ~CScope(); 30 31 int GetStartAddress(); 32 SCOPE_TYPE GetTypeOfStatement(); 33 34 void Break(); 35 void RunScheduleOfBreak(); 36 }; 37 3 38 class CLexicalScopes{ 39 CScope **ppScopes; 4 40 int level; 5 int StartAddresses[1024]; 41 42 CScope *SearchScope( SCOPE_TYPE TypeOfStatement ); 43 6 44 public: 7 45 CLexicalScopes(); 8 46 ~CLexicalScopes(); 9 47 48 //初期化(関数コンパイルの開始時に呼び出される) 10 49 void Init(int addr); 11 50 12 void LevelUp(int addr); 13 void LevelDown(void); 51 // スコープを開始 52 void Start( int addr, SCOPE_TYPE TypeOfStatement ); 53 54 //スコープを終了 55 void End(); 56 57 //スコープ抜け出しステートメント 58 void Break(); 59 void ExitFor(); 60 void ExitWhile(); 61 void ExitDo(); 14 62 15 63 int GetNowLevel(void); 64 void SetNowLevel( int level ); 16 65 int GetStartAddress(void); 66 67 //スコープ終了時のデストラクタ呼び出し 68 void CallDestructorsOfScopeEnd(); 69 70 //Returnステートメント用のデストラクタ呼び出し 71 void CallDestructorsOfReturn( int BaseLevel = 0 ); 17 72 18 73 private: -
BasicCompiler_Common/Object.cpp
r31 r34 183 183 } 184 184 } 185 186 187 void CallDestrouctorsOfScope(void){188 extern BOOL bCompilingGlobal;189 VARIABLE *pVar;190 int num;191 if(bCompilingGlobal){192 //グローバルオブジェクトの解放処理193 extern VARIABLE *GlobalVar;194 extern int MaxGlobalVarNum;195 pVar=GlobalVar;196 num=MaxGlobalVarNum;197 }198 else{199 //ローカルオブジェクトの解放処理200 extern VARIABLE *LocalVar;201 extern int MaxLocalVarNum;202 pVar=LocalVar;203 num=MaxLocalVarNum;204 }205 206 207 int i3,i4,i5;208 int indexSystemGC=-1;209 for(i3=0;i3<num;i3++){210 211 if(bCompilingGlobal&&obj_LexScopes.GetNowLevel()==0){212 if(lstrcmp(pVar[i3].name,"_System_GC")==0){213 indexSystemGC=i3;214 continue;215 }216 }217 218 //同一レベルのレキシカルスコープのみを検知219 if(!pVar[i3].bLiving) continue;220 if(pVar[i3].ScopeLevel!=obj_LexScopes.GetNowLevel()) continue;221 222 if(pVar[i3].type==DEF_OBJECT&&pVar[i3].fRef&OBJECT_PARAMETER){223 //実態オブジェクトのパラメータを持つとき224 225 //デストラクタを呼び出す226 i5=pVar[i3].u.pobj_c->DestructorMemberSubIndex;227 if(i5!=-1)228 Opcode_CallProc("",pVar[i3].u.pobj_c->ppobj_Method[i5]->psi,0,pVar[i3].name,DEF_OBJECT);229 230 //メモリを解放する231 232 #ifdef _AMD64_233 //x64ビットコード234 235 //mov rcx,qword ptr[rsp+offset]236 op_mov_RM(sizeof(_int64),REG_RCX,REG_RSP,237 -pVar[i3].offset,238 MOD_BASE_DISP32);239 obp-=sizeof(long);240 AddLocalVarAddrSchedule();241 obp+=sizeof(long);242 #else243 //x86コード244 245 //mov ecx,dword ptr[ebp+offset]246 op_mov_RM(sizeof(long),REG_ECX,REG_EBP,-pVar[i3].offset,MOD_BASE_DISP32);247 obp-=sizeof(long);248 AddLocalVarAddrSchedule();249 obp+=sizeof(long);250 251 //push ecx252 op_push(REG_ECX);253 #endif254 255 //call free256 extern SUBINFO *pSub_free;257 op_call(pSub_free);258 259 260 if(bCompilingGlobal){261 //ここには来ないハズ262 SetError(300,NULL,cp);263 }264 }265 else if(pVar[i3].type==DEF_OBJECT&&pVar[i3].fRef==0){266 //デストラクタの呼び出し267 i5=pVar[i3].u.pobj_c->DestructorMemberSubIndex;268 if(i5!=-1){269 int ss[MAX_ARRAYDIM];270 memset(ss,0,MAX_ARRAYDIM*sizeof(int));271 if(pVar[i3].SubScripts[0]!=-1){272 while(1){273 for(i4=0;;i4++){274 if(pVar[i3].SubScripts[i4]==-1) break;275 276 if(ss[i4]>pVar[i3].SubScripts[i4]){277 ss[i4]=0;278 ss[i4+1]++;279 }280 else break;281 }282 if(pVar[i3].SubScripts[i4]==-1) break;283 char temporary[VN_SIZE];284 sprintf(temporary,"%s[%d",pVar[i3].name,ss[0]);285 for(i4=1;;i4++){286 if(pVar[i3].SubScripts[i4]==-1) break;287 288 sprintf(temporary+lstrlen(temporary),",%d",ss[i4]);289 }290 lstrcat(temporary,"]");291 Opcode_CallProc("",pVar[i3].u.pobj_c->ppobj_Method[i5]->psi,0,temporary,DEF_OBJECT);292 293 ss[0]++;294 295 296 //ネイティブコードバッファの再確保297 extern int obp_AllocSize;298 if(obp_AllocSize<obp+8192){299 obp_AllocSize+=8192;300 OpBuffer=(char *)HeapReAlloc(hHeap,0,OpBuffer,obp_AllocSize); //matea301 }302 }303 }304 else{305 Opcode_CallProc("",pVar[i3].u.pobj_c->ppobj_Method[i5]->psi,0,pVar[i3].name,DEF_OBJECT);306 }307 }308 }309 }310 311 if(indexSystemGC!=-1){312 //_System_GCオブジェクトのデストラクタの呼び出し処理313 i3=pVar[indexSystemGC].u.pobj_c->DestructorMemberSubIndex;314 if(i3!=-1){315 Opcode_CallProc("",pVar[indexSystemGC].u.pobj_c->ppobj_Method[i3]->psi,0,pVar[indexSystemGC].name,DEF_OBJECT);316 }317 }318 }319 -
BasicCompiler_Common/PESchedule.cpp
r5 r34 265 265 } 266 266 void CTempSchedule::unlock(){ 267 if( num <= 0 ){ 268 //エラー 269 SetError(300,NULL,cp); 270 } 267 271 num--; 268 272 } -
BasicCompiler_Common/Variable.cpp
r29 r34 648 648 649 649 for(i=MaxLocalVarNum-1;i>=0;i--){ //レキシカルスコープを考慮してバックサーチ 650 if(LocalVar[i].bLiving){ 651 if(lstrcmp(VarName,LocalVar[i].name)==0) break; 650 if( LocalVar[i].bLiving //現在のスコープで有効なもの 651 && LocalVar[i].ScopeLevel <= obj_LexScopes.GetNowLevel() //現在のスコープレベルを超さないもの(Returnによる解放処理中を考慮) 652 ){ 653 if(lstrcmp(VarName,LocalVar[i].name)==0) break; 652 654 } 653 655 } … … 766 768 767 769 for(i=MaxGlobalVarNum-1;i>=0;i--){ //レキシカルスコープを考慮してバックサーチ 768 if(GlobalVar[i].bLiving){ 769 if(lstrcmp(VarName,GlobalVar[i].name)==0) break; 770 if( GlobalVar[i].bLiving //現在のスコープで有効なもの 771 && GlobalVar[i].ScopeLevel <= obj_LexScopes.GetNowLevel() //現在のスコープレベルを超さないもの(Returnによる解放処理中を考慮) 772 ){ 773 if(lstrcmp(VarName,GlobalVar[i].name)==0) break; 770 774 } 771 775 } -
BasicCompiler_Common/common.h
r31 r34 385 385 386 386 387 #include "../BasicCompiler_Common/ schedule.h"387 #include "../BasicCompiler_Common/PESchedule.h" 388 388 #include "../BasicCompiler_Common/DebugSection.h" 389 389 #include "../BasicCompiler_Common/LexicalScoping.h" … … 423 423 void AddClassName(char *Parameter,int NowLine); 424 424 void CallConstractor(char *VarName,int *SubScripts,TYPEINFO &TypeInfo,char *Parameter); 425 void CallDestrouctorsOfScope(void);426 425 427 426 //Overload.sbp -
BasicCompiler_Common/error.cpp
r28 r34 143 143 if(num==60) lstrcpy(msg,"Staticステートメントはグローバル領域では使用できません。"); 144 144 if(num==61) sprintf(msg,"\"%s\" は定数です。書き込みアクセスはできません。",KeyWord); 145 if(num==62) sprintf(msg,"グローバル領域でのReturnは禁止されています。",KeyWord); 145 146 146 147
Note:
See TracChangeset
for help on using the changeset viewer.