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

Last change on this file since 243 was 243, checked in by dai_9181, 17 years ago
File size: 8.1 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 rax,TypeSize
82 compiler.codeGenerator.op_add_RV( REG_RAX, ObjectSize );
83
84 //sub rbx,1
85 compiler.codeGenerator.op_sub_RV( sizeof(_int64), REG_RBX, 1 );
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.GetName().c_str(),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 compiler.codeGenerator.op_add_RV(REG_RAX,1);
114
115 //オブジェクトの個数をrbxに一時保持
116 //※rbxは関数が呼ばれても不変
117 //mov rbx,rax
118 compiler.codeGenerator.op_mov_RR(REG_RBX,REG_RAX);
119
120 //imul rax,size
121 compiler.codeGenerator.op_imul_RV(sizeof(_int64),REG_RAX,typeSize);
122
123 //add rax,OBJECT_HEAD_SIZE
124 compiler.codeGenerator.op_add_RV(REG_RAX,OBJECT_HEAD_SIZE);
125
126 //mov rcx,rax
127 compiler.codeGenerator.op_mov_RR(REG_RCX,REG_RAX);
128 }
129 else{
130 //オブジェクトの個数をrbxに一時保持
131 //※rbxは関数が呼ばれても不変
132 //mov rbx,1
133 compiler.codeGenerator.op_mov_RV(sizeof(_int64),REG_RBX,1);
134
135 //mov rcx,typeSize+OBJECT_HEAD_SIZE
136 compiler.codeGenerator.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 const UserProc *pSub_System_GC_malloc_ForObject;
145 compiler.codeGenerator.op_call(pSub_System_GC_malloc_ForObject);
146 }
147 else{
148 // オブジェクトポインタ
149 // ※明示的なDeleteが必要
150
151 //call _System_GC_malloc_ForObjectPtr
152 extern const UserProc *pSub_System_GC_malloc_ForObjectPtr;
153 compiler.codeGenerator.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 compiler.codeGenerator.op_mov_MR(sizeof(_int64),REG_RBX,REG_RAX,0,MOD_BASE);
169
170 //add rax,PTR_SIZE
171 compiler.codeGenerator.op_add_RV(REG_RAX,PTR_SIZE);
172
173
174 //mov qword ptr[rax],typeSize(オブジェクトのサイズ)
175 compiler.codeGenerator.op_mov_MV(sizeof(_int64),REG_RAX,0, Schedule::None, NON_OFFSET,typeSize);
176
177 //add rax,PTR_SIZE
178 compiler.codeGenerator.op_add_RV(REG_RAX,PTR_SIZE);
179
180
181 const CMethod *method = classObj.GetDestructorMethod();
182 if( method == NULL ) return;
183
184 //mov rcx,DestructorProcAddr(デストラクタの関数ポインタ)
185 compiler.codeGenerator.op_mov_RV(sizeof(_int64),REG_RCX,0);
186 obp-=sizeof(long);
187 pobj_SubAddrSchedule->add(&method->GetUserProc(),0);
188 method->GetUserProc().Using();
189 obp+=sizeof(long);
190
191 //mov qword ptr[rax],rcx
192 compiler.codeGenerator.op_mov_MR(sizeof(_int64),REG_RCX,REG_RAX,0,MOD_BASE);
193
194 //add rax,PTR_SIZE
195 compiler.codeGenerator.op_add_RV(REG_RAX,PTR_SIZE);
196
197
198 // リザーブ領域
199 //add rax,PTR_SIZE
200 compiler.codeGenerator.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 compiler.codeGenerator.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 compiler.codeGenerator.op_mov_RM(sizeof(_int64),REG_RBX,REG_RAX,0,MOD_BASE);
237
238 //add rax,PTR_SIZE
239 compiler.codeGenerator.op_add_RV(REG_RAX,PTR_SIZE);
240
241
242 //mov rsi,qword ptr[rax](オブジェクトのサイズ)
243 compiler.codeGenerator.op_mov_RM(sizeof(_int64),REG_RSI,REG_RAX,0,MOD_BASE);
244
245 //add rax,PTR_SIZE
246 compiler.codeGenerator.op_add_RV(REG_RAX,PTR_SIZE);
247
248
249 //mov rdi,qword ptr[rax](デストラクタの関数ポインタ)
250 compiler.codeGenerator.op_mov_RM(sizeof(_int64),REG_RDI,REG_RAX,0,MOD_BASE);
251
252 //add rax,PTR_SIZE
253 compiler.codeGenerator.op_add_RV(REG_RAX,PTR_SIZE);
254
255
256 // リザーブ領域
257 //add rax,PTR_SIZE
258 compiler.codeGenerator.op_add_RV(REG_RAX,PTR_SIZE);
259
260
261 //mov rcx,rax
262 compiler.codeGenerator.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 compiler.codeGenerator.PutOld(
274 (char)0xFF,
275 (char)0xD7
276 );
277
278 //mov rcx,qword ptr[rsp+offset] ※スタックフレームを利用
279 pobj_sf->pop(REG_RCX);
280
281 //add rcx,rsi
282 compiler.codeGenerator.op_add_RR(REG_RCX,REG_RSI);
283
284 //sub rbx,1
285 compiler.codeGenerator.op_sub_RV(sizeof(_int64),REG_RBX,1);
286
287 //jnz ↑
288 OpBuffer[obp++]=(char)0x0F;
289 OpBuffer[obp++]=(char)0x85;
290 *((long *)(OpBuffer+obp))=jnz_back-(obp+sizeof(long));
291 obp+=sizeof(long);
292
293
294 //////////////////////////////////////////
295 // オブジェクトメンバ変数用のメモリを解放
296 //////////////////////////////////////////
297
298 //mov rcx,qword ptr[rsp+offset] ※スタックフレームを利用
299 pobj_sf->pop(REG_RCX);
300
301 if( isSweeping ){
302 //call _System_GC_free_for_SweepingDelete
303 extern const UserProc *pSub_System_GC_free_for_SweepingDelete;
304 compiler.codeGenerator.op_call(pSub_System_GC_free_for_SweepingDelete);
305 }
306 else{
307 //call free
308 extern const UserProc *pSub_free;
309 compiler.codeGenerator.op_call(pSub_free);
310 }
311}
Note: See TracBrowser for help on using the repository browser.