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

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