Changeset 282 in dev for trunk/abdev/BasicCompiler_Common


Ignore:
Timestamp:
Aug 14, 2007, 11:57:32 PM (17 years ago)
Author:
dai_9181
Message:

vtbl構築をコード生成後(最終リンクの前)に行うようにした

Location:
trunk/abdev/BasicCompiler_Common
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/abdev/BasicCompiler_Common/include/Class.h

    r272 r282  
    360360    int GetFuncNumInVtbl( const UserProc *pUserProc ) const;
    361361    LONG_PTR GetVtblGlobalOffset(void) const;
     362    void GenerateVTables();
    362363    void ActionVtblSchedule(LONG_PTR ImageBase, LONG_PTR MemPos_CodeSection);
    363364    bool IsAbstract() const;
     
    387388    virtual void CollectClassesForNameOnly( const BasicSource &source );
    388389
     390    void GenerateVTables();
    389391    void ActionVtblSchedule(LONG_PTR ImageBase, LONG_PTR MemPos_CodeSection);
    390392
  • trunk/abdev/BasicCompiler_Common/include/CodeGenerator.h

    r276 r282  
    448448    void op_ret( short stackFrameSize );
    449449    void op_addressof( int reg, const UserProc *pUserProc );
     450    void op_mov_RV_vtbl( int reg, const CClass *pClass );
    450451#endif
    451452
  • trunk/abdev/BasicCompiler_Common/include/Linker.h

    r273 r282  
    3434    void ResolveGlobalVarSchedules( long rwSectionBaseOffset );
    3535
     36    // vtblスケジュール
     37    void ResolveVtblSchedule( long dataSectionBaseOffset );
     38
    3639    // リンク
    3740    void Link( ObjectModule &masterObjectModule );
  • trunk/abdev/BasicCompiler_Common/include/NativeCode.h

    r280 r282  
    2121        AddressOf,      // ユーザ定義関数位置スケジュール
    2222        DllProc,        // DLL関数位置スケジュール
     23        Vtbl,           // vtblスケジュール
    2324    };
    2425
     
    3132        const ::UserProc *pUserProc;
    3233        const ::DllProc *pDllProc;
     34        const ::CClass *pClass;
    3335    };
    3436
     
    5254            ar & boost::serialization::make_nvp("pDllProc", const_cast<::DllProc *&>(pDllProc));
    5355            break;
     56        case Vtbl:
     57            ar & boost::serialization::make_nvp("pClass", const_cast<::CClass *&>(pClass));
     58            break;
    5459        default:
    5560            ar & BOOST_SERIALIZATION_NVP( lpValue );
     
    8085    {
    8186    }
     87    Schedule( const ::CClass *pClass, long offset )
     88        : type( Schedule::Vtbl )
     89        , offset( offset )
     90        , pClass( pClass )
     91    {
     92    }
    8293    ~Schedule()
    8394    {
     
    111122        }
    112123        return *pUserProc;
     124    }
     125    const ::CClass &GetClass() const
     126    {
     127        if( type != Schedule::Vtbl )
     128        {
     129            SetError();
     130        }
     131        return *pClass;
    113132    }
    114133
     
    360379    void PutUserProcSchedule( const UserProc *pUserProc, bool isCall );
    361380    void PutDllProcSchedule( const DllProc *pDllProc );
     381    void PutVtblSchedule( const CClass *pClass );
    362382    void Put( short s )
    363383    {
  • trunk/abdev/BasicCompiler_Common/include/Source.h

    r281 r282  
    176176        bool isEqualBasbuf = false;
    177177        extern char *basbuf;
    178         if( basbuf == buffer )
     178        if( basbuf == buffer + 2 )
    179179        {
    180180            isEqualBasbuf = true;
  • trunk/abdev/BasicCompiler_Common/src/Class.cpp

    r276 r282  
    720720    return vtbl_offset;
    721721}
     722void CClass::GenerateVTables()
     723{
     724    if( IsAbstract() )
     725    {
     726        // 抽象クラスは無視
     727        return;
     728    }
     729    if( !IsUsing() )
     730    {
     731        // 使われていないクラスは無視
     732        return;
     733    }
     734
     735    const UserProc **ppsi;
     736    ppsi=(const UserProc **)malloc(GetVtblNum()*sizeof(UserProc *));
     737
     738    //関数テーブルに値をセット
     739    int i2 = 0;
     740    BOOST_FOREACH( const CMethod *pMethod, methods ){
     741        if(pMethod->IsVirtual()){
     742            if( !pMethod->GetUserProc().IsUsing() )
     743            {
     744                ts((char *)pMethod->GetUserProc().GetFullName().c_str());
     745            }
     746            pMethod->GetUserProc().Using();
     747
     748            if(pMethod->IsAbstract()){
     749                extern int cp;
     750                SmoothieException::Throw(300,NULL,cp);
     751
     752                ppsi[i2]=0;
     753            }
     754            else{
     755                ppsi[i2]=&pMethod->GetUserProc();
     756            }
     757            i2++;
     758        }
     759    }
     760
     761    vtbl_offset=compiler.GetObjectModule().dataTable.AddBinary((void *)ppsi,GetVtblNum()*sizeof(LONG_PTR));
     762
     763    for( int i=0; i < GetVtblNum(); i++ ){
     764        pobj_Reloc->AddSchedule_DataSection(vtbl_offset+i*sizeof(LONG_PTR));
     765    }
     766
     767    free(ppsi);
     768}
    722769void CClass::ActionVtblSchedule(LONG_PTR ImageBase, LONG_PTR MemPos_CodeSection){
     770    if( IsAbstract() )
     771    {
     772        // 抽象クラスは無視
     773        return;
     774    }
     775    if( !IsUsing() )
     776    {
     777        // 使われていないクラスは無視
     778        return;
     779    }
    723780    if(vtbl_offset==-1) return;
    724781
     
    731788        pUserProc=(UserProc *)pVtbl[i];
    732789        if(!pUserProc) continue;
     790
     791        if( pUserProc->GetBeginOpAddress() == 0
     792            && pUserProc->GetEndOpAddress() == 0 )
     793        {
     794            Jenga::Throw( "未解決の仮想関数が存在する" );
     795        }
    733796
    734797        pVtbl[i]=pUserProc->GetBeginOpAddress()+ImageBase+MemPos_CodeSection;
     
    908971                }
    909972        }
     973    }
     974}
     975
     976void Classes::GenerateVTables()
     977{
     978    Iterator_Reset();
     979    while( Iterator_HasNext() )
     980    {
     981        CClass *pClass = Iterator_GetNext();
     982        pClass->GenerateVTables();
    910983    }
    911984}
     
    16151688        pParentClass->Using();
    16161689
     1690        // 仮想関数になるメソッドに使用チェックをつける
     1691        BOOST_FOREACH( const CMethod *pMethod, pParentClass->GetMethods() )
     1692        {
     1693            if( pMethod->IsVirtual() )
     1694            {
     1695                pMethod->GetUserProc().Using();
     1696            }
     1697        }
     1698
    16171699        pCompilingMethod = pParentClass->GetMethods().GetMethodPtr( pUserProc );
    16181700        if( !pCompilingMethod ){
  • trunk/abdev/BasicCompiler_Common/src/Linker.cpp

    r276 r282  
    102102}
    103103
     104void Linker::ResolveVtblSchedule( long dataSectionBaseOffset )
     105{
     106    BOOST_FOREACH( const Schedule &schedule, nativeCode.GetSchedules() )
     107    {
     108        if( schedule.GetType() == Schedule::Vtbl )
     109        {
     110            LONG_PTR vtblAddress = schedule.GetClass().GetVtblGlobalOffset();
     111
     112            nativeCode.Overwrite(
     113                schedule.GetOffset(),
     114                static_cast<long>( vtblAddress + imageBase + dataSectionBaseOffset )
     115            );
     116        }
     117    }
     118}
     119
    104120void Linker::Link( ObjectModule &masterObjectModule )
    105121{
  • trunk/abdev/BasicCompiler_Common/src/NativeCode.cpp

    r280 r282  
    6464}
    6565
     66void NativeCode::PutVtblSchedule( const CClass *pClass )
     67{
     68    schedules.push_back( Schedule( pClass, size ) );
     69
     70    *((long *)(codeBuffer+size))=0;
     71    size += sizeof(long);
     72}
     73
    6674void NativeCode::NextSourceLine()
    6775{
  • trunk/abdev/BasicCompiler_Common/src/ObjectModule.cpp

    r280 r282  
    3333        this->sources.push_back( source );
    3434    }
     35
     36    // TODO: basbufがいらなくなったら消す
     37    extern char *basbuf;
     38    basbuf = this->sources[0].GetBuffer();
    3539}
    3640
Note: See TracChangeset for help on using the changeset viewer.