source: dev/trunk/abdev/BasicCompiler64/Compile_Object.cpp@ 206

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

コード全体のリファクタリングを実施

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