source: dev/BasicCompiler32/Compile_Object.cpp@ 64

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

すべてのオブジェクトを参照型に切り替えた。

File size: 8.2 KB
Line 
1#include "../BasicCompiler_Common/common.h"
2#include "opcode.h"
3
4void _call_constructor(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 //push ebx
21 op_push(REG_EBX);
22
23 // ※ここでプッシュされた値はコンストラクタのthisポインタとなる
24 //push eax
25 op_push(REG_EAX);
26
27
28
29 ////////////////////////
30 // オーバーロードを解決
31 ////////////////////////
32
33 std::vector<SUBINFO *> subs;
34 pobj_c->EnumMethod( pobj_c->name, subs );
35
36 SUBINFO *psi;
37 if( subs.size() > 0 ){
38 //オーバーロードを解決
39 psi=OverloadSolutionWithStrParam(pobj_c->name,
40 subs,CreateParameter,"",NULL);
41
42 if(!psi) return;
43 }
44
45 //コンストラクタを呼び出す
46 Opcode_CallProc(CreateParameter,
47 psi,
48 PROCFLAG_NEW,"",0);
49
50
51
52 //pop eax
53 op_pop(REG_EAX);
54
55 //pop ebx
56 op_pop(REG_EBX);
57
58 if(bSomeObjects){
59 //add eax,TypeSize
60 OpBuffer[obp++]=(char)0x05;
61 *((long *)(OpBuffer+obp))=ObjectSize;
62 obp+=sizeof(long);
63
64 //sub ebx,1
65 OpBuffer[obp++]=(char)0x83;
66 OpBuffer[obp++]=(char)0xEB;
67 OpBuffer[obp++]=(char)0x01;
68
69 //jnz ↑
70 OpBuffer[obp++]=(char)0x0F;
71 OpBuffer[obp++]=(char)0x85;
72 *((long *)(OpBuffer+obp))=jnz_back-(obp+sizeof(long));
73 obp+=sizeof(long);
74 }
75}
76void Operator_New( CClass &classObj, const char *objectSizeStr, const char *parameter, const TYPEINFO &baseTypeInfo ){
77 int typeSize = classObj.GetSize();
78
79 if(classObj.IsAbstract()){
80 //抽象クラスだったとき
81 SetError(125,classObj.name,cp);
82 }
83
84 if(objectSizeStr[0]){
85 int type = NumOpe(objectSizeStr,0,0,0);
86 ChangeTypeToLong(type);
87
88 //pop eax
89 op_pop(REG_EAX);
90
91 //※添え字上限値であることを考慮
92 //add eax,1
93 OpBuffer[obp++]=(char)0x83;
94 OpBuffer[obp++]=(char)0xC0;
95 OpBuffer[obp++]=(char)0x01;
96
97 //オブジェクトの個数をebxに一時保持
98 //※ebxは関数が呼ばれても不変
99 //mov ebx,eax
100 OpBuffer[obp++]=(char)0x8B;
101 OpBuffer[obp++]=(char)0xD8;
102
103 //imul eax,size
104 OpBuffer[obp++]=(char)0x69;
105 OpBuffer[obp++]=(char)0xC0;
106 *((long *)(OpBuffer+obp))=typeSize;
107 obp+=sizeof(long);
108
109 //add eax,sizeof(DWORD)*2
110 OpBuffer[obp++]=(char)0x05;
111 *((long *)(OpBuffer+obp))=sizeof(DWORD)*3;
112 obp+=sizeof(long);
113
114 //push eax
115 op_push(REG_EAX);
116 }
117 else{
118 //オブジェクトの個数をebxに一時保持
119 //※ebxは関数が呼ばれても不変
120 //mov ebx,1
121 OpBuffer[obp++]=(char)0xBB;
122 *((long *)(OpBuffer+obp))=1;
123 obp+=sizeof(long);
124
125 //push size
126 OpBuffer[obp++]=(char)0x68;
127 *((long *)(OpBuffer+obp))=typeSize+sizeof(DWORD)*3;
128 obp+=sizeof(long);
129 }
130
131 if( baseTypeInfo.type == DEF_OBJECT ){
132 //DeleteはGCで処理
133
134 //call _System_GC_malloc_ForObject
135 extern SUBINFO *pSub_System_GC_malloc_ForObject;
136 op_call(pSub_System_GC_malloc_ForObject);
137 }
138 else{
139 //明示的なDeleteが必要
140
141 //call _System_GC_malloc_ForObjectPtr
142 extern SUBINFO *pSub_System_GC_malloc_ForObjectPtr;
143 op_call(pSub_System_GC_malloc_ForObjectPtr);
144 }
145
146
147 /*
148 確保されたヒープ領域のポインタ(callocの戻り値eax)をpPtrとすると、
149 pPtr-=sizeof(DWORD)*3
150 pPtr[0]=オブジェクトの個数
151 pPtr[1]=オブジェクトのサイズ
152 pPtr[2]=デストラクタの関数ポインタ
153 */
154
155
156 //mov dword ptr[eax],ebx(オブジェクトの個数)
157 OpBuffer[obp++]=(char)0x89;
158 OpBuffer[obp++]=(char)0x18;
159
160 //add eax,sizeof(DWORD)
161 OpBuffer[obp++]=(char)0x05;
162 *((long *)(OpBuffer+obp))=sizeof(DWORD);
163 obp+=sizeof(long);
164
165
166 //mov ecx,TypeSize
167 OpBuffer[obp++]=(char)0xB9;
168 *((long *)(OpBuffer+obp))=typeSize;
169 obp+=sizeof(long);
170
171 //mov dword ptr[eax],ecx
172 OpBuffer[obp++]=(char)0x89;
173 OpBuffer[obp++]=(char)0x08;
174
175 //add eax,sizeof(DWORD)
176 OpBuffer[obp++]=(char)0x05;
177 *((long *)(OpBuffer+obp))=sizeof(DWORD);
178 obp+=sizeof(long);
179
180
181 CMethod *method = classObj.GetDestructorMethod();
182 if( method == NULL ) return;
183
184 //mov ecx,DestructorProcAddr
185 OpBuffer[obp++]=(char)0xB9;
186 pobj_SubAddrSchedule->add(method->psi,0);
187 method->psi->bUse=1;
188 obp+=sizeof(long);
189
190 //mov dword ptr[eax],ecx
191 OpBuffer[obp++]=(char)0x89;
192 OpBuffer[obp++]=(char)0x08;
193
194 //add eax,sizeof(DWORD)
195 OpBuffer[obp++]=(char)0x05;
196 *((long *)(OpBuffer+obp))=sizeof(DWORD);
197 obp+=sizeof(long);
198
199
200 // ※ここでプッシュされた値はNew演算子の戻り値となる
201 //push eax
202 op_push(REG_EAX);
203
204
205 /////////////////////////////////////////////////////////////////////
206
207 ////////////////////////////
208 // コンストラクタの呼び出し
209 ////////////////////////////
210
211 BOOL bSomeObjects;
212 if(objectSizeStr[0]) bSomeObjects=1;
213 else bSomeObjects=0;
214 _call_constructor(&classObj,parameter,typeSize,bSomeObjects);
215}
216int Operator_New(const char *Parameter,LONG_PTR *plpIndex,const TYPEINFO &baseTypeInfo ){
217 char TypeName[VN_SIZE],CreateParameter[VN_SIZE],objectSizeStr[VN_SIZE];
218 int i,i2;
219
220 i=0;
221
222 if(Parameter[0]=='['){
223 i=GetStringInBracket(objectSizeStr,Parameter);
224
225 SlideString(objectSizeStr+1,-1);
226 objectSizeStr[i-2]=0;
227 }
228 else objectSizeStr[0]=0;
229
230 for(i2=0;;i++,i2++){
231 if(Parameter[i]=='('){
232 TypeName[i2]=0;
233
234 //コンストラクタに渡すパラメータを取得
235 i2=GetStringInPare(CreateParameter,Parameter+i);
236 RemoveStringPare(CreateParameter);
237 i+=i2;
238 if(Parameter[i]!='\0'){
239 SetError(42,NULL,cp);
240 return -1;
241 }
242 break;
243 }
244 TypeName[i2]=Parameter[i];
245 if(Parameter[i]=='\0'){
246 CreateParameter[0]=0;
247 break;
248 }
249 }
250
251 int type,TypeSize;
252 type=GetTypeFixed(TypeName,plpIndex);
253 if(type==-1){
254 SetError(3,TypeName,cp);
255 return -1;
256 }
257 TypeSize=GetTypeSize(type,*plpIndex);
258
259 if(type!=DEF_OBJECT){
260 ////////////////////////
261 // 通常のデータ型の場合
262 ////////////////////////
263
264 SetError(121,NULL,cp);
265 return -1;
266 }
267
268 CClass *pobj_c;
269 pobj_c=(CClass *)*plpIndex;
270
271 Operator_New( *pobj_c, objectSizeStr, CreateParameter, baseTypeInfo );
272
273 if( baseTypeInfo.type == DEF_OBJECT ){
274 return DEF_OBJECT;
275 }
276 return DEF_PTR_OBJECT;
277}
278
279void OpcodeDelete(const char *Parameter, bool isSweeping){
280 int type;
281
282 type=NumOpe(Parameter,0,0,0);
283 if(type==-1) return;
284 if(!(type==DEF_PTR_OBJECT||type==DEF_PTR_VOID)) SetError(122,NULL,cp);
285
286 //pop eax
287 op_pop(REG_EAX);
288
289 //sub eax,sizeof(DWORD)*3
290 OpBuffer[obp++]=(char)0x83;
291 OpBuffer[obp++]=(char)0xE8;
292 OpBuffer[obp++]=(char)0x0C;
293
294 //push eax
295 op_push(REG_EAX);
296
297
298 //mov ebx,dword ptr[eax](オブジェクトの個数)
299 OpBuffer[obp++]=(char)0x8B;
300 OpBuffer[obp++]=(char)0x18;
301
302 //add eax,sizeof(DWORD)
303 OpBuffer[obp++]=(char)0x05;
304 *((long *)(OpBuffer+obp))=sizeof(DWORD);
305 obp+=sizeof(long);
306
307
308 //mov esi,dword ptr[eax](オブジェクトのサイズ)
309 OpBuffer[obp++]=(char)0x8B;
310 OpBuffer[obp++]=(char)0x30;
311
312 //add eax,sizeof(DWORD)
313 OpBuffer[obp++]=(char)0x05;
314 *((long *)(OpBuffer+obp))=sizeof(DWORD);
315 obp+=sizeof(long);
316
317
318 //mov edx,dword ptr[eax](デストラクタの関数ポインタ)
319 OpBuffer[obp++]=(char)0x8B;
320 OpBuffer[obp++]=(char)0x10;
321
322 //add eax,sizeof(DWORD)
323 OpBuffer[obp++]=(char)0x05;
324 *((long *)(OpBuffer+obp))=sizeof(DWORD);
325 obp+=sizeof(long);
326
327
328 //mov ecx,eax
329 OpBuffer[obp++]=(char)0x8B;
330 OpBuffer[obp++]=(char)0xC8;
331
332
333 //jnzの番地
334 int jnz_back;
335 jnz_back=obp;
336
337 //push ecx
338 op_push(REG_ECX);
339
340 //push edx
341 op_push(REG_EDX);
342
343 //push ecx(Thisポインタ ※隠れた第一パラメータ)
344 op_push(REG_ECX);
345
346 //call edx
347 OpBuffer[obp++]=(char)0xFF;
348 OpBuffer[obp++]=(char)0xD2;
349
350 //pop edx
351 op_pop(REG_EDX);
352
353 //pop ecx
354 op_pop(REG_ECX);
355
356 //add ecx,esi
357 OpBuffer[obp++]=(char)0x03;
358 OpBuffer[obp++]=(char)0xCE;
359
360 //sub ebx,1
361 OpBuffer[obp++]=(char)0x83;
362 OpBuffer[obp++]=(char)0xEB;
363 OpBuffer[obp++]=(char)0x01;
364
365 //jnz ↑
366 OpBuffer[obp++]=(char)0x0F;
367 OpBuffer[obp++]=(char)0x85;
368 *((long *)(OpBuffer+obp))=jnz_back-(obp+sizeof(long));
369 obp+=sizeof(long);
370
371
372 //////////////////////////////////////////
373 // オブジェクトメンバ変数用のメモリを解放
374 //////////////////////////////////////////
375
376 if( isSweeping ){
377 //call _System_GC_free_for_SweepingDelete
378 extern SUBINFO *pSub_System_GC_free_for_SweepingDelete;
379 op_call(pSub_System_GC_free_for_SweepingDelete);
380 }
381 else{
382 //call free
383 extern SUBINFO *pSub_free;
384 op_call(pSub_free);
385 }
386}
Note: See TracBrowser for help on using the repository browser.