source: dev/BasicCompiler32/Compile_Object.cpp@ 51

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

ppobj_Member及びppobj_StaticMemberを廃止し、vectorに統一した(methods及びstaticMethods)。

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