source: dev/BasicCompiler64/Compile_Object.cpp@ 90

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

実行時型情報の生成にほぼ対応した。

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