source: dev/BasicCompiler32/Compile_Object.cpp@ 31

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

_System_LocalThis(見えないThisポインタパラメータ)を通常のパラメータ保有領域ではなく、リアルパラメータ保有領域に移動した。
メソッドとグローバル関数のオーバーロードに対応(DLL関数オーバーロードには未対応)。

File size: 7.3 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 PROCFLAG_NEW,"",0);
50
51
52
53 //pop eax
54 op_pop(REG_EAX);
55
56 //pop ebx
57 op_pop(REG_EBX);
58
59 if(bSomeObjects){
60 //add eax,TypeSize
61 OpBuffer[obp++]=(char)0x05;
62 *((long *)(OpBuffer+obp))=ObjectSize;
63 obp+=sizeof(long);
64
65 //sub ebx,1
66 OpBuffer[obp++]=(char)0x83;
67 OpBuffer[obp++]=(char)0xEB;
68 OpBuffer[obp++]=(char)0x01;
69
70 //jnz ↑
71 OpBuffer[obp++]=(char)0x0F;
72 OpBuffer[obp++]=(char)0x85;
73 *((long *)(OpBuffer+obp))=jnz_back-(obp+sizeof(long));
74 obp+=sizeof(long);
75 }
76}
77int Operator_New(char *Parameter,LONG_PTR *plpIndex){
78 char TypeName[VN_SIZE],CreateParameter[VN_SIZE],ObjectSize[VN_SIZE];
79 int i,i2;
80
81 i=0;
82
83 if(Parameter[0]=='['){
84 i=GetStringInBracket(ObjectSize,Parameter);
85
86 SlideString(ObjectSize+1,-1);
87 ObjectSize[i-2]=0;
88 }
89 else ObjectSize[0]=0;
90
91 for(i2=0;;i++,i2++){
92 if(Parameter[i]=='('){
93 TypeName[i2]=0;
94
95 //コンストラクタに渡すパラメータを取得
96 i2=GetStringInPare(CreateParameter,Parameter+i);
97 RemoveStringPare(CreateParameter);
98 i+=i2;
99 if(Parameter[i]!='\0'){
100 SetError(42,NULL,cp);
101 return -1;
102 }
103 break;
104 }
105 TypeName[i2]=Parameter[i];
106 if(Parameter[i]=='\0'){
107 CreateParameter[0]=0;
108 break;
109 }
110 }
111
112 int type,TypeSize;
113 type=GetTypeFixed(TypeName,plpIndex);
114 if(type==-1){
115 SetError(3,TypeName,cp);
116 return -1;
117 }
118 TypeSize=GetTypeSize(type,*plpIndex);
119
120 if(type!=DEF_OBJECT){
121 ////////////////////////
122 // 通常のデータ型の場合
123 ////////////////////////
124
125 SetError(121,NULL,cp);
126 return -1;
127 }
128
129 CClass *pobj_c;
130 pobj_c=(CClass *)*plpIndex;
131
132 if(pobj_c->IsAbstract()){
133 //抽象クラスだったとき
134 SetError(125,pobj_c->name,cp);
135 }
136
137 if(ObjectSize[0]){
138 i2=NumOpe(ObjectSize,0,0,0);
139 ChangeTypeToLong(i2);
140
141 //pop eax
142 op_pop(REG_EAX);
143
144 //※添え字上限値であることを考慮
145 //add eax,1
146 OpBuffer[obp++]=(char)0x83;
147 OpBuffer[obp++]=(char)0xC0;
148 OpBuffer[obp++]=(char)0x01;
149
150 //オブジェクトの個数をebxに一時保持
151 //※ebxは関数が呼ばれても不変
152 //mov ebx,eax
153 OpBuffer[obp++]=(char)0x8B;
154 OpBuffer[obp++]=(char)0xD8;
155
156 //imul eax,size
157 OpBuffer[obp++]=(char)0x69;
158 OpBuffer[obp++]=(char)0xC0;
159 *((long *)(OpBuffer+obp))=TypeSize;
160 obp+=sizeof(long);
161
162 //add eax,sizeof(DWORD)*2
163 OpBuffer[obp++]=(char)0x05;
164 *((long *)(OpBuffer+obp))=sizeof(DWORD)*3;
165 obp+=sizeof(long);
166
167 //push eax
168 op_push(REG_EAX);
169 }
170 else{
171 //オブジェクトの個数をebxに一時保持
172 //※ebxは関数が呼ばれても不変
173 //mov ebx,1
174 OpBuffer[obp++]=(char)0xBB;
175 *((long *)(OpBuffer+obp))=1;
176 obp+=sizeof(long);
177
178 //push size
179 OpBuffer[obp++]=(char)0x68;
180 *((long *)(OpBuffer+obp))=TypeSize+sizeof(DWORD)*3;
181 obp+=sizeof(long);
182 }
183
184 //call calloc
185 extern SUBINFO *pSub_calloc;
186 op_call(pSub_calloc);
187
188
189 /*
190 確保されたヒープ領域のポインタ(callocの戻り値eax)をpPtrとすると、
191 pPtr-=sizeof(DWORD)*3
192 pPtr[0]=オブジェクトの個数
193 pPtr[1]=オブジェクトのサイズ
194 pPtr[2]=デストラクタの関数ポインタ
195 */
196
197
198 //mov dword ptr[eax],ebx(オブジェクトの個数)
199 OpBuffer[obp++]=(char)0x89;
200 OpBuffer[obp++]=(char)0x18;
201
202 //add eax,sizeof(DWORD)
203 OpBuffer[obp++]=(char)0x05;
204 *((long *)(OpBuffer+obp))=sizeof(DWORD);
205 obp+=sizeof(long);
206
207
208 //mov ecx,TypeSize
209 OpBuffer[obp++]=(char)0xB9;
210 *((long *)(OpBuffer+obp))=TypeSize;
211 obp+=sizeof(long);
212
213 //mov dword ptr[eax],ecx
214 OpBuffer[obp++]=(char)0x89;
215 OpBuffer[obp++]=(char)0x08;
216
217 //add eax,sizeof(DWORD)
218 OpBuffer[obp++]=(char)0x05;
219 *((long *)(OpBuffer+obp))=sizeof(DWORD);
220 obp+=sizeof(long);
221
222
223 //mov ecx,DestructorProcAddr
224 i2=pobj_c->DestructorMemberSubIndex;
225 if(i2==-1) return -1;
226 OpBuffer[obp++]=(char)0xB9;
227 pobj_SubAddrSchedule->add(pobj_c->ppobj_Method[i2]->psi,0);
228 pobj_c->ppobj_Method[i2]->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 CallConstructor(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.