Get rid of more raw pointer passing

This commit is contained in:
Konstantin Nazarov 2024-11-30 01:39:50 +00:00
parent 4d406a11f7
commit 02d1d51383
Signed by: knazarov
GPG key ID: 4CFE0A42FA409C22
5 changed files with 81 additions and 129 deletions

View file

@ -20,6 +20,10 @@ static uint64_t round_up(uint64_t number, uint64_t to) {
return ((number + to - 1) / to) * to;
}
template <class T>
requires std::derived_from<T, PodObject>
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 <class T>
GcRoot<T>&& move_as() &&;
protected:
PodObject* _ptr;
GcRootList* _node;
@ -59,6 +70,11 @@ Result<GcRoot<T>> MkGcRoot(T* ptr) {
return GcRoot<T>::create(ptr);
}
template <class T>
GcRoot<T>&& GcRootBase::move_as() && {
return (GcRoot<T>&&)std::move(*this);
}
class GcRootList {
public:
friend class Arena;

View file

@ -8,50 +8,50 @@
#include "utf8.hpp"
#include "writer.hpp"
Result<Value> Value::create(PodObject* obj) {
Result<Value> 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<PodNil>()));
case Tag::Int64:
return Value(TRY(Int64::create((PodInt64*)obj)));
return Value(Int64(std::move(obj).move_as<PodInt64>()));
case Tag::Float:
return Value(TRY(Float::create((PodFloat*)obj)));
return Value(Float(std::move(obj).move_as<PodFloat>()));
case Tag::Bool:
return Value(TRY(Bool::create((PodBool*)obj)));
return Value(Bool(std::move(obj).move_as<PodBool>()));
case Tag::Array:
return Value(TRY(Array::create((PodArray*)obj)));
return Value(Array(std::move(obj).move_as<PodArray>()));
case Tag::ByteArray:
return Value(TRY(ByteArray::create((PodByteArray*)obj)));
return Value(ByteArray(std::move(obj).move_as<PodByteArray>()));
case Tag::Dict:
return Value(TRY(Dict::create((PodDict*)obj)));
return Value(Dict(std::move(obj).move_as<PodDict>()));
case Tag::String:
return Value(TRY(String::create((PodString*)obj)));
return Value(String(std::move(obj).move_as<PodString>()));
case Tag::Symbol:
return Value(TRY(Symbol::create((PodSymbol*)obj)));
return Value(Symbol(std::move(obj).move_as<PodSymbol>()));
case Tag::SrcLoc:
return Value(TRY(SrcLoc::create((PodSrcLoc*)obj)));
return Value(SrcLoc(std::move(obj).move_as<PodSrcLoc>()));
case Tag::Syntax:
return Value(TRY(Syntax::create((PodSyntax*)obj)));
return Value(Syntax(std::move(obj).move_as<PodSyntax>()));
case Tag::Pair:
return Value(TRY(Pair::create((PodPair*)obj)));
return Value(Pair(std::move(obj).move_as<PodPair>()));
case Tag::Opcode:
return Value(TRY(Opcode::create((PodOpcode*)obj)));
return Value(Opcode(std::move(obj).move_as<PodOpcode>()));
case Tag::Function:
return Value(TRY(Function::create((PodFunction*)obj)));
return Value(Function(std::move(obj).move_as<PodFunction>()));
case Tag::StdlibFunction:
return Value(TRY(StdlibFunction::create((PodStdlibFunction*)obj)));
return Value(StdlibFunction(std::move(obj).move_as<PodStdlibFunction>()));
case Tag::Module:
return Value(TRY(Module::create((PodModule*)obj)));
return Value(Module(std::move(obj).move_as<PodModule>()));
case Tag::StackFrame:
return Value(TRY(StackFrame::create((PodStackFrame*)obj)));
return Value(StackFrame(std::move(obj).move_as<PodStackFrame>()));
case Tag::Error:
return Value(TRY(Error::create((PodError*)obj)));
return Value(Error(std::move(obj).move_as<PodError>()));
case Tag::Continuation:
return Value(TRY(Continuation::create((PodContinuation*)obj)));
return Value(Continuation(std::move(obj).move_as<PodContinuation>()));
case Tag::Task:
return Value(TRY(Task::create((PodTask*)obj)));
return Value(Task(std::move(obj).move_as<PodTask>()));
case Tag::TaskResult:
return Value(TRY(TaskResult::create((PodTaskResult*)obj)));
return Value(TaskResult(std::move(obj).move_as<PodTaskResult>()));
};
return Value();
}
@ -245,15 +245,15 @@ Result<Syntax> Syntax::create(const String& filename,
}
Result<Value> Syntax::filename() const {
return Value::create(_value->filename.get());
return Value::create(TRY(MkGcRoot(_value->filename.get())));
}
Result<Value> Syntax::srcloc() const {
return Value::create(_value->srcloc.get());
return Value::create(TRY(MkGcRoot(_value->srcloc.get())));
}
Result<Value> Syntax::expression() const {
return Value::create(_value->expression.get());
return Value::create(TRY(MkGcRoot(_value->expression.get())));
}
Result<short> Syntax::cmp(const Syntax& rhs) const {
@ -509,7 +509,7 @@ Result<StackFrame> StackFrame::copy() const {
Result<Value> 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> StackFrame::set(uint64_t idx, const Value& val) const {
@ -561,10 +561,10 @@ Result<StackFrame> StackFrame::settop(uint64_t idx) const {
}
Result<Value> StackFrame::parent() const {
return Value::create(_value->parent.get());
return Value::create(TRY(MkGcRoot(_value->parent.get())));
}
Result<Value> 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<Value> Error::copy_value() const {
}
Result<Error> Error::copy() const { return Error(TRY(_value.copy())); }
Result<Value> Error::name() const { return Value::create(_value->name.get()); }
Result<Value> Error::name() const {
return Value::create(TRY(MkGcRoot(_value->name.get())));
}
Result<Value> Error::message() const {
return Value::create(_value->message.get());
return Value::create(TRY(MkGcRoot(_value->message.get())));
}
Result<short> Error::cmp(const Error& rhs) const {
@ -865,10 +867,11 @@ Result<Continuation> Continuation::copy() const {
}
Result<Value> Continuation::value() const {
return Value::create(_value->value.get());
return Value::create(TRY(MkGcRoot(_value->value.get())));
}
Result<StackFrame> Continuation::frame() const {
return StackFrame::create((PodStackFrame*)_value->frame.get());
return StackFrame(
TRY(MkGcRoot<PodStackFrame>((PodStackFrame*)_value->frame.get())));
}
Result<short> Continuation::cmp(const Continuation& rhs) const {
@ -906,7 +909,7 @@ Result<Symbol> Task::name() const {
uint64_t Task::task_id() const { return _value->task_id; }
Result<Array> Task::params() const {
return Array::create((PodArray*)_value->params.get());
return Array(TRY(MkGcRoot((PodArray*)_value->params.get())));
}
Result<short> Task::cmp(const Task& rhs) const {
@ -936,10 +939,10 @@ Result<TaskResult> TaskResult::copy() const {
}
Result<Value> TaskResult::result() const {
return Value::create(_value->result.get());
return Value::create(TRY(MkGcRoot(_value->result.get())));
}
Result<Value> TaskResult::error() const {
return Value::create(_value->error.get());
return Value::create(TRY(MkGcRoot(_value->error.get())));
}
Result<short> TaskResult::cmp(const TaskResult& rhs) const {
@ -976,7 +979,7 @@ Result<Pair> Pair::create(const Array& arr) {
Result<Value> Pair::first() const {
auto val = _value->first.get();
return Value::create(val);
return Value::create(TRY(MkGcRoot(val)));
}
Result<Value> Pair::second() const { return TRY(TRY(rest()).first()); }
@ -986,7 +989,7 @@ Result<Value> Pair::third() const {
Result<Value> Pair::rest() const {
auto val = _value->rest.get();
return Value::create(val);
return Value::create(TRY(MkGcRoot(val)));
}
Result<uint64_t> Pair::size() const {
@ -1046,19 +1049,19 @@ Result<Function> Function::create(const Function& prototype,
}
Result<Value> Function::name() const {
return Value::create(_value->name.get());
return Value::create(TRY(MkGcRoot(_value->name.get())));
}
Result<Array> Function::code() const {
return Array::create((PodArray*)_value->code.get());
return Array(TRY(MkGcRoot((PodArray*)_value->code.get())));
}
Result<Array> Function::constants() const {
return Array::create((PodArray*)_value->constants.get());
return Array(TRY(MkGcRoot((PodArray*)_value->constants.get())));
}
Result<Array> Function::closure() const {
return Array::create((PodArray*)_value->closure.get());
return Array(TRY(MkGcRoot((PodArray*)_value->closure.get())));
}
Result<String> Function::disassemble() const {
@ -1138,10 +1141,12 @@ Result<Module> Module::create(const Value& name, const Function& fun) {
return Module(std::move(pod));
}
Result<Value> Module::name() const { return Value::create(_value->name.get()); }
Result<Value> Module::name() const {
return Value::create(TRY(MkGcRoot(_value->name.get())));
}
Result<Function> Module::fun() const {
return Function::create((PodFunction*)_value->fun.get());
return Function(TRY(MkGcRoot((PodFunction*)_value->fun.get())));
}
Result<Value> reverse(Value& val) {
@ -1187,7 +1192,7 @@ Result<void> debug_print(const Value& val) {
Result<Value> 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<Value> Array::get(const Value& key) const {
@ -1246,8 +1251,9 @@ Result<Dict> 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<Value> 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> Dict::set(const Value& key, const Value& value) const {
@ -1276,7 +1282,7 @@ Result<Dict> 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<uint64_t> 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<short> 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<short> 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++;

View file

@ -162,8 +162,6 @@ class Nil : public Object {
}
virtual Result<short> cmp(const Nil& rhs) const final { return 0; }
static Result<Nil> create(PodNil* obj) { return Nil(TRY(MkGcRoot(obj))); }
static Result<Nil> create() {
auto pod = TRY(arena_alloc<PodNil>());
@ -202,10 +200,6 @@ class Array : public Object {
virtual void move(Object* obj) final { new (obj) Array(std::move(_value)); }
static Result<Array> create(PodArray* obj) {
return Array(TRY(MkGcRoot(obj)));
}
static Result<Array> create() {
auto pod = TRY(arena_alloc<PodArray>());
@ -284,9 +278,6 @@ class ByteArray : public Object {
new (obj) ByteArray(std::move(_value));
}
static Result<ByteArray> create(PodByteArray* obj) {
return ByteArray(TRY(MkGcRoot(obj)));
}
static Result<ByteArray> create(char* chars, int64_t size) {
auto pod = TRY(arena_alloc<PodByteArray>(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<Dict> create(PodDict* obj) { return Dict(TRY(MkGcRoot(obj))); }
static Result<Dict> create(const Array& arr);
static Result<Dict> create() {
@ -486,9 +475,6 @@ class String : public Object {
virtual void move(Object* obj) final { new (obj) String(std::move(_value)); }
static Result<String> create(PodString* obj) {
return String(TRY(MkGcRoot(obj)));
}
static Result<String> create(char32_t* chars, int64_t size) {
auto pod = TRY(arena_alloc<PodString>(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<Symbol> create(PodSymbol* obj) {
return Symbol(TRY(MkGcRoot(obj)));
}
static Result<Symbol> create(char32_t* chars, int64_t size) {
auto pod = TRY(arena_alloc<PodSymbol>(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<SrcLoc> create(PodSrcLoc* obj) {
return SrcLoc(TRY(MkGcRoot(obj)));
}
static Result<SrcLoc> create(const SourcePosition& start,
const SourcePosition& end) {
auto pod = TRY(arena_alloc<PodSrcLoc>());
@ -737,10 +715,6 @@ class Syntax : public Object {
virtual void move(Object* obj) final { new (obj) Syntax(std::move(_value)); }
static Result<Syntax> create(PodSyntax* obj) {
return Syntax(TRY(MkGcRoot(obj)));
}
Result<Value> filename() const;
Result<Value> srcloc() const;
Result<Value> expression() const;
@ -772,7 +746,6 @@ class Pair : public Object {
virtual void move(Object* obj) final { new (obj) Pair(std::move(_value)); }
static Result<Pair> create(PodPair* obj) { return Pair(TRY(MkGcRoot(obj))); }
static Result<Pair> create(const Value& first, const Value& rest);
static Result<Pair> 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<Int64> create(PodInt64* obj) {
return Int64(TRY(MkGcRoot(obj)));
}
static Result<Int64> create(int64_t val) {
auto pod = TRY(arena_alloc<PodInt64>());
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<Float> create(PodFloat* obj) {
return Float(TRY(MkGcRoot(obj)));
}
static Result<Float> create(double val) {
auto pod = TRY(arena_alloc<PodFloat>());
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<Bool> create(PodBool* obj) { return Bool(TRY(MkGcRoot(obj))); }
static Result<Bool> create(bool val) {
auto pod = TRY(arena_alloc<PodBool>());
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<Opcode> create(PodOpcode* obj) {
return Opcode(TRY(MkGcRoot(obj)));
}
static Result<Opcode> 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<Function> create(PodFunction* obj) {
return Function(TRY(MkGcRoot(obj)));
}
static Result<Function> create(const Function& prototype,
const Array& closure);
@ -1058,10 +1013,6 @@ class StdlibFunction : public Object {
new (obj) StdlibFunction(std::move(_value));
}
static Result<StdlibFunction> create(PodStdlibFunction* obj) {
return StdlibFunction(TRY(MkGcRoot(obj)));
}
static Result<StdlibFunction> create(StdlibFunctionId fun_id);
Result<Symbol> name() const;
@ -1094,10 +1045,6 @@ class Module : public Object {
virtual void move(Object* obj) final { new (obj) Module(std::move(_value)); }
static Result<Module> create(PodModule* obj) {
return Module(TRY(MkGcRoot(obj)));
}
static Result<Module> create(const Value& name, const Function& fun);
Result<Value> name() const;
@ -1132,10 +1079,6 @@ class StackFrame : public Object {
new (obj) StackFrame(std::move(_value));
}
static Result<StackFrame> create(PodStackFrame* obj) {
return StackFrame(TRY(MkGcRoot(obj)));
}
using Object::get;
Result<Value> get(uint64_t idx) const;
Result<StackFrame> 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<Error> create(PodError* obj) {
return Error(TRY(MkGcRoot(obj)));
}
static Result<Error> 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<Continuation> create(PodContinuation* obj) {
return Continuation(TRY(MkGcRoot(obj)));
}
static Result<Continuation> 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<Task> create(PodTask* obj) { return Task(TRY(MkGcRoot(obj))); }
static Result<Task> create(uint64_t task_id, const Array& params);
Result<Symbol> name() const;
@ -1317,10 +1250,6 @@ class TaskResult : public Object {
new (obj) TaskResult(std::move(_value));
}
static Result<TaskResult> create(PodTaskResult* obj) {
return TaskResult(TRY(MkGcRoot(obj)));
}
static Result<TaskResult> create(const Value& result, const Value& error);
Result<Value> result() const;
@ -1358,7 +1287,7 @@ class Value {
return *this;
}
static Result<Value> create(PodObject* obj);
static Result<Value> create(GcRootBase&& obj);
static Result<Value> create(const int64_t& value) {
return Value(TRY(Int64::create(value)));

View file

@ -391,5 +391,5 @@ Result<Value> deserialize(const ByteArray& val) {
auto obj = TRY(arena_alloc_bytes<PodObject>(size));
memcpy(obj.get(), decompressed.raw_bytes(), size);
return TRY(Value::create(obj.get()));
return TRY(Value::create(std::move(obj)));
}

View file

@ -272,8 +272,9 @@ Result<String> 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(" "));