Ignore:
Timestamp:
Mar 2, 2008, 5:40:44 AM (16 years ago)
Author:
dai_9181
Message:

Select Caseに指定された値でエラーが起こったとき、スコープ処理に不具合が生じてしまう問題を修正。

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/abdev/BasicCompiler64/Compile_Statement.cpp

    r402 r408  
    669669std::vector<SelectSchedule> selectSchedules;
    670670
    671 void OpcodeSelect( const char *lpszParms ){
     671void OpcodeSelect( const char *lpszParms )
     672{
    672673    extern HANDLE hHeap;
    673674    extern char *basbuf;
     
    677678    int reg1=REG_RAX;
    678679    Type type1;
    679     if( !NumOpe(&reg1,lpszParms,Type(), type1 ) ){
    680         return;
    681     }
     680    bool result = NumOpe(&reg1,lpszParms,Type(), type1 );
    682681
    683682    selectSchedules.push_back( SelectSchedule( type1.GetSize() ) );
    684683
    685     if( selectSchedules.back().typeSize < sizeof(long) ){
    686         selectSchedules.back().typeSize = sizeof(long);
    687     }
    688 
    689     if(type1.IsDouble()){
    690         //movsd qword ptr[rsp+offset],xmm_reg       ※スタックフレームを利用
    691         pobj_sf->push(reg1,sizeof(double));
    692     }
    693     else if(type1.IsSingle()){
    694         //movss dword ptr[rsp+offset],xmm_reg       ※スタックフレームを利用
    695         pobj_sf->push(reg1,sizeof(float));
    696     }
    697     else{
    698         ExtendTypeTo64(type1.GetBasicType(),reg1);
    699 
    700         //mov qword ptr[rsp+offset],reg     ※スタックフレームを利用
    701         pobj_sf->push(reg1);
    702     }
    703 
    704     for(i=cp;;i++){
    705         if(basbuf[i]=='\0'){
    706             selectSchedules.pop_back();
    707             SetError(22,"Select",cp);
    708             return;
    709         }
    710         if(basbuf[i]==1&&basbuf[i+1]==ESC_SELECTCASE){
    711             for(i2=0;;i++){
    712                 if(basbuf[i]==1&&basbuf[i+1]==ESC_SELECTCASE) i2++;
    713                 if(basbuf[i]==1&&basbuf[i+1]==ESC_ENDSELECT){
    714                     i2--;
    715                     if(i2==0) break;
     684    if( result )
     685    {
     686        if( selectSchedules.back().typeSize < sizeof(long) ){
     687            selectSchedules.back().typeSize = sizeof(long);
     688        }
     689
     690        if(type1.IsDouble()){
     691            //movsd qword ptr[rsp+offset],xmm_reg       ※スタックフレームを利用
     692            pobj_sf->push(reg1,sizeof(double));
     693        }
     694        else if(type1.IsSingle()){
     695            //movss dword ptr[rsp+offset],xmm_reg       ※スタックフレームを利用
     696            pobj_sf->push(reg1,sizeof(float));
     697        }
     698        else{
     699            ExtendTypeTo64(type1.GetBasicType(),reg1);
     700
     701            //mov qword ptr[rsp+offset],reg     ※スタックフレームを利用
     702            pobj_sf->push(reg1);
     703        }
     704
     705        for(i=cp;;i++){
     706            if(basbuf[i]=='\0'){
     707                selectSchedules.pop_back();
     708                SetError(22,"Select",cp);
     709                return;
     710            }
     711            if(basbuf[i]==1&&basbuf[i+1]==ESC_SELECTCASE){
     712                for(i2=0;;i++){
     713                    if(basbuf[i]==1&&basbuf[i+1]==ESC_SELECTCASE) i2++;
     714                    if(basbuf[i]==1&&basbuf[i+1]==ESC_ENDSELECT){
     715                        i2--;
     716                        if(i2==0) break;
     717                    }
    716718                }
    717             }
    718             continue;
    719         }
    720         if(basbuf[i]==1&&basbuf[i+1]==ESC_ENDSELECT) break;
    721 
    722         if(basbuf[i]==1&&basbuf[i+1]==ESC_CASE){
    723             NowCaseCp=i;
    724 
    725             i++;
    726             while(1){
    727                 for(i++,i2=0;;i++,i2++){
    728                     if(basbuf[i]=='\"'){
    729                         i3=GetStringInQuotation(temporary+i2,basbuf+i);
    730                         i+=i3-1;
    731                         i2+=i3-1;
    732                         continue;
     719                continue;
     720            }
     721            if(basbuf[i]==1&&basbuf[i+1]==ESC_ENDSELECT) break;
     722
     723            if(basbuf[i]==1&&basbuf[i+1]==ESC_CASE){
     724                NowCaseCp=i;
     725
     726                i++;
     727                while(1){
     728                    for(i++,i2=0;;i++,i2++){
     729                        if(basbuf[i]=='\"'){
     730                            i3=GetStringInQuotation(temporary+i2,basbuf+i);
     731                            i+=i3-1;
     732                            i2+=i3-1;
     733                            continue;
     734                        }
     735                        if(basbuf[i]=='('){
     736                            i3=GetStringInPare(temporary+i2,basbuf+i);
     737                            i+=i3-1;
     738                            i2+=i3-1;
     739                            continue;
     740                        }
     741                        if(basbuf[i]=='['){
     742                            i3=GetStringInBracket(temporary+i2,basbuf+i);
     743                            i+=i3-1;
     744                            i2+=i3-1;
     745                            continue;
     746                        }
     747
     748                        if(IsCommandDelimitation(basbuf[i])){
     749                            temporary[i2]=0;
     750                            break;
     751                        }
     752                        if(basbuf[i]==','){
     753                            temporary[i2]=0;
     754                            break;
     755                        }
     756
     757                        temporary[i2]=basbuf[i];
    733758                    }
    734                     if(basbuf[i]=='('){
    735                         i3=GetStringInPare(temporary+i2,basbuf+i);
    736                         i+=i3-1;
    737                         i2+=i3-1;
    738                         continue;
    739                     }
    740                     if(basbuf[i]=='['){
    741                         i3=GetStringInBracket(temporary+i2,basbuf+i);
    742                         i+=i3-1;
    743                         i2+=i3-1;
    744                         continue;
    745                     }
    746 
    747                     if(IsCommandDelimitation(basbuf[i])){
    748                         temporary[i2]=0;
    749                         break;
    750                     }
    751                     if(basbuf[i]==','){
    752                         temporary[i2]=0;
    753                         break;
    754                     }
    755 
    756                     temporary[i2]=basbuf[i];
    757                 }
    758 
    759                 //エラー用
    760                 i2=cp;
    761                 cp=NowCaseCp;
    762 
    763                 int reg2=REG_RDX;
    764                 Type type2;
    765                 if( !NumOpe(&reg2,temporary,type1,type2) ){
    766                     return;
    767                 }
    768 
    769                 cp=i2;
    770 
    771                 if(type1.IsObject()){
    772                     std::vector<const UserProc *> subs;
    773                     type1.GetClass().GetDynamicMethods().Enum( CALC_EQUAL, subs );
    774                     if( subs.size() == 0 ){
     759
     760                    //エラー用
     761                    i2=cp;
     762                    cp=NowCaseCp;
     763
     764                    int reg2=REG_RDX;
     765                    Type type2;
     766                    if( !NumOpe(&reg2,temporary,type1,type2) ){
    775767                        return;
    776768                    }
    777769
    778                     Parameters params;
    779                     params.push_back( new Parameter( "", Type( type2 ) ) );
    780 
    781                     //オーバーロードを解決
    782                     const UserProc *pUserProc = OverloadSolution("==",subs, params, NULL);
    783 
    784                     delete params[0];
    785 
    786                     if(!pUserProc){
    787                         //エラー
    788                         return;
    789                     }
    790 
    791 
    792                     //実体オブジェクト
    793                     if(reg2!=REG_RDX){
    794                         //mov rdx,reg2
    795                         compiler.codeGenerator.op_mov_RR(REG_RDX,reg2);
    796                     }
    797 
    798                     //mov rcx,qword ptr[rsp+offset]     ※スタックフレームから参照
    799                     pobj_sf->ref(REG_RCX);
    800 
    801                     //call operator_proc    ※ ==演算子
    802                     compiler.codeGenerator.op_call(pUserProc);
    803 
    804                     //test rax,rax
    805                     compiler.codeGenerator.op_test(REG_RAX,REG_RAX);
    806 
    807                     //jne ...
    808                     selectSchedules.back().casePertialSchedules.push_back(
    809                         compiler.codeGenerator.op_jne( 0, sizeof(long), true )
    810                     );
    811                 }
    812                 else{
    813                     if(type1.IsDouble()){
    814                         int xmm_reg;
    815                         if(IsXmmReg(reg2)) xmm_reg=reg2;
    816                         else xmm_reg=REG_XMM5;
    817                         ChangeTypeToXmm_Double(type2.GetBasicType(),xmm_reg,reg2);
    818 
    819                         //movsd xmm4,qword ptr[rsp+offset]  ※スタックフレームから参照
    820                         pobj_sf->ref(REG_XMM4,sizeof(double));
    821 
    822                         //comiss xmm_reg1,xmm_reg2
    823                         compiler.codeGenerator.op_comisd(xmm_reg,REG_XMM4);
    824                     }
    825                     else if(type1.IsSingle()){
    826                         int xmm_reg;
    827                         if(IsXmmReg(reg2)) xmm_reg=reg2;
    828                         else xmm_reg=REG_XMM5;
    829                         ChangeTypeToXmm_Single(type2.GetBasicType(),xmm_reg,reg2);
    830 
    831                         //movss xmm4,dword ptr[rsp+offset]  ※スタックフレームから参照
    832                         pobj_sf->ref(REG_XMM4,sizeof(float));
    833 
    834                         //comiss xmm_reg1,xmm_reg2
    835                         compiler.codeGenerator.op_comiss(xmm_reg,REG_XMM4);
     770                    cp=i2;
     771
     772                    if(type1.IsObject()){
     773                        std::vector<const UserProc *> subs;
     774                        type1.GetClass().GetDynamicMethods().Enum( CALC_EQUAL, subs );
     775                        if( subs.size() == 0 ){
     776                            return;
     777                        }
     778
     779                        Parameters params;
     780                        params.push_back( new Parameter( "", Type( type2 ) ) );
     781
     782                        //オーバーロードを解決
     783                        const UserProc *pUserProc = OverloadSolution("==",subs, params, NULL);
     784
     785                        delete params[0];
     786
     787                        if(!pUserProc){
     788                            //エラー
     789                            return;
     790                        }
     791
     792
     793                        //実体オブジェクト
     794                        if(reg2!=REG_RDX){
     795                            //mov rdx,reg2
     796                            compiler.codeGenerator.op_mov_RR(REG_RDX,reg2);
     797                        }
     798
     799                        //mov rcx,qword ptr[rsp+offset]     ※スタックフレームから参照
     800                        pobj_sf->ref(REG_RCX);
     801
     802                        //call operator_proc    ※ ==演算子
     803                        compiler.codeGenerator.op_call(pUserProc);
     804
     805                        //test rax,rax
     806                        compiler.codeGenerator.op_test(REG_RAX,REG_RAX);
     807
     808                        //jne ...
     809                        selectSchedules.back().casePertialSchedules.push_back(
     810                            compiler.codeGenerator.op_jne( 0, sizeof(long), true )
     811                        );
    836812                    }
    837813                    else{
    838                         //その他整数型
    839 
    840                         i2=NeutralizationType(type1.GetBasicType(),-1,type2.GetBasicType(),-1);
    841 
    842                         //mov r14,qword ptr[rsp+offset]     ※スタックフレームから参照
    843                         pobj_sf->ref(REG_R14);
    844 
    845                         //cmp reg2,r14
    846                         compiler.codeGenerator.op_cmp_reg(Type(i2).GetSize(),reg2,REG_R14);
     814                        if(type1.IsDouble()){
     815                            int xmm_reg;
     816                            if(IsXmmReg(reg2)) xmm_reg=reg2;
     817                            else xmm_reg=REG_XMM5;
     818                            ChangeTypeToXmm_Double(type2.GetBasicType(),xmm_reg,reg2);
     819
     820                            //movsd xmm4,qword ptr[rsp+offset]  ※スタックフレームから参照
     821                            pobj_sf->ref(REG_XMM4,sizeof(double));
     822
     823                            //comiss xmm_reg1,xmm_reg2
     824                            compiler.codeGenerator.op_comisd(xmm_reg,REG_XMM4);
     825                        }
     826                        else if(type1.IsSingle()){
     827                            int xmm_reg;
     828                            if(IsXmmReg(reg2)) xmm_reg=reg2;
     829                            else xmm_reg=REG_XMM5;
     830                            ChangeTypeToXmm_Single(type2.GetBasicType(),xmm_reg,reg2);
     831
     832                            //movss xmm4,dword ptr[rsp+offset]  ※スタックフレームから参照
     833                            pobj_sf->ref(REG_XMM4,sizeof(float));
     834
     835                            //comiss xmm_reg1,xmm_reg2
     836                            compiler.codeGenerator.op_comiss(xmm_reg,REG_XMM4);
     837                        }
     838                        else{
     839                            //その他整数型
     840
     841                            i2=NeutralizationType(type1.GetBasicType(),-1,type2.GetBasicType(),-1);
     842
     843                            //mov r14,qword ptr[rsp+offset]     ※スタックフレームから参照
     844                            pobj_sf->ref(REG_R14);
     845
     846                            //cmp reg2,r14
     847                            compiler.codeGenerator.op_cmp_reg(Type(i2).GetSize(),reg2,REG_R14);
     848                        }
     849
     850                        //je ...
     851                        selectSchedules.back().casePertialSchedules.push_back(
     852                            compiler.codeGenerator.op_je( 0, sizeof(long), true )
     853                        );
    847854                    }
    848855
    849                     //je ...
    850                     selectSchedules.back().casePertialSchedules.push_back(
    851                         compiler.codeGenerator.op_je( 0, sizeof(long), true )
    852                     );
     856                    if(basbuf[i]!=',') break;
    853857                }
    854 
    855                 if(basbuf[i]!=',') break;
    856             }
    857         }
    858         if(basbuf[i]==1&&basbuf[i+1]==ESC_CASEELSE){
    859             //jmp ...
    860             selectSchedules.back().casePertialSchedules.push_back(
    861                 compiler.codeGenerator.op_jmp( 0, sizeof(long), true )
    862             );
    863         }
    864     }
    865 
    866     //スタックフレームを1スペースだけ解除
    867     pobj_sf->pop(REG_NON);
     858            }
     859            if(basbuf[i]==1&&basbuf[i+1]==ESC_CASEELSE){
     860                //jmp ...
     861                selectSchedules.back().casePertialSchedules.push_back(
     862                    compiler.codeGenerator.op_jmp( 0, sizeof(long), true )
     863                );
     864            }
     865        }
     866
     867        //スタックフレームを1スペースだけ解除
     868        pobj_sf->pop(REG_NON);
     869    }
    868870
    869871    //レキシカルスコープをレベルアップ
Note: See TracChangeset for help on using the changeset viewer.