source: dev/BasicCompiler32/Compile_Object.cpp@ 14

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