#include "furvm/serializer.hpp" #include "furvm/function.hpp" // IWYU pragma: keep #include #include #include #include #include #include namespace furvm { template static inline void write_raw(std::ostream& os, const T& value) { os.write(reinterpret_cast(&value), sizeof(T)); } template static inline void read_raw(std::istream& is, T& value) { is.read(reinterpret_cast(&value), sizeof(T)); } static inline void write_u64(std::ostream& os, std::uint64_t value) { os.put(static_cast((value >> 0ULL) & 0xFF)); os.put(static_cast((value >> 8ULL) & 0xFF)); os.put(static_cast((value >> 16ULL) & 0xFF)); os.put(static_cast((value >> 24ULL) & 0xFF)); os.put(static_cast((value >> 32ULL) & 0xFF)); os.put(static_cast((value >> 40ULL) & 0xFF)); os.put(static_cast((value >> 48ULL) & 0xFF)); os.put(static_cast((value >> 56ULL) & 0xFF)); } static inline void read_u64(std::istream& is, std::uint64_t& value) { value = (static_cast(is.get()) << 0) | (static_cast(is.get()) << 8) | (static_cast(is.get()) << 16) | (static_cast(is.get()) << 24) | (static_cast(is.get()) << 32) | (static_cast(is.get()) << 40) | (static_cast(is.get()) << 48) | (static_cast(is.get()) << 56); } static inline void write_u32(std::ostream& os, std::uint32_t value) { os.put(static_cast((value >> 0ULL) & 0xFF)); os.put(static_cast((value >> 8ULL) & 0xFF)); os.put(static_cast((value >> 16ULL) & 0xFF)); os.put(static_cast((value >> 24ULL) & 0xFF)); } static inline void read_u32(std::istream& is, std::uint32_t& value) { value = static_cast(is.get() << 0) | static_cast(is.get() << 8) | static_cast(is.get() << 16) | static_cast(is.get() << 24); } static inline void write_u16(std::ostream& os, std::uint16_t value) { os.put(static_cast((value >> 0ULL) & 0xFF)); os.put(static_cast((value >> 8ULL) & 0xFF)); } static inline void read_u16(std::istream& is, std::uint16_t& value) { value = static_cast(is.get() << 0) | static_cast(is.get() << 8); } static inline void write_u8(std::ostream& os, std::uint8_t value) { os.put(static_cast((value >> 0ULL) & 0xFF)); } static inline void read_u8(std::istream& is, std::uint8_t& value) { value = static_cast(is.get() << 0); } bool serializer::serialize_module(std::ostream& os, const mod_p& mod) { os.write(reinterpret_cast(MODULE_MAGIC), sizeof(MODULE_MAGIC)); write_u32(os, VERSION); write_u32(os, mod->m_functions.size()); for (const auto& func : mod->m_functions) { write_u16(os, func->id()); write_u8(os, static_cast(func->type())); switch (func->type()) { case function_t::Normal: { write_u64(os, func->position()); } break; case function_t::Native: { // TODO: Replace with a reference to the function's name from constant pool throw std::runtime_error("cannot serialize native functions yet"); } break; case function_t::Import: { // TODO: Replace with a reference to the module's and function's name from constant pool throw std::runtime_error("cannot serialize import functions yet"); } break; } } write_u64(os, mod->m_bytecode.size()); os.write(reinterpret_cast(mod->m_bytecode.data()), static_cast(mod->m_bytecode.size())); return false; } } // namespace furvm