source: dev/BasicCompiler32/Compile_Func.cpp@ 50

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

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

File size: 11.0 KB
Line 
1#include "../BasicCompiler_Common/common.h"
2#include "Opcode.h"
3
4int GetFunctionType(int FuncNum){
5 switch(FuncNum){
6 case FUNC_CUDBL:
7 return DEF_DOUBLE;
8 case FUNC_FIX:
9 case FUNC_LEN:
10 return DEF_LONG;
11 case FUNC_ADDRESSOF:
12 case FUNC_SIZEOF:
13 case FUNC_VARPTR:
14 return DEF_DWORD;
15 case FUNC_GETDOUBLE:
16 return DEF_DOUBLE;
17 case FUNC_GETSINGLE:
18 return DEF_SINGLE;
19 case FUNC_GETQWORD:
20 return DEF_QWORD;
21 case FUNC_GETDWORD:
22 return DEF_DWORD;
23 case FUNC_GETWORD:
24 return DEF_WORD;
25 case FUNC_GETBYTE:
26 return DEF_BYTE;
27 }
28 return 0;
29}
30int GetFunctionFromName(char *FuncName){
31 if(lstrcmpi(FuncName,"CUDbl")==0) return FUNC_CUDBL;
32 if(lstrcmpi(FuncName,"Fix")==0) return FUNC_FIX;
33 if(lstrcmpi(FuncName,"Len")==0) return FUNC_LEN;
34 if(lstrcmpi(FuncName,"AddressOf")==0) return FUNC_ADDRESSOF;
35 if(lstrcmpi(FuncName,"SizeOf")==0) return FUNC_SIZEOF;
36 if(lstrcmpi(FuncName,"VarPtr")==0) return FUNC_VARPTR;
37 if(lstrcmpi(FuncName,"GetDouble")==0) return FUNC_GETDOUBLE;
38 if(lstrcmpi(FuncName,"GetSingle")==0) return FUNC_GETSINGLE;
39 if(lstrcmpi(FuncName,"GetQWord")==0) return FUNC_GETQWORD;
40 if(lstrcmpi(FuncName,"GetDWord")==0) return FUNC_GETDWORD;
41 if(lstrcmpi(FuncName,"GetWord")==0) return FUNC_GETWORD;
42 if(lstrcmpi(FuncName,"GetByte")==0) return FUNC_GETBYTE;
43 return 0;
44}
45
46void Opcode_Func_Fix(const char *Parameter){
47 int i;
48
49 i=NumOpe(Parameter,0,0,0);
50
51 if(i==DEF_DOUBLE){
52 //fld qword ptr[esp]
53 op_fld_ptr_esp(DEF_DOUBLE);
54
55 //fnstcw word ptr[esp]
56 OpBuffer[obp++]=(char)0xD9;
57 OpBuffer[obp++]=(char)0x3C;
58 OpBuffer[obp++]=(char)0x24;
59
60 //mov ax,word ptr[esp]
61 OpBuffer[obp++]=(char)0x66;
62 OpBuffer[obp++]=(char)0x8B;
63 OpBuffer[obp++]=(char)0x04;
64 OpBuffer[obp++]=(char)0x24;
65
66 //or ah,0Ch
67 OpBuffer[obp++]=(char)0x80;
68 OpBuffer[obp++]=(char)0xCC;
69 OpBuffer[obp++]=(char)0x0C;
70
71 //mov word ptr[esp-2],ax
72 OpBuffer[obp++]=(char)0x66;
73 OpBuffer[obp++]=(char)0x89;
74 OpBuffer[obp++]=(char)0x44;
75 OpBuffer[obp++]=(char)0x24;
76 OpBuffer[obp++]=(char)0xFE;
77
78 //fldcw word ptr[esp-2]
79 OpBuffer[obp++]=(char)0xD9;
80 OpBuffer[obp++]=(char)0x6C;
81 OpBuffer[obp++]=(char)0x24;
82 OpBuffer[obp++]=(char)0xFE;
83
84 //fistp dword ptr[esp+4]
85 OpBuffer[obp++]=(char)0xDB;
86 OpBuffer[obp++]=(char)0x5C;
87 OpBuffer[obp++]=(char)0x24;
88 OpBuffer[obp++]=(char)0x04;
89
90 //fldcw word ptr[esp]
91 OpBuffer[obp++]=(char)0xD9;
92 OpBuffer[obp++]=(char)0x2C;
93 OpBuffer[obp++]=(char)0x24;
94
95 //add esp,4
96 op_add_esp(4);
97 }
98 else if(i==DEF_SINGLE){
99 //fld dword ptr[esp]
100 op_fld_ptr_esp(DEF_SINGLE);
101
102 //sub esp,4
103 op_sub_esp(4);
104
105 //fnstcw word ptr[esp]
106 OpBuffer[obp++]=(char)0xD9;
107 OpBuffer[obp++]=(char)0x3C;
108 OpBuffer[obp++]=(char)0x24;
109
110 //mov ax,word ptr[esp]
111 OpBuffer[obp++]=(char)0x66;
112 OpBuffer[obp++]=(char)0x8B;
113 OpBuffer[obp++]=(char)0x04;
114 OpBuffer[obp++]=(char)0x24;
115
116 //or ah,0Ch
117 OpBuffer[obp++]=(char)0x80;
118 OpBuffer[obp++]=(char)0xCC;
119 OpBuffer[obp++]=(char)0x0C;
120
121 //mov word ptr[esp-2],ax
122 OpBuffer[obp++]=(char)0x66;
123 OpBuffer[obp++]=(char)0x89;
124 OpBuffer[obp++]=(char)0x44;
125 OpBuffer[obp++]=(char)0x24;
126 OpBuffer[obp++]=(char)0xFE;
127
128 //fldcw word ptr[esp-2]
129 OpBuffer[obp++]=(char)0xD9;
130 OpBuffer[obp++]=(char)0x6C;
131 OpBuffer[obp++]=(char)0x24;
132 OpBuffer[obp++]=(char)0xFE;
133
134 //fistp dword ptr[esp+4]
135 OpBuffer[obp++]=(char)0xDB;
136 OpBuffer[obp++]=(char)0x5C;
137 OpBuffer[obp++]=(char)0x24;
138 OpBuffer[obp++]=(char)0x04;
139
140 //fldcw word ptr[esp]
141 OpBuffer[obp++]=(char)0xD9;
142 OpBuffer[obp++]=(char)0x2C;
143 OpBuffer[obp++]=(char)0x24;
144
145 //add esp,4
146 op_add_esp(4);
147 }
148 else if(Is64Type(i)){
149 //pop eax
150 op_pop(REG_EAX);
151
152 //add esp,4
153 op_add_esp(4);
154
155 //push eax
156 op_push(REG_EAX);
157 }
158
159 //pop eax
160 op_pop(REG_EAX);
161}
162
163void Opcode_Func_CUDbl(const char *Parameter){
164 int i;
165
166 i=NumOpe(Parameter,0,0,0);
167 ChangeTypeToLong(i);
168
169 //pop eax
170 op_pop(REG_EAX);
171
172 //push 0
173 OpBuffer[obp++]=(char)0x6A;
174 OpBuffer[obp++]=(char)0x00;
175
176 //push eax
177 op_push(REG_EAX);
178
179 //fild qword ptr[esp]
180 OpBuffer[obp++]=(char)0xDF;
181 OpBuffer[obp++]=(char)0x2C;
182 OpBuffer[obp++]=(char)0x24;
183
184 //add esp,8
185 op_add_esp(8);
186}
187void Opcode_Func_Len(const char *Parameter){
188 int type,TypeSize;
189 LONG_PTR lpIndex;
190 BOOL bArrayHead;
191
192 type=GetVarType(Parameter,&lpIndex,0);
193
194 const char *tempParm=Parameter;
195 char temporary[VN_SIZE];
196 char temp2[32];
197 if(type==-1){
198 sprintf(temporary,"_System_DummyStr2=%s",Parameter);
199 OpcodeCalc(temporary);
200
201 lstrcpy(temp2,"_System_DummyStr2");
202 tempParm=temp2;
203
204 extern CClass *pobj_StringClass;
205 type=DEF_OBJECT;
206 lpIndex=(LONG_PTR)pobj_StringClass;
207 }
208
209 TYPEINFO TypeInfo={type,lpIndex};
210 if(IsStringObjectType(&TypeInfo)){
211 //Stringオブジェクトの場合
212 char temporary[VN_SIZE];
213 sprintf(temporary,"%s.Length",tempParm);
214
215 NumOpe(temporary,0,0,NULL,NULL);
216
217 //pop eax
218 op_pop(REG_EAX);
219
220 return;
221 }
222
223 int SubScripts[MAX_ARRAYDIM];
224 RELATIVE_VAR RelativeVar;
225 if(!GetVarOffsetReadOnly(tempParm,&type,&RelativeVar,&lpIndex,SubScripts)) return;
226
227 if(type&FLAG_PTR){
228 type&=~FLAG_PTR;
229
230 bArrayHead=1;
231 }
232 else bArrayHead=0;
233
234 TypeSize=GetTypeSize(type,lpIndex);
235
236 if(bArrayHead) TypeSize*=JumpSubScripts(SubScripts);
237
238 //mov eax,TypeSize
239 OpBuffer[obp++]=(char)0xB8;
240 *((long *)(OpBuffer+obp))=TypeSize;
241 obp+=sizeof(long);
242}
243void Opcode_Func_AddressOf(const char *name){
244 extern int cp;
245 SUBINFO *psi;
246
247 extern LONG_PTR ProcPtr_BaseIndex;
248 if(ProcPtr_BaseIndex!=-1){
249 //左辺の型にのっとり、オーバーロードを解決
250
251 std::vector<SUBINFO *> subs;
252 GetOverloadSubHash( name, subs );
253 if( subs.size() == 0 ){
254 SetError(27,name,cp);
255 return;
256 }
257
258 //オーバーロードを解決
259 extern PROCPTRINFO *pProcPtrInfo;
260 psi=OverloadSolution(name,subs,pProcPtrInfo[ProcPtr_BaseIndex].pParmInfo,pProcPtrInfo[ProcPtr_BaseIndex].ParmNum,NULL);
261
262 if(!psi){
263 SetError(27,name,cp);
264 return;
265 }
266 }
267 else{
268 psi=GetSubHash(name);
269 if(!psi){
270 SetError(27,name,cp);
271 return;
272 }
273 }
274
275
276 if(psi->bVirtual){
277 ///////////////////////////////
278 // 仮想関数の場合
279 // thisポインタをrcxにコピー
280 ///////////////////////////////
281
282 CClass *pobj_c;
283
284 char ObjectName[VN_SIZE];
285 int RefType;
286 SplitObjectName(name,ObjectName,&RefType);
287
288 if(ObjectName[0]){
289 if(lstrcmpi(ObjectName,"Super")==0) goto InClassMember;
290 else{
291 RELATIVE_VAR RelativeVar;
292 int type;
293 if(!GetVarOffsetReadOnly(ObjectName,&type,&RelativeVar,(LONG_PTR *)&pobj_c)) return;
294 SetVarPtrToEax(&RelativeVar);
295
296 //mov ecx,eax
297 op_mov_RR(REG_ECX,REG_EAX);
298
299 //参照タイプが整合しているかをチェック
300 if(type!=RefType) SetError(104,ObjectName,cp);
301
302 if(type==DEF_PTR_OBJECT){
303 //mov ecx,dword ptr[ecx]
304 op_mov_RM(sizeof(long),REG_ECX,REG_ECX,0,MOD_BASE);
305 }
306 }
307 }
308 else{
309InClassMember:
310 //自身のオブジェクトのThisポインタをrcxにコピー
311 SetThisPtrToReg(REG_RCX);
312
313 pobj_c=pobj_CompilingClass;
314 }
315
316
317 //仮想関数(オブジェクトメソッド)
318 //pObj->func_table->func1
319 // ->func2
320 // ->func3
321
322 //mov edx,dword ptr[ecx]
323 OpBuffer[obp++]=(char)0x8B;
324 OpBuffer[obp++]=(char)0x11;
325
326 int i,i2;
327 for(i=0,i2=0;i<pobj_c->iMethodNum;i++){
328 if(pobj_c->ppobj_Method[i]->psi==psi) break;
329 if(pobj_c->ppobj_Method[i]->psi->bVirtual) i2++;
330 }
331
332 //mov eax,dword ptr[edx+func_index]
333 if(i2*PTR_SIZE<=0x7F){
334 op_mov_RM(sizeof(long),REG_EAX,REG_EDX,i2*PTR_SIZE,MOD_BASE_DISP8);
335 }
336 else{
337 op_mov_RM(sizeof(long),REG_EAX,REG_EDX,i2*PTR_SIZE,MOD_BASE_DISP32);
338 }
339 }
340 else{
341 //一般の関数
342
343 //mov eax,ProcAddr
344 OpBuffer[obp++]=(char)0xB8;
345 pobj_SubAddrSchedule->add(psi,0);
346 obp+=sizeof(long);
347 }
348
349 psi->bUse=1;
350}
351void Opcode_Func_SizeOf(const char *Parameter){
352 int type,size;
353 LONG_PTR lpIndex;
354
355 type=GetTypeFixed(Parameter,&lpIndex);
356 if(type==-1){
357 extern int cp;
358 SetError(3,Parameter,cp);
359 return;
360 }
361 size=GetTypeSize(type,lpIndex);
362
363 //mov eax,size
364 OpBuffer[obp++]=(char)0xB8;
365 *((long *)(OpBuffer+obp))=size;
366 obp+=sizeof(long);
367}
368void Opcode_Func_VarPtr( const char *Parameter, TYPEINFO &ReturnTypeInfo ){
369 RELATIVE_VAR RelativeVar;
370
371 //変数のアドレスを取得
372 if(!GetVarOffsetReadOnly( Parameter, &ReturnTypeInfo.type, &RelativeVar, &ReturnTypeInfo.u.lpIndex )) return;
373
374 PTR_LEVEL_UP( ReturnTypeInfo.type );
375
376 SetVarPtrToEax(&RelativeVar);
377}
378void Opcode_Func_GetPtrData(const char *Parameter,const int type){
379 int i2;
380
381 i2=NumOpe(Parameter,0,0,0);
382 ChangeTypeToLong(i2);
383
384 if(type==DEF_DOUBLE){
385 //pop eax
386 op_pop(REG_EAX);
387
388 //fld qword ptr[eax]
389 OpBuffer[obp++]=(char)0xDD;
390 OpBuffer[obp++]=(char)0x00;
391 }
392 else if(type==DEF_SINGLE||type==DEF_DWORD){
393 //pop eax
394 op_pop(REG_EAX);
395
396 //mov eax,dword ptr[eax]
397 OpBuffer[obp++]=(char)0x8B;
398 OpBuffer[obp++]=(char)0x00;
399 }
400 else if(type==DEF_QWORD){
401 //pop ecx
402 op_pop(REG_ECX);
403
404 //mov eax,dword ptr[ecx]
405 op_mov_RM(sizeof(long),REG_EAX,REG_ECX,0,MOD_BASE);
406
407 //mov edx,dword ptr[ecx+sizeof(long)]
408 op_mov_RM(sizeof(long),REG_EDX,REG_ECX,sizeof(long),MOD_BASE_DISP8);
409 }
410 else if(type==DEF_WORD){
411 //pop ebx
412 op_pop(REG_EBX);
413
414 //xor eax,eax
415 OpBuffer[obp++]=(char)0x33;
416 OpBuffer[obp++]=(char)0xC0;
417
418 //mov ax,word ptr[ebx]
419 OpBuffer[obp++]=(char)0x66;
420 OpBuffer[obp++]=(char)0x8B;
421 OpBuffer[obp++]=(char)0x03;
422 }
423 else if(type==DEF_BYTE){
424 //pop ebx
425 op_pop(REG_EBX);
426
427 //xor eax,eax
428 OpBuffer[obp++]=(char)0x33;
429 OpBuffer[obp++]=(char)0xC0;
430
431 //mov al,byte ptr[ebx]
432 OpBuffer[obp++]=(char)0x8A;
433 OpBuffer[obp++]=(char)0x03;
434 }
435}
436
437void Opcode_CallFunc( const char *Parameter, const int FuncNum, TYPEINFO &ReturnTypeInfo ){
438 switch(FuncNum){
439 case FUNC_FIX:
440 Opcode_Func_Fix(Parameter);
441 ReturnTypeInfo.type = DEF_LONG;
442 break;
443 case FUNC_CUDBL:
444 Opcode_Func_CUDbl(Parameter);
445 ReturnTypeInfo.type = DEF_DOUBLE;
446 break;
447 case FUNC_LEN:
448 Opcode_Func_Len(Parameter);
449 ReturnTypeInfo.type = DEF_LONG;
450 break;
451 case FUNC_ADDRESSOF:
452 Opcode_Func_AddressOf(Parameter);
453 ReturnTypeInfo.type = DEF_PTR_VOID;
454 break;
455 case FUNC_SIZEOF:
456 Opcode_Func_SizeOf(Parameter);
457 ReturnTypeInfo.type = DEF_LONG;
458 break;
459 case FUNC_VARPTR:
460 Opcode_Func_VarPtr( Parameter, ReturnTypeInfo );
461 break;
462
463 case FUNC_GETDOUBLE:
464 Opcode_Func_GetPtrData(Parameter,DEF_DOUBLE);
465 ReturnTypeInfo.type = DEF_DOUBLE;
466 break;
467 case FUNC_GETSINGLE:
468 Opcode_Func_GetPtrData(Parameter,DEF_SINGLE);
469 ReturnTypeInfo.type = DEF_SINGLE;
470 break;
471 case FUNC_GETQWORD:
472 Opcode_Func_GetPtrData(Parameter,DEF_QWORD);
473 ReturnTypeInfo.type = DEF_QWORD;
474 break;
475 case FUNC_GETDWORD:
476 Opcode_Func_GetPtrData(Parameter,DEF_DWORD);
477 ReturnTypeInfo.type = DEF_DWORD;
478 break;
479 case FUNC_GETWORD:
480 Opcode_Func_GetPtrData(Parameter,DEF_WORD);
481 ReturnTypeInfo.type = DEF_WORD;
482 break;
483 case FUNC_GETBYTE:
484 Opcode_Func_GetPtrData(Parameter,DEF_BYTE);
485 ReturnTypeInfo.type = DEF_BYTE;
486 break;
487 }
488}
Note: See TracBrowser for help on using the repository browser.