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

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