source: dev/BasicCompiler32/Compile_Func.cpp@ 78

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

CTypeDef → TypeDef
Houseクラスを追加。
オーバーロードレベルの種類を追加(レベル1に挿入)

File size: 11.7 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
[76]46void Opcode_Func_Fix(const char *lpszParms){
47 Type resultType;
48 if( !NumOpe( lpszParms, Type(), resultType ) ){
49 return;
50 }
[3]51
[76]52 if( resultType.IsDouble() ){
[3]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 }
[76]99 else if( resultType.IsSingle() ){
[3]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 }
[76]149 else if( resultType.Is64() ){
[3]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
[46]164void Opcode_Func_CUDbl(const char *Parameter){
[76]165 Type resultType;
166 if( !NumOpe(Parameter,Type(),resultType) ){
167 return;
168 }
169 ChangeTypeToLong(resultType.GetBasicType());
[3]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}
[46]189void Opcode_Func_Len(const char *Parameter){
[3]190 BOOL bArrayHead;
191
[46]192 const char *tempParm=Parameter;
[3]193 char temporary[VN_SIZE];
194 char temp2[32];
[76]195 Type type;
196 if( !GetVarType(Parameter,type,0) ){
[3]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;
[76]204 type.SetType( DEF_OBJECT, pobj_StringClass );
[3]205 }
206
[76]207 if( type.IsStringObject() ){
[3]208 //Stringオブジェクトの場合
209 sprintf(temporary,"%s.Length",tempParm);
210
[76]211 int reg=REG_RAX;
212 NumOpe(temporary,Type(),Type());
[3]213
214 //pop eax
215 op_pop(REG_EAX);
216
217 return;
218 }
219
220 int SubScripts[MAX_ARRAYDIM];
221 RELATIVE_VAR RelativeVar;
[76]222 if(!GetVarOffsetReadOnly(tempParm,&RelativeVar,type,SubScripts)) return;
[3]223
[76]224 if(type.GetBasicType()&FLAG_PTR){
225 type.SetBasicType( type.GetBasicType() & ( ~FLAG_PTR ) );
[3]226
227 bArrayHead=1;
228 }
229 else bArrayHead=0;
230
[76]231 int typeSize = type.GetSize();
[3]232
[76]233 if(bArrayHead) typeSize*=JumpSubScripts(SubScripts);
[3]234
235 //mov eax,TypeSize
236 OpBuffer[obp++]=(char)0xB8;
[76]237 *((long *)(OpBuffer+obp))=typeSize;
[3]238 obp+=sizeof(long);
239}
[76]240void Opcode_Func_AddressOf( const char *name ){
[3]241 extern int cp;
[75]242 UserProc *pUserProc;
[3]243
244 extern LONG_PTR ProcPtr_BaseIndex;
245 if(ProcPtr_BaseIndex!=-1){
246 //左辺の型にのっとり、オーバーロードを解決
247
[75]248 std::vector<UserProc *> subs;
[50]249 GetOverloadSubHash( name, subs );
250 if( subs.size() == 0 ){
[3]251 SetError(27,name,cp);
252 return;
253 }
254
255 //オーバーロードを解決
[78]256 pUserProc=OverloadSolution(name,subs,House::procPointers[ProcPtr_BaseIndex]->Params(), Type() );
[3]257
[75]258 if(!pUserProc){
[3]259 SetError(27,name,cp);
260 return;
261 }
262 }
263 else{
[75]264 pUserProc=GetSubHash(name);
265 if(!pUserProc){
[3]266 SetError(27,name,cp);
267 return;
268 }
269 }
270
[75]271 if( pUserProc->IsVirtual() ){
[3]272 ///////////////////////////////
273 // 仮想関数の場合
274 // thisポインタをrcxにコピー
275 ///////////////////////////////
276
277 CClass *pobj_c;
278
279 char ObjectName[VN_SIZE];
280 int RefType;
[28]281 SplitObjectName(name,ObjectName,&RefType);
[3]282
283 if(ObjectName[0]){
284 if(lstrcmpi(ObjectName,"Super")==0) goto InClassMember;
285 else{
286 RELATIVE_VAR RelativeVar;
[76]287 Type type;
288 if(!GetVarOffsetReadOnly(ObjectName,&RelativeVar,type)) return;
[3]289 SetVarPtrToEax(&RelativeVar);
290
291 //mov ecx,eax
292 op_mov_RR(REG_ECX,REG_EAX);
293
294 //参照タイプが整合しているかをチェック
[76]295 if(type.GetBasicType()!=RefType) SetError(104,ObjectName,cp);
[3]296
[76]297 if(type.IsObjectPtr()){
[3]298 //mov ecx,dword ptr[ecx]
299 op_mov_RM(sizeof(long),REG_ECX,REG_ECX,0,MOD_BASE);
300 }
301 }
302 }
303 else{
304InClassMember:
305 //自身のオブジェクトのThisポインタをrcxにコピー
306 SetThisPtrToReg(REG_RCX);
307
308 pobj_c=pobj_CompilingClass;
309 }
310
311
312 //仮想関数(オブジェクトメソッド)
313 //pObj->func_table->func1
314 // ->func2
315 // ->func3
316
317 //mov edx,dword ptr[ecx]
318 OpBuffer[obp++]=(char)0x8B;
319 OpBuffer[obp++]=(char)0x11;
320
[75]321 int i2 = pobj_c->GetFuncNumInVtbl( pUserProc );
[3]322
323 //mov eax,dword ptr[edx+func_index]
324 if(i2*PTR_SIZE<=0x7F){
325 op_mov_RM(sizeof(long),REG_EAX,REG_EDX,i2*PTR_SIZE,MOD_BASE_DISP8);
326 }
327 else{
328 op_mov_RM(sizeof(long),REG_EAX,REG_EDX,i2*PTR_SIZE,MOD_BASE_DISP32);
329 }
330 }
331 else{
332 //一般の関数
333
334 //mov eax,ProcAddr
335 OpBuffer[obp++]=(char)0xB8;
[75]336 pobj_SubAddrSchedule->add(pUserProc,0);
[3]337 obp+=sizeof(long);
338 }
339
[75]340 pUserProc->Using();
[3]341}
[46]342void Opcode_Func_SizeOf(const char *Parameter){
[3]343 LONG_PTR lpIndex;
[64]344 int type = GetTypeFixed(Parameter,&lpIndex);
[3]345
[64]346 int size;
347 if( type == DEF_OBJECT ){
348 CClass *pClass = (CClass *)lpIndex;
349 size = pClass->GetSize();
[3]350 }
[64]351 else{
352 size=GetTypeSize(type,lpIndex);
353 }
[3]354
355 //mov eax,size
[64]356 op_mov_RV( REG_EAX, size );
[3]357}
[76]358void Opcode_Func_VarPtr( const char *Parameter, Type &resultType, bool isCallOn ){
359 if( isCallOn == false ){
360 // 戻り値の型を取得するだけ
361
362 //変数のアドレスを取得
363 if(!GetVarType( Parameter, resultType, true )) return;
364
365 resultType.PtrLevelUp();
366
367 return;
368 }
369
[3]370 RELATIVE_VAR RelativeVar;
371
372 //変数のアドレスを取得
[76]373 if(!GetVarOffsetReadOnly( Parameter, &RelativeVar, resultType )) return;
[3]374
[76]375 int beforeType = resultType.GetBasicType();
[64]376
[76]377 resultType.PtrLevelUp();
[46]378
[3]379 SetVarPtrToEax(&RelativeVar);
[64]380
381 if( beforeType == DEF_OBJECT && lstrcmpi( Parameter, "This" ) != 0 ){
382 //参照をオブジェクトポインタに変更
383
384 //mov eax,dword ptr[eax]
385 op_mov_RM( sizeof(long), REG_EAX, REG_EAX, 0, MOD_BASE );
386 }
[3]387}
[46]388void Opcode_Func_GetPtrData(const char *Parameter,const int type){
[76]389 Type tempType;
390 if( !NumOpe(Parameter,Type(),tempType) ){
391 return;
392 }
393 if(!tempType.IsWhole()){
394 SetError(11,Parameter,cp);
395 return;
396 }
397 ChangeTypeToLong(tempType.GetBasicType());
[3]398
399 if(type==DEF_DOUBLE){
400 //pop eax
401 op_pop(REG_EAX);
402
403 //fld qword ptr[eax]
404 OpBuffer[obp++]=(char)0xDD;
405 OpBuffer[obp++]=(char)0x00;
406 }
407 else if(type==DEF_SINGLE||type==DEF_DWORD){
408 //pop eax
409 op_pop(REG_EAX);
410
411 //mov eax,dword ptr[eax]
412 OpBuffer[obp++]=(char)0x8B;
413 OpBuffer[obp++]=(char)0x00;
414 }
415 else if(type==DEF_QWORD){
416 //pop ecx
417 op_pop(REG_ECX);
418
419 //mov eax,dword ptr[ecx]
420 op_mov_RM(sizeof(long),REG_EAX,REG_ECX,0,MOD_BASE);
421
422 //mov edx,dword ptr[ecx+sizeof(long)]
423 op_mov_RM(sizeof(long),REG_EDX,REG_ECX,sizeof(long),MOD_BASE_DISP8);
424 }
425 else if(type==DEF_WORD){
426 //pop ebx
427 op_pop(REG_EBX);
428
429 //xor eax,eax
430 OpBuffer[obp++]=(char)0x33;
431 OpBuffer[obp++]=(char)0xC0;
432
433 //mov ax,word ptr[ebx]
434 OpBuffer[obp++]=(char)0x66;
435 OpBuffer[obp++]=(char)0x8B;
436 OpBuffer[obp++]=(char)0x03;
437 }
438 else if(type==DEF_BYTE){
439 //pop ebx
440 op_pop(REG_EBX);
441
442 //xor eax,eax
443 OpBuffer[obp++]=(char)0x33;
444 OpBuffer[obp++]=(char)0xC0;
445
446 //mov al,byte ptr[ebx]
447 OpBuffer[obp++]=(char)0x8A;
448 OpBuffer[obp++]=(char)0x03;
449 }
450}
451
[76]452bool Opcode_CallFunc( const char *Parameter, const int FuncNum, Type &resultType, bool isCallOn ){
[3]453 switch(FuncNum){
454 case FUNC_FIX:
[76]455 if( isCallOn ) Opcode_Func_Fix(Parameter);
456 resultType.SetBasicType( DEF_LONG );
[46]457 break;
[3]458 case FUNC_CUDBL:
[76]459 if( isCallOn ) Opcode_Func_CUDbl(Parameter);
460 resultType.SetBasicType( DEF_DOUBLE );
[46]461 break;
[3]462 case FUNC_LEN:
[76]463 if( isCallOn ) Opcode_Func_Len(Parameter);
464 resultType.SetBasicType( DEF_LONG );
[46]465 break;
[3]466 case FUNC_ADDRESSOF:
[76]467 if( isCallOn ) Opcode_Func_AddressOf(Parameter);
468 resultType.SetBasicType( DEF_PTR_VOID );
[46]469 break;
[3]470 case FUNC_SIZEOF:
[76]471 if( isCallOn ) Opcode_Func_SizeOf(Parameter);
472 resultType.SetBasicType( DEF_LONG );
[46]473 break;
[3]474 case FUNC_VARPTR:
[76]475 Opcode_Func_VarPtr( Parameter, resultType, isCallOn );
[46]476 break;
[3]477
478 case FUNC_GETDOUBLE:
[76]479 if( isCallOn ) Opcode_Func_GetPtrData(Parameter,DEF_DOUBLE);
480 resultType.SetBasicType( DEF_DOUBLE );
[46]481 break;
[3]482 case FUNC_GETSINGLE:
[76]483 if( isCallOn ) Opcode_Func_GetPtrData(Parameter,DEF_SINGLE);
484 resultType.SetBasicType( DEF_SINGLE );
[46]485 break;
[3]486 case FUNC_GETQWORD:
[76]487 if( isCallOn ) Opcode_Func_GetPtrData(Parameter,DEF_QWORD);
488 resultType.SetBasicType( DEF_QWORD );
[46]489 break;
[3]490 case FUNC_GETDWORD:
[76]491 if( isCallOn ) Opcode_Func_GetPtrData(Parameter,DEF_DWORD);
492 resultType.SetBasicType( DEF_DWORD );
[46]493 break;
[3]494 case FUNC_GETWORD:
[76]495 if( isCallOn ) Opcode_Func_GetPtrData(Parameter,DEF_WORD);
496 resultType.SetBasicType( DEF_WORD );
[46]497 break;
[3]498 case FUNC_GETBYTE:
[76]499 if( isCallOn ) Opcode_Func_GetPtrData(Parameter,DEF_BYTE);
500 resultType.SetBasicType( DEF_BYTE );
[46]501 break;
[76]502 default:
503 return false;
[3]504 }
[76]505 return true;
[3]506}
Note: See TracBrowser for help on using the repository browser.