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

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

静的領域に初期オブジェクトを配置可能にした

File size: 32.0 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 const int useReg=pobj_reg->GetNextReg();
138 const int xmmReg=pobj_reg->GetNextXmmReg();
139
140
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 ///////////////////////////////////////////////////////////////////
200 if( GetMemberType( leftType, member, resultType, 0, false ) ){
201 // メンバが見つかったとき
202
203 //オブジェクトポインタをr11にコピー
204 compiler.codeGenerator.op_mov_RR( REG_R11, useReg );
205
206 RELATIVE_VAR relativeVar;
207 relativeVar.dwKind=VAR_DIRECTMEM;
208
209 if( !_member_offset(
210 true, //エラー表示あり
211 false, //読み込み専用
212 leftType,
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 ///////////////////////////////////////////////////////////////////
228 vector<const UserProc *> userProcs;
229
230 char methodName[VN_SIZE], lpPtrOffset[VN_SIZE], parameter[VN_SIZE], dummy[1];
231 ReferenceKind refType;
232 lstrcpy( methodName, member );
233 GetVarFormatString(methodName,parameter,lpPtrOffset,dummy,refType);
234
235 objClass.EnumDynamicMethodsOrInterfaceMethods( methodName, userProcs );
236 if(userProcs.size()){
237 //オーバーロードを解決
238 const UserProc *pUserProc = OverloadSolutionWithStrParam(termFull,userProcs,parameter,termLeft);
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 ※スタックフレームを利用
252 pobj_sf->push( useReg );
253
254 if( !Opcode_CallProc(parameter,pUserProc,PROCFLAG_NEW,termLeft ) ){
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
278 SetUseRegFromRax(resultType.GetBasicType(),useReg,xmmReg);
279
280 // 型パラメータを解決
281 ResolveFormalGenericTypeParameter( resultType, leftType, pUserProc );
282
283
284 /////////////////////////////////////////////
285 ////// レジスタ資源を復元
286 RESTORE_REGISTER_RESOURCE
287 }////////////////////////////////////////////
288
289 return true;
290 }
291 }
292
293 return false;
294}
295bool TermOpe( const char *term, const Type &baseType, Type &resultType, bool &isLiteral, BOOL *pbUseHeap, bool isWantObject, bool *pIsClassName, bool isProcedureCallOnly ){
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];
311 ReferenceKind refType;
312 if( SplitMemberName( termFull, termLeft, member, refType ) ){
313 ///////////////////////////////////////////////////////////////////
314 // オブジェクトとメンバに分解できるとき
315 // termLeft.member
316 ///////////////////////////////////////////////////////////////////
317
318 isLiteral = false;
319
320 // オブジェクト側の型を取得
321 bool isClassName = false;
322 Type leftType;
323 if( GetTermType( termLeft, Type(), leftType, isLiteral, &isClassName ) ){
324 if( isClassName == false && compiler.GetObjectModule().meta.GetBlittableTypes().IsExist( leftType ) ){
325 // 左側のオブジェクト部分がBlittable型のとき
326
327 char temporary[VN_SIZE];
328 lstrcpy( temporary, termLeft );
329 sprintf( termLeft, "%s(%s)",
330 compiler.GetObjectModule().meta.GetBlittableTypes().Find( leftType ).GetCreateStaticMethodFullName().c_str(),
331 temporary );
332 }
333 }
334
335 if( !TermOpe( termLeft, baseType, leftType, isLiteral, pbUseHeap, true, &isClassName ) ){
336 goto globalArea;
337 }
338
339 if( isClassName ){
340 // 静的メンバ/メソッドの場合
341 goto globalArea;
342 }
343
344 if( !leftType.HasMember() ){
345 // メンバを持たない型の場合
346 return false;
347 }
348
349 return TermMemberOpe( leftType, baseType, resultType, termFull, termLeft, member );
350 }
351globalArea:
352
353 //////////////////////////////////////////////
354 // クラス名かどうかをチェック(静的メンバ用)
355 //////////////////////////////////////////////
356
357 if( pIsClassName ){
358 if( compiler.GetObjectModule().meta.GetClasses().Find( termFull ) ){
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
373 if(lstrcmpi(termFull,"This")==0 && isProcedureCallOnly == false ){
374 //Thisオブジェクト
375 resultType.SetType( DEF_OBJECT, compiler.pCompilingClass );
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
415 CallProc(idProc,pInfo,procName,parameter, baseType,resultType);
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
452 ConstMacro *pConstMacro = compiler.GetObjectModule().meta.GetGlobalConstMacros().Find( procName );
453 if( pConstMacro )
454 {
455 if( pConstMacro->GetCalcBuffer( parameter, temporary ) )
456 {
457 /////////////////////////
458 // マクロ関数
459 /////////////////////////
460
461 //閉じカッコ")"に続く文字がNULLでないときはエラーにする
462 if(termFull[i2+1+i4+1]!='\0') SetError(42,NULL,cp);
463
464 //マクロ関数の場合
465 NumOpe(&UseReg, temporary,Type(),resultType);
466
467 if(!IS_LITERAL(resultType.GetIndex())){
468 //リテラル値ではなかったとき
469 isLiteral = false;
470 }
471
472 return true;
473 }
474 }
475 }
476 else if( isProcedureCallOnly ){
477 // 関数呼び出し以外は受け付けない
478 return false;
479 }
480
481
482 ////////////////////////////////
483 // インデクサ(getアクセサ)
484 ////////////////////////////////
485
486 char VarName[VN_SIZE],ArrayElements[VN_SIZE];
487 GetArrayElement(termFull,VarName,ArrayElements);
488 if(ArrayElements[0]){
489 Type classType;
490 GetVarType(VarName,classType,false);
491 if( classType.IsObject() )
492 {
493 CallIndexerGetterProc(UseReg,classType,VarName,ArrayElements,resultType);
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
530 if( compiler.StringToType( termFull, resultType ) ){
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
586bool _numope( int *pReg,
587 const char *expression,
588 const Type &baseType,
589 Type &resultType,
590 BOOL *pbUseHeap )
591{
592 int i,i2,i3;
593 char temporary[1024],temp2[1024];
594
595 if( (string)expression == "typeInfo=t2" )
596 {
597 int test=0;
598 }
599
600 if(expression[0]=='\0'){
601 SetError(1,NULL,cp);
602 return false;
603 }
604
605 if( !baseType.IsNull() && expression[0] == '[' ){
606 // リテラル配列の場合
607
608 int dataTableOffset;
609 if( !compiler.GetObjectModule().dataTable.MakeLiteralArrayBuffer( expression, baseType, dataTableOffset ) )
610 {
611 return false;
612 }
613
614 //mov reg,i2
615 compiler.codeGenerator.op_mov_RV( sizeof(_int64), *pReg, dataTableOffset, Schedule::DataTable );
616
617 resultType = baseType;
618
619 return true;
620 }
621
622 bool isLiteralCalculation;
623 if( NumOpe_GetType( expression, baseType, resultType, &isLiteralCalculation ) )
624 {
625 if( isLiteralCalculation )
626 {
627 //右辺値が数値の定数式の場合
628 _int64 i64data;
629 StaticCalculation(true, expression,baseType.GetBasicType(),&i64data,resultType);
630
631 if(resultType.IsReal()){
632 if(baseType.IsReal()) resultType=baseType;
633
634 int xmmReg = pobj_reg->GetNextXmmReg();
635 *pReg = xmmReg;
636
637 if(resultType.IsDouble()){
638 i3 = compiler.GetObjectModule().dataTable.Add( i64data );
639
640 //movlpd xmm_reg,qword ptr[data table offset]
641 compiler.codeGenerator.op_movlpd_RM( xmmReg, 0, i3, MOD_DISP32, Schedule::DataTable );
642 }
643 if(resultType.IsSingle()){
644 double dbl;
645 memcpy(&dbl,&i64data,sizeof(_int64));
646
647 float flt;
648 int i32data;
649 flt=(float)dbl;
650 memcpy(&i32data,&flt,sizeof(long));
651
652 i3 = compiler.GetObjectModule().dataTable.Add( i32data );
653
654 //movss xmm_reg,dword ptr[data table offset]
655 compiler.codeGenerator.op_movss_RM( xmmReg, 0, i3, MOD_DISP32, Schedule::DataTable );
656 }
657 }
658 else{
659 if(!resultType.Is64()){
660 //整数(符号有り/無し)
661
662 i3=(long)i64data;
663
664 if(resultType.GetBasicSize()==sizeof(char)) i3=i3&0x000000FF;
665 if(resultType.GetBasicSize()==sizeof(short)) i3=i3&0x0000FFFF;
666
667 i64data=(_int64)i3;
668 }
669
670 //mov reg,i64data
671 compiler.codeGenerator.op_mov_RV64(*pReg,i64data);
672 }
673 return true;
674 }
675 }
676
677 if( expression[0] == 1 )
678 {
679 if( expression[1]==ESC_NEW )
680 {
681 //New演算子(オブジェクト生成)
682
683 if( pobj_BlockReg->check(REG_RAX) ){
684 SetError();
685 }
686
687 //////////////////////////////////////////////////////
688 ///// レジスタ資源のバックアップ
689 { BACKUP_REGISTER_RESOURCE
690 //////////////////////////////////////////////////////
691
692 if( !Operator_New( expression+2, baseType, resultType ) ){
693 return false;
694 }
695
696 /////////////////////////////////////////////
697 ////// レジスタ資源を復元
698 RESTORE_REGISTER_RESOURCE
699 }////////////////////////////////////////////
700
701 //mov reg,rax
702 compiler.codeGenerator.op_mov_RR( *pReg, REG_RAX );
703
704 return true;
705 }
706 else if( expression[1] == ESC_SYSTEM_STATIC_NEW )
707 {
708 // 静的領域にオブジェクトを作る
709
710 // 静的領域にオブジェクトを生成
711 int dataTableOffset;
712 if( !compiler.GetObjectModule().dataTable.MakeConstObjectToProcessStaticBuffer( expression + 2, resultType, dataTableOffset ) )
713 {
714 return false;
715 }
716
717 //mov reg,i2
718 compiler.codeGenerator.op_mov_RV( sizeof(_int64), *pReg, dataTableOffset, Schedule::DataTable);
719
720 return true;
721 }
722 }
723
724
725 /////////////////////////////////
726 // 式要素を逆ポーランド式で取得
727 /////////////////////////////////
728
729 char *values[255];
730 long calc[255];
731 long stack[255];
732 int pnum;
733 if(!GetNumOpeElements(expression,&pnum,values,calc,stack)){
734 for(i=0;i<pnum;i++){
735 if(values[i]) HeapDefaultFree(values[i]);
736 }
737 return 0;
738 }
739
740
741 if( strstr(expression,"xxxxx"))
742 {
743 int test=0;
744 }
745
746 ////////////////////////////////
747 // 演算部分のコード生成を開始
748 ////////////////////////////////
749
750 BOOL bError;
751 bError=0;
752
753 //リテラル値のみの計算かどうかを判別するためのフラグ
754 BOOL bLiteralCalculation=1;
755
756 double dbl;
757 int sp;
758 int type_stack[255];
759 LONG_PTR index_stack[255];
760 bool isNothing_stack[255];
761 BOOL bUseHeap[255];
762 _int64 i64data;
763 int UseReg,XmmReg;
764 BOOL bXmm;
765 for(i=0,sp=0;i<pnum;i++){
766 int idCalc;
767 idCalc=calc[i]%100;
768
769 if(idCalc){
770 if(type_stack[sp-2]==DEF_OBJECT){
771 if( idCalc == CALC_AS
772 && type_stack[sp-1] == ( DEF_OBJECT | FLAG_CAST )
773 && index_stack[sp-1] == index_stack[sp-2]
774 || isNothing_stack[sp-2] ){
775 // 同一の型、またはNothingに対するAsはAs演算子を呼び出さない
776 }
777 else if( idCalc == CALC_AS
778 && type_stack[sp-1] == ( DEF_OBJECT | FLAG_CAST )
779 && ( ((CClass *)index_stack[sp-1])->IsEqualsOrSubClass( (CClass *)index_stack[sp-2] ) || ((CClass *)index_stack[sp-2])->IsEqualsOrSubClass( (CClass *)index_stack[sp-1] )
780 )){
781 // ダウンキャストを許可する
782 }
783 else{
784 //オーバーロードされたオペレータを呼び出す
785 i2=CallOperatorProc(idCalc,baseType,type_stack,index_stack,bUseHeap,sp);
786 if(i2==0){
787 if(idCalc==CALC_EQUAL) lstrcpy(temp2,"==");
788 else GetCalcName(idCalc,temp2);
789 sprintf(temporary,"Operator %s",temp2);
790 SetError(27,temporary,cp);
791 goto error;
792 }
793 else if(i2==-1) goto error;
794
795 continue;
796 }
797 }
798
799 if(!CheckCalcType(idCalc,type_stack,sp)) goto error;
800 }
801
802 switch(idCalc){
803 //数値
804 case 0:
805 index_stack[sp]=-1;
806 isNothing_stack[sp] = false;
807 bUseHeap[sp]=0;
808
809 UseReg=pobj_reg->GetNextReg();
810 XmmReg=pobj_reg->GetNextXmmReg();
811
812 bXmm=0;
813
814 char *term;
815 term=values[i];
816
817 if( calc[i+1]%100 == CALC_AS ){
818 // As演算子の右辺値
819 //型名
820 if( compiler.StringToType( term, resultType ) ){
821 resultType.SetBasicType( resultType.GetBasicType() | FLAG_CAST );
822 }
823 else{
824 SetError(3, term, cp );
825 goto error;
826 }
827
828 type_stack[sp] = resultType.GetBasicType();
829 index_stack[sp] = resultType.GetIndex();
830 sp++;
831
832 break;
833 }
834
835 if( (term[0]=='e'||term[0]=='E')
836 && (term[1]=='x'||term[1]=='X')
837 && term[2]=='\"'
838 || term[0] == '\"' )
839 {
840 bool isEx = true;
841 if( term[0] == '\"' )
842 {
843 isEx = false;
844 }
845
846 if( isEx )
847 {
848 // 拡張版リテラル文字列(エスケープシーケンス可能)
849 if(!RemoveStringQuotes(term+2)){
850 SetError(43,NULL,cp);
851 goto error;
852 }
853 i3=FormatString_EscapeSequence(term+2);
854 term+=2;
855 }
856 else
857 {
858 // 通常文字列
859 if(!RemoveStringQuotes(term)){
860 SetError(43,NULL,cp);
861 goto error;
862 }
863 i3=lstrlen(term);
864 }
865
866 if( !baseType.IsPointer() )
867 {
868 //要求タイプがオブジェクト、または未定のとき
869
870 //String型オブジェクトを生成
871 i2 = compiler.GetObjectModule().dataTable.MakeConstStringObjectToProcessStaticBuffer( term );
872
873 //mov reg,i2
874 compiler.codeGenerator.op_mov_RV(sizeof(_int64),UseReg,i2, Schedule::DataTable);
875
876 type_stack[sp]=DEF_OBJECT;
877 index_stack[sp]=(LONG_PTR)compiler.GetObjectModule().meta.GetClasses().GetStringClassPtr();
878 bLiteralCalculation=0;
879
880 if(bXmm) pobj_reg->LockXmmReg();
881 else pobj_reg->LockReg();
882
883 sp++;
884 break;
885 }
886
887StrLiteral:
888
889 type_stack[sp]=typeOfPtrChar;
890 bLiteralCalculation=0;
891
892 i2 = compiler.GetObjectModule().dataTable.AddString( term, i3 );
893
894 //mov reg,i2
895 compiler.codeGenerator.op_mov_RV(sizeof(_int64),UseReg,i2, Schedule::DataTable);
896
897 if(UseReg==REG_R14){
898 //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用
899 pobj_sf->push(REG_R14);
900 }
901 }
902 else if(IsVariableTopChar(term[0])||
903 term[0]=='*'||
904 (term[0]=='.'&&IsVariableTopChar(term[1])))
905 {
906 //////////////////
907 // 何らかの識別子
908
909 bool isLiteral;
910 if( TermOpe( term, baseType, resultType, isLiteral, &bUseHeap[sp] ) ){
911 if(resultType.IsNull()){
912 //戻り値が存在しないとき
913 for(i2=0;;i2++){
914 if(term[i2]=='('||term[i2]=='\0'){
915 term[i2]=0;
916 break;
917 }
918 }
919 SetError(38,term,cp);
920
921 goto error;
922 }
923
924 type_stack[sp] = resultType.GetBasicType();
925 index_stack[sp] = resultType.GetIndex();
926
927 if( !isLiteral ){
928 bLiteralCalculation=0;
929 }
930
931 if( resultType.GetBasicType() & FLAG_CAST ){
932 // 型名のみ
933 SetError();
934 }
935 else{
936 if( resultType.IsReal() == false && UseReg==REG_R14 ){
937 //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用
938 pobj_sf->push(REG_R14);
939 }
940 if( resultType.IsReal() && XmmReg==REG_XMM4 ){
941 if(resultType.IsDouble()){
942 //movsd qword ptr[rsp+offset],xmm4 ※スタックフレームを利用
943 pobj_sf->push(REG_XMM4,sizeof(double));
944 }
945 if(resultType.IsSingle()){
946 //movss dword ptr[rsp+offset],xmm4 ※スタックフレームを利用
947 pobj_sf->push(REG_XMM4,sizeof(float));
948 }
949 }
950
951 if( resultType.IsReal() ){
952 pobj_reg->LockXmmReg();
953 }
954 else{
955 pobj_reg->LockReg();
956 }
957 }
958
959 sp++;
960 break;
961 }
962
963
964 // Nothing
965 if( lstrcmp( term, "Nothing" ) == 0 ){
966 isNothing_stack[sp] = true;
967
968 type_stack[sp] = DEF_OBJECT;
969 if( baseType.IsObject() ){
970 index_stack[sp] = baseType.GetIndex();
971 }
972 else{
973 index_stack[sp] = (LONG_PTR)compiler.GetObjectModule().meta.GetClasses().GetObjectClassPtr();
974 }
975
976 bLiteralCalculation = 0;
977
978 //xor reg,reg
979 compiler.codeGenerator.op_zero_reg( UseReg );
980
981 if(UseReg==REG_R14){
982 //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用
983 pobj_sf->push(REG_R14);
984 }
985
986 pobj_reg->LockReg();
987 sp++;
988 break;
989 }
990
991
992 //////////////
993 // 定数の場合
994 //////////////
995
996 i3 = compiler.GetObjectModule().meta.GetGlobalConsts().GetBasicType(term);
997 if(i3){
998 if( compiler.GetObjectModule().meta.GetGlobalConsts().IsStringPtr( term ) ){
999 //リテラル文字列
1000
1001 if( baseType.IsObject() || baseType.IsNull() )
1002 {
1003 //要求タイプがオブジェクト、または未定のとき
1004
1005 //String型オブジェクトを生成
1006 NewStringObject(UseReg,term);
1007
1008 type_stack[sp]=DEF_OBJECT;
1009 index_stack[sp]=(LONG_PTR)compiler.GetObjectModule().meta.GetClasses().GetStringClassPtr();
1010 bLiteralCalculation=0;
1011
1012 if(bXmm) pobj_reg->LockXmmReg();
1013 else pobj_reg->LockReg();
1014
1015 sp++;
1016 break;
1017 }
1018
1019 double dbl = compiler.GetObjectModule().meta.GetGlobalConsts().GetDoubleData(term);
1020 memcpy(&i64data,&dbl,sizeof(double));
1021
1022 //バイト数
1023 i3=lstrlen((char *)i64data);
1024
1025 memcpy(term,(char *)i64data,i3);
1026 term[i3]=0;
1027 goto StrLiteral;
1028 }
1029
1030 type_stack[sp] = i3;
1031 if(IsRealNumberType(i3)){
1032 //実数
1033 double dbl = compiler.GetObjectModule().meta.GetGlobalConsts().GetDoubleData(term);
1034 memcpy(&i64data,&dbl,sizeof(double));
1035 goto Literal;
1036 }
1037 else if(IsWholeNumberType(i3)){
1038 //整数
1039 i64data = compiler.GetObjectModule().meta.GetGlobalConsts().GetWholeData(term);
1040 goto Literal;
1041 }
1042 else{
1043 SetError(1,NULL,0);
1044 goto error;
1045 }
1046 }
1047
1048
1049 //該当する識別子が見当たらないときはエラー扱いにする
1050 bError=1;
1051 SetError(3,term,cp);
1052 type_stack[sp]=DEF_DOUBLE;
1053 }
1054 else{
1055 //リテラル値
1056 type_stack[sp]=GetLiteralValue(term,&i64data,baseType.GetBasicType());
1057Literal:
1058 if(type_stack[sp]==DEF_DOUBLE){
1059 //64ビット浮動小数型
1060 bXmm=1;
1061
1062 if(XmmReg==REG_XMM4){
1063 //mov r14,i64data
1064 compiler.codeGenerator.op_mov_RV64(REG_R14,i64data);
1065
1066
1067 //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用
1068 pobj_sf->push(REG_R14);
1069 }
1070 else{
1071 i3 = compiler.GetObjectModule().dataTable.Add( i64data );
1072
1073 //movlpd xmm_reg,qword ptr[data table offset]
1074 compiler.codeGenerator.op_movlpd_RM( XmmReg, 0, i3, MOD_DISP32, Schedule::DataTable );
1075 }
1076 }
1077 else if(type_stack[sp]==DEF_SINGLE){
1078 //32ビット浮動小数型
1079 bXmm=1;
1080
1081 float flt;
1082 int i32data;
1083 memcpy(&dbl,&i64data,sizeof(double));
1084 flt=(float)dbl;
1085 memcpy(&i32data,&flt,sizeof(long));
1086
1087 if(XmmReg==REG_XMM4){
1088 SetError(); // TODO: 未実装
1089 //push term
1090 //compiler.codeGenerator.op_push_value(i32data);
1091 }
1092 else{
1093 i3=compiler.GetObjectModule().dataTable.Add( i32data );
1094
1095 //movss xmm_reg,dword ptr[data table offset]
1096 compiler.codeGenerator.op_movss_RM( XmmReg, 0, i3, MOD_DISP32, Schedule::DataTable );
1097 }
1098 }
1099 else{
1100 //整数
1101
1102 index_stack[sp]=GetLiteralIndex(i64data);
1103
1104 //mov reg,i64data
1105 compiler.codeGenerator.op_mov_RV64(UseReg,i64data);
1106
1107 if(UseReg==REG_R14){
1108 //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用
1109 pobj_sf->push(REG_R14);
1110 }
1111 }
1112 }
1113
1114 if(bXmm) pobj_reg->LockXmmReg();
1115 else pobj_reg->LockReg();
1116
1117 sp++;
1118 break;
1119
1120 //論理演算子
1121 case CALC_XOR:
1122 case CALC_OR:
1123 case CALC_AND:
1124 if(!CalcTwoTerm_Logical(idCalc,type_stack,index_stack,&sp)) goto error;
1125 break;
1126 case CALC_NOT:
1127 //value[sp-1]=Not value[sp-1]
1128 //NOT演算子
1129 if(!Calc_Not(type_stack,sp)) goto error;
1130 break;
1131
1132 //比較演算子
1133 case CALC_PE: //value[sp-2] <= value[sp-1]
1134 case CALC_QE: //value[sp-2] >= value[sp-1]
1135 case CALC_P: //value[sp-2] < value[sp-1]
1136 case CALC_Q: //value[sp-2] > value[sp-1]
1137 case CALC_NOTEQUAL: //value[sp-2] <> value[sp-1]
1138 case CALC_EQUAL: //value[sp-2] = value[sp-1]
1139 if(!CalcTwoTerm_Relational(idCalc,type_stack,index_stack,&sp)) goto error;
1140 break;
1141
1142 //ビットシフト
1143 case CALC_SHL: //value[sp-2] << value[sp-1]
1144 case CALC_SHR: //value[sp-2] >> value[sp-1]
1145 if(!Calc_Shift(idCalc,type_stack,&sp)) goto error;
1146 break;
1147
1148 //算術演算
1149 case CALC_ADDITION:
1150 case CALC_SUBTRACTION:
1151 case CALC_PRODUCT:
1152 if(!CalcTwoTerm_Arithmetic(idCalc,type_stack,index_stack,&sp)) goto error;
1153 break;
1154 case CALC_MOD:
1155 //value[sp-2]%=value[sp-1]
1156 //剰余演算
1157 if(!Calc_Mod(type_stack,index_stack,&sp)) goto error;
1158 break;
1159 case CALC_QUOTIENT:
1160 //value[sp-2]/=value[sp-1];
1161 //除算
1162 if(!Calc_Divide(type_stack,&sp,baseType.GetBasicType())) goto error;
1163 break;
1164 case CALC_INTQUOTIENT:
1165 //value[sp-2]/=value[sp-1]
1166 //整数除算
1167 if(!Calc_IntDivide(type_stack,index_stack,&sp)) goto error;
1168 break;
1169 case CALC_MINUSMARK:
1170 //value[sp-1]=-value[sp-1]
1171 //符号反転
1172 if(!Calc_MinusMark(type_stack,sp)) goto error;
1173 break;
1174 case CALC_POWER:
1175 //べき乗演算(浮動小数点演算のみ)
1176 if(!Calc_Power(type_stack,&sp)) goto error;
1177 break;
1178 case CALC_AS:
1179 //キャスト
1180 if(!Calc_Cast(type_stack,index_stack,&sp)) goto error;
1181 break;
1182 case CALC_BYVAL:
1183 //ポインタ型→参照型
1184 if( PTR_LEVEL( type_stack[sp-1] ) <= 0 ){
1185 //ポインタ型ではないとき
1186 SetError( 3, NULL, cp );
1187 goto error;
1188 }
1189
1190 type_stack[sp-1] = PTR_LEVEL_DOWN( type_stack[sp-1] );
1191
1192 break;
1193
1194 default:
1195 SetError(300,NULL,cp);
1196 goto error;
1197 }
1198 }
1199
1200 if(bError) goto error;
1201
1202 if(sp!=1){
1203 SetError(1,NULL,cp);
1204 goto error;
1205 }
1206
1207 if(bLiteralCalculation){
1208 SetError();
1209 }
1210 else{
1211 //右辺値が数値の定数式ではないとき
1212 if(IS_LITERAL(index_stack[0])) index_stack[0]=-1;
1213 }
1214
1215 if(pbUseHeap) *pbUseHeap=bUseHeap[0];
1216
1217 if(IsRealNumberType(type_stack[0]))
1218 *pReg=pobj_reg->UnlockXmmReg();
1219 else
1220 *pReg=pobj_reg->UnlockReg();
1221
1222
1223 resultType.SetType( type_stack[0], index_stack[0] );
1224
1225 bool isSuccessful = true;
1226 goto finish;
1227
1228
1229
1230 //////////////////
1231 // エラー処理
1232 //////////////////
1233
1234error:
1235
1236 isSuccessful = false;
1237 goto finish;
1238
1239
1240
1241
1242finish:
1243
1244 for(i=0;i<pnum;i++){
1245 if(values[i]) HeapDefaultFree(values[i]);
1246 }
1247
1248 return isSuccessful;
1249}
1250
1251bool NumOpe( int *pReg,
1252 const char *expression,
1253 const Type &baseType,
1254 Type &resultType,
1255 BOOL *pbUseHeap )
1256{
1257 BOOL bInitRegSwitch=0;
1258 if(!pobj_reg){
1259 bInitRegSwitch=1;
1260
1261 //作業用レジスタを取得
1262 pobj_reg=new CRegister(*pReg);
1263 }
1264
1265 //エラー時の復旧用
1266 CRegister objReg_Backup;
1267 objReg_Backup=*pobj_reg;
1268
1269 *pReg = pobj_reg->GetNextReg();
1270
1271
1272 bool result = _numope( pReg, expression, baseType, resultType, pbUseHeap );
1273
1274
1275 if( !result )
1276 {
1277 *pobj_reg=objReg_Backup;
1278 }
1279
1280 if(bInitRegSwitch){
1281 //整合性をチェック(バグ回避)
1282 if( result )
1283 {
1284 pobj_reg->bug_check();
1285 }
1286
1287 //作業レジスタを解放
1288 delete pobj_reg;
1289 pobj_reg=0;
1290 }
1291
1292 return result;
1293}
Note: See TracBrowser for help on using the repository browser.