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