source: dev/trunk/abdev/BasicCompiler_Common/src/DataTable.cpp@ 370

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

COM修飾子に対応。COMインターフェイスを呼び出せるようにした

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