source: dev/branches/egtra/ab5.0/abdev/compiler_x64/Compile_Object.cpp@ 802

Last change on this file since 802 was 768, checked in by dai, 16 years ago

[750]をx64版にマージ

File size: 10.0 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 compiler.errorMessenger.OutputFatalError();
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 // 動的型情報をセットする
52 // obj._System_SetType( _System_TypeBase_Search( fullName ) )
53 subs.clear();
54 pobj_c->GetDynamicMethods().Enum( "_System_SetType", subs );
55 if( subs.size() == 1 ){
56 char temporary[VN_SIZE];
57 sprintf( temporary, "_System_TypeBase_Search(\"%s\"))", pobj_c->GetFullName().c_str() );
58
59 Opcode_CallProc(temporary,
60 subs[0],
61 PROCFLAG_NEW,"");
62 }
63 else{
64 compiler.errorMessenger.OutputFatalError();
65 }
66 }
67
68 //コンストラクタを呼び出す
69 Opcode_CallProc(CreateParameter,
70 pUserProc,
71 PROCFLAG_NEW | PROCFLAG_PERMIT_CONSTRUCTOR,"");
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 std::string tempMessage;
106 foreach( const CMethod *pMethod, pClass->GetDynamicMethods() ){
107 if(pMethod->IsVirtual()){
108 if(pMethod->IsAbstract()){
109 if( !tempMessage.empty() )
110 {
111 tempMessage += ", ";
112 }
113 tempMessage += pMethod->GetUserProc().GetName();
114 }
115 }
116 }
117
118 // インターフェイスのvtbl
119 foreach( const ::Interface *pInterface, pClass->GetInterfaces() )
120 {
121 foreach( const CMethod *pMethod, pInterface->GetDynamicMethods() ){
122 if(pMethod->IsVirtual()){
123 if(pMethod->IsAbstract()){
124 if( !tempMessage.empty() )
125 {
126 tempMessage += ", ";
127 }
128 tempMessage += pMethod->GetUserProc().GetName();
129 }
130 }
131 }
132 }
133
134 //抽象クラスだったとき
135 compiler.errorMessenger.Output(-1,"\"%s\" は抽象クラスです。インスタンス化することはできません(抽象メソッド … " + tempMessage + ")。",cp);
136 }
137
138 BOOL bSomeObjects=0;
139 if(objectSizeStr[0]){
140 bSomeObjects=1;
141
142 int reg=REG_RAX;
143 Type tempType;
144 NumOpe(&reg,objectSizeStr,Type(),tempType);
145 if( !tempType.IsWhole() ) compiler.errorMessenger.Output(49,NULL,cp);
146
147 //※添え字上限値であることを考慮
148 //add rax,1
149 compiler.codeGenerator.op_add_RV(REG_RAX,1);
150
151 //オブジェクトの個数をrbxに一時保持
152 //※rbxは関数が呼ばれても不変
153 //mov rbx,rax
154 compiler.codeGenerator.op_mov_RR(REG_RBX,REG_RAX);
155
156 //imul rax,size
157 compiler.codeGenerator.op_imul_RV(sizeof(_int64),REG_RAX,typeSize);
158
159 //add rax,OBJECT_HEAD_SIZE
160 compiler.codeGenerator.op_add_RV(REG_RAX,OBJECT_HEAD_SIZE);
161
162 //mov rcx,rax
163 compiler.codeGenerator.op_mov_RR(REG_RCX,REG_RAX);
164 }
165 else{
166 //オブジェクトの個数をrbxに一時保持
167 //※rbxは関数が呼ばれても不変
168 //mov rbx,1
169 compiler.codeGenerator.op_mov_RV(sizeof(_int64),REG_RBX,1);
170
171 //mov rcx,typeSize+OBJECT_HEAD_SIZE
172 compiler.codeGenerator.op_mov_RV(sizeof(_int64),REG_RCX,typeSize+OBJECT_HEAD_SIZE);
173 }
174
175 if( baseType.IsObject() ){
176 // オブジェクト インスタンス
177 // ※DeleteはGCで処理
178
179 //call _System_GC_malloc_ForObject
180 extern const UserProc *pSub_System_GC_malloc_ForObject;
181 compiler.codeGenerator.op_call(pSub_System_GC_malloc_ForObject);
182 }
183 else{
184 // オブジェクトポインタ
185 // ※明示的なDeleteが必要
186
187 //call _System_GC_malloc_ForObjectPtr
188 extern const UserProc *pSub_System_GC_malloc_ForObjectPtr;
189 compiler.codeGenerator.op_call(pSub_System_GC_malloc_ForObjectPtr);
190 }
191
192
193 /*
194 確保されたヒープ領域のポインタ(callocの戻り値eax)をpPtrとすると、
195 pPtr-=OBJECT_HEAD_SIZE ... ( sizeof(DWORD)*4 )
196 pPtr[0]=オブジェクトの個数
197 pPtr[1]=オブジェクトのサイズ
198 pPtr[2]=デストラクタの関数ポインタ
199 pPtr[3]=reserve
200 */
201
202
203 //mov qword ptr[rax],rbx(オブジェクトの個数)
204 compiler.codeGenerator.op_mov_MR(sizeof(_int64),REG_RBX,REG_RAX,0,MOD_BASE);
205
206 //add rax,PTR_SIZE
207 compiler.codeGenerator.op_add_RV(REG_RAX,PTR_SIZE);
208
209
210 //mov qword ptr[rax],typeSize(オブジェクトのサイズ)
211 compiler.codeGenerator.op_mov_MV(sizeof(_int64),REG_RAX,0, Schedule::None, false, NON_OFFSET,typeSize);
212
213 //add rax,PTR_SIZE
214 compiler.codeGenerator.op_add_RV(REG_RAX,PTR_SIZE);
215
216
217 const CMethod *method = pClass->GetDestructorMethod();
218 if( method == NULL ) return;
219
220 //mov rcx,DestructorProcAddr(デストラクタの関数ポインタ)
221 compiler.codeGenerator.op_addressof( REG_RCX, &method->GetUserProc() );
222
223 //mov qword ptr[rax],rcx
224 compiler.codeGenerator.op_mov_MR(sizeof(_int64),REG_RCX,REG_RAX,0,MOD_BASE);
225
226 //add rax,PTR_SIZE
227 compiler.codeGenerator.op_add_RV(REG_RAX,PTR_SIZE);
228
229
230 // リザーブ領域
231 //add rax,PTR_SIZE
232 compiler.codeGenerator.op_add_RV(REG_RAX,PTR_SIZE);
233
234
235 // ※ここでプッシュされた値はNew演算子の戻り値となる
236 //mov qword ptr[rsp+offset],rax ※スタックフレームを利用
237 pobj_sf->push(REG_RAX);
238
239
240 //仮想関数テーブルを初期化
241 if( pClass->IsExistVirtualFunctions()
242 && !pClass->IsAbstract() )
243 {
244 // mov rcx,com_vtbl
245 compiler.codeGenerator.op_mov_RV_com_vtbl( REG_RCX, pClass );
246
247 //mov qword ptr[rax],rcx
248 compiler.codeGenerator.op_mov_MR(sizeof(_int64),REG_RCX,REG_RAX,0,MOD_BASE);
249
250 // mov rcx,vtblAddress
251 compiler.codeGenerator.op_mov_RV_vtbl( REG_RCX, pClass );
252
253 //mov qword ptr[rax+sizeof(com_vtbl)],rcx
254 compiler.codeGenerator.op_mov_MR(sizeof(_int64),REG_RCX,REG_RAX,PTR_SIZE,MOD_BASE_DISP8);
255
256
257 // 仮想関数になるメソッドに使用チェックをつける
258 foreach( const CMethod *pMethod, pClass->GetDynamicMethods() )
259 {
260 if( pMethod->IsVirtual() )
261 {
262 pMethod->GetUserProc().Using();
263 }
264 }
265 foreach( const ::Interface *pInterface, pClass->GetInterfaces() )
266 {
267 foreach( const CMethod *pMethod, pInterface->GetDynamicMethods() )
268 {
269 if( pMethod->IsVirtual() )
270 {
271 pMethod->GetUserProc().Using();
272 }
273 }
274 }
275 }
276
277
278 /////////////////////////////////////////////////////////////////////
279
280 ////////////////////////////
281 // コンストラクタの呼び出し
282 ////////////////////////////
283
284 _call_constructor(pClass,parameter,typeSize,bSomeObjects);
285
286
287 //mov rax,qword ptr[rsp+offset] ※スタックフレームを利用
288 pobj_sf->pop(REG_RAX);
289}
290void OpcodeDelete(const char *Parameter, bool isSweeping){
291 int reg=REG_RAX;
292 Type tempType;
293 if( !NumOpe(&reg,Parameter,Type(),tempType) ){
294 return;
295 }
296 if(!( tempType.IsObjectPtr() || tempType.IsVoidPtr() )) compiler.errorMessenger.Output(122,NULL,cp);
297
298 //sub rax,OBJECT_HEAD_SIZE
299 compiler.codeGenerator.op_sub_RV(sizeof(_int64),REG_RAX,OBJECT_HEAD_SIZE);
300
301 //mov qword ptr[rsp+offset],rax ※スタックフレームを利用
302 pobj_sf->push(REG_RAX);
303
304
305 //mov rbx,qword ptr[rax](オブジェクトの個数)
306 compiler.codeGenerator.op_mov_RM(sizeof(_int64),REG_RBX,REG_RAX,0,MOD_BASE);
307
308 //add rax,PTR_SIZE
309 compiler.codeGenerator.op_add_RV(REG_RAX,PTR_SIZE);
310
311
312 //mov rsi,qword ptr[rax](オブジェクトのサイズ)
313 compiler.codeGenerator.op_mov_RM(sizeof(_int64),REG_RSI,REG_RAX,0,MOD_BASE);
314
315 //add rax,PTR_SIZE
316 compiler.codeGenerator.op_add_RV(REG_RAX,PTR_SIZE);
317
318
319 //mov rdi,qword ptr[rax](デストラクタの関数ポインタ)
320 compiler.codeGenerator.op_mov_RM(sizeof(_int64),REG_RDI,REG_RAX,0,MOD_BASE);
321
322 //add rax,PTR_SIZE
323 compiler.codeGenerator.op_add_RV(REG_RAX,PTR_SIZE);
324
325
326 // リザーブ領域
327 //add rax,PTR_SIZE
328 compiler.codeGenerator.op_add_RV(REG_RAX,PTR_SIZE);
329
330
331 //mov rcx,rax
332 compiler.codeGenerator.op_mov_RR(REG_RCX,REG_RAX);
333
334
335 //jnzの番地
336 //int jnz_back=obp;
337
338 //mov qword ptr[rsp+offset],rcx ※スタックフレームを利用
339 pobj_sf->push(REG_RCX);
340
341 //call rdi
342 compiler.codeGenerator.PutOld(
343 (char)0xFF,
344 (char)0xD7
345 );
346
347 //mov rcx,qword ptr[rsp+offset] ※スタックフレームを利用
348 pobj_sf->pop(REG_RCX);
349
350 //add rcx,rsi
351 compiler.codeGenerator.op_add_RR(REG_RCX,REG_RSI);
352
353 //sub rbx,1
354 compiler.codeGenerator.op_sub_RV(sizeof(_int64),REG_RBX,1);
355
356 //jnz ↑
357 //compiler.codeGenerator.op_jne( jnz_back-obp, sizeof(long), false, true );
358
359
360 //////////////////////////////////////////
361 // オブジェクトメンバ変数用のメモリを解放
362 //////////////////////////////////////////
363
364 //mov rcx,qword ptr[rsp+offset] ※スタックフレームを利用
365 pobj_sf->pop(REG_RCX);
366
367 if( isSweeping ){
368 //call _System_GC_free_for_SweepingDelete
369 extern const UserProc *pSub_System_GC_free_for_SweepingDelete;
370 compiler.codeGenerator.op_call(pSub_System_GC_free_for_SweepingDelete);
371 }
372 else{
373 //call free
374 extern const UserProc *pSub_free;
375 compiler.codeGenerator.op_call(pSub_free);
376 }
377}
Note: See TracBrowser for help on using the repository browser.