source: dev/trunk/abdev/BasicCompiler64/Compile_Func.cpp@ 431

Last change on this file since 431 was 427, checked in by dai_9181, 17 years ago

[426]を64bit版にマージ。

File size: 16.5 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, "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;
15 if( lstrcmpi( FuncName, "ObjPtr" ) == 0 ) return FUNC_OBJPTR;
16 if( lstrcmpi( FuncName, "__delegate_dynamicmethod_call" ) == 0 ) return FUNC_DELEGATE_DYNAMICMETHOD_CALL;
17 if( lstrcmpi( FuncName, "__delegate_staticmethod_call" ) == 0 ) return FUNC_DELEGATE_STATICMETHOD_CALL;
18 if( lstrcmpi( FuncName, "_System_GetNowScopeCatchAddresses" ) == 0 )return FUNC_SYSTEM_GET_NOW_SCOPE_CATCH_ADDRESS;
19 if( lstrcmpi( FuncName, "_System_GetNowScopeFinallyAddresses" ) == 0 )return FUNC_SYSTEM_GET_NOW_SCOPE_FINALLY_ADDRESS;
20 if( lstrcmpi( FuncName, "_System_GetBp" ) == 0 ) return FUNC_SYSTEM_GET_BP;
21 if( lstrcmpi( FuncName, "_System_GetSp" ) == 0 ) return FUNC_SYSTEM_GET_SP;
22 if( lstrcmp( FuncName, "_System_New" ) == 0 ) return FUNC_SYSTEM_NEW;
23 if( lstrcmpi( FuncName, "GetDouble" ) == 0 ) return FUNC_GETDOUBLE;
24 if( lstrcmpi( FuncName, "GetSingle" ) == 0 ) return FUNC_GETSINGLE;
25 if( lstrcmpi( FuncName, "GetQWord" ) == 0 ) return FUNC_GETQWORD;
26 if( lstrcmpi( FuncName, "GetDWord" ) == 0 ) return FUNC_GETDWORD;
27 if( lstrcmpi( FuncName, "GetWord" ) == 0 ) return FUNC_GETWORD;
28 if( lstrcmpi( FuncName, "GetByte" ) == 0 ) return FUNC_GETBYTE;
29 return 0;
30}
31void Opcode_Func_Len( const char *Parameter ){
32 BOOL bArrayHead;
33
34 const char *tempParm=Parameter;
35 char temporary[VN_SIZE];
36 char temp2[32];
37 Type type;
38 if( !GetVarType(Parameter,type,0) ){
39 sprintf(temporary,"_System_DummyStr2=%s",Parameter);
40 OpcodeCalc(temporary);
41
42 lstrcpy(temp2,"_System_DummyStr2");
43 tempParm=temp2;
44
45 type.SetType( DEF_OBJECT, compiler.GetObjectModule().meta.GetClasses().GetStringClassPtr() );
46 }
47
48 if( type.IsStringClass() ){
49 //Stringオブジェクトの場合
50 sprintf(temporary,"%s.Length",tempParm);
51
52 int reg=REG_RAX;
53 NumOpe(&reg,temporary,Type(),Type());
54 return;
55 }
56
57 Subscripts subscripts;
58 RELATIVE_VAR RelativeVar;
59 if(!GetVarOffsetReadOnly(tempParm,&RelativeVar,type,&subscripts)) return;
60
61 if(type.GetBasicType()&FLAG_PTR){
62 type.SetBasicType( type.GetBasicType() & ( ~FLAG_PTR ) );
63
64 bArrayHead=1;
65 }
66 else bArrayHead=0;
67
68 int typeSize = type.GetSize();
69
70 if(bArrayHead) typeSize*=JumpSubScripts(subscripts);
71
72 //mov rax,TypeSize
73 compiler.codeGenerator.op_mov_RV(sizeof(_int64),REG_RAX,typeSize);
74
75 return;
76}
77
78void _Opcode_Func_AddressOf( const char *methodInstanceName, const UserProc &userProc )
79{
80 if( userProc.IsVirtual() )
81 {
82 ///////////////////////////////
83 // 仮想関数の場合
84 // thisポインタをrcxにコピー
85 ///////////////////////////////
86
87 const CClass *pobj_c;
88
89 char ObjectName[VN_SIZE];
90 ReferenceKind referenceKind;
91 SplitObjectName(methodInstanceName,ObjectName, referenceKind );
92
93 if(ObjectName[0]){
94 if(lstrcmpi(ObjectName,"Super")==0) goto InClassMember;
95 else{
96 RELATIVE_VAR RelativeVar;
97 Type type;
98 if(!GetVarOffsetReadOnly(ObjectName,&RelativeVar,type)) return;
99 SetVarPtrToReg(REG_RCX,&RelativeVar);
100
101 //参照タイプが整合しているかをチェック
102 if( !( type.IsObject() && referenceKind == RefDot
103 || type.IsObjectPtr() && referenceKind == RefPointer ) )
104 {
105 SetError(104,ObjectName,cp);
106 }
107
108 if(type.IsObjectPtr()){
109 //mov rcx,qword ptr[rcx]
110 compiler.codeGenerator.op_mov_RM(sizeof(_int64),REG_RCX,REG_RCX,0,MOD_BASE);
111 }
112 }
113 }
114 else{
115InClassMember:
116 //自身のオブジェクトのThisポインタをrcxにコピー
117 SetThisPtrToReg(REG_RCX);
118
119 pobj_c=compiler.pCompilingClass;
120 }
121
122
123 int vtblIndex;
124 if( pobj_c->IsInterface() )
125 {
126 // インターフェイスメソッド
127
128 int offset_vtbl = compiler.GetObjectModule().meta.GetClasses().GetInterfaceInfoClassPtr()->GetMemberOffset( "__vtbl" );
129
130 // vtblのポインタを取得
131 //mov r11,qword ptr[rcx+offset_vtbl]
132 compiler.codeGenerator.op_mov_RM(sizeof(_int64),REG_R11,REG_RCX,offset_vtbl,MOD_BASE_DISP8);
133
134 int offset_this = compiler.GetObjectModule().meta.GetClasses().GetInterfaceInfoClassPtr()->GetMemberOffset( "__this" );
135
136 // インターフェイスの場合は更に__thisを取得する
137 //mov rcx,qword ptr[rcx+offset_this]
138 compiler.codeGenerator.op_mov_RM(sizeof(_int64),REG_RCX,REG_RCX,offset_this,MOD_BASE_DISP8);
139
140 int vtblMasterListIndex;
141 pobj_c->GetVtblMasterListIndexAndVtblIndex( &userProc, vtblMasterListIndex, vtblIndex );
142 if( vtblMasterListIndex != 0 )
143 {
144 SetError();
145 }
146 }
147 else if( pobj_c->IsComInterface() )
148 {
149 //仮想関数(オブジェクトメソッド)
150 // pObj -> vtbl1 -> func1
151 // -> func2
152 // -> func3
153
154 int vtblMasterListIndex;
155 pobj_c->GetVtblMasterListIndexAndVtblIndex( &userProc, vtblMasterListIndex, vtblIndex );
156
157 // vtblのポインタを取得
158 //mov r11,qword ptr[rcx]
159 compiler.codeGenerator.op_mov_RM(sizeof(_int64),REG_R11,REG_RCX,0,MOD_BASE);
160 }
161 else
162 {
163 //仮想関数(オブジェクトメソッド)
164 // pObj -> vtbl_master_list -> vtbl1 -> func1
165 // -> func2
166 // -> func3
167 // -> vtbl2 -> func1
168 // -> func2
169 // -> func3
170
171 int vtblMasterListIndex;
172 pobj_c->GetVtblMasterListIndexAndVtblIndex( &userProc, vtblMasterListIndex, vtblIndex );
173
174 // vtblマスターリストのポインタを取得
175 //mov r11,qword ptr[rcx+sizeof(com_vtbl)]
176 compiler.codeGenerator.op_mov_RM(sizeof(_int64),REG_R11,REG_RCX,PTR_SIZE,MOD_BASE_DISP8);
177
178 // vtblのポインタを取得
179 //mov r11,dword ptr[r11+vtblMasterListIndex]
180 compiler.codeGenerator.op_mov_RM( sizeof(_int64), REG_R11, REG_R11, vtblMasterListIndex, MOD_BASE_DISP32 );
181 }
182
183 //mov rax,qword ptr[r11+func_index]
184 if( vtblIndex * PTR_SIZE <= 0x7F )
185 {
186 compiler.codeGenerator.op_mov_RM(sizeof(_int64),REG_RAX,REG_R11,vtblIndex*PTR_SIZE,MOD_BASE_DISP8);
187 }
188 else
189 {
190 compiler.codeGenerator.op_mov_RM(sizeof(_int64),REG_RAX,REG_R11,vtblIndex*PTR_SIZE,MOD_BASE_DISP32);
191 }
192 }
193 else{
194 //一般の関数
195
196 //mov rax,ProcAddr
197 compiler.codeGenerator.op_addressof( REG_RAX, &userProc );
198 }
199
200 userProc.Using();
201}
202void Opcode_CreateDelegate( const CClass &dgClass, const char *methodInstanceName, const UserProc &userProc )
203{
204 /////////////////////////////////////////////////////////////////
205 // 関数ポインタをpush
206 /////////////////////////////////////////////////////////////////
207
208 //mov rax,AddressOf
209 _Opcode_Func_AddressOf( methodInstanceName, userProc );
210
211
212 if( userProc.GetMethod().IsDynamic() )
213 {
214 //mov rdx,rax
215 compiler.codeGenerator.op_mov_RR( REG_RDX, REG_RAX );
216
217 pobj_BlockReg->lock( REG_RDX );
218
219
220 /////////////////////////////////////////////////////////////////
221 // オブジェクト ポインタをpush
222 /////////////////////////////////////////////////////////////////
223
224 // オブジェクト名を取得
225 char objectName[VN_SIZE];
226 char memberName[VN_SIZE];
227 char *thisPtrName = "This";
228 Type type;
229 if( SplitMemberName( methodInstanceName, objectName, memberName ) )
230 {
231 if( GetVarType( objectName, type, false ) )
232 {
233 thisPtrName = objectName;
234 }
235 }
236
237 // オブジェクト ポインタを取得
238 RELATIVE_VAR relativeVar;
239 GetVarOffsetReadOnly( thisPtrName, &relativeVar, type );
240 if( !type.IsObject() )
241 {
242 extern int cp;
243 SetError(1,NULL,cp);
244 return;
245 }
246
247 SetVarPtrToReg( REG_RAX, &relativeVar );
248
249 //mov rcx,dword ptr[rax]
250 compiler.codeGenerator.op_mov_RM( sizeof(_int64), REG_RCX, REG_RAX, 0, MOD_BASE );
251
252 pobj_BlockReg->unlock( REG_RDX );
253 }
254 else
255 {
256 //mov rcx,rax
257 compiler.codeGenerator.op_mov_RR( REG_RCX, REG_RAX );
258 }
259
260
261 /////////////////////////////////////////////////////////////////
262 // call _CreateDynamicDelegate/_CreateStaticDelegate
263 /////////////////////////////////////////////////////////////////
264
265 std::vector<const UserProc *> subs;
266 if( userProc.GetMethod().IsDynamic() )
267 {
268 dgClass.GetStaticMethods().Enum( "_CreateDynamicDelegate", subs );
269 }
270 else
271 {
272 dgClass.GetStaticMethods().Enum( "_CreateStaticDelegate", subs );
273 }
274
275 // call _CreateDynamicDelegate
276 compiler.codeGenerator.op_call( subs[0] );
277}
278void Opcode_Func_AddressOf( const char *name, const Type &baseType, bool isCallOn, Type &resultType )
279{
280 extern int cp;
281 const UserProc *pUserProc;
282
283 const Parameters *pBaseParams = NULL;
284 if( baseType.IsProcPtr() )
285 {
286 // 左辺で関数ポインタを要求されているとき
287 pBaseParams = &compiler.GetObjectModule().meta.GetProcPointers()[baseType.GetIndex()]->Params();
288 }
289 else if( baseType.IsDelegate() )
290 {
291 // 左辺でデリゲートを要求されているとき
292 pBaseParams = &baseType.GetClass().GetDelegate().Params();
293 }
294
295 if( pBaseParams )
296 {
297 //左辺の型にのっとり、オーバーロードを解決
298
299 std::vector<const UserProc *> subs;
300 GetOverloadSubHash( name, subs );
301 if( subs.size() == 0 ){
302 SetError(27,name,cp);
303 return;
304 }
305
306 //オーバーロードを解決
307 pUserProc=OverloadSolution( name, subs, *pBaseParams, Type(), Type() );
308
309 if( isCallOn && baseType.IsDelegate() )
310 {
311 // コード生成を伴う場合はエラーチェックを行う
312 if( !pUserProc->Params().Equals( *pBaseParams )
313 || !pUserProc->ReturnType().Equals( baseType.GetClass().GetDelegate().ReturnType() ) )
314 {
315 if( baseType.IsDelegate() )
316 {
317 SetError(67, name, cp );
318 }
319 else
320 {
321 SetError(66, name, cp );
322 }
323 }
324 }
325
326 if(!pUserProc){
327 SetError(27,name,cp);
328 return;
329 }
330 }
331 else{
332 pUserProc=GetSubHash(name);
333 if(!pUserProc){
334 SetError(27,name,cp);
335 return;
336 }
337 }
338
339 if( baseType.IsDelegate() )
340 {
341 if( isCallOn )
342 {
343 // デリゲートのとき
344 Opcode_CreateDelegate( baseType.GetClass(), name, *pUserProc );
345 }
346 resultType = baseType;
347 }
348 else
349 {
350 if( isCallOn )
351 {
352 // 関数ポインタのとき
353 _Opcode_Func_AddressOf( name, *pUserProc );
354 }
355 resultType.SetBasicType( DEF_PTR_VOID );
356 }
357}
358void Opcode_Func_SizeOf( const string &typeName ){
359 Type tempType;
360 if( !compiler.StringToType( typeName, tempType ) ){
361 SetError(3,typeName,cp);
362 return;
363 }
364
365 int typeSize = ( tempType.IsObject() ) ?
366 tempType.GetClass().GetSize() : tempType.GetSize();
367
368 //mov rax,size
369 compiler.codeGenerator.op_mov_RV(sizeof(_int64),REG_RAX,typeSize);
370}
371void Opcode_Func_VarPtr( 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 SetVarPtrToReg(REG_RAX,&RelativeVar);
393
394 // TODO: 取り除く(この動きはObjPtrに託す)
395 /*
396 if( beforeType == DEF_OBJECT && lstrcmpi( Parameter, "This" ) != 0 ){
397 //参照をオブジェクトポインタに変更
398
399 //mov rax,qword ptr[rax]
400 compiler.codeGenerator.op_mov_RM( sizeof(_int64), REG_RAX, REG_RAX, 0, MOD_BASE );
401
402 SetError(-120,NULL,cp);
403 }*/
404}
405void Opcode_Func_ObjPtr( const char *Parameter, Type &resultType, bool isCallOn ){
406 if( isCallOn == false ){
407 // 戻り値の型を取得するだけ
408
409 //変数のアドレスを取得
410 if(!GetVarType( Parameter, resultType, true )) return;
411
412 resultType.PtrLevelUp();
413
414 return;
415 }
416
417 RELATIVE_VAR RelativeVar;
418
419 //変数のアドレスを取得
420 if(!GetVarOffsetReadOnly( Parameter, &RelativeVar, resultType )) return;
421
422 int beforeType = resultType.GetBasicType();
423
424 resultType.PtrLevelUp();
425
426 SetVarPtrToReg(REG_RAX,&RelativeVar);
427
428 if( lstrcmpi( Parameter, "This" )==0 ){
429 // Thisの場合は特別にオブジェクトポインタが返ってくるので、何もせずに抜ける
430 }
431 else if( beforeType == DEF_OBJECT ){
432 //参照をオブジェクトポインタに変更
433
434 //mov rax,qword ptr[rax]
435 compiler.codeGenerator.op_mov_RM( sizeof(_int64), REG_RAX, REG_RAX, 0, MOD_BASE );
436 }
437 else{
438 SetError(134,NULL,cp );
439 }
440}
441
442void Opcode_Func_delegate_call( const char *paramsStr, Type &resultType, bool isDynamicCall, bool isCallOn )
443{
444 if( isCallOn )
445 {
446 int i = 0;
447 char methodPtrParamStr[VN_SIZE];
448 i = GetOneParameter( paramsStr, i, methodPtrParamStr );
449
450 char objPtrValueStr[VN_SIZE] = "";
451 if( isDynamicCall )
452 {
453 i = GetOneParameter( paramsStr, i, objPtrValueStr );
454 }
455
456 Opcode_CallDelegate( compiler.pCompilingClass->GetDelegate(), methodPtrParamStr, objPtrValueStr, paramsStr + i );
457 }
458
459 resultType = UserProc::CompilingUserProc().ReturnType();
460}
461
462void Opcode_Func_System_Get_Bp()
463{
464 //mov rax,rbp
465 compiler.codeGenerator.op_mov_RR(REG_RAX,REG_RBP);
466}
467void Opcode_Func_System_Get_Sp()
468{
469 //mov rax,rsp
470 compiler.codeGenerator.op_mov_RR(REG_RAX,REG_RSP);
471}
472
473void Opcode_Func_System_New( const char *parameter, Type &resultType, bool isCallOn )
474{
475 if( !compiler.StringToType( parameter, resultType ) )
476 {
477 SetError();
478 return;
479 }
480 if( !resultType.IsObject() )
481 {
482 SetError();
483 return;
484 }
485
486 if( isCallOn )
487 {
488 Type tempResultType;
489 if( !Operator_New( parameter, resultType, tempResultType ) )
490 {
491 return;
492 }
493
494 if( !resultType.Equals( tempResultType ) )
495 {
496 SetError();
497 }
498 }
499}
500
501void Opcode_Func_GetPtrData( const char *Parameter, const int type ){
502 int reg=REG_RAX;
503 Type tempType;
504 if( !NumOpe(&reg,Parameter,Type(),tempType) ){
505 return;
506 }
507 if(!tempType.IsWhole()){
508 SetError(11,Parameter,cp);
509 return;
510 }
511
512 if(type==DEF_DOUBLE){
513 //movlpd xmm0,qword ptr[rax]
514 compiler.codeGenerator.op_movlpd_RM(REG_XMM0,REG_RAX,0,MOD_BASE);
515 }
516 else if(type==DEF_SINGLE){
517 //movss xmm0,dword ptr[rax]
518 compiler.codeGenerator.op_movss_RM(REG_XMM0,REG_RAX,0,MOD_BASE);
519 }
520 else{
521 //mov rax,ptr[rax]
522 compiler.codeGenerator.op_mov_RM(Type(type).GetSize(),REG_RAX,REG_RAX,0,MOD_BASE);
523 }
524}
525
526bool Opcode_CallFunc( const char *Parameter, const int FuncNum, const Type &baseType, Type &resultType, bool isCallOn )
527{
528 switch(FuncNum){
529 case FUNC_LEN:
530 if( isCallOn ) Opcode_Func_Len(Parameter);
531 resultType.SetBasicType( DEF_LONG );
532 break;
533 case FUNC_ADDRESSOF:
534 Opcode_Func_AddressOf( Parameter, baseType, isCallOn, resultType );
535 break;
536 case FUNC_SIZEOF:
537 if( isCallOn ) Opcode_Func_SizeOf(Parameter);
538 resultType.SetBasicType( DEF_LONG );
539 break;
540 case FUNC_VARPTR:
541 Opcode_Func_VarPtr( Parameter, resultType, isCallOn );
542 break;
543 case FUNC_OBJPTR:
544 Opcode_Func_ObjPtr( Parameter, resultType, isCallOn );
545 break;
546 case FUNC_DELEGATE_DYNAMICMETHOD_CALL:
547 Opcode_Func_delegate_call( Parameter, resultType, true, isCallOn );
548 break;
549 case FUNC_DELEGATE_STATICMETHOD_CALL:
550 Opcode_Func_delegate_call( Parameter, resultType, false, isCallOn );
551 break;
552 case FUNC_SYSTEM_GET_NOW_SCOPE_CATCH_ADDRESS:
553 if( isCallOn ) Exception::Opcode_Func_System_GetNowScopeCatchAddress();
554 resultType.SetBasicType( DEF_PTR_VOID );
555 break;
556 case FUNC_SYSTEM_GET_NOW_SCOPE_FINALLY_ADDRESS:
557 if( isCallOn ) Exception::Opcode_Func_System_GetNowScopeFinallyAddress();
558 resultType.SetBasicType( DEF_PTR_VOID );
559 break;
560 case FUNC_SYSTEM_GET_BP:
561 if( isCallOn ) Opcode_Func_System_Get_Bp();
562 resultType.SetBasicType( DEF_INT64 );
563 break;
564 case FUNC_SYSTEM_GET_SP:
565 if( isCallOn ) Opcode_Func_System_Get_Sp();
566 resultType.SetBasicType( DEF_INT64 );
567 break;
568 case FUNC_SYSTEM_NEW:
569 Opcode_Func_System_New( Parameter, resultType, isCallOn );
570 break;
571
572 case FUNC_GETDOUBLE:
573 if( isCallOn ) Opcode_Func_GetPtrData(Parameter,DEF_DOUBLE);
574 resultType.SetBasicType( DEF_DOUBLE );
575 break;
576 case FUNC_GETSINGLE:
577 if( isCallOn ) Opcode_Func_GetPtrData(Parameter,DEF_SINGLE);
578 resultType.SetBasicType( DEF_SINGLE );
579 break;
580 case FUNC_GETQWORD:
581 if( isCallOn ) Opcode_Func_GetPtrData(Parameter,DEF_QWORD);
582 resultType.SetBasicType( DEF_QWORD );
583 break;
584 case FUNC_GETDWORD:
585 if( isCallOn ) Opcode_Func_GetPtrData(Parameter,DEF_DWORD);
586 resultType.SetBasicType( DEF_DWORD );
587 break;
588 case FUNC_GETWORD:
589 if( isCallOn ) Opcode_Func_GetPtrData(Parameter,DEF_WORD);
590 resultType.SetBasicType( DEF_WORD );
591 break;
592 case FUNC_GETBYTE:
593 if( isCallOn ) Opcode_Func_GetPtrData(Parameter,DEF_BYTE);
594 resultType.SetBasicType( DEF_BYTE );
595 break;
596 default:
597 return false;
598 }
599 return true;
600}
Note: See TracBrowser for help on using the repository browser.