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

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