source: dev/BasicCompiler32/Compile_Func.cpp@ 76

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

TYPEINFO→Typeへのリファクタリングを実施。32bitが未完成。

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