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