Changeset 355 in dev for trunk/abdev/BasicCompiler_Common/src/DataTable.cpp
- Timestamp:
- Nov 2, 2007, 2:53:56 AM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/abdev/BasicCompiler_Common/src/DataTable.cpp
r273 r355 71 71 } 72 72 73 const void *DataTable::GetPtr() const 74 { 75 return buffer; 76 } 77 int DataTable::GetSize() const 78 { 79 return size; 80 } 73 bool 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 } 161 bool 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 212 int 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 247 bool 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 300 void 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.