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

Last change on this file since 198 was 184, checked in by dai_9181, 17 years ago
File size: 3.0 KB
Line 
1#include <LexicalScopingImpl.h>
2
3#include "../common.h"
4
5#ifdef _AMD64_
6#include "../../BasicCompiler64/opcode.h"
7#else
8#include "../../BasicCompiler32/opcode.h"
9#endif
10
11
12void ScopeImpl::Break(){
13 //未解放のローカルオブジェクトを解放する
14 GetLexicalScopes().CallDestructorsOfReturn( level );
15
16 //jmp ...(Next addr)
17 OpBuffer[obp++]=(char)0xE9;
18
19 pBreakSchedule=(DWORD *)realloc( pBreakSchedule, ( nBreakSchedule + 1 ) * sizeof(DWORD) );
20 pBreakSchedule[nBreakSchedule]=obp;
21 nBreakSchedule++;
22
23 obp+=sizeof(long);
24}
25void ScopeImpl::RunScheduleOfBreak(){
26 for(int i=0;i<nBreakSchedule;i++){
27 *((long *)(OpBuffer+pBreakSchedule[i]))=obp-(pBreakSchedule[i]+sizeof(long));
28 }
29}
30
31// スコープ終了時のデストラクタ呼び出し
32void LexicalScopesImpl::CallDestructorsOfScopeEnd(){
33
34 Variables &vars = UserProc::IsGlobalAreaCompiling()?
35 globalVars :
36 UserProc::CompilingUserProc().localVars;
37
38
39 int i3;
40 int indexSystemGC=-1;
41 for( i3 = (int)vars.size() - 1; i3 >= 0; i3-- ){ //確保したのと逆順序で解放するため、バックサーチにする
42
43 Variable *pVar = vars[i3];
44
45 if( UserProc::IsGlobalAreaCompiling() && GetNowLevel() == 0 ){
46 if( pVar->GetName() == "_System_GC" ){
47 indexSystemGC=i3;
48 continue;
49 }
50 }
51
52 //同一レベルのレキシカルスコープのみを検知
53 if(!pVar->bLiving) continue;
54 if( pVar->ScopeLevel != GetNowLevel() ) continue;
55
56 if( pVar->IsStruct() && pVar->IsParameter() ){
57 //構造体パラメータを持つとき
58
59 //メモリを解放する
60
61#ifdef _AMD64_
62 //x64ビットコード
63
64 //mov rcx,qword ptr[rsp+offset]
65 op_mov_RM(sizeof(_int64),REG_RCX,REG_RSP,
66 -pVar->offset,
67 MOD_BASE_DISP32);
68 obp-=sizeof(long);
69 AddLocalVarAddrSchedule();
70 obp+=sizeof(long);
71#else
72 //x86コード
73
74 //mov ecx,dword ptr[ebp+offset]
75 op_mov_RM(sizeof(long),REG_ECX,REG_EBP,-pVar->offset,MOD_BASE_DISP32);
76 obp-=sizeof(long);
77 AddLocalVarAddrSchedule();
78 obp+=sizeof(long);
79
80 //push ecx
81 op_push(REG_ECX);
82#endif
83
84 //call free
85 extern UserProc *pSub_free;
86 op_call(pSub_free);
87
88
89 if( UserProc::IsGlobalAreaCompiling() ){
90 //ここには来ないハズ
91 SetError(300,NULL,cp);
92 }
93 }
94 }
95
96 if(indexSystemGC!=-1){
97 //_System_GCオブジェクトのデストラクタの呼び出し処理
98 const CMethod *method = vars[indexSystemGC]->GetClass().GetDestructorMethod();
99 if( method ){
100 Opcode_CallProc("",method->pUserProc,0,vars[indexSystemGC]->GetName().c_str(),DEF_OBJECT);
101 }
102 }
103}
104
105// Returnステートメントで発行されるデストラクタを生成
106void LexicalScopesImpl::CallDestructorsOfReturn( int BaseLevel ){
107 //現在のスコープレベルを退避
108 int backupScopeLevel = GetNowLevel();
109
110 for( int i = GetNowLevel(); i >= BaseLevel; i-- ){
111 SetNowLevel( i );
112
113 CallDestructorsOfScopeEnd();
114 }
115
116 //現在のスコープレベルを復元
117 SetNowLevel( backupScopeLevel );
118}
119
120LexicalScopesImpl &GetLexicalScopes()
121{
122 static LexicalScopesImpl *pTemp = NULL;
123 if( !pTemp )
124 {
125 pTemp = (LexicalScopesImpl *)Smoothie::Temp::pLexicalScopes;
126 }
127 return *pTemp;
128}
Note: See TracBrowser for help on using the repository browser.