source: dev/trunk/abdev/BasicCompiler64/Compile_Object.cpp@ 227

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