source: dev/trunk/abdev/BasicCompiler32/Compile_Object.cpp@ 332

Last change on this file since 332 was 332, checked in by dai_9181, 17 years ago
File size: 8.8 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 //・eaxに先頭ポインタ
16 //をセットしておかなければならない
17
18
19 const Delegate *pBackConstructingDelegate;
20 if( pobj_c->IsDelegate() )
21 {
22 // デリゲートの場合はオーバーロード解決用のグローバル変数をセットする
23 extern const Delegate *pConstructingDelegate;
24 pBackConstructingDelegate = pConstructingDelegate;
25 pConstructingDelegate = &pobj_c->GetDelegate();
26 }
27
28
29/* //jnzのジャンプ先番地
30 extern int obp;
31 int jnz_back = obp;*/
32
33 if(bSomeObjects){
34 SetError();
35
36 //push ebx
37 //compiler.codeGenerator.op_push(REG_EBX);
38 }
39
40 // ※ここでプッシュされた値はコンストラクタのthisポインタとなる
41 //push eax
42 compiler.codeGenerator.op_push(REG_EAX);
43
44
45
46 ////////////////////////
47 // オーバーロードを解決
48 ////////////////////////
49
50 std::vector<const UserProc *> subs;
51 pobj_c->GetMethods().Enum( pobj_c->GetName().c_str(), subs );
52
53 const UserProc *pUserProc;
54 if( subs.size() > 0 ){
55 //オーバーロードを解決
56 pUserProc=OverloadSolutionWithStrParam(pobj_c->GetName().c_str(),
57 subs,CreateParameter,"");
58
59 if(!pUserProc) return;
60 }
61
62 //コンストラクタを呼び出す
63 Opcode_CallProc(CreateParameter,
64 pUserProc,
65 PROCFLAG_NEW,"");
66
67 {
68 // 動的型情報をセットする
69 // obj._System_SetType( _System_TypeBase.Search( strNamespace, name ) )
70 subs.clear();
71 pobj_c->GetMethods().Enum( "_System_SetType", subs );
72 if( subs.size() == 1 ){
73 char temporary[VN_SIZE];
74 sprintf( temporary, "_System_TypeBase_Search(\"\",\"%s\"))", pobj_c->GetName().c_str() );
75
76 Opcode_CallProc(temporary,
77 subs[0],
78 PROCFLAG_NEW,"");
79 }
80 else{
81 SetError();
82 }
83
84 // インターフェイスを初期化する
85 // TODO: 実装
86 }
87
88
89
90 //pop eax
91 compiler.codeGenerator.op_pop(REG_EAX);
92
93 if(bSomeObjects){
94 /*
95 //pop ebx
96 compiler.codeGenerator.op_pop(REG_EBX);
97
98 //add eax,TypeSize
99 compiler.codeGenerator.op_add_RV( REG_EAX, ObjectSize );
100
101 //sub ebx,1
102 compiler.codeGenerator.op_sub_RV8(REG_EBX,1);
103
104 //jne ↑
105 compiler.codeGenerator.op_jne( jnz_back-obp, sizeof(long), false, true );
106 */
107 }
108
109 if( pobj_c->IsDelegate() )
110 {
111 // デリゲートの場合はオーバーロード解決用のグローバル変数を元に戻す
112 extern const Delegate *pConstructingDelegate;
113 pConstructingDelegate = pBackConstructingDelegate;
114 }
115}
116void Operator_New( const CClass &classObj, const char *objectSizeStr, const char *parameter, const Type &baseType ){
117 int typeSize = classObj.GetSize();
118
119 if(classObj.IsAbstract()){
120 //抽象クラスだったとき
121 SetError(125,classObj.GetName(),cp);
122 }
123
124 BOOL bSomeObjects=0;
125 if(objectSizeStr[0]){
126 bSomeObjects=1;
127
128 Type tempType;
129 NumOpe(objectSizeStr,Type(),tempType);
130 if( !tempType.IsWhole() ) SetError(49,NULL,cp);
131 ChangeTypeToLong(tempType.GetBasicType());
132
133 //pop eax
134 compiler.codeGenerator.op_pop(REG_EAX);
135
136 //※添え字上限値であることを考慮
137 //inc eax
138 compiler.codeGenerator.op_inc( REG_EAX );
139
140 //オブジェクトの個数をebxに一時保持
141 //※ebxは関数が呼ばれても不変
142 //mov ebx,eax
143 compiler.codeGenerator.op_mov_RR( REG_EBX, REG_EAX );
144
145 //imul eax,size
146 compiler.codeGenerator.op_imul_RV( REG_EAX, typeSize );
147
148 //add eax,OBJECT_HEAD_SIZE
149 compiler.codeGenerator.op_add_RV8( REG_EAX, (char)OBJECT_HEAD_SIZE );
150
151 //push eax
152 compiler.codeGenerator.op_push(REG_EAX);
153 }
154 else{
155 //オブジェクトの個数をebxに一時保持
156 //※ebxは関数が呼ばれても不変
157 //mov ebx,1
158 compiler.codeGenerator.op_mov_RV( REG_EBX, 1 );
159
160 //push size + OBJECT_HEAD_SIZE
161 compiler.codeGenerator.op_push_V( typeSize + OBJECT_HEAD_SIZE );
162 }
163
164 if( baseType.IsObject() ){
165 // オブジェクト インスタンス
166 // ※DeleteはGCで処理
167
168 //call _System_GC_malloc_ForObject
169 extern const UserProc *pSub_System_GC_malloc_ForObject;
170 compiler.codeGenerator.op_call(pSub_System_GC_malloc_ForObject);
171 }
172 else{
173 // オブジェクトポインタ
174 // ※明示的なDeleteが必要
175
176 //call _System_GC_malloc_ForObjectPtr
177 extern const UserProc *pSub_System_GC_malloc_ForObjectPtr;
178 compiler.codeGenerator.op_call(pSub_System_GC_malloc_ForObjectPtr);
179 }
180
181
182 /*
183 確保されたヒープ領域のポインタ(callocの戻り値eax)をpPtrとすると、
184 pPtr[0]=オブジェクトの個数
185 pPtr[1]=オブジェクトのサイズ
186 pPtr[2]=デストラクタの関数ポインタ
187 pPtr[3]=reserve
188 */
189
190
191 //mov dword ptr[eax],ebx(オブジェクトの個数)
192 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EBX, REG_EAX, 0, MOD_BASE );
193
194 //add eax,sizeof(long)
195 compiler.codeGenerator.op_add_RV8( REG_EAX, sizeof(long) );
196
197 //mov ecx,TypeSize
198 compiler.codeGenerator.op_mov_RV( REG_ECX, typeSize );
199
200 //mov dword ptr[eax],ecx(オブジェクトのサイズ)
201 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_ECX, REG_EAX, 0, MOD_BASE );
202
203 //add eax,sizeof(long)
204 compiler.codeGenerator.op_add_RV8( REG_EAX, sizeof(long) );
205
206
207 const CMethod *method = classObj.GetDestructorMethod();
208 if( method == NULL ) return;
209
210 //mov ecx,DestructorProcAddr
211 compiler.codeGenerator.op_addressof( REG_ECX, &method->GetUserProc() );
212
213 //mov dword ptr[eax],ecx(デストラクタの関数ポインタ)
214 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_ECX, REG_EAX, 0, MOD_BASE );
215
216 //add eax,sizeof(long)
217 compiler.codeGenerator.op_add_RV8( REG_EAX, sizeof(long) );
218
219
220 // リザーブ領域
221 //add eax,sizeof(long)
222 compiler.codeGenerator.op_add_RV8( REG_EAX, sizeof(long) );
223
224
225 //仮想関数テーブルを初期化
226 if( classObj.IsExistVirtualFunctions()
227 && !classObj.IsAbstract() )
228 {
229 // mov ecx,vtblAddress
230 compiler.codeGenerator.op_mov_RV_vtbl( REG_ECX, &classObj );
231
232 //mov dword ptr[eax],ecx
233 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_ECX, REG_EAX, 0, MOD_BASE );
234
235 // 仮想関数になるメソッドに使用チェックをつける
236 BOOST_FOREACH( const CMethod *pMethod, classObj.GetMethods() )
237 {
238 if( pMethod->IsVirtual() )
239 {
240 pMethod->GetUserProc().Using();
241 }
242 }
243 }
244
245
246 // ※ここでプッシュされた値はNew演算子の戻り値となる
247 //push eax
248 compiler.codeGenerator.op_push(REG_EAX);
249
250
251 /////////////////////////////////////////////////////////////////////
252
253 ////////////////////////////
254 // コンストラクタの呼び出し
255 ////////////////////////////
256
257 _call_constructor(&classObj,parameter,typeSize,bSomeObjects);
258}
259void OpcodeDelete(const char *Parameter, bool isSweeping){
260 Type tempType;
261 if( !NumOpe(Parameter,Type(),tempType) ){
262 return;
263 }
264 if(!( tempType.IsObjectPtr() || tempType.IsVoidPtr() )) SetError(122,NULL,cp);
265
266 //pop eax
267 compiler.codeGenerator.op_pop(REG_EAX);
268
269 //sub eax,sizeof(DWORD)*3
270 compiler.codeGenerator.op_sub_RV8( REG_EAX, OBJECT_HEAD_SIZE );
271
272 //push eax
273 compiler.codeGenerator.op_push(REG_EAX);
274
275
276 //mov ebx,dword ptr[eax](オブジェクトの個数)
277 compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EBX, REG_EAX, 0, MOD_BASE );
278
279 //add eax,sizeof(long)
280 compiler.codeGenerator.op_add_RV8( REG_EAX, sizeof(long) );
281
282
283 //mov esi,dword ptr[eax](オブジェクトのサイズ)
284 compiler.codeGenerator.op_mov_RM( sizeof(long), REG_ESI, REG_EAX, 0, MOD_BASE );
285
286 //add eax,sizeof(long)
287 compiler.codeGenerator.op_add_RV8( REG_EAX, sizeof(long) );
288
289
290 //mov edx,dword ptr[eax](デストラクタの関数ポインタ)
291 compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EDX, REG_EAX, 0, MOD_BASE );
292
293 //add eax,sizeof(long)
294 compiler.codeGenerator.op_add_RV8( REG_EAX, sizeof(long) );
295
296
297 // リザーブ領域
298 //add eax,sizeof(long)
299 compiler.codeGenerator.op_add_RV8( REG_EAX, sizeof(long) );
300
301
302 //mov ecx,eax
303 compiler.codeGenerator.op_mov_RR( REG_ECX, REG_EAX );
304
305
306 //jnzの番地
307 /*extern int obp;
308 int jnz_back = obp;*/
309
310 //push ecx
311 compiler.codeGenerator.op_push(REG_ECX);
312
313 //push edx
314 compiler.codeGenerator.op_push(REG_EDX);
315
316 //push ecx(Thisポインタ ※隠れた第一パラメータ)
317 compiler.codeGenerator.op_push(REG_ECX);
318
319 //call edx
320 compiler.codeGenerator.op_call_R( REG_EDX );
321
322 //pop edx
323 compiler.codeGenerator.op_pop(REG_EDX);
324
325 //pop ecx
326 compiler.codeGenerator.op_pop(REG_ECX);
327
328 //add ecx,esi
329 compiler.codeGenerator.op_add_RR( REG_ECX, REG_ESI );
330
331 //sub ebx,1
332 compiler.codeGenerator.op_sub_RV8(REG_EBX,1);
333
334 //jne ↑
335 //compiler.codeGenerator.op_jne( jnz_back-obp, sizeof(long), false, true );
336
337
338 //////////////////////////////////////////
339 // オブジェクトメンバ変数用のメモリを解放
340 //////////////////////////////////////////
341
342 if( isSweeping ){
343 //call _System_GC_free_for_SweepingDelete
344 extern const UserProc *pSub_System_GC_free_for_SweepingDelete;
345 compiler.codeGenerator.op_call(pSub_System_GC_free_for_SweepingDelete);
346 }
347 else{
348 //call free
349 extern const UserProc *pSub_free;
350 compiler.codeGenerator.op_call(pSub_free);
351 }
352}
Note: See TracBrowser for help on using the repository browser.