source: dev/BasicCompiler64/Compile_Object.cpp@ 60

Last change on this file since 60 was 51, checked in by dai_9181, 18 years ago

ppobj_Member及びppobj_StaticMemberを廃止し、vectorに統一した(methods及びstaticMethods)。

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