source: dev/BasicCompiler32/Compile_Object.cpp@ 68

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

#84の対応(64bitでの動作確認はまだ)。
Stringクラスのコンストラクタにリテラル文字列が渡せないバグを修正。
STRING_IS_NOT_ALWAYS_UNICODEを暗黙的に定義するようにした(暫定対応)。

File size: 8.3 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 if( lstrcmp(classObj.name,"proc")==0){
212 int i=0;
213 }
214
215 BOOL bSomeObjects;
216 if(objectSizeStr[0]) bSomeObjects=1;
217 else bSomeObjects=0;
218 _call_constructor(&classObj,parameter,typeSize,bSomeObjects);
219}
220int Operator_New(const char *Parameter,LONG_PTR *plpIndex,const TYPEINFO &baseTypeInfo ){
221 char TypeName[VN_SIZE],CreateParameter[VN_SIZE],objectSizeStr[VN_SIZE];
222 int i,i2;
223
224 i=0;
225
226 if(Parameter[0]=='['){
227 i=GetStringInBracket(objectSizeStr,Parameter);
228
229 SlideString(objectSizeStr+1,-1);
230 objectSizeStr[i-2]=0;
231 }
232 else objectSizeStr[0]=0;
233
234 for(i2=0;;i++,i2++){
235 if(Parameter[i]=='('){
236 TypeName[i2]=0;
237
238 //コンストラクタに渡すパラメータを取得
239 i2=GetStringInPare(CreateParameter,Parameter+i);
240 RemoveStringPare(CreateParameter);
241 i+=i2;
242 if(Parameter[i]!='\0'){
243 SetError(42,NULL,cp);
244 return -1;
245 }
246 break;
247 }
248 TypeName[i2]=Parameter[i];
249 if(Parameter[i]=='\0'){
250 CreateParameter[0]=0;
251 break;
252 }
253 }
254
255 int type,TypeSize;
256 type=GetTypeFixed(TypeName,plpIndex);
257 if(type==-1){
258 SetError(3,TypeName,cp);
259 return -1;
260 }
261 TypeSize=GetTypeSize(type,*plpIndex);
262
263 if(type!=DEF_OBJECT){
264 ////////////////////////
265 // 通常のデータ型の場合
266 ////////////////////////
267
268 SetError(121,NULL,cp);
269 return -1;
270 }
271
272 CClass *pobj_c;
273 pobj_c=(CClass *)*plpIndex;
274
275 Operator_New( *pobj_c, objectSizeStr, CreateParameter, baseTypeInfo );
276
277 if( baseTypeInfo.type == DEF_OBJECT ){
278 return DEF_OBJECT;
279 }
280 return DEF_PTR_OBJECT;
281}
282
283void OpcodeDelete(const char *Parameter, bool isSweeping){
284 int type;
285
286 type=NumOpe(Parameter,0,0,0);
287 if(type==-1) return;
288 if(!(type==DEF_PTR_OBJECT||type==DEF_PTR_VOID)) SetError(122,NULL,cp);
289
290 //pop eax
291 op_pop(REG_EAX);
292
293 //sub eax,sizeof(DWORD)*3
294 OpBuffer[obp++]=(char)0x83;
295 OpBuffer[obp++]=(char)0xE8;
296 OpBuffer[obp++]=(char)0x0C;
297
298 //push eax
299 op_push(REG_EAX);
300
301
302 //mov ebx,dword ptr[eax](オブジェクトの個数)
303 OpBuffer[obp++]=(char)0x8B;
304 OpBuffer[obp++]=(char)0x18;
305
306 //add eax,sizeof(DWORD)
307 OpBuffer[obp++]=(char)0x05;
308 *((long *)(OpBuffer+obp))=sizeof(DWORD);
309 obp+=sizeof(long);
310
311
312 //mov esi,dword ptr[eax](オブジェクトのサイズ)
313 OpBuffer[obp++]=(char)0x8B;
314 OpBuffer[obp++]=(char)0x30;
315
316 //add eax,sizeof(DWORD)
317 OpBuffer[obp++]=(char)0x05;
318 *((long *)(OpBuffer+obp))=sizeof(DWORD);
319 obp+=sizeof(long);
320
321
322 //mov edx,dword ptr[eax](デストラクタの関数ポインタ)
323 OpBuffer[obp++]=(char)0x8B;
324 OpBuffer[obp++]=(char)0x10;
325
326 //add eax,sizeof(DWORD)
327 OpBuffer[obp++]=(char)0x05;
328 *((long *)(OpBuffer+obp))=sizeof(DWORD);
329 obp+=sizeof(long);
330
331
332 //mov ecx,eax
333 OpBuffer[obp++]=(char)0x8B;
334 OpBuffer[obp++]=(char)0xC8;
335
336
337 //jnzの番地
338 int jnz_back;
339 jnz_back=obp;
340
341 //push ecx
342 op_push(REG_ECX);
343
344 //push edx
345 op_push(REG_EDX);
346
347 //push ecx(Thisポインタ ※隠れた第一パラメータ)
348 op_push(REG_ECX);
349
350 //call edx
351 OpBuffer[obp++]=(char)0xFF;
352 OpBuffer[obp++]=(char)0xD2;
353
354 //pop edx
355 op_pop(REG_EDX);
356
357 //pop ecx
358 op_pop(REG_ECX);
359
360 //add ecx,esi
361 OpBuffer[obp++]=(char)0x03;
362 OpBuffer[obp++]=(char)0xCE;
363
364 //sub ebx,1
365 OpBuffer[obp++]=(char)0x83;
366 OpBuffer[obp++]=(char)0xEB;
367 OpBuffer[obp++]=(char)0x01;
368
369 //jnz ↑
370 OpBuffer[obp++]=(char)0x0F;
371 OpBuffer[obp++]=(char)0x85;
372 *((long *)(OpBuffer+obp))=jnz_back-(obp+sizeof(long));
373 obp+=sizeof(long);
374
375
376 //////////////////////////////////////////
377 // オブジェクトメンバ変数用のメモリを解放
378 //////////////////////////////////////////
379
380 if( isSweeping ){
381 //call _System_GC_free_for_SweepingDelete
382 extern SUBINFO *pSub_System_GC_free_for_SweepingDelete;
383 op_call(pSub_System_GC_free_for_SweepingDelete);
384 }
385 else{
386 //call free
387 extern SUBINFO *pSub_free;
388 op_call(pSub_free);
389 }
390}
Note: See TracBrowser for help on using the repository browser.