refactor(furvm): remove thing handles
This commit is contained in:
@@ -70,43 +70,6 @@ public:
|
||||
|
||||
const std::vector<executor>& executors() const { return m_executors; }
|
||||
public:
|
||||
template <typename... Args>
|
||||
auto emplace_thing(Args&&... args) {
|
||||
return m_things.emplace_back(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns a thing from the context.
|
||||
*
|
||||
* @param args Id of the thing.
|
||||
* @return A handle to the thing.
|
||||
*/
|
||||
template <typename... Args>
|
||||
auto thing_at(Args&&... args) {
|
||||
return m_things.at(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns a thing from the context.
|
||||
*
|
||||
* @param args Id of the thing.
|
||||
* @return A handle to the thing.
|
||||
*/
|
||||
template <typename... Args>
|
||||
auto thing_at(Args&&... args) const {
|
||||
return m_things.at(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Erases a thing from the context.
|
||||
*
|
||||
* @param args Id of the thing.
|
||||
*/
|
||||
template <typename... Args>
|
||||
void erase_thing(Args&&... args) {
|
||||
m_things.erase(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns context's thing allocator.
|
||||
*
|
||||
@@ -116,9 +79,8 @@ public:
|
||||
|
||||
thing_type_store& tt_store() { return m_thingTypeStore; }
|
||||
private:
|
||||
handle_container<mod_h> m_modules;
|
||||
handle_container<thing_h> m_things;
|
||||
std::vector<executor> m_executors;
|
||||
handle_container<mod_h> m_modules;
|
||||
std::vector<executor> m_executors;
|
||||
|
||||
furlang::arena m_thingArena;
|
||||
thing_allocator<std::byte> m_thingAllocator;
|
||||
|
||||
@@ -48,7 +48,7 @@ public:
|
||||
std::size_t stackBase; /**< Snapshot of the stack size before this frame. */
|
||||
|
||||
thing_type* returnType; /**< Return type. */
|
||||
std::vector<thing_h> variables; /**< Frame variables. */
|
||||
std::vector<thing<>> variables; /**< Frame variables. */
|
||||
};
|
||||
public:
|
||||
~executor() = default;
|
||||
@@ -105,20 +105,10 @@ public:
|
||||
*
|
||||
* @return The frame.
|
||||
*/
|
||||
frame frame() const;
|
||||
frame top_frame() const;
|
||||
|
||||
const std::stack<struct frame>& frames() const { return m_frames; }
|
||||
const std::stack<frame>& frames() const { return m_frames; }
|
||||
public:
|
||||
/**
|
||||
* @brief Pushes a thing handle onto the stack.
|
||||
*
|
||||
* @param handle Thing handle.
|
||||
*/
|
||||
template <typename HandleFwd>
|
||||
void push_thing(HandleFwd&& handle) {
|
||||
m_stack.emplace(std::forward<HandleFwd>(handle));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Pushes a thing onto the stack.
|
||||
*
|
||||
@@ -127,21 +117,25 @@ public:
|
||||
* @param thing Thing.
|
||||
* @return The pushed handle.
|
||||
*/
|
||||
thing_h push_thing(class thing<>&& thing);
|
||||
thing<>& push_thing(thing<>&& thing);
|
||||
|
||||
thing<>& push_thing(const thing<>& thing);
|
||||
|
||||
/**
|
||||
* @brief Pops a thing from the stack.
|
||||
*
|
||||
* @return A handle to the popped thing.
|
||||
*/
|
||||
thing_h pop_thing();
|
||||
thing<> pop_thing();
|
||||
|
||||
/**
|
||||
* @brief Returns the top thing on the stack.
|
||||
*
|
||||
* @return A handle to the top thing.
|
||||
*/
|
||||
thing_h thing() const;
|
||||
thing<>& top_thing();
|
||||
|
||||
const thing<>& top_thing() const;
|
||||
public:
|
||||
/**
|
||||
* @brief Stores a thing in a frame variable.
|
||||
@@ -149,7 +143,7 @@ public:
|
||||
* @param variable Id of the variable in which the handle will be put.
|
||||
* @param thing Thing handle.
|
||||
*/
|
||||
void store_thing(variable_t variable, const thing_h& thing);
|
||||
void store_thing(variable_t variable, const thing<>& thing);
|
||||
|
||||
/**
|
||||
* @brief Stores a thing in a frame variable.
|
||||
@@ -157,7 +151,7 @@ public:
|
||||
* @param variable Id of the variable in which the handle will be put.
|
||||
* @param thing Thing handle.
|
||||
*/
|
||||
void store_thing(variable_t variable, thing_h&& thing);
|
||||
void store_thing(variable_t variable, thing<>&& thing);
|
||||
|
||||
/**
|
||||
* @brief Returns a thing stored in a variable.
|
||||
@@ -165,7 +159,9 @@ public:
|
||||
* @param variable Id of the variable from which the handle will be fetched.
|
||||
* @return A handle stored in the variable.
|
||||
*/
|
||||
thing_h load_thing(variable_t variable) const;
|
||||
thing<>& load_thing(variable_t variable);
|
||||
|
||||
const thing<>& load_thing(variable_t variable) const;
|
||||
public:
|
||||
/**
|
||||
* @brief Executes next instruction.
|
||||
@@ -175,12 +171,14 @@ private:
|
||||
thing_type thing_type_impl(mod_h mod, mod_type type) const;
|
||||
|
||||
thing_type* mod_to_thing_type(const mod_h& mod, const mod_type& type) const;
|
||||
|
||||
thing<> make_reference(const thing<>& thing) const;
|
||||
private:
|
||||
executor_flags m_flags{}; // NOLINT(bugprone-invalid-enum-default-initialization)
|
||||
context* m_context;
|
||||
|
||||
std::stack<struct frame> m_frames;
|
||||
std::stack<thing_h> m_stack;
|
||||
std::stack<frame> m_frames;
|
||||
std::stack<thing<>> m_stack;
|
||||
|
||||
executor_callback m_newFrameCb = nullptr;
|
||||
};
|
||||
|
||||
@@ -169,11 +169,6 @@ class thing;
|
||||
*/
|
||||
using thing_id = std::uint32_t;
|
||||
|
||||
/**
|
||||
* @brief A handle to a thing.
|
||||
*/
|
||||
using thing_h = handle<thing<thing_allocator>, refcount_header<thing_id>>;
|
||||
|
||||
// executor.hpp
|
||||
|
||||
/**
|
||||
|
||||
@@ -49,7 +49,7 @@ struct thing_type {
|
||||
Array,
|
||||
|
||||
Count,
|
||||
} type;
|
||||
} type = Count;
|
||||
union value {
|
||||
std::nullptr_t null = nullptr;
|
||||
thing_type* typeRef;
|
||||
@@ -202,6 +202,8 @@ public:
|
||||
std::byte* data;
|
||||
};
|
||||
public:
|
||||
thing() {}
|
||||
|
||||
/**
|
||||
* @brief Constructs a thing.
|
||||
*
|
||||
@@ -239,6 +241,7 @@ public:
|
||||
thing& operator=(thing&& other) noexcept {
|
||||
if (this == &other) return *this;
|
||||
m_type = other.m_type;
|
||||
m_size = other.m_size;
|
||||
m_data = other.m_data;
|
||||
m_allocator = std::move(other.m_allocator);
|
||||
other.m_type.type = thing_type::Count;
|
||||
@@ -247,8 +250,32 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
thing(const thing&) = delete;
|
||||
thing& operator=(const thing&) = delete;
|
||||
thing(const thing& other)
|
||||
: m_type(other.m_type), m_size(other.m_size), m_allocator(other.m_allocator) {
|
||||
if (m_type.type == thing_type::Ref) {
|
||||
m_data = other.m_data;
|
||||
return;
|
||||
}
|
||||
m_data = m_allocator.allocate(m_size);
|
||||
other.copy(*this);
|
||||
}
|
||||
|
||||
thing& operator=(const thing& other) {
|
||||
if (this == &other) return *this;
|
||||
|
||||
m_type = other.m_type;
|
||||
m_size = other.m_size;
|
||||
m_allocator = std::move(other.m_allocator);
|
||||
|
||||
if (m_type.type == thing_type::Ref) {
|
||||
m_data = other.m_data;
|
||||
return *this;
|
||||
}
|
||||
m_data = m_allocator.allocate(m_size);
|
||||
other.copy(*this);
|
||||
|
||||
return *this;
|
||||
}
|
||||
public:
|
||||
/**
|
||||
* @brief Returns a clone of the thing.
|
||||
@@ -257,6 +284,10 @@ public:
|
||||
*/
|
||||
thing clone() const {
|
||||
thing res(m_type, m_allocator);
|
||||
copy(res);
|
||||
}
|
||||
private:
|
||||
void copy(thing<>& dst) const {
|
||||
switch (m_type.type) {
|
||||
case thing_type::S8:
|
||||
case thing_type::S16:
|
||||
@@ -266,9 +297,9 @@ public:
|
||||
case thing_type::U16:
|
||||
case thing_type::U32:
|
||||
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.m_data, m_data); return std::move(res);
|
||||
case thing_type::Ref: throw std::runtime_error("cannot clone references");
|
||||
case thing_type::Ptr: std::memcpy(dst.m_data, m_data, m_size); return;
|
||||
case thing_type::Array: copy_list(m_type, dst.m_data, m_data); return;
|
||||
case thing_type::Ref: throw std::runtime_error("cannot copy references");
|
||||
case thing_type::Count: break;
|
||||
}
|
||||
throw std::runtime_error("unreachable");
|
||||
@@ -460,17 +491,17 @@ public:
|
||||
thing at(thing_type::u64 index) const {
|
||||
if (!is(thing_type::Array)) throw bad_thing_access();
|
||||
|
||||
std::size_t elementSize = compute_size_na(*m_type.value.array.type);
|
||||
if (m_type.value.array.size == 0) {
|
||||
std::size_t elementSize = compute_size_na(*true_type().value.array.type);
|
||||
if (true_type().value.array.size == 0) {
|
||||
auto& array = get<dynamic_array>();
|
||||
if (index < 0 || index >= array.size) throw std::out_of_range("index out of range");
|
||||
thing ref = { { thing_type::Ref, m_type.value.array.type }, m_allocator };
|
||||
thing ref = { { thing_type::Ref, true_type().value.array.type }, m_allocator };
|
||||
ref.m_data = array.data + (index * elementSize);
|
||||
return ref;
|
||||
}
|
||||
|
||||
if (index < 0 || index >= m_type.value.array.size) throw std::out_of_range("index out of range");
|
||||
thing ref = { { thing_type::Ref, m_type.value.array.type }, m_allocator };
|
||||
if (index < 0 || index >= true_type().value.array.size) throw std::out_of_range("index out of range");
|
||||
thing ref = { { thing_type::Ref, true_type().value.array.type }, m_allocator };
|
||||
ref.m_data = m_data + (index * elementSize);
|
||||
return ref;
|
||||
}
|
||||
@@ -727,8 +758,8 @@ private:
|
||||
}
|
||||
private:
|
||||
thing_type m_type;
|
||||
std::size_t m_size;
|
||||
std::byte* m_data;
|
||||
std::size_t m_size = 0;
|
||||
std::byte* m_data = nullptr;
|
||||
|
||||
allocator_type m_allocator;
|
||||
};
|
||||
|
||||
@@ -16,6 +16,8 @@ class thing_allocator {
|
||||
public:
|
||||
using value_type = T; /**< Value type. */
|
||||
public:
|
||||
thing_allocator() = default;
|
||||
|
||||
/**
|
||||
* @brief Constructs a thing allocator.
|
||||
*
|
||||
@@ -101,7 +103,7 @@ public:
|
||||
return m_arena != other.m_arena || m_deadThings != other.m_deadThings;
|
||||
}
|
||||
private:
|
||||
furlang::arena* m_arena;
|
||||
furlang::arena* m_arena = nullptr;
|
||||
|
||||
std::shared_ptr<dead_things> m_deadThings;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user