source: dev/BasicCompiler32/Compile_Func.cpp@ 6

Last change on this file since 6 was 3, checked in by dai_9181, 18 years ago
File size: 10.6 KB
RevLine 
[3]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(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(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(char *Parameter){
188 int type,TypeSize;
189 LONG_PTR lpIndex;
190 BOOL bArrayHead;
191
192 type=GetVarType(Parameter,&lpIndex,0);
193
194 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(!GetVarOffset(1,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(char *name){
244 extern int cp;
245 SUBINFO *psi;
246
247 extern LONG_PTR ProcPtr_BaseIndex;
248 if(ProcPtr_BaseIndex!=-1){
249 //左辺の型にのっとり、オーバーロードを解決
250
251 SUBINFO **ppsi;
252 int num;
253 ppsi=GetOverloadSubHash(name,&num);
254 if(!num){
255 HeapDefaultFree(ppsi);
256
257 SetError(27,name,cp);
258 return;
259 }
260
261 //オーバーロードを解決
262 extern PROCPTRINFO *pProcPtrInfo;
263 psi=OverloadSolution(name,ppsi,num,pProcPtrInfo[ProcPtr_BaseIndex].pParmInfo,pProcPtrInfo[ProcPtr_BaseIndex].ParmNum,NULL);
264 HeapDefaultFree(ppsi);
265
266 if(!psi){
267 SetError(27,name,cp);
268 return;
269 }
270 }
271 else{
272 psi=GetSubHash(name);
273 if(!psi){
274 SetError(27,name,cp);
275 return;
276 }
277 }
278
279
280 if(psi->bVirtual){
281 ///////////////////////////////
282 // 仮想関数の場合
283 // thisポインタをrcxにコピー
284 ///////////////////////////////
285
286 CClass *pobj_c;
287
288 char ObjectName[VN_SIZE];
289 int RefType;
290 GetObjectName(name,ObjectName,&RefType);
291
292 if(ObjectName[0]){
293 if(lstrcmpi(ObjectName,"Super")==0) goto InClassMember;
294 else{
295 RELATIVE_VAR RelativeVar;
296 int type;
297 if(!GetVarOffset(1,ObjectName,&type,&RelativeVar,(LONG_PTR *)&pobj_c)) return;
298 SetVarPtrToEax(&RelativeVar);
299
300 //mov ecx,eax
301 op_mov_RR(REG_ECX,REG_EAX);
302
303 //参照タイプが整合しているかをチェック
304 if(type!=RefType) SetError(104,ObjectName,cp);
305
306 if(type==DEF_PTR_OBJECT){
307 //mov ecx,dword ptr[ecx]
308 op_mov_RM(sizeof(long),REG_ECX,REG_ECX,0,MOD_BASE);
309 }
310 }
311 }
312 else{
313InClassMember:
314 //自身のオブジェクトのThisポインタをrcxにコピー
315 SetThisPtrToReg(REG_RCX);
316
317 pobj_c=pobj_CompilingClass;
318 }
319
320
321 //仮想関数(オブジェクトメソッド)
322 //pObj->func_table->func1
323 // ->func2
324 // ->func3
325
326 //mov edx,dword ptr[ecx]
327 OpBuffer[obp++]=(char)0x8B;
328 OpBuffer[obp++]=(char)0x11;
329
330 int i,i2;
331 for(i=0,i2=0;i<pobj_c->iMethodNum;i++){
332 if(pobj_c->ppobj_Method[i]->psi==psi) break;
333 if(pobj_c->ppobj_Method[i]->psi->bVirtual) i2++;
334 }
335
336 //mov eax,dword ptr[edx+func_index]
337 if(i2*PTR_SIZE<=0x7F){
338 op_mov_RM(sizeof(long),REG_EAX,REG_EDX,i2*PTR_SIZE,MOD_BASE_DISP8);
339 }
340 else{
341 op_mov_RM(sizeof(long),REG_EAX,REG_EDX,i2*PTR_SIZE,MOD_BASE_DISP32);
342 }
343 }
344 else{
345 //一般の関数
346
347 //mov eax,ProcAddr
348 OpBuffer[obp++]=(char)0xB8;
349 pobj_SubAddrSchedule->add(psi,0);
350 obp+=sizeof(long);
351 }
352
353 psi->bUse=1;
354}
355void Opcode_Func_SizeOf(char *Parameter){
356 int type,size;
357 LONG_PTR lpIndex;
358
359 type=GetTypeFixed(Parameter,&lpIndex);
360 if(type==-1){
361 extern int cp;
362 SetError(3,Parameter,cp);
363 return;
364 }
365 size=GetTypeSize(type,lpIndex);
366
367 //mov eax,size
368 OpBuffer[obp++]=(char)0xB8;
369 *((long *)(OpBuffer+obp))=size;
370 obp+=sizeof(long);
371}
372void Opcode_Func_VarPtr(char *Parameter){
373 int type;
374 RELATIVE_VAR RelativeVar;
375
376 //変数のアドレスを取得
377 if(!GetVarOffset(1,Parameter,&type,&RelativeVar,0)) return;
378
379 SetVarPtrToEax(&RelativeVar);
380}
381void Opcode_Func_GetPtrData(char *Parameter,int type){
382 int i2;
383
384 i2=NumOpe(Parameter,0,0,0);
385 ChangeTypeToLong(i2);
386
387 if(type==DEF_DOUBLE){
388 //pop eax
389 op_pop(REG_EAX);
390
391 //fld qword ptr[eax]
392 OpBuffer[obp++]=(char)0xDD;
393 OpBuffer[obp++]=(char)0x00;
394 }
395 else if(type==DEF_SINGLE||type==DEF_DWORD){
396 //pop eax
397 op_pop(REG_EAX);
398
399 //mov eax,dword ptr[eax]
400 OpBuffer[obp++]=(char)0x8B;
401 OpBuffer[obp++]=(char)0x00;
402 }
403 else if(type==DEF_QWORD){
404 //pop ecx
405 op_pop(REG_ECX);
406
407 //mov eax,dword ptr[ecx]
408 op_mov_RM(sizeof(long),REG_EAX,REG_ECX,0,MOD_BASE);
409
410 //mov edx,dword ptr[ecx+sizeof(long)]
411 op_mov_RM(sizeof(long),REG_EDX,REG_ECX,sizeof(long),MOD_BASE_DISP8);
412 }
413 else if(type==DEF_WORD){
414 //pop ebx
415 op_pop(REG_EBX);
416
417 //xor eax,eax
418 OpBuffer[obp++]=(char)0x33;
419 OpBuffer[obp++]=(char)0xC0;
420
421 //mov ax,word ptr[ebx]
422 OpBuffer[obp++]=(char)0x66;
423 OpBuffer[obp++]=(char)0x8B;
424 OpBuffer[obp++]=(char)0x03;
425 }
426 else if(type==DEF_BYTE){
427 //pop ebx
428 op_pop(REG_EBX);
429
430 //xor eax,eax
431 OpBuffer[obp++]=(char)0x33;
432 OpBuffer[obp++]=(char)0xC0;
433
434 //mov al,byte ptr[ebx]
435 OpBuffer[obp++]=(char)0x8A;
436 OpBuffer[obp++]=(char)0x03;
437 }
438}
439
440int Opcode_CallFunc(char *Parameter,int FuncNum){
441 switch(FuncNum){
442 case FUNC_FIX:
443 Opcode_Func_Fix(Parameter);
444 return DEF_LONG;
445 case FUNC_CUDBL:
446 Opcode_Func_CUDbl(Parameter);
447 return DEF_DOUBLE;
448 case FUNC_LEN:
449 Opcode_Func_Len(Parameter);
450 return DEF_LONG;
451 case FUNC_ADDRESSOF:
452 Opcode_Func_AddressOf(Parameter);
453 return DEF_PTR_VOID;
454 case FUNC_SIZEOF:
455 Opcode_Func_SizeOf(Parameter);
456 return DEF_LONG;
457 case FUNC_VARPTR:
458 Opcode_Func_VarPtr(Parameter);
459 return DEF_PTR_VOID;
460
461 case FUNC_GETDOUBLE:
462 Opcode_Func_GetPtrData(Parameter,DEF_DOUBLE);
463 return DEF_DOUBLE;
464 case FUNC_GETSINGLE:
465 Opcode_Func_GetPtrData(Parameter,DEF_SINGLE);
466 return DEF_SINGLE;
467 case FUNC_GETQWORD:
468 Opcode_Func_GetPtrData(Parameter,DEF_QWORD);
469 return DEF_QWORD;
470 case FUNC_GETDWORD:
471 Opcode_Func_GetPtrData(Parameter,DEF_DWORD);
472 return DEF_DWORD;
473 case FUNC_GETWORD:
474 Opcode_Func_GetPtrData(Parameter,DEF_WORD);
475 return DEF_WORD;
476 case FUNC_GETBYTE:
477 Opcode_Func_GetPtrData(Parameter,DEF_BYTE);
478 return DEF_BYTE;
479 }
480 return 0;
481}
Note: See TracBrowser for help on using the repository browser.