+19
-1
@@ -222,6 +222,25 @@ void executor::step() {
|
||||
push_thing({ (struct thing_type){ thing_type::U32 } }).get<thing_type::u32>() =
|
||||
static_cast<thing_type::u32>(instr.arg.u8);
|
||||
} break;
|
||||
case instruction_t::PushConstant: {
|
||||
auto constant = frame.mod->constant_at(instr.arg.u16);
|
||||
switch (constant.type) {
|
||||
case constant::S32:
|
||||
push_thing({ (struct thing_type){ thing_type::S32 } }).get<thing_type::s32>() = constant.s32; // NOLINT
|
||||
break;
|
||||
case constant::U32:
|
||||
push_thing({ (struct thing_type){ thing_type::U32 } }).get<thing_type::u32>() = constant.u32; // NOLINT
|
||||
break;
|
||||
case constant::S64:
|
||||
push_thing({ (struct thing_type){ thing_type::S64 } }).get<thing_type::s64>() = constant.s64; // NOLINT
|
||||
break;
|
||||
case constant::U64:
|
||||
push_thing({ (struct thing_type){ thing_type::U64 } }).get<thing_type::u64>() = constant.u64; // NOLINT
|
||||
break;
|
||||
case constant::String: throw std::runtime_error("unimplemented");
|
||||
default: throw std::runtime_error("invalid constant");
|
||||
}
|
||||
} break;
|
||||
case instruction_t::Array: {
|
||||
const auto& type = *mod_to_thing_type(frame.mod, *frame.mod->type_at(instr.arg.u32));
|
||||
if (type.type != thing_type::Array || type.value.array.type == nullptr || type.value.array.type == &type)
|
||||
@@ -377,7 +396,6 @@ void executor::step() {
|
||||
pop_frame();
|
||||
if (m_frames.empty()) m_flags = m_flags | executor_flags::Done;
|
||||
} break;
|
||||
case instruction_t::PushConstant: throw std::runtime_error("unimplemented");
|
||||
default: throw std::runtime_error("unknown instruction");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ const std::size_t instruction_argument::s_sizes[instruction_argument::Count] = {
|
||||
// U32
|
||||
1,
|
||||
// Constant:
|
||||
4,
|
||||
2,
|
||||
// Type:
|
||||
4,
|
||||
// Variable:
|
||||
|
||||
@@ -16,6 +16,19 @@ std::ostream& mod::serialize(std::ostream& os) const {
|
||||
os.write(MAGIC, sizeof(MAGIC));
|
||||
detail::serialize(os, std::uint32_t(0)); // version
|
||||
|
||||
detail::serialize(os, static_cast<constant_index>(m_constants.size()));
|
||||
for (const auto& constant : m_constants) {
|
||||
detail::serialize(os, constant.type);
|
||||
switch (constant.type) {
|
||||
case constant::S32:
|
||||
case constant::U32: detail::serialize(os, constant.u32); break;
|
||||
case constant::S64:
|
||||
case constant::U64: detail::serialize(os, constant.u64); break;
|
||||
case constant::String: throw std::runtime_error("unimplemented");
|
||||
default: throw std::runtime_error("unreachable");
|
||||
}
|
||||
}
|
||||
|
||||
mod_type_id typeCount = mod_type_id(m_types.cend() - m_types.cbegin());
|
||||
detail::serialize(os, typeCount);
|
||||
for (mod_type_id id = 0; id < typeCount; ++id) {
|
||||
@@ -104,6 +117,22 @@ mod mod::load(std::istream& is) {
|
||||
|
||||
mod mod;
|
||||
|
||||
constant_index constantCount = 0;
|
||||
detail::load(is, constantCount);
|
||||
mod.m_constants.reserve(constantCount);
|
||||
for (; constantCount != 0; --constantCount) {
|
||||
constant constant{};
|
||||
detail::load(is, reinterpret_cast<std::uint32_t&>(constant.type));
|
||||
switch (constant.type) {
|
||||
case constant::S32:
|
||||
case constant::U32: detail::load(is, constant.u32); break;
|
||||
case constant::S64:
|
||||
case constant::U64: detail::load(is, constant.u64); break;
|
||||
case constant::String: throw std::runtime_error("unimplemented");
|
||||
default: throw std::runtime_error("unreachable");
|
||||
}
|
||||
}
|
||||
|
||||
mod_type_id typeCount = 0;
|
||||
detail::load(is, typeCount);
|
||||
for (mod_type_id id = 0; id < typeCount; ++id) {
|
||||
|
||||
Reference in New Issue
Block a user