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

Last change on this file since 299 was 263, checked in by dai_9181, 17 years ago
File size: 7.9 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
19 //jnzの番地
20 /*extern int obp;
21 int jnz_back = obp;*/
22
23 if(bSomeObjects){
24 SetError();
25 //mov qword ptr[rsp+offset],rbx ※スタックフレームを利用
26 //pobj_sf->push(REG_RBX);
27
28 // ※ここでプッシュされた値はコンストラクタのthisポインタとなる
29 //mov qword ptr[rsp+offset],rax ※スタックフレームを利用
30 //pobj_sf->push(REG_RAX);
31 }
32
33
34 ////////////////////////
35 // オーバーロードを解決
36 ////////////////////////
37
38 std::vector<const UserProc *> subs;
39 pobj_c->GetMethods().Enum( pobj_c->GetName().c_str(), subs );
40
41 const UserProc *pUserProc;
42 if( subs.size() > 0 ){
43 //オーバーロードを解決
44 pUserProc=OverloadSolutionWithStrParam(pobj_c->GetName().c_str(),
45 subs,CreateParameter,"");
46
47 if(!pUserProc) return;
48 }
49
50 //コンストラクタを呼び出す
51 Opcode_CallProc(CreateParameter,
52 pUserProc,
53 PROCFLAG_NEW,"",0);
54
55 {
56 // 動的型情報をセットする
57 // obj._System_SetType( _System_TypeBase.Search( strNamespace, name ) )
58 subs.clear();
59 pobj_c->GetMethods().Enum( "_System_SetType", subs );
60 if( subs.size() == 1 ){
61 char temporary[VN_SIZE];
62 sprintf( temporary, "_System_TypeBase_Search(\"\",\"%s\"))", pobj_c->GetName().c_str() );
63
64 Opcode_CallProc(temporary,
65 subs[0],
66 PROCFLAG_NEW,"",0);
67 }
68 else{
69 SetError();
70 }
71 }
72
73 if(bSomeObjects){
74 /*
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 compiler.codeGenerator.op_jne( jnz_back-obp, sizeof(long), false, true );
89 */
90 }
91}
92void Operator_New( const CClass &classObj, const char *objectSizeStr, const char *parameter, const Type &baseType ){
93 int typeSize = classObj.GetSize();
94
95 if(classObj.IsAbstract()){
96 //抽象クラスだったとき
97 SetError(125,classObj.GetName().c_str(),cp);
98 }
99
100 BOOL bSomeObjects=0;
101 if(objectSizeStr[0]){
102 bSomeObjects=1;
103
104 int reg=REG_RAX;
105 Type tempType;
106 NumOpe(&reg,objectSizeStr,Type(),tempType);
107 if( !tempType.IsWhole() ) SetError(49,NULL,cp);
108
109 //※添え字上限値であることを考慮
110 //add rax,1
111 compiler.codeGenerator.op_add_RV(REG_RAX,1);
112
113 //オブジェクトの個数をrbxに一時保持
114 //※rbxは関数が呼ばれても不変
115 //mov rbx,rax
116 compiler.codeGenerator.op_mov_RR(REG_RBX,REG_RAX);
117
118 //imul rax,size
119 compiler.codeGenerator.op_imul_RV(sizeof(_int64),REG_RAX,typeSize);
120
121 //add rax,OBJECT_HEAD_SIZE
122 compiler.codeGenerator.op_add_RV(REG_RAX,OBJECT_HEAD_SIZE);
123
124 //mov rcx,rax
125 compiler.codeGenerator.op_mov_RR(REG_RCX,REG_RAX);
126 }
127 else{
128 //オブジェクトの個数をrbxに一時保持
129 //※rbxは関数が呼ばれても不変
130 //mov rbx,1
131 compiler.codeGenerator.op_mov_RV(sizeof(_int64),REG_RBX,1);
132
133 //mov rcx,typeSize+OBJECT_HEAD_SIZE
134 compiler.codeGenerator.op_mov_RV(sizeof(_int64),REG_RCX,typeSize+OBJECT_HEAD_SIZE);
135 }
136
137 if( baseType.IsObject() ){
138 // オブジェクト インスタンス
139 // ※DeleteはGCで処理
140
141 //call _System_GC_malloc_ForObject
142 extern const UserProc *pSub_System_GC_malloc_ForObject;
143 compiler.codeGenerator.op_call(pSub_System_GC_malloc_ForObject);
144 }
145 else{
146 // オブジェクトポインタ
147 // ※明示的なDeleteが必要
148
149 //call _System_GC_malloc_ForObjectPtr
150 extern const UserProc *pSub_System_GC_malloc_ForObjectPtr;
151 compiler.codeGenerator.op_call(pSub_System_GC_malloc_ForObjectPtr);
152 }
153
154
155 /*
156 確保されたヒープ領域のポインタ(callocの戻り値eax)をpPtrとすると、
157 pPtr-=OBJECT_HEAD_SIZE ... ( sizeof(DWORD)*4 )
158 pPtr[0]=オブジェクトの個数
159 pPtr[1]=オブジェクトのサイズ
160 pPtr[2]=デストラクタの関数ポインタ
161 pPtr[3]=reserve
162 */
163
164
165 //mov qword ptr[rax],rbx(オブジェクトの個数)
166 compiler.codeGenerator.op_mov_MR(sizeof(_int64),REG_RBX,REG_RAX,0,MOD_BASE);
167
168 //add rax,PTR_SIZE
169 compiler.codeGenerator.op_add_RV(REG_RAX,PTR_SIZE);
170
171
172 //mov qword ptr[rax],typeSize(オブジェクトのサイズ)
173 compiler.codeGenerator.op_mov_MV(sizeof(_int64),REG_RAX,0, Schedule::None, false, NON_OFFSET,typeSize);
174
175 //add rax,PTR_SIZE
176 compiler.codeGenerator.op_add_RV(REG_RAX,PTR_SIZE);
177
178
179 const CMethod *method = classObj.GetDestructorMethod();
180 if( method == NULL ) return;
181
182 //mov rcx,DestructorProcAddr(デストラクタの関数ポインタ)
183 compiler.codeGenerator.op_addressof( REG_RCX, &method->GetUserProc() );
184
185 //mov qword ptr[rax],rcx
186 compiler.codeGenerator.op_mov_MR(sizeof(_int64),REG_RCX,REG_RAX,0,MOD_BASE);
187
188 //add rax,PTR_SIZE
189 compiler.codeGenerator.op_add_RV(REG_RAX,PTR_SIZE);
190
191
192 // リザーブ領域
193 //add rax,PTR_SIZE
194 compiler.codeGenerator.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,OBJECT_HEAD_SIZE
223 compiler.codeGenerator.op_sub_RV(sizeof(_int64),REG_RAX,OBJECT_HEAD_SIZE);
224
225 //mov qword ptr[rsp+offset],rax ※スタックフレームを利用
226 pobj_sf->push(REG_RAX);
227
228
229 //mov rbx,qword ptr[rax](オブジェクトの個数)
230 compiler.codeGenerator.op_mov_RM(sizeof(_int64),REG_RBX,REG_RAX,0,MOD_BASE);
231
232 //add rax,PTR_SIZE
233 compiler.codeGenerator.op_add_RV(REG_RAX,PTR_SIZE);
234
235
236 //mov rsi,qword ptr[rax](オブジェクトのサイズ)
237 compiler.codeGenerator.op_mov_RM(sizeof(_int64),REG_RSI,REG_RAX,0,MOD_BASE);
238
239 //add rax,PTR_SIZE
240 compiler.codeGenerator.op_add_RV(REG_RAX,PTR_SIZE);
241
242
243 //mov rdi,qword ptr[rax](デストラクタの関数ポインタ)
244 compiler.codeGenerator.op_mov_RM(sizeof(_int64),REG_RDI,REG_RAX,0,MOD_BASE);
245
246 //add rax,PTR_SIZE
247 compiler.codeGenerator.op_add_RV(REG_RAX,PTR_SIZE);
248
249
250 // リザーブ領域
251 //add rax,PTR_SIZE
252 compiler.codeGenerator.op_add_RV(REG_RAX,PTR_SIZE);
253
254
255 //mov rcx,rax
256 compiler.codeGenerator.op_mov_RR(REG_RCX,REG_RAX);
257
258
259 //jnzの番地
260 //int jnz_back=obp;
261
262 //mov qword ptr[rsp+offset],rcx ※スタックフレームを利用
263 pobj_sf->push(REG_RCX);
264
265 //call rdi
266 compiler.codeGenerator.PutOld(
267 (char)0xFF,
268 (char)0xD7
269 );
270
271 //mov rcx,qword ptr[rsp+offset] ※スタックフレームを利用
272 pobj_sf->pop(REG_RCX);
273
274 //add rcx,rsi
275 compiler.codeGenerator.op_add_RR(REG_RCX,REG_RSI);
276
277 //sub rbx,1
278 compiler.codeGenerator.op_sub_RV(sizeof(_int64),REG_RBX,1);
279
280 //jnz ↑
281 //compiler.codeGenerator.op_jne( jnz_back-obp, sizeof(long), false, true );
282
283
284 //////////////////////////////////////////
285 // オブジェクトメンバ変数用のメモリを解放
286 //////////////////////////////////////////
287
288 //mov rcx,qword ptr[rsp+offset] ※スタックフレームを利用
289 pobj_sf->pop(REG_RCX);
290
291 if( isSweeping ){
292 //call _System_GC_free_for_SweepingDelete
293 extern const UserProc *pSub_System_GC_free_for_SweepingDelete;
294 compiler.codeGenerator.op_call(pSub_System_GC_free_for_SweepingDelete);
295 }
296 else{
297 //call free
298 extern const UserProc *pSub_free;
299 compiler.codeGenerator.op_call(pSub_free);
300 }
301}
Note: See TracBrowser for help on using the repository browser.