refactor(furvm): integrate handle system into things

Sloppy af

Refs: #12
This commit is contained in:
2026-06-17 20:19:53 +02:00
parent 00bcc0e6a5
commit e9b38e95a2
7 changed files with 253 additions and 302 deletions
+27
View File
@@ -5,7 +5,9 @@
#include "furvm/executor.hpp"
#include "furvm/fwd.hpp"
#include "furvm/module.hpp"
#include "furvm/thing.hpp"
#include <cstring>
#include <memory>
#include <queue>
#include <string>
@@ -102,6 +104,31 @@ public:
* @brief Removes unreferenced things from the thing list.
*/
void collect();
public:
thing_h emplace_thing(thing_t type) {
thing_id id = m_things.size();
if (!m_deadThings.empty()) {
id = m_deadThings.front();
m_deadThings.pop();
}
size_t size = thing_type_size(type);
void* data = nullptr;
for (auto it = m_deadThingData.begin(); it != m_deadThingData.end(); ++it) {
thing_t curType{};
std::memcpy(&curType, static_cast<char*>(*it) - sizeof(curType), sizeof(curType));
if (thing_type_size(curType) != size) continue;
data = *it;
m_deadThingData.erase(it);
break;
}
if (data == nullptr) data = m_thingArena.allocate<char>(sizeof(thing_t) + size);
memcpy(data, &type, sizeof(type));
data = static_cast<char*>(data) + sizeof(type);
thing_p thing = std::make_shared<class thing>(type, data);
return { id, m_things.emplace_back(std::move(thing)) };
}
private:
std::unordered_map<std::string, mod_p> m_modules;
+9 -9
View File
@@ -37,7 +37,7 @@ public:
std::size_t position; /**< Cursor to a current instruction in the bytecode. */
std::size_t stackBase; /**< Snapshot of the stack size before this frame. */
std::vector<thing_p> variables; /**< Frame variables. */
std::vector<thing_h> variables; /**< Frame variables. */
};
public:
/**
@@ -104,28 +104,28 @@ public:
*
* @param thing The thing to push.
*/
void push_thing(const thing_p& thing);
void push_thing(const thing_h& thing);
/**
* @brief Pushes a thing onto the stack.
*
* @param thing The thing to push.
*/
void push_thing(thing_p&& thing);
void push_thing(thing_h&& thing);
/**
* @brief Pops a thing from the stack.
*
* @return The popped thing.
*/
thing_p pop_thing();
thing_h pop_thing();
/**
* @brief Returns the top thing on the stack.
*
* @return The thing.
*/
thing_p thing() const;
thing_h thing() const;
public:
/**
* @brief Stores a thing in a variable.
@@ -133,7 +133,7 @@ public:
* @param variable Variable to store the thing in.
* @param thing Thing to store.
*/
void store_thing(variable_t variable, const thing_p& thing);
void store_thing(variable_t variable, const thing_h& thing);
/**
* @brief Stores a thing in a variable.
@@ -141,7 +141,7 @@ public:
* @param variable Variable to store the thing in.
* @param thing Thing to store.
*/
void store_thing(variable_t variable, thing_p&& thing);
void store_thing(variable_t variable, thing_h&& thing);
/**
* @brief Returns a thing stored in a variable.
@@ -149,7 +149,7 @@ public:
* @param variable Variable where the thing is stored.
* @return The thing stored in the variable.
*/
thing_p load_thing(variable_t variable) const;
thing_h load_thing(variable_t variable) const;
public:
/**
* @brief Executes next instruction.
@@ -160,7 +160,7 @@ private:
context_p m_context;
std::stack<struct frame> m_frames;
std::stack<thing_p> m_stack;
std::stack<thing_h> m_stack;
};
} // namespace furvm
+1 -1
View File
@@ -151,7 +151,7 @@ using thing_id = std::uint32_t;
/**
* @brief A handle to a furvm's thing.
*/
using thing_h = handle<thing_id, thing>;
using thing_h = handle<thing_id, thing_p>;
// executor.hpp
+19
View File
@@ -1,10 +1,26 @@
#ifndef FURVM_HANDLE_HPP
#define FURVM_HANDLE_HPP
#include <limits>
#include <type_traits>
#include <utility>
namespace furvm {
namespace detail {
template <typename Id, typename = void>
struct dead_id {
static constexpr Id value = {};
};
template <typename Id>
struct dead_id<Id, std::enable_if_t<std::is_integral_v<Id>>> {
static constexpr Id value = std::numeric_limits<Id>::max();
};
} // namespace detail
template <typename Id, typename T>
class handle {
public:
@@ -25,6 +41,9 @@ public:
template <typename IdF, typename Value>
handle(IdF&& id, Value&& value)
: m_id(std::forward<IdF>(id)), m_value(std::forward<Value>(value)) {}
handle()
: m_id(detail::dead_id<Id>::value), m_value() {}
public:
handle& operator=(value_type&& value) noexcept {
m_value = std::move(value);
+20 -106
View File
@@ -1,7 +1,6 @@
#ifndef FURVM_THING_HPP
#define FURVM_THING_HPP
#include "furvm/context.hpp" // IWYU pragma: keep
#include "furvm/fwd.hpp"
namespace furvm {
@@ -58,7 +57,9 @@ public:
static constexpr thing_id GENERATION_SIZE = 12; /**< Bit size of generation part in thing_handle. */
public:
thing(const context_p& context, thing_t type);
thing(thing_t type);
thing(thing_t type, void* data);
~thing();
@@ -74,104 +75,6 @@ public:
thing(const thing&) = delete;
thing& operator=(const thing&) = delete;
public:
/**
* @brief Adds two things together.
*
* @param lhs Left-hand-side thing.
* @param rhs Right-hand-side thing.
* @return Shared pointer to result thing.
*/
friend thing_p operator+(const thing_p& lhs, const thing_p& rhs);
/**
* @brief Subtracts two things together.
*
* @param lhs Left-hand-side thing.
* @param rhs Right-hand-side thing.
* @return Shared pointer to result thing.
*/
friend thing_p operator-(const thing_p& lhs, const thing_p& rhs);
/**
* @brief Multiplies two things together.
*
* @param lhs Left-hand-side thing.
* @param rhs Right-hand-side thing.
* @return Shared pointer to result thing.
*/
friend thing_p operator*(const thing_p& lhs, const thing_p& rhs);
/**
* @brief Divides two things together.
*
* @param lhs Left-hand-side thing.
* @param rhs Right-hand-side thing.
* @return Shared pointer to result thing.
*/
friend thing_p operator/(const thing_p& lhs, const thing_p& rhs);
/**
* @brief Modulos two things together.
*
* @param lhs Left-hand-side thing.
* @param rhs Right-hand-side thing.
* @return Shared pointer to result thing.
*/
friend thing_p operator%(const thing_p& lhs, const thing_p& rhs);
/**
* @brief Compares two things for equality.
*
* @param lhs Left-hand-side thing.
* @param rhs Right-hand-side thing.
* @return Shared pointer to result thing.
*/
friend thing_p operator==(const thing_p& lhs, const thing_p& rhs);
/**
* @brief Compares two things for equality.
*
* @param lhs Left-hand-side thing.
* @param rhs Right-hand-side thing.
* @return Shared pointer to result thing.
*/
friend thing_p operator!=(const thing_p& lhs, const thing_p& rhs);
/**
* @brief Compares if the left thing is less than the right thing.
*
* @param lhs Left-hand-side thing.
* @param rhs Right-hand-side thing.
* @return Shared pointer to result thing.
*/
friend thing_p operator<(const thing_p& lhs, const thing_p& rhs);
/**
* @brief Compares if the left thing is greater than the right thing.
*
* @param lhs Left-hand-side thing.
* @param rhs Right-hand-side thing.
* @return Shared pointer to result thing.
*/
friend thing_p operator>(const thing_p& lhs, const thing_p& rhs);
/**
* @brief Compares if the left thing is less than or equal to the right thing.
*
* @param lhs Left-hand-side thing.
* @param rhs Right-hand-side thing.
* @return Shared pointer to result thing.
*/
friend thing_p operator<=(const thing_p& lhs, const thing_p& rhs);
/**
* @brief Compares if the left thing is greater than or equal to the right thing.
*
* @param lhs Left-hand-side thing.
* @param rhs Right-hand-side thing.
* @return Shared pointer to result thing.
*/
friend thing_p operator>=(const thing_p& lhs, const thing_p& rhs);
public:
/**
* @brief Returns a clone of the thing.
@@ -179,7 +82,7 @@ public:
* @param thing Thing to clone.
* @return Shared pointer to a clone of the thing.
*/
static thing_p clone(const thing_p& thing);
static thing_h clone(const context_p& context, const thing_h& thing);
public:
/**
* @brief Returns an int32 value from this thing.
@@ -194,6 +97,18 @@ public:
* @return The value.
*/
const std::int32_t& int32() const;
public:
thing_h add(const context_p& context, const thing_h& rhs) const;
thing_h sub(const context_p& context, const thing_h& rhs) const;
thing_h mul(const context_p& context, const thing_h& rhs) const;
thing_h div(const context_p& context, const thing_h& rhs) const;
thing_h mod(const context_p& context, const thing_h& rhs) const;
thing_h equals(const context_p& context, const thing_h& rhs) const;
thing_h not_equals(const context_p& context, const thing_h& rhs) const;
thing_h less_than(const context_p& context, const thing_h& rhs) const;
thing_h greater_than(const context_p& context, const thing_h& rhs) const;
thing_h less_equals(const context_p& context, const thing_h& rhs) const;
thing_h greater_equals(const context_p& context, const thing_h& rhs) const;
public:
/**
* @brief Increments reference count of this thing by one.
@@ -212,11 +127,10 @@ public:
*/
constexpr nref_t reference_count() const { return m_refCount; }
private:
context_p m_context;
thing_t m_type;
nref_t m_refCount = 0;
void* m_data = nullptr;
thing_t m_type;
bool m_ownData = true;
nref_t m_refCount = 0;
void* m_data = nullptr;
};
} // namespace furvm