Changeset 282 in dev


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

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

Location:
trunk/abdev
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/abdev/BasicCompiler32/Compile_ProcOp.cpp

    r278 r282  
    499499            //仮想関数テーブルを初期化
    500500            if( compiler.pCompilingClass->IsExistVirtualFunctions()
    501                 && !compiler.pCompilingClass->IsAbstract() ){
    502                     //関数テーブルに値をセット
    503                     int offset = (int)compiler.pCompilingClass->GetVtblGlobalOffset();
    504 
    505                     //mov eax,offset
    506                     compiler.codeGenerator.op_mov_RV( REG_EAX, offset, Schedule::DataTable );
    507 
    508                     //Thisポインタをecxにコピー
    509                     SetThisPtrToReg(REG_ECX);
    510 
    511                     //mov dword ptr[ecx],eax
    512                     compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, REG_ECX, 0, MOD_BASE );
     501                && !compiler.pCompilingClass->IsAbstract() )
     502            {
     503                // mov eax,vtblAddress
     504                compiler.codeGenerator.op_mov_RV_vtbl( REG_EAX, compiler.pCompilingClass );
     505
     506                /* TODO: 消す
     507                //関数テーブルに値をセット
     508                int offset = (int)compiler.pCompilingClass->GetVtblGlobalOffset();
     509
     510                //mov eax,offset
     511                compiler.codeGenerator.op_mov_RV( REG_EAX, offset, Schedule::DataTable );
     512                */
     513
     514                //Thisポインタをecxにコピー
     515                SetThisPtrToReg(REG_ECX);
     516
     517                //mov dword ptr[ecx],eax
     518                compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, REG_ECX, 0, MOD_BASE );
     519
     520
     521                // 仮想関数になるメソッドに使用チェックをつける
     522                BOOST_FOREACH( const CMethod *pMethod, compiler.pCompilingClass->GetMethods() )
     523                {
     524                    if( pMethod->IsVirtual() )
     525                    {
     526                        pMethod->GetUserProc().Using();
     527                    }
     528                }
    513529            }
    514530        }
  • trunk/abdev/BasicCompiler32/MakePeHdr.cpp

    r281 r282  
    509509
    510510
     511    /////////////////////////////////////////////////////////////////
     512    // vtblの構築
     513    /////////////////////////////////////////////////////////////////
     514
     515    compiler.GetObjectModule().meta.GetClasses().GenerateVTables();
     516
     517
    511518
    512519    ////////////////////////////////
    513520    // ここで一旦ログを取る
    514521    ////////////////////////////////
     522
    515523    Diagnose();
    516524
     
    10651073    compiler.linker.ResolveUserProcSchedules( MemPos_CodeSection );
    10661074    compiler.linker.ResolveGlobalVarSchedules( MemPos_RWSection );
     1075    compiler.linker.ResolveVtblSchedule( MemPos_DataSection );
    10671076
    10681077
  • trunk/abdev/BasicCompiler32/x86CodeGenerator.cpp

    r253 r282  
    13111311    pNativeCode->PutUserProcSchedule( pUserProc, false );
    13121312}
     1313void CodeGenerator::op_mov_RV_vtbl( int reg, const CClass *pClass )
     1314{
     1315    // mov reg,vtblAddress
     1316
     1317    //オペコード、レジスタ
     1318    pNativeCode->Put( (char)(0xB8|REGISTER_OPERAND(reg)) );
     1319
     1320    //DISP32
     1321    pNativeCode->PutVtblSchedule( pClass );
     1322}
  • 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.