Ignore:
Timestamp:
Jul 31, 2007, 4:30:31 AM (17 years ago)
Author:
dai_9181
Message:
 
File:
1 edited

Legend:

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

    r243 r254  
    33#include <jenga/include/smoothie/LexicalAnalysis.h>
    44
    5 #include <LexicalScopingImpl.h>
    65#include <Compiler.h>
    76
     
    192191
    193192    //je (endif、または else まで条件ジャンプ)
    194     CodeGenerator::PertialSchedule *pIfPertialSchedule = compiler.codeGenerator.op_je( 0, sizeof(long), true );
     193    const PertialSchedule *pIfPertialSchedule = compiler.codeGenerator.op_je( 0, sizeof(long), true );
    195194
    196195
     
    200199
    201200    //レキシカルスコープをレベルアップ
    202     GetLexicalScopes().Start( obp, SCOPE_TYPE_IF );
     201    compiler.codeGenerator.lexicalScopes.Start( obp, LexicalScope::SCOPE_TYPE_IF );
    203202
    204203    int i2=CompileBuffer(ESC_ENDIF,0);
    205204
    206205    //レキシカルスコープをレベルダウン
    207     GetLexicalScopes().End();
     206    compiler.codeGenerator.lexicalScopes.End();
    208207
    209208
    210209    if(i2==ESC_ELSE){
    211210        //jmp (endifまで)
    212         CodeGenerator::PertialSchedule *pTempPertialSchedule = compiler.codeGenerator.op_jmp( 0, sizeof(long), true );
     211        const PertialSchedule *pTempPertialSchedule = compiler.codeGenerator.op_jmp( 0, sizeof(long), true );
    213212
    214213        compiler.codeGenerator.opfix_JmpPertialSchedule( pIfPertialSchedule );
     
    221220
    222221        //レキシカルスコープをレベルアップ
    223         GetLexicalScopes().Start( obp, SCOPE_TYPE_IF );
     222        compiler.codeGenerator.lexicalScopes.Start( obp, LexicalScope::SCOPE_TYPE_IF );
    224223
    225224        CompileBuffer(ESC_ENDIF,0);
    226225
    227226        //レキシカルスコープをレベルダウン
    228         GetLexicalScopes().End();
     227        compiler.codeGenerator.lexicalScopes.End();
    229228
    230229
     
    259258void OpcodeGoto(char *Parameter){
    260259    extern HANDLE hHeap;
    261     extern GOTOLABELSCHEDULE *pGotoLabelSchedule;
    262     extern int GotoLabelScheduleNum;
    263260    int i,LineNum;
    264261
     
    266263        i=GetLabelAddress(Parameter+1,0);
    267264
    268         //jmp ...
    269         OpBuffer[obp++]=(char)0xE9;
    270         if(i==-1){
    271             pGotoLabelSchedule=(GOTOLABELSCHEDULE *)HeapReAlloc(hHeap,0,pGotoLabelSchedule,(GotoLabelScheduleNum+1)*sizeof(GOTOLABELSCHEDULE));
    272             pGotoLabelSchedule[GotoLabelScheduleNum].pName=(char *)HeapAlloc(hHeap,0,lstrlen(Parameter+1)+1);
    273             lstrcpy(pGotoLabelSchedule[GotoLabelScheduleNum].pName,Parameter+1);
    274             pGotoLabelSchedule[GotoLabelScheduleNum].pos=obp;
    275             pGotoLabelSchedule[GotoLabelScheduleNum].now_cp=cp;
    276             GotoLabelScheduleNum++;
    277         }
    278         *((long *)(OpBuffer+obp))=i-(obp+sizeof(long));
    279         obp+=sizeof(long);
     265        if( i == -1 )
     266        {
     267            //jmp ...(schedule)
     268            extern int obp;
     269            compiler.codeGenerator.op_jmp_goto_schedule( (const std::string)(Parameter + 1), 0, cp );
     270        }
     271        else
     272        {
     273            //jmp ...
     274            extern int obp;
     275            compiler.codeGenerator.op_jmp( i-obp, sizeof(long), false, true );
     276        }
    280277    }
    281278    else{
     
    283280        i=GetLabelAddress(0,LineNum);
    284281
    285         //jmp ...
    286         OpBuffer[obp++]=(char)0xE9;
    287         if(i==-1){
    288             pGotoLabelSchedule=(GOTOLABELSCHEDULE *)HeapReAlloc(hHeap,0,pGotoLabelSchedule,(GotoLabelScheduleNum+1)*sizeof(GOTOLABELSCHEDULE));
    289             pGotoLabelSchedule[GotoLabelScheduleNum].pName=0;
    290             pGotoLabelSchedule[GotoLabelScheduleNum].line=LineNum;
    291             pGotoLabelSchedule[GotoLabelScheduleNum].pos=obp;
    292             pGotoLabelSchedule[GotoLabelScheduleNum].now_cp=cp;
    293             GotoLabelScheduleNum++;
    294         }
    295         *((long *)(OpBuffer+obp))=i-(obp+sizeof(long));
    296         obp+=sizeof(long);
     282        if( i == -1 )
     283        {
     284            //jmp ...(schedule)
     285            extern int obp;
     286            compiler.codeGenerator.op_jmp_goto_schedule( "", LineNum, cp );
     287        }
     288        else
     289        {
     290            //jmp ...
     291            extern int obp;
     292            compiler.codeGenerator.op_jmp( i-obp, sizeof(long), false, true );
     293        }
    297294    }
    298295}
     
    309306
    310307    //je (Wend まで)
    311     CodeGenerator::PertialSchedule *pWhilePertialSchedule = compiler.codeGenerator.op_je( 0, sizeof(long), true );
     308    const PertialSchedule *pWhilePertialSchedule = compiler.codeGenerator.op_je( 0, sizeof(long), true );
    312309
    313310    //レキシカルスコープをレベルアップ
    314     GetLexicalScopes().Start( obp, SCOPE_TYPE_WHILE );
     311    compiler.codeGenerator.lexicalScopes.Start( obp, LexicalScope::SCOPE_TYPE_WHILE );
    315312
    316313    //While内をコンパイル
    317314    CompileBuffer(0,COM_WEND);
    318315
    319     GetLexicalScopes().CallDestructorsOfScopeEnd();
     316    compiler.codeGenerator.lexicalScopes.CallDestructorsOfScopeEnd();
    320317
    321318    //jmp ...
     
    323320
    324321    //レキシカルスコープをレベルダウン
    325     GetLexicalScopes().End();
     322    compiler.codeGenerator.lexicalScopes.End();
    326323
    327324    compiler.codeGenerator.opfix_JmpPertialSchedule( pWhilePertialSchedule );
     
    364361
    365362    //jmp ...
    366     CodeGenerator::PertialSchedule *pTempPertialSchedule = compiler.codeGenerator.op_jmp( 0, sizeof(long), true );
     363    const PertialSchedule *pTempPertialSchedule = compiler.codeGenerator.op_jmp( 0, sizeof(long), true );
    367364
    368365    //Continueアドレスのバックアップとセット
     
    407404
    408405    //jmp [カウンタ減少の場合の判定を飛び越す]
    409     CodeGenerator::PertialSchedule *pTempPertialSchedule2 = compiler.codeGenerator.op_jmp( 0, sizeof(long), true );
     406    const PertialSchedule *pTempPertialSchedule2 = compiler.codeGenerator.op_jmp( 0, sizeof(long), true );
    410407
    411408    //jeジャンプ先のオフセット値
     
    430427
    431428    //レキシカルスコープをレベルアップ
    432     GetLexicalScopes().Start( obp, SCOPE_TYPE_FOR );
     429    compiler.codeGenerator.lexicalScopes.Start( obp, LexicalScope::SCOPE_TYPE_FOR );
    433430
    434431    //For内をコンパイル
    435432    CompileBuffer(0,COM_NEXT);
    436433
    437     GetLexicalScopes().CallDestructorsOfScopeEnd();
     434    compiler.codeGenerator.lexicalScopes.CallDestructorsOfScopeEnd();
    438435
    439436    if(szNextVariable[0]){
     
    447444
    448445    //レキシカルスコープをレベルダウン
    449     GetLexicalScopes().End();
     446    compiler.codeGenerator.lexicalScopes.End();
    450447
    451448    //jeジャンプ先のオフセット値
     
    466463
    467464    //レキシカルスコープをレベルアップ
    468     GetLexicalScopes().Start( obp, SCOPE_TYPE_DO );
     465    compiler.codeGenerator.lexicalScopes.Start( obp, LexicalScope::SCOPE_TYPE_DO );
    469466
    470467    //Do内をコンパイル
    471468    CompileBuffer(0,COM_LOOP);
    472469
    473     GetLexicalScopes().CallDestructorsOfScopeEnd();
    474 
    475     CodeGenerator::PertialSchedule *pDoPertialSchedule = NULL;
     470    compiler.codeGenerator.lexicalScopes.CallDestructorsOfScopeEnd();
     471
     472    const PertialSchedule *pDoPertialSchedule = NULL;
    476473
    477474    extern char *basbuf;
     
    522519
    523520    //jmp ...
    524     CodeGenerator::PertialSchedule *pTempPertialSchedule = compiler.codeGenerator.op_jmp( 0, sizeof(long), true );
     521    const PertialSchedule *pTempPertialSchedule = compiler.codeGenerator.op_jmp( 0, sizeof(long), true );
    525522
    526523    //レキシカルスコープをレベルダウン
    527     GetLexicalScopes().End();
     524    compiler.codeGenerator.lexicalScopes.End();
    528525
    529526    //jmpジャンプ先のオフセット値
     
    539536
    540537void OpcodeExitSub(void){
    541     extern DWORD *pExitSubSchedule;
    542     extern int ExitSubScheduleNum;
    543     extern HANDLE hHeap;
    544 
    545538    if( UserProc::IsGlobalAreaCompiling() ){
    546539        SetError(12,"Exit Sub/Function",cp);
     
    549542
    550543    //未解放のローカルオブジェクトのデストラクタを呼び出す
    551     GetLexicalScopes().CallDestructorsOfReturn();
     544    compiler.codeGenerator.lexicalScopes.CallDestructorsOfReturn();
    552545
    553546    //jmp ...(End Sub/Function)
    554     OpBuffer[obp++]=(char)0xE9;
    555 
    556     pExitSubSchedule=(DWORD *)HeapReAlloc(hHeap,0,pExitSubSchedule,(ExitSubScheduleNum+1)*sizeof(DWORD));
    557     pExitSubSchedule[ExitSubScheduleNum]=obp;
    558     ExitSubScheduleNum++;
    559 
    560     obp+=sizeof(long);
    561 }
    562 
    563 void AddCaseSchedule(void){
    564     extern DWORD *pCaseSchedule;
    565     extern int CaseScheduleNum;
    566     extern HANDLE hHeap;
    567 
    568     pCaseSchedule=(DWORD *)HeapReAlloc(hHeap,0,pCaseSchedule,(CaseScheduleNum+1)*sizeof(DWORD));
    569     pCaseSchedule[CaseScheduleNum]=obp;
    570     CaseScheduleNum++;
    571 }
     547    compiler.codeGenerator.op_jmp_exitsub();
     548}
     549
     550//Caseスケジュール
     551class SelectSchedule
     552{
     553public:
     554    SelectSchedule( int typeSize )
     555        : typeSize( typeSize )
     556        , nowCaseSchedule( 0 )
     557    {
     558    }
     559
     560    PertialSchedules casePertialSchedules;
     561    int typeSize;
     562    int nowCaseSchedule;
     563};
     564std::vector<SelectSchedule> selectSchedules;
     565
    572566void OpcodeSelect( const char *lpszParms ){
    573     extern DWORD *pCaseSchedule;
    574     extern int CaseScheduleNum;
    575     extern int NowCaseSchedule;
    576567    extern HANDLE hHeap;
    577568    extern char *basbuf;
    578569    int i,i2,i3,NowCaseCp;
    579570    char temporary[VN_SIZE];
    580 
    581     DWORD *temp_pCaseSchedule;
    582     int temp_CaseScheduleNum;
    583     int temp_NowCaseSchedule;
    584 
    585     temp_pCaseSchedule=pCaseSchedule;
    586     temp_CaseScheduleNum=CaseScheduleNum;
    587     temp_NowCaseSchedule=NowCaseSchedule;
    588     pCaseSchedule=(DWORD *)HeapAlloc(hHeap,0,1);
    589     CaseScheduleNum=0;
    590     NowCaseSchedule=0;
    591 
     571   
    592572    int reg1=REG_RAX;
    593573    Type type1;
     
    596576    }
    597577
     578    selectSchedules.push_back( SelectSchedule( type1.GetSize() ) );
     579
     580    if( selectSchedules.back().typeSize < sizeof(long) ){
     581        selectSchedules.back().typeSize = sizeof(long);
     582    }
     583
    598584    if(type1.IsDouble()){
    599585        //movsd qword ptr[rsp+offset],xmm_reg       ※スタックフレームを利用
     
    613599    for(i=cp;;i++){
    614600        if(basbuf[i]=='\0'){
    615             HeapDefaultFree(pCaseSchedule);
    616             pCaseSchedule=temp_pCaseSchedule;
    617             CaseScheduleNum=temp_CaseScheduleNum;
    618             NowCaseSchedule=temp_NowCaseSchedule;
     601            selectSchedules.pop_back();
    619602            SetError(22,"Select",cp);
    620603            return;
     
    718701
    719702                    //jne ...
    720                     OpBuffer[obp++]=(char)0x0F;
    721                     OpBuffer[obp++]=(char)0x85;
     703                    selectSchedules.back().casePertialSchedules.push_back(
     704                        compiler.codeGenerator.op_jne( 0, sizeof(long), true )
     705                    );
    722706                }
    723707                else{
     
    759743
    760744                    //je ...
    761                     OpBuffer[obp++]=(char)0x0F;
    762                     OpBuffer[obp++]=(char)0x84;
     745                    selectSchedules.back().casePertialSchedules.push_back(
     746                        compiler.codeGenerator.op_je( 0, sizeof(long), true )
     747                    );
    763748                }
    764                 AddCaseSchedule();
    765                 obp+=sizeof(long);
    766749
    767750                if(basbuf[i]!=',') break;
     
    770753        if(basbuf[i]==1&&basbuf[i+1]==ESC_CASEELSE){
    771754            //jmp ...
    772             OpBuffer[obp++]=(char)0xE9;
    773             AddCaseSchedule();
    774             obp+=sizeof(long);
     755            selectSchedules.back().casePertialSchedules.push_back(
     756                compiler.codeGenerator.op_jmp( 0, sizeof(long), true )
     757            );
    775758        }
    776759    }
     
    780763
    781764    //レキシカルスコープをレベルアップ
    782     GetLexicalScopes().Start( obp, SCOPE_TYPE_SELECT );
     765    compiler.codeGenerator.lexicalScopes.Start( obp, LexicalScope::SCOPE_TYPE_SELECT );
    783766
    784767    //Select Case内をコンパイル
     
    786769
    787770    //jmp EndSelect
    788     OpBuffer[obp++]=(char)0xE9;
    789     AddCaseSchedule();
    790     obp+=sizeof(long);
     771    selectSchedules.back().casePertialSchedules.push_back(
     772        compiler.codeGenerator.op_jmp( 0, sizeof(long), true )
     773    );
    791774
    792775    //最終スケジュール
    793     for(i=NowCaseSchedule;i<CaseScheduleNum;i++){
    794         *(long *)(OpBuffer+pCaseSchedule[i])=obp-(pCaseSchedule[i]+sizeof(long));
    795     }
    796     HeapDefaultFree(pCaseSchedule);
     776    for(i=selectSchedules.back().nowCaseSchedule;i<(int)selectSchedules.back().casePertialSchedules.size();i++){
     777        compiler.codeGenerator.opfix_JmpPertialSchedule( selectSchedules.back().casePertialSchedules[i] );
     778    }
    797779
    798780    //レキシカルスコープをレベルダウン
    799     GetLexicalScopes().End();
    800 
    801     pCaseSchedule=temp_pCaseSchedule;
    802     CaseScheduleNum=temp_CaseScheduleNum;
    803     NowCaseSchedule=temp_NowCaseSchedule;
     781    compiler.codeGenerator.lexicalScopes.End();
     782
     783    selectSchedules.pop_back();
    804784}
    805785void OpcodeCase(char *Parameter){
    806     extern DWORD *pCaseSchedule;
    807     extern int NowCaseSchedule;
    808786    int i;
    809787
    810     if(!pCaseSchedule){
     788    if(selectSchedules.back().typeSize==-1){
    811789        SetError(30,"Case",cp);
    812790        return;
     
    814792
    815793    //jmp EndSelect
    816     OpBuffer[obp++]=(char)0xE9;
    817     AddCaseSchedule();
    818     obp+=sizeof(long);
     794    selectSchedules.back().casePertialSchedules.push_back(
     795        compiler.codeGenerator.op_jmp( 0, sizeof(long), true )
     796    );
    819797
    820798    i=0;
    821799    while(1){
    822800        //Caseスケジュール
    823         *(long *)(OpBuffer+pCaseSchedule[NowCaseSchedule])=obp-(pCaseSchedule[NowCaseSchedule]+sizeof(long));
    824         NowCaseSchedule++;
     801        compiler.codeGenerator.opfix_JmpPertialSchedule( selectSchedules.back().casePertialSchedules[selectSchedules.back().nowCaseSchedule] );
     802        selectSchedules.back().nowCaseSchedule++;
    825803
    826804        i=JumpOneParameter(Parameter,i);
     
    830808
    831809void OpcodeGosub(char *Parameter){
    832     extern HANDLE hHeap;
    833     extern GOTOLABELSCHEDULE *pGotoLabelSchedule;
    834     extern int GotoLabelScheduleNum;
    835     int i,LineNum;
    836 
    837     //call _System_GetEip
    838     extern const UserProc *pSub_System_GetEip;
    839     compiler.codeGenerator.op_call(pSub_System_GetEip);
    840 
    841     //add rax,offset(Gosubステートメントの最終ポイント)
    842     int schedule=obp,schedule2;
    843     compiler.codeGenerator.op_add_RV(REG_RAX,0);
    844     schedule2=obp-sizeof(long);
    845 
    846     //※戻り先用のrip
    847     //mov qword ptr[rsp+offset],rax     ※スタックフレームを利用
    848     pobj_sf->push(REG_RAX);
    849 
    850 
    851     if(Parameter[0]=='*'){
    852         i=GetLabelAddress(Parameter+1,0);
    853 
    854         //jmp ...
    855         OpBuffer[obp++]=(char)0xE9;
    856         if(i==-1){
    857             pGotoLabelSchedule=(GOTOLABELSCHEDULE *)HeapReAlloc(hHeap,0,pGotoLabelSchedule,(GotoLabelScheduleNum+1)*sizeof(GOTOLABELSCHEDULE));
    858             pGotoLabelSchedule[GotoLabelScheduleNum].pName=(char *)HeapAlloc(hHeap,0,lstrlen(Parameter+1)+1);
    859             lstrcpy(pGotoLabelSchedule[GotoLabelScheduleNum].pName,Parameter+1);
    860             pGotoLabelSchedule[GotoLabelScheduleNum].pos=obp;
    861             pGotoLabelSchedule[GotoLabelScheduleNum].now_cp=cp;
    862             GotoLabelScheduleNum++;
    863         }
    864         *((long *)(OpBuffer+obp))=i-(obp+sizeof(long));
    865         obp+=sizeof(long);
    866     }
    867     else{
    868         LineNum=atoi(Parameter);
    869         i=GetLabelAddress(0,LineNum);
    870 
    871         //jmp ...
    872         OpBuffer[obp++]=(char)0xE9;
    873         if(i==-1){
    874             pGotoLabelSchedule=(GOTOLABELSCHEDULE *)HeapReAlloc(hHeap,0,pGotoLabelSchedule,(GotoLabelScheduleNum+1)*sizeof(GOTOLABELSCHEDULE));
    875             pGotoLabelSchedule[GotoLabelScheduleNum].pName=0;
    876             pGotoLabelSchedule[GotoLabelScheduleNum].line=LineNum;
    877             pGotoLabelSchedule[GotoLabelScheduleNum].pos=obp;
    878             pGotoLabelSchedule[GotoLabelScheduleNum].now_cp=cp;
    879             GotoLabelScheduleNum++;
    880         }
    881         *((long *)(OpBuffer+obp))=i-(obp+sizeof(long));
    882         obp+=sizeof(long);
    883     }
    884 
    885     *((long *)(OpBuffer+schedule2))=obp-schedule;
    886 
    887     //※スタックフレームを元に戻す
    888     pobj_sf->pop(REG_NON);
    889 
    890810    SetError(-1,"Gosub ~ Returnステートメントは64ビットコンパイラで利用することはできません。",cp);
    891811}
Note: See TracChangeset for help on using the changeset viewer.