source: dev/BasicCompiler_Common/Object.cpp@ 20

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

参照型パラメータに関数の戻り値オブジェクトを指定した場合などの、一時オブジェクトの扱いを可能にした。
Dimで指定される初期値を見分けることで、As指定を省略できるようにした。

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 "../BasicCompiler32/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 *ObjectName,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 SUBINFO *psi;
124 psi=GetMethodHash(ObjectName,pobj_c->name,Parameter);
125 if(!psi){
126 if(Parameter[0]) SetError(113,pobj_c->name,cp);
127 return;
128 }
129
130
131 char temporary[VN_SIZE];
132
133 if(SubScripts[0]!=-1){
134 int ss[MAX_ARRAYDIM];
135 memset(ss,0,MAX_ARRAYDIM*sizeof(int));
136 while(1){
137 int i3;
138 for(i3=0;;i3++){
139 if(SubScripts[i3]==-1) break;
140
141 if(ss[i3]>SubScripts[i3]){
142 ss[i3]=0;
143 ss[i3+1]++;
144 }
145 else break;
146 }
147 if(SubScripts[i3]==-1) break;
148 sprintf(temporary,"%s[%d",ObjectName,ss[0]);
149 for(i3=1;;i3++){
150 if(SubScripts[i3]==-1) break;
151
152 sprintf(temporary+lstrlen(temporary),",%d",ss[i3]);
153 }
154 lstrcat(temporary,"]");
155
156 LONG_PTR lp;
157 sprintf(temporary+lstrlen(temporary),".%s",pobj_c->name);
158 CallProc(PROC_DEFAULT,
159 psi,
160 temporary,
161 Parameter,
162 &lp);
163
164 ss[0]++;
165
166
167 //ネイティブコードバッファの再確保
168 extern int obp_AllocSize;
169 if(obp_AllocSize<obp+8192){
170 obp_AllocSize+=8192;
171 OpBuffer=(char *)HeapReAlloc(hHeap,0,OpBuffer,obp_AllocSize); //matea
172 }
173 }
174 }
175 else{
176 LONG_PTR lp;
177 sprintf(temporary,"%s.%s",ObjectName,pobj_c->name);
178 CallProc(PROC_DEFAULT,
179 psi,
180 temporary,
181 Parameter,
182 &lp);
183 }
184}
185
186
187void CallDestrouctorsOfScope(void){
188 extern BOOL bCompilingGlobal;
189 VARIABLE *pVar;
190 int num;
191 if(bCompilingGlobal){
192 //グローバルオブジェクトの解放処理
193 extern VARIABLE *GlobalVar;
194 extern int MaxGlobalVarNum;
195 pVar=GlobalVar;
196 num=MaxGlobalVarNum;
197 }
198 else{
199 //ローカルオブジェクトの解放処理
200 extern VARIABLE *LocalVar;
201 extern int MaxLocalVarNum;
202 pVar=LocalVar;
203 num=MaxLocalVarNum;
204 }
205
206
207 int i3,i4,i5;
208 int indexSystemGC=-1;
209 for(i3=0;i3<num;i3++){
210
211 if(bCompilingGlobal&&obj_LexScopes.GetNowLevel()==0){
212 if(lstrcmp(pVar[i3].name,"_System_GC")==0){
213 indexSystemGC=i3;
214 continue;
215 }
216 }
217
218 //同一レベルのレキシカルスコープのみを検知
219 if(!pVar[i3].bLiving) continue;
220 if(pVar[i3].ScopeLevel!=obj_LexScopes.GetNowLevel()) continue;
221
222 if(pVar[i3].type==DEF_OBJECT&&pVar[i3].fRef&OBJECT_PARAMETER){
223 //実態オブジェクトのパラメータを持つとき
224
225 //デストラクタを呼び出す
226 i5=pVar[i3].u.pobj_c->DestructorMemberSubIndex;
227 if(i5!=-1)
228 Opcode_CallProc("",pVar[i3].u.pobj_c->ppobj_Method[i5]->psi,0,0,pVar[i3].name,DEF_OBJECT);
229
230 //メモリを解放する
231
232#ifdef _AMD64_
233 //x64ビットコード
234
235 //mov rcx,qword ptr[rsp+offset]
236 op_mov_RM(sizeof(_int64),REG_RCX,REG_RSP,
237 -pVar[i3].offset,
238 MOD_BASE_DISP32);
239 obp-=sizeof(long);
240 AddLocalVarAddrSchedule();
241 obp+=sizeof(long);
242#else
243 //x86コード
244
245 //mov ecx,dword ptr[ebp+offset]
246 op_mov_RM(sizeof(long),REG_ECX,REG_EBP,-pVar[i3].offset,MOD_BASE_DISP32);
247 obp-=sizeof(long);
248 AddLocalVarAddrSchedule();
249 obp+=sizeof(long);
250
251 //push ecx
252 op_push(REG_ECX);
253#endif
254
255 //call free
256 extern SUBINFO *pSub_free;
257 op_call(pSub_free);
258 }
259 else if(pVar[i3].type==DEF_OBJECT&&pVar[i3].fRef==0){
260 //デストラクタの呼び出し
261 i5=pVar[i3].u.pobj_c->DestructorMemberSubIndex;
262 if(i5!=-1){
263 int ss[MAX_ARRAYDIM];
264 memset(ss,0,MAX_ARRAYDIM*sizeof(int));
265 if(pVar[i3].SubScripts[0]!=-1){
266 while(1){
267 for(i4=0;;i4++){
268 if(pVar[i3].SubScripts[i4]==-1) break;
269
270 if(ss[i4]>pVar[i3].SubScripts[i4]){
271 ss[i4]=0;
272 ss[i4+1]++;
273 }
274 else break;
275 }
276 if(pVar[i3].SubScripts[i4]==-1) break;
277 char temporary[VN_SIZE];
278 sprintf(temporary,"%s[%d",pVar[i3].name,ss[0]);
279 for(i4=1;;i4++){
280 if(pVar[i3].SubScripts[i4]==-1) break;
281
282 sprintf(temporary+lstrlen(temporary),",%d",ss[i4]);
283 }
284 lstrcat(temporary,"]");
285 Opcode_CallProc("",pVar[i3].u.pobj_c->ppobj_Method[i5]->psi,0,0,temporary,DEF_OBJECT);
286
287 ss[0]++;
288
289
290 //ネイティブコードバッファの再確保
291 extern int obp_AllocSize;
292 if(obp_AllocSize<obp+8192){
293 obp_AllocSize+=8192;
294 OpBuffer=(char *)HeapReAlloc(hHeap,0,OpBuffer,obp_AllocSize); //matea
295 }
296 }
297 }
298 else{
299 Opcode_CallProc("",pVar[i3].u.pobj_c->ppobj_Method[i5]->psi,0,0,pVar[i3].name,DEF_OBJECT);
300 }
301 }
302 }
303 }
304
305 if(indexSystemGC!=-1){
306 //_System_GCオブジェクトのデストラクタの呼び出し処理
307 i3=pVar[indexSystemGC].u.pobj_c->DestructorMemberSubIndex;
308 if(i3!=-1){
309 Opcode_CallProc("",pVar[indexSystemGC].u.pobj_c->ppobj_Method[i3]->psi,0,0,pVar[indexSystemGC].name,DEF_OBJECT);
310 }
311 }
312}
313
Note: See TracBrowser for help on using the repository browser.