Changeset 342 in dev for trunk/abdev


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

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

Location:
trunk/abdev
Files:
15 edited

Legend:

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

    r339 r342  
    8181}
    8282
    83 bool Opcode_CallProc(const char *Parameter,const UserProc *pUserProc,DWORD dwFlags,const char *ObjectName ){
    84     int i2;
    85 
     83bool Opcode_CallProc(const char *Parameter,const UserProc *pUserProc,DWORD dwFlags,const char *ObjectName )
     84{
    8685    if( pUserProc->IsMacro() ){
    8786        if( lstrcmpi( pUserProc->GetName().c_str(), "Print" ) == 0 ){
     
    157156        /////////////////////////////////
    158157        pMethod = NULL;
    159         if( ! isStatic ) pMethod = pobj_c->GetMethods().GetMethodPtr( pUserProc );
     158        if( ! isStatic ) pMethod = pobj_c->GetDynamicMethods().GetMethodPtr( pUserProc );
    160159        if( ! pMethod ){
    161160            //動的メソッドが取得できなかったときは静的メソッドを当たる
     
    331330        //                ->func3
    332331
     332        // vtblマスターリストのポインタを取得
    333333        //mov edx,dword ptr[ecx]
    334334        compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EDX, REG_ECX, 0, MOD_BASE );
    335 
    336         i2 = pobj_c->GetFuncNumInVtbl( pUserProc );
     335       
     336        // vtblのポインタを取得
     337        //mov edx,dword ptr[edx+vtblMasterListIndex]
     338        int vtblMasterListIndex = pobj_c->GetVtblMasterListIndex( pUserProc );
     339        compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EDX, REG_EDX, vtblMasterListIndex, MOD_BASE_DISP32 );
     340
     341        int vtblIndex = pobj_c->GetFuncNumInVtbl( pUserProc );
    337342
    338343        //call dword ptr[edx+func_index]
    339         if(i2*PTR_SIZE<=0x7F){
     344        if( vtblIndex * PTR_SIZE <= 0x7F )
     345        {
    340346            compiler.codeGenerator.PutOld(
    341347                (char)0xFF,
    342348                (char)0x52,
    343                 (char)(i2*PTR_SIZE)
     349                (char)(vtblIndex*PTR_SIZE)
    344350            );
    345351        }
     
    349355                (char)0x92
    350356            );
    351             compiler.codeGenerator.PutOld( (long)(i2*PTR_SIZE), Schedule::None );
     357            compiler.codeGenerator.PutOld( (long)(vtblIndex*PTR_SIZE), Schedule::None );
    352358        }
    353359    }
  • trunk/abdev/BasicCompiler32/Compile_Func.cpp

    r339 r342  
    274274        //                ->func3
    275275
     276        // vtblマスターリストのポインタを取得
    276277        //mov edx,dword ptr[ecx]
    277278        compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EDX, REG_ECX, 0, MOD_BASE );
    278 
    279         int i2 = pobj_c->GetFuncNumInVtbl( &userProc );
     279       
     280        // vtblのポインタを取得
     281        //mov edx,dword ptr[edx+vtblMasterListIndex]
     282        int vtblMasterListIndex = pobj_c->GetVtblMasterListIndex( &userProc );
     283        compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EDX, REG_EDX, vtblMasterListIndex, MOD_BASE_DISP32 );
     284
     285        int vtblIndex = pobj_c->GetFuncNumInVtbl( &userProc );
    280286
    281287        //mov eax,dword ptr[edx+func_index]
    282         if(i2*PTR_SIZE<=0x7F){
    283             compiler.codeGenerator.op_mov_RM(sizeof(long),REG_EAX,REG_EDX,i2*PTR_SIZE,MOD_BASE_DISP8);
     288        if( vtblIndex * PTR_SIZE <= 0x7F )
     289        {
     290            compiler.codeGenerator.op_mov_RM(sizeof(long),REG_EAX,REG_EDX,vtblIndex*PTR_SIZE,MOD_BASE_DISP8);
    284291        }
    285292        else{
    286             compiler.codeGenerator.op_mov_RM(sizeof(long),REG_EAX,REG_EDX,i2*PTR_SIZE,MOD_BASE_DISP32);
     293            compiler.codeGenerator.op_mov_RM(sizeof(long),REG_EAX,REG_EDX,vtblIndex*PTR_SIZE,MOD_BASE_DISP32);
    287294        }
    288295    }
  • trunk/abdev/BasicCompiler32/Compile_Object.cpp

    r334 r342  
    3939
    4040    std::vector<const UserProc *> subs;
    41     pobj_c->GetMethods().Enum( pobj_c->GetName().c_str(), subs );
     41    pobj_c->GetDynamicMethods().Enum( pobj_c->GetName().c_str(), subs );
    4242
    4343    const UserProc *pUserProc;
     
    5959        // obj._System_SetType( _System_TypeBase.Search( strNamespace, name ) )
    6060        subs.clear();
    61         pobj_c->GetMethods().Enum( "_System_SetType", subs );
     61        pobj_c->GetDynamicMethods().Enum( "_System_SetType", subs );
    6262        if( subs.size() == 1 ){
    6363            char temporary[VN_SIZE];
     
    217217
    218218        // 仮想関数になるメソッドに使用チェックをつける
    219         BOOST_FOREACH( const CMethod *pMethod, classObj.GetMethods() )
     219        BOOST_FOREACH( const CMethod *pMethod, classObj.GetDynamicMethods() )
    220220        {
    221221            if( pMethod->IsVirtual() )
     
    224224            }
    225225        }
     226        BOOST_FOREACH( const ::Interface &objInterface, classObj.GetInterfaces() )
     227        {
     228            BOOST_FOREACH( const CMethod *pMethod, objInterface.GetClass().GetDynamicMethods() )
     229            {
     230                if( pMethod->IsVirtual() )
     231                {
     232                    pMethod->GetUserProc().Using();
     233                }
     234            }
     235        }
    226236    }
    227237
  • trunk/abdev/BasicCompiler32/Compile_Statement.cpp

    r326 r342  
    923923                if(type1.IsObject()){
    924924                    std::vector<const UserProc *> subs;
    925                     type1.GetClass().GetMethods().Enum( CALC_EQUAL, subs );
     925                    type1.GetClass().GetDynamicMethods().Enum( CALC_EQUAL, subs );
    926926                    if( subs.size() == 0 ){
    927927                        return;
  • trunk/abdev/BasicCompiler32/MakePeHdr.cpp

    r334 r342  
    10611061    ////////////////////////////////////////
    10621062    //仮想関数データテーブルスケジュール
    1063     compiler.GetObjectModule().meta.GetClasses().ActionVtblSchedule(ImageBase,MemPos_CodeSection);
     1063    compiler.GetObjectModule().meta.GetClasses().ActionVtblSchedule( ImageBase, MemPos_CodeSection, MemPos_DataSection );
    10641064
    10651065
  • trunk/abdev/BasicCompiler32/NumOpe.cpp

    r334 r342  
    232232    GetVarFormatString(methodName,parameter,lpPtrOffset,dummy,refType);
    233233
    234     objClass.GetMethods().Enum( methodName, userProcs );
     234    objClass.GetDynamicMethods().Enum( methodName, userProcs );
    235235    if(userProcs.size()){
    236236        //オーバーロードを解決
  • trunk/abdev/BasicCompiler32/OperatorProc.cpp

    r334 r342  
    3434
    3535    std::vector<const UserProc *> subs;
    36     pobj_c->GetMethods().Enum( idCalc, subs );
     36    pobj_c->GetDynamicMethods().Enum( idCalc, subs );
    3737    if( subs.size() == 0 ){
    3838        return 0;
     
    254254void CallIndexerGetterProc( const Type &classType, const char *ObjectName, char *Parameter,Type &resultType, DWORD dwProcFlags ){
    255255    std::vector<const UserProc *> subs;
    256     classType.GetClass().GetMethods().Enum( CALC_ARRAY_GET, subs );
     256    classType.GetClass().GetDynamicMethods().Enum( CALC_ARRAY_GET, subs );
    257257    if( subs.size() == 0 ){
    258258        return;
  • trunk/abdev/BasicCompiler_Common/Diagnose.cpp

    r276 r342  
    7979
    8080            // 動的メソッド
    81             BOOST_FOREACH( const CMethod *pMethod, objClass.GetMethods() ){
     81            BOOST_FOREACH( const CMethod *pMethod, objClass.GetDynamicMethods() ){
    8282                if( pMethod->GetUserProc().IsCompiled() ){
    8383                    codeSizeOfClass += pMethod->GetUserProc().GetCodeSize();
     
    113113
    114114            // 動的メソッド
    115             BOOST_FOREACH( const CMethod *pMethod, objClass.GetMethods() ){
     115            BOOST_FOREACH( const CMethod *pMethod, objClass.GetDynamicMethods() ){
    116116                if( pMethod->GetUserProc().IsCompiled() ){
    117117                    codeSizeOfClass += pMethod->GetUserProc().GetCodeSize();
  • trunk/abdev/BasicCompiler_Common/NumOpe_GetType.cpp

    r334 r342  
    201201
    202202    std::vector<const UserProc *> subs;
    203     pobj_c->GetMethods().Enum( idCalc, subs );
     203    pobj_c->GetDynamicMethods().Enum( idCalc, subs );
    204204    if( subs.size() == 0 ){
    205205        return 0;
     
    342342
    343343    vector<const UserProc *> userProcs;
    344     leftType.GetClass().GetMethods().Enum( methodName, userProcs );
     344    leftType.GetClass().GetDynamicMethods().Enum( methodName, userProcs );
    345345    if(userProcs.size()){
    346346        //オーバーロードを解決
  • trunk/abdev/BasicCompiler_Common/Subroutine.cpp

    r332 r342  
    311311{
    312312    vector<const UserProc *> subs;
    313     classType.GetClass().GetMethods().Enum( CALC_ARRAY_GET, subs );
     313    classType.GetClass().GetDynamicMethods().Enum( CALC_ARRAY_GET, subs );
    314314    if( subs.size() == 0 ){
    315315        return false;
  • trunk/abdev/BasicCompiler_Common/error.cpp

    r340 r342  
    203203    if(num==136) lstrcpy( msg, "非仮想関数に対してオーバーライドしようとしました。" );
    204204    if(num==137) lstrcpy(msg,"ImplementsはClass定義内の先頭に記述する必要があります。");
     205    if(num==138) sprintf(msg,"%s はインターフェイスではありません。Implementsできるのはインターフェイスに限ります。",tempKeyWord);
    205206
    206207    //Enum関連
  • trunk/abdev/BasicCompiler_Common/hash.cpp

    r304 r342  
    9090            else{
    9191                //動的メソッドから列挙
    92                 pobj_c->GetMethods().Enum( NestMember, subs );
     92                pobj_c->GetDynamicMethods().Enum( NestMember, subs );
    9393            }
    9494
     
    105105
    106106        // 動的メソッド
    107         compiler.pCompilingClass->GetMethods().Enum( name, subs );
     107        compiler.pCompilingClass->GetDynamicMethods().Enum( name, subs );
    108108    }
    109109
     
    157157    if( pClass ){
    158158        vector<const UserProc *> userProcs;
    159         pClass->GetMethods().Enum( methodName, userProcs );
     159        pClass->GetDynamicMethods().Enum( methodName, userProcs );
    160160        if( userProcs.size() == 1 ){
    161161            return userProcs[0];
  • trunk/abdev/BasicCompiler_Common/include/Class.h

    r340 r342  
    1212class Delegate;
    1313
    14 class InheritedInterface
     14class ClassPrototype : public Prototype
    1515{
    16     CClass *pInterfaceClass;
    17     int vtblOffset;
    18 public:
    19     InheritedInterface( CClass *pInterfaceClass, int vtblOffset )
     16    // 動的メソッド
     17    Methods dynamicMethods;
     18
     19    // XMLシリアライズ用
     20private:
     21    friend class boost::serialization::access;
     22    template<class Archive> void serialize(Archive& ar, const unsigned int version)
     23    {
     24        ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP( Prototype );
     25        ar & BOOST_SERIALIZATION_NVP( dynamicMethods );
     26    }
     27
     28public:
     29    ClassPrototype( const NamespaceScopes &namespaceScopes, const string &name )
     30        : Prototype( namespaceScopes, name )
     31    {
     32    }
     33    ClassPrototype()
     34        : Prototype()
     35    {
     36    }
     37    const Methods &GetDynamicMethods() const
     38    {
     39        return dynamicMethods;
     40    }
     41    Methods &GetDynamicMethods()
     42    {
     43        return dynamicMethods;
     44    }
     45};
     46
     47class Interface : public ClassPrototype
     48{
     49    const CClass *pInterfaceClass;
     50    mutable int vtblOffset;
     51public:
     52    Interface( const CClass *pInterfaceClass )
    2053        : pInterfaceClass( pInterfaceClass )
    21         , vtblOffset( vtblOffset )
    22     {
    23     }
    24 
    25     CClass &GetInterfaceClass() const{
     54        , vtblOffset( -1 )
     55    {
     56    }
     57
     58    const CClass &GetClass() const{
    2659        return *pInterfaceClass;
    2760    }
    28     int GetVtblOffset() const
     61    LONG_PTR GetVtblOffset() const
    2962    {
    3063        return vtblOffset;
    3164    }
     65    void SetVtblOffset( LONG_PTR vtblOffset ) const
     66    {
     67        this->vtblOffset = vtblOffset;
     68    }
    3269};
    33 typedef vector<InheritedInterface> Interfaces;
    34 
    35 class CClass: public Prototype, public Jenga::Common::ObjectInHashmap<CClass>
     70typedef std::vector<Interface> Interfaces;
     71
     72class CClass: public ClassPrototype, public Jenga::Common::ObjectInHashmap<CClass>
    3673{
    3774public:
     
    73110
    74111    // 動的メソッド
    75     Methods methods;
    76112    int ConstructorMemberSubIndex;
    77113    int DestructorMemberSubIndex;
     
    92128        trace_for_serialize( "serializing - CClass" );
    93129
    94         ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP( Prototype );
     130        ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP( ClassPrototype );
    95131        ar & BOOST_SERIALIZATION_NVP( classType );
    96132        ar & BOOST_SERIALIZATION_NVP( importedNamespaces );
     
    102138        ar & BOOST_SERIALIZATION_NVP( dynamicMembers );
    103139        ar & BOOST_SERIALIZATION_NVP( staticMembers );
    104         ar & BOOST_SERIALIZATION_NVP( methods );
    105140        ar & BOOST_SERIALIZATION_NVP( ConstructorMemberSubIndex );
    106141        ar & BOOST_SERIALIZATION_NVP( DestructorMemberSubIndex );
     
    114149
    115150    CClass( const NamespaceScopes &namespaceScopes, const NamespaceScopesCollection &importedNamespaces, const string &name )
    116         : Prototype( namespaceScopes, name )
     151        : ClassPrototype( namespaceScopes, name )
    117152        , importedNamespaces( importedNamespaces )
    118153        , classType( Class )
     
    131166    }
    132167    CClass()
    133         : Prototype()
     168        : ClassPrototype()
    134169        , importedNamespaces()
    135170        , classType()
     
    292327        return ( interfaces.size() != 0 );
    293328    }
     329    const Interfaces &GetInterfaces() const
     330    {
     331        return interfaces;
     332    }
    294333    bool IsInheritsInterface( const CClass *pInterfaceClass ) const;
    295334
     
    300339
    301340    // インターフェイス実装
     341    bool Implements( const CClass &interfaceClass, int nowLine );
    302342    bool Implements( const char *interfaceNames, int nowLine );
    303343
     
    331371    }
    332372
    333     const Methods &GetMethods() const
    334     {
    335         return methods;
    336     }
    337373    const Methods &GetStaticMethods() const
    338374    {
    339375        return staticMethods;
    340     }
    341     Methods &GetMethods()
    342     {
    343         return methods;
    344376    }
    345377    Methods &GetStaticMethods()
     
    352384    {
    353385        if( ConstructorMemberSubIndex == -1 ) return NULL;
    354         return methods[ConstructorMemberSubIndex];
     386        return GetDynamicMethods()[ConstructorMemberSubIndex];
    355387    }
    356388    void SetConstructorMemberSubIndex( int constructorMemberSubIndex )
     
    363395    {
    364396        if( DestructorMemberSubIndex == -1 ) return NULL;
    365         return methods[DestructorMemberSubIndex];
     397        return GetDynamicMethods()[DestructorMemberSubIndex];
    366398    }
    367399    void SetDestructorMemberSubIndex( int destructorMemberSubIndex )
     
    373405    const ::Delegate &GetDelegate() const;
    374406
     407    // ユーザ指定のアラインメント固定値
     408    int GetFixedAlignment() const
     409    {
     410        return fixedAlignment;
     411    }
     412    void SetFixedAlignment( int fixedAlignment )
     413    {
     414        this->fixedAlignment = fixedAlignment;
     415    }
     416
     417    // メンバの総合サイズを取得
     418    int GetSize() const;
     419
     420    // メンバのオフセットを取得
     421    int GetMemberOffset( const char *memberName, int *pMemberNum = NULL ) const;
     422private:
     423    // アラインメント値を取得
     424    int GetAlignment() const;
     425
     426
     427    /////////////////////////////////////////////////////////////////
     428    // vtbl
     429    /////////////////////////////////////////////////////////////////
     430public:
    375431    // vtblに存在する仮想関数の数
    376432    int GetVtblNum() const
     
    390446        return ( vtblNum > 0 );
    391447    }
    392 
    393     // ユーザ指定のアラインメント固定値
    394     int GetFixedAlignment() const
    395     {
    396         return fixedAlignment;
    397     }
    398     void SetFixedAlignment( int fixedAlignment )
    399     {
    400         this->fixedAlignment = fixedAlignment;
    401     }
    402 
    403     // メンバの総合サイズを取得
    404     int GetSize() const;
    405 
    406     // メンバのオフセットを取得
    407     int GetMemberOffset( const char *memberName, int *pMemberNum = NULL ) const;
    408 private:
    409     // アラインメント値を取得
    410     int GetAlignment() const;
    411 
    412     //vtbl
    413 protected:
    414     mutable long vtbl_offset;
    415 public:
     448   
     449private:
     450    long vtbl_offset;
     451    long vtblMasterListOffset;
     452    std::vector<LONG_PTR> vtblMasterList;
     453public:
     454    int GetVtblMasterListIndex( const UserProc *pUserProc ) const;
    416455    int GetFuncNumInVtbl( const UserProc *pUserProc ) const;
    417     LONG_PTR GetVtblGlobalOffset(void) const;
    418     void GenerateVTables();
    419     void ActionVtblSchedule(LONG_PTR ImageBase, LONG_PTR MemPos_CodeSection);
     456    LONG_PTR GetVtblMasterListOffset() const;
     457    void GenerateVTablePart( LONG_PTR &vtableDataTableOffset ) const;
     458    void GenerateVTableMasterList( const std::vector<LONG_PTR> &vtableMasterList, LONG_PTR &offset );
     459    void GenerateFullVTables();
     460    void ActionVtblSchedule( LONG_PTR ImageBase, LONG_PTR MemPos_CodeSection, LONG_PTR MemPos_DataSection );
    420461    bool IsAbstract() const;
    421462
     
    444485    virtual void CollectClassesForNameOnly( const BasicSource &source );
    445486
     487    // vtblを一時的に生成
    446488    void GenerateVTables();
    447     void ActionVtblSchedule(LONG_PTR ImageBase, LONG_PTR MemPos_CodeSection);
     489
     490    // vtblのを正規のオフセットで再構築
     491    void ActionVtblSchedule(LONG_PTR ImageBase, LONG_PTR MemPos_CodeSection, LONG_PTR MemPos_DataSection );
    448492
    449493    virtual void InitStaticMember();
  • 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 );
  • trunk/abdev/BasicCompiler_Common/src/Linker.cpp

    r288 r342  
    108108        if( schedule.GetType() == Schedule::Vtbl )
    109109        {
    110             LONG_PTR vtblAddress = schedule.GetClass().GetVtblGlobalOffset();
     110            LONG_PTR vtblMasterListOffset = schedule.GetClass().GetVtblMasterListOffset();
    111111
    112112            nativeCode.Overwrite(
    113113                schedule.GetOffset(),
    114                 static_cast<long>( vtblAddress + imageBase + dataSectionBaseOffset )
     114                static_cast<long>( vtblMasterListOffset + imageBase + dataSectionBaseOffset )
    115115            );
    116116        }
Note: See TracChangeset for help on using the changeset viewer.