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

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

64ビット版でもインターフェイスのベース実装周りをコンパイルできるようにした(インターフェイス機構自体はまだ未完成)

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