source: dev/BasicCompiler32/Compile_Func.cpp@ 122

Last change on this file since 122 was 117, checked in by dai_9181, 18 years ago

String/ObjectをSystem名前空間に依存しない特殊型として扱うようにした

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