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

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