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

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

Selectステートメントのスケジュール機構をリファクタリング

File size: 5.3 KB
Line 
1#pragma once
2
3#include <vector>
4
5#include <jenga/include/common/Exception.h>
6
7#include <BoostSerializationSupport.h>
8
9void AddLocalVarAddrSchedule();
10void ObpPlus( int step = 1 );
11
12class UserProc;
13
14class Schedule
15{
16public:
17 enum Type
18 {
19 None = 10000,
20 GlobalVar, // グローバル変数スケジュール
21 LocalVar, // ローカル変数スケジュール
22 DataTable, // データテーブル スケジュール
23 Relocation, // リロケーション情報スケジュール
24 UserProc, // ユーザ定義関数呼び出し側スケジュール
25 AddressOf, // ユーザ定義関数位置スケジュール
26 };
27
28private:
29 Type type;
30 long offset;
31
32 union{
33 LONG_PTR lpValue;
34 const ::UserProc *pUserProc;
35 const ::DllProc *pDllProc;
36 };
37
38 // XMLシリアライズ用
39private:
40 friend class boost::serialization::access;
41 template<class Archive> void serialize(Archive& ar, const unsigned int version)
42 {
43 ar & BOOST_SERIALIZATION_NVP( type );
44 ar & BOOST_SERIALIZATION_NVP( offset );
45 }
46
47public:
48 Schedule()
49 {
50 }
51 Schedule( Type type, long offset )
52 : type( type )
53 , offset( offset )
54 , lpValue( 0 )
55 {
56 }
57 Schedule( const ::UserProc *pUserProc, long offest )
58 : type( Schedule::UserProc )
59 , offset( offset )
60 , pUserProc( pUserProc )
61 {
62 }
63 Schedule( const ::DllProc *pDllProc, long offest )
64 : type( Schedule::UserProc )
65 , offset( offset )
66 , pDllProc( pDllProc )
67 {
68 }
69 ~Schedule()
70 {
71 }
72
73 void SpecifyAddressOf()
74 {
75 if( type != Schedule::UserProc )
76 {
77 SetError();
78 }
79 type = Schedule::AddressOf;
80 }
81};
82typedef std::vector<Schedule> Schedules;
83
84class NativeCode
85{
86 int allocateSize;
87 char *codeBuffer;
88 int size;
89
90 Schedules schedules;
91
92 // XMLシリアライズ用
93private:
94 friend class boost::serialization::access;
95 BOOST_SERIALIZATION_SPLIT_MEMBER();
96 template<class Archive> void load(Archive& ar, const unsigned int version)
97 {
98 std::string code;
99 ar & BOOST_SERIALIZATION_NVP( code );
100 ar & BOOST_SERIALIZATION_NVP( size );
101 ar & BOOST_SERIALIZATION_NVP( schedules );
102
103 // 読み込み後の処理
104 Realloc( size );
105 for( int i=0; i<size; i++ )
106 {
107 char c;
108 sscanf( code.c_str() + i*3, "%02x,", &c );
109 codeBuffer[i] = c;
110 }
111 }
112 template<class Archive> void save(Archive& ar, const unsigned int version) const
113 {
114 // 保存準備
115 char *tempCode = (char *)malloc( (size+1) * 3 );
116 for( int i=0; i<size; i++ )
117 {
118 char temp[32];
119 sprintf( temp, "%02x,", codeBuffer[i] );
120 tempCode[i*3] = temp[0];
121 tempCode[i*3+1] = temp[1];
122 tempCode[i*3+2] = temp[2];
123 }
124
125 std::string code = tempCode;
126 free( tempCode );
127
128 ar & BOOST_SERIALIZATION_NVP( code );
129 ar & BOOST_SERIALIZATION_NVP( size );
130 ar & BOOST_SERIALIZATION_NVP( schedules );
131 }
132
133
134 void Realloc( int additionSize = 0 )
135 {
136 if( allocateSize < size + 8192 + additionSize )
137 {
138 while( allocateSize < size + 8192 + additionSize )
139 {
140 allocateSize += 8192;
141 }
142 codeBuffer = (char *)realloc( codeBuffer, allocateSize );
143 }
144 }
145
146public:
147 NativeCode()
148 : allocateSize( 8192 )
149 , codeBuffer( (char *)malloc( allocateSize ) )
150 , size( 0 )
151 {
152 }
153 ~NativeCode()
154 {
155 free( codeBuffer );
156 }
157 void Clear()
158 {
159 size = 0;
160 }
161
162 int GetSize() const
163 {
164 return size;
165 }
166
167 void Overwrite( int codePos, char c )
168 {
169 codeBuffer[codePos] = c;
170 }
171 void OverwriteOld( int _obpOld, char c )
172 {
173 // 未完成
174 extern char *OpBuffer;
175 OpBuffer[_obpOld] = c;
176 }
177 void Overwrite( int codePos, long newLongValue )
178 {
179 *(long *)(this->codeBuffer+codePos) = newLongValue;
180 }
181 void OverwriteOld( int _obpOld, long newLongValue )
182 {
183 // 未完成
184 extern char *OpBuffer;
185 *(long *)(OpBuffer+_obpOld) = newLongValue;
186 }
187
188 void Put( const char *codeBuffer, int size )
189 {
190 Realloc( size );
191
192 memcpy( this->codeBuffer + this->size, codeBuffer, size );
193 this->size += size;
194
195 // 未完成
196 extern char *OpBuffer;
197 extern int obp;
198 memcpy( OpBuffer + obp, codeBuffer, size );
199 ObpPlus( size );
200 }
201 void Put( const NativeCode &nativeCode )
202 {
203 Put( nativeCode.codeBuffer, nativeCode.size );
204 }
205 void Put( _int64 i64data )
206 {
207 Put( (const char *)(&i64data), sizeof(_int64) );
208 }
209 void Put( long l, Schedule::Type scheduleType = Schedule::None )
210 {
211 if( scheduleType != Schedule::None )
212 {
213 schedules.push_back( Schedule( scheduleType, size ) );
214 }
215
216 *((long *)(codeBuffer+size))=l;
217 size += sizeof(long);
218
219
220
221 // 未完成
222 switch( scheduleType )
223 {
224 case Schedule::None:
225 // 何もしない
226 break;
227 case Schedule::GlobalVar:
228 extern CSchedule *pobj_GlobalVarSchedule;
229 pobj_GlobalVarSchedule->add();
230 break;
231 case Schedule::LocalVar:
232 AddLocalVarAddrSchedule();
233 break;
234 case Schedule::DataTable:
235 extern CSchedule *pobj_DataTableSchedule;
236 pobj_DataTableSchedule->add();
237 break;
238 case Schedule::Relocation:
239 // 未完成
240 break;
241 default:
242 Jenga::Throw( "scheduleTypeが無効な値を保持している" );
243 break;
244 }
245 extern char *OpBuffer;
246 extern int obp;
247 *((long *)(OpBuffer+obp))=l;
248 ObpPlus( sizeof(long) );
249 }
250 void PutUserProcSchedule( const UserProc *pUserProc, bool isCall );
251 void PutDllProcSchedule( const DllProc *pDllProc );
252 void Put( short s )
253 {
254 Put( (const char *)(&s), sizeof(short) );
255 }
256 void Put( char c )
257 {
258 codeBuffer[size++] = c;
259 Realloc();
260
261
262
263 // 未完成
264 extern char *OpBuffer;
265 extern int obp;
266 OpBuffer[obp]=c;
267 ObpPlus();
268 }
269};
Note: See TracBrowser for help on using the repository browser.