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

Last change on this file since 206 was 206, checked in by dai_9181, 17 years ago

コード全体のリファクタリングを実施

File size: 8.0 KB
RevLine 
[206]1#include "stdafx.h"
2
[3]3#include "../BasicCompiler_Common/common.h"
4#include "opcode.h"
5
[75]6void _call_constructor( const CClass *pobj_c, const char *CreateParameter,int ObjectSize,BOOL bSomeObjects){
[3]7 ////////////////////////////
8 // コンストラクタの呼び出し
9 ////////////////////////////
10
11 //この関数を使用する場合は、
12 //・ebxにオブジェクトの個数
13 //・eaxに先頭ポインタ
14 //をセットしておかなければならない
15
16 int jnz_back;
17
18
19 //jnzの番地
20 jnz_back=obp;
21
[94]22 if(bSomeObjects){
23 SetError();
[3]24
[94]25 //push ebx
26 op_push(REG_EBX);
27 }
28
[3]29 // ※ここでプッシュされた値はコンストラクタのthisポインタとなる
30 //push eax
31 op_push(REG_EAX);
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
77 op_pop(REG_EAX);
78
[94]79 if(bSomeObjects){
80 //pop ebx
81 op_pop(REG_EBX);
[3]82
83 //add eax,TypeSize
84 OpBuffer[obp++]=(char)0x05;
85 *((long *)(OpBuffer+obp))=ObjectSize;
86 obp+=sizeof(long);
87
88 //sub ebx,1
89 OpBuffer[obp++]=(char)0x83;
90 OpBuffer[obp++]=(char)0xEB;
91 OpBuffer[obp++]=(char)0x01;
92
93 //jnz ↑
94 OpBuffer[obp++]=(char)0x0F;
95 OpBuffer[obp++]=(char)0x85;
96 *((long *)(OpBuffer+obp))=jnz_back-(obp+sizeof(long));
97 obp+=sizeof(long);
98 }
99}
[75]100void Operator_New( const CClass &classObj, const char *objectSizeStr, const char *parameter, const Type &baseType ){
[64]101 int typeSize = classObj.GetSize();
[3]102
[64]103 if(classObj.IsAbstract()){
[3]104 //抽象クラスだったとき
[131]105 SetError(125,classObj.GetName(),cp);
[3]106 }
107
[75]108 BOOL bSomeObjects=0;
[64]109 if(objectSizeStr[0]){
[75]110 bSomeObjects=1;
[3]111
[75]112 Type tempType;
113 NumOpe(objectSizeStr,Type(),tempType);
114 if( !tempType.IsWhole() ) SetError(49,NULL,cp);
115 ChangeTypeToLong(tempType.GetBasicType());
116
[3]117 //pop eax
118 op_pop(REG_EAX);
119
120 //※添え字上限値であることを考慮
121 //add eax,1
122 OpBuffer[obp++]=(char)0x83;
123 OpBuffer[obp++]=(char)0xC0;
124 OpBuffer[obp++]=(char)0x01;
125
126 //オブジェクトの個数をebxに一時保持
127 //※ebxは関数が呼ばれても不変
128 //mov ebx,eax
129 OpBuffer[obp++]=(char)0x8B;
130 OpBuffer[obp++]=(char)0xD8;
131
132 //imul eax,size
133 OpBuffer[obp++]=(char)0x69;
134 OpBuffer[obp++]=(char)0xC0;
[64]135 *((long *)(OpBuffer+obp))=typeSize;
[3]136 obp+=sizeof(long);
137
[123]138 //add eax,OBJECT_HEAD_SIZE
[3]139 OpBuffer[obp++]=(char)0x05;
[123]140 *((long *)(OpBuffer+obp))=OBJECT_HEAD_SIZE;
[3]141 obp+=sizeof(long);
142
143 //push eax
144 op_push(REG_EAX);
145 }
146 else{
147 //オブジェクトの個数をebxに一時保持
148 //※ebxは関数が呼ばれても不変
149 //mov ebx,1
150 OpBuffer[obp++]=(char)0xBB;
151 *((long *)(OpBuffer+obp))=1;
152 obp+=sizeof(long);
153
[123]154 //push size + OBJECT_HEAD_SIZE
[3]155 OpBuffer[obp++]=(char)0x68;
[123]156 *((long *)(OpBuffer+obp))=typeSize + OBJECT_HEAD_SIZE;
[3]157 obp+=sizeof(long);
158 }
159
[75]160 if( baseType.IsObject() ){
161 // オブジェクト インスタンス
162 // ※DeleteはGCで処理
[3]163
[64]164 //call _System_GC_malloc_ForObject
[206]165 extern const UserProc *pSub_System_GC_malloc_ForObject;
[64]166 op_call(pSub_System_GC_malloc_ForObject);
167 }
168 else{
[75]169 // オブジェクトポインタ
170 // ※明示的なDeleteが必要
[3]171
[64]172 //call _System_GC_malloc_ForObjectPtr
[206]173 extern const UserProc *pSub_System_GC_malloc_ForObjectPtr;
[64]174 op_call(pSub_System_GC_malloc_ForObjectPtr);
175 }
176
177
[3]178 /*
179 確保されたヒープ領域のポインタ(callocの戻り値eax)をpPtrとすると、
180 pPtr[0]=オブジェクトの個数
181 pPtr[1]=オブジェクトのサイズ
182 pPtr[2]=デストラクタの関数ポインタ
[123]183 pPtr[3]=reserve
[3]184 */
185
186
187 //mov dword ptr[eax],ebx(オブジェクトの個数)
188 OpBuffer[obp++]=(char)0x89;
189 OpBuffer[obp++]=(char)0x18;
190
191 //add eax,sizeof(DWORD)
192 OpBuffer[obp++]=(char)0x05;
193 *((long *)(OpBuffer+obp))=sizeof(DWORD);
194 obp+=sizeof(long);
195
196
197 //mov ecx,TypeSize
198 OpBuffer[obp++]=(char)0xB9;
[64]199 *((long *)(OpBuffer+obp))=typeSize;
[3]200 obp+=sizeof(long);
201
[123]202 //mov dword ptr[eax],ecx(オブジェクトのサイズ)
[3]203 OpBuffer[obp++]=(char)0x89;
204 OpBuffer[obp++]=(char)0x08;
205
206 //add eax,sizeof(DWORD)
207 OpBuffer[obp++]=(char)0x05;
208 *((long *)(OpBuffer+obp))=sizeof(DWORD);
209 obp+=sizeof(long);
210
211
[135]212 const CMethod *method = classObj.GetDestructorMethod();
[64]213 if( method == NULL ) return;
[51]214
[3]215 //mov ecx,DestructorProcAddr
216 OpBuffer[obp++]=(char)0xB9;
[206]217 pobj_SubAddrSchedule->add(&method->GetUserProc(),0);
218 method->GetUserProc().Using();
[3]219 obp+=sizeof(long);
220
[123]221 //mov dword ptr[eax],ecx(デストラクタの関数ポインタ)
[3]222 OpBuffer[obp++]=(char)0x89;
223 OpBuffer[obp++]=(char)0x08;
224
225 //add eax,sizeof(DWORD)
226 OpBuffer[obp++]=(char)0x05;
227 *((long *)(OpBuffer+obp))=sizeof(DWORD);
228 obp+=sizeof(long);
229
230
[123]231 // リザーブ領域
232 //add eax,sizeof(DWORD)
233 OpBuffer[obp++]=(char)0x05;
234 *((long *)(OpBuffer+obp))=sizeof(DWORD);
235 obp+=sizeof(long);
236
237
[3]238 // ※ここでプッシュされた値はNew演算子の戻り値となる
239 //push eax
240 op_push(REG_EAX);
241
242
243 /////////////////////////////////////////////////////////////////////
244
245 ////////////////////////////
246 // コンストラクタの呼び出し
247 ////////////////////////////
248
[64]249 _call_constructor(&classObj,parameter,typeSize,bSomeObjects);
250}
[75]251void OpcodeDelete(const char *Parameter, bool isSweeping){
252 Type tempType;
253 if( !NumOpe(Parameter,Type(),tempType) ){
254 return;
[64]255 }
[75]256 if(!( tempType.IsObjectPtr() || tempType.IsVoidPtr() )) SetError(122,NULL,cp);
[64]257
[3]258 //pop eax
259 op_pop(REG_EAX);
260
261 //sub eax,sizeof(DWORD)*3
[123]262 op_sub_RV8( REG_EAX, OBJECT_HEAD_SIZE );
[3]263
264 //push eax
265 op_push(REG_EAX);
266
267
268 //mov ebx,dword ptr[eax](オブジェクトの個数)
269 OpBuffer[obp++]=(char)0x8B;
270 OpBuffer[obp++]=(char)0x18;
271
272 //add eax,sizeof(DWORD)
273 OpBuffer[obp++]=(char)0x05;
274 *((long *)(OpBuffer+obp))=sizeof(DWORD);
275 obp+=sizeof(long);
276
277
278 //mov esi,dword ptr[eax](オブジェクトのサイズ)
279 OpBuffer[obp++]=(char)0x8B;
280 OpBuffer[obp++]=(char)0x30;
281
282 //add eax,sizeof(DWORD)
283 OpBuffer[obp++]=(char)0x05;
284 *((long *)(OpBuffer+obp))=sizeof(DWORD);
285 obp+=sizeof(long);
286
287
288 //mov edx,dword ptr[eax](デストラクタの関数ポインタ)
289 OpBuffer[obp++]=(char)0x8B;
290 OpBuffer[obp++]=(char)0x10;
291
292 //add eax,sizeof(DWORD)
293 OpBuffer[obp++]=(char)0x05;
294 *((long *)(OpBuffer+obp))=sizeof(DWORD);
295 obp+=sizeof(long);
296
297
[123]298 // リザーブ領域
299 //add eax,sizeof(DWORD)
300 OpBuffer[obp++]=(char)0x05;
301 *((long *)(OpBuffer+obp))=sizeof(DWORD);
302 obp+=sizeof(long);
303
304
[3]305 //mov ecx,eax
306 OpBuffer[obp++]=(char)0x8B;
307 OpBuffer[obp++]=(char)0xC8;
308
309
310 //jnzの番地
311 int jnz_back;
312 jnz_back=obp;
313
314 //push ecx
315 op_push(REG_ECX);
316
317 //push edx
318 op_push(REG_EDX);
319
320 //push ecx(Thisポインタ ※隠れた第一パラメータ)
321 op_push(REG_ECX);
322
323 //call edx
324 OpBuffer[obp++]=(char)0xFF;
325 OpBuffer[obp++]=(char)0xD2;
326
327 //pop edx
328 op_pop(REG_EDX);
329
330 //pop ecx
331 op_pop(REG_ECX);
332
333 //add ecx,esi
334 OpBuffer[obp++]=(char)0x03;
335 OpBuffer[obp++]=(char)0xCE;
336
337 //sub ebx,1
338 OpBuffer[obp++]=(char)0x83;
339 OpBuffer[obp++]=(char)0xEB;
340 OpBuffer[obp++]=(char)0x01;
341
342 //jnz ↑
343 OpBuffer[obp++]=(char)0x0F;
344 OpBuffer[obp++]=(char)0x85;
345 *((long *)(OpBuffer+obp))=jnz_back-(obp+sizeof(long));
346 obp+=sizeof(long);
347
348
349 //////////////////////////////////////////
350 // オブジェクトメンバ変数用のメモリを解放
351 //////////////////////////////////////////
352
[64]353 if( isSweeping ){
354 //call _System_GC_free_for_SweepingDelete
[206]355 extern const UserProc *pSub_System_GC_free_for_SweepingDelete;
[64]356 op_call(pSub_System_GC_free_for_SweepingDelete);
357 }
358 else{
359 //call free
[206]360 extern const UserProc *pSub_free;
[64]361 op_call(pSub_free);
362 }
[3]363}
Note: See TracBrowser for help on using the repository browser.