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

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

ジェネリクスのベースを実装

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