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

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

Linkerの骨格を作成した

File size: 6.7 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
114class NativeCode
115{
116 int allocateSize;
117 char *codeBuffer;
118 int size;
119
120 Schedules schedules;
121
122 // XMLシリアライズ用
123private:
124 friend class boost::serialization::access;
125 BOOST_SERIALIZATION_SPLIT_MEMBER();
126 template<class Archive> void load(Archive& ar, const unsigned int version)
127 {
128 trace_for_serialize( "serializing(load) - NativeCode" );
129
130 std::string code;
131 ar & BOOST_SERIALIZATION_NVP( code );
132 ar & BOOST_SERIALIZATION_NVP( size );
133 ar & BOOST_SERIALIZATION_NVP( schedules );
134
135 // 読み込み後の処理
136 Realloc( size );
137 for( int i=0; i<size; i++ )
138 {
139 ULONG_PTR l;
140 sscanf( code.c_str() + i*3, "%02x,", &l );
141 codeBuffer[i] = (char)l;
142 }
143 }
144 template<class Archive> void save(Archive& ar, const unsigned int version) const
145 {
146 trace_for_serialize( "serializing(save) - NativeCode" );
147
148 // 保存準備
149 char *tempCode = (char *)calloc( (size+1) * 3, 1 );
150 for( int i=0; i<size; i++ )
151 {
152 char temp[32];
153 sprintf( temp, "%02x,", (unsigned char)codeBuffer[i] );
154 tempCode[i*3] = temp[0];
155 tempCode[i*3+1] = temp[1];
156 tempCode[i*3+2] = temp[2];
157 }
158
159 std::string code = tempCode;
160 free( tempCode );
161
162 ar & BOOST_SERIALIZATION_NVP( code );
163 ar & BOOST_SERIALIZATION_NVP( size );
164 ar & BOOST_SERIALIZATION_NVP( schedules );
165 }
166
167
168 void Realloc( int newSize )
169 {
170 if( allocateSize < newSize + 8192 )
171 {
172 while( allocateSize < newSize + 8192 )
173 {
174 allocateSize += 8192;
175 }
176 codeBuffer = (char *)realloc( codeBuffer, allocateSize );
177 }
178 }
179
180public:
181 NativeCode()
182 : allocateSize( 8192 )
183 , codeBuffer( (char *)malloc( allocateSize ) )
184 , size( 0 )
185 {
186 }
187 NativeCode( const NativeCode &nativeCode, bool isOpBuffer )
188 : allocateSize( 8192 )
189 , codeBuffer( (char *)malloc( allocateSize ) )
190 , size( 0 )
191 {
192 Put( nativeCode, isOpBuffer );
193 }
194 NativeCode( const char *codeBuffer, int size )
195 : allocateSize( 8192 )
196 , codeBuffer( (char *)malloc( allocateSize ) )
197 , size( 0 )
198 {
199 Put( codeBuffer, size );
200 }
201 ~NativeCode()
202 {
203 free( codeBuffer );
204 }
205 void Clear()
206 {
207 size = 0;
208 }
209
210 void operator =( const NativeCode &nativeCode )
211 {
212 Clear();
213 Put( nativeCode, false );
214 }
215
216 int GetSize() const
217 {
218 return size;
219 }
220 const Schedules &GetSchedules() const
221 {
222 return schedules;
223 }
224
225 long GetLong( int codePos ) const
226 {
227 return *(long *)(this->codeBuffer+codePos);
228 }
229 long _GetLong_ObpOld( int _obpOld ) const
230 {
231 extern char *OpBuffer;
232 return *(long *)(OpBuffer+_obpOld);
233 }
234
235 void Overwrite( int codePos, char c )
236 {
237 codeBuffer[codePos] = c;
238 }
239 void OverwriteOld( int _obpOld, char c )
240 {
241 // 未完成
242 extern char *OpBuffer;
243 OpBuffer[_obpOld] = c;
244 }
245 void Overwrite( int codePos, long newLongValue )
246 {
247 *(long *)(this->codeBuffer+codePos) = newLongValue;
248 }
249 void OverwriteOld( int _obpOld, long newLongValue )
250 {
251 // 未完成
252 extern char *OpBuffer;
253 *(long *)(OpBuffer+_obpOld) = newLongValue;
254 }
255
256 void Put( const char *codeBuffer, int size, bool isOpBuffer = true )
257 {
258 Realloc( this->size + size );
259
260 memcpy( this->codeBuffer + this->size, codeBuffer, size );
261 this->size += size;
262
263 // 未完成
264 if( isOpBuffer )
265 {
266 extern char *OpBuffer;
267 extern int obp;
268 memcpy( OpBuffer + obp, codeBuffer, size );
269 ObpPlus( size );
270 }
271 }
272 void Put( const NativeCode &nativeCode, bool isOpBuffer );
273 void Put( _int64 i64data )
274 {
275 Put( (const char *)(&i64data), sizeof(_int64) );
276 }
277 void Put( long l, Schedule::Type scheduleType = Schedule::None )
278 {
279 if( scheduleType != Schedule::None )
280 {
281 schedules.push_back( Schedule( scheduleType, size ) );
282 }
283
284 *((long *)(codeBuffer+size))=l;
285 size += sizeof(long);
286
287
288
289 // 未完成
290 switch( scheduleType )
291 {
292 case Schedule::None:
293 // 何もしない
294 break;
295 case Schedule::GlobalVar:
296 extern CSchedule *pobj_GlobalVarSchedule;
297 pobj_GlobalVarSchedule->add();
298 break;
299 case Schedule::DataTable:
300 extern CSchedule *pobj_DataTableSchedule;
301 pobj_DataTableSchedule->add();
302 break;
303 case Schedule::Relocation:
304 // 未完成
305 break;
306 default:
307 Jenga::Throw( "scheduleTypeが無効な値を保持している" );
308 break;
309 }
310 extern char *OpBuffer;
311 extern int obp;
312 *((long *)(OpBuffer+obp))=l;
313 ObpPlus( sizeof(long) );
314 }
315 void PutUserProcSchedule( const UserProc *pUserProc, bool isCall );
316 void PutDllProcSchedule( const DllProc *pDllProc );
317 void Put( short s )
318 {
319 Put( (const char *)(&s), sizeof(short) );
320 }
321 void Put( char c )
322 {
323 Realloc( size + 1 );
324 codeBuffer[size++] = c;
325
326
327
328 // 未完成
329 extern char *OpBuffer;
330 extern int obp;
331 OpBuffer[obp]=c;
332 ObpPlus();
333 }
334};
Note: See TracBrowser for help on using the repository browser.