source: dev/trunk/abdev/BasicCompiler32/Compile_Func.cpp@ 193

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