#include "stdafx.h" #include #include #include "../common.h" #ifdef _AMD64_ #include "../../BasicCompiler64/opcode.h" #else #include "../../BasicCompiler32/opcode.h" #endif void ScopeImpl::Break(){ //未解放のローカルオブジェクトを解放する GetLexicalScopes().CallDestructorsOfReturn( level ); //jmp ...(Next addr) OpBuffer[obp++]=(char)0xE9; pBreakSchedule=(DWORD *)realloc( pBreakSchedule, ( nBreakSchedule + 1 ) * sizeof(DWORD) ); pBreakSchedule[nBreakSchedule]=obp; nBreakSchedule++; obp+=sizeof(long); } void ScopeImpl::RunScheduleOfBreak(){ for(int i=0;ibLiving&&pVar->GetScopeLevel()==level){ pVar->bLiving=0; extern int obp; pVar->SetScopeEndAddress( obp ); } } //スコープ抜け出しスケジュール ppScopes[level]->RunScheduleOfBreak(); //スコープレベルを下げる delete ppScopes[level]; level--; } // スコープ終了時のデストラクタ呼び出し void LexicalScopesImpl::CallDestructorsOfScopeEnd(){ Variables &vars = UserProc::IsGlobalAreaCompiling() ? compiler.GetMeta().GetGlobalVars() : UserProc::CompilingUserProc().GetLocalVars(); int i3; int indexSystemGC=-1; for( i3 = (int)vars.size() - 1; i3 >= 0; i3-- ){ //確保したのと逆順序で解放するため、バックサーチにする Variable *pVar = vars[i3]; if( UserProc::IsGlobalAreaCompiling() && GetNowLevel() == 0 ){ if( pVar->GetName() == "_System_GC" ){ indexSystemGC=i3; continue; } } //同一レベルのレキシカルスコープのみを検知 if(!pVar->bLiving) continue; if( pVar->GetScopeLevel() != GetNowLevel() ) continue; if( pVar->GetType().IsStruct() && pVar->IsParameter() ){ //構造体パラメータを持つとき //メモリを解放する #ifdef _AMD64_ //x64ビットコード //mov rcx,qword ptr[rsp+offset] op_mov_RM(sizeof(_int64),REG_RCX,REG_RSP, -pVar->GetOffsetAddress(), MOD_BASE_DISP32); obp-=sizeof(long); AddLocalVarAddrSchedule(); obp+=sizeof(long); #else //x86コード //mov ecx,dword ptr[ebp+offset] compiler.codeGenerator.op_mov_RM(sizeof(long),REG_ECX,REG_EBP,-pVar->GetOffsetAddress(),MOD_BASE_DISP32); obp-=sizeof(long); AddLocalVarAddrSchedule(); obp+=sizeof(long); //push ecx compiler.codeGenerator.op_push(REG_ECX); #endif //call free extern const UserProc *pSub_free; compiler.codeGenerator.op_call(pSub_free); if( UserProc::IsGlobalAreaCompiling() ){ //ここには来ないハズ SetError(300,NULL,cp); } } } if(indexSystemGC!=-1){ //_System_GCオブジェクトのデストラクタの呼び出し処理 const CMethod *method = vars[indexSystemGC]->GetType().GetClass().GetDestructorMethod(); if( method ){ Opcode_CallProc("",&method->GetUserProc(),0,vars[indexSystemGC]->GetName().c_str(),DEF_OBJECT); } } } // Returnステートメントで発行されるデストラクタを生成 void LexicalScopesImpl::CallDestructorsOfReturn( int BaseLevel ){ //現在のスコープレベルを退避 int backupScopeLevel = GetNowLevel(); for( int i = GetNowLevel(); i >= BaseLevel; i-- ){ SetNowLevel( i ); CallDestructorsOfScopeEnd(); } //現在のスコープレベルを復元 SetNowLevel( backupScopeLevel ); } LexicalScopesImpl &GetLexicalScopes() { static LexicalScopesImpl *pTemp = NULL; if( !pTemp ) { pTemp = (LexicalScopesImpl *)Smoothie::Temp::pLexicalScopes; } return *pTemp; }