Ignore:
Timestamp:
May 10, 2008, 3:37:40 PM (17 years ago)
Author:
dai_9181
Message:

DataTableGeneratorクラスを追加。

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/ab5.0/abdev/BasicCompiler_Common/src/DataTable.cpp

    r561 r589  
    8282}
    8383
    84 bool DataTable::MakeConstObjectToProcessStaticBuffer( const CClass &objClass, const Jenga::Common::Strings &initMemberValues, int &dataTableOffset )
    85 {
    86     // クラスに必要なバッファサイズを取得
    87     int size = objClass.GetSize();
    88 
    89     // クラスのバッファイメージを作成
    90     BYTE *buffer = (BYTE *)calloc( size, 1 );
    91 
    92     // クラスのバッファイメージをデータ領域へ追加
    93     dataTableOffset = this->AddBinary( buffer, size );
    94 
    95     this->lastMadeConstObjectDataTableOffset = dataTableOffset;
    96 
    97     // com_vtblスケジュール
    98     this->schedules.push_back( Schedule( Schedule::ComVtbl, &objClass, dataTableOffset ) );
    99 
    100     // vtblスケジュール
    101     this->schedules.push_back( Schedule( Schedule::Vtbl, &objClass, dataTableOffset + PTR_SIZE ) );
    102 
    103     // TypeInfoスケジュール
    104     int offsetForTypeInfo = objClass.GetMemberOffset( "_system_object_member_typeInfo" );
    105     //this->schedules.push_back( Schedule( Schedule::TypeInfo, &objClass, dataTableOffset + offsetForTypeInfo ) );
    106 
    107     BOOST_FOREACH( const std::string &initMemberValue, initMemberValues )
    108     {
    109         int i = 0;
    110 
    111         // メンバ名
    112         char memberName[VN_SIZE];
    113         for( i=0; ; i++ )
    114         {
    115             if( initMemberValue[i] == '\0' )
    116             {
    117                 // エラー
    118                 compiler.errorMessenger.OutputFatalError();
    119                 return false;
    120             }
    121             if( initMemberValue[i] == '=' )
    122             {
    123                 memberName[i] = 0;
    124                 break;
    125             }
    126             memberName[i] = initMemberValue[i];
    127         }
    128 
    129         // 初期値
    130         const char *initValue = initMemberValue.c_str() + i + 1;
    131 
    132         // メンバを取得
    133         const Member *member = objClass.FindDynamicMember( memberName );
    134 
    135         // メンバオフセットを取得
    136         int memberOffset = objClass.GetMemberOffset( member->GetName().c_str() );
    137 
    138         if( member->GetType().IsPointer() && initValue[0] == '[' )
    139         {
    140             // ポインタ型でバッファ指定のとき
    141             int memberDataTableOffset;
    142             if( !this->MakeLiteralArrayBuffer( initValue, member->GetType(),memberDataTableOffset ) )
    143             {
    144                 return false;
    145             }
    146 
    147             this->Overwrite( dataTableOffset + memberOffset, memberDataTableOffset );
    148             this->schedules.push_back( Schedule( Schedule::DataTable, dataTableOffset + memberOffset ) );
    149         }
    150         else if( member->GetType().IsWhole() )
    151         {
    152             // 整数
    153             Type resultType;
    154             _int64 i64data;
    155             if( !StaticCalculation( true, initValue, member->GetType().GetBasicType(), &i64data, resultType ) ){
    156                 return false;
    157             }
    158 
    159             this->Overwrite( dataTableOffset + memberOffset, static_cast<long>(i64data) );
    160         }
    161         else if( member->GetType().IsStringClass() )
    162         {
    163             // 文字列型
    164             char temporary[VN_SIZE];
    165             lstrcpy( temporary, initValue );
    166             RemoveStringQuotes( temporary );
    167             int memberDataTableOffset = MakeConstStringObjectToProcessStaticBuffer( temporary );
    168             this->Overwrite( dataTableOffset + memberOffset, memberDataTableOffset );
    169             this->schedules.push_back( Schedule( Schedule::DataTable, dataTableOffset + memberOffset ) );
    170         }
    171     }
    172 
    173     return true;
    174 }
    175 bool DataTable::MakeConstObjectToProcessStaticBuffer( const char *expression, Type &resultType, int &dataTableOffset )
    176 {
    177     char CreateParameter[VN_SIZE];
    178     int i,i2;
    179 
    180     i=0;
    181 
    182     // クラス名を取得
    183     char typeName[VN_SIZE];
    184     for(i2=0;;i++,i2++){
    185         if(expression[i]=='['){
    186             typeName[i2]=0;
    187 
    188             // メンバの初期値を取得
    189             i2=GetStringInBracket(CreateParameter,expression+i);
    190             RemoveStringBracket(CreateParameter);
    191             i+=i2;
    192             if(expression[i]!='\0'){
    193                 compiler.errorMessenger.Output(42,NULL,cp);
    194                 return false;
    195             }
    196             break;
    197         }
    198         typeName[i2]=expression[i];
    199         if(expression[i]=='\0'){
    200             CreateParameter[0]=0;
    201             break;
    202         }
    203     }
    204 
    205     // パラメータを取得
    206     Jenga::Common::Strings initMemberValues;
    207     SplitParameter( CreateParameter, initMemberValues );
    208 
    209     if( !compiler.StringToType( typeName, resultType ) ){
    210         compiler.errorMessenger.Output(3,typeName,cp);
    211         return false;
    212     }
    213 
    214     if( !resultType.IsObject() ){
    215         ////////////////////////
    216         // 通常のデータ型の場合
    217         ////////////////////////
    218 
    219         compiler.errorMessenger.Output(121,NULL,cp);
    220         return false;
    221     }
    222 
    223     return MakeConstObjectToProcessStaticBuffer( resultType.GetClass(), initMemberValues, dataTableOffset );
    224 }
    225 
    226 int DataTable::MakeConstStringObjectToProcessStaticBuffer( const char *str )
    227 {
    228     const CClass &strClass = *compiler.GetObjectModule().meta.GetClasses().GetStringClassPtr();
    229     const CClass &objClass = strClass.GetSuperClass();
    230 
    231     // クラスに必要なバッファサイズを取得
    232     int size = strClass.GetSize();
    233 
    234     // メンバ位置を取得
    235     int offsetForTypeInfo = strClass.GetMemberOffset( "_system_object_member_typeInfo" );
    236     int offsetForLength = strClass.GetMemberOffset( "m_Length" );
    237     int offsetForChars = strClass.GetMemberOffset( "Chars" );
    238 
    239     // 現在のデータ領域のヘッダ位置を取得
    240     int headOffset = this->GetSize();
    241 
    242     // クラスのバッファイメージを作成
    243     BYTE *buffer = (BYTE *)calloc( size, 1 );
    244     *(long *)(buffer + offsetForLength) = lstrlen( str );
    245     *(LONG_PTR *)(buffer + offsetForChars) = headOffset + size;
    246 
    247     // クラスのバッファイメージをデータ領域へ追加
    248     int dataTableOffset = this->AddBinary( buffer, size );
    249 
    250     // スケジューリング
    251     this->schedules.push_back( Schedule( Schedule::ComVtbl, &strClass, headOffset ) );
    252     this->schedules.push_back( Schedule( Schedule::Vtbl, &strClass, headOffset + PTR_SIZE ) );
    253     this->schedules.push_back( Schedule( Schedule::TypeInfo, &strClass, headOffset + offsetForTypeInfo ) );
    254     this->schedules.push_back( Schedule( Schedule::DataTable, headOffset + offsetForChars ) );
    255 
    256     // 文字列バッファをデータ領域へ追加
    257     this->AddString( str );
    258 
    259     return dataTableOffset;
    260 }
    261 
    262 bool DataTable::MakeLiteralArrayBuffer( const char *expression, const Type &baseType, int &dataTableOffset )
    263 {
    264     if( !baseType.IsPointer() ){
    265         compiler.errorMessenger.Output(1,NULL,cp);
    266         return false;
    267     }
    268     Type tempBaseType( baseType );
    269     tempBaseType.PtrLevelDown();
    270 
    271     char *buffer = (char *)malloc( lstrlen( expression ) + 1 );
    272     lstrcpy( buffer, expression );
    273     RemoveStringBracket( buffer );
    274 
    275     Jenga::Common::Strings parameters;
    276     SplitParameter( buffer, parameters );
    277 
    278     // アラインメント
    279     AddAlignment( tempBaseType.GetSize() );
    280 
    281     // データテーブルに空間を確保
    282     dataTableOffset = AddSpace( static_cast<int>(tempBaseType.GetSize() * parameters.size()) );
    283 
    284     bool isSuccessful = true;
    285     int i = 0;
    286     BOOST_FOREACH( const std::string &paramStr, parameters )
    287     {
    288         if( paramStr.size() == 0 )
    289         {
    290             throw;
    291         }
    292         if( paramStr[0] == '\"' )
    293         {
    294             // 文字列
    295             std::string tempParamStr = paramStr;
    296             if( !RemoveStringQuotes( tempParamStr ) )
    297             {
    298                 compiler.errorMessenger.OutputFatalError();
    299             }
    300 
    301             // 文字列を追加
    302             _int64 strOffset;
    303             if( tempBaseType.IsStringClass() )
    304             {
    305                 // Stringクラス
    306                 strOffset = MakeConstStringObjectToProcessStaticBuffer( tempParamStr.c_str() );
    307             }
    308             else
    309             {
    310                 // Charポインタ
    311                 strOffset = this->AddString( tempParamStr );
    312             }
    313 
    314             // ポインタ値を上書き
    315             int tempOffset = dataTableOffset + i * tempBaseType.GetSize();
    316             this->OverwriteBinary( tempOffset, &strOffset, tempBaseType.GetSize() );
    317 
    318             // DataTableスケジュール
    319             this->schedules.push_back( Schedule( Schedule::DataTable, tempOffset  ) );
    320         }
    321         else
    322         {
    323             // 数値
    324             Type resultType;
    325             _int64 i64data;
    326             if( !StaticCalculation( true, paramStr.c_str(), tempBaseType.GetBasicType(), &i64data, resultType ) ){
    327                 isSuccessful = false;
    328                 break;
    329             }
    330             if( !resultType.IsWhole() ){
    331                 // TODO: 実数に未対応
    332                 compiler.errorMessenger.OutputFatalError();
    333                 isSuccessful = false;
    334                 break;
    335             }
    336 
    337             // 上書き
    338             this->OverwriteBinary( dataTableOffset + i * tempBaseType.GetSize(), &i64data, tempBaseType.GetSize() );
    339         }
    340 
    341         i++;
    342     }
    343 
    344     free( buffer );
    345 
    346     return isSuccessful;
    347 }
    348 
    34984void DataTable::ResetDataSectionBaseOffset( long dataSectionBaseOffset )
    35085{
Note: See TracChangeset for help on using the changeset viewer.