Changeset 359 in dev for trunk/abdev/BasicCompiler_Common


Ignore:
Timestamp:
Nov 9, 2007, 8:52:07 AM (17 years ago)
Author:
dai_9181
Message:

例外処理機構実装中…

Location:
trunk/abdev/BasicCompiler_Common
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/abdev/BasicCompiler_Common/Compile.cpp

    r322 r359  
    298298                break;
    299299            case ESC_CATCH:
    300                 Exception::CatchCommand();
     300                Exception::CatchCommand( Command + 2 );
    301301                break;
    302302            case ESC_FINALLY:
  • trunk/abdev/BasicCompiler_Common/error.cpp

    r353 r359  
    166166    if(num==68) sprintf(msg,"\"%s\" 不正な関数名です。", tempKeyWord);
    167167    if(num==69) sprintf(msg,"\"%s\" 不正なメソッド名です。", tempKeyWord);
     168    if(num==70) lstrcpy(msg,"一つのTryに対して複数のFinallyを記述できません。");
     169    if(num==71) lstrcpy(msg,"Finallyの後ろにCatchを記述することはできません。");
     170    if(num==72) lstrcpy(msg,"Catchのパラメータの型が指定されていません。");
     171    if(num==73) lstrcpy(msg,"Catchのパラメータの型はクラス型でなければなりません。");
    168172
    169173
  • trunk/abdev/BasicCompiler_Common/include/Exception.h

    r357 r359  
     1#pragma once
    12
    23namespace Exception{
    34
    45    void TryCommand();
    5     void CatchCommand();
     6    void CatchCommand( const char *parameter );
    67    void FinallyCommand();
    78    void EndTryCommand();
     
    1011
    1112    void Opcode_Func_System_GetNowScopeCatchAddress();
    12 
     13    void Opcode_Func_System_GetNowScopeFinallyAddress();
    1314}
  • trunk/abdev/BasicCompiler_Common/src/Exception.cpp

    r358 r359  
    1313class TryScope
    1414{
     15    bool isCatched;
     16    bool isDefinedFinally;
     17
     18    std::vector<const PertialSchedule *> finallySchedules;
     19    void JmpFinally()
     20    {
     21        finallySchedules.push_back(
     22            compiler.codeGenerator.op_jmp( 0, sizeof(long), true )
     23        );
     24    }
     25    void ResolveJmpFinally()
     26    {
     27        BOOST_FOREACH( const PertialSchedule *pPertialSchedule, finallySchedules )
     28        {
     29            compiler.codeGenerator.opfix_JmpPertialSchedule( pPertialSchedule );
     30        }
     31    }
     32
     33    const PertialSchedule *pPertialScheduleForFinallyAddress;
     34
    1535public:
    1636    const PertialSchedule *pPertialScheduleForCatchAddress;
    1737    TryScope()
     38        : isCatched( false )
     39        , isDefinedFinally( false )
    1840    {
    1941    }
     
    2244    }
    2345
     46    bool IsCatched() const
     47    {
     48        return isCatched;
     49    }
     50    bool IsDefinedFinally() const
     51    {
     52        return isDefinedFinally;
     53    }
     54
    2455    void RegistPertialScheduleForCatchAddress( const PertialSchedule *pPertialScheduleForCatchAddress )
    2556    {
    2657        this->pPertialScheduleForCatchAddress = pPertialScheduleForCatchAddress;
    2758    }
    28 
    29     void AddCatch()
    30     {
     59    void RegistPertialScheduleForFinallyAddress( const PertialSchedule *pPertialScheduleForFinallyAddress )
     60    {
     61        this->pPertialScheduleForFinallyAddress = pPertialScheduleForFinallyAddress;
     62    }
     63    const PertialSchedule *GetPertialScheduleForFinallyAddress() const
     64    {
     65        return pPertialScheduleForFinallyAddress;
     66    }
     67   
     68   
     69
     70    void Try()
     71    {
     72    }
     73
     74    void Catch()
     75    {
     76        if( isDefinedFinally )
     77        {
     78            SetError(71,NULL,cp);
     79            return;
     80        }
     81
     82        isCatched = true;
     83
     84        JmpFinally();
     85    }
     86    void Finally()
     87    {
     88        if( isDefinedFinally )
     89        {
     90            SetError(70,NULL,cp);
     91            return;
     92        }
     93
     94        isDefinedFinally = true;
     95
     96        ResolveJmpFinally();
    3197    }
    3298
    3399    void EndTry()
    34100    {
     101        if( !isDefinedFinally )
     102        {
     103            Finally();
     104        }
    35105    }
    36106};
     
    47117
    48118    tryScopes.push_back( TryScope() );
    49 
    50     int backCp = cp;
    51 
    52     char temporary[1024];
    53     lstrcpy( temporary, "ExceptionService.BeginTryScope( _System_GetNowScopeCatchAddresses() As VoidPtr, _System_GetBp() As LONG_PTR, _System_GetSp() As LONG_PTR )" );
    54     MakeMiddleCode( temporary );
    55     ChangeOpcode( temporary );
    56 
    57     cp = backCp;
    58 }
    59 void CatchCommand()
    60 {
    61     if( tryScopes.size() == 0 )
    62     {
    63         SetError(1,NULL,cp);
    64         return;
    65     }
    66 
     119    tryScopes.back().Try();
     120
     121    int backCp = cp;
     122
     123    char temporary[1024];
     124    lstrcpy( temporary, "ExceptionService.BeginTryScope( _System_GetNowScopeCatchAddresses() As VoidPtr, _System_GetNowScopeFinallyAddresses() As VoidPtr, _System_GetBp() As LONG_PTR, _System_GetSp() As LONG_PTR )" );
     125    MakeMiddleCode( temporary );
     126    ChangeOpcode( temporary );
     127
     128    cp = backCp;
     129}
     130void CatchCommand( const char *parameter )
     131{
     132    if( tryScopes.size() == 0 )
     133    {
     134        SetError(1,NULL,cp);
     135        return;
     136    }
     137
     138    Type paramType;
     139    if( parameter[0] )
     140    {
     141        char varName[VN_SIZE], typeName[VN_SIZE];
     142        SplitSyntacticForAs( parameter, varName, typeName );
     143        if( !typeName[0] )
     144        {
     145            SetError(72,NULL,cp);
     146        }
     147        else
     148        {
     149            if( !compiler.StringToType( typeName, paramType ) )
     150            {
     151                SetError(73,NULL,cp);
     152            }
     153        }
     154    }
     155
     156    // パラメータの扱いが未完成
     157
     158    tryScopes.back().Catch();
     159
     160    // _System_GetNowScopeCatchAddressesを解決
    67161    compiler.codeGenerator.opfix( tryScopes.back().pPertialScheduleForCatchAddress, compiler.codeGenerator.GetNativeCodeSize() );
    68162}
    69163void FinallyCommand()
    70164{
     165    tryScopes.back().Finally();
     166
     167    int backCp = cp;
     168
     169    char temporary[1024];
     170    lstrcpy( temporary, "_System_pobj_AllThreads->GetCurrentException()->FinishFinally()" );
     171    MakeMiddleCode( temporary );
     172    ChangeOpcode( temporary );
     173
     174    cp = backCp;
     175
     176    //Tryスコープに入るときに引き渡されるパラメータ値を解決
     177    compiler.codeGenerator.opfix( tryScopes.back().GetPertialScheduleForFinallyAddress(), compiler.codeGenerator.GetNativeCodeSize() );
    71178}
    72179void EndTryCommand()
     
    80187    int backCp = cp;
    81188
     189    if( !tryScopes.back().IsCatched() )
     190    {
     191        // _System_GetNowScopeCatchAddressesを解決
     192        compiler.codeGenerator.opfix( tryScopes.back().pPertialScheduleForCatchAddress, 0 );
     193    }
     194
     195    if( !tryScopes.back().IsDefinedFinally() )
     196    {
     197        // Finallyが定義されていないときは空のFinallyを定義しておく
     198        FinallyCommand();
     199    }
     200
    82201    char temporary[1024];
    83202    lstrcpy( temporary, "_System_pobj_AllThreads->GetCurrentException()->EndTryScope()" );
     
    87206    cp = backCp;
    88207
     208    tryScopes.back().EndTry();
    89209    tryScopes.pop_back();
    90210}
     
    133253}
    134254
     255void Opcode_Func_System_GetNowScopeFinallyAddress()
     256{
     257    if( tryScopes.size() == 0 )
     258    {
     259        SetError(1,NULL,cp);
     260        return;
     261    }
     262
     263#ifdef _WIN64
     264    //mov rax,finallyAddress
     265    const PertialSchedule *pPertialSchedule = compiler.codeGenerator.op_mov_RV( sizeof(long), REG_RAX, 0, Schedule::CatchAddress, true );
     266#else
     267    //mov eax,finallyAddress
     268    const PertialSchedule *pPertialSchedule = compiler.codeGenerator.op_mov_RV( REG_EAX, 0, Schedule::CatchAddress, true );
     269#endif
     270
     271    tryScopes.back().RegistPertialScheduleForFinallyAddress( pPertialSchedule );
     272
     273    /*
     274    int dataTableOffset = compiler.GetObjectModule().dataTable.Add( static_cast<LONG_PTR>(0) );
     275
     276#ifdef _WIN64
     277    //mov rax,dataTableOffset
     278    compiler.codeGenerator.op_mov_RV( sizeof(_int64), REG_RAX, dataTableOffset, Schedule::DataTable);
     279#else
     280    //mov eax,dataTableOffset
     281    compiler.codeGenerator.op_mov_RV( REG_EAX, dataTableOffset, Schedule::DataTable);
     282#endif
     283    */
     284}
     285
    135286
    136287}   // Exception
  • trunk/abdev/BasicCompiler_Common/src/Linker.cpp

    r357 r359  
    4444        if( schedule.GetType() == Schedule::CatchAddress )
    4545        {
    46             nativeCode.Overwrite(
    47                 schedule.GetOffset(),
    48                 static_cast<long>( nativeCode.GetLong( schedule.GetOffset() ) + schedule.GetUserProc().GetBeginOpAddress() + imageBase + codeSectionBaseOffset )
    49             );
     46            if( nativeCode.GetLong( schedule.GetOffset() ) != 0 )
     47            {
     48                // 置き換える値が0の場合を除く
     49                nativeCode.Overwrite(
     50                    schedule.GetOffset(),
     51                    static_cast<long>( nativeCode.GetLong( schedule.GetOffset() ) + schedule.GetUserProc().GetBeginOpAddress() + imageBase + codeSectionBaseOffset )
     52                );
     53            }
    5054        }
    5155    }
Note: See TracChangeset for help on using the changeset viewer.