diff --git a/src/arena.hpp b/src/arena.hpp index 674c133..6288a73 100644 --- a/src/arena.hpp +++ b/src/arena.hpp @@ -20,6 +20,10 @@ static uint64_t round_up(uint64_t number, uint64_t to) { return ((number + to - 1) / to) * to; } +template + requires std::derived_from +class GcRoot; + class GcRootBase { public: friend class Arena; @@ -31,6 +35,13 @@ class GcRootBase { PodObject* get() { return _ptr; } + PodObject* get() const { return _ptr; } + PodObject& operator*() const { return *_ptr; } + PodObject* operator->() const { return _ptr; } + + template + GcRoot&& move_as() &&; + protected: PodObject* _ptr; GcRootList* _node; @@ -59,6 +70,11 @@ Result> MkGcRoot(T* ptr) { return GcRoot::create(ptr); } +template +GcRoot&& GcRootBase::move_as() && { + return (GcRoot&&)std::move(*this); +} + class GcRootList { public: friend class Arena; diff --git a/src/common.cpp b/src/common.cpp index 80f43dc..98e2934 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -8,50 +8,50 @@ #include "utf8.hpp" #include "writer.hpp" -Result Value::create(PodObject* obj) { +Result Value::create(GcRootBase&& obj) { switch (obj->header.tag) { case Tag::Nil: - return Value(TRY(Nil::create((PodNil*)obj))); + return Value(Nil(std::move(obj).move_as())); case Tag::Int64: - return Value(TRY(Int64::create((PodInt64*)obj))); + return Value(Int64(std::move(obj).move_as())); case Tag::Float: - return Value(TRY(Float::create((PodFloat*)obj))); + return Value(Float(std::move(obj).move_as())); case Tag::Bool: - return Value(TRY(Bool::create((PodBool*)obj))); + return Value(Bool(std::move(obj).move_as())); case Tag::Array: - return Value(TRY(Array::create((PodArray*)obj))); + return Value(Array(std::move(obj).move_as())); case Tag::ByteArray: - return Value(TRY(ByteArray::create((PodByteArray*)obj))); + return Value(ByteArray(std::move(obj).move_as())); case Tag::Dict: - return Value(TRY(Dict::create((PodDict*)obj))); + return Value(Dict(std::move(obj).move_as())); case Tag::String: - return Value(TRY(String::create((PodString*)obj))); + return Value(String(std::move(obj).move_as())); case Tag::Symbol: - return Value(TRY(Symbol::create((PodSymbol*)obj))); + return Value(Symbol(std::move(obj).move_as())); case Tag::SrcLoc: - return Value(TRY(SrcLoc::create((PodSrcLoc*)obj))); + return Value(SrcLoc(std::move(obj).move_as())); case Tag::Syntax: - return Value(TRY(Syntax::create((PodSyntax*)obj))); + return Value(Syntax(std::move(obj).move_as())); case Tag::Pair: - return Value(TRY(Pair::create((PodPair*)obj))); + return Value(Pair(std::move(obj).move_as())); case Tag::Opcode: - return Value(TRY(Opcode::create((PodOpcode*)obj))); + return Value(Opcode(std::move(obj).move_as())); case Tag::Function: - return Value(TRY(Function::create((PodFunction*)obj))); + return Value(Function(std::move(obj).move_as())); case Tag::StdlibFunction: - return Value(TRY(StdlibFunction::create((PodStdlibFunction*)obj))); + return Value(StdlibFunction(std::move(obj).move_as())); case Tag::Module: - return Value(TRY(Module::create((PodModule*)obj))); + return Value(Module(std::move(obj).move_as())); case Tag::StackFrame: - return Value(TRY(StackFrame::create((PodStackFrame*)obj))); + return Value(StackFrame(std::move(obj).move_as())); case Tag::Error: - return Value(TRY(Error::create((PodError*)obj))); + return Value(Error(std::move(obj).move_as())); case Tag::Continuation: - return Value(TRY(Continuation::create((PodContinuation*)obj))); + return Value(Continuation(std::move(obj).move_as())); case Tag::Task: - return Value(TRY(Task::create((PodTask*)obj))); + return Value(Task(std::move(obj).move_as())); case Tag::TaskResult: - return Value(TRY(TaskResult::create((PodTaskResult*)obj))); + return Value(TaskResult(std::move(obj).move_as())); }; return Value(); } @@ -245,15 +245,15 @@ Result Syntax::create(const String& filename, } Result Syntax::filename() const { - return Value::create(_value->filename.get()); + return Value::create(TRY(MkGcRoot(_value->filename.get()))); } Result Syntax::srcloc() const { - return Value::create(_value->srcloc.get()); + return Value::create(TRY(MkGcRoot(_value->srcloc.get()))); } Result Syntax::expression() const { - return Value::create(_value->expression.get()); + return Value::create(TRY(MkGcRoot(_value->expression.get()))); } Result Syntax::cmp(const Syntax& rhs) const { @@ -509,7 +509,7 @@ Result StackFrame::copy() const { Result StackFrame::get(uint64_t idx) const { if (idx >= _value->size) return ERROR(KeyError); - return Value::create(_value->data[idx].get()); + return Value::create(TRY(MkGcRoot(_value->data[idx].get()))); } Result StackFrame::set(uint64_t idx, const Value& val) const { @@ -561,10 +561,10 @@ Result StackFrame::settop(uint64_t idx) const { } Result StackFrame::parent() const { - return Value::create(_value->parent.get()); + return Value::create(TRY(MkGcRoot(_value->parent.get()))); } Result StackFrame::fun() const { - return Value::create(_value->fun.get()); + return Value::create(TRY(MkGcRoot(_value->fun.get()))); } uint64_t StackFrame::pc() const { return _value->pc; } @@ -830,9 +830,11 @@ Result Error::copy_value() const { } Result Error::copy() const { return Error(TRY(_value.copy())); } -Result Error::name() const { return Value::create(_value->name.get()); } +Result Error::name() const { + return Value::create(TRY(MkGcRoot(_value->name.get()))); +} Result Error::message() const { - return Value::create(_value->message.get()); + return Value::create(TRY(MkGcRoot(_value->message.get()))); } Result Error::cmp(const Error& rhs) const { @@ -865,10 +867,11 @@ Result Continuation::copy() const { } Result Continuation::value() const { - return Value::create(_value->value.get()); + return Value::create(TRY(MkGcRoot(_value->value.get()))); } Result Continuation::frame() const { - return StackFrame::create((PodStackFrame*)_value->frame.get()); + return StackFrame( + TRY(MkGcRoot((PodStackFrame*)_value->frame.get()))); } Result Continuation::cmp(const Continuation& rhs) const { @@ -906,7 +909,7 @@ Result Task::name() const { uint64_t Task::task_id() const { return _value->task_id; } Result Task::params() const { - return Array::create((PodArray*)_value->params.get()); + return Array(TRY(MkGcRoot((PodArray*)_value->params.get()))); } Result Task::cmp(const Task& rhs) const { @@ -936,10 +939,10 @@ Result TaskResult::copy() const { } Result TaskResult::result() const { - return Value::create(_value->result.get()); + return Value::create(TRY(MkGcRoot(_value->result.get()))); } Result TaskResult::error() const { - return Value::create(_value->error.get()); + return Value::create(TRY(MkGcRoot(_value->error.get()))); } Result TaskResult::cmp(const TaskResult& rhs) const { @@ -976,7 +979,7 @@ Result Pair::create(const Array& arr) { Result Pair::first() const { auto val = _value->first.get(); - return Value::create(val); + return Value::create(TRY(MkGcRoot(val))); } Result Pair::second() const { return TRY(TRY(rest()).first()); } @@ -986,7 +989,7 @@ Result Pair::third() const { Result Pair::rest() const { auto val = _value->rest.get(); - return Value::create(val); + return Value::create(TRY(MkGcRoot(val))); } Result Pair::size() const { @@ -1046,19 +1049,19 @@ Result Function::create(const Function& prototype, } Result Function::name() const { - return Value::create(_value->name.get()); + return Value::create(TRY(MkGcRoot(_value->name.get()))); } Result Function::code() const { - return Array::create((PodArray*)_value->code.get()); + return Array(TRY(MkGcRoot((PodArray*)_value->code.get()))); } Result Function::constants() const { - return Array::create((PodArray*)_value->constants.get()); + return Array(TRY(MkGcRoot((PodArray*)_value->constants.get()))); } Result Function::closure() const { - return Array::create((PodArray*)_value->closure.get()); + return Array(TRY(MkGcRoot((PodArray*)_value->closure.get()))); } Result Function::disassemble() const { @@ -1138,10 +1141,12 @@ Result Module::create(const Value& name, const Function& fun) { return Module(std::move(pod)); } -Result Module::name() const { return Value::create(_value->name.get()); } +Result Module::name() const { + return Value::create(TRY(MkGcRoot(_value->name.get()))); +} Result Module::fun() const { - return Function::create((PodFunction*)_value->fun.get()); + return Function(TRY(MkGcRoot((PodFunction*)_value->fun.get()))); } Result reverse(Value& val) { @@ -1187,7 +1192,7 @@ Result debug_print(const Value& val) { Result Array::get(uint64_t idx) const { if (idx >= _value->size) return ERROR(IndexOutOfRange); auto val = _value->data[idx].get(); - return Value::create(val); + return Value::create(TRY(MkGcRoot(val))); } Result Array::get(const Value& key) const { @@ -1246,8 +1251,9 @@ Result Dict::create(const Array& arr) { Dict res = TRY(Dict::create()); for (uint64_t i = 0; i < arr_size / 2; i++) { - auto key = TRY(Value::create(arr._value->data[2 * i].get())); - auto value = TRY(Value::create(arr._value->data[2 * i + 1].get())); + auto key = TRY(Value::create(TRY(MkGcRoot(arr._value->data[2 * i].get())))); + auto value = + TRY(Value::create(TRY(MkGcRoot(arr._value->data[2 * i + 1].get())))); res = TRY(res.set(key, value)); } @@ -1260,13 +1266,13 @@ Result Dict::get(const Value& key) const { if (pos >= TRY(size())) { return ERROR(KeyError); } - auto k = TRY(Value::create(_value->data[pos * 2].get())); + auto k = TRY(Value::create(TRY(MkGcRoot(_value->data[pos * 2].get())))); if (TRY(k.cmp(key)) != 0) { return ERROR(KeyError); } - return TRY(Value::create(_value->data[pos * 2 + 1].get())); + return TRY(Value::create(TRY(MkGcRoot(_value->data[pos * 2 + 1].get())))); } Result Dict::set(const Value& key, const Value& value) const { @@ -1276,7 +1282,7 @@ Result Dict::set(const Value& key, const Value& value) const { if (pos >= s) { s += 1; } else { - auto k = TRY(Value::create(_value->data[pos * 2].get())); + auto k = TRY(Value::create(TRY(MkGcRoot(_value->data[pos * 2].get())))); if (TRY(k.cmp(key)) != 0) s += 1; } @@ -1311,7 +1317,7 @@ Result Dict::find(const Value& key) const { uint64_t right = TRY(size()); uint64_t pos = (left + right) / 2; while (left < right) { - auto v = TRY(Value::create(_value->data[pos * 2].get())); + auto v = TRY(Value::create(TRY(MkGcRoot(_value->data[pos * 2].get())))); auto c = TRY(v.cmp(key)); if (c == 0) { return pos; @@ -1447,8 +1453,8 @@ Result Dict::cmp(const Dict& rhs) const { short cmp = short(i == lsize) - short(j == rsize); if (cmp != 0) return cmp; - Value lc = TRY(Value::create(_value->data[i].get())); - Value rc = TRY(Value::create(rhs._value->data[j].get())); + Value lc = TRY(Value::create(TRY(MkGcRoot(_value->data[i].get())))); + Value rc = TRY(Value::create(TRY(MkGcRoot(rhs._value->data[j].get())))); cmp = TRY(lc.cmp(rc)); if (cmp != 0) return cmp; i++; @@ -1468,8 +1474,8 @@ Result Array::cmp(const Array& rhs) const { short cmp = short(i == lsize) - short(j == rsize); if (cmp != 0) return cmp; - Value lc = TRY(Value::create(_value->data[i].get())); - Value rc = TRY(Value::create(rhs._value->data[j].get())); + Value lc = TRY(Value::create(TRY(MkGcRoot(_value->data[i].get())))); + Value rc = TRY(Value::create(TRY(MkGcRoot(rhs._value->data[j].get())))); cmp = TRY(lc.cmp(rc)); if (cmp != 0) return cmp; i++; diff --git a/src/common.hpp b/src/common.hpp index 3694fa9..4a493c9 100644 --- a/src/common.hpp +++ b/src/common.hpp @@ -162,8 +162,6 @@ class Nil : public Object { } virtual Result cmp(const Nil& rhs) const final { return 0; } - static Result create(PodNil* obj) { return Nil(TRY(MkGcRoot(obj))); } - static Result create() { auto pod = TRY(arena_alloc()); @@ -202,10 +200,6 @@ class Array : public Object { virtual void move(Object* obj) final { new (obj) Array(std::move(_value)); } - static Result create(PodArray* obj) { - return Array(TRY(MkGcRoot(obj))); - } - static Result create() { auto pod = TRY(arena_alloc()); @@ -284,9 +278,6 @@ class ByteArray : public Object { new (obj) ByteArray(std::move(_value)); } - static Result create(PodByteArray* obj) { - return ByteArray(TRY(MkGcRoot(obj))); - } static Result create(char* chars, int64_t size) { auto pod = TRY(arena_alloc(size * sizeof(char))); @@ -398,8 +389,6 @@ class Dict : public Object { virtual void move(Object* obj) final { new (obj) Dict(std::move(_value)); } - static Result create(PodDict* obj) { return Dict(TRY(MkGcRoot(obj))); } - static Result create(const Array& arr); static Result create() { @@ -486,9 +475,6 @@ class String : public Object { virtual void move(Object* obj) final { new (obj) String(std::move(_value)); } - static Result create(PodString* obj) { - return String(TRY(MkGcRoot(obj))); - } static Result create(char32_t* chars, int64_t size) { auto pod = TRY(arena_alloc(size * sizeof(char32_t))); @@ -642,10 +628,6 @@ class Symbol : public Object { } virtual void move(Object* obj) final { new (obj) Symbol(std::move(_value)); } - static Result create(PodSymbol* obj) { - return Symbol(TRY(MkGcRoot(obj))); - } - static Result create(char32_t* chars, int64_t size) { auto pod = TRY(arena_alloc(size * sizeof(char32_t))); @@ -694,10 +676,6 @@ class SrcLoc : public Object { virtual void move(Object* obj) final { new (obj) SrcLoc(std::move(_value)); } - static Result create(PodSrcLoc* obj) { - return SrcLoc(TRY(MkGcRoot(obj))); - } - static Result create(const SourcePosition& start, const SourcePosition& end) { auto pod = TRY(arena_alloc()); @@ -737,10 +715,6 @@ class Syntax : public Object { virtual void move(Object* obj) final { new (obj) Syntax(std::move(_value)); } - static Result create(PodSyntax* obj) { - return Syntax(TRY(MkGcRoot(obj))); - } - Result filename() const; Result srcloc() const; Result expression() const; @@ -772,7 +746,6 @@ class Pair : public Object { virtual void move(Object* obj) final { new (obj) Pair(std::move(_value)); } - static Result create(PodPair* obj) { return Pair(TRY(MkGcRoot(obj))); } static Result create(const Value& first, const Value& rest); static Result create(const Array& arr); @@ -828,10 +801,6 @@ class Int64 : public Object { virtual void move(Object* obj) final { new (obj) Int64(std::move(_value)); } - static Result create(PodInt64* obj) { - return Int64(TRY(MkGcRoot(obj))); - } - static Result create(int64_t val) { auto pod = TRY(arena_alloc()); pod->value = val; @@ -884,10 +853,6 @@ class Float : public Object { virtual void move(Object* obj) final { new (obj) Float(std::move(_value)); } - static Result create(PodFloat* obj) { - return Float(TRY(MkGcRoot(obj))); - } - static Result create(double val) { auto pod = TRY(arena_alloc()); pod->value = val; @@ -922,8 +887,6 @@ class Bool : public Object { virtual void move(Object* obj) final { new (obj) Bool(std::move(_value)); } - static Result create(PodBool* obj) { return Bool(TRY(MkGcRoot(obj))); } - static Result create(bool val) { auto pod = TRY(arena_alloc()); pod->value = val; @@ -955,10 +918,6 @@ class Opcode : public Object { virtual void move(Object* obj) final { new (obj) Opcode(std::move(_value)); } - static Result create(PodOpcode* obj) { - return Opcode(TRY(MkGcRoot(obj))); - } - static Result create(Oc opcode, OpArg arg1 = {0, 0}, OpArg arg2 = {0, 0}, OpArg arg3 = {0, 0}, OpArg arg4 = {0, 0}) { @@ -1009,10 +968,6 @@ class Function : public Object { new (obj) Function(std::move(_value)); } - static Result create(PodFunction* obj) { - return Function(TRY(MkGcRoot(obj))); - } - static Result create(const Function& prototype, const Array& closure); @@ -1058,10 +1013,6 @@ class StdlibFunction : public Object { new (obj) StdlibFunction(std::move(_value)); } - static Result create(PodStdlibFunction* obj) { - return StdlibFunction(TRY(MkGcRoot(obj))); - } - static Result create(StdlibFunctionId fun_id); Result name() const; @@ -1094,10 +1045,6 @@ class Module : public Object { virtual void move(Object* obj) final { new (obj) Module(std::move(_value)); } - static Result create(PodModule* obj) { - return Module(TRY(MkGcRoot(obj))); - } - static Result create(const Value& name, const Function& fun); Result name() const; @@ -1132,10 +1079,6 @@ class StackFrame : public Object { new (obj) StackFrame(std::move(_value)); } - static Result create(PodStackFrame* obj) { - return StackFrame(TRY(MkGcRoot(obj))); - } - using Object::get; Result get(uint64_t idx) const; Result set(uint64_t idx, const Value& val) const; @@ -1201,10 +1144,6 @@ class Error : public Object { virtual void move(Object* obj) final { new (obj) Error(std::move(_value)); } - static Result create(PodError* obj) { - return Error(TRY(MkGcRoot(obj))); - } - static Result create(const char* name, const char* message) { auto name_str = TRY(Symbol::create(name)); auto message_str = TRY(String::create(message)); @@ -1253,10 +1192,6 @@ class Continuation : public Object { new (obj) Continuation(std::move(_value)); } - static Result create(PodContinuation* obj) { - return Continuation(TRY(MkGcRoot(obj))); - } - static Result create(const Value& value, const StackFrame& frame); @@ -1285,8 +1220,6 @@ class Task : public Object { virtual void move(Object* obj) final { new (obj) Task(std::move(_value)); } - static Result create(PodTask* obj) { return Task(TRY(MkGcRoot(obj))); } - static Result create(uint64_t task_id, const Array& params); Result name() const; @@ -1317,10 +1250,6 @@ class TaskResult : public Object { new (obj) TaskResult(std::move(_value)); } - static Result create(PodTaskResult* obj) { - return TaskResult(TRY(MkGcRoot(obj))); - } - static Result create(const Value& result, const Value& error); Result result() const; @@ -1358,7 +1287,7 @@ class Value { return *this; } - static Result create(PodObject* obj); + static Result create(GcRootBase&& obj); static Result create(const int64_t& value) { return Value(TRY(Int64::create(value))); diff --git a/src/serialize.cpp b/src/serialize.cpp index 0c7f6db..042e1c4 100644 --- a/src/serialize.cpp +++ b/src/serialize.cpp @@ -391,5 +391,5 @@ Result deserialize(const ByteArray& val) { auto obj = TRY(arena_alloc_bytes(size)); memcpy(obj.get(), decompressed.raw_bytes(), size); - return TRY(Value::create(obj.get())); + return TRY(Value::create(std::move(obj))); } diff --git a/src/writer.cpp b/src/writer.cpp index e3b787a..463df26 100644 --- a/src/writer.cpp +++ b/src/writer.cpp @@ -272,8 +272,9 @@ Result Writer::write_dict(const Dict& val) { bool is_first = true; auto size = TRY(val.size()); for (uint64_t i = 0; i < size; i++) { - Value k = TRY(Value::create(val._value->data[i * 2].get())); - Value v = TRY(Value::create(val._value->data[i * 2 + 1].get())); + Value k = TRY(Value::create(TRY(MkGcRoot(val._value->data[i * 2].get())))); + Value v = + TRY(Value::create(TRY(MkGcRoot(val._value->data[i * 2 + 1].get())))); if (!is_first) res = TRY(res.concat(" "));