source: dev/BasicCompiler64/NumOpe.cpp @ 131

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

Prototypeクラスを用意した。

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