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

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

インターフェイス実装中…

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