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

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

UserProc::SetParamsAndReturnTypeメソッドをリファクタリング
LexicalAnalysis.hのインクルードを除去した

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