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

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

traceログ機能を搭載
動的メンバをstl::vectorにまとめた
シンボルをクラス化した

File size: 7.9 KB
Line 
1#include "../BasicCompiler_Common/common.h"
2#include "opcode.h"
3
4void _call_constructor( const CClass *pobj_c, const char *CreateParameter,int ObjectSize,BOOL bSomeObjects){
5 ////////////////////////////
6 // コンストラクタの呼び出し
7 ////////////////////////////
8
9 //この関数を使用する場合は、
10 //・ebxにオブジェクトの個数
11 //・eaxに先頭ポインタ
12 //をセットしておかなければならない
13
14 int jnz_back;
15
16
17 //jnzの番地
18 jnz_back=obp;
19
20 if(bSomeObjects){
21 SetError();
22
23 //push ebx
24 op_push(REG_EBX);
25 }
26
27 // ※ここでプッシュされた値はコンストラクタのthisポインタとなる
28 //push eax
29 op_push(REG_EAX);
30
31
32
33 ////////////////////////
34 // オーバーロードを解決
35 ////////////////////////
36
37 std::vector<UserProc *> subs;
38 pobj_c->GetMethods().Enum( pobj_c->GetName().c_str(), subs );
39
40 UserProc *pUserProc;
41 if( subs.size() > 0 ){
42 //オーバーロードを解決
43 pUserProc=OverloadSolutionWithStrParam(pobj_c->GetName().c_str(),
44 subs,CreateParameter,"");
45
46 if(!pUserProc) return;
47 }
48
49 //コンストラクタを呼び出す
50 Opcode_CallProc(CreateParameter,
51 pUserProc,
52 PROCFLAG_NEW,"",0);
53
54 {
55 // 動的型情報をセットする
56 // obj._System_SetType( _System_TypeBase.Search( strNamespace, name ) )
57 subs.clear();
58 pobj_c->GetMethods().Enum( "_System_SetType", subs );
59 if( subs.size() == 1 ){
60 char temporary[VN_SIZE];
61 sprintf( temporary, "ActiveBasic.Core._System_TypeBase.Search(\"\",\"%s\"))", pobj_c->GetName().c_str() );
62
63 Opcode_CallProc(temporary,
64 subs[0],
65 PROCFLAG_NEW,"",0);
66 }
67 else{
68 SetError();
69 }
70 }
71
72
73
74 //pop eax
75 op_pop(REG_EAX);
76
77 if(bSomeObjects){
78 //pop ebx
79 op_pop(REG_EBX);
80
81 //add eax,TypeSize
82 OpBuffer[obp++]=(char)0x05;
83 *((long *)(OpBuffer+obp))=ObjectSize;
84 obp+=sizeof(long);
85
86 //sub ebx,1
87 OpBuffer[obp++]=(char)0x83;
88 OpBuffer[obp++]=(char)0xEB;
89 OpBuffer[obp++]=(char)0x01;
90
91 //jnz ↑
92 OpBuffer[obp++]=(char)0x0F;
93 OpBuffer[obp++]=(char)0x85;
94 *((long *)(OpBuffer+obp))=jnz_back-(obp+sizeof(long));
95 obp+=sizeof(long);
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 op_pop(REG_EAX);
117
118 //※添え字上限値であることを考慮
119 //add eax,1
120 OpBuffer[obp++]=(char)0x83;
121 OpBuffer[obp++]=(char)0xC0;
122 OpBuffer[obp++]=(char)0x01;
123
124 //オブジェクトの個数をebxに一時保持
125 //※ebxは関数が呼ばれても不変
126 //mov ebx,eax
127 OpBuffer[obp++]=(char)0x8B;
128 OpBuffer[obp++]=(char)0xD8;
129
130 //imul eax,size
131 OpBuffer[obp++]=(char)0x69;
132 OpBuffer[obp++]=(char)0xC0;
133 *((long *)(OpBuffer+obp))=typeSize;
134 obp+=sizeof(long);
135
136 //add eax,OBJECT_HEAD_SIZE
137 OpBuffer[obp++]=(char)0x05;
138 *((long *)(OpBuffer+obp))=OBJECT_HEAD_SIZE;
139 obp+=sizeof(long);
140
141 //push eax
142 op_push(REG_EAX);
143 }
144 else{
145 //オブジェクトの個数をebxに一時保持
146 //※ebxは関数が呼ばれても不変
147 //mov ebx,1
148 OpBuffer[obp++]=(char)0xBB;
149 *((long *)(OpBuffer+obp))=1;
150 obp+=sizeof(long);
151
152 //push size + OBJECT_HEAD_SIZE
153 OpBuffer[obp++]=(char)0x68;
154 *((long *)(OpBuffer+obp))=typeSize + OBJECT_HEAD_SIZE;
155 obp+=sizeof(long);
156 }
157
158 if( baseType.IsObject() ){
159 // オブジェクト インスタンス
160 // ※DeleteはGCで処理
161
162 //call _System_GC_malloc_ForObject
163 extern UserProc *pSub_System_GC_malloc_ForObject;
164 op_call(pSub_System_GC_malloc_ForObject);
165 }
166 else{
167 // オブジェクトポインタ
168 // ※明示的なDeleteが必要
169
170 //call _System_GC_malloc_ForObjectPtr
171 extern UserProc *pSub_System_GC_malloc_ForObjectPtr;
172 op_call(pSub_System_GC_malloc_ForObjectPtr);
173 }
174
175
176 /*
177 確保されたヒープ領域のポインタ(callocの戻り値eax)をpPtrとすると、
178 pPtr[0]=オブジェクトの個数
179 pPtr[1]=オブジェクトのサイズ
180 pPtr[2]=デストラクタの関数ポインタ
181 pPtr[3]=reserve
182 */
183
184
185 //mov dword ptr[eax],ebx(オブジェクトの個数)
186 OpBuffer[obp++]=(char)0x89;
187 OpBuffer[obp++]=(char)0x18;
188
189 //add eax,sizeof(DWORD)
190 OpBuffer[obp++]=(char)0x05;
191 *((long *)(OpBuffer+obp))=sizeof(DWORD);
192 obp+=sizeof(long);
193
194
195 //mov ecx,TypeSize
196 OpBuffer[obp++]=(char)0xB9;
197 *((long *)(OpBuffer+obp))=typeSize;
198 obp+=sizeof(long);
199
200 //mov dword ptr[eax],ecx(オブジェクトのサイズ)
201 OpBuffer[obp++]=(char)0x89;
202 OpBuffer[obp++]=(char)0x08;
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->pUserProc,0);
216 method->pUserProc->Using();
217 obp+=sizeof(long);
218
219 //mov dword ptr[eax],ecx(デストラクタの関数ポインタ)
220 OpBuffer[obp++]=(char)0x89;
221 OpBuffer[obp++]=(char)0x08;
222
223 //add eax,sizeof(DWORD)
224 OpBuffer[obp++]=(char)0x05;
225 *((long *)(OpBuffer+obp))=sizeof(DWORD);
226 obp+=sizeof(long);
227
228
229 // リザーブ領域
230 //add eax,sizeof(DWORD)
231 OpBuffer[obp++]=(char)0x05;
232 *((long *)(OpBuffer+obp))=sizeof(DWORD);
233 obp+=sizeof(long);
234
235
236 // ※ここでプッシュされた値はNew演算子の戻り値となる
237 //push eax
238 op_push(REG_EAX);
239
240
241 /////////////////////////////////////////////////////////////////////
242
243 ////////////////////////////
244 // コンストラクタの呼び出し
245 ////////////////////////////
246
247 _call_constructor(&classObj,parameter,typeSize,bSomeObjects);
248}
249void OpcodeDelete(const char *Parameter, bool isSweeping){
250 Type tempType;
251 if( !NumOpe(Parameter,Type(),tempType) ){
252 return;
253 }
254 if(!( tempType.IsObjectPtr() || tempType.IsVoidPtr() )) SetError(122,NULL,cp);
255
256 //pop eax
257 op_pop(REG_EAX);
258
259 //sub eax,sizeof(DWORD)*3
260 op_sub_RV8( REG_EAX, OBJECT_HEAD_SIZE );
261
262 //push eax
263 op_push(REG_EAX);
264
265
266 //mov ebx,dword ptr[eax](オブジェクトの個数)
267 OpBuffer[obp++]=(char)0x8B;
268 OpBuffer[obp++]=(char)0x18;
269
270 //add eax,sizeof(DWORD)
271 OpBuffer[obp++]=(char)0x05;
272 *((long *)(OpBuffer+obp))=sizeof(DWORD);
273 obp+=sizeof(long);
274
275
276 //mov esi,dword ptr[eax](オブジェクトのサイズ)
277 OpBuffer[obp++]=(char)0x8B;
278 OpBuffer[obp++]=(char)0x30;
279
280 //add eax,sizeof(DWORD)
281 OpBuffer[obp++]=(char)0x05;
282 *((long *)(OpBuffer+obp))=sizeof(DWORD);
283 obp+=sizeof(long);
284
285
286 //mov edx,dword ptr[eax](デストラクタの関数ポインタ)
287 OpBuffer[obp++]=(char)0x8B;
288 OpBuffer[obp++]=(char)0x10;
289
290 //add eax,sizeof(DWORD)
291 OpBuffer[obp++]=(char)0x05;
292 *((long *)(OpBuffer+obp))=sizeof(DWORD);
293 obp+=sizeof(long);
294
295
296 // リザーブ領域
297 //add eax,sizeof(DWORD)
298 OpBuffer[obp++]=(char)0x05;
299 *((long *)(OpBuffer+obp))=sizeof(DWORD);
300 obp+=sizeof(long);
301
302
303 //mov ecx,eax
304 OpBuffer[obp++]=(char)0x8B;
305 OpBuffer[obp++]=(char)0xC8;
306
307
308 //jnzの番地
309 int jnz_back;
310 jnz_back=obp;
311
312 //push ecx
313 op_push(REG_ECX);
314
315 //push edx
316 op_push(REG_EDX);
317
318 //push ecx(Thisポインタ ※隠れた第一パラメータ)
319 op_push(REG_ECX);
320
321 //call edx
322 OpBuffer[obp++]=(char)0xFF;
323 OpBuffer[obp++]=(char)0xD2;
324
325 //pop edx
326 op_pop(REG_EDX);
327
328 //pop ecx
329 op_pop(REG_ECX);
330
331 //add ecx,esi
332 OpBuffer[obp++]=(char)0x03;
333 OpBuffer[obp++]=(char)0xCE;
334
335 //sub ebx,1
336 OpBuffer[obp++]=(char)0x83;
337 OpBuffer[obp++]=(char)0xEB;
338 OpBuffer[obp++]=(char)0x01;
339
340 //jnz ↑
341 OpBuffer[obp++]=(char)0x0F;
342 OpBuffer[obp++]=(char)0x85;
343 *((long *)(OpBuffer+obp))=jnz_back-(obp+sizeof(long));
344 obp+=sizeof(long);
345
346
347 //////////////////////////////////////////
348 // オブジェクトメンバ変数用のメモリを解放
349 //////////////////////////////////////////
350
351 if( isSweeping ){
352 //call _System_GC_free_for_SweepingDelete
353 extern UserProc *pSub_System_GC_free_for_SweepingDelete;
354 op_call(pSub_System_GC_free_for_SweepingDelete);
355 }
356 else{
357 //call free
358 extern UserProc *pSub_free;
359 op_call(pSub_free);
360 }
361}
Note: See TracBrowser for help on using the repository browser.