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