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

Last change on this file since 265 was 265, checked in by dai_9181, 17 years ago
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
[232]9void ObpPlus( int step = 1 );
[228]10
[244]11class UserProc;
12
[224]13class Schedule
14{
15public:
16 enum Type
17 {
[237]18 None = 10000,
[225]19 GlobalVar, // グローバル変数スケジュール
[237]20 DataTable, // データテーブル スケジュール
[225]21 Relocation, // リロケーション情報スケジュール
[244]22 UserProc, // ユーザ定義関数呼び出し側スケジュール
23 AddressOf, // ユーザ定義関数位置スケジュール
[257]24 DllProc, // DLL関数位置スケジュール
[224]25 };
26
27private:
28 Type type;
[244]29 long offset;
[224]30
[244]31 union{
32 LONG_PTR lpValue;
33 const ::UserProc *pUserProc;
[250]34 const ::DllProc *pDllProc;
[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 );
46 }
47
48public:
49 Schedule()
50 {
51 }
[258]52 Schedule( Type type, long offset, LONG_PTR lpValue = 0 )
[224]53 : type( type )
54 , offset( offset )
[258]55 , lpValue( lpValue )
[224]56 {
57 }
[258]58 Schedule( const ::UserProc *pUserProc, long offset )
[244]59 : type( Schedule::UserProc )
60 , offset( offset )
61 , pUserProc( pUserProc )
62 {
63 }
[258]64 Schedule( const ::DllProc *pDllProc, long offset )
[257]65 : type( Schedule::DllProc )
[250]66 , offset( offset )
67 , pDllProc( pDllProc )
68 {
69 }
[224]70 ~Schedule()
71 {
72 }
[244]73
[257]74 Type GetType() const
75 {
76 return type;
77 }
78 long GetOffset() const
79 {
80 return offset;
81 }
[258]82 LONG_PTR GetLongPtrValue() const
83 {
84 return lpValue;
85 }
[257]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 {
[258]96 if( !( type == Schedule::UserProc || type == Schedule::AddressOf ) )
[257]97 {
98 SetError();
99 }
100 return *pUserProc;
101 }
102
[244]103 void SpecifyAddressOf()
104 {
105 if( type != Schedule::UserProc )
106 {
107 SetError();
108 }
109 type = Schedule::AddressOf;
110 }
[224]111};
112typedef std::vector<Schedule> Schedules;
113
[263]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
[224]179class NativeCode
180{
181 int allocateSize;
182 char *codeBuffer;
183 int size;
184
[263]185 // リンカで解決しなければならないスケジュール
[224]186 Schedules schedules;
187
[263]188 // ソースコード行番号とネイティブコード位置の対応情報
189 SourceLines sourceLines;
190
[224]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 {
[256]197 trace_for_serialize( "serializing(load) - NativeCode" );
198
[224]199 std::string code;
200 ar & BOOST_SERIALIZATION_NVP( code );
201 ar & BOOST_SERIALIZATION_NVP( size );
202 ar & BOOST_SERIALIZATION_NVP( schedules );
[263]203 ar & BOOST_SERIALIZATION_NVP( sourceLines );
[224]204
205 // 読み込み後の処理
206 Realloc( size );
207 for( int i=0; i<size; i++ )
208 {
[256]209 ULONG_PTR l;
210 sscanf( code.c_str() + i*3, "%02x,", &l );
211 codeBuffer[i] = (char)l;
[224]212 }
213 }
214 template<class Archive> void save(Archive& ar, const unsigned int version) const
215 {
[256]216 trace_for_serialize( "serializing(save) - NativeCode" );
217
[224]218 // 保存準備
[256]219 char *tempCode = (char *)calloc( (size+1) * 3, 1 );
[224]220 for( int i=0; i<size; i++ )
221 {
222 char temp[32];
[256]223 sprintf( temp, "%02x,", (unsigned char)codeBuffer[i] );
[224]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 );
[263]235 ar & BOOST_SERIALIZATION_NVP( sourceLines );
[224]236 }
237
238
[256]239 void Realloc( int newSize )
[224]240 {
[256]241 if( allocateSize < newSize + 8192 )
[224]242 {
[256]243 while( allocateSize < newSize + 8192 )
[224]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]258 NativeCode( const NativeCode &nativeCode, bool isOpBuffer )
[256]259 : allocateSize( 8192 )
260 , codeBuffer( (char *)malloc( allocateSize ) )
261 , size( 0 )
262 {
[258]263 Put( nativeCode, isOpBuffer );
[256]264 }
[263]265 NativeCode( const char *codeBuffer, int size, bool isOpBuffer )
[252]266 : allocateSize( 8192 )
267 , codeBuffer( (char *)malloc( allocateSize ) )
268 , size( 0 )
269 {
[263]270 Put( codeBuffer, size, isOpBuffer );
[252]271 }
[224]272 ~NativeCode()
273 {
274 free( codeBuffer );
275 }
276 void Clear()
277 {
278 size = 0;
279 }
280
[256]281 void operator =( const NativeCode &nativeCode )
282 {
283 Clear();
[258]284 Put( nativeCode, false );
[256]285 }
286
[263]287 const char *GetCodeBuffer() const
288 {
289 return codeBuffer;
290 }
[237]291 int GetSize() const
292 {
293 return size;
294 }
[257]295 const Schedules &GetSchedules() const
296 {
297 return schedules;
298 }
[237]299
[253]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
[237]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 }
[241]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 }
[237]330
[258]331 void Put( const char *codeBuffer, int size, bool isOpBuffer = true )
[224]332 {
[256]333 Realloc( this->size + size );
[224]334
335 memcpy( this->codeBuffer + this->size, codeBuffer, size );
336 this->size += size;
[225]337
338 // 未完成
[258]339 if( isOpBuffer )
340 {
341 extern char *OpBuffer;
342 extern int obp;
343 memcpy( OpBuffer + obp, codeBuffer, size );
344 ObpPlus( size );
345 }
[224]346 }
[258]347 void Put( const NativeCode &nativeCode, bool isOpBuffer );
[226]348 void Put( _int64 i64data )
[224]349 {
[226]350 Put( (const char *)(&i64data), sizeof(_int64) );
[224]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);
[225]361
362
363
364 // 未完成
[228]365 switch( scheduleType )
366 {
367 case Schedule::None:
[244]368 // 何もしない
[228]369 break;
370 case Schedule::GlobalVar:
371 extern CSchedule *pobj_GlobalVarSchedule;
372 pobj_GlobalVarSchedule->add();
373 break;
[237]374 case Schedule::DataTable:
375 extern CSchedule *pobj_DataTableSchedule;
376 pobj_DataTableSchedule->add();
377 break;
[228]378 case Schedule::Relocation:
[244]379 // 未完成
[228]380 break;
381 default:
382 Jenga::Throw( "scheduleTypeが無効な値を保持している" );
383 break;
384 }
[225]385 extern char *OpBuffer;
386 extern int obp;
387 *((long *)(OpBuffer+obp))=l;
[232]388 ObpPlus( sizeof(long) );
[224]389 }
[245]390 void PutUserProcSchedule( const UserProc *pUserProc, bool isCall );
[250]391 void PutDllProcSchedule( const DllProc *pDllProc );
[226]392 void Put( short s )
393 {
394 Put( (const char *)(&s), sizeof(short) );
395 }
396 void Put( char c )
397 {
[256]398 Realloc( size + 1 );
[226]399 codeBuffer[size++] = c;
400
401
402
403 // 未完成
404 extern char *OpBuffer;
405 extern int obp;
[232]406 OpBuffer[obp]=c;
407 ObpPlus();
[226]408 }
[263]409
[265]410 const SourceLines &GetSourceLines() const
411 {
412 return sourceLines;
413 }
[263]414 void NextSourceLine();
[224]415};
Note: See TracBrowser for help on using the repository browser.