source: dev/BasicCompiler64/Compile_Object.cpp@ 89

Last change on this file since 89 was 75, checked in by dai_9181, 18 years ago

TYPEINFO→Typeへのリファクタリングを実施。64bitはほぼ完了。32bitが全般的に未完成。

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