source: dev/BasicCompiler32/Compile_Object.cpp@ 50

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

オーバーロード解決用の関数保持リストを "SUBINFO " ではなく、"vector<SUBINFO *>" に変更した。

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 //mov ecx,DestructorProcAddr
223 i2=pobj_c->DestructorMemberSubIndex;
224 if(i2==-1) return -1;
225 OpBuffer[obp++]=(char)0xB9;
226 pobj_SubAddrSchedule->add(pobj_c->ppobj_Method[i2]->psi,0);
227 pobj_c->ppobj_Method[i2]->psi->bUse=1;
228 obp+=sizeof(long);
229
230 //mov dword ptr[eax],ecx
231 OpBuffer[obp++]=(char)0x89;
232 OpBuffer[obp++]=(char)0x08;
233
234 //add eax,sizeof(DWORD)
235 OpBuffer[obp++]=(char)0x05;
236 *((long *)(OpBuffer+obp))=sizeof(DWORD);
237 obp+=sizeof(long);
238
239
240 // ※ここでプッシュされた値はNew演算子の戻り値となる
241 //push eax
242 op_push(REG_EAX);
243
244
245 /////////////////////////////////////////////////////////////////////
246
247 ////////////////////////////
248 // コンストラクタの呼び出し
249 ////////////////////////////
250
251 BOOL bSomeObjects;
252 if(ObjectSize[0]) bSomeObjects=1;
253 else bSomeObjects=0;
254 _call_constructor(pobj_c,CreateParameter,TypeSize,bSomeObjects);
255
256 return DEF_PTR_OBJECT;
257}
258
259void OpcodeDelete(char *Parameter){
260 int type;
261
262 type=NumOpe(Parameter,0,0,0);
263 if(type==-1) return;
264 if(!(type==DEF_PTR_OBJECT||type==DEF_PTR_VOID)) SetError(122,NULL,cp);
265
266 //pop eax
267 op_pop(REG_EAX);
268
269 //sub eax,sizeof(DWORD)*3
270 OpBuffer[obp++]=(char)0x83;
271 OpBuffer[obp++]=(char)0xE8;
272 OpBuffer[obp++]=(char)0x0C;
273
274 //push eax
275 op_push(REG_EAX);
276
277
278 //mov ebx,dword ptr[eax](オブジェクトの個数)
279 OpBuffer[obp++]=(char)0x8B;
280 OpBuffer[obp++]=(char)0x18;
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 esi,dword ptr[eax](オブジェクトのサイズ)
289 OpBuffer[obp++]=(char)0x8B;
290 OpBuffer[obp++]=(char)0x30;
291
292 //add eax,sizeof(DWORD)
293 OpBuffer[obp++]=(char)0x05;
294 *((long *)(OpBuffer+obp))=sizeof(DWORD);
295 obp+=sizeof(long);
296
297
298 //mov edx,dword ptr[eax](デストラクタの関数ポインタ)
299 OpBuffer[obp++]=(char)0x8B;
300 OpBuffer[obp++]=(char)0x10;
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 ecx,eax
309 OpBuffer[obp++]=(char)0x8B;
310 OpBuffer[obp++]=(char)0xC8;
311
312
313 //jnzの番地
314 int jnz_back;
315 jnz_back=obp;
316
317 //push ecx
318 op_push(REG_ECX);
319
320 //push edx
321 op_push(REG_EDX);
322
323 //push ecx(Thisポインタ ※隠れた第一パラメータ)
324 op_push(REG_ECX);
325
326 //call edx
327 OpBuffer[obp++]=(char)0xFF;
328 OpBuffer[obp++]=(char)0xD2;
329
330 //pop edx
331 op_pop(REG_EDX);
332
333 //pop ecx
334 op_pop(REG_ECX);
335
336 //add ecx,esi
337 OpBuffer[obp++]=(char)0x03;
338 OpBuffer[obp++]=(char)0xCE;
339
340 //sub ebx,1
341 OpBuffer[obp++]=(char)0x83;
342 OpBuffer[obp++]=(char)0xEB;
343 OpBuffer[obp++]=(char)0x01;
344
345 //jnz ↑
346 OpBuffer[obp++]=(char)0x0F;
347 OpBuffer[obp++]=(char)0x85;
348 *((long *)(OpBuffer+obp))=jnz_back-(obp+sizeof(long));
349 obp+=sizeof(long);
350
351
352 //////////////////////////////////////////
353 // オブジェクトメンバ変数用のメモリを解放
354 //////////////////////////////////////////
355
356 //call free
357 extern SUBINFO *pSub_free;
358 op_call(pSub_free);
359}
Note: See TracBrowser for help on using the repository browser.