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

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

GCのバグをいくつか修正

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