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

Last change on this file since 349 was 349, checked in by dai_9181, 17 years ago

インターフェイス実装中…

File size: 8.7 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 &objClass, const char *objectSizeStr, const char *parameter, const Type &baseType )
100{
101 const CClass *pClass = &objClass;
102 int typeSize = pClass->GetSize();
103
104 if( pClass->IsInterface() )
105 {
106 pClass = compiler.GetObjectModule().meta.GetClasses().GetInterfaceInfoClassPtr();
107 }
108
109 if(pClass->IsAbstract()){
110 //抽象クラスだったとき
111 SetError(125,pClass->GetName(),cp);
112 }
113
114 BOOL bSomeObjects=0;
115 if(objectSizeStr[0]){
116 bSomeObjects=1;
117
118 Type tempType;
119 NumOpe(objectSizeStr,Type(),tempType);
120 if( !tempType.IsWhole() ) SetError(49,NULL,cp);
121 ChangeTypeToLong(tempType.GetBasicType());
122
123 //pop eax
124 compiler.codeGenerator.op_pop(REG_EAX);
125
126 //※添え字上限値であることを考慮
127 //inc eax
128 compiler.codeGenerator.op_inc( REG_EAX );
129
130 //オブジェクトの個数をebxに一時保持
131 //※ebxは関数が呼ばれても不変
132 //mov ebx,eax
133 compiler.codeGenerator.op_mov_RR( REG_EBX, REG_EAX );
134
135 //imul eax,size
136 compiler.codeGenerator.op_imul_RV( REG_EAX, typeSize );
137
138 //add eax,OBJECT_HEAD_SIZE
139 compiler.codeGenerator.op_add_RV8( REG_EAX, (char)OBJECT_HEAD_SIZE );
140
141 //push eax
142 compiler.codeGenerator.op_push(REG_EAX);
143 }
144 else{
145 //オブジェクトの個数をebxに一時保持
146 //※ebxは関数が呼ばれても不変
147 //mov ebx,1
148 compiler.codeGenerator.op_mov_RV( REG_EBX, 1 );
149
150 //push size + OBJECT_HEAD_SIZE
151 compiler.codeGenerator.op_push_V( typeSize + OBJECT_HEAD_SIZE );
152 }
153
154 if( baseType.IsObject() ){
155 // オブジェクト インスタンス
156 // ※DeleteはGCで処理
157
158 //call _System_GC_malloc_ForObject
159 extern const UserProc *pSub_System_GC_malloc_ForObject;
160 compiler.codeGenerator.op_call(pSub_System_GC_malloc_ForObject);
161 }
162 else{
163 // オブジェクトポインタ
164 // ※明示的なDeleteが必要
165
166 //call _System_GC_malloc_ForObjectPtr
167 extern const UserProc *pSub_System_GC_malloc_ForObjectPtr;
168 compiler.codeGenerator.op_call(pSub_System_GC_malloc_ForObjectPtr);
169 }
170
171
172 /*
173 確保されたヒープ領域のポインタ(callocの戻り値eax)をpPtrとすると、
174 pPtr[0]=オブジェクトの個数
175 pPtr[1]=オブジェクトのサイズ
176 pPtr[2]=デストラクタの関数ポインタ
177 pPtr[3]=reserve
178 */
179
180
181 //mov dword ptr[eax],ebx(オブジェクトの個数)
182 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EBX, REG_EAX, 0, MOD_BASE );
183
184 //add eax,sizeof(long)
185 compiler.codeGenerator.op_add_RV8( REG_EAX, sizeof(long) );
186
187 //mov ecx,TypeSize
188 compiler.codeGenerator.op_mov_RV( REG_ECX, typeSize );
189
190 //mov dword ptr[eax],ecx(オブジェクトのサイズ)
191 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_ECX, REG_EAX, 0, MOD_BASE );
192
193 //add eax,sizeof(long)
194 compiler.codeGenerator.op_add_RV8( REG_EAX, sizeof(long) );
195
196
197 const CMethod *method = pClass->GetDestructorMethod();
198 if( method == NULL ) return;
199
200 //mov ecx,DestructorProcAddr
201 compiler.codeGenerator.op_addressof( REG_ECX, &method->GetUserProc() );
202
203 //mov dword ptr[eax],ecx(デストラクタの関数ポインタ)
204 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_ECX, REG_EAX, 0, MOD_BASE );
205
206 //add eax,sizeof(long)
207 compiler.codeGenerator.op_add_RV8( REG_EAX, sizeof(long) );
208
209
210 // リザーブ領域
211 //add eax,sizeof(long)
212 compiler.codeGenerator.op_add_RV8( REG_EAX, sizeof(long) );
213
214
215 //仮想関数テーブルを初期化
216 if( pClass->IsExistVirtualFunctions()
217 && !pClass->IsAbstract() )
218 {
219 // mov ecx,vtblAddress
220 compiler.codeGenerator.op_mov_RV_vtbl( REG_ECX, pClass );
221
222 //mov dword ptr[eax],ecx
223 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_ECX, REG_EAX, 0, MOD_BASE );
224
225 // 仮想関数になるメソッドに使用チェックをつける
226 BOOST_FOREACH( const CMethod *pMethod, pClass->GetDynamicMethods() )
227 {
228 if( pMethod->IsVirtual() )
229 {
230 pMethod->GetUserProc().Using();
231 }
232 }
233 BOOST_FOREACH( const ::Interface *pInterface, pClass->GetInterfaces() )
234 {
235 BOOST_FOREACH( const CMethod *pMethod, pInterface->GetDynamicMethods() )
236 {
237 if( pMethod->IsVirtual() )
238 {
239 pMethod->GetUserProc().Using();
240 }
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(pClass,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.