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

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

Selectステートメントのスケジュール機構をリファクタリング

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