source: dev/trunk/abdev/BasicCompiler64/NumOpe.cpp@ 315

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

静的リンクライブラリにより、複数のグローバル領域が存在することになったのでそれぞれを関数ベースに分けた

File size: 30.0 KB
RevLine 
[206]1#include "stdafx.h"
2
[183]3#include <jenga/include/smoothie/Smoothie.h>
4#include <jenga/include/smoothie/LexicalAnalysis.h>
5
6#include <Compiler.h>
7
[3]8#include "../BasicCompiler_Common/common.h"
9#include "Opcode.h"
10
[76]11void NewStringObject(int reg, const char *str){
[3]12 ///////////////////////////////////////////////////////
13 // lpszTextを元にStringオブジェクトを生成し、
14 // オブジェクトポインタをregに格納する
15 ///////////////////////////////////////////////////////
16
17
18 //////////////////////////////////////////////////////
19 ///// レジスタ資源のバックアップ
20 { BACKUP_REGISTER_RESOURCE
21 //////////////////////////////////////////////////////
22
[76]23 char *parameter = (char *)malloc( lstrlen( str ) + 32 );
24 sprintf( parameter, "\"%s\"%c%c*Char", str, 1, ESC_AS );
[64]25 SetStringQuotes( parameter );
26
[266]27 Operator_New( *compiler.GetObjectModule().meta.GetClasses().GetStringClassPtr(), "", parameter, Type( DEF_OBJECT, *compiler.GetObjectModule().meta.GetClasses().GetStringClassPtr() ) );
[3]28
[64]29 free( parameter );
[3]30
[64]31 //mov reg,rax
[226]32 compiler.codeGenerator.op_mov_RR( reg, REG_RAX );
[3]33
34 /////////////////////////////////////////////
35 ////// レジスタ資源を復元
36 RESTORE_REGISTER_RESOURCE
37 }////////////////////////////////////////////
38}
39
40void SetUseRegFromRax(int type,int UseReg,int XmmReg){
41 if(IsRealNumberType(type)){
42 //実数型
43 if(XmmReg==REG_XMM4){
44 if(type==DEF_DOUBLE){
45 //movsd qword ptr[rsp+offset],xmm0 ※スタックフレームを利用
46 pobj_sf->push(REG_XMM0,sizeof(double));
47 }
48 if(type==DEF_SINGLE){
49 //movss dword ptr[rsp+offset],xmm0 ※スタックフレームを利用
50 pobj_sf->push(REG_XMM0,sizeof(float));
51 }
52 }
53 else{
54 if(type==DEF_DOUBLE){
55 //movsd xmm_reg,xmm0
[226]56 compiler.codeGenerator.op_movsd_RR(XmmReg,REG_XMM0);
[3]57 }
58 else if(type==DEF_SINGLE){
59 //movss xmm_reg,xmm0
[226]60 compiler.codeGenerator.op_movss_RR(XmmReg,REG_XMM0);
[3]61 }
62 }
63 }
64 else{
65 //整数型
66 if(UseReg==REG_R14){
67 //mov qword ptr[rsp+offset],rax ※スタックフレームを利用
68 pobj_sf->push(REG_RAX);
69 }
70 else{
71 //mov reg,rax
[226]72 compiler.codeGenerator.op_mov_RR(UseReg,REG_RAX);
[3]73 }
74 }
75}
76
[75]77void ExtendRegToBigType( int reg, int bigBasicType, int baseBasicType ){
78 switch( Type::GetBasicSize( bigBasicType ) ){
79 case sizeof(_int64):
80 ExtendTypeTo64(baseBasicType,reg);
81 break;
82 case sizeof(long):
83 ExtendTypeTo32(baseBasicType,reg);
84 break;
85 case sizeof(short):
86 ExtendTypeTo16(baseBasicType,reg);
87 break;
88 }
89}
90
[97]91
92bool VarToReg( RELATIVE_VAR &relativeVar, const Type &baseType, Type &resultType ){
93 int UseReg=pobj_reg->GetNextReg();
94 int XmmReg=pobj_reg->GetNextXmmReg();
95
96 //大きな型への暗黙の変換
97 int bigType = AutoBigCast(baseType.GetBasicType(),resultType.GetBasicType());
98
99 if(resultType.GetBasicType()&FLAG_PTR){
100 //配列ポインタ
101 resultType.SetBasicType( GetPtrType(resultType.GetBasicType()^FLAG_PTR) );
102
103 SetVarPtrToReg(UseReg,&relativeVar);
104 }
105 else if(resultType.IsReal()){
106 //実数型
107 if( resultType.IsDouble() )
108 SetXmmReg_DoubleVariable(&relativeVar,XmmReg);
109 if( resultType.IsSingle() )
110 SetXmmReg_SingleVariable(&relativeVar,XmmReg);
111 }
112 else if( resultType.IsWhole() || resultType.IsObject()){
113 //整数型
[308]114 SetReg_WholeVariable(resultType,&relativeVar,UseReg);
[97]115 }
116 else if( resultType.IsStruct() ){
117 //構造体ポインタをUseRegへ格納(構造体は値型)
118 SetVarPtrToReg(UseReg,&relativeVar);
119 }
120 else{
121 return false;
122 }
123
124 if( resultType.GetBasicType() != bigType ){
125 // 大きな型へ変換された場合
126 // ※レジスタの値をキャストする
127 ExtendRegToBigType( UseReg, bigType, resultType.GetBasicType() );
128
129 resultType.SetBasicType( bigType );
130 }
131
132 return true;
133}
[308]134bool TermMemberOpe( const Type &leftType, const Type &baseType, Type &resultType, const char *termFull, const char *termLeft, const char *member )
135{
136 const CClass &objClass = leftType.GetClass();
[97]137
138 int UseReg=pobj_reg->GetNextReg();
139 int XmmReg=pobj_reg->GetNextXmmReg();
140
141
[308]142 if( GetMemberType( leftType, member, resultType, 0, false ) ){
[97]143 // メンバが見つかったとき
144
145 //オブジェクトポインタをr11にコピー
[226]146 compiler.codeGenerator.op_mov_RR( REG_R11, UseReg );
[97]147
148 RELATIVE_VAR relativeVar;
149 relativeVar.dwKind=VAR_DIRECTMEM;
150
151 if( !_member_offset(
152 true, //エラー表示あり
153 false, //読み込み専用
154 objClass,
155 member,&relativeVar,resultType,0)){
156 return false;
157 }
158
159 if( !VarToReg( relativeVar, baseType, resultType ) ){
160 SetError(11,termFull,cp);
161 }
162
163 return true;
164 }
165
166
167 ///////////////////////////////////////////////////////////////////
168 // 動的メソッドを検索
169 ///////////////////////////////////////////////////////////////////
[206]170 vector<const UserProc *> userProcs;
[97]171
172 char methodName[VN_SIZE], lpPtrOffset[VN_SIZE], parameter[VN_SIZE], dummy[1];
[206]173 ReferenceKind refType;
[97]174 lstrcpy( methodName, member );
175 GetVarFormatString(methodName,parameter,lpPtrOffset,dummy,refType);
176
[135]177 objClass.GetMethods().Enum( methodName, userProcs );
[97]178 if(userProcs.size()){
179 //オーバーロードを解決
[206]180 const UserProc *pUserProc = OverloadSolutionWithStrParam(termFull,userProcs,parameter,termLeft);
[97]181
182 if( pUserProc ){
183
184 resultType = pUserProc->ReturnType();
185
186
187 //////////////////////////////////////////////////////
188 ///// レジスタ資源のバックアップ
189 { BACKUP_REGISTER_RESOURCE
190 //////////////////////////////////////////////////////
191
192 //オブジェクトポインタをスタックに入れておく
193 //mov qword ptr[rsp+offset],reg ※スタックフレームを利用
194 pobj_sf->push( UseReg );
195
[308]196 if( !Opcode_CallProc(parameter,pUserProc,PROCFLAG_NEW,termLeft ) ){
[97]197 //レジスタ資源を復元
198 RESTORE_REGISTER_RESOURCE
199
200 return false;
201 }
202
203 pobj_sf->pop();
204
205 /////////////////////
206 // 戻り値の処理
207 /////////////////////
208
209 //大きな型への暗黙の変換
210 int bigType = AutoBigCast(baseType.GetBasicType(), resultType.GetBasicType() );
211
212 if( resultType.GetBasicType() != bigType ){
213 // 大きな型へ変換された場合
214 // ※レジスタの値をキャストする
215 ExtendRegToBigType( REG_RAX, bigType, resultType.GetBasicType() );
216
217 resultType.SetBasicType( bigType );
218 }
219
220 SetUseRegFromRax(resultType.GetBasicType(),UseReg,XmmReg);
221
222
223 /////////////////////////////////////////////
224 ////// レジスタ資源を復元
225 RESTORE_REGISTER_RESOURCE
226 }////////////////////////////////////////////
227
228 return true;
229 }
230 }
231
232 return false;
233}
[128]234bool TermOpe( const char *term, const Type &baseType, Type &resultType, bool &isLiteral, BOOL *pbUseHeap, bool isWantObject, bool *pIsClassName, bool isProcedureCallOnly ){
[97]235 char parameter[VN_SIZE];
236
237 // Withを解決
238 char termFull[VN_SIZE];
239 if(term[0]=='.'){
240 GetWithName(termFull);
241 lstrcat(termFull,term);
242 }
243 else lstrcpy(termFull,term);
244
245 char termLeft[VN_SIZE];
246 lstrcpy(termLeft,termFull);
247
248 // パース
249 char member[VN_SIZE];
[206]250 ReferenceKind refType;
251 if( SplitMemberName( termFull, termLeft, member, refType ) ){
[97]252 ///////////////////////////////////////////////////////////////////
253 // オブジェクトとメンバに分解できるとき
254 // termLeft.member
255 ///////////////////////////////////////////////////////////////////
256
257 isLiteral = false;
258
259 // オブジェクト側の型を取得
260 bool isClassName = false;
261 Type leftType;
[128]262 if( GetTermType( termLeft, leftType, isLiteral, &isClassName ) ){
[266]263 if( isClassName == false && compiler.GetObjectModule().meta.GetBlittableTypes().IsExist( leftType ) ){
[128]264 // 左側のオブジェクト部分がBlittable型のとき
265
266 char temporary[VN_SIZE];
267 lstrcpy( temporary, termLeft );
268 sprintf( termLeft, "%s(%s)",
[266]269 compiler.GetObjectModule().meta.GetBlittableTypes().Find( leftType ).GetCreateStaticMethodFullName().c_str(),
[128]270 temporary );
271 }
272 }
273
274 if( !TermOpe( termLeft, baseType, leftType, isLiteral, pbUseHeap, true, &isClassName ) ){
[103]275 goto globalArea;
[97]276 }
277
278 if( isClassName ){
279 // 静的メンバ/メソッドの場合
280 goto globalArea;
281 }
282
283 if( !leftType.HasMember() ){
284 // メンバを持たない型の場合
285 return false;
286 }
287
[308]288 return TermMemberOpe( leftType, baseType, resultType, termFull, termLeft, member );
[97]289 }
[103]290globalArea:
[97]291
292 //////////////////////////////////////////////
293 // クラス名かどうかをチェック(静的メンバ用)
294 //////////////////////////////////////////////
295
296 if( pIsClassName ){
[266]297 if( compiler.GetObjectModule().meta.GetClasses().Find( termFull ) ){
[97]298 *pIsClassName = true;
299 return true;
300 }
301 }
302
303
304 /////////////////////////////////////////////////////////////////
305 // グローバル属性エリア
306 /////////////////////////////////////////////////////////////////
307
308 int UseReg=pobj_reg->GetNextReg();
309 int XmmReg=pobj_reg->GetNextXmmReg();
310
311
[122]312 if(lstrcmpi(termFull,"This")==0 && isProcedureCallOnly == false ){
[97]313 //Thisオブジェクト
[206]314 resultType.SetType( DEF_OBJECT, compiler.pCompilingClass );
[97]315
316 SetThisPtrToReg( UseReg );
317
318 isLiteral = false;
319
320 return true;
321 }
322
323
324 //////////////////////////////////////
325 // 関数(DLL、ユーザー定義、組み込み)
326 //////////////////////////////////////
327 char procName[VN_SIZE];
328 char temporary[8192];
329
330 int i2=GetCallProcName(termFull,procName);
331 if(termFull[i2]=='('){
332 int i4=GetStringInPare_RemovePare(parameter,termFull+i2+1);
333
334 void *pInfo;
335 int idProc=GetProc(procName,(void **)&pInfo);
336
337 if(idProc){
338 //閉じカッコ")"に続く文字がNULLでないとき
339 if(termFull[i2+1+i4+1]!='\0'){
340 SetError(42,NULL,cp);
341 }
342
343
344 //////////////////////////////////////////////////////
345 ///// レジスタ資源のバックアップ
346 { BACKUP_REGISTER_RESOURCE
347 //////////////////////////////////////////////////////
348
349
350 ////////////////
351 // 呼び出し
352 ////////////////
353
354 CallProc(idProc,pInfo,procName,parameter,resultType);
355
356
357 /////////////////////
358 // 戻り値の処理
359 /////////////////////
360
361 //大きな型への暗黙の変換
362 int bigType = AutoBigCast(baseType.GetBasicType(), resultType.GetBasicType() );
363
364 if( resultType.GetBasicType() != bigType ){
365 // 大きな型へ変換された場合
366 // ※レジスタの値をキャストする
367 ExtendRegToBigType( REG_RAX, bigType, resultType.GetBasicType() );
368
369 resultType.SetBasicType( bigType );
370 }
371
372 SetUseRegFromRax(resultType.GetBasicType(),UseReg,XmmReg);
373
374 /////////////////////////////////////////////
375 ////// レジスタ資源を復元
376 RESTORE_REGISTER_RESOURCE
377 }////////////////////////////////////////////
378
379 if(resultType.IsStruct()){
380 //構造体が戻ったときはヒープ領域にインスタンスが格納されている
381 //※後にfreeする必要あり
382 // TODO: 解放はGCに任せる
383 *pbUseHeap = 1;
384 }
385
386 isLiteral = false;
387
388 return true;
389 }
390
[266]391 ConstMacro *pConstMacro = compiler.GetObjectModule().meta.GetGlobalConstMacros().Find( procName );
[206]392 if( pConstMacro )
393 {
394 if( pConstMacro->GetCalcBuffer( parameter, temporary ) )
395 {
396 /////////////////////////
397 // マクロ関数
398 /////////////////////////
[97]399
[206]400 //閉じカッコ")"に続く文字がNULLでないときはエラーにする
401 if(termFull[i2+1+i4+1]!='\0') SetError(42,NULL,cp);
[97]402
[206]403 //マクロ関数の場合
404 NumOpe(&UseReg, temporary,Type(),resultType);
405
406 if(!IS_LITERAL(resultType.GetIndex())){
407 //リテラル値ではなかったとき
408 isLiteral = false;
409 }
410
411 return true;
[97]412 }
413 }
414 }
[122]415 else if( isProcedureCallOnly ){
416 // 関数呼び出し以外は受け付けない
417 return false;
418 }
[97]419
420
421 ////////////////////////////////
422 // インデクサ(getアクセサ)
423 ////////////////////////////////
424
425 char VarName[VN_SIZE],ArrayElements[VN_SIZE];
426 GetArrayElement(termFull,VarName,ArrayElements);
427 if(ArrayElements[0]){
428 GetVarType(VarName,resultType,false);
429 if( resultType.IsObject() ){
430 CallIndexerGetterProc(UseReg,&resultType.GetClass(),VarName,ArrayElements,resultType);
431
432 isLiteral = false;
433
434 return true;
435 }
436 }
437
438
439 ////////////////////////////////
440 // 変数
441 ////////////////////////////////
442
443 RELATIVE_VAR relativeVar;
444 if(GetVarOffset(
445 false, //エラー表示なし
446 false, //読み込み専用
447 termFull,
448 &relativeVar,resultType)){
449 //////////
450 // 変数
451 //////////
452
453 if( !VarToReg( relativeVar, baseType, resultType ) ){
454 SetError(11,termFull,cp);
455 }
456
457 isLiteral = false;
458
459 return true;
460 }
461
462/*
463 ////////////////////////////////
464 // 型名
465 ////////////////////////////////
466
[308]467 if( compiler.StringToType( termFull, resultType ) ){
[97]468 resultType.SetBasicType( resultType.GetBasicType() | FLAG_CAST );
469 return true;
470 }*/
471
472
473 /////////////////////////////////
474 // プロパティ用のメソッド
475 /////////////////////////////////
476
477 //配列要素を排除
478 GetArrayElement(termFull,VarName,ArrayElements);
479
480 if(GetSubHash(VarName,0)){
481
482 //////////////////////////////////////////////////////
483 ///// レジスタ資源のバックアップ
484 { BACKUP_REGISTER_RESOURCE
485 //////////////////////////////////////////////////////
486
487 CallPropertyMethod(termFull,NULL,resultType);
488
489 //大きな型への暗黙の変換
490 int bigType = AutoBigCast(baseType.GetBasicType(), resultType.GetBasicType() );
491
492 if( resultType.GetBasicType() != bigType ){
493 // 大きな型へ変換された場合
494 // ※レジスタの値をキャストする
495 ExtendRegToBigType( REG_RAX, bigType, resultType.GetBasicType() );
496
497 resultType.SetBasicType( bigType );
498 }
499
500 SetUseRegFromRax(resultType.GetBasicType(),UseReg,XmmReg);
501
502 /////////////////////////////////////////////
503 ////// レジスタ資源を復元
504 RESTORE_REGISTER_RESOURCE
505 }////////////////////////////////////////////
506
507 if(resultType.IsStruct()){
508 //構造体が戻ったときはヒープ領域にインスタンスが格納されている
509 //※後にfreeする必要あり
510 // TODO: 解放はGCに任せる
511 *pbUseHeap = 1;
512 }
513
514 isLiteral = false;
515
516 return true;
517 }
518
519
520 return false;
521}
522
[255]523bool _numope( int *pReg,
[75]524 const char *expression,
525 const Type &baseType,
526 Type &resultType,
[255]527 BOOL *pbUseHeap )
528{
[75]529
[97]530 int i,i2,i3;
531 char temporary[1024],temp2[1024];
[3]532
[75]533 if(expression[0]=='\0'){
[3]534 SetError(1,NULL,cp);
[75]535 return false;
[3]536 }
537
[93]538 if( !baseType.IsNull() && expression[0] == '[' ){
539 // リテラル配列の場合
[3]540
[93]541 if( !baseType.IsPointer() ){
542 SetError(1,NULL,cp);
543 return false;
544 }
545 Type tempBaseType( baseType );
546 tempBaseType.PtrLevelDown();
547
548 char *buffer = (char *)malloc( lstrlen( expression ) + 1 );
549 lstrcpy( buffer, expression );
550 RemoveStringBracket( buffer );
551
552 void *binary = malloc( 1 );
553 int num = 0;
554
555 i = 0;
556 while( buffer[i] ){
557 i = GetOneParameter( buffer, i, temporary );
558 if( buffer[i] == ',' ){
559 i++;
560 }
561
562 Type resultType;
563 _int64 i64data;
564 if( !StaticCalculation( true, temporary, tempBaseType.GetBasicType(), &i64data, resultType ) ){
565 return false;
566 }
567 if( !resultType.IsWhole() ){
568 // TODO: 実数に未対応
569 SetError();
570 return false;
571 }
572
573 binary = realloc( binary, ( num + 1 ) * tempBaseType.GetSize() );
574 memcpy( (char *)binary + (num * tempBaseType.GetSize()), &i64data, tempBaseType.GetSize() );
575 num++;
576 }
577
[266]578 i2 = compiler.GetObjectModule().dataTable.AddBinary( binary, num * tempBaseType.GetSize() );
[93]579
580 //mov reg,i2
[242]581 compiler.codeGenerator.op_mov_RV(sizeof(_int64),*pReg,i2, Schedule::DataTable );
[93]582
583 free( buffer );
584
585 resultType = baseType;
586
587 return true;
588 }
589
[254]590 bool isLiteralCalculation;
591 if( !NumOpe_GetType( expression, baseType, resultType, &isLiteralCalculation ) )
592 {
593 return false;
594 }
595 if( isLiteralCalculation )
596 {
597 //右辺値が数値の定数式の場合
598 _int64 i64data;
599 StaticCalculation(true, expression,baseType.GetBasicType(),&i64data,resultType);
[93]600
[254]601 if(resultType.IsReal()){
602 if(baseType.IsReal()) resultType=baseType;
603
604 int xmmReg = REG_XMM0;
605
606 if(resultType.IsDouble()){
[266]607 i3 = compiler.GetObjectModule().dataTable.Add( i64data );
[254]608
609 //movlpd xmm_reg,qword ptr[data table offset]
610 compiler.codeGenerator.op_movlpd_RM( xmmReg, 0, i3, MOD_DISP32, Schedule::DataTable );
611 }
612 if(resultType.IsSingle()){
613 double dbl;
614 memcpy(&dbl,&i64data,sizeof(_int64));
615
616 float flt;
617 int i32data;
618 flt=(float)dbl;
619 memcpy(&i32data,&flt,sizeof(long));
620
[266]621 i3 = compiler.GetObjectModule().dataTable.Add( i32data );
[254]622
623 //movss xmm_reg,dword ptr[data table offset]
624 compiler.codeGenerator.op_movss_RM( xmmReg, 0, i3, MOD_DISP32, Schedule::DataTable );
625 }
626 }
627 else{
628 if(!resultType.Is64()){
629 //整数(符号有り/無し)
630
631 i3=(long)i64data;
632
633 if(resultType.GetBasicSize()==sizeof(char)) i3=i3&0x000000FF;
634 if(resultType.GetBasicSize()==sizeof(short)) i3=i3&0x0000FFFF;
635
636 i64data=(_int64)i3;
637 }
638
639 //mov reg,i64data
640 compiler.codeGenerator.op_mov_RV64(*pReg,i64data);
641 }
642 return true;
643 }
644
645 if(expression[0]==1&& expression[1]==ESC_NEW ){
646 //New演算子(オブジェクト生成)
647
648 if( pobj_BlockReg->check(REG_RAX) ){
649 SetError();
650 }
651
652 //////////////////////////////////////////////////////
653 ///// レジスタ資源のバックアップ
654 { BACKUP_REGISTER_RESOURCE
655 //////////////////////////////////////////////////////
656
657 if( !Operator_New( expression+2, baseType, resultType ) ){
658 return false;
659 }
660
661 /////////////////////////////////////////////
662 ////// レジスタ資源を復元
663 RESTORE_REGISTER_RESOURCE
664 }////////////////////////////////////////////
665
666 //mov reg,rax
667 compiler.codeGenerator.op_mov_RR( *pReg, REG_RAX );
668
669 return true;
670 }
671
672
[3]673 /////////////////////////////////
674 // 式要素を逆ポーランド式で取得
675 /////////////////////////////////
676
677 char *values[255];
678 long calc[255];
679 long stack[255];
680 int pnum;
[75]681 if(!GetNumOpeElements(expression,&pnum,values,calc,stack)){
[3]682 for(i=0;i<pnum;i++){
683 if(values[i]) HeapDefaultFree(values[i]);
684 }
685 return 0;
686 }
687
688
689
690 ////////////////////////////////
691 // 演算部分のコード生成を開始
692 ////////////////////////////////
693
694 BOOL bError;
695 bError=0;
696
697 //リテラル値のみの計算かどうかを判別するためのフラグ
698 BOOL bLiteralCalculation=1;
699
700 double dbl;
701 int sp;
[75]702 int type_stack[255];
[3]703 LONG_PTR index_stack[255];
[79]704 bool isNothing_stack[255];
[3]705 BOOL bUseHeap[255];
706 _int64 i64data;
707 int UseReg,XmmReg;
708 BOOL bXmm;
709 for(i=0,sp=0;i<pnum;i++){
710 int idCalc;
711 idCalc=calc[i]%100;
712
713 if(idCalc){
[75]714 if(type_stack[sp-2]==DEF_OBJECT){
[79]715 if( idCalc == CALC_AS
716 && type_stack[sp-1] == ( DEF_OBJECT | FLAG_CAST )
717 && index_stack[sp-1] == index_stack[sp-2]
718 || isNothing_stack[sp-2] ){
719 // 同一の型、またはNothingに対するAsはAs演算子を呼び出さない
[3]720 }
[94]721 else if( idCalc == CALC_AS
722 && type_stack[sp-1] == ( DEF_OBJECT | FLAG_CAST )
723 && ( ((CClass *)index_stack[sp-1])->IsEqualsOrSubClass( (CClass *)index_stack[sp-2] ) || ((CClass *)index_stack[sp-2])->IsEqualsOrSubClass( (CClass *)index_stack[sp-1] )
724 )){
725 // ダウンキャストを許可する
726 }
[131]727 else if( idCalc == CALC_AS
728 && type_stack[sp-1] == ( DEF_OBJECT | FLAG_CAST ) && ((CClass *)index_stack[sp-1])->IsInterface()
729 ){
730 // インターフェイスへのキャスト
731 // TODO: 実装
732 CastToInterface( pobj_reg->GetLockingReg(), REG_R15, *(CClass *)index_stack[sp-2], *(CClass *)index_stack[sp-1] );
733 }
[79]734 else{
735 //オーバーロードされたオペレータを呼び出す
736 i2=CallOperatorProc(idCalc,baseType,type_stack,index_stack,bUseHeap,sp);
737 if(i2==0){
738 if(idCalc==CALC_EQUAL) lstrcpy(temp2,"==");
739 else GetCalcName(idCalc,temp2);
740 sprintf(temporary,"Operator %s",temp2);
741 SetError(27,temporary,cp);
742 goto error;
743 }
744 else if(i2==-1) goto error;
[3]745
[79]746 continue;
747 }
[3]748 }
749
[75]750 if(!CheckCalcType(idCalc,type_stack,sp)) goto error;
[3]751 }
752
753 switch(idCalc){
754 //数値
755 case 0:
756 index_stack[sp]=-1;
[79]757 isNothing_stack[sp] = false;
[3]758 bUseHeap[sp]=0;
759
760 UseReg=pobj_reg->GetNextReg();
761 XmmReg=pobj_reg->GetNextXmmReg();
762
763 bXmm=0;
764
765 char *term;
766 term=values[i];
767
[97]768 if( calc[i+1]%100 == CALC_AS ){
769 // As演算子の右辺値
770 //型名
[308]771 if( compiler.StringToType( term, resultType ) ){
[97]772 resultType.SetBasicType( resultType.GetBasicType() | FLAG_CAST );
773 }
774 else{
775 SetError(3, term, cp );
776 goto error;
777 }
778
779 type_stack[sp] = resultType.GetBasicType();
780 index_stack[sp] = resultType.GetIndex();
781 sp++;
782
783 break;
784 }
785
[3]786 if(term[0]=='\"'){
787 //リテラル文字列
788 if(!RemoveStringQuotes(term)){
789 SetError(43,NULL,cp);
790 goto error;
791 }
792 i3=lstrlen(term);
793StrLiteral:
[76]794
[97]795 if( baseType.IsObject() || baseType.IsNull() ){
796 //要求タイプがオブジェクト、または未定のとき
[3]797
[97]798 //String型オブジェクトを生成
799 NewStringObject(UseReg,term);
[3]800
[97]801 type_stack[sp]=DEF_OBJECT;
[266]802 index_stack[sp]=(LONG_PTR)compiler.GetObjectModule().meta.GetClasses().GetStringClassPtr();
[97]803 bLiteralCalculation=0;
[3]804
[97]805 if(bXmm) pobj_reg->LockXmmReg();
806 else pobj_reg->LockReg();
[3]807
[97]808 sp++;
809 break;
[3]810 }
811
[75]812 type_stack[sp]=typeOfPtrChar;
[3]813 bLiteralCalculation=0;
814
[266]815 i2 = compiler.GetObjectModule().dataTable.AddString( term, i3 );
[3]816
817 //mov reg,i2
[242]818 compiler.codeGenerator.op_mov_RV(sizeof(_int64),UseReg,i2, Schedule::DataTable);
[3]819
820 if(UseReg==REG_R14){
821 //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用
822 pobj_sf->push(REG_R14);
823 }
824 }
825 else if((term[0]=='e'||term[0]=='E')&&
826 (term[1]=='x'||term[1]=='X')&&
827 term[2]=='\"'){
828 //拡張版リテラル文字列(エスケープシーケンス可能)
829 if(!RemoveStringQuotes(term+2)){
830 SetError(43,NULL,cp);
831 goto error;
832 }
833 i3=FormatString_EscapeSequence(term+2);
834 term+=2;
835
836 goto StrLiteral;
837 }
838 else if(IsVariableTopChar(term[0])||
839 term[0]=='*'||
840 (term[0]=='.'&&IsVariableTopChar(term[1]))){
841 //////////////////
842 // 何らかの識別子
843
[97]844 bool isLiteral;
845 if( TermOpe( term, baseType, resultType, isLiteral, &bUseHeap[sp] ) ){
846 if(resultType.IsNull()){
847 //戻り値が存在しないとき
848 for(i2=0;;i2++){
849 if(term[i2]=='('||term[i2]=='\0'){
850 term[i2]=0;
851 break;
[49]852 }
853 }
[97]854 SetError(38,term,cp);
[3]855
[97]856 goto error;
857 }
[3]858
[97]859 type_stack[sp] = resultType.GetBasicType();
860 index_stack[sp] = resultType.GetIndex();
[3]861
[97]862 if( !isLiteral ){
863 bLiteralCalculation=0;
864 }
[3]865
[97]866 if( resultType.GetBasicType() & FLAG_CAST ){
867 // 型名のみ
868 SetError();
869 }
870 else{
871 if( resultType.IsReal() == false && UseReg==REG_R14 ){
872 //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用
873 pobj_sf->push(REG_R14);
874 }
875 if( resultType.IsReal() && XmmReg==REG_XMM4 ){
876 if(resultType.IsDouble()){
877 //movsd qword ptr[rsp+offset],xmm4 ※スタックフレームを利用
878 pobj_sf->push(REG_XMM4,sizeof(double));
[3]879 }
[97]880 if(resultType.IsSingle()){
881 //movss dword ptr[rsp+offset],xmm4 ※スタックフレームを利用
882 pobj_sf->push(REG_XMM4,sizeof(float));
[75]883 }
[3]884 }
885
[97]886 if( resultType.IsReal() ){
887 pobj_reg->LockXmmReg();
[3]888 }
[97]889 else{
890 pobj_reg->LockReg();
891 }
[3]892 }
893
[97]894 sp++;
895 break;
[3]896 }
897
898
[67]899 // Nothing
900 if( lstrcmp( term, "Nothing" ) == 0 ){
[79]901 isNothing_stack[sp] = true;
902
[75]903 type_stack[sp] = DEF_OBJECT;
904 if( baseType.IsObject() ){
905 index_stack[sp] = baseType.GetIndex();
[67]906 }
907 else{
[266]908 index_stack[sp] = (LONG_PTR)compiler.GetObjectModule().meta.GetClasses().GetObjectClassPtr();
[67]909 }
910
911 bLiteralCalculation = 0;
912
913 //xor reg,reg
[226]914 compiler.codeGenerator.op_zero_reg( UseReg );
[67]915
916 if(UseReg==REG_R14){
917 //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用
918 pobj_sf->push(REG_R14);
919 }
920
921 pobj_reg->LockReg();
922 sp++;
923 break;
924 }
925
926
[3]927 //////////////
928 // 定数の場合
929 //////////////
930
[266]931 i3 = compiler.GetObjectModule().meta.GetGlobalConsts().GetBasicType(term);
[9]932 if(i3){
[266]933 if( compiler.GetObjectModule().meta.GetGlobalConsts().IsStringPtr( term ) ){
[103]934 //リテラル文字列
935
[266]936 double dbl = compiler.GetObjectModule().meta.GetGlobalConsts().GetDoubleData(term);
[103]937 memcpy(&i64data,&dbl,sizeof(double));
938
939 //バイト数
940 i3=lstrlen((char *)i64data);
941
942 memcpy(term,(char *)i64data,i3);
943 term[i3]=0;
944 goto StrLiteral;
945 }
946
[75]947 type_stack[sp] = i3;
[3]948 if(IsRealNumberType(i3)){
949 //実数
[266]950 double dbl = compiler.GetObjectModule().meta.GetGlobalConsts().GetDoubleData(term);
[3]951 memcpy(&i64data,&dbl,sizeof(double));
952 goto Literal;
953 }
954 else if(IsWholeNumberType(i3)){
955 //整数
[266]956 i64data = compiler.GetObjectModule().meta.GetGlobalConsts().GetWholeData(term);
[3]957 goto Literal;
958 }
[9]959 /*else if(i3==DEF_STRING){
[3]960 //リテラル文字列
961
962 //バイト数
963 i3=(int)dbl;
964
965 memcpy(term,temporary,i3);
966 goto StrLiteral;
[9]967 }*/
[3]968 else{
969 SetError(1,NULL,0);
970 goto error;
971 }
972 }
973
974
975 //該当する識別子が見当たらないときはエラー扱いにする
976 bError=1;
977 SetError(3,term,cp);
[75]978 type_stack[sp]=DEF_DOUBLE;
[3]979 }
980 else{
981 //リテラル値
[75]982 type_stack[sp]=GetLiteralValue(term,&i64data,baseType.GetBasicType());
[3]983Literal:
[75]984 if(type_stack[sp]==DEF_DOUBLE){
[3]985 //64ビット浮動小数型
986 bXmm=1;
987
988 if(XmmReg==REG_XMM4){
989 //mov r14,i64data
[232]990 compiler.codeGenerator.op_mov_RV64(REG_R14,i64data);
[3]991
992
993 //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用
994 pobj_sf->push(REG_R14);
995 }
996 else{
[266]997 i3 = compiler.GetObjectModule().dataTable.Add( i64data );
[3]998
999 //movlpd xmm_reg,qword ptr[data table offset]
[242]1000 compiler.codeGenerator.op_movlpd_RM( XmmReg, 0, i3, MOD_DISP32, Schedule::DataTable );
[3]1001 }
1002 }
[75]1003 else if(type_stack[sp]==DEF_SINGLE){
[3]1004 //32ビット浮動小数型
1005 bXmm=1;
1006
1007 float flt;
1008 int i32data;
1009 memcpy(&dbl,&i64data,sizeof(double));
1010 flt=(float)dbl;
1011 memcpy(&i32data,&flt,sizeof(long));
1012
1013 if(XmmReg==REG_XMM4){
[97]1014 SetError(); // TODO: 未実装
[3]1015 //push term
[226]1016 //compiler.codeGenerator.op_push_value(i32data);
[3]1017 }
1018 else{
[266]1019 i3=compiler.GetObjectModule().dataTable.Add( i32data );
[3]1020
1021 //movss xmm_reg,dword ptr[data table offset]
[242]1022 compiler.codeGenerator.op_movss_RM( XmmReg, 0, i3, MOD_DISP32, Schedule::DataTable );
[3]1023 }
1024 }
1025 else{
1026 //整数
1027
1028 index_stack[sp]=GetLiteralIndex(i64data);
1029
1030 //mov reg,i64data
[232]1031 compiler.codeGenerator.op_mov_RV64(UseReg,i64data);
[3]1032
1033 if(UseReg==REG_R14){
1034 //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用
1035 pobj_sf->push(REG_R14);
1036 }
1037 }
1038 }
1039
1040 if(bXmm) pobj_reg->LockXmmReg();
1041 else pobj_reg->LockReg();
1042
1043 sp++;
1044 break;
1045
1046 //論理演算子
1047 case CALC_XOR:
1048 case CALC_OR:
1049 case CALC_AND:
[75]1050 if(!CalcTwoTerm_Logical(idCalc,type_stack,index_stack,&sp)) goto error;
[3]1051 break;
1052 case CALC_NOT:
1053 //value[sp-1]=Not value[sp-1]
1054 //NOT演算子
[75]1055 if(!Calc_Not(type_stack,sp)) goto error;
[3]1056 break;
1057
1058 //比較演算子
1059 case CALC_PE: //value[sp-2] <= value[sp-1]
1060 case CALC_QE: //value[sp-2] >= value[sp-1]
1061 case CALC_P: //value[sp-2] < value[sp-1]
1062 case CALC_Q: //value[sp-2] > value[sp-1]
1063 case CALC_NOTEQUAL: //value[sp-2] <> value[sp-1]
1064 case CALC_EQUAL: //value[sp-2] = value[sp-1]
[75]1065 if(!CalcTwoTerm_Relational(idCalc,type_stack,index_stack,&sp)) goto error;
[3]1066 break;
1067
1068 //ビットシフト
1069 case CALC_SHL: //value[sp-2] << value[sp-1]
1070 case CALC_SHR: //value[sp-2] >> value[sp-1]
[75]1071 if(!Calc_Shift(idCalc,type_stack,&sp)) goto error;
[3]1072 break;
1073
1074 //算術演算
1075 case CALC_ADDITION:
1076 case CALC_SUBTRACTION:
1077 case CALC_PRODUCT:
[75]1078 if(!CalcTwoTerm_Arithmetic(idCalc,type_stack,index_stack,&sp)) goto error;
[3]1079 break;
1080 case CALC_MOD:
1081 //value[sp-2]%=value[sp-1]
1082 //剰余演算
[75]1083 if(!Calc_Mod(type_stack,index_stack,&sp)) goto error;
[3]1084 break;
1085 case CALC_QUOTIENT:
1086 //value[sp-2]/=value[sp-1];
1087 //除算
[75]1088 if(!Calc_Divide(type_stack,&sp,baseType.GetBasicType())) goto error;
[3]1089 break;
1090 case CALC_INTQUOTIENT:
1091 //value[sp-2]/=value[sp-1]
1092 //整数除算
[75]1093 if(!Calc_IntDivide(type_stack,index_stack,&sp)) goto error;
[3]1094 break;
1095 case CALC_MINUSMARK:
1096 //value[sp-1]=-value[sp-1]
1097 //符号反転
[75]1098 if(!Calc_MinusMark(type_stack,sp)) goto error;
[3]1099 break;
1100 case CALC_POWER:
1101 //べき乗演算(浮動小数点演算のみ)
[75]1102 if(!Calc_Power(type_stack,&sp)) goto error;
[3]1103 break;
1104 case CALC_AS:
1105 //キャスト
[75]1106 if(!Calc_Cast(type_stack,index_stack,&sp)) goto error;
[3]1107 break;
[41]1108 case CALC_BYVAL:
1109 //ポインタ型→参照型
[75]1110 if( PTR_LEVEL( type_stack[sp-1] ) <= 0 ){
[41]1111 //ポインタ型ではないとき
1112 SetError( 3, NULL, cp );
1113 goto error;
1114 }
[3]1115
[75]1116 type_stack[sp-1] = PTR_LEVEL_DOWN( type_stack[sp-1] );
[41]1117
1118 break;
1119
[3]1120 default:
1121 SetError(300,NULL,cp);
[41]1122 goto error;
[3]1123 }
1124 }
1125
1126 if(bError) goto error;
1127
1128 if(sp!=1){
1129 SetError(1,NULL,cp);
1130 goto error;
1131 }
1132
1133 if(bLiteralCalculation){
[255]1134 SetError();
[3]1135 }
1136 else{
1137 //右辺値が数値の定数式ではないとき
1138 if(IS_LITERAL(index_stack[0])) index_stack[0]=-1;
1139 }
1140
1141 if(pbUseHeap) *pbUseHeap=bUseHeap[0];
1142
[75]1143 if(IsRealNumberType(type_stack[0]))
[3]1144 *pReg=pobj_reg->UnlockXmmReg();
1145 else
1146 *pReg=pobj_reg->UnlockReg();
1147
1148
[75]1149 resultType.SetType( type_stack[0], index_stack[0] );
1150
1151 bool isSuccessful = true;
[3]1152 goto finish;
1153
1154
1155
1156 //////////////////
1157 // エラー処理
1158 //////////////////
1159
1160error:
1161
[75]1162 isSuccessful = false;
[3]1163 goto finish;
1164
1165
1166
1167
1168finish:
1169
1170 for(i=0;i<pnum;i++){
1171 if(values[i]) HeapDefaultFree(values[i]);
1172 }
1173
[75]1174 return isSuccessful;
[3]1175}
[255]1176
1177bool NumOpe( int *pReg,
1178 const char *expression,
1179 const Type &baseType,
1180 Type &resultType,
1181 BOOL *pbUseHeap )
1182{
1183 BOOL bInitRegSwitch=0;
1184 if(!pobj_reg){
1185 bInitRegSwitch=1;
1186
1187 //作業用レジスタを取得
1188 pobj_reg=new CRegister(*pReg);
1189 }
1190
1191 //エラー時の復旧用
1192 CRegister objReg_Backup;
1193 objReg_Backup=*pobj_reg;
1194
1195 *pReg = pobj_reg->GetNextReg();
1196
1197
1198 bool result = _numope( pReg, expression, baseType, resultType, pbUseHeap );
1199
1200
1201 if( !result )
1202 {
1203 *pobj_reg=objReg_Backup;
1204 }
1205
1206 if(bInitRegSwitch){
1207 //整合性をチェック(バグ回避)
1208 if( result )
1209 {
1210 pobj_reg->bug_check();
1211 }
1212
1213 //作業レジスタを解放
1214 delete pobj_reg;
1215 pobj_reg=0;
1216 }
1217
1218 return result;
1219}
Note: See TracBrowser for help on using the repository browser.