source: dev/BasicCompiler64/Compile_Object.cpp@ 94

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

New[]を禁止した。
一部の動的型情報が生成されないバグを修正。
As演算子によるダウンキャストを許可(プログラム的なチェックはまだ走っていない)

File size: 7.1 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,PTR_SIZE*3
124 op_add_RV(REG_RAX,PTR_SIZE*3);
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+PTR_SIZE*3
136 op_mov_RV(sizeof(_int64),REG_RCX,typeSize+PTR_SIZE*3);
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-=sizeof(DWORD)*3
160 pPtr[0]=オブジェクトの個数
161 pPtr[1]=オブジェクトのサイズ
162 pPtr[2]=デストラクタの関数ポインタ
163 */
164
165
166 //mov qword ptr[rax],rbx(オブジェクトの個数)
167 op_mov_MR(sizeof(_int64),REG_RBX,REG_RAX,0,MOD_BASE);
168
169 //add rax,PTR_SIZE
170 op_add_RV(REG_RAX,PTR_SIZE);
171
172
173 //mov qword ptr[rax],typeSize(オブジェクトのサイズ)
174 op_mov_MV(sizeof(_int64),REG_RAX,0,NON_OFFSET,typeSize);
175
176 //add rax,PTR_SIZE
177 op_add_RV(REG_RAX,PTR_SIZE);
178
179
180 CMethod *method = classObj.GetDestructorMethod();
181 if( method == NULL ) return;
182
183 //mov rcx,DestructorProcAddr
184 op_mov_RV(sizeof(_int64),REG_RCX,0);
185 obp-=sizeof(long);
186 pobj_SubAddrSchedule->add(method->pUserProc,0);
187 method->pUserProc->Using();
188 obp+=sizeof(long);
189
190 //mov qword ptr[rax],rcx
191 op_mov_MR(sizeof(_int64),REG_RCX,REG_RAX,0,MOD_BASE);
192
193 //add rax,PTR_SIZE
194 op_add_RV(REG_RAX,PTR_SIZE);
195
196
197 // ※ここでプッシュされた値はNew演算子の戻り値となる
198 //mov qword ptr[rsp+offset],rax ※スタックフレームを利用
199 pobj_sf->push(REG_RAX);
200
201
202 /////////////////////////////////////////////////////////////////////
203
204 ////////////////////////////
205 // コンストラクタの呼び出し
206 ////////////////////////////
207
208 _call_constructor(&classObj,parameter,typeSize,bSomeObjects);
209
210
211 //mov rax,qword ptr[rsp+offset] ※スタックフレームを利用
212 pobj_sf->pop(REG_RAX);
213}
214void OpcodeDelete(const char *Parameter, bool isSweeping){
215 int reg=REG_RAX;
216 Type tempType;
217 if( !NumOpe(&reg,Parameter,Type(),tempType) ){
218 return;
219 }
220 if(!( tempType.IsObjectPtr() || tempType.IsVoidPtr() )) SetError(122,NULL,cp);
221
222 //sub rax,PTR_SIZE*3
223 op_sub_RV(sizeof(_int64),REG_RAX,PTR_SIZE*3);
224
225 //mov qword ptr[rsp+offset],rax ※スタックフレームを利用
226 pobj_sf->push(REG_RAX);
227
228
229 //mov rbx,qword ptr[rax](オブジェクトの個数)
230 op_mov_RM(sizeof(_int64),REG_RBX,REG_RAX,0,MOD_BASE);
231
232 //add rax,PTR_SIZE
233 op_add_RV(REG_RAX,PTR_SIZE);
234
235
236 //mov rsi,qword ptr[rax](オブジェクトのサイズ)
237 op_mov_RM(sizeof(_int64),REG_RSI,REG_RAX,0,MOD_BASE);
238
239 //add rax,PTR_SIZE
240 op_add_RV(REG_RAX,PTR_SIZE);
241
242
243 //mov rdi,qword ptr[rax](デストラクタの関数ポインタ)
244 op_mov_RM(sizeof(_int64),REG_RDI,REG_RAX,0,MOD_BASE);
245
246 //add rax,PTR_SIZE
247 op_add_RV(REG_RAX,PTR_SIZE);
248
249
250 //mov rcx,rax
251 op_mov_RR(REG_RCX,REG_RAX);
252
253
254 //jnzの番地
255 int jnz_back;
256 jnz_back=obp;
257
258 //mov qword ptr[rsp+offset],rcx ※スタックフレームを利用
259 pobj_sf->push(REG_RCX);
260
261 //call rdi
262 OpBuffer[obp++]=(char)0xFF;
263 OpBuffer[obp++]=(char)0xD7;
264
265 //mov rcx,qword ptr[rsp+offset] ※スタックフレームを利用
266 pobj_sf->pop(REG_RCX);
267
268 //add rcx,rsi
269 op_add64_reg(REG_RCX,REG_RSI);
270
271 //sub rbx,1
272 op_sub_RV(sizeof(_int64),REG_RBX,1);
273
274 //jnz ↑
275 OpBuffer[obp++]=(char)0x0F;
276 OpBuffer[obp++]=(char)0x85;
277 *((long *)(OpBuffer+obp))=jnz_back-(obp+sizeof(long));
278 obp+=sizeof(long);
279
280
281 //////////////////////////////////////////
282 // オブジェクトメンバ変数用のメモリを解放
283 //////////////////////////////////////////
284
285 //mov rcx,qword ptr[rsp+offset] ※スタックフレームを利用
286 pobj_sf->pop(REG_RCX);
287
288 if( isSweeping ){
289 //call _System_GC_free_for_SweepingDelete
290 extern UserProc *pSub_System_GC_free_for_SweepingDelete;
291 op_call(pSub_System_GC_free_for_SweepingDelete);
292 }
293 else{
294 //call free
295 extern UserProc *pSub_free;
296 op_call(pSub_free);
297 }
298}
Note: See TracBrowser for help on using the repository browser.