diff options
1 files changed, 120 insertions, 0 deletions
| -rw-r--r-- | spasm/src/asm/bytecode.cpp | 120 |
diff --git a/spasm/src/asm/bytecode.cpp b/spasm/src/asm/bytecode.cpp new file mode 100644 index 0000000..70e16c9 --- /dev/null +++ b/spasm/src/asm/bytecode.cpp @@ -0,0 +1,120 @@ +#include <fstream> +#include <iostream> +#include <string> +#include <vector> + +#include "bytecode.hpp" + +namespace SpasmImpl +{ +namespace ASM +{ +Bytecode_Stream::~Bytecode_Stream() {} + +Bytecode_File::Bytecode_File(const std::string& filename) + : _bytecode(filename.c_str(), std::ios_base::out | std::ios_base::binary) +{ +} + +void Bytecode_File::push_byte(Bytecode_Stream::byte byte) +{ + _bytecode.put(byte); +} + +void Bytecode_File::push_opcode(Bytecode_Stream::Opcode_t opcode) +{ + push_byte(opcode); +} + +union DoubleToBits { + double as_double; + int64_t as_bits; +}; + +int64_t to_bits(double d) +{ + DoubleToBits v; + v.as_double = d; + return v.as_bits; +}; + +void Bytecode_File::push_integer(int64_t number, int size) +{ + for (int i = 0; i < size; ++i) + push_byte((number >> (i << 3)) & 0xff); +} + +void Bytecode_File::push_double(double number) +{ + auto bits = to_bits(number); + for (size_t i = 0; i < sizeof(size_t); ++i) + push_byte((bits >> (i << 3)) & 0xff); +} + +void Bytecode_Memory::push_byte(Bytecode_Stream::byte byte) +{ + _bytecode.push_back(byte); +} + +void Bytecode_Memory::push_opcode(Bytecode_Stream::Opcode_t opcode) +{ + push_byte(opcode); +} + +void Bytecode_Memory::push_integer(int64_t number, int size) +{ + for (int i = 0; i < size; ++i) + push_byte((number >> (i << 3)) & 0xff); +} + +void Bytecode_Memory::push_double(double number) +{ + auto bits = to_bits(number); + for (size_t i = 0; i < sizeof(size_t); ++i) + push_byte((bits >> (i << 3)) & 0xff); +} + +void Bytecode_Memory::set_location(size_t index, size_t location) +{ + if (location <= 0xff) + { + _bytecode[index] = (byte)location; + } + else + { + for (size_t i = 0; i < sizeof(size_t); ++i) + _bytecode.at(index + i) = ((location >> (i << 3)) & 0xff); + } +} + +void Bytecode_Memory::push_location(size_t location) +{ + if (location <= 0xff) + { + push_byte((byte)location); + } + else + { + for (size_t i = 0; i < sizeof(size_t); ++i) + _bytecode.push_back((location >> (i << 3)) & 0xff); + } +} + +void Bytecode_Memory::push_string(const char* s, size_t length, int size) +{ + push_integer(int64_t(length), size); + _bytecode.insert(_bytecode.end(), s, s + length); +} + +const Bytecode_Memory::Bytecode& Bytecode_Memory::bytecode() const +{ + return _bytecode; +} + +size_t Bytecode_Memory::size() const +{ + return _bytecode.size(); +} + +} // namespace ASM +} // namespace SpasmImpl |
