source: dev/BasicCompiler_Common/Object.cpp@ 4

Last change on this file since 4 was 4, checked in by dai_9181, 17 years ago
File size: 7.5 KB
Line 
1#include "../BasicCompiler_Common/common.h"
2
3#ifdef _AMD64_
4#include "../BasicCompiler64/opcode.h"
5#else
6#include "../BasicCompiler/opcode.h"
7#endif
8
9extern HANDLE hHeap;
10
11int GetAlignment(CClass *pobj_c){
12 int i;
13 int alignment,member_size;
14
15 if(pobj_c->vtbl_num) alignment=PTR_SIZE;
16 else alignment=0;
17
18 for(i=0;i<pobj_c->iMemberNum;i++){
19 if(pobj_c->ppobj_Member[i]->TypeInfo.type==DEF_OBJECT){
20 //メンバクラスのアラインメントを取得
21 member_size=GetAlignment(pobj_c->ppobj_Member[i]->TypeInfo.u.pobj_Class);
22 }
23 else{
24 //メンバサイズを取得
25 member_size=GetTypeSize(pobj_c->ppobj_Member[i]->TypeInfo.type,pobj_c->ppobj_Member[i]->TypeInfo.u.lpIndex);
26 }
27
28 //アラインメントをセット
29 if(alignment<member_size) alignment=member_size;
30 }
31
32 if(alignment==0) return 0;
33
34 if(pobj_c->iAlign) alignment=pobj_c->iAlign;
35
36 return alignment;
37}
38int GetSizeOfClassMember(CClass *pobj_c,char *pMemberName,int *pMemberNum){
39 int i,i2,offset;
40
41 //仮想関数が存在する場合は関数リストへのポインタのサイズを追加
42 if(pobj_c->vtbl_num) offset=PTR_SIZE;
43 else offset=0;
44
45 int alignment;
46 if(pobj_c->iAlign) alignment=pobj_c->iAlign;
47 else alignment=1;
48
49 int iMaxAlign=0;
50 for(i=0;i<pobj_c->iMemberNum;i++){
51 //メンバ変数の型サイズを取得
52 i2=GetTypeSize(pobj_c->ppobj_Member[i]->TypeInfo.type,pobj_c->ppobj_Member[i]->TypeInfo.u.lpIndex);
53 if(i2==-1) return -1;
54
55 //アラインメントを算出
56 int member_size;
57 if(pobj_c->ppobj_Member[i]->TypeInfo.type==DEF_OBJECT){
58 //メンバクラスのアラインメントを取得
59 member_size=GetAlignment(pobj_c->ppobj_Member[i]->TypeInfo.u.pobj_Class);
60 }
61 else{
62 //メンバサイズを取得
63 member_size=i2;
64 }
65 if(iMaxAlign<member_size) iMaxAlign=member_size;
66
67 //アラインメントを考慮
68 if(pobj_c->iAlign&&pobj_c->iAlign<member_size){
69 if(offset%alignment) offset+=alignment-(offset%alignment);
70 }
71 else{
72 if(alignment<member_size) alignment=member_size;
73
74 if(member_size==0){
75 //メンバを持たないクラス
76 //※何もしない(オフセットの計算をしない)
77 }
78 else{
79 if(offset%member_size) offset+=member_size-(offset%member_size);
80 }
81 }
82
83 if(pMemberName){
84 //メンバ指定がある場合は、オフセットを返す
85 if(lstrcmp(pobj_c->ppobj_Member[i]->name,pMemberName)==0){
86 if(pMemberNum) *pMemberNum=i;
87 return offset;
88 }
89 }
90
91 //配列を考慮したメンバサイズを取得
92 member_size=i2 * JumpSubScripts(pobj_c->ppobj_Member[i]->SubScripts);
93
94 //メンバサイズを加算
95 offset+= member_size;
96 }
97
98 if(iMaxAlign<alignment) alignment=iMaxAlign;
99
100 //アラインメントを考慮
101 if(alignment){
102 if(offset%alignment) offset+=alignment-(offset%alignment);
103 }
104
105 if(pMemberNum) *pMemberNum=i;
106 return offset;
107}
108int GetSizeOfClass(CClass *pobj_c){
109 return GetSizeOfClassMember(pobj_c,0,0);
110}
111
112
113void CallConstractor(char *VarName,int *SubScripts,TYPEINFO &TypeInfo,char *Parameter){
114 if(TypeInfo.type!=DEF_OBJECT) return;
115
116 /////////////////////////////////////
117 // クラスオブジェクトの場合
118 // ※コンストラクタの呼び出し
119 /////////////////////////////////////
120 CClass *pobj_c;
121 pobj_c=(CClass *)TypeInfo.u.lpIndex;
122
123 char temporary[VN_SIZE];
124 sprintf(temporary,"%s.%s",VarName,pobj_c->name);
125
126 SUBINFO *psi;
127 psi=GetSubHash(temporary);
128 if(!psi){
129 if(Parameter[0]) SetError(113,pobj_c->name,cp);
130 return;
131 }
132 if(SubScripts[0]!=-1){
133 int ss[MAX_ARRAYDIM];
134 memset(ss,0,MAX_ARRAYDIM*sizeof(int));
135 while(1){
136 int i3;
137 for(i3=0;;i3++){
138 if(SubScripts[i3]==-1) break;
139
140 if(ss[i3]>SubScripts[i3]){
141 ss[i3]=0;
142 ss[i3+1]++;
143 }
144 else break;
145 }
146 if(SubScripts[i3]==-1) break;
147 sprintf(temporary,"%s[%d",VarName,ss[0]);
148 for(i3=1;;i3++){
149 if(SubScripts[i3]==-1) break;
150
151 sprintf(temporary+lstrlen(temporary),",%d",ss[i3]);
152 }
153 lstrcat(temporary,"]");
154
155 LONG_PTR lp;
156 sprintf(temporary+lstrlen(temporary),".%s",pobj_c->name);
157 CallProc(PROC_DEFAULT,
158 psi,
159 temporary,
160 Parameter,
161 &lp);
162
163 ss[0]++;
164
165
166 //ネイティブコードバッファの再確保
167 extern int obp_AllocSize;
168 if(obp_AllocSize<obp+8192){
169 obp_AllocSize+=8192;
170 OpBuffer=(char *)HeapReAlloc(hHeap,0,OpBuffer,obp_AllocSize); //matea
171 }
172 }
173 }
174 else{
175 LONG_PTR lp;
176 sprintf(temporary,"%s.%s",VarName,pobj_c->name);
177 CallProc(PROC_DEFAULT,
178 psi,
179 temporary,
180 Parameter,
181 &lp);
182 }
183}
184
185
186void CallDestrouctorsOfScope(void){
187 extern BOOL bCompilingGlobal;
188 VARIABLE *pVar;
189 int num;
190 if(bCompilingGlobal){
191 //グローバルオブジェクトの解放処理
192 extern VARIABLE *GlobalVar;
193 extern int MaxGlobalVarNum;
194 pVar=GlobalVar;
195 num=MaxGlobalVarNum;
196 }
197 else{
198 //ローカルオブジェクトの解放処理
199 extern VARIABLE *LocalVar;
200 extern int MaxLocalVarNum;
201 pVar=LocalVar;
202 num=MaxLocalVarNum;
203 }
204
205
206 int i3,i4,i5;
207 int indexSystemGC=-1;
208 for(i3=0;i3<num;i3++){
209
210 if(bCompilingGlobal&&obj_LexScopes.GetNowLevel()==0){
211 if(lstrcmp(pVar[i3].name,"_System_GC")==0){
212 indexSystemGC=i3;
213 continue;
214 }
215 }
216
217 //同一レベルのレキシカルスコープのみを検知
218 if(!pVar[i3].bLiving) continue;
219 if(pVar[i3].ScopeLevel!=obj_LexScopes.GetNowLevel()) continue;
220
221 if(pVar[i3].type==DEF_OBJECT&&pVar[i3].fRef&OBJECT_PARAMETER){
222 //実態オブジェクトのパラメータを持つとき
223
224 //デストラクタを呼び出す
225 i5=pVar[i3].u.pobj_c->DestructorMemberSubIndex;
226 if(i5!=-1)
227 Opcode_CallProc("",pVar[i3].u.pobj_c->ppobj_Method[i5]->psi,0,0,pVar[i3].name,DEF_OBJECT);
228
229 //メモリを解放する
230
231#ifdef _AMD64_
232 //x64ビットコード
233
234 //mov rcx,qword ptr[rsp+offset]
235 op_mov_RM(sizeof(_int64),REG_RCX,REG_RSP,
236 -pVar[i3].offset,
237 MOD_BASE_DISP32);
238 obp-=sizeof(long);
239 AddLocalVarAddrSchedule();
240 obp+=sizeof(long);
241#else
242 //x86コード
243
244 //mov ecx,dword ptr[ebp+offset]
245 op_mov_RM(sizeof(long),REG_ECX,REG_EBP,-pVar[i3].offset,MOD_BASE_DISP32);
246 obp-=sizeof(long);
247 AddLocalVarAddrSchedule();
248 obp+=sizeof(long);
249
250 //push ecx
251 op_push(REG_ECX);
252#endif
253
254 //call free
255 extern SUBINFO *pSub_free;
256 op_call(pSub_free);
257 }
258 if(pVar[i3].type==DEF_OBJECT&&pVar[i3].fRef==0){
259 //デストラクタの呼び出し
260 i5=pVar[i3].u.pobj_c->DestructorMemberSubIndex;
261 if(i5!=-1){
262 int ss[MAX_ARRAYDIM];
263 memset(ss,0,MAX_ARRAYDIM*sizeof(int));
264 if(pVar[i3].SubScripts[0]!=-1){
265 while(1){
266 for(i4=0;;i4++){
267 if(pVar[i3].SubScripts[i4]==-1) break;
268
269 if(ss[i4]>pVar[i3].SubScripts[i4]){
270 ss[i4]=0;
271 ss[i4+1]++;
272 }
273 else break;
274 }
275 if(pVar[i3].SubScripts[i4]==-1) break;
276 char temporary[VN_SIZE];
277 sprintf(temporary,"%s[%d",pVar[i3].name,ss[0]);
278 for(i4=1;;i4++){
279 if(pVar[i3].SubScripts[i4]==-1) break;
280
281 sprintf(temporary+lstrlen(temporary),",%d",ss[i4]);
282 }
283 lstrcat(temporary,"]");
284 Opcode_CallProc("",pVar[i3].u.pobj_c->ppobj_Method[i5]->psi,0,0,temporary,DEF_OBJECT);
285
286 ss[0]++;
287
288
289 //ネイティブコードバッファの再確保
290 extern int obp_AllocSize;
291 if(obp_AllocSize<obp+8192){
292 obp_AllocSize+=8192;
293 OpBuffer=(char *)HeapReAlloc(hHeap,0,OpBuffer,obp_AllocSize); //matea
294 }
295 }
296 }
297 else{
298 Opcode_CallProc("",pVar[i3].u.pobj_c->ppobj_Method[i5]->psi,0,0,pVar[i3].name,DEF_OBJECT);
299 }
300 }
301 }
302 }
303
304 if(indexSystemGC!=-1){
305 //_System_GCオブジェクトのデストラクタの呼び出し処理
306 i3=pVar[indexSystemGC].u.pobj_c->DestructorMemberSubIndex;
307 if(i3!=-1){
308 Opcode_CallProc("",pVar[indexSystemGC].u.pobj_c->ppobj_Method[i3]->psi,0,0,pVar[indexSystemGC].name,DEF_OBJECT);
309 }
310 }
311}
312
Note: See TracBrowser for help on using the repository browser.