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

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