source: dev/trunk/ab5.0/abdev/compiler_x64/Compile_Object.cpp@ 704

Last change on this file since 704 was 704, checked in by dai_9181, 16 years ago

[702]を64bit版にマージ。

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