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

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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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}
Note: See TracChangeset for help on using the changeset viewer.