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

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

CodeGeneratorクラスのベースを実装

File size: 8.4 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 OpBuffer[obp++]=(char)0x05;
87 *((long *)(OpBuffer+obp))=ObjectSize;
88 obp+=sizeof(long);
89
90 //sub ebx,1
91 compiler.codeGenerator.op_sub_RV8(REG_EBX,1);
92
93 //jnz ↑
94 OpBuffer[obp++]=(char)0x0F;
95 OpBuffer[obp++]=(char)0x85;
96 *((long *)(OpBuffer+obp))=jnz_back-(obp+sizeof(long));
97 obp+=sizeof(long);
98 }
99}
100void Operator_New( const CClass &classObj, const char *objectSizeStr, const char *parameter, const Type &baseType ){
101 int typeSize = classObj.GetSize();
102
103 if(classObj.IsAbstract()){
104 //抽象クラスだったとき
105 SetError(125,classObj.GetName(),cp);
106 }
107
108 BOOL bSomeObjects=0;
109 if(objectSizeStr[0]){
110 bSomeObjects=1;
111
112 Type tempType;
113 NumOpe(objectSizeStr,Type(),tempType);
114 if( !tempType.IsWhole() ) SetError(49,NULL,cp);
115 ChangeTypeToLong(tempType.GetBasicType());
116
117 //pop eax
118 compiler.codeGenerator.op_pop(REG_EAX);
119
120 //※添え字上限値であることを考慮
121 //add eax,1
122 OpBuffer[obp++]=(char)0x83;
123 OpBuffer[obp++]=(char)0xC0;
124 OpBuffer[obp++]=(char)0x01;
125
126 //オブジェクトの個数をebxに一時保持
127 //※ebxは関数が呼ばれても不変
128 //mov ebx,eax
129 OpBuffer[obp++]=(char)0x8B;
130 OpBuffer[obp++]=(char)0xD8;
131
132 //imul eax,size
133 OpBuffer[obp++]=(char)0x69;
134 OpBuffer[obp++]=(char)0xC0;
135 *((long *)(OpBuffer+obp))=typeSize;
136 obp+=sizeof(long);
137
138 //add eax,OBJECT_HEAD_SIZE
139 OpBuffer[obp++]=(char)0x05;
140 *((long *)(OpBuffer+obp))=OBJECT_HEAD_SIZE;
141 obp+=sizeof(long);
142
143 //push eax
144 compiler.codeGenerator.op_push(REG_EAX);
145 }
146 else{
147 //オブジェクトの個数をebxに一時保持
148 //※ebxは関数が呼ばれても不変
149 //mov ebx,1
150 OpBuffer[obp++]=(char)0xBB;
151 *((long *)(OpBuffer+obp))=1;
152 obp+=sizeof(long);
153
154 //push size + OBJECT_HEAD_SIZE
155 OpBuffer[obp++]=(char)0x68;
156 *((long *)(OpBuffer+obp))=typeSize + OBJECT_HEAD_SIZE;
157 obp+=sizeof(long);
158 }
159
160 if( baseType.IsObject() ){
161 // オブジェクト インスタンス
162 // ※DeleteはGCで処理
163
164 //call _System_GC_malloc_ForObject
165 extern const UserProc *pSub_System_GC_malloc_ForObject;
166 compiler.codeGenerator.op_call(pSub_System_GC_malloc_ForObject);
167 }
168 else{
169 // オブジェクトポインタ
170 // ※明示的なDeleteが必要
171
172 //call _System_GC_malloc_ForObjectPtr
173 extern const UserProc *pSub_System_GC_malloc_ForObjectPtr;
174 compiler.codeGenerator.op_call(pSub_System_GC_malloc_ForObjectPtr);
175 }
176
177
178 /*
179 確保されたヒープ領域のポインタ(callocの戻り値eax)をpPtrとすると、
180 pPtr[0]=オブジェクトの個数
181 pPtr[1]=オブジェクトのサイズ
182 pPtr[2]=デストラクタの関数ポインタ
183 pPtr[3]=reserve
184 */
185
186
187 //mov dword ptr[eax],ebx(オブジェクトの個数)
188 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EBX, REG_EAX, 0, MOD_BASE );
189
190 //add eax,sizeof(DWORD)
191 OpBuffer[obp++]=(char)0x05;
192 *((long *)(OpBuffer+obp))=sizeof(DWORD);
193 obp+=sizeof(long);
194
195
196 //mov ecx,TypeSize
197 OpBuffer[obp++]=(char)0xB9;
198 *((long *)(OpBuffer+obp))=typeSize;
199 obp+=sizeof(long);
200
201 //mov dword ptr[eax],ecx(オブジェクトのサイズ)
202 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_ECX, REG_EAX, 0, MOD_BASE );
203
204 //add eax,sizeof(DWORD)
205 OpBuffer[obp++]=(char)0x05;
206 *((long *)(OpBuffer+obp))=sizeof(DWORD);
207 obp+=sizeof(long);
208
209
210 const CMethod *method = classObj.GetDestructorMethod();
211 if( method == NULL ) return;
212
213 //mov ecx,DestructorProcAddr
214 OpBuffer[obp++]=(char)0xB9;
215 pobj_SubAddrSchedule->add(&method->GetUserProc(),0);
216 method->GetUserProc().Using();
217 obp+=sizeof(long);
218
219 //mov dword ptr[eax],ecx(デストラクタの関数ポインタ)
220 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_ECX, REG_EAX, 0, MOD_BASE );
221
222 //add eax,sizeof(DWORD)
223 OpBuffer[obp++]=(char)0x05;
224 *((long *)(OpBuffer+obp))=sizeof(DWORD);
225 obp+=sizeof(long);
226
227
228 // リザーブ領域
229 //add eax,sizeof(DWORD)
230 OpBuffer[obp++]=(char)0x05;
231 *((long *)(OpBuffer+obp))=sizeof(DWORD);
232 obp+=sizeof(long);
233
234
235 // ※ここでプッシュされた値はNew演算子の戻り値となる
236 //push eax
237 compiler.codeGenerator.op_push(REG_EAX);
238
239
240 /////////////////////////////////////////////////////////////////////
241
242 ////////////////////////////
243 // コンストラクタの呼び出し
244 ////////////////////////////
245
246 _call_constructor(&classObj,parameter,typeSize,bSomeObjects);
247}
248void OpcodeDelete(const char *Parameter, bool isSweeping){
249 Type tempType;
250 if( !NumOpe(Parameter,Type(),tempType) ){
251 return;
252 }
253 if(!( tempType.IsObjectPtr() || tempType.IsVoidPtr() )) SetError(122,NULL,cp);
254
255 //pop eax
256 compiler.codeGenerator.op_pop(REG_EAX);
257
258 //sub eax,sizeof(DWORD)*3
259 compiler.codeGenerator.op_sub_RV8( REG_EAX, OBJECT_HEAD_SIZE );
260
261 //push eax
262 compiler.codeGenerator.op_push(REG_EAX);
263
264
265 //mov ebx,dword ptr[eax](オブジェクトの個数)
266 OpBuffer[obp++]=(char)0x8B;
267 OpBuffer[obp++]=(char)0x18;
268
269 //add eax,sizeof(DWORD)
270 OpBuffer[obp++]=(char)0x05;
271 *((long *)(OpBuffer+obp))=sizeof(DWORD);
272 obp+=sizeof(long);
273
274
275 //mov esi,dword ptr[eax](オブジェクトのサイズ)
276 OpBuffer[obp++]=(char)0x8B;
277 OpBuffer[obp++]=(char)0x30;
278
279 //add eax,sizeof(DWORD)
280 OpBuffer[obp++]=(char)0x05;
281 *((long *)(OpBuffer+obp))=sizeof(DWORD);
282 obp+=sizeof(long);
283
284
285 //mov edx,dword ptr[eax](デストラクタの関数ポインタ)
286 OpBuffer[obp++]=(char)0x8B;
287 OpBuffer[obp++]=(char)0x10;
288
289 //add eax,sizeof(DWORD)
290 OpBuffer[obp++]=(char)0x05;
291 *((long *)(OpBuffer+obp))=sizeof(DWORD);
292 obp+=sizeof(long);
293
294
295 // リザーブ領域
296 //add eax,sizeof(DWORD)
297 OpBuffer[obp++]=(char)0x05;
298 *((long *)(OpBuffer+obp))=sizeof(DWORD);
299 obp+=sizeof(long);
300
301
302 //mov ecx,eax
303 OpBuffer[obp++]=(char)0x8B;
304 OpBuffer[obp++]=(char)0xC8;
305
306
307 //jnzの番地
308 int jnz_back;
309 jnz_back=obp;
310
311 //push ecx
312 compiler.codeGenerator.op_push(REG_ECX);
313
314 //push edx
315 compiler.codeGenerator.op_push(REG_EDX);
316
317 //push ecx(Thisポインタ ※隠れた第一パラメータ)
318 compiler.codeGenerator.op_push(REG_ECX);
319
320 //call edx
321 OpBuffer[obp++]=(char)0xFF;
322 OpBuffer[obp++]=(char)0xD2;
323
324 //pop edx
325 compiler.codeGenerator.op_pop(REG_EDX);
326
327 //pop ecx
328 compiler.codeGenerator.op_pop(REG_ECX);
329
330 //add ecx,esi
331 compiler.codeGenerator.op_add_RR( REG_ECX, REG_ESI );
332
333 //sub ebx,1
334 compiler.codeGenerator.op_sub_RV8(REG_EBX,1);
335
336 //jnz ↑
337 OpBuffer[obp++]=(char)0x0F;
338 OpBuffer[obp++]=(char)0x85;
339 *((long *)(OpBuffer+obp))=jnz_back-(obp+sizeof(long));
340 obp+=sizeof(long);
341
342
343 //////////////////////////////////////////
344 // オブジェクトメンバ変数用のメモリを解放
345 //////////////////////////////////////////
346
347 if( isSweeping ){
348 //call _System_GC_free_for_SweepingDelete
349 extern const UserProc *pSub_System_GC_free_for_SweepingDelete;
350 compiler.codeGenerator.op_call(pSub_System_GC_free_for_SweepingDelete);
351 }
352 else{
353 //call free
354 extern const UserProc *pSub_free;
355 compiler.codeGenerator.op_call(pSub_free);
356 }
357}
Note: See TracBrowser for help on using the repository browser.