Changeset 34 in dev for BasicCompiler_Common/LexicalScoping.cpp
- Timestamp:
- Jan 14, 2007, 6:11:23 AM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
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 }
Note:
See TracChangeset
for help on using the changeset viewer.