#include "InstrReelFixed.hpp" #include #include namespace spider { // Constructors & Destructors // InstrReelFixed::InstrReelFixed(u64 length) : _mem(nullptr), _size(length) { if (_size > 0) { _mem = new u8[_size]; std::memset(_mem, 0, _size); } } InstrReelFixed::InstrReelFixed(const u8* data, u64 length) : _mem(nullptr), _size(length) { if (_size > 0) { _mem = new u8[_size]; std::copy(data, data + _size, _mem); } } InstrReelFixed::InstrReelFixed(const InstrReelFixed& other) { _size = other._size; _mem = new u8[_size]; std::copy(other._mem, other._mem + _size, _mem); } InstrReelFixed::InstrReelFixed(InstrReelFixed&& other) noexcept { _mem = other._mem; _size = other._size; other._mem = nullptr; other._size = 0; } InstrReelFixed::~InstrReelFixed() { delete[] _mem; } // General Case(s) // // Instruction abstraction // u8 InstrReelFixed::readU8(u64 ip) { u8 dat; spider::loadPartialLE(&dat, _mem + ip, _size); return dat; } u16 InstrReelFixed::readU16(u64 ip) { u16 dat; spider::loadPartialLE(&dat, _mem + ip, _size); return dat; } u32 InstrReelFixed::readU32(u64 ip) { u32 dat; spider::loadPartialLE(&dat, _mem + ip, _size); return dat; } u64 InstrReelFixed::readU64(u64 ip) { u64 dat; spider::loadPartialLE(&dat, _mem + ip, _size); return dat; } void InstrReelFixed::readRange(u64 ip, u8* out, u64 length) { spider::loadPartialBytes(_mem, isize(ip), _size, out, length); } void InstrReelFixed::loadRegister(u64 ip, u8 size_code, register_t* r) { ip = std::min(ip, _size); spider::loadRegister[size_code](r, _mem + ip, _size - ip); } u64 InstrReelFixed::size() { return _size; } // Assign Operators // InstrReelFixed& InstrReelFixed::operator=(const InstrReelFixed& other) { if (this == &other) return *this; // lock self u8* new_mem = new u8[other._size]; std::copy(other._mem, other._mem + other._size, new_mem); delete[] _mem; _mem = new_mem; _size = other._size; return *this; } InstrReelFixed& InstrReelFixed::operator=(InstrReelFixed&& other) noexcept { if (this == &other) return *this; // lock self delete[] _mem; _mem = other._mem; // steal _size = other._size; other._mem = nullptr; // leave as husk other._size = 0; return *this; } // Misc // void InstrReelFixed::writeU8(u64 ip, u8 dat) { if(ip + 1 > _size) return; _mem[ip] = dat; } void InstrReelFixed::writeU16(u64 ip, u16 dat) { if(ip + 2 > _size) return; spider::storeLE(dat, _mem + ip); } void InstrReelFixed::writeU32(u64 ip, u32 dat) { if(ip + 4 > _size) return; spider::storeLE(dat, _mem + ip); } void InstrReelFixed::writeU64(u64 ip, u64 dat) { if(ip + 8 > _size) return; spider::storeLE(dat, _mem + ip); } void InstrReelFixed::resize(u64 new_size) { // Special case 1 if (new_size == _size) return; // Special case 2 if (new_size == 0) { delete[] _mem; _mem = nullptr; _size = 0; return; } // 1. Allocate the new block u8* new_mem = new u8[new_size]; // 2. Zero-initialize std::memset(new_mem, 0, new_size); // 3. Preserve data // If shrinking, copy 'new_size' bytes. If growing, copy 'old_size' bytes. u64 bytes_to_copy = (new_size < _size) ? new_size : _size; // 3.1 Previous size could be zero, where _mem would be null if (_mem != nullptr) { std::copy(_mem, _mem + bytes_to_copy, new_mem); } // 4. Swap and Clean up delete[] _mem; _mem = new_mem; _size = new_size; } }