source: dev/trunk/ab5.0/abdev/compiler_x86/Compile_Object.cpp@ 750

Last change on this file since 750 was 750, checked in by イグトランス (egtra), 16 years ago

BOOST_FOREACHを可能なものはVC++ 2005 for eachへ置換(やや速くなる)。

File size: 9.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
[332]18
[259]19/* //jnzのジャンプ先番地
[253]20 extern int obp;
[259]21 int jnz_back = obp;*/
[3]22
[94]23 if(bSomeObjects){
[465]24 compiler.errorMessenger.OutputFatalError();
[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;
[342]41 pobj_c->GetDynamicMethods().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
[90]52 {
53 // 動的型情報をセットする
[355]54 // obj._System_SetType( _System_TypeBase_Search( fullName ) )
[90]55 subs.clear();
[342]56 pobj_c->GetDynamicMethods().Enum( "_System_SetType", subs );
[90]57 if( subs.size() == 1 ){
58 char temporary[VN_SIZE];
[355]59 sprintf( temporary, "_System_TypeBase_Search(\"%s\"))", pobj_c->GetFullName().c_str() );
[3]60
[90]61 Opcode_CallProc(temporary,
62 subs[0],
[290]63 PROCFLAG_NEW,"");
[90]64 }
65 else{
[465]66 compiler.errorMessenger.OutputFatalError();
[90]67 }
[303]68
69 // インターフェイスを初期化する
70 // TODO: 実装
[90]71 }
[3]72
[391]73 //コンストラクタを呼び出す
74 Opcode_CallProc(CreateParameter,
75 pUserProc,
[702]76 PROCFLAG_NEW | PROCFLAG_PERMIT_CONSTRUCTOR,"");
[90]77
78
[391]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}
[349]99void Operator_New( const CClass &objClass, const char *objectSizeStr, const char *parameter, const Type &baseType )
100{
101 const CClass *pClass = &objClass;
[3]102
[349]103 if( pClass->IsInterface() )
104 {
105 pClass = compiler.GetObjectModule().meta.GetClasses().GetInterfaceInfoClassPtr();
106 }
107
[354]108 int typeSize = pClass->GetSize();
109
[728]110 if(pClass->IsAbstract())
111 {
112 std::string tempMessage;
[750]113 foreach( const CMethod *pMethod, pClass->GetDynamicMethods() ){
[728]114 if(pMethod->IsVirtual()){
115 if(pMethod->IsAbstract()){
116 if( !tempMessage.empty() )
117 {
118 tempMessage += ", ";
119 }
120 tempMessage += pMethod->GetUserProc().GetName();
121 }
122 }
123 }
124
125 // インターフェイスのvtbl
[750]126 foreach( const ::Interface *pInterface, pClass->GetInterfaces() )
[728]127 {
[750]128 foreach( const CMethod *pMethod, pInterface->GetDynamicMethods() ){
[728]129 if(pMethod->IsVirtual()){
130 if(pMethod->IsAbstract()){
131 if( !tempMessage.empty() )
132 {
133 tempMessage += ", ";
134 }
135 tempMessage += pMethod->GetUserProc().GetName();
136 }
137 }
138 }
139 }
140
[3]141 //抽象クラスだったとき
[728]142 compiler.errorMessenger.Output(-1,"\"%s\" は抽象クラスです。インスタンス化することはできません(抽象メソッド … " + tempMessage + ")。",cp);
[3]143 }
144
[75]145 BOOL bSomeObjects=0;
[64]146 if(objectSizeStr[0]){
[75]147 bSomeObjects=1;
[3]148
[75]149 Type tempType;
150 NumOpe(objectSizeStr,Type(),tempType);
[465]151 if( !tempType.IsWhole() ) compiler.errorMessenger.Output(49,NULL,cp);
[75]152 ChangeTypeToLong(tempType.GetBasicType());
153
[3]154 //pop eax
[225]155 compiler.codeGenerator.op_pop(REG_EAX);
[3]156
157 //※添え字上限値であることを考慮
[235]158 //inc eax
159 compiler.codeGenerator.op_inc( REG_EAX );
[3]160
161 //オブジェクトの個数をebxに一時保持
162 //※ebxは関数が呼ばれても不変
163 //mov ebx,eax
[235]164 compiler.codeGenerator.op_mov_RR( REG_EBX, REG_EAX );
[3]165
166 //imul eax,size
[235]167 compiler.codeGenerator.op_imul_RV( REG_EAX, typeSize );
[3]168
[123]169 //add eax,OBJECT_HEAD_SIZE
[235]170 compiler.codeGenerator.op_add_RV8( REG_EAX, (char)OBJECT_HEAD_SIZE );
[3]171
172 //push eax
[225]173 compiler.codeGenerator.op_push(REG_EAX);
[3]174 }
175 else{
176 //オブジェクトの個数をebxに一時保持
177 //※ebxは関数が呼ばれても不変
178 //mov ebx,1
[235]179 compiler.codeGenerator.op_mov_RV( REG_EBX, 1 );
[3]180
[123]181 //push size + OBJECT_HEAD_SIZE
[235]182 compiler.codeGenerator.op_push_V( typeSize + OBJECT_HEAD_SIZE );
[3]183 }
184
[75]185 if( baseType.IsObject() ){
186 // オブジェクト インスタンス
187 // ※DeleteはGCで処理
[3]188
[64]189 //call _System_GC_malloc_ForObject
[206]190 extern const UserProc *pSub_System_GC_malloc_ForObject;
[225]191 compiler.codeGenerator.op_call(pSub_System_GC_malloc_ForObject);
[64]192 }
193 else{
[75]194 // オブジェクトポインタ
195 // ※明示的なDeleteが必要
[3]196
[64]197 //call _System_GC_malloc_ForObjectPtr
[206]198 extern const UserProc *pSub_System_GC_malloc_ForObjectPtr;
[225]199 compiler.codeGenerator.op_call(pSub_System_GC_malloc_ForObjectPtr);
[64]200 }
201
202
[3]203 /*
204 確保されたヒープ領域のポインタ(callocの戻り値eax)をpPtrとすると、
205 pPtr[0]=オブジェクトの個数
206 pPtr[1]=オブジェクトのサイズ
207 pPtr[2]=デストラクタの関数ポインタ
[123]208 pPtr[3]=reserve
[3]209 */
210
211
212 //mov dword ptr[eax],ebx(オブジェクトの個数)
[225]213 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EBX, REG_EAX, 0, MOD_BASE );
[3]214
[235]215 //add eax,sizeof(long)
216 compiler.codeGenerator.op_add_RV8( REG_EAX, sizeof(long) );
[3]217
218 //mov ecx,TypeSize
[235]219 compiler.codeGenerator.op_mov_RV( REG_ECX, typeSize );
[3]220
[123]221 //mov dword ptr[eax],ecx(オブジェクトのサイズ)
[225]222 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_ECX, REG_EAX, 0, MOD_BASE );
[3]223
[235]224 //add eax,sizeof(long)
225 compiler.codeGenerator.op_add_RV8( REG_EAX, sizeof(long) );
[3]226
227
[349]228 const CMethod *method = pClass->GetDestructorMethod();
[64]229 if( method == NULL ) return;
[51]230
[3]231 //mov ecx,DestructorProcAddr
[244]232 compiler.codeGenerator.op_addressof( REG_ECX, &method->GetUserProc() );
[3]233
[123]234 //mov dword ptr[eax],ecx(デストラクタの関数ポインタ)
[225]235 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_ECX, 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
[123]241 // リザーブ領域
[235]242 //add eax,sizeof(long)
243 compiler.codeGenerator.op_add_RV8( REG_EAX, sizeof(long) );
[123]244
245
[319]246 //仮想関数テーブルを初期化
[349]247 if( pClass->IsExistVirtualFunctions()
248 && !pClass->IsAbstract() )
[319]249 {
[370]250 // mov ecx,com_vtbl
251 compiler.codeGenerator.op_mov_RV_com_vtbl( REG_ECX, pClass );
[319]252
253 //mov dword ptr[eax],ecx
254 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_ECX, REG_EAX, 0, MOD_BASE );
255
[370]256 // mov rcx,vtblAddress
257 compiler.codeGenerator.op_mov_RV_vtbl( REG_ECX, pClass );
258
259 //mov qword ptr[rax+sizeof(com_vtbl)],rcx
260 compiler.codeGenerator.op_mov_MR(sizeof(long),REG_ECX,REG_EAX,PTR_SIZE,MOD_BASE_DISP8);
261
[319]262 // 仮想関数になるメソッドに使用チェックをつける
[750]263 foreach( const CMethod *pMethod, pClass->GetDynamicMethods() )
[319]264 {
265 if( pMethod->IsVirtual() )
266 {
267 pMethod->GetUserProc().Using();
268 }
269 }
[750]270 foreach( const ::Interface *pInterface, pClass->GetInterfaces() )
[342]271 {
[750]272 foreach( const CMethod *pMethod, pInterface->GetDynamicMethods() )
[342]273 {
274 if( pMethod->IsVirtual() )
275 {
276 pMethod->GetUserProc().Using();
277 }
278 }
279 }
[319]280 }
281
282
[3]283 // ※ここでプッシュされた値はNew演算子の戻り値となる
284 //push eax
[225]285 compiler.codeGenerator.op_push(REG_EAX);
[3]286
287
288 /////////////////////////////////////////////////////////////////////
289
290 ////////////////////////////
291 // コンストラクタの呼び出し
292 ////////////////////////////
293
[349]294 _call_constructor(pClass,parameter,typeSize,bSomeObjects);
[64]295}
[75]296void OpcodeDelete(const char *Parameter, bool isSweeping){
297 Type tempType;
298 if( !NumOpe(Parameter,Type(),tempType) ){
299 return;
[64]300 }
[465]301 if(!( tempType.IsObjectPtr() || tempType.IsVoidPtr() )) compiler.errorMessenger.Output(122,NULL,cp);
[64]302
[3]303 //pop eax
[225]304 compiler.codeGenerator.op_pop(REG_EAX);
[3]305
306 //sub eax,sizeof(DWORD)*3
[225]307 compiler.codeGenerator.op_sub_RV8( REG_EAX, OBJECT_HEAD_SIZE );
[3]308
309 //push eax
[225]310 compiler.codeGenerator.op_push(REG_EAX);
[3]311
312
313 //mov ebx,dword ptr[eax](オブジェクトの個数)
[235]314 compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EBX, REG_EAX, 0, MOD_BASE );
[3]315
[235]316 //add eax,sizeof(long)
317 compiler.codeGenerator.op_add_RV8( REG_EAX, sizeof(long) );
[3]318
319
320 //mov esi,dword ptr[eax](オブジェクトのサイズ)
[235]321 compiler.codeGenerator.op_mov_RM( sizeof(long), REG_ESI, REG_EAX, 0, MOD_BASE );
[3]322
[235]323 //add eax,sizeof(long)
324 compiler.codeGenerator.op_add_RV8( REG_EAX, sizeof(long) );
[3]325
326
327 //mov edx,dword ptr[eax](デストラクタの関数ポインタ)
[235]328 compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EDX, REG_EAX, 0, MOD_BASE );
[3]329
[235]330 //add eax,sizeof(long)
331 compiler.codeGenerator.op_add_RV8( REG_EAX, sizeof(long) );
[3]332
333
[123]334 // リザーブ領域
[235]335 //add eax,sizeof(long)
336 compiler.codeGenerator.op_add_RV8( REG_EAX, sizeof(long) );
[123]337
338
[3]339 //mov ecx,eax
[235]340 compiler.codeGenerator.op_mov_RR( REG_ECX, REG_EAX );
[3]341
342
343 //jnzの番地
[259]344 /*extern int obp;
345 int jnz_back = obp;*/
[3]346
347 //push ecx
[225]348 compiler.codeGenerator.op_push(REG_ECX);
[3]349
350 //push edx
[225]351 compiler.codeGenerator.op_push(REG_EDX);
[3]352
353 //push ecx(Thisポインタ ※隠れた第一パラメータ)
[225]354 compiler.codeGenerator.op_push(REG_ECX);
[3]355
356 //call edx
[235]357 compiler.codeGenerator.op_call_R( REG_EDX );
[3]358
359 //pop edx
[225]360 compiler.codeGenerator.op_pop(REG_EDX);
[3]361
362 //pop ecx
[225]363 compiler.codeGenerator.op_pop(REG_ECX);
[3]364
365 //add ecx,esi
[225]366 compiler.codeGenerator.op_add_RR( REG_ECX, REG_ESI );
[3]367
368 //sub ebx,1
[225]369 compiler.codeGenerator.op_sub_RV8(REG_EBX,1);
[3]370
[250]371 //jne ↑
[259]372 //compiler.codeGenerator.op_jne( jnz_back-obp, sizeof(long), false, true );
[3]373
374
375 //////////////////////////////////////////
376 // オブジェクトメンバ変数用のメモリを解放
377 //////////////////////////////////////////
378
[64]379 if( isSweeping ){
380 //call _System_GC_free_for_SweepingDelete
[206]381 extern const UserProc *pSub_System_GC_free_for_SweepingDelete;
[225]382 compiler.codeGenerator.op_call(pSub_System_GC_free_for_SweepingDelete);
[64]383 }
384 else{
385 //call free
[206]386 extern const UserProc *pSub_free;
[225]387 compiler.codeGenerator.op_call(pSub_free);
[64]388 }
[3]389}
Note: See TracBrowser for help on using the repository browser.