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

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

静的領域に初期オブジェクトを配置可能にした

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