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

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

Try-Catchを試験的に実装。
(まだ下記の動作しか実装していません)
・Try
・Catch(パラメータ無し)
・Throw(パラメータ無し)

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