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

Last change on this file since 368 was 368, checked in by dai_9181, 16 years ago

System名前空間をImportsしているときにNew演算子にBlittable型を("System." を省略する形で)指定するとコンパイルエラーになるバグを修正。

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