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

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

GCのバグをいくつか修正

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