source: dev/BasicCompiler64/Compile_Object.cpp@ 64

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

すべてのオブジェクトを参照型に切り替えた。

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