diff --git a/furvm/include/furvm/thing.hpp b/furvm/include/furvm/thing.hpp index 15dcdd5..3a8d368 100644 --- a/furvm/include/furvm/thing.hpp +++ b/furvm/include/furvm/thing.hpp @@ -62,6 +62,8 @@ private: explicit rzecz() = default; }; public: + using nref_t = std::size_t; /**< Type of reference count. */ + static constexpr thing_handle GENERATION_SIZE = 12; /**< Bit size of generation part in thing_handle. */ public: /** @@ -110,12 +112,30 @@ public: * @return The value. */ const std::int32_t& int32() const; +public: + /** + * @brief Increments reference count of this thing by one. + */ + void add_reference() { ++m_refCount; } + + /** + * @brief Decrements reference count of this thing by one. + */ + void remove_reference() { --m_refCount; } + + /** + * @brief Returns reference count of this thing. + * + * @return The reference count. + */ + constexpr nref_t reference_count() const { return m_refCount; } private: thing_handle m_id; thing_t m_type; context_p m_context; - void* m_data = nullptr; + nref_t m_refCount = 0; + void* m_data = nullptr; }; } // namespace furvm diff --git a/furvm/src/executor.cpp b/furvm/src/executor.cpp index 687cb00..368e6a7 100644 --- a/furvm/src/executor.cpp +++ b/furvm/src/executor.cpp @@ -38,6 +38,7 @@ struct executor::frame executor::frame() const { } void executor::push_thing(const thing_p& thing) { + thing->add_reference(); m_stack.push(thing); } @@ -45,6 +46,7 @@ thing_p executor::pop_thing() { if (m_frames.top().stackBase >= m_stack.size()) throw stack_underflow(); thing_p top = std::move(m_stack.top()); m_stack.pop(); + top->remove_reference(); return top; }