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

Last change on this file since 425 was 425, checked in by dai_9181, 16 years ago

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

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