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

Last change on this file since 252 was 248, checked in by dai_9181, 17 years ago

BreakPertialScheduleをリファクタリング

File size: 4.3 KB
Line 
1#include "stdafx.h"
2
3#include <LexicalScope.h>
4#include <Compiler.h>
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
15void LexicalScope::Break(){
16 //未解放のローカルオブジェクトを解放する
17 compiler.codeGenerator.lexicalScopes.CallDestructorsOfReturn( level );
18
19 //jmp ...(Next addr)
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}
30
31
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 }
38 }
39 return NULL;
40}
41
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(){
65 if( level <= 0 ){
66 SetError();
67 return;
68 }
69
70 //デストラクタを呼ぶ
71 CallDestructorsOfScopeEnd();
72
73 Variables &vars = UserProc::IsGlobalAreaCompiling() ?
74 compiler.GetMeta().GetGlobalVars() :
75 UserProc::CompilingUserProc().GetLocalVars();
76
77 //使用済みローカル変数の生存チェックを外す
78 BOOST_FOREACH( Variable *pVar, vars ){
79 if(pVar->bLiving&&pVar->GetScopeLevel()==level){
80 pVar->bLiving=0;
81 extern int obp;
82 pVar->SetScopeEndAddress( obp );
83 }
84 }
85
86
87 //スコープ抜け出しスケジュール
88 ppScopes[level]->RunScheduleOfBreak();
89
90
91 //スコープレベルを下げる
92 delete ppScopes[level];
93 level--;
94}
95
96// スコープ終了時のデストラクタ呼び出し
97void LexicalScopes::CallDestructorsOfScopeEnd(){
98
99 Variables &vars = UserProc::IsGlobalAreaCompiling() ?
100 compiler.GetMeta().GetGlobalVars() :
101 UserProc::CompilingUserProc().GetLocalVars();
102
103
104 int i3;
105 int indexSystemGC=-1;
106 for( i3 = (int)vars.size() - 1; i3 >= 0; i3-- ){ //確保したのと逆順序で解放するため、バックサーチにする
107
108 Variable *pVar = vars[i3];
109
110 if( UserProc::IsGlobalAreaCompiling() && GetNowLevel() == 0 ){
111 if( pVar->GetName() == "_System_GC" ){
112 indexSystemGC=i3;
113 continue;
114 }
115 }
116
117 //同一レベルのレキシカルスコープのみを検知
118 if(!pVar->bLiving) continue;
119 if( pVar->GetScopeLevel() != GetNowLevel() ) continue;
120
121 if( pVar->GetType().IsStruct() && pVar->IsParameter() ){
122 //構造体パラメータを持つとき
123
124 //メモリを解放する
125
126#ifdef _AMD64_
127 //x64ビットコード
128
129 //mov rcx,qword ptr[rsp+offset]
130 compiler.codeGenerator.op_mov_RM(sizeof(_int64),REG_RCX,REG_RSP,
131 -pVar->GetOffsetAddress(),
132 MOD_BASE_DISP32,
133 Schedule::LocalVar);
134#else
135 //x86コード
136
137 //mov ecx,dword ptr[ebp+offset]
138 compiler.codeGenerator.op_mov_RM(sizeof(long),REG_ECX,REG_EBP,-pVar->GetOffsetAddress(),MOD_BASE_DISP32, Schedule::LocalVar );
139
140 //push ecx
141 compiler.codeGenerator.op_push(REG_ECX);
142#endif
143
144 //call free
145 extern const UserProc *pSub_free;
146 compiler.codeGenerator.op_call(pSub_free);
147
148
149 if( UserProc::IsGlobalAreaCompiling() ){
150 //ここには来ないハズ
151 SetError(300,NULL,cp);
152 }
153 }
154 }
155
156 if(indexSystemGC!=-1){
157 //_System_GCオブジェクトのデストラクタの呼び出し処理
158 const CMethod *method = vars[indexSystemGC]->GetType().GetClass().GetDestructorMethod();
159 if( method ){
160 Opcode_CallProc("",&method->GetUserProc(),0,vars[indexSystemGC]->GetName().c_str(),DEF_OBJECT);
161 }
162 }
163}
164
165// Returnステートメントで発行されるデストラクタを生成
166void LexicalScopes::CallDestructorsOfReturn( int BaseLevel ){
167 //現在のスコープレベルを退避
168 int backupScopeLevel = GetNowLevel();
169
170 for( int i = GetNowLevel(); i >= BaseLevel; i-- ){
171 SetNowLevel( i );
172
173 CallDestructorsOfScopeEnd();
174 }
175
176 //現在のスコープレベルを復元
177 SetNowLevel( backupScopeLevel );
178}
Note: See TracBrowser for help on using the repository browser.