source: dev/trunk/abdev/BasicCompiler_Common/src/LexicalScope.cpp@ 420

Last change on this file since 420 was 392, checked in by dai_9181, 17 years ago

BOOL bLiving → bool isLiving

File size: 4.6 KB
RevLine 
[206]1#include "stdafx.h"
2
[248]3#include <LexicalScope.h>
[206]4#include <Compiler.h>
[184]5
6#include "../common.h"
7
8#ifdef _AMD64_
9#include "../../BasicCompiler64/opcode.h"
10#else
11#include "../../BasicCompiler32/opcode.h"
12#endif
13
14
[248]15void LexicalScope::Break(){
[184]16 //未解放のローカルオブジェクトを解放する
[248]17 compiler.codeGenerator.lexicalScopes.CallDestructorsOfReturn( level );
[184]18
19 //jmp ...(Next addr)
[248]20 breakPertialSchedules.push_back(
21 compiler.codeGenerator.op_jmp( 0, sizeof(long), true )
22 );
23}
24void LexicalScope::RunScheduleOfBreak(){
25 BOOST_FOREACH( const PertialSchedule *pBreakPertialSchedule, breakPertialSchedules )
26 {
27 compiler.codeGenerator.opfix_JmpPertialSchedule( pBreakPertialSchedule );
28 }
29}
[184]30
31
[248]32
33LexicalScope *LexicalScopes::SearchScope( LexicalScope::SCOPE_TYPE TypeOfStatement ){
34 for( int i = level; i>=0; i-- ){
35 if( ppScopes[i]->GetTypeOfStatement() == TypeOfStatement ){
36 return ppScopes[i];
37 }
[184]38 }
[248]39 return NULL;
[184]40}
41
[248]42void LexicalScopes::Init(int addr){
43 // TODO: エラーチェック
44
45 level = -1;
46 Start( addr, LexicalScope::SCOPE_TYPE_BASE );
47}
48void LexicalScopes::Start( int addr, LexicalScope::SCOPE_TYPE TypeOfStatement ){
49 level++;
50 ppScopes = (LexicalScope **)realloc( ppScopes, ( level + 1 ) * sizeof( LexicalScope * ) );
51 ppScopes[level] = new LexicalScope( level, addr, TypeOfStatement );
52}
53
54int LexicalScopes::GetNowLevel(){
55 return level;
56}
57void LexicalScopes::SetNowLevel( int level ){
58 this->level = level;
59}
60int LexicalScopes::GetStartAddress(){
61 return ppScopes[level]->GetStartAddress();
62}
63
64void LexicalScopes::End(){
[206]65 if( level <= 0 ){
66 SetError();
67 return;
68 }
69
70 //デストラクタを呼ぶ
71 CallDestructorsOfScopeEnd();
72
[288]73 Variables *pVars = UserProc::IsGlobalAreaCompiling() ?
74 &compiler.GetObjectModule().meta.GetGlobalVars() :
75 &UserProc::CompilingUserProc().GetLocalVars();
[206]76
77 //使用済みローカル変数の生存チェックを外す
[392]78 BOOST_FOREACH( Variable *pVar, (*pVars) )
79 {
80 if( pVar->isLiving && pVar->GetScopeLevel() == level )
81 {
82 pVar->isLiving = false;
[276]83 pVar->SetScopeEndAddress( compiler.codeGenerator.GetNativeCodeSize() );
[206]84 }
85 }
86
87
88 //スコープ抜け出しスケジュール
89 ppScopes[level]->RunScheduleOfBreak();
90
91
92 //スコープレベルを下げる
93 delete ppScopes[level];
94 level--;
95}
96
[184]97// スコープ終了時のデストラクタ呼び出し
[248]98void LexicalScopes::CallDestructorsOfScopeEnd(){
[184]99
[288]100 Variables *pVariabls = UserProc::IsGlobalAreaCompiling() ?
101 &compiler.GetObjectModule().meta.GetGlobalVars() :
102 &UserProc::CompilingUserProc().GetLocalVars();
[184]103
104
105 int i3;
106 int indexSystemGC=-1;
[288]107 for( i3 = (int)pVariabls->size() - 1; i3 >= 0; i3-- ){ //確保したのと逆順序で解放するため、バックサーチにする
[184]108
[288]109 Variable *pVar = (*pVariabls)[i3];
[184]110
111 if( UserProc::IsGlobalAreaCompiling() && GetNowLevel() == 0 ){
112 if( pVar->GetName() == "_System_GC" ){
113 indexSystemGC=i3;
114 continue;
115 }
116 }
117
118 //同一レベルのレキシカルスコープのみを検知
[392]119 if( !pVar->isLiving ) continue;
[206]120 if( pVar->GetScopeLevel() != GetNowLevel() ) continue;
[184]121
[206]122 if( pVar->GetType().IsStruct() && pVar->IsParameter() ){
[184]123 //構造体パラメータを持つとき
124
125 //メモリを解放する
126
127#ifdef _AMD64_
128 //x64ビットコード
129
130 //mov rcx,qword ptr[rsp+offset]
[254]131 compiler.codeGenerator.localVarPertialSchedules.push_back(
[226]132 compiler.codeGenerator.op_mov_RM(sizeof(_int64),REG_RCX,REG_RSP,
[206]133 -pVar->GetOffsetAddress(),
[234]134 MOD_BASE_DISP32,
[254]135 Schedule::None, true)
136 );
[184]137#else
138 //x86コード
139
140 //mov ecx,dword ptr[ebp+offset]
[253]141 compiler.codeGenerator.localVarPertialSchedules.push_back(
142 compiler.codeGenerator.op_mov_RM(sizeof(long),REG_ECX,REG_EBP,-pVar->GetOffsetAddress(),MOD_BASE_DISP32, Schedule::None, true )
143 );
[184]144
145 //push ecx
[225]146 compiler.codeGenerator.op_push(REG_ECX);
[184]147#endif
148
149 //call free
[206]150 extern const UserProc *pSub_free;
[225]151 compiler.codeGenerator.op_call(pSub_free);
[184]152
153
154 if( UserProc::IsGlobalAreaCompiling() ){
155 //ここには来ないハズ
156 SetError(300,NULL,cp);
157 }
158 }
159 }
160
161 if(indexSystemGC!=-1){
162 //_System_GCオブジェクトのデストラクタの呼び出し処理
[288]163 const CMethod *method = (*pVariabls)[indexSystemGC]->GetType().GetClass().GetDestructorMethod();
[184]164 if( method ){
[290]165 Opcode_CallProc("",&method->GetUserProc(),0,(*pVariabls)[indexSystemGC]->GetName().c_str());
[184]166 }
167 }
168}
169
170// Returnステートメントで発行されるデストラクタを生成
[248]171void LexicalScopes::CallDestructorsOfReturn( int BaseLevel ){
[184]172 //現在のスコープレベルを退避
173 int backupScopeLevel = GetNowLevel();
174
175 for( int i = GetNowLevel(); i >= BaseLevel; i-- ){
176 SetNowLevel( i );
177
178 CallDestructorsOfScopeEnd();
179 }
180
181 //現在のスコープレベルを復元
182 SetNowLevel( backupScopeLevel );
183}
Note: See TracBrowser for help on using the repository browser.