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

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

例外処理機構実装中…

File size: 15.4 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 }
146 else
147 {
148 //仮想関数(オブジェクトメソッド)
149 // pObj -> vtbl_master_list -> vtbl1 -> func1
150 // -> func2
151 // -> func3
152 // -> vtbl2 -> func1
153 // -> func2
154 // -> func3
155
156 int vtblMasterListIndex;
157 pobj_c->GetVtblMasterListIndexAndVtblIndex( &userProc, vtblMasterListIndex, vtblIndex );
158
159 // vtblマスターリストのポインタを取得
160 //mov r11,qword ptr[rcx]
161 compiler.codeGenerator.op_mov_RM(sizeof(_int64),REG_R11,REG_RCX,0,MOD_BASE);
162
163 // vtblのポインタを取得
164 //mov r11,dword ptr[r11+vtblMasterListIndex]
165 compiler.codeGenerator.op_mov_RM( sizeof(_int64), REG_R11, REG_R11, vtblMasterListIndex, MOD_BASE_DISP32 );
166 }
167
[3]168 //mov rax,qword ptr[r11+func_index]
[345]169 if( vtblIndex * PTR_SIZE <= 0x7F )
170 {
171 compiler.codeGenerator.op_mov_RM(sizeof(_int64),REG_RAX,REG_R11,vtblIndex*PTR_SIZE,MOD_BASE_DISP8);
[3]172 }
[345]173 else
174 {
175 compiler.codeGenerator.op_mov_RM(sizeof(_int64),REG_RAX,REG_R11,vtblIndex*PTR_SIZE,MOD_BASE_DISP32);
[3]176 }
177 }
178 else{
179 //一般の関数
180
181 //mov rax,ProcAddr
[339]182 compiler.codeGenerator.op_addressof( REG_RAX, &userProc );
[3]183 }
184
[339]185 userProc.Using();
[3]186}
[339]187void Opcode_CreateDelegate( const CClass &dgClass, const char *methodInstanceName, const UserProc &userProc )
188{
189 /////////////////////////////////////////////////////////////////
190 // 関数ポインタをpush
191 /////////////////////////////////////////////////////////////////
192
193 //mov rax,AddressOf
194 _Opcode_Func_AddressOf( methodInstanceName, userProc );
195
196
197 if( userProc.GetMethod().IsDynamic() )
198 {
199 //mov rdx,rax
200 compiler.codeGenerator.op_mov_RR( REG_RDX, REG_RAX );
201
202 pobj_BlockReg->lock( REG_RDX );
203
204
205 /////////////////////////////////////////////////////////////////
206 // オブジェクト ポインタをpush
207 /////////////////////////////////////////////////////////////////
208
209 // オブジェクト名を取得
210 char objectName[VN_SIZE];
211 char memberName[VN_SIZE];
212 char *thisPtrName = "This";
213 Type type;
214 if( SplitMemberName( methodInstanceName, objectName, memberName ) )
215 {
216 if( GetVarType( objectName, type, false ) )
217 {
218 thisPtrName = objectName;
219 }
220 }
221
222 // オブジェクト ポインタを取得
223 RELATIVE_VAR relativeVar;
224 GetVarOffsetReadOnly( thisPtrName, &relativeVar, type );
225 if( !type.IsObject() )
226 {
227 extern int cp;
228 SetError(1,NULL,cp);
229 return;
230 }
231
232 SetVarPtrToReg( REG_RAX, &relativeVar );
233
234 //mov rcx,dword ptr[rax]
235 compiler.codeGenerator.op_mov_RM( sizeof(_int64), REG_RCX, REG_RAX, 0, MOD_BASE );
236
237 pobj_BlockReg->unlock( REG_RDX );
238 }
239 else
240 {
241 //mov rcx,rax
242 compiler.codeGenerator.op_mov_RR( REG_RCX, REG_RAX );
243 }
244
245
246 /////////////////////////////////////////////////////////////////
247 // call _CreateDynamicDelegate/_CreateStaticDelegate
248 /////////////////////////////////////////////////////////////////
249
250 std::vector<const UserProc *> subs;
251 if( userProc.GetMethod().IsDynamic() )
252 {
253 dgClass.GetStaticMethods().Enum( "_CreateDynamicDelegate", subs );
254 }
255 else
256 {
257 dgClass.GetStaticMethods().Enum( "_CreateStaticDelegate", subs );
258 }
259
260 // call _CreateDynamicDelegate
261 compiler.codeGenerator.op_call( subs[0] );
262}
263void Opcode_Func_AddressOf( const char *name, const Type &baseType, bool isCallOn, Type &resultType )
264{
265 extern int cp;
266 const UserProc *pUserProc;
267
268 const Parameters *pBaseParams = NULL;
269 if( baseType.IsProcPtr() )
270 {
271 // 左辺で関数ポインタを要求されているとき
272 pBaseParams = &compiler.GetObjectModule().meta.GetProcPointers()[baseType.GetIndex()]->Params();
273 }
274 else if( baseType.IsDelegate() )
275 {
276 // 左辺でデリゲートを要求されているとき
277 pBaseParams = &baseType.GetClass().GetDelegate().Params();
278 }
279
280 if( pBaseParams )
281 {
282 //左辺の型にのっとり、オーバーロードを解決
283
284 std::vector<const UserProc *> subs;
285 GetOverloadSubHash( name, subs );
286 if( subs.size() == 0 ){
287 SetError(27,name,cp);
288 return;
289 }
290
291 //オーバーロードを解決
292 pUserProc=OverloadSolution( name, subs, *pBaseParams, Type() );
293
294 if( isCallOn && baseType.IsDelegate() )
295 {
296 // コード生成を伴う場合はエラーチェックを行う
297 if( !pUserProc->Params().Equals( *pBaseParams )
298 || !pUserProc->ReturnType().Equals( baseType.GetClass().GetDelegate().ReturnType() ) )
299 {
300 if( baseType.IsDelegate() )
301 {
302 SetError(67, name, cp );
303 }
304 else
305 {
306 SetError(66, name, cp );
307 }
308 }
309 }
310
311 if(!pUserProc){
312 SetError(27,name,cp);
313 return;
314 }
315 }
316 else{
317 pUserProc=GetSubHash(name);
318 if(!pUserProc){
319 SetError(27,name,cp);
320 return;
321 }
322 }
323
324 if( baseType.IsDelegate() )
325 {
326 if( isCallOn )
327 {
328 // デリゲートのとき
329 Opcode_CreateDelegate( baseType.GetClass(), name, *pUserProc );
330 }
331 resultType = baseType;
332 }
333 else
334 {
335 if( isCallOn )
336 {
337 // 関数ポインタのとき
338 _Opcode_Func_AddressOf( name, *pUserProc );
339 }
340 resultType.SetBasicType( DEF_PTR_VOID );
341 }
342}
[79]343void Opcode_Func_SizeOf( const string &typeName ){
344 Type tempType;
[308]345 if( !compiler.StringToType( typeName, tempType ) ){
[79]346 SetError(3,typeName,cp);
347 return;
[64]348 }
[3]349
[79]350 int typeSize = ( tempType.IsObject() ) ?
351 tempType.GetClass().GetSize() : tempType.GetSize();
352
[3]353 //mov rax,size
[226]354 compiler.codeGenerator.op_mov_RV(sizeof(_int64),REG_RAX,typeSize);
[3]355}
[75]356void Opcode_Func_VarPtr( const char *Parameter, Type &resultType, bool isCallOn ){
357 if( isCallOn == false ){
358 // 戻り値の型を取得するだけ
359
360 //変数のアドレスを取得
361 if(!GetVarType( Parameter, resultType, true )) return;
362
363 resultType.PtrLevelUp();
364
365 return;
366 }
367
[3]368 RELATIVE_VAR RelativeVar;
369
370 //変数のアドレスを取得
[75]371 if(!GetVarOffsetReadOnly( Parameter, &RelativeVar, resultType )) return;
[3]372
[75]373 int beforeType = resultType.GetBasicType();
[64]374
[75]375 resultType.PtrLevelUp();
[46]376
[3]377 SetVarPtrToReg(REG_RAX,&RelativeVar);
[64]378
[109]379 // TODO: 取り除く(この動きはObjPtrに託す)
[130]380 /*
[64]381 if( beforeType == DEF_OBJECT && lstrcmpi( Parameter, "This" ) != 0 ){
382 //参照をオブジェクトポインタに変更
383
384 //mov rax,qword ptr[rax]
[226]385 compiler.codeGenerator.op_mov_RM( sizeof(_int64), REG_RAX, REG_RAX, 0, MOD_BASE );
[111]386
387 SetError(-120,NULL,cp);
[130]388 }*/
[3]389}
[109]390void Opcode_Func_ObjPtr( const char *Parameter, Type &resultType, bool isCallOn ){
391 if( isCallOn == false ){
392 // 戻り値の型を取得するだけ
393
394 //変数のアドレスを取得
395 if(!GetVarType( Parameter, resultType, true )) return;
396
397 resultType.PtrLevelUp();
398
399 return;
400 }
401
402 RELATIVE_VAR RelativeVar;
403
404 //変数のアドレスを取得
405 if(!GetVarOffsetReadOnly( Parameter, &RelativeVar, resultType )) return;
406
407 int beforeType = resultType.GetBasicType();
408
409 resultType.PtrLevelUp();
410
411 SetVarPtrToReg(REG_RAX,&RelativeVar);
412
[111]413 if( lstrcmpi( Parameter, "This" )==0 ){
414 // Thisの場合は特別にオブジェクトポインタが返ってくるので、何もせずに抜ける
415 }
416 else if( beforeType == DEF_OBJECT ){
[109]417 //参照をオブジェクトポインタに変更
418
419 //mov rax,qword ptr[rax]
[226]420 compiler.codeGenerator.op_mov_RM( sizeof(_int64), REG_RAX, REG_RAX, 0, MOD_BASE );
[109]421 }
422 else{
423 SetError(134,NULL,cp );
424 }
425}
[325]426
[330]427void Opcode_Func_delegate_call( const char *paramsStr, Type &resultType, bool isDynamicCall, bool isCallOn )
[325]428{
429 if( isCallOn )
430 {
431 int i = 0;
[330]432 char methodPtrParamStr[VN_SIZE];
433 i = GetOneParameter( paramsStr, i, methodPtrParamStr );
434
[339]435 char objPtrValueStr[VN_SIZE] = "";
[330]436 if( isDynamicCall )
437 {
438 i = GetOneParameter( paramsStr, i, objPtrValueStr );
439 }
440
441 Opcode_CallDelegate( compiler.pCompilingClass->GetDelegate(), methodPtrParamStr, objPtrValueStr, paramsStr + i );
[325]442 }
443
444 resultType = UserProc::CompilingUserProc().ReturnType();
445}
446
[357]447void Opcode_Func_System_Get_Bp()
448{
449 //mov rax,rbp
450 compiler.codeGenerator.op_mov_RR(REG_RAX,REG_RBP);
451}
[358]452void Opcode_Func_System_Get_Sp()
453{
454 //mov rax,rsp
455 compiler.codeGenerator.op_mov_RR(REG_RAX,REG_RSP);
456}
[357]457
[46]458void Opcode_Func_GetPtrData( const char *Parameter, const int type ){
[3]459 int reg=REG_RAX;
[75]460 Type tempType;
461 if( !NumOpe(&reg,Parameter,Type(),tempType) ){
462 return;
463 }
464 if(!tempType.IsWhole()){
[3]465 SetError(11,Parameter,cp);
466 return;
467 }
468
469 if(type==DEF_DOUBLE){
470 //movlpd xmm0,qword ptr[rax]
[226]471 compiler.codeGenerator.op_movlpd_RM(REG_XMM0,REG_RAX,0,MOD_BASE);
[3]472 }
473 else if(type==DEF_SINGLE){
474 //movss xmm0,dword ptr[rax]
[226]475 compiler.codeGenerator.op_movss_RM(REG_XMM0,REG_RAX,0,MOD_BASE);
[3]476 }
477 else{
478 //mov rax,ptr[rax]
[308]479 compiler.codeGenerator.op_mov_RM(Type(type).GetSize(),REG_RAX,REG_RAX,0,MOD_BASE);
[3]480 }
481}
482
[331]483bool Opcode_CallFunc( const char *Parameter, const int FuncNum, const Type &baseType, Type &resultType, bool isCallOn )
484{
[3]485 switch(FuncNum){
486 case FUNC_LEN:
[75]487 if( isCallOn ) Opcode_Func_Len(Parameter);
488 resultType.SetBasicType( DEF_LONG );
[46]489 break;
[3]490 case FUNC_ADDRESSOF:
[339]491 Opcode_Func_AddressOf( Parameter, baseType, isCallOn, resultType );
[46]492 break;
[3]493 case FUNC_SIZEOF:
[75]494 if( isCallOn ) Opcode_Func_SizeOf(Parameter);
495 resultType.SetBasicType( DEF_LONG );
[46]496 break;
[3]497 case FUNC_VARPTR:
[75]498 Opcode_Func_VarPtr( Parameter, resultType, isCallOn );
[46]499 break;
[109]500 case FUNC_OBJPTR:
501 Opcode_Func_ObjPtr( Parameter, resultType, isCallOn );
502 break;
[330]503 case FUNC_DELEGATE_DYNAMICMETHOD_CALL:
504 Opcode_Func_delegate_call( Parameter, resultType, true, isCallOn );
[325]505 break;
[330]506 case FUNC_DELEGATE_STATICMETHOD_CALL:
507 Opcode_Func_delegate_call( Parameter, resultType, false, isCallOn );
508 break;
[357]509 case FUNC_SYSTEM_GET_NOW_SCOPE_CATCH_ADDRESS:
510 if( isCallOn ) Exception::Opcode_Func_System_GetNowScopeCatchAddress();
[358]511 resultType.SetBasicType( DEF_PTR_VOID );
[357]512 break;
[359]513 case FUNC_SYSTEM_GET_NOW_SCOPE_FINALLY_ADDRESS:
514 if( isCallOn ) Exception::Opcode_Func_System_GetNowScopeFinallyAddress();
515 resultType.SetBasicType( DEF_PTR_VOID );
516 break;
[357]517 case FUNC_SYSTEM_GET_BP:
518 if( isCallOn ) Opcode_Func_System_Get_Bp();
[358]519 resultType.SetBasicType( DEF_INT64 );
[357]520 break;
[358]521 case FUNC_SYSTEM_GET_SP:
522 if( isCallOn ) Opcode_Func_System_Get_Sp();
523 resultType.SetBasicType( DEF_INT64 );
524 break;
[3]525
526 case FUNC_GETDOUBLE:
[75]527 if( isCallOn ) Opcode_Func_GetPtrData(Parameter,DEF_DOUBLE);
528 resultType.SetBasicType( DEF_DOUBLE );
[46]529 break;
[3]530 case FUNC_GETSINGLE:
[75]531 if( isCallOn ) Opcode_Func_GetPtrData(Parameter,DEF_SINGLE);
532 resultType.SetBasicType( DEF_SINGLE );
[46]533 break;
[3]534 case FUNC_GETQWORD:
[75]535 if( isCallOn ) Opcode_Func_GetPtrData(Parameter,DEF_QWORD);
536 resultType.SetBasicType( DEF_QWORD );
[46]537 break;
[3]538 case FUNC_GETDWORD:
[75]539 if( isCallOn ) Opcode_Func_GetPtrData(Parameter,DEF_DWORD);
540 resultType.SetBasicType( DEF_DWORD );
[46]541 break;
[3]542 case FUNC_GETWORD:
[75]543 if( isCallOn ) Opcode_Func_GetPtrData(Parameter,DEF_WORD);
544 resultType.SetBasicType( DEF_WORD );
[46]545 break;
[3]546 case FUNC_GETBYTE:
[75]547 if( isCallOn ) Opcode_Func_GetPtrData(Parameter,DEF_BYTE);
548 resultType.SetBasicType( DEF_BYTE );
[46]549 break;
[75]550 default:
551 return false;
[3]552 }
[75]553 return true;
[3]554}
Note: See TracBrowser for help on using the repository browser.