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

Last change on this file since 235 was 235, checked in by dai_9181, 17 years ago
File size: 12.9 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 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 compiler.codeGenerator.op_add_esp(4);
79 }
80 else if( resultType.IsSingle() ){
81 //fld dword ptr[esp]
82 compiler.codeGenerator.op_fld_ptr_esp(DEF_SINGLE);
83
84 //sub esp,4
85 compiler.codeGenerator.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 compiler.codeGenerator.op_add_esp(4);
129 }
130 else if( resultType.Is64() ){
131 //pop eax
132 compiler.codeGenerator.op_pop(REG_EAX);
133
134 //add esp,4
135 compiler.codeGenerator.op_add_esp(4);
136
137 //push eax
138 compiler.codeGenerator.op_push(REG_EAX);
139 }
140
141 //pop eax
142 compiler.codeGenerator.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 compiler.codeGenerator.op_pop(REG_EAX);
154
155 //push 0
156 compiler.codeGenerator.op_push_V( 0 );
157
158 //push eax
159 compiler.codeGenerator.op_push(REG_EAX);
160
161 //fild qword ptr[esp]
162 compiler.codeGenerator.op_fld_ptr_esp(DEF_INT64);
163
164 //add esp,8
165 compiler.codeGenerator.op_add_esp(8);
166}
167void Opcode_Func_Len(const char *Parameter){
168 BOOL bArrayHead;
169
170 const char *tempParm=Parameter;
171 char temporary[VN_SIZE];
172 char temp2[32];
173 Type type;
174 if( !GetVarType(Parameter,type,0) ){
175 sprintf(temporary,"_System_DummyStr2=%s",Parameter);
176 OpcodeCalc(temporary);
177
178 lstrcpy(temp2,"_System_DummyStr2");
179 tempParm=temp2;
180
181 type.SetType( DEF_OBJECT, compiler.GetMeta().GetClasses().GetStringClassPtr() );
182 }
183
184 if( type.IsStringClass() ){
185 //Stringオブジェクトの場合
186 sprintf(temporary,"%s.Length",tempParm);
187
188 int reg=REG_RAX;
189 NumOpe(temporary,Type(),Type());
190
191 //pop eax
192 compiler.codeGenerator.op_pop(REG_EAX);
193
194 return;
195 }
196
197 Subscripts subscripts;
198 RELATIVE_VAR RelativeVar;
199 if(!GetVarOffsetReadOnly(tempParm,&RelativeVar,type,&subscripts)) return;
200
201 if(type.GetBasicType()&FLAG_PTR){
202 type.SetBasicType( type.GetBasicType() & ( ~FLAG_PTR ) );
203
204 bArrayHead=1;
205 }
206 else bArrayHead=0;
207
208 int typeSize = type.GetSize();
209
210 if(bArrayHead) typeSize*=JumpSubScripts(subscripts);
211
212 //mov eax,typeSize
213 compiler.codeGenerator.op_mov_RV( REG_EAX, typeSize );
214}
215void Opcode_Func_AddressOf( const char *name ){
216 extern int cp;
217 const UserProc *pUserProc;
218
219 extern LONG_PTR ProcPtr_BaseIndex;
220 if(ProcPtr_BaseIndex!=-1){
221 //左辺の型にのっとり、オーバーロードを解決
222
223 std::vector<const UserProc *> subs;
224 GetOverloadSubHash( name, subs );
225 if( subs.size() == 0 ){
226 SetError(27,name,cp);
227 return;
228 }
229
230 //オーバーロードを解決
231 pUserProc=OverloadSolution(name,subs,compiler.GetMeta().GetProcPointers()[ProcPtr_BaseIndex]->Params(), Type() );
232
233 if(!pUserProc){
234 SetError(27,name,cp);
235 return;
236 }
237 }
238 else{
239 pUserProc=GetSubHash(name);
240 if(!pUserProc){
241 SetError(27,name,cp);
242 return;
243 }
244 }
245
246 if( pUserProc->IsVirtual() ){
247 ///////////////////////////////
248 // 仮想関数の場合
249 // thisポインタをrcxにコピー
250 ///////////////////////////////
251
252 const CClass *pobj_c;
253
254 char ObjectName[VN_SIZE];
255 int RefType;
256 SplitObjectName(name,ObjectName,&RefType);
257
258 if(ObjectName[0]){
259 if(lstrcmpi(ObjectName,"Super")==0) goto InClassMember;
260 else{
261 RELATIVE_VAR RelativeVar;
262 Type type;
263 if(!GetVarOffsetReadOnly(ObjectName,&RelativeVar,type)) return;
264 SetVarPtrToEax(&RelativeVar);
265
266 //mov ecx,eax
267 compiler.codeGenerator.op_mov_RR(REG_ECX,REG_EAX);
268
269 //参照タイプが整合しているかをチェック
270 if(type.GetBasicType()!=RefType) SetError(104,ObjectName,cp);
271
272 if(type.IsObjectPtr()){
273 //mov ecx,dword ptr[ecx]
274 compiler.codeGenerator.op_mov_RM(sizeof(long),REG_ECX,REG_ECX,0,MOD_BASE);
275 }
276 }
277 }
278 else{
279InClassMember:
280 //自身のオブジェクトのThisポインタをrcxにコピー
281 SetThisPtrToReg(REG_RCX);
282
283 pobj_c=compiler.pCompilingClass;
284 }
285
286
287 //仮想関数(オブジェクトメソッド)
288 //pObj->func_table->func1
289 // ->func2
290 // ->func3
291
292 //mov edx,dword ptr[ecx]
293 compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EDX, REG_ECX, 0, MOD_BASE );
294
295 int i2 = pobj_c->GetFuncNumInVtbl( pUserProc );
296
297 //mov eax,dword ptr[edx+func_index]
298 if(i2*PTR_SIZE<=0x7F){
299 compiler.codeGenerator.op_mov_RM(sizeof(long),REG_EAX,REG_EDX,i2*PTR_SIZE,MOD_BASE_DISP8);
300 }
301 else{
302 compiler.codeGenerator.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;
310 pobj_SubAddrSchedule->add(pUserProc,0);
311 obp+=sizeof(long);
312 }
313
314 pUserProc->Using();
315}
316void Opcode_Func_SizeOf( const string &typeName ){
317 Type tempType;
318 if( !Compiler::StringToType( typeName, tempType ) ){
319 SetError(3,typeName,cp);
320 return;
321 }
322
323 int typeSize = ( tempType.IsObject() ) ?
324 tempType.GetClass().GetSize() : tempType.GetSize();
325
326 //mov eax,size
327 compiler.codeGenerator.op_mov_RV( REG_EAX, typeSize );
328}
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
341 RELATIVE_VAR RelativeVar;
342
343 //変数のアドレスを取得
344 if(!GetVarOffsetReadOnly( Parameter, &RelativeVar, resultType )) return;
345
346 int beforeType = resultType.GetBasicType();
347
348 resultType.PtrLevelUp();
349
350 SetVarPtrToEax(&RelativeVar);
351
352 // TODO: 取り除く(この動きはObjPtrに託す)
353 /*
354 if( beforeType == DEF_OBJECT && lstrcmpi( Parameter, "This" ) != 0 ){
355 //参照をオブジェクトポインタに変更
356
357 //mov eax,dword ptr[eax]
358 compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EAX, REG_EAX, 0, MOD_BASE );
359
360 SetError(-120,NULL,cp);
361 }*/
362}
363void Opcode_Func_ObjPtr( const char *Parameter, Type &resultType, bool isCallOn ){
364 if( isCallOn == false ){
365 // 戻り値の型を取得するだけ
366
367 //変数のアドレスを取得
368 if(!GetVarType( Parameter, resultType, true )) return;
369
370 resultType.PtrLevelUp();
371
372 return;
373 }
374
375 RELATIVE_VAR RelativeVar;
376
377 //変数のアドレスを取得
378 if(!GetVarOffsetReadOnly( Parameter, &RelativeVar, resultType )) return;
379
380 int beforeType = resultType.GetBasicType();
381
382 resultType.PtrLevelUp();
383
384 SetVarPtrToEax(&RelativeVar);
385
386 if( lstrcmpi( Parameter, "This" )==0 ){
387 // Thisの場合は特別にオブジェクトポインタが返ってくるので、何もせずに抜ける
388 }
389 else if( beforeType == DEF_OBJECT ){
390 //参照をオブジェクトポインタに変更
391
392 //mov eax,dword ptr[eax]
393 compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EAX, REG_EAX, 0, MOD_BASE );
394 }
395 else{
396 SetError(134,NULL,cp );
397 }
398}
399void Opcode_Func_GetPtrData(const char *Parameter,const int type){
400 Type tempType;
401 if( !NumOpe(Parameter,Type(),tempType) ){
402 return;
403 }
404 if(!tempType.IsWhole()){
405 SetError(11,Parameter,cp);
406 return;
407 }
408 ChangeTypeToLong(tempType.GetBasicType());
409
410 if(type==DEF_DOUBLE){
411 //pop eax
412 compiler.codeGenerator.op_pop(REG_EAX);
413
414 //fld qword ptr[eax]
415 compiler.codeGenerator.PutOld(
416 (char)0xDD,
417 (char)0x00
418 );
419 }
420 else if(type==DEF_SINGLE||type==DEF_DWORD){
421 //pop eax
422 compiler.codeGenerator.op_pop(REG_EAX);
423
424 //mov eax,dword ptr[eax]
425 compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EAX, REG_EAX, 0, MOD_BASE );
426 }
427 else if(type==DEF_QWORD){
428 //pop ecx
429 compiler.codeGenerator.op_pop(REG_ECX);
430
431 //mov eax,dword ptr[ecx]
432 compiler.codeGenerator.op_mov_RM(sizeof(long),REG_EAX,REG_ECX,0,MOD_BASE);
433
434 //mov edx,dword ptr[ecx+sizeof(long)]
435 compiler.codeGenerator.op_mov_RM(sizeof(long),REG_EDX,REG_ECX,sizeof(long),MOD_BASE_DISP8);
436 }
437 else if(type==DEF_WORD){
438 //pop ebx
439 compiler.codeGenerator.op_pop(REG_EBX);
440
441 //xor eax,eax
442 compiler.codeGenerator.op_xor_RR(REG_EAX);
443
444 //mov ax,word ptr[ebx]
445 compiler.codeGenerator.op_mov_RM( sizeof(short), REG_EAX, REG_EBX, 0, MOD_BASE );
446 }
447 else if(type==DEF_BYTE){
448 //pop ebx
449 compiler.codeGenerator.op_pop(REG_EBX);
450
451 //xor eax,eax
452 compiler.codeGenerator.op_xor_RR(REG_EAX);
453
454 //mov al,byte ptr[ebx]
455 compiler.codeGenerator.op_mov_RM( sizeof(char), REG_EAX, REG_EBX, 0, MOD_BASE );
456 }
457}
458
459bool Opcode_CallFunc( const char *Parameter, const int FuncNum, Type &resultType, bool isCallOn ){
460 switch(FuncNum){
461 case FUNC_FIX:
462 if( isCallOn ) Opcode_Func_Fix(Parameter);
463 resultType.SetBasicType( DEF_LONG );
464 break;
465 case FUNC_CUDBL:
466 if( isCallOn ) Opcode_Func_CUDbl(Parameter);
467 resultType.SetBasicType( DEF_DOUBLE );
468 break;
469 case FUNC_LEN:
470 if( isCallOn ) Opcode_Func_Len(Parameter);
471 resultType.SetBasicType( DEF_LONG );
472 break;
473 case FUNC_ADDRESSOF:
474 if( isCallOn ) Opcode_Func_AddressOf(Parameter);
475 resultType.SetBasicType( DEF_PTR_VOID );
476 break;
477 case FUNC_SIZEOF:
478 if( isCallOn ) Opcode_Func_SizeOf(Parameter);
479 resultType.SetBasicType( DEF_LONG );
480 break;
481 case FUNC_VARPTR:
482 Opcode_Func_VarPtr( Parameter, resultType, isCallOn );
483 break;
484 case FUNC_OBJPTR:
485 Opcode_Func_ObjPtr( Parameter, resultType, isCallOn );
486 break;
487
488 case FUNC_GETDOUBLE:
489 if( isCallOn ) Opcode_Func_GetPtrData(Parameter,DEF_DOUBLE);
490 resultType.SetBasicType( DEF_DOUBLE );
491 break;
492 case FUNC_GETSINGLE:
493 if( isCallOn ) Opcode_Func_GetPtrData(Parameter,DEF_SINGLE);
494 resultType.SetBasicType( DEF_SINGLE );
495 break;
496 case FUNC_GETQWORD:
497 if( isCallOn ) Opcode_Func_GetPtrData(Parameter,DEF_QWORD);
498 resultType.SetBasicType( DEF_QWORD );
499 break;
500 case FUNC_GETDWORD:
501 if( isCallOn ) Opcode_Func_GetPtrData(Parameter,DEF_DWORD);
502 resultType.SetBasicType( DEF_DWORD );
503 break;
504 case FUNC_GETWORD:
505 if( isCallOn ) Opcode_Func_GetPtrData(Parameter,DEF_WORD);
506 resultType.SetBasicType( DEF_WORD );
507 break;
508 case FUNC_GETBYTE:
509 if( isCallOn ) Opcode_Func_GetPtrData(Parameter,DEF_BYTE);
510 resultType.SetBasicType( DEF_BYTE );
511 break;
512 default:
513 return false;
514 }
515 return true;
516}
Note: See TracBrowser for help on using the repository browser.