source: dev/trunk/ab5.0/abdev/compiler_x86/Compile_Object.cpp@ 715

Last change on this file since 715 was 702, checked in by dai_9181, 16 years ago
  • コンストラクタ、デストラクタの直接呼出しをエラー扱いにした。
    • コンストラクタ … New演算子にて、呼ばれるものとする。また、コンストラクタの1ステップ目にて、基底クラスのコンストラクタ呼び出しを許可する。
    • デストラクタ … Delete演算子にて呼ばれるものとする。また、デストラクタ内にて、基底クラスのコンストラクタ呼び出しが自動的に行われるものとする。

※まずは32bit版のみ対応。速やかに64bit版にマージすること。

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