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

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