source: dev/trunk/abdev/BasicCompiler_Common/src/LexicalScopingImpl.cpp@ 210

Last change on this file since 210 was 206, checked in by dai_9181, 17 years ago

コード全体のリファクタリングを実施

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