source: dev/BasicCompiler64/Compile_Object.cpp@ 20

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

LexicalAnalysisを廃止。

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->IsHoldAbstractFunction()){
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.