source: dev/BasicCompiler32/Compile_Object.cpp @ 123

Last change on this file since 123 was 123, checked in by dai_9181, 16 years ago

オブジェクトの先頭バッファのサイズを4ポインタ分に拡張した(偶数個数なところがキモ)。

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