source: dev/trunk/abdev/BasicCompiler_Common/include/NativeCode.h@ 282

Last change on this file since 282 was 282, checked in by dai_9181, 17 years ago

vtbl構築をコード生成後(最終リンクの前)に行うようにした

File size: 8.4 KB
Line 
1#pragma once
2
3#include <vector>
4
5#include <jenga/include/common/Exception.h>
6
7#include <BoostSerializationSupport.h>
8
9class UserProc;
10
11class Schedule
12{
13public:
14 enum Type
15 {
16 None = 10000,
17 GlobalVar, // グローバル変数スケジュール
18 DataTable, // データテーブル スケジュール
19 Relocation, // リロケーション情報スケジュール
20 UserProc, // ユーザ定義関数呼び出し側スケジュール
21 AddressOf, // ユーザ定義関数位置スケジュール
22 DllProc, // DLL関数位置スケジュール
23 Vtbl, // vtblスケジュール
24 };
25
26private:
27 Type type;
28 long offset;
29
30 union{
31 LONG_PTR lpValue;
32 const ::UserProc *pUserProc;
33 const ::DllProc *pDllProc;
34 const ::CClass *pClass;
35 };
36
37 // XMLシリアライズ用
38private:
39 friend class boost::serialization::access;
40 template<class Archive> void serialize(Archive& ar, const unsigned int version)
41 {
42 trace_for_serialize( "serializing - Schedule" );
43
44 ar & BOOST_SERIALIZATION_NVP( type );
45 ar & BOOST_SERIALIZATION_NVP( offset );
46
47 switch( type )
48 {
49 case UserProc:
50 case AddressOf:
51 ar & boost::serialization::make_nvp("pUserProc", const_cast<::UserProc *&>(pUserProc));
52 break;
53 case DllProc:
54 ar & boost::serialization::make_nvp("pDllProc", const_cast<::DllProc *&>(pDllProc));
55 break;
56 case Vtbl:
57 ar & boost::serialization::make_nvp("pClass", const_cast<::CClass *&>(pClass));
58 break;
59 default:
60 ar & BOOST_SERIALIZATION_NVP( lpValue );
61 break;
62 }
63 }
64
65public:
66 Schedule()
67 {
68 }
69 Schedule( Type type, long offset, LONG_PTR lpValue = 0 )
70 : type( type )
71 , offset( offset )
72 , lpValue( lpValue )
73 {
74 }
75 Schedule( const ::UserProc *pUserProc, long offset )
76 : type( Schedule::UserProc )
77 , offset( offset )
78 , pUserProc( pUserProc )
79 {
80 }
81 Schedule( const ::DllProc *pDllProc, long offset )
82 : type( Schedule::DllProc )
83 , offset( offset )
84 , pDllProc( pDllProc )
85 {
86 }
87 Schedule( const ::CClass *pClass, long offset )
88 : type( Schedule::Vtbl )
89 , offset( offset )
90 , pClass( pClass )
91 {
92 }
93 ~Schedule()
94 {
95 }
96
97 Type GetType() const
98 {
99 return type;
100 }
101 long GetOffset() const
102 {
103 return offset;
104 }
105 LONG_PTR GetLongPtrValue() const
106 {
107 return lpValue;
108 }
109 const ::DllProc &GetDllProc() const
110 {
111 if( type != Schedule::DllProc )
112 {
113 SetError();
114 }
115 return *pDllProc;
116 }
117 const ::UserProc &GetUserProc() const
118 {
119 if( !( type == Schedule::UserProc || type == Schedule::AddressOf ) )
120 {
121 SetError();
122 }
123 return *pUserProc;
124 }
125 const ::CClass &GetClass() const
126 {
127 if( type != Schedule::Vtbl )
128 {
129 SetError();
130 }
131 return *pClass;
132 }
133
134 void SpecifyAddressOf()
135 {
136 if( type != Schedule::UserProc )
137 {
138 SetError();
139 }
140 type = Schedule::AddressOf;
141 }
142};
143typedef std::vector<Schedule> Schedules;
144
145#define CODETYPE_SYSTEMPROC 0x0001
146#define CODETYPE_DEBUGPROC 0x0002
147class SourceLine
148{
149 int lineNum;
150 long nativeCodePos;
151 int sourceIndex;
152 long sourceCodePos;
153 DWORD codeType;
154
155 // XMLシリアライズ用
156private:
157 friend class boost::serialization::access;
158 template<class Archive> void serialize(Archive& ar, const unsigned int version)
159 {
160 trace_for_serialize( "serializing - SourceLine" );
161
162 ar & BOOST_SERIALIZATION_NVP( lineNum );
163 ar & BOOST_SERIALIZATION_NVP( nativeCodePos );
164 ar & BOOST_SERIALIZATION_NVP( sourceIndex );
165 ar & BOOST_SERIALIZATION_NVP( sourceCodePos );
166 ar & BOOST_SERIALIZATION_NVP( codeType );
167 }
168
169public:
170 SourceLine( int lineNum, int nativeCodePos, int sourceIndex, int sourceCodePos, DWORD codeType )
171 : lineNum( lineNum )
172 , nativeCodePos( nativeCodePos )
173 , sourceIndex( sourceIndex )
174 , sourceCodePos( sourceCodePos )
175 , codeType( codeType )
176 {
177 }
178 SourceLine()
179 {
180 }
181
182 int GetLineNum() const
183 {
184 return lineNum;
185 }
186 long GetNativeCodePos() const
187 {
188 return nativeCodePos;
189 }
190 int GetSourceIndex() const
191 {
192 return sourceIndex;
193 }
194 void SetSourceIndex( int sourceIndex )
195 {
196 this->sourceIndex = sourceIndex;
197 }
198 long GetSourceCodePos() const
199 {
200 return sourceCodePos;
201 }
202 void SetSourceCodePos( int sourceCodePos )
203 {
204 this->sourceCodePos = sourceCodePos;
205 }
206 DWORD GetCodeType() const
207 {
208 return codeType;
209 }
210 bool IsInSystemProc() const
211 {
212 return ( (codeType&CODETYPE_SYSTEMPROC) != 0 );
213 }
214 bool IsInDebugProc() const
215 {
216 return ( (codeType&CODETYPE_DEBUGPROC) != 0 );
217 }
218};
219typedef std::vector<SourceLine> SourceLines;
220
221class NativeCode
222{
223 int allocateSize;
224 char *codeBuffer;
225 int size;
226
227 // リンカで解決しなければならないスケジュール
228 Schedules schedules;
229
230 // ソースコード行番号とネイティブコード位置の対応情報
231 SourceLines sourceLines;
232
233 // XMLシリアライズ用
234private:
235 friend class boost::serialization::access;
236 BOOST_SERIALIZATION_SPLIT_MEMBER();
237 template<class Archive> void load(Archive& ar, const unsigned int version)
238 {
239 trace_for_serialize( "serializing(load) - NativeCode" );
240
241 std::string code;
242 ar & BOOST_SERIALIZATION_NVP( code );
243 ar & BOOST_SERIALIZATION_NVP( size );
244 ar & BOOST_SERIALIZATION_NVP( schedules );
245 ar & BOOST_SERIALIZATION_NVP( sourceLines );
246
247 // 読み込み後の処理
248 Realloc( size );
249 for( int i=0; i<size; i++ )
250 {
251 ULONG_PTR l1 = ( ( code[i*3] >= 'a' ) ? ( code[i*3] - 'a' + 0x0a ) : ( code[i*3] - '0' ) ) * 0x10;
252 ULONG_PTR l2 = ( code[i*3+1] >= 'a' ) ? ( code[i*3+1] - 'a' + 0x0a ) : ( code[i*3+1] - '0' );
253 ULONG_PTR l = l1 + l2;
254 codeBuffer[i] = static_cast<char>(l);
255 }
256 }
257 template<class Archive> void save(Archive& ar, const unsigned int version) const
258 {
259 trace_for_serialize( "serializing(save) - NativeCode" );
260
261 // 保存準備
262 char *tempCode = (char *)calloc( (size+1) * 3, 1 );
263 for( int i=0; i<size; i++ )
264 {
265 char temp[32];
266 sprintf( temp, "%02x,", (unsigned char)codeBuffer[i] );
267 tempCode[i*3] = temp[0];
268 tempCode[i*3+1] = temp[1];
269 tempCode[i*3+2] = temp[2];
270 }
271
272 std::string code = tempCode;
273 free( tempCode );
274
275 ar & BOOST_SERIALIZATION_NVP( code );
276 ar & BOOST_SERIALIZATION_NVP( size );
277 ar & BOOST_SERIALIZATION_NVP( schedules );
278 ar & BOOST_SERIALIZATION_NVP( sourceLines );
279 }
280
281
282 void Realloc( int newSize )
283 {
284 if( allocateSize < newSize + 8192 )
285 {
286 while( allocateSize < newSize + 8192 )
287 {
288 allocateSize += 8192;
289 }
290 codeBuffer = (char *)realloc( codeBuffer, allocateSize );
291 }
292 }
293
294public:
295 NativeCode()
296 : allocateSize( 8192 )
297 , codeBuffer( (char *)malloc( allocateSize ) )
298 , size( 0 )
299 {
300 }
301 NativeCode( const NativeCode &nativeCode )
302 : allocateSize( 8192 )
303 , codeBuffer( (char *)malloc( allocateSize ) )
304 , size( 0 )
305 {
306 Put( nativeCode );
307 }
308 NativeCode( const char *codeBuffer, int size )
309 : allocateSize( 8192 )
310 , codeBuffer( (char *)malloc( allocateSize ) )
311 , size( 0 )
312 {
313 Put( codeBuffer, size );
314 }
315 ~NativeCode()
316 {
317 free( codeBuffer );
318 }
319 void Clear()
320 {
321 size = 0;
322 }
323
324 void operator =( const NativeCode &nativeCode )
325 {
326 Clear();
327 Put( nativeCode );
328 }
329
330 const char *GetCodeBuffer() const
331 {
332 return codeBuffer;
333 }
334 int GetSize() const
335 {
336 return size;
337 }
338 const Schedules &GetSchedules() const
339 {
340 return schedules;
341 }
342
343 long GetLong( int codePos ) const
344 {
345 return *(long *)(this->codeBuffer+codePos);
346 }
347
348 void Overwrite( int codePos, char c )
349 {
350 codeBuffer[codePos] = c;
351 }
352 void Overwrite( int codePos, long newLongValue )
353 {
354 *(long *)(this->codeBuffer+codePos) = newLongValue;
355 }
356
357 void Put( const char *codeBuffer, int size )
358 {
359 Realloc( this->size + size );
360
361 memcpy( this->codeBuffer + this->size, codeBuffer, size );
362 this->size += size;
363 }
364 void Put( const NativeCode &nativeCode );
365 void Put( _int64 i64data )
366 {
367 Put( (const char *)(&i64data), sizeof(_int64) );
368 }
369 void Put( long l, Schedule::Type scheduleType = Schedule::None )
370 {
371 if( scheduleType != Schedule::None )
372 {
373 schedules.push_back( Schedule( scheduleType, size ) );
374 }
375
376 *((long *)(codeBuffer+size))=l;
377 size += sizeof(long);
378 }
379 void PutUserProcSchedule( const UserProc *pUserProc, bool isCall );
380 void PutDllProcSchedule( const DllProc *pDllProc );
381 void PutVtblSchedule( const CClass *pClass );
382 void Put( short s )
383 {
384 Put( (const char *)(&s), sizeof(short) );
385 }
386 void Put( char c )
387 {
388 Realloc( size + 1 );
389 codeBuffer[size++] = c;
390 }
391
392 const SourceLines &GetSourceLines() const
393 {
394 return sourceLines;
395 }
396 void NextSourceLine();
397
398 void ResetDataSectionBaseOffset( long dataSectionBaseOffset );
399 void ResetSourceIndexes( long sourceIndexBase );
400};
Note: See TracBrowser for help on using the repository browser.