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 |
|
---|
9 | extern HANDLE hHeap;
|
---|
10 |
|
---|
11 | int 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 | }
|
---|
38 | int 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 | }
|
---|
108 | int GetSizeOfClass(CClass *pobj_c){
|
---|
109 | return GetSizeOfClassMember(pobj_c,0,0);
|
---|
110 | }
|
---|
111 |
|
---|
112 |
|
---|
113 | void 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 |
|
---|
187 | void 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 | 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 |
|
---|