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

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

コード全体のリファクタリングを実施

File size: 8.0 KB
Line 
1#include "stdafx.h"
2
3#include "../BasicCompiler_Common/common.h"
4#include "opcode.h"
5
6void _call_constructor( const CClass *pobj_c, const char *CreateParameter,int ObjectSize,BOOL bSomeObjects){
7 ////////////////////////////
8 // コンストラクタの呼び出し
9 ////////////////////////////
10
11 //この関数を使用する場合は、
12 //・ebxにオブジェクトの個数
13 //・eaxに先頭ポインタ
14 //をセットしておかなければならない
15
16 int jnz_back;
17
18
19 //jnzの番地
20 jnz_back=obp;
21
22 if(bSomeObjects){
23 SetError();
24
25 //push ebx
26 op_push(REG_EBX);
27 }
28
29 // ※ここでプッシュされた値はコンストラクタのthisポインタとなる
30 //push eax
31 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,"",0);
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, "ActiveBasic.Core._System_TypeBase.Search(\"\",\"%s\"))", pobj_c->GetName().c_str() );
64
65 Opcode_CallProc(temporary,
66 subs[0],
67 PROCFLAG_NEW,"",0);
68 }
69 else{
70 SetError();
71 }
72 }
73
74
75
76 //pop eax
77 op_pop(REG_EAX);
78
79 if(bSomeObjects){
80 //pop ebx
81 op_pop(REG_EBX);
82
83 //add eax,TypeSize
84 OpBuffer[obp++]=(char)0x05;
85 *((long *)(OpBuffer+obp))=ObjectSize;
86 obp+=sizeof(long);
87
88 //sub ebx,1
89 OpBuffer[obp++]=(char)0x83;
90 OpBuffer[obp++]=(char)0xEB;
91 OpBuffer[obp++]=(char)0x01;
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 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 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 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 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 OpBuffer[obp++]=(char)0x89;
189 OpBuffer[obp++]=(char)0x18;
190
191 //add eax,sizeof(DWORD)
192 OpBuffer[obp++]=(char)0x05;
193 *((long *)(OpBuffer+obp))=sizeof(DWORD);
194 obp+=sizeof(long);
195
196
197 //mov ecx,TypeSize
198 OpBuffer[obp++]=(char)0xB9;
199 *((long *)(OpBuffer+obp))=typeSize;
200 obp+=sizeof(long);
201
202 //mov dword ptr[eax],ecx(オブジェクトのサイズ)
203 OpBuffer[obp++]=(char)0x89;
204 OpBuffer[obp++]=(char)0x08;
205
206 //add eax,sizeof(DWORD)
207 OpBuffer[obp++]=(char)0x05;
208 *((long *)(OpBuffer+obp))=sizeof(DWORD);
209 obp+=sizeof(long);
210
211
212 const CMethod *method = classObj.GetDestructorMethod();
213 if( method == NULL ) return;
214
215 //mov ecx,DestructorProcAddr
216 OpBuffer[obp++]=(char)0xB9;
217 pobj_SubAddrSchedule->add(&method->GetUserProc(),0);
218 method->GetUserProc().Using();
219 obp+=sizeof(long);
220
221 //mov dword ptr[eax],ecx(デストラクタの関数ポインタ)
222 OpBuffer[obp++]=(char)0x89;
223 OpBuffer[obp++]=(char)0x08;
224
225 //add eax,sizeof(DWORD)
226 OpBuffer[obp++]=(char)0x05;
227 *((long *)(OpBuffer+obp))=sizeof(DWORD);
228 obp+=sizeof(long);
229
230
231 // リザーブ領域
232 //add eax,sizeof(DWORD)
233 OpBuffer[obp++]=(char)0x05;
234 *((long *)(OpBuffer+obp))=sizeof(DWORD);
235 obp+=sizeof(long);
236
237
238 // ※ここでプッシュされた値はNew演算子の戻り値となる
239 //push eax
240 op_push(REG_EAX);
241
242
243 /////////////////////////////////////////////////////////////////////
244
245 ////////////////////////////
246 // コンストラクタの呼び出し
247 ////////////////////////////
248
249 _call_constructor(&classObj,parameter,typeSize,bSomeObjects);
250}
251void OpcodeDelete(const char *Parameter, bool isSweeping){
252 Type tempType;
253 if( !NumOpe(Parameter,Type(),tempType) ){
254 return;
255 }
256 if(!( tempType.IsObjectPtr() || tempType.IsVoidPtr() )) SetError(122,NULL,cp);
257
258 //pop eax
259 op_pop(REG_EAX);
260
261 //sub eax,sizeof(DWORD)*3
262 op_sub_RV8( REG_EAX, OBJECT_HEAD_SIZE );
263
264 //push eax
265 op_push(REG_EAX);
266
267
268 //mov ebx,dword ptr[eax](オブジェクトの個数)
269 OpBuffer[obp++]=(char)0x8B;
270 OpBuffer[obp++]=(char)0x18;
271
272 //add eax,sizeof(DWORD)
273 OpBuffer[obp++]=(char)0x05;
274 *((long *)(OpBuffer+obp))=sizeof(DWORD);
275 obp+=sizeof(long);
276
277
278 //mov esi,dword ptr[eax](オブジェクトのサイズ)
279 OpBuffer[obp++]=(char)0x8B;
280 OpBuffer[obp++]=(char)0x30;
281
282 //add eax,sizeof(DWORD)
283 OpBuffer[obp++]=(char)0x05;
284 *((long *)(OpBuffer+obp))=sizeof(DWORD);
285 obp+=sizeof(long);
286
287
288 //mov edx,dword ptr[eax](デストラクタの関数ポインタ)
289 OpBuffer[obp++]=(char)0x8B;
290 OpBuffer[obp++]=(char)0x10;
291
292 //add eax,sizeof(DWORD)
293 OpBuffer[obp++]=(char)0x05;
294 *((long *)(OpBuffer+obp))=sizeof(DWORD);
295 obp+=sizeof(long);
296
297
298 // リザーブ領域
299 //add eax,sizeof(DWORD)
300 OpBuffer[obp++]=(char)0x05;
301 *((long *)(OpBuffer+obp))=sizeof(DWORD);
302 obp+=sizeof(long);
303
304
305 //mov ecx,eax
306 OpBuffer[obp++]=(char)0x8B;
307 OpBuffer[obp++]=(char)0xC8;
308
309
310 //jnzの番地
311 int jnz_back;
312 jnz_back=obp;
313
314 //push ecx
315 op_push(REG_ECX);
316
317 //push edx
318 op_push(REG_EDX);
319
320 //push ecx(Thisポインタ ※隠れた第一パラメータ)
321 op_push(REG_ECX);
322
323 //call edx
324 OpBuffer[obp++]=(char)0xFF;
325 OpBuffer[obp++]=(char)0xD2;
326
327 //pop edx
328 op_pop(REG_EDX);
329
330 //pop ecx
331 op_pop(REG_ECX);
332
333 //add ecx,esi
334 OpBuffer[obp++]=(char)0x03;
335 OpBuffer[obp++]=(char)0xCE;
336
337 //sub ebx,1
338 OpBuffer[obp++]=(char)0x83;
339 OpBuffer[obp++]=(char)0xEB;
340 OpBuffer[obp++]=(char)0x01;
341
342 //jnz ↑
343 OpBuffer[obp++]=(char)0x0F;
344 OpBuffer[obp++]=(char)0x85;
345 *((long *)(OpBuffer+obp))=jnz_back-(obp+sizeof(long));
346 obp+=sizeof(long);
347
348
349 //////////////////////////////////////////
350 // オブジェクトメンバ変数用のメモリを解放
351 //////////////////////////////////////////
352
353 if( isSweeping ){
354 //call _System_GC_free_for_SweepingDelete
355 extern const UserProc *pSub_System_GC_free_for_SweepingDelete;
356 op_call(pSub_System_GC_free_for_SweepingDelete);
357 }
358 else{
359 //call free
360 extern const UserProc *pSub_free;
361 op_call(pSub_free);
362 }
363}
Note: See TracBrowser for help on using the repository browser.