Ignore:
Timestamp:
Oct 9, 2007, 1:10:33 AM (17 years ago)
Author:
dai_9181
Message:

vtblの構造を変更。vtblMasterListをはさんでvtblを表現した。
その他メンバ名変更。
ClassPrototypeクラスを追加。

File:
1 edited

Legend:

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

    r340 r342  
    166166bool CClass::IsInheritsInterface( const CClass *pInterfaceClass ) const
    167167{
    168     BOOST_FOREACH( const InheritedInterface &objInterface, interfaces ){
    169         if( pInterfaceClass == &objInterface.GetInterfaceClass() ){
     168    BOOST_FOREACH( const ::Interface &objInterface, interfaces ){
     169        if( pInterfaceClass == &objInterface.GetClass() ){
    170170            return true;
    171171        }
     
    320320
    321321    //メソッドをコピー
    322     BOOST_FOREACH( const CMethod *pBaseMethod, inheritsClass.GetMethods() ){
     322    BOOST_FOREACH( const CMethod *pBaseMethod, inheritsClass.GetDynamicMethods() ){
    323323        CMethod *pMethod = new DynamicMethod( *pBaseMethod );
    324324
     
    340340        }
    341341
    342         methods.push_back( pMethod );
     342        GetDynamicMethods().push_back( pMethod );
    343343    }
    344344
     
    368368
    369369    //メソッドをコピー
    370     BOOST_FOREACH( const CMethod *pBaseMethod, inheritsInterface.GetMethods() ){
     370    BOOST_FOREACH( const CMethod *pBaseMethod, inheritsInterface.GetDynamicMethods() ){
    371371        CMethod *pMethod = new DynamicMethod( *pBaseMethod );
    372372
     
    388388        }
    389389
    390         methods.push_back( pMethod );
    391     }
    392 
    393     interfaces.push_back( InheritedInterface( const_cast<CClass *>(&inheritsInterface), vtblNum ) );
     390        GetDynamicMethods().push_back( pMethod );
     391    }
     392
     393    //interfaces.push_back( Interface( &inheritsInterface, vtblNum ) );
    394394
    395395    //仮想関数の数
     
    399399}
    400400
     401bool CClass::Implements( const CClass &interfaceClass, int nowLine )
     402{
     403    if( !interfaceClass.IsInterface() )
     404    {
     405        // インターフェイスではないとき
     406        SetError(138,interfaceClass.GetName().c_str(),nowLine );
     407        return false;
     408    }
     409
     410    if( !interfaceClass.IsReady() ){
     411        // インターフェイスが未解析のとき
     412        pobj_LoopRefCheck->add(this->GetName().c_str());
     413        compiler.GetObjectModule().meta.GetClasses().GetClass_recur(interfaceClass.GetName().c_str());
     414        pobj_LoopRefCheck->del(this->GetName().c_str());
     415    }
     416
     417    interfaces.push_back( ::Interface( &interfaceClass ) );
     418
     419    return true;
     420}
    401421bool CClass::Implements( const char *interfaceNames, int nowLine )
    402422{
    403423    Jenga::Common::Strings paramStrs;
    404424    SplitParameter( interfaceNames, paramStrs );
    405 
    406     // TODO: 実装
     425   
     426    BOOST_FOREACH( const std::string &paramStr, paramStrs )
     427    {
     428        //継承元クラスを取得
     429        const CClass *pInterfaceClass = compiler.GetObjectModule().meta.GetClasses().Find( paramStr.c_str() );
     430        if( !pInterfaceClass ){
     431            SetError(106,paramStr.c_str(),nowLine);
     432            continue;
     433        }
     434
     435        // インターフェイスを継承する
     436        Implements( *pInterfaceClass, nowLine );
     437    }
     438
    407439    return true;
    408440}
     
    489521
    490522    if( fConstructor == 1 )
    491         pobj_c->SetConstructorMemberSubIndex( (int)pobj_c->GetMethods().size() );
     523        pobj_c->SetConstructorMemberSubIndex( (int)pobj_c->GetDynamicMethods().size() );
    492524    else if( bDestructor )
    493         pobj_c->SetDestructorMemberSubIndex( (int)pobj_c->GetMethods().size() );
     525        pobj_c->SetDestructorMemberSubIndex( (int)pobj_c->GetDynamicMethods().size() );
    494526
    495527
     
    505537
    506538    //メソッド
    507     BOOST_FOREACH( const CMethod *pMethod, pobj_c->GetMethods() ){
     539    BOOST_FOREACH( const CMethod *pMethod, pobj_c->GetDynamicMethods() ){
    508540        //基底クラスと重複する場合はオーバーライドを行う
    509541        if( pMethod->GetInheritsClassPtr() ) continue;
     
    524556
    525557    //メソッドのオーバーライド
    526     BOOST_FOREACH( CMethod *pMethod, pobj_c->GetMethods() ){
     558    BOOST_FOREACH( CMethod *pMethod, pobj_c->GetDynamicMethods() ){
    527559        if( pMethod->GetUserProc().GetName() == temporary ){
    528560            if( pMethod->GetUserProc().Params().Equals( pUserProc->Params() )
     
    565597    }
    566598    else{
    567         pobj_c->GetMethods().Add(pUserProc, accessibility, isConst, isAbstract, isVirtual);
     599        pobj_c->GetDynamicMethods().Add(pUserProc, accessibility, isConst, isAbstract, isVirtual);
    568600    }
    569601}
     
    576608
    577609    //メソッド
    578     BOOST_FOREACH( const CMethod *pMethod, methods ){
     610    BOOST_FOREACH( const CMethod *pMethod, GetDynamicMethods() ){
    579611        if( lstrcmp( name, pMethod->GetUserProc().GetName().c_str() ) == 0 ){
    580612            return 1;
     
    727759    return alignment;
    728760}
     761
     762int CClass::GetVtblMasterListIndex( const UserProc *pUserProc ) const
     763{
     764    int index = 0;
     765    BOOST_FOREACH( const CMethod *pMethod, GetDynamicMethods() ){
     766        if( &pMethod->GetUserProc() == pUserProc )
     767        {
     768            return index;
     769        }
     770    }
     771
     772    BOOST_FOREACH( const ::Interface &objInterface, interfaces )
     773    {
     774        index++;
     775
     776        BOOST_FOREACH( const CMethod *pMethod, objInterface.GetClass().GetDynamicMethods() ){
     777            if( &pMethod->GetUserProc() == pUserProc )
     778            {
     779                return index;
     780            }
     781        }
     782    }
     783
     784    SetError();
     785    return 0;
     786}
    729787int CClass::GetFuncNumInVtbl( const UserProc *pUserProc ) const
    730788{
    731789    int n = 0;
    732     BOOST_FOREACH( const CMethod *pMethod, methods ){
     790    BOOST_FOREACH( const CMethod *pMethod, GetDynamicMethods() ){
    733791        if( &pMethod->GetUserProc() == pUserProc ) break;
    734792        if( pMethod->IsVirtual() ) n++;
     
    736794    return n;
    737795}
    738 LONG_PTR CClass::GetVtblGlobalOffset(void) const
    739 {
    740 
     796LONG_PTR CClass::GetVtblMasterListOffset() const
     797{
    741798    //既に存在する場合はそれを返す
    742     if(vtbl_offset!=-1) return vtbl_offset;
    743 
    744 
    745 
    746     //////////////////////////////////////
    747     // 存在しないときは新たに生成する
    748     //////////////////////////////////////
    749 
    750     const UserProc **ppsi;
    751     ppsi=(const UserProc **)malloc(GetVtblNum()*sizeof(UserProc *));
     799    if( vtblMasterListOffset == -1 )
     800    {
     801        SetError();
     802    }
     803
     804    return vtblMasterListOffset;
     805}
     806void CClass::GenerateVTablePart( LONG_PTR &vtableDataTableOffset ) const
     807{
     808    const UserProc **ppsi = (const UserProc **)malloc(GetVtblNum()*sizeof(UserProc *));
    752809
    753810    //関数テーブルに値をセット
    754811    int i2 = 0;
    755     BOOST_FOREACH( const CMethod *pMethod, methods ){
    756         if(pMethod->IsVirtual()){
    757             pMethod->GetUserProc().Using();
    758 
    759             if(pMethod->IsAbstract()){
    760                 extern int cp;
    761                 SmoothieException::Throw(300,NULL,cp);
    762 
    763                 ppsi[i2]=0;
    764             }
    765             else{
    766                 ppsi[i2]=&pMethod->GetUserProc();
    767             }
    768             i2++;
    769         }
    770     }
    771 
    772     vtbl_offset=compiler.GetObjectModule().dataTable.AddBinary((void *)ppsi,GetVtblNum()*sizeof(LONG_PTR));
    773 
    774     for( int i=0; i < GetVtblNum(); i++ ){
    775         pobj_Reloc->AddSchedule_DataSection(vtbl_offset+i*sizeof(LONG_PTR));
    776     }
    777 
    778     free(ppsi);
    779 
    780     return vtbl_offset;
    781 }
    782 void CClass::GenerateVTables()
    783 {
    784     if( IsAbstract() )
    785     {
    786         // 抽象クラスは無視
    787         return;
    788     }
    789     if( !IsUsing() )
    790     {
    791         // 使われていないクラスは無視
    792         return;
    793     }
    794 
    795     const UserProc **ppsi;
    796     ppsi=(const UserProc **)malloc(GetVtblNum()*sizeof(UserProc *));
    797 
    798     //関数テーブルに値をセット
    799     int i2 = 0;
    800     BOOST_FOREACH( const CMethod *pMethod, methods ){
     812    BOOST_FOREACH( const CMethod *pMethod, GetDynamicMethods() ){
    801813        if(pMethod->IsVirtual()){
    802814            if( !pMethod->GetUserProc().IsUsing() )
     
    819831    }
    820832
    821     vtbl_offset=compiler.GetObjectModule().dataTable.AddBinary((void *)ppsi,GetVtblNum()*sizeof(LONG_PTR));
     833    vtableDataTableOffset = compiler.GetObjectModule().dataTable.AddBinary( (void *)ppsi, GetVtblNum()*sizeof(LONG_PTR) );
    822834
    823835    for( int i=0; i < GetVtblNum(); i++ ){
    824         pobj_Reloc->AddSchedule_DataSection(vtbl_offset+i*sizeof(LONG_PTR));
     836        pobj_Reloc->AddSchedule_DataSection(vtableDataTableOffset+i*sizeof(LONG_PTR));
    825837    }
    826838
    827839    free(ppsi);
    828840}
    829 void CClass::ActionVtblSchedule(LONG_PTR ImageBase, LONG_PTR MemPos_CodeSection){
     841void CClass::GenerateVTableMasterList( const std::vector<LONG_PTR> &vtableMasterList, LONG_PTR &offset )
     842{
     843    offset = compiler.GetObjectModule().dataTable.AddBinary(
     844        (void *)&vtableMasterList[0],
     845        vtableMasterList.size()*sizeof(LONG_PTR)
     846    );
     847}
     848void CClass::GenerateFullVTables()
     849{
    830850    if( IsAbstract() )
    831851    {
     
    838858        return;
    839859    }
     860
     861    // vtblマスターリストの元データに不要なデータが含まれていたらエラー
     862    if( vtblMasterList.size() )
     863    {
     864        SetError();
     865    }
     866
     867    // 自身のクラスのvtblを生成
     868    GenerateVTablePart( this->vtbl_offset );
     869    vtblMasterList.push_back( this->vtbl_offset );
     870
     871    // インターフェイスのvtblを生成
     872    BOOST_FOREACH( const ::Interface &objInterface, interfaces )
     873    {
     874        LONG_PTR tempVtblOffset;
     875        objInterface.GetClass().GenerateVTablePart( tempVtblOffset );
     876        vtblMasterList.push_back( tempVtblOffset );
     877
     878        objInterface.SetVtblOffset( tempVtblOffset );
     879    }
     880
     881    // vtblマスターリストを生成
     882    GenerateVTableMasterList( vtblMasterList, this->vtblMasterListOffset );
     883}
     884void CClass::ActionVtblSchedule( LONG_PTR ImageBase, LONG_PTR MemPos_CodeSection, LONG_PTR MemPos_DataSection )
     885{
     886    if( IsAbstract() )
     887    {
     888        // 抽象クラスは無視
     889        return;
     890    }
     891    if( !IsUsing() )
     892    {
     893        // 使われていないクラスは無視
     894        return;
     895    }
    840896    if(vtbl_offset==-1) return;
    841897
    842     LONG_PTR *pVtbl;
    843     pVtbl=(LONG_PTR *)((char *)compiler.GetObjectModule().dataTable.GetPtr()+vtbl_offset);
    844 
    845     int i;
    846     for(i=0;i<GetVtblNum();i++){
    847         UserProc *pUserProc;
    848         pUserProc=(UserProc *)pVtbl[i];
    849         if(!pUserProc) continue;
    850 
    851         if( pUserProc->GetBeginOpAddress() == 0
    852             && pUserProc->GetEndOpAddress() == 0 )
    853         {
    854             Jenga::Throw( "未解決の仮想関数が存在する" );
    855         }
    856 
    857         pVtbl[i]=pUserProc->GetBeginOpAddress()+ImageBase+MemPos_CodeSection;
     898    // 自身のクラスのvtbl
     899    {
     900        LONG_PTR *pVtbl = (LONG_PTR *)((char *)compiler.GetObjectModule().dataTable.GetPtr() + vtbl_offset);
     901
     902        for( int i=0; i<GetVtblNum(); i++ ){
     903            const UserProc *pUserProc = (UserProc *)pVtbl[i];
     904            if(!pUserProc) continue;
     905
     906            if( pUserProc->GetBeginOpAddress() == 0
     907                && pUserProc->GetEndOpAddress() == 0 )
     908            {
     909                Jenga::Throw( "未解決の仮想関数が存在する" );
     910            }
     911
     912            pVtbl[i] = pUserProc->GetBeginOpAddress() + ImageBase + MemPos_CodeSection;
     913        }
     914    }
     915
     916    // インターフェイスのvtbl
     917    BOOST_FOREACH( const ::Interface &objInterface, interfaces )
     918    {
     919        LONG_PTR *pVtbl = (LONG_PTR *)((char *)compiler.GetObjectModule().dataTable.GetPtr() + objInterface.GetClass().vtbl_offset);
     920
     921        for( int i=0; i<objInterface.GetClass().GetVtblNum(); i++ ){
     922            const UserProc *pUserProc = (UserProc *)pVtbl[i];
     923            if(!pUserProc) continue;
     924
     925            if( pUserProc->GetBeginOpAddress() == 0
     926                && pUserProc->GetEndOpAddress() == 0 )
     927            {
     928                Jenga::Throw( "未解決の仮想関数が存在する" );
     929            }
     930
     931            pVtbl[i] = pUserProc->GetBeginOpAddress() + ImageBase + MemPos_CodeSection;
     932        }
     933    }
     934
     935    // vtblマスターリスト
     936    LONG_PTR *pVtblMasterList = (LONG_PTR *)((char *)compiler.GetObjectModule().dataTable.GetPtr() + vtblMasterListOffset );
     937    for( int i=0; i<static_cast<int>(vtblMasterList.size()); i++ )
     938    {
     939        pVtblMasterList[i] = vtblMasterList[i] + ImageBase + MemPos_DataSection;
    858940    }
    859941}
     
    862944    // 未実装(abstract)の仮想関数を持つ場合はtrueを返す
    863945
    864     BOOST_FOREACH( const CMethod *pMethod, methods ){
     946    BOOST_FOREACH( const CMethod *pMethod, GetDynamicMethods() ){
    865947        if(pMethod->IsVirtual()){
    866948            if(pMethod->IsAbstract()){
     
    10511133    {
    10521134        CClass *pClass = Iterator_GetNext();
    1053         pClass->GenerateVTables();
    1054     }
    1055 }
    1056 
    1057 void Classes::ActionVtblSchedule(LONG_PTR ImageBase, LONG_PTR MemPos_CodeSection){
     1135        pClass->GenerateFullVTables();
     1136    }
     1137}
     1138
     1139void Classes::ActionVtblSchedule( LONG_PTR ImageBase, LONG_PTR MemPos_CodeSection, LONG_PTR MemPos_DataSection ){
    10581140    Iterator_Reset();
    10591141    while( Iterator_HasNext() )
    10601142    {
    10611143        CClass *pClass = Iterator_GetNext();
    1062         pClass->ActionVtblSchedule(ImageBase,MemPos_CodeSection);
     1144        pClass->ActionVtblSchedule( ImageBase, MemPos_CodeSection, MemPos_DataSection);
    10631145    }
    10641146}
     
    18261908
    18271909        // 仮想関数になるメソッドに使用チェックをつける
    1828         BOOST_FOREACH( const CMethod *pMethod, pParentClass->GetMethods() )
     1910        BOOST_FOREACH( const CMethod *pMethod, pParentClass->GetDynamicMethods() )
    18291911        {
    18301912            if( pMethod->IsVirtual() )
     
    18341916        }
    18351917
    1836         pCompilingMethod = pParentClass->GetMethods().GetMethodPtr( pUserProc );
     1918        pCompilingMethod = pParentClass->GetDynamicMethods().GetMethodPtr( pUserProc );
    18371919        if( !pCompilingMethod ){
    18381920            pCompilingMethod = pParentClass->GetStaticMethods().GetMethodPtr( pUserProc );
Note: See TracChangeset for help on using the changeset viewer.