overengineered piece of shit, but compiles fine
This commit is contained in:
@@ -26,7 +26,7 @@ namespace spider {
|
||||
* Reindexing may occur, continous access
|
||||
* may incurr in less penalties.
|
||||
*/
|
||||
virtual u8 readU8(u64 ip) = 0;
|
||||
virtual u8 readU8(u64 ip) const = 0;
|
||||
|
||||
/**
|
||||
* Obtains a byte of data at
|
||||
@@ -34,7 +34,7 @@ namespace spider {
|
||||
* Reindexing may occur, continous access
|
||||
* may incurr in less penalties.
|
||||
*/
|
||||
virtual u16 readU16(u64 ip) = 0;
|
||||
virtual u16 readU16(u64 ip) const = 0;
|
||||
|
||||
/**
|
||||
* Obtains a byte of data at
|
||||
@@ -42,7 +42,7 @@ namespace spider {
|
||||
* Reindexing may occur, continous access
|
||||
* may incurr in less penalties.
|
||||
*/
|
||||
virtual u32 readU32(u64 ip) = 0;
|
||||
virtual u32 readU32(u64 ip) const = 0;
|
||||
|
||||
/**
|
||||
* Obtains a byte of data at
|
||||
@@ -50,20 +50,20 @@ namespace spider {
|
||||
* Reindexing may occur, continous access
|
||||
* may incurr in less penalties.
|
||||
*/
|
||||
virtual u64 readU64(u64 ip) = 0;
|
||||
virtual u64 readU64(u64 ip) const = 0;
|
||||
|
||||
/**
|
||||
* Reads a range of data, and
|
||||
* outputs it.
|
||||
*/
|
||||
virtual void readRange(u64 ip, u8* out, u64 length) = 0;
|
||||
virtual void readRange(u64 ip, u8* out, u64 length) const = 0;
|
||||
|
||||
virtual void loadRegister(u64 ip, u8 size_code, register_t* r) = 0;
|
||||
virtual void loadRegister(u64 ip, u8 size_code, register_t* r) const = 0;
|
||||
|
||||
/**
|
||||
* Current size of the instructions.
|
||||
*/
|
||||
virtual u64 size() = 0;
|
||||
virtual u64 size() const = 0;
|
||||
|
||||
public: // Static Utils //
|
||||
|
||||
|
||||
@@ -5,181 +5,69 @@
|
||||
namespace spider {
|
||||
|
||||
InstrReelDyn::InstrReelDyn(u64 length) : _size(length) {
|
||||
// Safe int ceil division
|
||||
growTo((length >> 8) + ((length & 255) != 0));
|
||||
if (_size == 0) return;
|
||||
|
||||
// 1. Allocate and fill the buffer with zeroed blocks
|
||||
grow(_size);
|
||||
_buffer.assign(_size, 0);
|
||||
|
||||
// 2. Pad the physical vector to match block alignment
|
||||
if (_buffer.size() % _blocksize != 0) {
|
||||
u64 padding = _blocksize - (_buffer.size() % _blocksize);
|
||||
_buffer.insert(_buffer.end(), padding, 0);
|
||||
}
|
||||
|
||||
// 3. Manifest the initial blank part in our orchestration
|
||||
_pieces.push_back({ 0, _size });
|
||||
}
|
||||
|
||||
//InstrReelDyn::InstrReelDyn(const u8* data, u64 length) {}
|
||||
InstrReelDyn::InstrReelDyn(const u8* data, u64 length) : _size(0) {
|
||||
if (length == 0) return;
|
||||
grow(length);
|
||||
write(0, data, length);
|
||||
}
|
||||
|
||||
InstrReelDyn::InstrReelDyn(const InstrReelDyn& copy)
|
||||
: _blocks(copy._blocks), _size(copy._size) {
|
||||
}
|
||||
: _buffer(copy._buffer),
|
||||
_pieces(copy._pieces),
|
||||
_size(copy._size) {}
|
||||
|
||||
// No-throw Move Constructor
|
||||
InstrReelDyn::InstrReelDyn(InstrReelDyn&& move) noexcept
|
||||
: _blocks(std::move(move._blocks)), _size(std::move(move._size)) {
|
||||
: _buffer(std::move(move._buffer)),
|
||||
_pieces(std::move(move._pieces)),
|
||||
_size(move._size) {
|
||||
move._size = 0;
|
||||
}
|
||||
|
||||
// Explicit Destructor execution
|
||||
InstrReelDyn::~InstrReelDyn() {
|
||||
// .. //
|
||||
_pieces.clear();
|
||||
_buffer.clear();
|
||||
}
|
||||
|
||||
// Deep Copy Assignment Operator
|
||||
InstrReelDyn& InstrReelDyn::operator=(const InstrReelDyn& copy) {
|
||||
_blocks = copy._blocks;
|
||||
_size = copy._size;
|
||||
if (this != ©) {
|
||||
_buffer = copy._buffer;
|
||||
_pieces = copy._pieces;
|
||||
_size = copy._size;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// No-throw Move Assignment Operator
|
||||
InstrReelDyn& InstrReelDyn::operator=(InstrReelDyn&& move) noexcept {
|
||||
_blocks = std::move(move._blocks);
|
||||
_size = std::move(move._size);
|
||||
if (this != &move) {
|
||||
_buffer = std::move(move._buffer);
|
||||
_pieces = std::move(move._pieces);
|
||||
_size = move._size;
|
||||
move._size = 0;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
void InstrReelDyn::growTo(u64 ip) {
|
||||
u64 b_index = (ip >> 8) + 1;
|
||||
while (_blocks.size() < b_index) {
|
||||
_blocks.emplace_back();
|
||||
}
|
||||
if (ip >= _size) _size = ip + 1;
|
||||
}
|
||||
|
||||
std::pair<u64, u8> InstrReelDyn::indexOf(u64 ip) {
|
||||
return { ip >> 8, ip & 0xFF }; // { ip / 256, ip % 256 };
|
||||
}
|
||||
|
||||
bool InstrReelDyn::continous(u64 ip0, u64 ip1, u64* b_index, u16* s_index) {
|
||||
auto i = indexOf(ip0);
|
||||
*b_index = i.first;
|
||||
*s_index = i.second;
|
||||
return i.first == (ip1 >> 8);
|
||||
}
|
||||
|
||||
// Particular Cases
|
||||
|
||||
/**
|
||||
* Obtains a byte of data at
|
||||
* the specific location.
|
||||
* Reindexing may occur, continous access
|
||||
* may incurr in less penalties.
|
||||
*/
|
||||
u8 InstrReelDyn::readU8(u64 ip) {
|
||||
if (ip + 1 > _size) return 0;
|
||||
auto i = indexOf(ip);
|
||||
return _blocks[i.first].data[i.second];
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains a byte of data at
|
||||
* the specific location.
|
||||
* Reindexing may occur, continous access
|
||||
* may incurr in less penalties.
|
||||
*/
|
||||
u16 InstrReelDyn::readU16(u64 ip) {
|
||||
if (ip + 2 > _size) return 0;
|
||||
|
||||
u16 dat;
|
||||
u64 b_index;
|
||||
u16 s_index;
|
||||
|
||||
if (continous(ip, ip + 1, &b_index, &s_index)) {
|
||||
spider::loadLE(&dat, &_blocks[b_index].data[s_index]);
|
||||
return dat;
|
||||
}
|
||||
|
||||
dat = 0;
|
||||
for (isize i = 0; i < sizeof(dat); i++) {
|
||||
auto& b = _blocks[(b_index + s_index) >> 8];
|
||||
dat |= u16(b.data[s_index++ & 0xFF] << (i * 8));
|
||||
}
|
||||
return dat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains a byte of data at
|
||||
* the specific location.
|
||||
* Reindexing may occur, continous access
|
||||
* may incurr in less penalties.
|
||||
*/
|
||||
u32 InstrReelDyn::readU32(u64 ip) {
|
||||
if (ip + 4 > _size) return 0;
|
||||
|
||||
u32 dat;
|
||||
u64 b_index;
|
||||
u16 s_index;
|
||||
|
||||
if (continous(ip, ip + 3, &b_index, &s_index)) {
|
||||
spider::loadLE(&dat, &_blocks[b_index].data[s_index]);
|
||||
return dat;
|
||||
}
|
||||
|
||||
dat = 0;
|
||||
for (isize i = 0; i < sizeof(dat); i++) {
|
||||
auto& b = _blocks[(b_index + s_index) >> 8];
|
||||
dat |= u32(b.data[s_index++ & 0xFF]) << (i * 8);
|
||||
}
|
||||
return dat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains a byte of data at
|
||||
* the specific location.
|
||||
* Reindexing may occur, continous access
|
||||
* may incurr in less penalties.
|
||||
*/
|
||||
u64 InstrReelDyn::readU64(u64 ip) {
|
||||
if (ip + 8 > _size) return 0;
|
||||
|
||||
u64 dat;
|
||||
u64 b_index;
|
||||
u16 s_index;
|
||||
|
||||
if (continous(ip, ip + 7, &b_index, &s_index)) {
|
||||
spider::loadLE(&dat, &_blocks[b_index].data[s_index]);
|
||||
return dat;
|
||||
}
|
||||
|
||||
dat = 0;
|
||||
for (isize i = 0; i < sizeof(dat); i++) {
|
||||
auto& b = _blocks[(b_index + s_index) >> 8];
|
||||
dat |= u64(b.data[s_index++ & 0xFF]) << (i * 8);
|
||||
}
|
||||
return dat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a range of data, and
|
||||
* outputs it.
|
||||
*/
|
||||
void InstrReelDyn::readRange(u64 ip, u8* out, u64 length) {
|
||||
if (ip + length > _size) {
|
||||
std::memset(out, 0, length);
|
||||
return;
|
||||
}
|
||||
|
||||
u64 b_index;
|
||||
u16 s_index;
|
||||
|
||||
if (continous(ip, ip + length, &b_index, &s_index)) {
|
||||
std::memcpy(out, &_blocks[b_index].data[s_index], length);
|
||||
return;
|
||||
}
|
||||
|
||||
u64 bytes_read = 0;
|
||||
while (bytes_read < length) {
|
||||
u64 remaining_in_block = 256 - s_index;
|
||||
u64 chunk_size = std::min(remaining_in_block, length - bytes_read);
|
||||
|
||||
// Perform bulk copy for the current segment
|
||||
std::memcpy(out + bytes_read, &_blocks[b_index].data[s_index], chunk_size);
|
||||
|
||||
// Advance pointers
|
||||
bytes_read += chunk_size;
|
||||
b_index++;
|
||||
s_index = 0; // reset
|
||||
}
|
||||
}
|
||||
|
||||
void InstrReelDyn::loadRegister(u64 ip, u8 size_code, register_t* r) {
|
||||
void InstrReelDyn::loadRegister(u64 ip, u8 size_code, register_t* r) const {
|
||||
u8 bytes[8];
|
||||
readRange(ip, bytes, 1 << size_code);
|
||||
spider::loadRegister[size_code](r, bytes, 8);
|
||||
@@ -188,22 +76,235 @@ namespace spider {
|
||||
/**
|
||||
* Current size of the instructions.
|
||||
*/
|
||||
u64 InstrReelDyn::size() {
|
||||
u64 InstrReelDyn::size() const {
|
||||
return _size;
|
||||
}
|
||||
|
||||
// Reading, Prepared //
|
||||
|
||||
u8 InstrReelDyn::readU8(u64 ip) const {
|
||||
u8 dat;
|
||||
u8 arr[sizeof(dat)];
|
||||
readRange(ip, arr, sizeof(arr));
|
||||
spider::loadPartialLE(&dat, arr, sizeof(arr));
|
||||
return dat;
|
||||
}
|
||||
|
||||
u16 InstrReelDyn::readU16(u64 ip) const {
|
||||
u16 dat;
|
||||
u8 arr[sizeof(dat)];
|
||||
readRange(ip, arr, sizeof(arr));
|
||||
spider::loadPartialLE(&dat, arr, sizeof(arr));
|
||||
return dat;
|
||||
}
|
||||
|
||||
u32 InstrReelDyn::readU32(u64 ip) const {
|
||||
u32 dat;
|
||||
u8 arr[sizeof(dat)];
|
||||
readRange(ip, arr, sizeof(arr));
|
||||
spider::loadPartialLE(&dat, arr, sizeof(arr));
|
||||
return dat;
|
||||
}
|
||||
|
||||
u64 InstrReelDyn::readU64(u64 ip) const {
|
||||
u64 dat;
|
||||
u8 arr[sizeof(dat)];
|
||||
readRange(ip, arr, sizeof(arr));
|
||||
spider::loadPartialLE(&dat, arr, sizeof(arr));
|
||||
return dat;
|
||||
}
|
||||
|
||||
// Mutation //
|
||||
|
||||
// TODO!
|
||||
void InstrReelDyn::readRange(u64 ip, u8* dat, const u64 len) const {
|
||||
// 1. Boundary Guard
|
||||
if (len == 0 || ip + len > _size || dat == nullptr) return;
|
||||
|
||||
//void InstrReelDyn::writeU8(u64 ip, u8 dat) {}
|
||||
//void InstrReelDyn::writeU16(u64 ip, u16 dat) {}
|
||||
//void InstrReelDyn::writeU32(u64 ip, u32 dat) {}
|
||||
//void InstrReelDyn::writeU64(u64 ip, u64 dat) {}
|
||||
u64 bytes_copied = 0;
|
||||
u64 current_ip = 0;
|
||||
|
||||
/**
|
||||
* Appends instruction at the end.
|
||||
*/
|
||||
//void InstrReelDyn::append(u16 bc) {}
|
||||
for (const auto& p : _pieces) {
|
||||
u64 piece_start = current_ip;
|
||||
u64 piece_end = current_ip + p.length;
|
||||
|
||||
// 2. Determine if the requested read window overlaps with this piece
|
||||
if (ip + bytes_copied < piece_end && (ip + len) > piece_start) {
|
||||
|
||||
// Calculate where inside this specific piece our read window begins
|
||||
u64 read_start_logical = std::max(ip + bytes_copied, piece_start);
|
||||
u64 local_offset_within_piece = read_start_logical - piece_start;
|
||||
|
||||
// Calculate how many remaining bytes can be extracted from this piece
|
||||
u64 available_in_piece = p.length - local_offset_within_piece;
|
||||
u64 bytes_to_copy = std::min(len - bytes_copied, available_in_piece);
|
||||
|
||||
// 3. Perform safe unaligned copy from our master buffer to the user's destination
|
||||
const u8* src_ptr = _buffer.data() + p.offset + local_offset_within_piece;
|
||||
std::memcpy(dat + bytes_copied, src_ptr, bytes_to_copy);
|
||||
|
||||
bytes_copied += bytes_to_copy;
|
||||
|
||||
// 4. Optimization: Break early if we've completely satisfied the read request
|
||||
if (bytes_copied == len) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
current_ip += p.length;
|
||||
}
|
||||
}
|
||||
|
||||
void InstrReelDyn::write(u64 ip, const u8* dat, const u64 len) {
|
||||
if (len == 0) return;
|
||||
|
||||
// If writing inside existing data, we OVERWRITE by removing the old section first.
|
||||
// If ip >= _size, it naturally appends, so remove does nothing.
|
||||
if (ip < _size) {
|
||||
u64 bytes_to_overwrite = std::min(len, _size - ip);
|
||||
remove(ip, bytes_to_overwrite);
|
||||
}
|
||||
|
||||
// 1. Capture the exact physical offset BEFORE inserting data or padding
|
||||
grow(len);
|
||||
u64 write_offset = _buffer.size();
|
||||
_buffer.insert(_buffer.end(), dat, dat + len);
|
||||
|
||||
// Apply padding immediately so _buffer.size() is always clean for the next run
|
||||
if (_buffer.size() % _blocksize != 0) {
|
||||
u64 padding = _blocksize - (_buffer.size() % _blocksize);
|
||||
_buffer.insert(_buffer.end(), padding, 0);
|
||||
}
|
||||
|
||||
// 2. Orchestrate Pieces (This is strictly an Insertion now because Old Data was removed)
|
||||
if (_pieces.empty() || ip >= _size) {
|
||||
_pieces.push_back({ write_offset, len });
|
||||
_size += len;
|
||||
return;
|
||||
}
|
||||
|
||||
u64 current_ip = 0;
|
||||
for (auto it = _pieces.begin(); it != _pieces.end(); ++it) {
|
||||
if (current_ip + it->length >= ip) {
|
||||
u64 local_offset = ip - current_ip;
|
||||
|
||||
if (local_offset == 0) {
|
||||
_pieces.insert(it, { write_offset, len });
|
||||
} else {
|
||||
// Split the piece cleanly
|
||||
piece left = { it->offset, local_offset };
|
||||
piece right = { it->offset + local_offset, it->length - local_offset };
|
||||
|
||||
*it = left; // Update existing piece to be the 'left' side
|
||||
|
||||
auto next_it = std::next(it);
|
||||
next_it = _pieces.insert(next_it, { write_offset, len });
|
||||
_pieces.insert(std::next(next_it), right);
|
||||
}
|
||||
break; // Essential: stop processing once the piece is handled!
|
||||
}
|
||||
current_ip += it->length;
|
||||
}
|
||||
_size += len;
|
||||
}
|
||||
|
||||
void InstrReelDyn::remove(u64 ip, const u64 len) {
|
||||
if (len == 0 || ip + len > _size) return;
|
||||
|
||||
u64 current_ip = 0;
|
||||
u64 bytes_to_remove = len;
|
||||
|
||||
for (auto it = _pieces.begin(); it != _pieces.end() && bytes_to_remove > 0;) {
|
||||
u64 piece_start = current_ip;
|
||||
u64 piece_end = current_ip + it->length;
|
||||
|
||||
if (ip < piece_end && (ip + bytes_to_remove) > piece_start) {
|
||||
u64 overlap_start = std::max(ip, piece_start);
|
||||
u64 overlap_end = std::min(ip + bytes_to_remove, piece_end);
|
||||
u64 overlap_len = overlap_end - overlap_start;
|
||||
|
||||
u64 local_offset = overlap_start - piece_start;
|
||||
|
||||
if (local_offset == 0 && overlap_len == it->length) {
|
||||
it = _pieces.erase(it); // Returns next valid iterator safely
|
||||
} else if (local_offset == 0) {
|
||||
it->offset += overlap_len;
|
||||
it->length -= overlap_len;
|
||||
++it;
|
||||
} else if (local_offset + overlap_len == it->length) {
|
||||
it->length -= overlap_len;
|
||||
++it;
|
||||
} else {
|
||||
// Slice a hole out of the middle
|
||||
piece right = { it->offset + local_offset + overlap_len, it->length - (local_offset + overlap_len) };
|
||||
it->length = local_offset;
|
||||
_pieces.insert(std::next(it), right);
|
||||
break;
|
||||
}
|
||||
bytes_to_remove -= overlap_len;
|
||||
} else {
|
||||
current_ip += it->length;
|
||||
++it;
|
||||
}
|
||||
}
|
||||
_size -= len;
|
||||
}
|
||||
|
||||
void InstrReelDyn::defragment() {
|
||||
// 1. Edge Case: If the buffer is completely empty, reset states cleanly
|
||||
if (_size == 0) {
|
||||
_pieces.clear();
|
||||
_buffer.clear();
|
||||
_size = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. Optimization: If there is only 1 piece and it's already aligned at physical offset 0,
|
||||
// then the buffer is already perfectly defragmented. Skip the work entirely.
|
||||
if (_pieces.size() == 1 && _pieces.front().offset == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 3. Allocate a fresh, temporary vector aligned perfectly to your 256-byte blocks
|
||||
std::vector<u8> clean_buffer;
|
||||
|
||||
// We use the same rounding formula to ensure clean_buffer matches block boundaries
|
||||
u64 blocks_needed = (_size + _blocksize - 1) / _blocksize;
|
||||
clean_buffer.reserve(blocks_needed * _blocksize);
|
||||
|
||||
// 4. Linearly stream only the ACTIVE byte chunks into our clean buffer
|
||||
for (const auto& p : _pieces) {
|
||||
const u8* src_ptr = _buffer.data() + p.offset;
|
||||
clean_buffer.insert(clean_buffer.end(), src_ptr, src_ptr + p.length);
|
||||
}
|
||||
|
||||
// 5. Enforce trailing block alignment padding
|
||||
if (clean_buffer.size() % _blocksize != 0) {
|
||||
u64 padding = _blocksize - (clean_buffer.size() % _blocksize);
|
||||
clean_buffer.insert(clean_buffer.end(), padding, 0);
|
||||
}
|
||||
|
||||
// 6. Fast O(1) swap to point your class to the new optimized buffer
|
||||
_buffer = std::move(clean_buffer);
|
||||
|
||||
// 7. Reset piece orchestration to a single monolithic piece mapping 1:1
|
||||
_pieces.clear();
|
||||
_pieces.push_back({ 0, _size });
|
||||
}
|
||||
|
||||
void InstrReelDyn::grow(u64 len) {
|
||||
u64 current_capacity = _buffer.capacity();
|
||||
|
||||
// Account for requested bytes PLUS up to a block's worth of trailing alignment padding
|
||||
u64 minimum_needed = _buffer.size() + len + (_blocksize - 1);
|
||||
|
||||
if (minimum_needed > current_capacity) {
|
||||
// Grow exponentially (1.5x). If empty, seed it with 1 full block minimum.
|
||||
u64 raw_growth = (current_capacity == 0) ? _blocksize : current_capacity + (current_capacity / 2);
|
||||
u64 target_capacity = std::max(minimum_needed, raw_growth);
|
||||
|
||||
// Round the final target UP to the nearest 256-byte block
|
||||
u64 blocks = (target_capacity + _blocksize - 1) / _blocksize;
|
||||
_buffer.reserve(blocks * _blocksize);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
#include <spider/runtime/reel/InstrReel.hpp>
|
||||
|
||||
#include <list>
|
||||
|
||||
namespace spider {
|
||||
|
||||
/**
|
||||
@@ -10,13 +12,14 @@ namespace spider {
|
||||
class InstrReelDyn : public InstrReel {
|
||||
private:
|
||||
|
||||
struct ReelBlock {
|
||||
u8 data[256] = {};
|
||||
struct piece {
|
||||
u64 offset;
|
||||
u64 length;
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
deque<ReelBlock> _blocks;
|
||||
static constexpr u64 _blocksize = 256;
|
||||
std::vector<u8> _buffer;
|
||||
std::list<piece> _pieces;
|
||||
u64 _size;
|
||||
|
||||
public:
|
||||
@@ -37,14 +40,6 @@ namespace spider {
|
||||
|
||||
InstrReelDyn& operator=(InstrReelDyn&& move) noexcept;
|
||||
|
||||
private:
|
||||
|
||||
std::pair<u64, u8> indexOf(u64 ip);
|
||||
|
||||
bool continous(u64 ip0, u64 ip1, u64* b_index, u16* s_index);
|
||||
|
||||
void growTo(u64 ip);
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
@@ -53,7 +48,7 @@ namespace spider {
|
||||
* Reindexing may occur, continous access
|
||||
* may incurr in less penalties.
|
||||
*/
|
||||
virtual u8 readU8(u64 ip) override;
|
||||
virtual u8 readU8(u64 ip) const override;
|
||||
|
||||
/**
|
||||
* Obtains a byte of data at
|
||||
@@ -61,7 +56,7 @@ namespace spider {
|
||||
* Reindexing may occur, continous access
|
||||
* may incurr in less penalties.
|
||||
*/
|
||||
virtual u16 readU16(u64 ip) override;
|
||||
virtual u16 readU16(u64 ip) const override;
|
||||
|
||||
/**
|
||||
* Obtains a byte of data at
|
||||
@@ -69,7 +64,7 @@ namespace spider {
|
||||
* Reindexing may occur, continous access
|
||||
* may incurr in less penalties.
|
||||
*/
|
||||
virtual u32 readU32(u64 ip) override;
|
||||
virtual u32 readU32(u64 ip) const override;
|
||||
|
||||
/**
|
||||
* Obtains a byte of data at
|
||||
@@ -77,35 +72,32 @@ namespace spider {
|
||||
* Reindexing may occur, continous access
|
||||
* may incurr in less penalties.
|
||||
*/
|
||||
virtual u64 readU64(u64 ip) override;
|
||||
virtual u64 readU64(u64 ip) const override;
|
||||
|
||||
/**
|
||||
* Reads a range of data, and
|
||||
* outputs it.
|
||||
*/
|
||||
virtual void readRange(u64 ip, u8* out, u64 length) override;
|
||||
virtual void readRange(u64 ip, u8* out, u64 length) const override;
|
||||
|
||||
virtual void loadRegister(u64 ip, u8 size_code, register_t* r) override;
|
||||
virtual void loadRegister(u64 ip, u8 size_code, register_t* r) const override;
|
||||
|
||||
/**
|
||||
* Current size of the instructions.
|
||||
*/
|
||||
virtual u64 size() override;
|
||||
virtual u64 size() const override;
|
||||
|
||||
public:
|
||||
|
||||
void writeU8(u64 ip, u8 dat);
|
||||
void write(u64 ip, const u8* dat, const u64 len);
|
||||
|
||||
void writeU16(u64 ip, u16 dat);
|
||||
void remove(u64 ip, const u64 len);
|
||||
|
||||
void writeU32(u64 ip, u32 dat);
|
||||
void defragment();
|
||||
|
||||
void writeU64(u64 ip, u64 dat);
|
||||
private:
|
||||
|
||||
/**
|
||||
* Appends instruction at the end.
|
||||
*/
|
||||
void append(u16 bc);
|
||||
void grow(u64 len);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -42,44 +42,42 @@ namespace spider {
|
||||
delete[] _mem;
|
||||
}
|
||||
|
||||
// General Case(s) //
|
||||
|
||||
// Instruction abstraction //
|
||||
|
||||
u8 InstrReelFixed::readU8(u64 ip) {
|
||||
u8 InstrReelFixed::readU8(u64 ip) const {
|
||||
u8 dat;
|
||||
spider::loadPartialLE(&dat, _mem + ip, _size);
|
||||
return dat;
|
||||
}
|
||||
|
||||
u16 InstrReelFixed::readU16(u64 ip) {
|
||||
u16 InstrReelFixed::readU16(u64 ip) const {
|
||||
u16 dat;
|
||||
spider::loadPartialLE(&dat, _mem + ip, _size);
|
||||
return dat;
|
||||
}
|
||||
|
||||
u32 InstrReelFixed::readU32(u64 ip) {
|
||||
u32 InstrReelFixed::readU32(u64 ip) const {
|
||||
u32 dat;
|
||||
spider::loadPartialLE(&dat, _mem + ip, _size);
|
||||
return dat;
|
||||
}
|
||||
|
||||
u64 InstrReelFixed::readU64(u64 ip) {
|
||||
u64 InstrReelFixed::readU64(u64 ip) const {
|
||||
u64 dat;
|
||||
spider::loadPartialLE(&dat, _mem + ip, _size);
|
||||
return dat;
|
||||
}
|
||||
|
||||
void InstrReelFixed::readRange(u64 ip, u8* out, u64 length) {
|
||||
void InstrReelFixed::readRange(u64 ip, u8* out, u64 length) const {
|
||||
spider::loadPartialBytes(_mem, isize(ip), _size, out, length);
|
||||
}
|
||||
|
||||
void InstrReelFixed::loadRegister(u64 ip, u8 size_code, register_t* r) {
|
||||
void InstrReelFixed::loadRegister(u64 ip, u8 size_code, register_t* r) const {
|
||||
ip = std::min(ip, _size);
|
||||
spider::loadRegister[size_code](r, _mem + ip, _size - ip);
|
||||
}
|
||||
|
||||
u64 InstrReelFixed::size() {
|
||||
u64 InstrReelFixed::size() const {
|
||||
return _size;
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace spider {
|
||||
* Reindexing may occur, continous access
|
||||
* may incurr in less penalties.
|
||||
*/
|
||||
virtual u8 readU8(u64 ip) override;
|
||||
virtual u8 readU8(u64 ip) const override;
|
||||
|
||||
/**
|
||||
* Obtains a byte of data at
|
||||
@@ -46,7 +46,7 @@ namespace spider {
|
||||
* Reindexing may occur, continous access
|
||||
* may incurr in less penalties.
|
||||
*/
|
||||
virtual u16 readU16(u64 ip) override;
|
||||
virtual u16 readU16(u64 ip) const override;
|
||||
|
||||
/**
|
||||
* Obtains a byte of data at
|
||||
@@ -54,7 +54,7 @@ namespace spider {
|
||||
* Reindexing may occur, continous access
|
||||
* may incurr in less penalties.
|
||||
*/
|
||||
virtual u32 readU32(u64 ip) override;
|
||||
virtual u32 readU32(u64 ip) const override;
|
||||
|
||||
/**
|
||||
* Obtains a byte of data at
|
||||
@@ -62,20 +62,20 @@ namespace spider {
|
||||
* Reindexing may occur, continous access
|
||||
* may incurr in less penalties.
|
||||
*/
|
||||
virtual u64 readU64(u64 ip) override;
|
||||
virtual u64 readU64(u64 ip) const override;
|
||||
|
||||
/**
|
||||
* Reads a range of data, and
|
||||
* outputs it.
|
||||
*/
|
||||
virtual void readRange(u64 ip, u8* out, u64 length) override;
|
||||
virtual void readRange(u64 ip, u8* out, u64 length) const override;
|
||||
|
||||
virtual void loadRegister(u64 ip, u8 size_code, register_t* r) override;
|
||||
virtual void loadRegister(u64 ip, u8 size_code, register_t* r) const override;
|
||||
|
||||
/**
|
||||
* Current size of the instructions.
|
||||
*/
|
||||
virtual u64 size() override;
|
||||
virtual u64 size() const override;
|
||||
|
||||
public:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user