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

Last change on this file since 255 was 255, checked in by dai_9181, 17 years ago
File size: 8.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 int jnz_back;
19
20
21 //jnzの番地
22 jnz_back=obp;
23
24 if(bSomeObjects){
[94]25 SetError();
[3]26 //mov qword ptr[rsp+offset],rbx ※スタックフレームを利用
27 pobj_sf->push(REG_RBX);
28
29 // ※ここでプッシュされた値はコンストラクタのthisポインタとなる
30 //mov qword ptr[rsp+offset],rax ※スタックフレームを利用
31 pobj_sf->push(REG_RAX);
32 }
33
34
35 ////////////////////////
36 // オーバーロードを解決
37 ////////////////////////
38
[206]39 std::vector<const UserProc *> subs;
[135]40 pobj_c->GetMethods().Enum( pobj_c->GetName().c_str(), subs );
[50]41
[206]42 const UserProc *pUserProc;
[50]43 if( subs.size() > 0 ){
[3]44 //オーバーロードを解決
[131]45 pUserProc=OverloadSolutionWithStrParam(pobj_c->GetName().c_str(),
[75]46 subs,CreateParameter,"");
[3]47
[75]48 if(!pUserProc) return;
[3]49 }
50
51 //コンストラクタを呼び出す
52 Opcode_CallProc(CreateParameter,
[75]53 pUserProc,
[3]54 PROCFLAG_NEW,"",0);
55
[90]56 {
57 // 動的型情報をセットする
58 // obj._System_SetType( _System_TypeBase.Search( strNamespace, name ) )
59 subs.clear();
[135]60 pobj_c->GetMethods().Enum( "_System_SetType", subs );
[90]61 if( subs.size() == 1 ){
62 char temporary[VN_SIZE];
[140]63 sprintf( temporary, "ActiveBasic.Core._System_TypeBase.Search(\"\",\"%s\"))", pobj_c->GetName().c_str() );
[90]64
65 Opcode_CallProc(temporary,
66 subs[0],
67 PROCFLAG_NEW,"",0);
68 }
69 else{
70 SetError();
71 }
72 }
73
[3]74 if(bSomeObjects){
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 );
[3]89 }
90}
[75]91void Operator_New( const CClass &classObj, const char *objectSizeStr, const char *parameter, const Type &baseType ){
[64]92 int typeSize = classObj.GetSize();
[3]93
[64]94 if(classObj.IsAbstract()){
[3]95 //抽象クラスだったとき
[131]96 SetError(125,classObj.GetName().c_str(),cp);
[3]97 }
98
99 BOOL bSomeObjects=0;
[64]100 if(objectSizeStr[0]){
[3]101 bSomeObjects=1;
102
[64]103 int reg=REG_RAX;
[75]104 Type tempType;
105 NumOpe(&reg,objectSizeStr,Type(),tempType);
106 if( !tempType.IsWhole() ) SetError(49,NULL,cp);
[3]107
108 //※添え字上限値であることを考慮
109 //add rax,1
[226]110 compiler.codeGenerator.op_add_RV(REG_RAX,1);
[3]111
112 //オブジェクトの個数をrbxに一時保持
113 //※rbxは関数が呼ばれても不変
114 //mov rbx,rax
[226]115 compiler.codeGenerator.op_mov_RR(REG_RBX,REG_RAX);
[3]116
117 //imul rax,size
[226]118 compiler.codeGenerator.op_imul_RV(sizeof(_int64),REG_RAX,typeSize);
[3]119
[123]120 //add rax,OBJECT_HEAD_SIZE
[226]121 compiler.codeGenerator.op_add_RV(REG_RAX,OBJECT_HEAD_SIZE);
[3]122
123 //mov rcx,rax
[226]124 compiler.codeGenerator.op_mov_RR(REG_RCX,REG_RAX);
[3]125 }
126 else{
127 //オブジェクトの個数をrbxに一時保持
128 //※rbxは関数が呼ばれても不変
129 //mov rbx,1
[226]130 compiler.codeGenerator.op_mov_RV(sizeof(_int64),REG_RBX,1);
[3]131
[123]132 //mov rcx,typeSize+OBJECT_HEAD_SIZE
[226]133 compiler.codeGenerator.op_mov_RV(sizeof(_int64),REG_RCX,typeSize+OBJECT_HEAD_SIZE);
[3]134 }
135
[75]136 if( baseType.IsObject() ){
137 // オブジェクト インスタンス
138 // ※DeleteはGCで処理
[3]139
[64]140 //call _System_GC_malloc_ForObject
[206]141 extern const UserProc *pSub_System_GC_malloc_ForObject;
[226]142 compiler.codeGenerator.op_call(pSub_System_GC_malloc_ForObject);
[64]143 }
144 else{
[75]145 // オブジェクトポインタ
146 // ※明示的なDeleteが必要
[3]147
[64]148 //call _System_GC_malloc_ForObjectPtr
[206]149 extern const UserProc *pSub_System_GC_malloc_ForObjectPtr;
[226]150 compiler.codeGenerator.op_call(pSub_System_GC_malloc_ForObjectPtr);
[64]151 }
152
153
[3]154 /*
155 確保されたヒープ領域のポインタ(callocの戻り値eax)をpPtrとすると、
[123]156 pPtr-=OBJECT_HEAD_SIZE ... ( sizeof(DWORD)*4 )
[3]157 pPtr[0]=オブジェクトの個数
158 pPtr[1]=オブジェクトのサイズ
159 pPtr[2]=デストラクタの関数ポインタ
[123]160 pPtr[3]=reserve
[3]161 */
162
163
164 //mov qword ptr[rax],rbx(オブジェクトの個数)
[226]165 compiler.codeGenerator.op_mov_MR(sizeof(_int64),REG_RBX,REG_RAX,0,MOD_BASE);
[3]166
167 //add rax,PTR_SIZE
[226]168 compiler.codeGenerator.op_add_RV(REG_RAX,PTR_SIZE);
[3]169
170
[64]171 //mov qword ptr[rax],typeSize(オブジェクトのサイズ)
[254]172 compiler.codeGenerator.op_mov_MV(sizeof(_int64),REG_RAX,0, Schedule::None, false, NON_OFFSET,typeSize);
[3]173
174 //add rax,PTR_SIZE
[226]175 compiler.codeGenerator.op_add_RV(REG_RAX,PTR_SIZE);
[3]176
177
[135]178 const CMethod *method = classObj.GetDestructorMethod();
[64]179 if( method == NULL ) return;
[3]180
[123]181 //mov rcx,DestructorProcAddr(デストラクタの関数ポインタ)
[226]182 compiler.codeGenerator.op_mov_RV(sizeof(_int64),REG_RCX,0);
[3]183 obp-=sizeof(long);
[206]184 pobj_SubAddrSchedule->add(&method->GetUserProc(),0);
185 method->GetUserProc().Using();
[3]186 obp+=sizeof(long);
187
188 //mov qword ptr[rax],rcx
[226]189 compiler.codeGenerator.op_mov_MR(sizeof(_int64),REG_RCX,REG_RAX,0,MOD_BASE);
[3]190
191 //add rax,PTR_SIZE
[226]192 compiler.codeGenerator.op_add_RV(REG_RAX,PTR_SIZE);
[3]193
194
[123]195 // リザーブ領域
196 //add rax,PTR_SIZE
[226]197 compiler.codeGenerator.op_add_RV(REG_RAX,PTR_SIZE);
[123]198
199
[3]200 // ※ここでプッシュされた値はNew演算子の戻り値となる
201 //mov qword ptr[rsp+offset],rax ※スタックフレームを利用
202 pobj_sf->push(REG_RAX);
203
204
205 /////////////////////////////////////////////////////////////////////
206
207 ////////////////////////////
208 // コンストラクタの呼び出し
209 ////////////////////////////
210
[64]211 _call_constructor(&classObj,parameter,typeSize,bSomeObjects);
[3]212
213
214 //mov rax,qword ptr[rsp+offset] ※スタックフレームを利用
215 pobj_sf->pop(REG_RAX);
[64]216}
217void OpcodeDelete(const char *Parameter, bool isSweeping){
[3]218 int reg=REG_RAX;
[75]219 Type tempType;
220 if( !NumOpe(&reg,Parameter,Type(),tempType) ){
221 return;
222 }
223 if(!( tempType.IsObjectPtr() || tempType.IsVoidPtr() )) SetError(122,NULL,cp);
[3]224
[123]225 //sub rax,OBJECT_HEAD_SIZE
[226]226 compiler.codeGenerator.op_sub_RV(sizeof(_int64),REG_RAX,OBJECT_HEAD_SIZE);
[3]227
228 //mov qword ptr[rsp+offset],rax ※スタックフレームを利用
229 pobj_sf->push(REG_RAX);
230
231
232 //mov rbx,qword ptr[rax](オブジェクトの個数)
[226]233 compiler.codeGenerator.op_mov_RM(sizeof(_int64),REG_RBX,REG_RAX,0,MOD_BASE);
[3]234
235 //add rax,PTR_SIZE
[226]236 compiler.codeGenerator.op_add_RV(REG_RAX,PTR_SIZE);
[3]237
238
239 //mov rsi,qword ptr[rax](オブジェクトのサイズ)
[226]240 compiler.codeGenerator.op_mov_RM(sizeof(_int64),REG_RSI,REG_RAX,0,MOD_BASE);
[3]241
242 //add rax,PTR_SIZE
[226]243 compiler.codeGenerator.op_add_RV(REG_RAX,PTR_SIZE);
[3]244
245
246 //mov rdi,qword ptr[rax](デストラクタの関数ポインタ)
[226]247 compiler.codeGenerator.op_mov_RM(sizeof(_int64),REG_RDI,REG_RAX,0,MOD_BASE);
[3]248
249 //add rax,PTR_SIZE
[226]250 compiler.codeGenerator.op_add_RV(REG_RAX,PTR_SIZE);
[3]251
252
[123]253 // リザーブ領域
254 //add rax,PTR_SIZE
[226]255 compiler.codeGenerator.op_add_RV(REG_RAX,PTR_SIZE);
[123]256
257
[3]258 //mov rcx,rax
[226]259 compiler.codeGenerator.op_mov_RR(REG_RCX,REG_RAX);
[3]260
261
262 //jnzの番地
263 int jnz_back;
264 jnz_back=obp;
265
[64]266 //mov qword ptr[rsp+offset],rcx ※スタックフレームを利用
267 pobj_sf->push(REG_RCX);
[3]268
269 //call rdi
[228]270 compiler.codeGenerator.PutOld(
271 (char)0xFF,
272 (char)0xD7
273 );
[3]274
275 //mov rcx,qword ptr[rsp+offset] ※スタックフレームを利用
276 pobj_sf->pop(REG_RCX);
277
278 //add rcx,rsi
[228]279 compiler.codeGenerator.op_add_RR(REG_RCX,REG_RSI);
[3]280
281 //sub rbx,1
[226]282 compiler.codeGenerator.op_sub_RV(sizeof(_int64),REG_RBX,1);
[3]283
284 //jnz ↑
[255]285 compiler.codeGenerator.op_jne( jnz_back-obp, sizeof(long), false, true );
[3]286
287
288 //////////////////////////////////////////
289 // オブジェクトメンバ変数用のメモリを解放
290 //////////////////////////////////////////
291
292 //mov rcx,qword ptr[rsp+offset] ※スタックフレームを利用
293 pobj_sf->pop(REG_RCX);
294
[64]295 if( isSweeping ){
296 //call _System_GC_free_for_SweepingDelete
[206]297 extern const UserProc *pSub_System_GC_free_for_SweepingDelete;
[226]298 compiler.codeGenerator.op_call(pSub_System_GC_free_for_SweepingDelete);
[64]299 }
300 else{
301 //call free
[206]302 extern const UserProc *pSub_free;
[226]303 compiler.codeGenerator.op_call(pSub_free);
[64]304 }
[3]305}
Note: See TracBrowser for help on using the repository browser.