source: dev/BasicCompiler64/Compile_Object.cpp@ 28

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

・【32ビットコンパイラ】戻り値に実態オブジェクトを持つインデクサを呼び出すと強制終了してしまうバグを修正。
・仮想関数のオーバーロードが正常に動作しないバグを修正。
・純仮想関数(抽象メソッド)が仮想関数でオーバーロードされていると、クラスのインスタンスが生成できてしまうバグを修正。

File size: 7.1 KB
Line 
1#include "../BasicCompiler_Common/common.h"
2#include "opcode.h"
3
4void CallConstructor(CClass *pobj_c,char *CreateParameter,int ObjectSize,BOOL bSomeObjects){
5 ////////////////////////////
6 // コンストラクタの呼び出し
7 ////////////////////////////
8
9 //この関数を使用する場合は、
10 //・ebxにオブジェクトの個数(複数個の場合のみ)
11 //・スタックフレームの先頭参照位置に先頭Thisポインタ
12 //をセットしておかなければならない
13
14 int jnz_back;
15
16
17 //jnzの番地
18 jnz_back=obp;
19
20 if(bSomeObjects){
21 //mov qword ptr[rsp+offset],rbx ※スタックフレームを利用
22 pobj_sf->push(REG_RBX);
23
24 // ※ここでプッシュされた値はコンストラクタのthisポインタとなる
25 //mov qword ptr[rsp+offset],rax ※スタックフレームを利用
26 pobj_sf->push(REG_RAX);
27 }
28
29
30 ////////////////////////
31 // オーバーロードを解決
32 ////////////////////////
33
34 SUBINFO **ppsi;
35 SUBINFO *psi;
36 int num;
37 ppsi=GetOverloadObjectSubHash(pobj_c->name,pobj_c,&num);
38 if(num){
39 //オーバーロードを解決
40 psi=OverloadSolutionWithStrParam(pobj_c->name,
41 ppsi,num,CreateParameter,"",NULL);
42 HeapDefaultFree(ppsi);
43
44 if(!psi) return;
45 }
46
47 //コンストラクタを呼び出す
48 Opcode_CallProc(CreateParameter,
49 psi,
50 0,
51 PROCFLAG_NEW,"",0);
52
53 if(bSomeObjects){
54 //mov rax,qword ptr[rsp+offset] ※スタックフレームを利用
55 pobj_sf->pop(REG_RAX);
56
57 //mov rbx,qword ptr[rsp+offset] ※スタックフレームを利用
58 pobj_sf->pop(REG_RBX);
59
60 //add eax,TypeSize
61 OpBuffer[obp++]=(char)0x05;
62 *((long *)(OpBuffer+obp))=ObjectSize;
63 obp+=sizeof(long);
64
65 //sub ebx,1
66 OpBuffer[obp++]=(char)0x83;
67 OpBuffer[obp++]=(char)0xEB;
68 OpBuffer[obp++]=(char)0x01;
69
70 //jnz ↑
71 OpBuffer[obp++]=(char)0x0F;
72 OpBuffer[obp++]=(char)0x85;
73 *((long *)(OpBuffer+obp))=jnz_back-(obp+sizeof(long));
74 obp+=sizeof(long);
75 }
76}
77int Operator_New(const char *Parameter,LONG_PTR *plpIndex){
78 char TypeName[VN_SIZE],CreateParameter[VN_SIZE],ObjectSize[VN_SIZE];
79 int i,i2;
80 int reg;
81
82 i=0;
83
84 if(Parameter[0]=='['){
85 i=GetStringInBracket(ObjectSize,Parameter);
86
87 SlideString(ObjectSize+1,-1);
88 ObjectSize[i-2]=0;
89 }
90 else ObjectSize[0]=0;
91
92 for(i2=0;;i++,i2++){
93 if(Parameter[i]=='('){
94 TypeName[i2]=0;
95
96 //コンストラクタに渡すパラメータを取得
97 i2=GetStringInPare(CreateParameter,Parameter+i);
98 RemoveStringPare(CreateParameter);
99 i+=i2;
100 if(Parameter[i]!='\0'){
101 SetError(42,NULL,cp);
102 return 0;
103 }
104 break;
105 }
106 TypeName[i2]=Parameter[i];
107 if(Parameter[i]=='\0'){
108 CreateParameter[0]=0;
109 break;
110 }
111 }
112
113 int type,TypeSize;
114 type=GetTypeFixed(TypeName,plpIndex);
115 if(type==-1){
116 SetError(3,TypeName,cp);
117 return 0;
118 }
119 TypeSize=GetTypeSize(type,*plpIndex);
120
121 if(type!=DEF_OBJECT){
122 ////////////////////////
123 // 通常のデータ型の場合
124 ////////////////////////
125
126 SetError(121,NULL,cp);
127 return 0;
128 }
129
130 CClass *pobj_c;
131 pobj_c=(CClass *)*plpIndex;
132
133 if(pobj_c->IsAbstract()){
134 //抽象クラスだったとき
135 SetError(125,pobj_c->name,cp);
136 }
137
138 BOOL bSomeObjects=0;
139 if(ObjectSize[0]){
140 bSomeObjects=1;
141
142 reg=REG_RAX;
143 i2=NumOpe(&reg,ObjectSize,0,0,0);
144 if(!IsWholeNumberType(i2)) SetError(49,NULL,cp);
145
146 //※添え字上限値であることを考慮
147 //add rax,1
148 op_add64_value(REG_RAX,1);
149
150 //オブジェクトの個数をrbxに一時保持
151 //※rbxは関数が呼ばれても不変
152 //mov rbx,rax
153 op_mov64_ToReg_FromReg(REG_RBX,REG_RAX);
154
155 //imul rax,size
156 op_imul_value(sizeof(_int64),REG_RAX,TypeSize);
157
158 //add rax,PTR_SIZE*3
159 op_add64_value(REG_RAX,PTR_SIZE*3);
160
161 //mov rcx,rax
162 op_mov64_ToReg_FromReg(REG_RCX,REG_RAX);
163 }
164 else{
165 //オブジェクトの個数をrbxに一時保持
166 //※rbxは関数が呼ばれても不変
167 //mov rbx,1
168 op_mov_RV(sizeof(_int64),REG_RBX,1);
169
170 //mov rcx,TypeSize+PTR_SIZE*3
171 op_mov_RV(sizeof(_int64),REG_RCX,TypeSize+PTR_SIZE*3);
172 }
173
174 //call calloc
175 extern SUBINFO *pSub_calloc;
176 op_call(pSub_calloc);
177
178
179 /*
180 確保されたヒープ領域のポインタ(callocの戻り値eax)をpPtrとすると、
181 pPtr-=sizeof(DWORD)*3
182 pPtr[0]=オブジェクトの個数
183 pPtr[1]=オブジェクトのサイズ
184 pPtr[2]=デストラクタの関数ポインタ
185 */
186
187
188 //mov qword ptr[rax],rbx(オブジェクトの個数)
189 op_mov_MR(sizeof(_int64),REG_RBX,REG_RAX,0,MOD_BASE);
190
191 //add rax,PTR_SIZE
192 op_add64_value(REG_RAX,PTR_SIZE);
193
194
195 //mov qword ptr[rax],TypeSize(オブジェクトのサイズ)
196 op_mov_MV(sizeof(_int64),REG_RAX,0,NON_OFFSET,TypeSize);
197
198 //add rax,PTR_SIZE
199 op_add64_value(REG_RAX,PTR_SIZE);
200
201
202 i2=pobj_c->DestructorMemberSubIndex;
203 if(i2==-1) return 0;
204
205 //mov rcx,DestructorProcAddr
206 op_mov_RV(sizeof(_int64),REG_RCX,0);
207 obp-=sizeof(long);
208 pobj_SubAddrSchedule->add(pobj_c->ppobj_Method[i2]->psi,0);
209 pobj_c->ppobj_Method[i2]->psi->bUse=1;
210 obp+=sizeof(long);
211
212 //mov qword ptr[rax],rcx
213 op_mov_MR(sizeof(_int64),REG_RCX,REG_RAX,0,MOD_BASE);
214
215 //add rax,PTR_SIZE
216 op_add64_value(REG_RAX,PTR_SIZE);
217
218
219 // ※ここでプッシュされた値はNew演算子の戻り値となる
220 //mov qword ptr[rsp+offset],rax ※スタックフレームを利用
221 pobj_sf->push(REG_RAX);
222
223
224 /////////////////////////////////////////////////////////////////////
225
226 ////////////////////////////
227 // コンストラクタの呼び出し
228 ////////////////////////////
229
230 CallConstructor(pobj_c,CreateParameter,TypeSize,bSomeObjects);
231
232
233 //mov rax,qword ptr[rsp+offset] ※スタックフレームを利用
234 pobj_sf->pop(REG_RAX);
235
236 return DEF_PTR_OBJECT;
237}
238
239void OpcodeDelete(const char *Parameter){
240 int type;
241
242 int reg=REG_RAX;
243 type=NumOpe(&reg,Parameter,0,0,0);
244 if(type==-1) return;
245 if(!(type==DEF_PTR_OBJECT||type==DEF_PTR_VOID)) SetError(122,NULL,cp);
246
247 //sub rax,PTR_SIZE*3
248 op_sub_RV(sizeof(_int64),REG_RAX,PTR_SIZE*3);
249
250 //mov qword ptr[rsp+offset],rax ※スタックフレームを利用
251 pobj_sf->push(REG_RAX);
252
253
254 //mov rbx,qword ptr[rax](オブジェクトの個数)
255 op_mov_RM(sizeof(_int64),REG_RBX,REG_RAX,0,MOD_BASE);
256
257 //add rax,PTR_SIZE
258 op_add64_value(REG_RAX,PTR_SIZE);
259
260
261 //mov rsi,qword ptr[rax](オブジェクトのサイズ)
262 op_mov_RM(sizeof(_int64),REG_RSI,REG_RAX,0,MOD_BASE);
263
264 //add rax,PTR_SIZE
265 op_add64_value(REG_RAX,PTR_SIZE);
266
267
268 //mov rdi,qword ptr[rax](デストラクタの関数ポインタ)
269 op_mov_RM(sizeof(_int64),REG_RDI,REG_RAX,0,MOD_BASE);
270
271 //add rax,PTR_SIZE
272 op_add64_value(REG_RAX,PTR_SIZE);
273
274
275 //mov rcx,rax
276 op_mov64_ToReg_FromReg(REG_RCX,REG_RAX);
277
278
279 //jnzの番地
280 int jnz_back;
281 jnz_back=obp;
282
283 //mov qword ptr[rsp+offset],rax ※スタックフレームを利用
284 pobj_sf->push(REG_RAX);
285
286 //call rdi
287 OpBuffer[obp++]=(char)0xFF;
288 OpBuffer[obp++]=(char)0xD7;
289
290 //mov rcx,qword ptr[rsp+offset] ※スタックフレームを利用
291 pobj_sf->pop(REG_RCX);
292
293 //add rcx,rsi
294 op_add64_reg(REG_RCX,REG_RSI);
295
296 //sub rbx,1
297 op_sub_RV(sizeof(_int64),REG_RBX,1);
298
299 //jnz ↑
300 OpBuffer[obp++]=(char)0x0F;
301 OpBuffer[obp++]=(char)0x85;
302 *((long *)(OpBuffer+obp))=jnz_back-(obp+sizeof(long));
303 obp+=sizeof(long);
304
305
306 //////////////////////////////////////////
307 // オブジェクトメンバ変数用のメモリを解放
308 //////////////////////////////////////////
309
310 //mov rcx,qword ptr[rsp+offset] ※スタックフレームを利用
311 pobj_sf->pop(REG_RCX);
312
313 //call free
314 extern SUBINFO *pSub_free;
315 op_call(pSub_free);
316}
Note: See TracBrowser for help on using the repository browser.