source: dev/BasicCompiler32/Compile_Func.cpp@ 64

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

すべてのオブジェクトを参照型に切り替えた。

File size: 11.1 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 i2 = pobj_c->GetFuncNumInVtbl( psi );
327
328 //mov eax,dword ptr[edx+func_index]
329 if(i2*PTR_SIZE<=0x7F){
330 op_mov_RM(sizeof(long),REG_EAX,REG_EDX,i2*PTR_SIZE,MOD_BASE_DISP8);
331 }
332 else{
333 op_mov_RM(sizeof(long),REG_EAX,REG_EDX,i2*PTR_SIZE,MOD_BASE_DISP32);
334 }
335 }
336 else{
337 //一般の関数
338
339 //mov eax,ProcAddr
340 OpBuffer[obp++]=(char)0xB8;
341 pobj_SubAddrSchedule->add(psi,0);
342 obp+=sizeof(long);
343 }
344
345 psi->bUse=1;
346}
347void Opcode_Func_SizeOf(const char *Parameter){
348 LONG_PTR lpIndex;
349 int type = GetTypeFixed(Parameter,&lpIndex);
350
351 int size;
352 if( type == DEF_OBJECT ){
353 CClass *pClass = (CClass *)lpIndex;
354 size = pClass->GetSize();
355 }
356 else{
357 size=GetTypeSize(type,lpIndex);
358 }
359
360 //mov eax,size
361 op_mov_RV( REG_EAX, size );
362}
363void Opcode_Func_VarPtr( const char *Parameter, TYPEINFO &ReturnTypeInfo ){
364 RELATIVE_VAR RelativeVar;
365
366 //変数のアドレスを取得
367 if(!GetVarOffsetReadOnly( Parameter, &ReturnTypeInfo.type, &RelativeVar, &ReturnTypeInfo.u.lpIndex )) return;
368
369 int beforeType = ReturnTypeInfo.type;
370
371 PTR_LEVEL_UP( ReturnTypeInfo.type );
372
373 SetVarPtrToEax(&RelativeVar);
374
375 if( beforeType == DEF_OBJECT && lstrcmpi( Parameter, "This" ) != 0 ){
376 //参照をオブジェクトポインタに変更
377
378 //mov eax,dword ptr[eax]
379 op_mov_RM( sizeof(long), REG_EAX, REG_EAX, 0, MOD_BASE );
380 }
381}
382void Opcode_Func_GetPtrData(const char *Parameter,const int type){
383 int i2;
384
385 i2=NumOpe(Parameter,0,0,0);
386 ChangeTypeToLong(i2);
387
388 if(type==DEF_DOUBLE){
389 //pop eax
390 op_pop(REG_EAX);
391
392 //fld qword ptr[eax]
393 OpBuffer[obp++]=(char)0xDD;
394 OpBuffer[obp++]=(char)0x00;
395 }
396 else if(type==DEF_SINGLE||type==DEF_DWORD){
397 //pop eax
398 op_pop(REG_EAX);
399
400 //mov eax,dword ptr[eax]
401 OpBuffer[obp++]=(char)0x8B;
402 OpBuffer[obp++]=(char)0x00;
403 }
404 else if(type==DEF_QWORD){
405 //pop ecx
406 op_pop(REG_ECX);
407
408 //mov eax,dword ptr[ecx]
409 op_mov_RM(sizeof(long),REG_EAX,REG_ECX,0,MOD_BASE);
410
411 //mov edx,dword ptr[ecx+sizeof(long)]
412 op_mov_RM(sizeof(long),REG_EDX,REG_ECX,sizeof(long),MOD_BASE_DISP8);
413 }
414 else if(type==DEF_WORD){
415 //pop ebx
416 op_pop(REG_EBX);
417
418 //xor eax,eax
419 OpBuffer[obp++]=(char)0x33;
420 OpBuffer[obp++]=(char)0xC0;
421
422 //mov ax,word ptr[ebx]
423 OpBuffer[obp++]=(char)0x66;
424 OpBuffer[obp++]=(char)0x8B;
425 OpBuffer[obp++]=(char)0x03;
426 }
427 else if(type==DEF_BYTE){
428 //pop ebx
429 op_pop(REG_EBX);
430
431 //xor eax,eax
432 OpBuffer[obp++]=(char)0x33;
433 OpBuffer[obp++]=(char)0xC0;
434
435 //mov al,byte ptr[ebx]
436 OpBuffer[obp++]=(char)0x8A;
437 OpBuffer[obp++]=(char)0x03;
438 }
439}
440
441void Opcode_CallFunc( const char *Parameter, const int FuncNum, TYPEINFO &ReturnTypeInfo ){
442 switch(FuncNum){
443 case FUNC_FIX:
444 Opcode_Func_Fix(Parameter);
445 ReturnTypeInfo.type = DEF_LONG;
446 break;
447 case FUNC_CUDBL:
448 Opcode_Func_CUDbl(Parameter);
449 ReturnTypeInfo.type = DEF_DOUBLE;
450 break;
451 case FUNC_LEN:
452 Opcode_Func_Len(Parameter);
453 ReturnTypeInfo.type = DEF_LONG;
454 break;
455 case FUNC_ADDRESSOF:
456 Opcode_Func_AddressOf(Parameter);
457 ReturnTypeInfo.type = DEF_PTR_VOID;
458 break;
459 case FUNC_SIZEOF:
460 Opcode_Func_SizeOf(Parameter);
461 ReturnTypeInfo.type = DEF_LONG;
462 break;
463 case FUNC_VARPTR:
464 Opcode_Func_VarPtr( Parameter, ReturnTypeInfo );
465 break;
466
467 case FUNC_GETDOUBLE:
468 Opcode_Func_GetPtrData(Parameter,DEF_DOUBLE);
469 ReturnTypeInfo.type = DEF_DOUBLE;
470 break;
471 case FUNC_GETSINGLE:
472 Opcode_Func_GetPtrData(Parameter,DEF_SINGLE);
473 ReturnTypeInfo.type = DEF_SINGLE;
474 break;
475 case FUNC_GETQWORD:
476 Opcode_Func_GetPtrData(Parameter,DEF_QWORD);
477 ReturnTypeInfo.type = DEF_QWORD;
478 break;
479 case FUNC_GETDWORD:
480 Opcode_Func_GetPtrData(Parameter,DEF_DWORD);
481 ReturnTypeInfo.type = DEF_DWORD;
482 break;
483 case FUNC_GETWORD:
484 Opcode_Func_GetPtrData(Parameter,DEF_WORD);
485 ReturnTypeInfo.type = DEF_WORD;
486 break;
487 case FUNC_GETBYTE:
488 Opcode_Func_GetPtrData(Parameter,DEF_BYTE);
489 ReturnTypeInfo.type = DEF_BYTE;
490 break;
491 }
492}
Note: See TracBrowser for help on using the repository browser.