source: dev/trunk/ab5.0/abdev/BasicCompiler64/NumOpe.cpp @ 463

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

[461]を64bit版にマージ。

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