Simplify the handling of OffPtr

This commit is contained in:
Konstantin Nazarov 2024-08-06 20:32:55 +01:00
parent 92f546107e
commit b40f835bfb
Signed by: knazarov
GPG key ID: 4CFE0A42FA409C22
5 changed files with 63 additions and 50 deletions

View file

@ -133,14 +133,14 @@ Result<PodObject*> Arena::gc_pair(PodPair* obj) {
nobj->header.tag = Tag::Pair;
PodObject* first = obj->first.get(obj);
PodObject* rest = obj->rest.get(obj);
PodObject* first = obj->first.get();
PodObject* rest = obj->rest.get();
first = TRY(gc_pod(first));
rest = TRY(gc_pod(rest));
nobj->first = OffPtr<PodObject>(nobj, first);
nobj->rest = OffPtr<PodObject>(nobj, rest);
nobj->first = first;
nobj->rest = rest;
return nobj;
}
@ -150,8 +150,8 @@ Result<PodObject*> Arena::gc_array(PodArray* obj) {
nobj->header.tag = Tag::Array;
nobj->size = obj->size;
for (uint64_t i = 0; i < obj->size; i++) {
PodObject* val = obj->data[i].get(obj);
nobj->data[i] = OffPtr<PodObject>(nobj, TRY(gc_pod(val)));
PodObject* val = obj->data[i].get();
nobj->data[i] = TRY(gc_pod(val));
}
return nobj;
}
@ -169,8 +169,8 @@ Result<PodObject*> Arena::gc_dict(PodDict* obj) {
nobj->header.tag = Tag::Dict;
nobj->size = obj->size;
for (uint64_t i = 0; i < obj->size * 2; i++) {
PodObject* val = obj->data[i].get(obj);
nobj->data[i] = OffPtr<PodObject>(nobj, TRY(gc_pod(val)));
PodObject* val = obj->data[i].get();
nobj->data[i] = TRY(gc_pod(val));
}
return nobj;
// return ErrorCode::NotImplemented;

View file

@ -9,7 +9,7 @@
Syntax::Syntax(String filename, String modulename, Value expression) {}
Result<Value> Syntax::get_value(Arena& arena) {
return Value::create(arena, _value->expression.get(&*_value));
return Value::create(arena, _value->expression.get());
}
Result<Value> Value::create(Arena& arena, PodObject* obj) {
@ -122,18 +122,18 @@ Result<Value> Bool::copy(Arena& arena) const {
Result<Pair> Pair::create(Arena& arena, Value& first, Value& rest) {
auto pod = TRY(arena.alloc<PodPair>());
pod->header.tag = Tag::Pair;
pod->first = OffPtr<PodObject>(pod, first.pod());
pod->rest = OffPtr<PodObject>(pod, rest.pod());
pod->first = first.pod();
pod->rest = rest.pod();
return Pair(TRY(MkGcRoot(pod, arena)));
}
Result<Value> Pair::first(Arena& arena) {
auto val = _value->first.get(pod());
auto val = _value->first.get();
return Value::create(arena, val);
}
Result<Value> Pair::rest(Arena& arena) {
auto val = _value->rest.get(pod());
auto val = _value->rest.get();
return Value::create(arena, val);
}
@ -172,7 +172,7 @@ Result<void> debug_print(Arena& arena, Value& val) {
Result<Value> Array::get(Arena& arena, uint64_t idx) {
if (idx >= _value->size) return ErrorCode::IndexOutOfRange;
auto val = _value->data[idx].get(pod());
auto val = _value->data[idx].get();
return Value::create(arena, val);
}
@ -188,9 +188,9 @@ Result<Array> Array::append(Arena& arena, Value& rhs) {
pod->header.tag = Tag::Array;
pod->size = res_size;
for (uint64_t i = 0; i < size(); i++) {
pod->data[i] = OffPtr<PodObject>(pod, _value->data[i].get(_value.get()));
pod->data[i] = _value->data[i].get();
}
pod->data[size()] = OffPtr<PodObject>(pod, rhs.pod());
pod->data[size()] = rhs.pod();
return Array(TRY(MkGcRoot(pod, arena)));
}
@ -204,13 +204,13 @@ short cmp_tag(Tag lhs, Tag rhs) {
Result<Value> Dict::get(Arena& arena, Value& key) {
auto pos = TRY(find(arena, key));
if (pos > size()) return ErrorCode::KeyError;
auto k = TRY(Value::create(arena, _value->data[pos * 2].get(_value.get())));
auto k = TRY(Value::create(arena, _value->data[pos * 2].get()));
if (TRY(k.cmp(arena, key)) != 0) {
return ErrorCode::KeyError;
}
return TRY(Value::create(arena, _value->data[pos * 2 + 1].get(_value.get())));
return TRY(Value::create(arena, _value->data[pos * 2 + 1].get()));
}
Result<Dict> Dict::insert(Arena& arena, Value& key, Value& value) {
@ -219,7 +219,7 @@ Result<Dict> Dict::insert(Arena& arena, Value& key, Value& value) {
if (pos >= s) {
s += 1;
} else {
auto k = TRY(Value::create(arena, _value->data[pos * 2].get(_value.get())));
auto k = TRY(Value::create(arena, _value->data[pos * 2].get()));
if (TRY(k.cmp(arena, key)) != 0) s += 1;
}
@ -230,19 +230,16 @@ Result<Dict> Dict::insert(Arena& arena, Value& key, Value& value) {
auto vpod = _value.get();
for (uint64_t i = 0, j = 0; i < s; i++, j++) {
if (i == pos) {
pod->data[i * 2] = OffPtr<PodObject>(pod, key.pod());
pod->data[i * 2 + 1] = OffPtr<PodObject>(pod, value.pod());
pod->data[i * 2] = key.pod();
pod->data[i * 2 + 1] = value.pod();
if (s > size() && i < s - 1) {
i++;
pod->data[i * 2] =
OffPtr<PodObject>(pod, _value->data[j * 2].get(vpod));
pod->data[i * 2 + 1] =
OffPtr<PodObject>(pod, _value->data[j * 2 + 1].get(vpod));
pod->data[i * 2] = _value->data[j * 2].get();
pod->data[i * 2 + 1] = _value->data[j * 2 + 1].get();
}
} else {
pod->data[i * 2] = OffPtr<PodObject>(pod, _value->data[j * 2].get(vpod));
pod->data[i * 2 + 1] =
OffPtr<PodObject>(pod, _value->data[j * 2 + 1].get(vpod));
pod->data[i * 2] = _value->data[j * 2].get();
pod->data[i * 2 + 1] = _value->data[j * 2 + 1].get();
}
}
@ -254,7 +251,7 @@ Result<uint64_t> Dict::find(Arena& arena, Value& key) {
uint64_t right = size();
uint64_t pos = (left + right) / 2;
while (left < right) {
auto v = TRY(Value::create(arena, _value->data[pos * 2].get(_value.get())));
auto v = TRY(Value::create(arena, _value->data[pos * 2].get()));
auto c = TRY(v.cmp(arena, key));
if (c == 0) {
return pos;
@ -291,9 +288,8 @@ Result<short> Dict::cmp(Arena& arena, Dict& rhs) {
short cmp = short(i == lsize) - short(j == rsize);
if (cmp != 0) return cmp;
Value lc = TRY(Value::create(arena, _value->data[i].get(_value.get())));
Value rc =
TRY(Value::create(arena, rhs._value->data[j].get(rhs._value.get())));
Value lc = TRY(Value::create(arena, _value->data[i].get()));
Value rc = TRY(Value::create(arena, rhs._value->data[j].get()));
cmp = TRY(lc.cmp(arena, rc));
if (cmp != 0) return cmp;
i++;

View file

@ -150,8 +150,12 @@ class Array : public Object {
auto pod = TRY(arena.alloc<PodArray>(res_size * sizeof(PodObject*)));
pod->size = res_size;
memcpy(pod->data, _value->data, sizeof(PodObject*) * lhs_size);
memcpy(pod->data + lhs_size, rhs._value->data, sizeof(char) * rhs_size);
for (uint64_t i = 0; i < size(); i++) {
pod->data[i] = _value->data[i];
}
for (uint64_t i = size(); i < rhs.size(); i++) {
pod->data[i] = rhs._value->data[i];
}
return Array(TRY(MkGcRoot(pod, arena)));
}
@ -161,7 +165,9 @@ class Array : public Object {
uint64_t res_size = end - start;
auto pod = TRY(arena.alloc<PodArray>(res_size * sizeof(PodObject*)));
pod->size = res_size;
memcpy(pod->data, _value->data + start, sizeof(PodObject*) * res_size);
for (uint64_t i = 0; i < end - start; i++) {
pod->data[i] = _value->data[start + i];
}
return Array(TRY(MkGcRoot(pod, arena)));
}
@ -326,10 +332,15 @@ class Dict : public Object {
uint64_t lhs_size = size();
uint64_t res_size = lhs_size + rhs_size;
auto pod = TRY(arena.alloc<PodDict>(res_size * sizeof(PodObject*)));
auto pod = TRY(arena.alloc<PodDict>(2 * res_size * sizeof(PodObject*)));
pod->size = res_size;
memcpy(pod->data, _value->data, sizeof(PodObject*) * lhs_size);
memcpy(pod->data + lhs_size, rhs._value->data, sizeof(char) * rhs_size);
for (uint64_t i = 0; i < 2 * size(); i++) {
pod->data[i] = _value->data[i];
}
for (uint64_t i = 2 * size(); i < 2 * rhs.size(); i++) {
pod->data[i] = rhs._value->data[i];
}
return Dict(TRY(MkGcRoot(pod, arena)));
}

View file

@ -24,13 +24,21 @@ class OffPtr {
public:
OffPtr() : _offset(0) {}
template <class R>
OffPtr(R* base, T* ptr)
: _offset((ptr == 0) ? 0 : (uint8_t*)ptr - (uint8_t*)base){};
OffPtr(T* ptr) : _offset((ptr == 0) ? 0 : (uint8_t*)ptr - (uint8_t*)this){};
template <class R>
T* get(R* base) {
T* get() const {
if (_offset == 0) return 0;
return (T*)(((uint8_t*)base) + _offset);
return (T*)(((uint8_t*)this) + _offset);
}
OffPtr<T>& operator=(const OffPtr<T>& rhs) {
_offset = (uint8_t*)rhs.get() - (uint8_t*)this;
return *this;
}
OffPtr<T>& operator=(T* rhs) {
_offset = (uint8_t*)rhs - (uint8_t*)this;
return *this;
}
private:
@ -40,9 +48,10 @@ class OffPtr {
static_assert(sizeof(OffPtr<void>) == 8);
struct PodHeader {
PodHeader(Tag tag) : tag(tag), forward(0) {}
PodHeader(Tag tag) : tag(tag), stat(0), forward(0) {}
Tag tag;
int64_t forward : 56;
unsigned stat : 1;
int64_t forward : 55;
};
static_assert(sizeof(PodHeader) == 8);

View file

@ -194,11 +194,8 @@ Result<String> Writer::write_dict(Dict& val) {
bool is_first = true;
for (uint64_t i = 0; i < val.size(); i++) {
Value k = TRY(
Value::create(_arena, val._value->data[i * 2].get(val._value.get())));
Value v = TRY(Value::create(
_arena, val._value->data[i * 2 + 1].get(val._value.get())));
Value k = TRY(Value::create(_arena, val._value->data[i * 2].get()));
Value v = TRY(Value::create(_arena, val._value->data[i * 2 + 1].get()));
if (!is_first) res = TRY(res.concat(_arena, " "));