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

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

コード全体のリファクタリングを実施

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