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

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

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

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