source: dev/trunk/ab5.0/abdev/BasicCompiler_Common/src/DataTable.cpp@ 465

Last change on this file since 465 was 465, checked in by dai_9181, 16 years ago

Messenger/ErrorMessengerクラスを導入。SetError関数によるエラー生成を廃止した。

File size: 9.7 KB
Line 
1#include "stdafx.h"
2
3#include <DataTable.h>
4
5#include <memory.h>
6#include <stdlib.h>
7
8int DataTable::AddBinary( const void *buffer, int size ){
9 int retSize = this->size;
10
11 Realloc( this->size + size );
12 memcpy( (char *)this->buffer + retSize, buffer, size );
13
14 return retSize;
15}
16int DataTable::Add( _int64 i64data ){
17 int retSize = size;
18 AddBinary( &i64data, sizeof( _int64 ) );
19 return retSize;
20}
21int DataTable::Add( int i32data ){
22 int retSize = size;
23 AddBinary( &i32data, sizeof( int ) );
24 return retSize;
25}
26int DataTable::Add( double dbl ){
27 int retSize = size;
28 AddBinary( &dbl, sizeof( double ) );
29 return retSize;
30}
31int DataTable::Add( float flt ){
32 int retSize = size;
33 AddBinary( &flt, sizeof( float ) );
34 return retSize;
35}
36int DataTable::AddString( const char *str, int length ){
37 int retSize = size;
38
39 if( compiler.IsUnicode() ){
40 //Shift-JIS → Unicode
41 int size = MultiByteToWideChar(
42 CP_ACP,
43 0,
44 str, length + 1,
45 NULL, 0 ) * 2;
46
47 LPWSTR pwstr = (LPWSTR)malloc( size );
48
49 MultiByteToWideChar(
50 CP_ACP,
51 0,
52 str, length + 1,
53 pwstr, length + 1 );
54
55 AddBinary( pwstr, size );
56
57 free( pwstr );
58 }
59 else{
60 AddBinary( str, length + 1 );
61 }
62
63 return retSize;
64}
65int DataTable::AddString( const char *str )
66{
67 return AddString( str, lstrlen( str ) );
68}
69int DataTable::AddString( const std::string &str )
70{
71 return AddString( str.c_str(), static_cast<int>(str.length()) );
72}
73int DataTable::AddSpace( int size )
74{
75 int retSize = this->size;
76 Realloc( this->size + size );
77 return retSize;
78}
79void DataTable::AddAlignment( int size )
80{
81 if( this->size % size == 0 )
82 {
83 // 既に境界のとき
84 return;
85 }
86 Realloc( this->size + ( size - (int)(this->size%size) ) );
87}
88
89bool DataTable::MakeConstObjectToProcessStaticBuffer( const CClass &objClass, const Jenga::Common::Strings &initMemberValues, int &dataTableOffset )
90{
91 // クラスに必要なバッファサイズを取得
92 int size = objClass.GetSize();
93
94 // クラスのバッファイメージを作成
95 BYTE *buffer = (BYTE *)calloc( size, 1 );
96
97 // クラスのバッファイメージをデータ領域へ追加
98 dataTableOffset = this->AddBinary( buffer, size );
99
100 this->lastMadeConstObjectDataTableOffset = dataTableOffset;
101
102 // com_vtblスケジュール
103 this->schedules.push_back( Schedule( Schedule::ComVtbl, &objClass, dataTableOffset ) );
104
105 // vtblスケジュール
106 this->schedules.push_back( Schedule( Schedule::Vtbl, &objClass, dataTableOffset + PTR_SIZE ) );
107
108 // TypeInfoスケジュール
109 int offsetForTypeInfo = objClass.GetMemberOffset( "_system_object_member_typeInfo" );
110 //this->schedules.push_back( Schedule( Schedule::TypeInfo, &objClass, dataTableOffset + offsetForTypeInfo ) );
111
112 BOOST_FOREACH( const std::string &initMemberValue, initMemberValues )
113 {
114 int i = 0;
115
116 // メンバ名
117 char memberName[VN_SIZE];
118 for( i=0; ; i++ )
119 {
120 if( initMemberValue[i] == '\0' )
121 {
122 // エラー
123 compiler.errorMessenger.OutputFatalError();
124 return false;
125 }
126 if( initMemberValue[i] == '=' )
127 {
128 memberName[i] = 0;
129 break;
130 }
131 memberName[i] = initMemberValue[i];
132 }
133
134 // 初期値
135 const char *initValue = initMemberValue.c_str() + i + 1;
136
137 // メンバを取得
138 const CMember *member = objClass.FindDynamicMember( memberName );
139
140 // メンバオフセットを取得
141 int memberOffset = objClass.GetMemberOffset( member->GetName().c_str() );
142
143 if( member->GetType().IsPointer() && initValue[0] == '[' )
144 {
145 // ポインタ型でバッファ指定のとき
146 int memberDataTableOffset;
147 if( !this->MakeLiteralArrayBuffer( initValue, member->GetType(),memberDataTableOffset ) )
148 {
149 return false;
150 }
151
152 this->Overwrite( dataTableOffset + memberOffset, memberDataTableOffset );
153 this->schedules.push_back( Schedule( Schedule::DataTable, dataTableOffset + memberOffset ) );
154 }
155 else if( member->GetType().IsWhole() )
156 {
157 // 整数
158 Type resultType;
159 _int64 i64data;
160 if( !StaticCalculation( true, initValue, member->GetType().GetBasicType(), &i64data, resultType ) ){
161 return false;
162 }
163
164 this->Overwrite( dataTableOffset + memberOffset, static_cast<long>(i64data) );
165 }
166 else if( member->GetType().IsStringClass() )
167 {
168 // 文字列型
169 char temporary[VN_SIZE];
170 lstrcpy( temporary, initValue );
171 RemoveStringQuotes( temporary );
172 int memberDataTableOffset = MakeConstStringObjectToProcessStaticBuffer( temporary );
173 this->Overwrite( dataTableOffset + memberOffset, memberDataTableOffset );
174 this->schedules.push_back( Schedule( Schedule::DataTable, dataTableOffset + memberOffset ) );
175 }
176 }
177
178 return true;
179}
180bool DataTable::MakeConstObjectToProcessStaticBuffer( const char *expression, Type &resultType, int &dataTableOffset )
181{
182 char CreateParameter[VN_SIZE];
183 int i,i2;
184
185 i=0;
186
187 // クラス名を取得
188 char typeName[VN_SIZE];
189 for(i2=0;;i++,i2++){
190 if(expression[i]=='['){
191 typeName[i2]=0;
192
193 // メンバの初期値を取得
194 i2=GetStringInBracket(CreateParameter,expression+i);
195 RemoveStringBracket(CreateParameter);
196 i+=i2;
197 if(expression[i]!='\0'){
198 compiler.errorMessenger.Output(42,NULL,cp);
199 return false;
200 }
201 break;
202 }
203 typeName[i2]=expression[i];
204 if(expression[i]=='\0'){
205 CreateParameter[0]=0;
206 break;
207 }
208 }
209
210 // パラメータを取得
211 Jenga::Common::Strings initMemberValues;
212 SplitParameter( CreateParameter, initMemberValues );
213
214 if( !compiler.StringToType( typeName, resultType ) ){
215 compiler.errorMessenger.Output(3,typeName,cp);
216 return false;
217 }
218
219 if( !resultType.IsObject() ){
220 ////////////////////////
221 // 通常のデータ型の場合
222 ////////////////////////
223
224 compiler.errorMessenger.Output(121,NULL,cp);
225 return false;
226 }
227
228 return MakeConstObjectToProcessStaticBuffer( resultType.GetClass(), initMemberValues, dataTableOffset );
229}
230
231int DataTable::MakeConstStringObjectToProcessStaticBuffer( const char *str )
232{
233 const CClass &strClass = *compiler.GetObjectModule().meta.GetClasses().GetStringClassPtr();
234 const CClass &objClass = strClass.GetSuperClass();
235
236 // クラスに必要なバッファサイズを取得
237 int size = strClass.GetSize();
238
239 // メンバ位置を取得
240 int offsetForTypeInfo = strClass.GetMemberOffset( "_system_object_member_typeInfo" );
241 int offsetForLength = strClass.GetMemberOffset( "m_Length" );
242 int offsetForChars = strClass.GetMemberOffset( "Chars" );
243
244 // 現在のデータ領域のヘッダ位置を取得
245 int headOffset = this->GetSize();
246
247 // クラスのバッファイメージを作成
248 BYTE *buffer = (BYTE *)calloc( size, 1 );
249 *(long *)(buffer + offsetForLength) = lstrlen( str );
250 *(LONG_PTR *)(buffer + offsetForChars) = headOffset + size;
251
252 // クラスのバッファイメージをデータ領域へ追加
253 int dataTableOffset = this->AddBinary( buffer, size );
254
255 // スケジューリング
256 this->schedules.push_back( Schedule( Schedule::ComVtbl, &strClass, headOffset ) );
257 this->schedules.push_back( Schedule( Schedule::Vtbl, &strClass, headOffset + PTR_SIZE ) );
258 this->schedules.push_back( Schedule( Schedule::TypeInfo, &strClass, headOffset + offsetForTypeInfo ) );
259 this->schedules.push_back( Schedule( Schedule::DataTable, headOffset + offsetForChars ) );
260
261 // 文字列バッファをデータ領域へ追加
262 this->AddString( str );
263
264 return dataTableOffset;
265}
266
267bool DataTable::MakeLiteralArrayBuffer( const char *expression, const Type &baseType, int &dataTableOffset )
268{
269 if( !baseType.IsPointer() ){
270 compiler.errorMessenger.Output(1,NULL,cp);
271 return false;
272 }
273 Type tempBaseType( baseType );
274 tempBaseType.PtrLevelDown();
275
276 char *buffer = (char *)malloc( lstrlen( expression ) + 1 );
277 lstrcpy( buffer, expression );
278 RemoveStringBracket( buffer );
279
280 Jenga::Common::Strings parameters;
281 SplitParameter( buffer, parameters );
282
283 // アラインメント
284 AddAlignment( tempBaseType.GetSize() );
285
286 // データテーブルに空間を確保
287 dataTableOffset = AddSpace( static_cast<int>(tempBaseType.GetSize() * parameters.size()) );
288
289 bool isSuccessful = true;
290 int i = 0;
291 BOOST_FOREACH( const std::string &paramStr, parameters )
292 {
293 if( paramStr.size() == 0 )
294 {
295 throw;
296 }
297 if( paramStr[0] == '\"' )
298 {
299 // 文字列
300 std::string tempParamStr = paramStr;
301 if( !RemoveStringQuotes( tempParamStr ) )
302 {
303 compiler.errorMessenger.OutputFatalError();
304 }
305
306 // 文字列を追加
307 _int64 strOffset;
308 if( tempBaseType.IsStringClass() )
309 {
310 // Stringクラス
311 strOffset = MakeConstStringObjectToProcessStaticBuffer( tempParamStr.c_str() );
312 }
313 else
314 {
315 // Charポインタ
316 strOffset = this->AddString( tempParamStr );
317 }
318
319 // ポインタ値を上書き
320 int tempOffset = dataTableOffset + i * tempBaseType.GetSize();
321 this->OverwriteBinary( tempOffset, &strOffset, tempBaseType.GetSize() );
322
323 // DataTableスケジュール
324 this->schedules.push_back( Schedule( Schedule::DataTable, tempOffset ) );
325 }
326 else
327 {
328 // 数値
329 Type resultType;
330 _int64 i64data;
331 if( !StaticCalculation( true, paramStr.c_str(), tempBaseType.GetBasicType(), &i64data, resultType ) ){
332 isSuccessful = false;
333 break;
334 }
335 if( !resultType.IsWhole() ){
336 // TODO: 実数に未対応
337 compiler.errorMessenger.OutputFatalError();
338 isSuccessful = false;
339 break;
340 }
341
342 // 上書き
343 this->OverwriteBinary( dataTableOffset + i * tempBaseType.GetSize(), &i64data, tempBaseType.GetSize() );
344 }
345
346 i++;
347 }
348
349 free( buffer );
350
351 return isSuccessful;
352}
353
354void DataTable::ResetDataSectionBaseOffset( long dataSectionBaseOffset )
355{
356 BOOST_FOREACH( const Schedule &schedule, schedules )
357 {
358 if( schedule.GetType() == Schedule::DataTable )
359 {
360#ifdef _WIN64
361 OverwriteInt64(
362 schedule.GetOffset(),
363 GetInt64( schedule.GetOffset() ) + dataSectionBaseOffset
364 );
365#else
366 Overwrite(
367 schedule.GetOffset(),
368 GetLong( schedule.GetOffset() ) + dataSectionBaseOffset
369 );
370#endif
371 }
372 }
373}
Note: See TracBrowser for help on using the repository browser.