source: dev/trunk/abdev/BasicCompiler32/Compile_Object.cpp@ 332

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