Ignore:
Timestamp:
Nov 10, 2007, 4:32:21 AM (17 years ago)
Author:
dai_9181
Message:

Catchのオーバーロードを実装中

Location:
trunk/abdev/BasicCompiler_Common/src
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/abdev/BasicCompiler_Common/src/Exception.cpp

    r359 r361  
    1111namespace Exception{
    1212
     13class CatchScope
     14{
     15    Type paramType;
     16    long codePos;
     17public:
     18    CatchScope( const Type &paramType, long codePos )
     19        : paramType( paramType )
     20        , codePos( codePos )
     21    {
     22    }
     23    ~CatchScope()
     24    {
     25    }
     26
     27    const Type &GetParamType() const
     28    {
     29        return paramType;
     30    }
     31    long GetCodePos() const
     32    {
     33        return codePos;
     34    }
     35};
     36typedef std::vector<CatchScope> CatchScopes;
     37
    1338class TryScope
    1439{
    15     bool isCatched;
    1640    bool isDefinedFinally;
     41
     42    CatchScopes catchScopes;
    1743
    1844    std::vector<const PertialSchedule *> finallySchedules;
     
    3157    }
    3258
     59    const PertialSchedule *pPertialScheduleForCatchAddress;
    3360    const PertialSchedule *pPertialScheduleForFinallyAddress;
    3461
    3562public:
    36     const PertialSchedule *pPertialScheduleForCatchAddress;
    3763    TryScope()
    38         : isCatched( false )
    39         , isDefinedFinally( false )
     64        : isDefinedFinally( false )
    4065    {
    4166    }
     
    4469    }
    4570
     71    const CatchScopes &GetCatchScopes() const
     72    {
     73        return catchScopes;
     74    }
    4675    bool IsCatched() const
    4776    {
    48         return isCatched;
     77        return ( catchScopes.size() != 0 );
    4978    }
    5079    bool IsDefinedFinally() const
     
    5685    {
    5786        this->pPertialScheduleForCatchAddress = pPertialScheduleForCatchAddress;
     87    }
     88    const PertialSchedule *GetPertialScheduleForCatchAddress() const
     89    {
     90        return pPertialScheduleForCatchAddress;
    5891    }
    5992    void RegistPertialScheduleForFinallyAddress( const PertialSchedule *pPertialScheduleForFinallyAddress )
     
    72105    }
    73106
    74     void Catch()
     107    void Catch( Type &paramType )
    75108    {
    76109        if( isDefinedFinally )
     
    80113        }
    81114
    82         isCatched = true;
    83 
    84115        JmpFinally();
     116
     117        catchScopes.push_back( CatchScope( paramType, compiler.codeGenerator.GetNativeCodeSize() ) );
    85118    }
    86119    void Finally()
     
    103136            Finally();
    104137        }
     138    }
     139
     140    int GenerateCatchTable()
     141    {
     142        int size = static_cast<int>(( (catchScopes.size()+1)*2 ) * sizeof(LONG_PTR));
     143        BYTE *buffer = (BYTE *)calloc( size, 1 );
     144
     145        int pos = 0;
     146        BOOST_FOREACH( const CatchScope &catchScope, catchScopes )
     147        {
     148            // パラメータのクラス名
     149            char paramName[VN_SIZE] = "";
     150            int paramNameDataTableOffset = 0;
     151            if( catchScope.GetParamType().IsObject() )
     152            {
     153                lstrcpy( paramName, catchScope.GetParamType().GetClass().GetFullName().c_str() );
     154            }
     155            paramNameDataTableOffset = compiler.GetObjectModule().dataTable.AddString( paramName );
     156            *((LONG_PTR *)(buffer+pos)) = paramNameDataTableOffset;
     157            pos += sizeof(LONG_PTR);
     158
     159            // Catchアドレス
     160            *((LONG_PTR *)(buffer+pos)) = catchScope.GetCodePos();
     161            pos += sizeof(LONG_PTR);
     162        }
     163
     164        int dataTableOffset = compiler.GetObjectModule().dataTable.AddBinary( buffer, size );
     165
     166        free( buffer );
     167
     168        pos = 0;
     169        BOOST_FOREACH( const CatchScope &catchScope, catchScopes )
     170        {
     171            // パラメータのクラス名
     172            compiler.GetObjectModule().dataTable.schedules.push_back( Schedule( Schedule::DataTable, dataTableOffset + pos ) );
     173            pos += sizeof(LONG_PTR);
     174
     175            // Catchアドレス
     176            compiler.GetObjectModule().dataTable.schedules.push_back( Schedule( &UserProc::CompilingUserProc(), dataTableOffset + pos ) );
     177            compiler.GetObjectModule().dataTable.schedules.back().SpecifyCatchAddress();
     178            pos += sizeof(LONG_PTR);
     179        }
     180
     181        return dataTableOffset;
    105182    }
    106183};
     
    154231    }
    155232
    156     // パラメータの扱いが未完成
    157 
    158     tryScopes.back().Catch();
    159 
    160     // _System_GetNowScopeCatchAddressesを解決
    161     compiler.codeGenerator.opfix( tryScopes.back().pPertialScheduleForCatchAddress, compiler.codeGenerator.GetNativeCodeSize() );
     233    tryScopes.back().Catch( paramType );
    162234}
    163235void FinallyCommand()
     
    185257    }
    186258
    187     int backCp = cp;
    188 
    189     if( !tryScopes.back().IsCatched() )
    190     {
    191         // _System_GetNowScopeCatchAddressesを解決
    192         compiler.codeGenerator.opfix( tryScopes.back().pPertialScheduleForCatchAddress, 0 );
    193     }
     259    int dataTableOffset = tryScopes.back().GenerateCatchTable();
     260
     261    // _System_GetNowScopeCatchAddressesを解決
     262    compiler.codeGenerator.opfix( tryScopes.back().GetPertialScheduleForCatchAddress(), dataTableOffset );
    194263
    195264    if( !tryScopes.back().IsDefinedFinally() )
     
    198267        FinallyCommand();
    199268    }
     269
     270    int backCp = cp;
    200271
    201272    char temporary[1024];
     
    215286
    216287    char temporary[1024];
    217     lstrcpy( temporary, "_System_pobj_AllThreads->GetCurrentException()->_Throw()" );
     288    if( Parameter[0] )
     289    {
     290        sprintf( temporary, "_System_pobj_AllThreads->GetCurrentException()->_ThrowWithParam(%s)", Parameter );
     291    }
     292    else
     293    {
     294        lstrcpy( temporary, "_System_pobj_AllThreads->GetCurrentException()->_ThrowNoneParam()" );
     295    }
    218296    MakeMiddleCode( temporary );
    219297    ChangeOpcode( temporary );
     
    232310#ifdef _WIN64
    233311    //mov rax,catchAddress
    234     const PertialSchedule *pPertialSchedule = compiler.codeGenerator.op_mov_RV( sizeof(long), REG_RAX, 0, Schedule::CatchAddress, true );
     312    const PertialSchedule *pPertialSchedule = compiler.codeGenerator.op_mov_RV( sizeof(long), REG_RAX, 0, Schedule::DataTable, true );
    235313#else
    236314    //mov eax,catchAddress
    237     const PertialSchedule *pPertialSchedule = compiler.codeGenerator.op_mov_RV( REG_EAX, 0, Schedule::CatchAddress, true );
     315    const PertialSchedule *pPertialSchedule = compiler.codeGenerator.op_mov_RV( REG_EAX, 0, Schedule::DataTable, true );
    238316#endif
    239317
  • trunk/abdev/BasicCompiler_Common/src/Linker.cpp

    r359 r361  
    5454        }
    5555    }
     56
     57    BOOST_FOREACH( const Schedule &schedule, dataTable.schedules )
     58    {
     59        if( schedule.GetType() == Schedule::CatchAddress )
     60        {
     61            if( nativeCode.GetLong( schedule.GetOffset() ) != 0 )
     62            {
     63                // 置き換える値が0の場合を除く
     64#ifdef _WIN64
     65                dataTable.OverwriteInt64(
     66                    schedule.GetOffset(),
     67                    dataTable.GetInt64( schedule.GetOffset() ) + schedule.GetUserProc().GetBeginOpAddress() + imageBase + codeSectionBaseOffset
     68                );
     69#else
     70                dataTable.Overwrite(
     71                    schedule.GetOffset(),
     72                    dataTable.GetLong( schedule.GetOffset() ) + schedule.GetUserProc().GetBeginOpAddress() + imageBase + codeSectionBaseOffset
     73                );
     74#endif
     75            }
     76        }
     77    }
    5678}
    5779
Note: See TracChangeset for help on using the changeset viewer.