| [4] | 1 | #include "common.h" | 
|---|
|  | 2 | #ifdef _AMD64_ | 
|---|
|  | 3 | #include "../BasicCompiler64/opcode.h" | 
|---|
|  | 4 | #else | 
|---|
| [5] | 5 | #include "../BasicCompiler32/opcode.h" | 
|---|
| [4] | 6 | #endif | 
|---|
|  | 7 |  | 
|---|
|  | 8 |  | 
|---|
|  | 9 | CLexicalScopes obj_LexScopes; | 
|---|
|  | 10 |  | 
|---|
| [34] | 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 |  | 
|---|
| [4] | 60 | CLexicalScopes::CLexicalScopes(){ | 
|---|
| [34] | 61 | ppScopes = (CScope **)malloc( 1 ); | 
|---|
| [4] | 62 | level=0; | 
|---|
|  | 63 | } | 
|---|
|  | 64 | CLexicalScopes::~CLexicalScopes(){ | 
|---|
| [34] | 65 | free( ppScopes ); | 
|---|
| [4] | 66 | } | 
|---|
|  | 67 | void CLexicalScopes::Init(int addr){ | 
|---|
| [34] | 68 | // TODO: エラーチェック | 
|---|
|  | 69 |  | 
|---|
|  | 70 | level = -1; | 
|---|
|  | 71 | Start( addr, SCOPE_TYPE_BASE ); | 
|---|
| [4] | 72 | } | 
|---|
| [34] | 73 | void CLexicalScopes::Start( int addr, SCOPE_TYPE TypeOfStatement ){ | 
|---|
| [4] | 74 | level++; | 
|---|
| [34] | 75 | ppScopes = (CScope **)realloc( ppScopes, ( level + 1 ) * sizeof( CScope * ) ); | 
|---|
|  | 76 | ppScopes[level] = new CScope( level, addr, TypeOfStatement ); | 
|---|
| [4] | 77 | } | 
|---|
| [34] | 78 | void CLexicalScopes::End(){ | 
|---|
|  | 79 | if( level <= 0 ){ | 
|---|
| [4] | 80 | SetError(300,NULL,cp); | 
|---|
|  | 81 | return; | 
|---|
|  | 82 | } | 
|---|
|  | 83 |  | 
|---|
| [34] | 84 | //デストラクタを呼ぶ | 
|---|
|  | 85 | CallDestructorsOfScopeEnd(); | 
|---|
|  | 86 |  | 
|---|
| [4] | 87 | extern BOOL bCompilingGlobal; | 
|---|
|  | 88 | VARIABLE *pVar; | 
|---|
|  | 89 | int num; | 
|---|
|  | 90 | if(bCompilingGlobal){ | 
|---|
|  | 91 | //グローバル領域をコンパイルしているとき | 
|---|
|  | 92 | extern VARIABLE *GlobalVar; | 
|---|
|  | 93 | extern int MaxGlobalVarNum; | 
|---|
|  | 94 | pVar=GlobalVar; | 
|---|
|  | 95 | num=MaxGlobalVarNum; | 
|---|
|  | 96 | } | 
|---|
|  | 97 | else{ | 
|---|
|  | 98 | //ローカル領域をコンパイルしているとき | 
|---|
|  | 99 | extern VARIABLE *LocalVar; | 
|---|
|  | 100 | extern int MaxLocalVarNum; | 
|---|
|  | 101 | pVar=LocalVar; | 
|---|
|  | 102 | num=MaxLocalVarNum; | 
|---|
|  | 103 | } | 
|---|
|  | 104 |  | 
|---|
| [34] | 105 | //使用済みローカル変数の生存チェックを外す | 
|---|
| [4] | 106 | for(int i=0;i<num;i++){ | 
|---|
| [34] | 107 | if(pVar[i].bLiving&&pVar[i].ScopeLevel==level){ | 
|---|
| [4] | 108 | pVar[i].bLiving=0; | 
|---|
|  | 109 | extern int obp; | 
|---|
|  | 110 | pVar[i].ScopeEndAddress=obp; | 
|---|
|  | 111 | } | 
|---|
|  | 112 | } | 
|---|
| [34] | 113 |  | 
|---|
|  | 114 |  | 
|---|
|  | 115 | //スコープ抜け出しスケジュール | 
|---|
|  | 116 | ppScopes[level]->RunScheduleOfBreak(); | 
|---|
|  | 117 |  | 
|---|
|  | 118 |  | 
|---|
|  | 119 | //スコープレベルを下げる | 
|---|
|  | 120 | delete ppScopes[level]; | 
|---|
|  | 121 | level--; | 
|---|
| [4] | 122 | } | 
|---|
|  | 123 |  | 
|---|
| [34] | 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(){ | 
|---|
| [4] | 153 | return level; | 
|---|
|  | 154 | } | 
|---|
| [34] | 155 | void CLexicalScopes::SetNowLevel( int level ){ | 
|---|
|  | 156 | this->level = level; | 
|---|
| [4] | 157 | } | 
|---|
| [34] | 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 | } | 
|---|