Ignore:
Timestamp:
Nov 2, 2007, 2:53:56 AM (17 years ago)
Author:
dai_9181
Message:

静的領域に初期オブジェクトを配置可能にした

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

Legend:

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

    r353 r355  
    12941294        compiler.GetNamespaceSupporter().GetLivingNamespaceScopes() = objClass.GetNamespaceScopes();
    12951295
     1296        DWORD dwFlags = 0;
     1297        if( objClass.GetName() == "_System_TypeBase" )
     1298        {
     1299            // _System_TypeBaseクラスはグローバル、スタティック領域を初期化するためのクラスなのでここでの初期化は除外する
     1300            dwFlags |= DIMFLAG_NONCALL_CONSTRACTOR;
     1301        }
     1302
    12961303        int i=0;
    12971304        BOOST_FOREACH( CMember *member, objClass.GetStaticMembers() ){
     
    13041311                member->GetInitializeExpression().c_str(),
    13051312                member->GetConstructParameter().c_str(),
    1306                 0);
     1313                dwFlags);
    13071314
    13081315            i++;
     
    18921899            // 未使用のクラスは無視する
    18931900            continue;
    1894         }
     1901        }   
    18951902
    18961903        char referenceOffsetsBuffer[1024] = "";
     
    19111918
    19121919        sprintf( temporary
    1913             , "Add(%c%c_System_TypeForClass(\"%s\",\"%s\",[%s],%d))"
     1920            , "Add(%c%c_System_TypeForClass[strNamespace=\"%s\",name=\"%s\",fullName=\"%s\",referenceOffsets=[%s],numOfReference=%d])"
    19141921            , 1
    1915             , ESC_NEW
    1916             , ""                            // 名前空間 (TODO: 実装)
    1917             , objClass.GetName().c_str()    // クラス名
    1918             , referenceOffsetsBuffer        // 参照メンバオフセット配列
    1919             , numOfReference                // 参照メンバの個数
     1922            , ESC_SYSTEM_STATIC_NEW
     1923            , objClass.GetNamespaceScopes().ToString().c_str()      // 名前空間
     1924            , objClass.GetName().c_str()                            // クラス名
     1925            , objClass.GetFullName().c_str()                        // フルネーム
     1926            , referenceOffsetsBuffer                                // 参照メンバオフセット配列
     1927            , numOfReference                                        // 参照メンバの個数
    19201928            );
    19211929
    19221930        // コンパイル
    19231931        ChangeOpcode( temporary );
    1924     }
    1925 
    1926 
     1932
     1933        objClass.SetTypeInfoDataTableOffset(
     1934            compiler.GetObjectModule().dataTable.GetLastMadeConstObjectDataTableOffset()
     1935        );
     1936    }
     1937}
     1938void Classes::Compile_System_InitializeUserTypesForBaseType()
     1939{
     1940    extern int cp;
     1941    cp = -1;
    19271942    ////////////////////////////////////////////////////////////////////
    19281943    // 基底クラスを登録
    19291944    ////////////////////////////////////////////////////////////////////
    19301945
     1946    char temporary[VN_SIZE];
    19311947    sprintf(temporary, "%c%ctempType=Nothing%c%cTypeBaseImpl"
    19321948        , HIBYTE( COM_DIM )
     
    19501966        if( objClass.HasSuperClass() ){
    19511967            sprintf( temporary
    1952                 , "tempType=Search(\"%s\",\"%s\")"
    1953                 , ""                            // 名前空間 (TODO: 実装)
    1954                 , objClass.GetName().c_str()    // クラス名
     1968                , "tempType=Search(\"%s\")"
     1969                , objClass.GetFullName().c_str()
    19551970                );
    19561971
     
    19591974
    19601975            sprintf( temporary
    1961                 , "tempType.SetBaseType(Search(\"%s\",\"%s\"))"
    1962                 , ""                                // 名前空間 (TODO: 実装)
    1963                 , objClass.GetSuperClass().GetName().c_str()    // 基底クラス名
     1976                , "tempType.SetBaseType(Search(\"%s\"))"
     1977                , objClass.GetSuperClass().GetFullName().c_str()
    19641978                );
    19651979
  • trunk/abdev/BasicCompiler_Common/src/DataTable.cpp

    r273 r355  
    7171}
    7272
    73 const void *DataTable::GetPtr() const
    74 {
    75     return buffer;
    76 }
    77 int DataTable::GetSize() const
    78 {
    79     return size;
    80 }
     73bool DataTable::MakeConstObjectToProcessStaticBuffer( const CClass &objClass, const Jenga::Common::Strings &initMemberValues, int &dataTableOffset )
     74{
     75    // クラスに必要なバッファサイズを取得
     76    int size = objClass.GetSize();
     77
     78    // クラスのバッファイメージを作成
     79    BYTE *buffer = (BYTE *)calloc( size, 1 );
     80
     81    // クラスのバッファイメージをデータ領域へ追加
     82    dataTableOffset = this->AddBinary( buffer, size );
     83
     84    this->lastMadeConstObjectDataTableOffset = dataTableOffset;
     85
     86    // vtblスケジュール
     87    this->schedules.push_back( Schedule( &objClass, dataTableOffset ) );
     88
     89    // TypeInfoスケジュール
     90    int offsetForTypeInfo = objClass.GetMemberOffset( "typeInfo" );
     91    //this->schedules.push_back( Schedule( Schedule::TypeInfo, &objClass, dataTableOffset + offsetForTypeInfo ) );
     92
     93    BOOST_FOREACH( const std::string &initMemberValue, initMemberValues )
     94    {
     95        int i = 0;
     96
     97        // メンバ名
     98        char memberName[VN_SIZE];
     99        for( i=0; ; i++ )
     100        {
     101            if( initMemberValue[i] == '\0' )
     102            {
     103                // エラー
     104                SetError();
     105                return false;
     106            }
     107            if( initMemberValue[i] == '=' )
     108            {
     109                memberName[i] = 0;
     110                break;
     111            }
     112            memberName[i] = initMemberValue[i];
     113        }
     114
     115        // 初期値
     116        const char *initValue = initMemberValue.c_str() + i + 1;
     117
     118        // メンバを取得
     119        const CMember *member = objClass.FindDynamicMember( memberName );
     120
     121        // メンバオフセットを取得
     122        int memberOffset = objClass.GetMemberOffset( member->GetName().c_str() );
     123
     124        if( member->GetType().IsPointer() && initValue[0] == '[' )
     125        {
     126            // ポインタ型でバッファ指定のとき
     127            int memberDataTableOffset;
     128            if( !this->MakeLiteralArrayBuffer( initValue, member->GetType(),memberDataTableOffset ) )
     129            {
     130                return false;
     131            }
     132
     133            this->Overwrite( dataTableOffset + memberOffset, memberDataTableOffset );
     134            this->schedules.push_back( Schedule( Schedule::DataTable, dataTableOffset + memberOffset ) );
     135        }
     136        else if( member->GetType().IsWhole() )
     137        {
     138            // 整数
     139            Type resultType;
     140            _int64 i64data;
     141            if( !StaticCalculation( true, initValue, member->GetType().GetBasicType(), &i64data, resultType ) ){
     142                return false;
     143            }
     144
     145            this->Overwrite( dataTableOffset + memberOffset, static_cast<long>(i64data) );
     146        }
     147        else if( member->GetType().IsStringClass() )
     148        {
     149            // 文字列型
     150            char temporary[VN_SIZE];
     151            lstrcpy( temporary, initValue );
     152            RemoveStringQuotes( temporary );
     153            int memberDataTableOffset = MakeConstStringObjectToProcessStaticBuffer( temporary );
     154            this->Overwrite( dataTableOffset + memberOffset, memberDataTableOffset );
     155            this->schedules.push_back( Schedule( Schedule::DataTable, dataTableOffset + memberOffset ) );
     156        }
     157    }
     158
     159    return true;
     160}
     161bool DataTable::MakeConstObjectToProcessStaticBuffer( const char *expression, Type &resultType, int &dataTableOffset )
     162{
     163    char CreateParameter[VN_SIZE];
     164    int i,i2;
     165
     166    i=0;
     167
     168    // クラス名を取得
     169    char typeName[VN_SIZE];
     170    for(i2=0;;i++,i2++){
     171        if(expression[i]=='['){
     172            typeName[i2]=0;
     173
     174            // メンバの初期値を取得
     175            i2=GetStringInBracket(CreateParameter,expression+i);
     176            RemoveStringBracket(CreateParameter);
     177            i+=i2;
     178            if(expression[i]!='\0'){
     179                SetError(42,NULL,cp);
     180                return false;
     181            }
     182            break;
     183        }
     184        typeName[i2]=expression[i];
     185        if(expression[i]=='\0'){
     186            CreateParameter[0]=0;
     187            break;
     188        }
     189    }
     190
     191    // パラメータを取得
     192    Jenga::Common::Strings initMemberValues;
     193    SplitParameter( CreateParameter, initMemberValues );
     194
     195    if( !compiler.StringToType( typeName, resultType ) ){
     196        SetError(3,typeName,cp);
     197        return false;
     198    }
     199
     200    if( !resultType.IsObject() ){
     201        ////////////////////////
     202        // 通常のデータ型の場合
     203        ////////////////////////
     204
     205        SetError(121,NULL,cp);
     206        return false;
     207    }
     208
     209    return MakeConstObjectToProcessStaticBuffer( resultType.GetClass(), initMemberValues, dataTableOffset );
     210}
     211
     212int DataTable::MakeConstStringObjectToProcessStaticBuffer( const char *str )
     213{
     214    const CClass &strClass = *compiler.GetObjectModule().meta.GetClasses().GetStringClassPtr();
     215    const CClass &objClass = strClass.GetSuperClass();
     216
     217    // クラスに必要なバッファサイズを取得
     218    int size = strClass.GetSize();
     219
     220    // メンバ位置を取得
     221    int offsetForTypeInfo = strClass.GetMemberOffset( "typeInfo" );
     222    int offsetForLength = strClass.GetMemberOffset( "m_Length" );
     223    int offsetForChars = strClass.GetMemberOffset( "Chars" );
     224
     225    // 現在のデータ領域のヘッダ位置を取得
     226    int headOffset = this->GetSize();
     227
     228    // クラスのバッファイメージを作成
     229    BYTE *buffer = (BYTE *)calloc( size, 1 );
     230    *(long *)(buffer + offsetForLength) = lstrlen( str );
     231    *(LONG_PTR *)(buffer + offsetForChars) = headOffset + size;
     232
     233    // クラスのバッファイメージをデータ領域へ追加
     234    int dataTableOffset = this->AddBinary( buffer, size );
     235
     236    // スケジューリング
     237    this->schedules.push_back( Schedule( &strClass, headOffset ) );
     238    this->schedules.push_back( Schedule( Schedule::TypeInfo, &strClass, headOffset + offsetForTypeInfo ) );
     239    this->schedules.push_back( Schedule( Schedule::DataTable, headOffset + offsetForChars ) );
     240
     241    // 文字列バッファをデータ領域へ追加
     242    this->AddString( str );
     243
     244    return dataTableOffset;
     245}
     246
     247bool DataTable::MakeLiteralArrayBuffer( const char *expression, const Type &baseType, int &dataTableOffset )
     248{
     249    if( !baseType.IsPointer() ){
     250        SetError(1,NULL,cp);
     251        return false;
     252    }
     253    Type tempBaseType( baseType );
     254    tempBaseType.PtrLevelDown();
     255
     256    char *buffer = (char *)malloc( lstrlen( expression ) + 1 );
     257    lstrcpy( buffer, expression );
     258    RemoveStringBracket( buffer );
     259
     260    void *binary = malloc( 1 );
     261    int num = 0;
     262
     263    int i = 0;
     264    bool isSuccessful = true;
     265    while( buffer[i] ){
     266        char temporary[1024];
     267
     268        i = GetOneParameter( buffer, i, temporary );
     269        if( buffer[i] == ',' ){
     270            i++;
     271        }
     272
     273        Type resultType;
     274        _int64 i64data;
     275        if( !StaticCalculation( true, temporary, tempBaseType.GetBasicType(), &i64data, resultType ) ){
     276            isSuccessful = false;
     277            break;
     278        }
     279        if( !resultType.IsWhole() ){
     280            // TODO: 実数に未対応
     281            SetError();
     282            isSuccessful = false;
     283            break;
     284        }
     285
     286        binary = realloc( binary, ( num + 1 ) * tempBaseType.GetSize() );
     287        memcpy( (char *)binary + (num * tempBaseType.GetSize()), &i64data, tempBaseType.GetSize() );
     288        num++;
     289    }
     290
     291    free( buffer );
     292
     293    dataTableOffset = this->AddBinary( binary, num * tempBaseType.GetSize() );
     294
     295    free( binary );
     296
     297    return isSuccessful;
     298}
     299
     300void DataTable::ResetDataSectionBaseOffset( long dataSectionBaseOffset )
     301{
     302    BOOST_FOREACH( const Schedule &schedule, schedules )
     303    {
     304        if( schedule.GetType() == Schedule::DataTable )
     305        {
     306#ifdef _WIN64
     307            OverwriteInt64(
     308                schedule.GetOffset(),
     309                GetInt64( schedule.GetOffset() ) + dataSectionBaseOffset
     310            );
     311#else
     312            Overwrite(
     313                schedule.GetOffset(),
     314                GetLong( schedule.GetOffset() ) + dataSectionBaseOffset
     315            );
     316#endif
     317        }
     318    }
     319}
  • trunk/abdev/BasicCompiler_Common/src/Linker.cpp

    r342 r355  
    1717        }
    1818    }
     19
     20    BOOST_FOREACH( const Schedule &schedule, dataTable.schedules )
     21    {
     22        if( schedule.GetType() == Schedule::DataTable )
     23        {
     24#ifdef _WIN64
     25            dataTable.OverwriteInt64(
     26                schedule.GetOffset(),
     27                dataTable.GetInt64( schedule.GetOffset() ) + imageBase + dataSectionBaseOffset
     28            );
     29#else
     30            dataTable.Overwrite(
     31                schedule.GetOffset(),
     32                dataTable.GetLong( schedule.GetOffset() ) + imageBase + dataSectionBaseOffset
     33            );
     34#endif
     35        }
     36    }
    1937}
    2038
     
    116134        }
    117135    }
     136
     137    BOOST_FOREACH( const Schedule &schedule, dataTable.schedules )
     138    {
     139        if( schedule.GetType() == Schedule::Vtbl )
     140        {
     141            LONG_PTR vtblMasterListOffset = schedule.GetClass().GetVtblMasterListOffset();
     142
     143#ifdef _WIN64
     144            dataTable.OverwriteInt64(
     145                schedule.GetOffset(),
     146                vtblMasterListOffset + imageBase + dataSectionBaseOffset
     147            );
     148#else
     149            dataTable.Overwrite(
     150                schedule.GetOffset(),
     151                vtblMasterListOffset + imageBase + dataSectionBaseOffset
     152            );
     153#endif
     154        }
     155    }
     156}
     157
     158void Linker::ResolveTypeInfoSchedule( long dataSectionBaseOffset )
     159{
     160    BOOST_FOREACH( const Schedule &schedule, dataTable.schedules )
     161    {
     162        if( schedule.GetType() == Schedule::TypeInfo )
     163        {
     164            LONG_PTR typeInfoDataTableOffset = schedule.GetClass().GetTypeInfoDataTableOffset();
     165
     166#ifdef _WIN64
     167            dataTable.OverwriteInt64(
     168                schedule.GetOffset(),
     169                typeInfoDataTableOffset + imageBase + dataSectionBaseOffset
     170            );
     171#else
     172            dataTable.Overwrite(
     173                schedule.GetOffset(),
     174                typeInfoDataTableOffset + imageBase + dataSectionBaseOffset
     175            );
     176#endif
     177        }
     178    }
    118179}
    119180
     
    143204    }
    144205}
     206
     207void Linker::SetDataTable( DataTable &dataTable )
     208{
     209    this->dataTable.Add( dataTable );
     210}
  • trunk/abdev/BasicCompiler_Common/src/ObjectModule.cpp

    r322 r355  
    2626
    2727    // データテーブルを結合
     28    objectModule.dataTable.ResetDataSectionBaseOffset( dataSectionBaseOffset );
    2829    dataTable.Add( objectModule.dataTable );
    2930
Note: See TracChangeset for help on using the changeset viewer.