diff --git a/furvm/include/furvm/module.hpp b/furvm/include/furvm/module.hpp index b456219..b950176 100644 --- a/furvm/include/furvm/module.hpp +++ b/furvm/include/furvm/module.hpp @@ -18,6 +18,10 @@ namespace furvm { struct mod_type { + struct ptr { + mod_type_id typeId; + }; + struct array { mod_type_id typeId; std::size_t size; @@ -37,6 +41,7 @@ struct mod_type { U16, U32, U64, + Ptr, Array, Import, @@ -44,11 +49,17 @@ struct mod_type { } type; union value { std::nullptr_t null = nullptr; + ptr ptr; array array; imprt imprt; value() = default; + value(mod_type_id id) + : ptr({}) { + ptr.typeId = id; + } + value(mod_type_id id, std::size_t size) : array({}) { array.typeId = id; diff --git a/furvm/include/furvm/thing.hpp b/furvm/include/furvm/thing.hpp index 8d15e1e..3d8c368 100644 --- a/furvm/include/furvm/thing.hpp +++ b/furvm/include/furvm/thing.hpp @@ -30,6 +30,10 @@ struct thing_type { using u32 = std::uint32_t; using u64 = std::uint64_t; + struct ptr { + thing_type* type; + }; + struct array { thing_type* type; std::size_t size; @@ -44,16 +48,23 @@ struct thing_type { U16, U32, U64, + Ptr, Array, Count, } type; union value { std::nullptr_t null = nullptr; + ptr ptr; array array; value() = default; + value(thing_type* type) + : ptr({}) { + ptr.type = type; + } + value(thing_type* type, std::size_t size) : array({}) { array.type = type; @@ -76,6 +87,7 @@ struct thing_type { case U16: case U32: case U64: return true; + case Ptr: return *value.ptr.type == *other.value.ptr.type; case Array: return *value.array.type == *other.value.array.type && value.array.size == other.value.array.size; case Count: break; } @@ -94,10 +106,11 @@ struct thing_type { case U16: case U32: case U64: return true; - case Array: + case Ptr: + case Array: return false; case Count: break; } - return false; + throw std::runtime_error("unreachable"); } static std::size_t primitive_size(enum type type) { @@ -110,10 +123,11 @@ struct thing_type { case thing_type::U16: return sizeof(u16); case thing_type::U32: return sizeof(u32); case thing_type::U64: return sizeof(u64); - case Array: + case Ptr: + case Array: return 0; case Count: break; } - return 0; + throw std::runtime_error("unreachable"); } }; @@ -131,6 +145,7 @@ struct thing_type_hash { case thing_type::U16: case thing_type::U32: case thing_type::U64: return seed; + case thing_type::Ptr: return furlang::utility::hash_combine(seed, thing_type_hash{}(*type.value.ptr.type)); case thing_type::Array: seed = furlang::utility::hash_combine(seed, thing_type_hash{}(*type.value.array.type)); seed = furlang::utility::hash_combine(seed, @@ -245,7 +260,8 @@ public: case thing_type::U8: case thing_type::U16: case thing_type::U32: - case thing_type::U64: std::memcpy(res.m_data, m_data, m_size); return std::move(res); + case thing_type::U64: + case thing_type::Ptr: std::memcpy(res.m_data, m_data, m_size); return std::move(res); case thing_type::Array: copy_list(m_type, res.get(), get()); return std::move(res); case thing_type::Count: break; } @@ -480,7 +496,8 @@ private: case thing_type::U8: case thing_type::U16: case thing_type::U32: - case thing_type::U64: std::memcpy(dst.flat, src.flat, size); return; + case thing_type::U64: + case thing_type::Ptr: std::memcpy(dst.flat, src.flat, size); return; case thing_type::Array: for (std::size_t i = 0; i < size; ++i) { copy_list(*innerType.value.array.type, @@ -503,6 +520,7 @@ private: case thing_type::U16: return sizeof(thing_type::u16); case thing_type::U32: return sizeof(thing_type::u32); case thing_type::U64: return sizeof(thing_type::u64); + case thing_type::Ptr: return sizeof(void*); case thing_type::Array: return type.value.array.size == 0 ? sizeof(array) : compute_size_na(*type.value.array.type) * type.value.array.size; @@ -639,6 +657,7 @@ private: case thing_type::U64: res.get() = Op{}(cast_to(), rhs.cast_to()); return res; + case thing_type::Ptr: // TODO: Pointer arithmetics case thing_type::Array: case thing_type::Count: break; } diff --git a/furvm/src/executor.cpp b/furvm/src/executor.cpp index 12b6a84..73d46b8 100644 --- a/furvm/src/executor.cpp +++ b/furvm/src/executor.cpp @@ -29,6 +29,7 @@ thing_type executor::thing_type_impl(mod_h mod, mod_type type) const { case thing_type::U16: case thing_type::U32: case thing_type::U64: return { static_cast(type.type) }; + case thing_type::Ptr: return { thing_type::Ptr, thing_type(mod, *mod->type_at(type.value.ptr.typeId)) }; case thing_type::Array: { return { static_cast(type.type), { thing_type(mod, *mod->type_at(type.value.array.typeId)), type.value.array.size } }; @@ -222,18 +223,11 @@ void executor::step() { push_thing(lhs->greater_equals(*rhs)); } break; case instruction_t::Pointerof: { - // auto thing = pop_thing(); - // auto ptr = push_thing( - //{ (struct thing_type){ thing_type::Primitive, { sizeof(std::uintptr_t) } }, m_context->thing_alloc() }); - // switch (thing->type().type) { - // case thing_type::Primitive: ptr->get() = reinterpret_cast(thing->raw()); - // break; case thing_type::Array: ptr->get() = reinterpret_cast( - // thing->type().value.array.size == 0 ? thing->get::array>().dynamic.data - //: thing->get::array>().flat); - // break; - // case thing_type::Count: throw std::runtime_error("unreachable"); - // } - throw std::runtime_error("unimplemented"); // TODO: Implement + auto thing = pop_thing(); + auto ptr = + push_thing({ (struct thing_type){ thing_type::Ptr, m_context->thing_type_store().at(thing->type().id) }, + m_context->thing_alloc() }); + ptr->get() = thing->raw(); } break; case instruction_t::Sizeof: { auto thing = pop_thing(); @@ -249,6 +243,7 @@ void executor::step() { case thing_type::U64: size->get() = static_cast(thing_type::primitive_size(thing->type().type)); break; + case thing_type::Ptr: size->get() = static_cast(sizeof(void*)); break; case thing_type::Array: size->get() = static_cast( (thing->type().value.array.size == 0) ? thing->get::array>().dynamic.size diff --git a/furvm/src/main.cpp b/furvm/src/main.cpp index c10cc46..0054bb2 100644 --- a/furvm/src/main.cpp +++ b/furvm/src/main.cpp @@ -58,7 +58,7 @@ int main(int argc, char** argv) { 0, 0, 0, - static_cast(furvm::instruction_t::Reference), + static_cast(furvm::instruction_t::Pointerof), static_cast(furvm::instruction_t::Call), 1, 0, diff --git a/furvm/src/module.cpp b/furvm/src/module.cpp index 1a74452..d0fbdd9 100644 --- a/furvm/src/module.cpp +++ b/furvm/src/module.cpp @@ -34,6 +34,7 @@ std::ostream& mod::serialize(std::ostream& os) const { case mod_type::U16: case mod_type::U32: case mod_type::U64: break; + case mod_type::Ptr: detail::serialize(os, type.value.ptr.typeId); break; case mod_type::Array: { detail::serialize(os, type.value.array.typeId); detail::serialize(os, type.value.array.size); @@ -115,6 +116,11 @@ mod mod::load(std::istream& is) { case mod_type::U16: case mod_type::U32: case mod_type::U64: break; + case mod_type::Ptr: { + mod_type_id typeId = 0; + detail::load(is, typeId); + mod.emplace_type(id, typeId).dispatch(); + } break; case mod_type::Array: { mod_type_id typeId = 0; detail::load(is, typeId);