source: dev/BasicCompiler64/Compile_Object.cpp@ 31

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

_System_LocalThis(見えないThisポインタパラメータ)を通常のパラメータ保有領域ではなく、リアルパラメータ保有領域に移動した。
メソッドとグローバル関数のオーバーロードに対応(DLL関数オーバーロードには未対応)。

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