| 1 | #pragma once | 
|---|
| 2 |  | 
|---|
| 3 | #include <vector> | 
|---|
| 4 |  | 
|---|
| 5 | #include <jenga/include/common/Exception.h> | 
|---|
| 6 |  | 
|---|
| 7 | #include <BoostSerializationSupport.h> | 
|---|
| 8 |  | 
|---|
| 9 | void AddLocalVarAddrSchedule(); | 
|---|
| 10 | void ObpPlus( int step = 1 ); | 
|---|
| 11 |  | 
|---|
| 12 | class UserProc; | 
|---|
| 13 |  | 
|---|
| 14 | class Schedule | 
|---|
| 15 | { | 
|---|
| 16 | public: | 
|---|
| 17 | enum Type | 
|---|
| 18 | { | 
|---|
| 19 | None = 10000, | 
|---|
| 20 | GlobalVar,      // グローバル変数スケジュール | 
|---|
| 21 | LocalVar,       // ローカル変数スケジュール | 
|---|
| 22 | DataTable,      // データテーブル スケジュール | 
|---|
| 23 | Relocation,     // リロケーション情報スケジュール | 
|---|
| 24 | UserProc,       // ユーザ定義関数呼び出し側スケジュール | 
|---|
| 25 | AddressOf,      // ユーザ定義関数位置スケジュール | 
|---|
| 26 | }; | 
|---|
| 27 |  | 
|---|
| 28 | private: | 
|---|
| 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シリアライズ用 | 
|---|
| 39 | private: | 
|---|
| 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 |  | 
|---|
| 47 | public: | 
|---|
| 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 | }; | 
|---|
| 82 | typedef std::vector<Schedule> Schedules; | 
|---|
| 83 |  | 
|---|
| 84 | class NativeCode | 
|---|
| 85 | { | 
|---|
| 86 | int allocateSize; | 
|---|
| 87 | char *codeBuffer; | 
|---|
| 88 | int size; | 
|---|
| 89 |  | 
|---|
| 90 | Schedules schedules; | 
|---|
| 91 |  | 
|---|
| 92 | // XMLシリアライズ用 | 
|---|
| 93 | private: | 
|---|
| 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 |  | 
|---|
| 146 | public: | 
|---|
| 147 | NativeCode() | 
|---|
| 148 | : allocateSize( 8192 ) | 
|---|
| 149 | , codeBuffer( (char *)malloc( allocateSize ) ) | 
|---|
| 150 | , size( 0 ) | 
|---|
| 151 | { | 
|---|
| 152 | } | 
|---|
| 153 | NativeCode( const char *codeBuffer, int size ) | 
|---|
| 154 | : allocateSize( 8192 ) | 
|---|
| 155 | , codeBuffer( (char *)malloc( allocateSize ) ) | 
|---|
| 156 | , size( 0 ) | 
|---|
| 157 | { | 
|---|
| 158 | Put( codeBuffer, size ); | 
|---|
| 159 | } | 
|---|
| 160 | ~NativeCode() | 
|---|
| 161 | { | 
|---|
| 162 | free( codeBuffer ); | 
|---|
| 163 | } | 
|---|
| 164 | void Clear() | 
|---|
| 165 | { | 
|---|
| 166 | size = 0; | 
|---|
| 167 | } | 
|---|
| 168 |  | 
|---|
| 169 | int GetSize() const | 
|---|
| 170 | { | 
|---|
| 171 | return size; | 
|---|
| 172 | } | 
|---|
| 173 |  | 
|---|
| 174 | void Overwrite( int codePos, char c ) | 
|---|
| 175 | { | 
|---|
| 176 | codeBuffer[codePos] = c; | 
|---|
| 177 | } | 
|---|
| 178 | void OverwriteOld( int _obpOld, char c ) | 
|---|
| 179 | { | 
|---|
| 180 | // 未完成 | 
|---|
| 181 | extern char *OpBuffer; | 
|---|
| 182 | OpBuffer[_obpOld] = c; | 
|---|
| 183 | } | 
|---|
| 184 | void Overwrite( int codePos, long newLongValue ) | 
|---|
| 185 | { | 
|---|
| 186 | *(long *)(this->codeBuffer+codePos) = newLongValue; | 
|---|
| 187 | } | 
|---|
| 188 | void OverwriteOld( int _obpOld, long newLongValue ) | 
|---|
| 189 | { | 
|---|
| 190 | // 未完成 | 
|---|
| 191 | extern char *OpBuffer; | 
|---|
| 192 | *(long *)(OpBuffer+_obpOld) = newLongValue; | 
|---|
| 193 | } | 
|---|
| 194 |  | 
|---|
| 195 | void Put( const char *codeBuffer, int size ) | 
|---|
| 196 | { | 
|---|
| 197 | Realloc( size ); | 
|---|
| 198 |  | 
|---|
| 199 | memcpy( this->codeBuffer + this->size, codeBuffer, size ); | 
|---|
| 200 | this->size += size; | 
|---|
| 201 |  | 
|---|
| 202 | // 未完成 | 
|---|
| 203 | extern char *OpBuffer; | 
|---|
| 204 | extern int obp; | 
|---|
| 205 | memcpy( OpBuffer + obp, codeBuffer, size ); | 
|---|
| 206 | ObpPlus( size ); | 
|---|
| 207 | } | 
|---|
| 208 | void Put( const NativeCode &nativeCode ) | 
|---|
| 209 | { | 
|---|
| 210 | Put( nativeCode.codeBuffer, nativeCode.size ); | 
|---|
| 211 | } | 
|---|
| 212 | void Put( _int64 i64data ) | 
|---|
| 213 | { | 
|---|
| 214 | Put( (const char *)(&i64data), sizeof(_int64) ); | 
|---|
| 215 | } | 
|---|
| 216 | void Put( long l, Schedule::Type scheduleType = Schedule::None ) | 
|---|
| 217 | { | 
|---|
| 218 | if( scheduleType != Schedule::None ) | 
|---|
| 219 | { | 
|---|
| 220 | schedules.push_back( Schedule( scheduleType, size ) ); | 
|---|
| 221 | } | 
|---|
| 222 |  | 
|---|
| 223 | *((long *)(codeBuffer+size))=l; | 
|---|
| 224 | size += sizeof(long); | 
|---|
| 225 |  | 
|---|
| 226 |  | 
|---|
| 227 |  | 
|---|
| 228 | // 未完成 | 
|---|
| 229 | switch( scheduleType ) | 
|---|
| 230 | { | 
|---|
| 231 | case Schedule::None: | 
|---|
| 232 | // 何もしない | 
|---|
| 233 | break; | 
|---|
| 234 | case Schedule::GlobalVar: | 
|---|
| 235 | extern CSchedule *pobj_GlobalVarSchedule; | 
|---|
| 236 | pobj_GlobalVarSchedule->add(); | 
|---|
| 237 | break; | 
|---|
| 238 | case Schedule::LocalVar: | 
|---|
| 239 | AddLocalVarAddrSchedule(); | 
|---|
| 240 | break; | 
|---|
| 241 | case Schedule::DataTable: | 
|---|
| 242 | extern CSchedule *pobj_DataTableSchedule; | 
|---|
| 243 | pobj_DataTableSchedule->add(); | 
|---|
| 244 | break; | 
|---|
| 245 | case Schedule::Relocation: | 
|---|
| 246 | // 未完成 | 
|---|
| 247 | break; | 
|---|
| 248 | default: | 
|---|
| 249 | Jenga::Throw( "scheduleTypeが無効な値を保持している" ); | 
|---|
| 250 | break; | 
|---|
| 251 | } | 
|---|
| 252 | extern char *OpBuffer; | 
|---|
| 253 | extern int obp; | 
|---|
| 254 | *((long *)(OpBuffer+obp))=l; | 
|---|
| 255 | ObpPlus( sizeof(long) ); | 
|---|
| 256 | } | 
|---|
| 257 | void PutUserProcSchedule( const UserProc *pUserProc, bool isCall ); | 
|---|
| 258 | void PutDllProcSchedule( const DllProc *pDllProc ); | 
|---|
| 259 | void Put( short s ) | 
|---|
| 260 | { | 
|---|
| 261 | Put( (const char *)(&s), sizeof(short) ); | 
|---|
| 262 | } | 
|---|
| 263 | void Put( char c ) | 
|---|
| 264 | { | 
|---|
| 265 | codeBuffer[size++] = c; | 
|---|
| 266 | Realloc(); | 
|---|
| 267 |  | 
|---|
| 268 |  | 
|---|
| 269 |  | 
|---|
| 270 | // 未完成 | 
|---|
| 271 | extern char *OpBuffer; | 
|---|
| 272 | extern int obp; | 
|---|
| 273 | OpBuffer[obp]=c; | 
|---|
| 274 | ObpPlus(); | 
|---|
| 275 | } | 
|---|
| 276 | }; | 
|---|