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

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

関数の戻り値がクラス型のとき、直接インデクサ指定できるような対応を行った。ただし、この対応は暫定的なものであるため、後ほど改修が必要。

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