From ded19f7962f962d7b5d9c73cb0389439b1304ade Mon Sep 17 00:00:00 2001 From: Konstantin Nazarov Date: Sat, 27 Jul 2024 01:01:38 +0100 Subject: [PATCH] Fix a few bugs with GC roots --- src/arena.hpp | 6 ++++-- src/common.hpp | 23 ++++++++++++++++++++++- src/error.hpp | 3 ++- src/vli.cpp | 9 +++++++-- 4 files changed, 35 insertions(+), 6 deletions(-) diff --git a/src/arena.hpp b/src/arena.hpp index 5b94898..faa6eb9 100644 --- a/src/arena.hpp +++ b/src/arena.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include "error.hpp" #include "pod.hpp" @@ -58,10 +59,10 @@ class GcRootList { } void remove() { - _prev = 0; - _next = 0; if (_prev) _prev->_next = _next; if (_next) _next->_prev = _prev; + _prev = 0; + _next = 0; } GcRootList* next() { return _next; } @@ -161,4 +162,5 @@ GcRoot::GcRoot(GcRoot&& rhs) { rhs._node->update(this); _ptr = rhs._ptr; _node = rhs._node; + rhs._node = 0; } diff --git a/src/common.hpp b/src/common.hpp index 9279e36..8721a15 100644 --- a/src/common.hpp +++ b/src/common.hpp @@ -96,10 +96,28 @@ class String : public Object { auto pod_string = TRY(arena.alloc(size * sizeof(char32_t))); memcpy(pod_string->data, chars, size * sizeof(char32_t)); + pod_string->size = size; return String(TRY(MkGcRoot(pod_string, arena))); } + static Result create(Arena& arena, const char* str) { + uint64_t size = strlen(str); + auto pod_string = TRY(arena.alloc(size * sizeof(char32_t))); + + for (uint64_t i = 0; i < size; i++) pod_string->data[i] = str[i]; + pod_string->size = size; + + return String(TRY(MkGcRoot(pod_string, arena))); + } + + uint64_t size() { return _value->size; } + + Result operator[](uint64_t idx) { + if (idx >= _value->size) return ErrorCode::IndexOutOfRange; + return _value->data[idx]; + } + virtual Result copy(Arena& arena) final; private: @@ -204,7 +222,10 @@ class Value { public: Value() { new (buf) Nil(); } ~Value() { ((Object*)buf)->~Object(); } - Value(Value&& val) { memcpy(buf, val.buf, 24); } + Value(Value&& val) { + memcpy(buf, val.buf, 24); + new (val.buf) Nil(); + } Value(const Value&) = delete; template diff --git a/src/error.hpp b/src/error.hpp index 695c0ae..294cf77 100644 --- a/src/error.hpp +++ b/src/error.hpp @@ -2,6 +2,7 @@ enum class ErrorCode { Success, - OutOfMemory + OutOfMemory, + IndexOutOfRange }; diff --git a/src/vli.cpp b/src/vli.cpp index a223145..0432c38 100644 --- a/src/vli.cpp +++ b/src/vli.cpp @@ -18,8 +18,13 @@ int main() { std::cout << int(((Int64&)*val).value()) << "\n"; */ - auto lst = DIEIF(arena.alloc()); - auto root = DIEIF(MkGcRoot(lst, arena)); + { + auto s = DIEIF(String::create(arena, "foo")); + + std::cout << "roout count: " << arena.root_count() << "\n"; + std::cout << "char: " << (char)DIEIF(s[2]) << "\n"; + } + std::cout << "roout count: " << arena.root_count() << "\n"; return 0; }