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

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