Simplify the handling of OffPtr
This commit is contained in:
parent
92f546107e
commit
b40f835bfb
5 changed files with 63 additions and 50 deletions
|
@ -133,14 +133,14 @@ Result<PodObject*> Arena::gc_pair(PodPair* obj) {
|
||||||
|
|
||||||
nobj->header.tag = Tag::Pair;
|
nobj->header.tag = Tag::Pair;
|
||||||
|
|
||||||
PodObject* first = obj->first.get(obj);
|
PodObject* first = obj->first.get();
|
||||||
PodObject* rest = obj->rest.get(obj);
|
PodObject* rest = obj->rest.get();
|
||||||
|
|
||||||
first = TRY(gc_pod(first));
|
first = TRY(gc_pod(first));
|
||||||
rest = TRY(gc_pod(rest));
|
rest = TRY(gc_pod(rest));
|
||||||
|
|
||||||
nobj->first = OffPtr<PodObject>(nobj, first);
|
nobj->first = first;
|
||||||
nobj->rest = OffPtr<PodObject>(nobj, rest);
|
nobj->rest = rest;
|
||||||
|
|
||||||
return nobj;
|
return nobj;
|
||||||
}
|
}
|
||||||
|
@ -150,8 +150,8 @@ Result<PodObject*> Arena::gc_array(PodArray* obj) {
|
||||||
nobj->header.tag = Tag::Array;
|
nobj->header.tag = Tag::Array;
|
||||||
nobj->size = obj->size;
|
nobj->size = obj->size;
|
||||||
for (uint64_t i = 0; i < obj->size; i++) {
|
for (uint64_t i = 0; i < obj->size; i++) {
|
||||||
PodObject* val = obj->data[i].get(obj);
|
PodObject* val = obj->data[i].get();
|
||||||
nobj->data[i] = OffPtr<PodObject>(nobj, TRY(gc_pod(val)));
|
nobj->data[i] = TRY(gc_pod(val));
|
||||||
}
|
}
|
||||||
return nobj;
|
return nobj;
|
||||||
}
|
}
|
||||||
|
@ -169,8 +169,8 @@ Result<PodObject*> Arena::gc_dict(PodDict* obj) {
|
||||||
nobj->header.tag = Tag::Dict;
|
nobj->header.tag = Tag::Dict;
|
||||||
nobj->size = obj->size;
|
nobj->size = obj->size;
|
||||||
for (uint64_t i = 0; i < obj->size * 2; i++) {
|
for (uint64_t i = 0; i < obj->size * 2; i++) {
|
||||||
PodObject* val = obj->data[i].get(obj);
|
PodObject* val = obj->data[i].get();
|
||||||
nobj->data[i] = OffPtr<PodObject>(nobj, TRY(gc_pod(val)));
|
nobj->data[i] = TRY(gc_pod(val));
|
||||||
}
|
}
|
||||||
return nobj;
|
return nobj;
|
||||||
// return ErrorCode::NotImplemented;
|
// return ErrorCode::NotImplemented;
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
Syntax::Syntax(String filename, String modulename, Value expression) {}
|
Syntax::Syntax(String filename, String modulename, Value expression) {}
|
||||||
|
|
||||||
Result<Value> Syntax::get_value(Arena& arena) {
|
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) {
|
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) {
|
Result<Pair> Pair::create(Arena& arena, Value& first, Value& rest) {
|
||||||
auto pod = TRY(arena.alloc<PodPair>());
|
auto pod = TRY(arena.alloc<PodPair>());
|
||||||
pod->header.tag = Tag::Pair;
|
pod->header.tag = Tag::Pair;
|
||||||
pod->first = OffPtr<PodObject>(pod, first.pod());
|
pod->first = first.pod();
|
||||||
pod->rest = OffPtr<PodObject>(pod, rest.pod());
|
pod->rest = rest.pod();
|
||||||
|
|
||||||
return Pair(TRY(MkGcRoot(pod, arena)));
|
return Pair(TRY(MkGcRoot(pod, arena)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<Value> Pair::first(Arena& arena) {
|
Result<Value> Pair::first(Arena& arena) {
|
||||||
auto val = _value->first.get(pod());
|
auto val = _value->first.get();
|
||||||
return Value::create(arena, val);
|
return Value::create(arena, val);
|
||||||
}
|
}
|
||||||
Result<Value> Pair::rest(Arena& arena) {
|
Result<Value> Pair::rest(Arena& arena) {
|
||||||
auto val = _value->rest.get(pod());
|
auto val = _value->rest.get();
|
||||||
return Value::create(arena, val);
|
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) {
|
Result<Value> Array::get(Arena& arena, uint64_t idx) {
|
||||||
if (idx >= _value->size) return ErrorCode::IndexOutOfRange;
|
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);
|
return Value::create(arena, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,9 +188,9 @@ Result<Array> Array::append(Arena& arena, Value& rhs) {
|
||||||
pod->header.tag = Tag::Array;
|
pod->header.tag = Tag::Array;
|
||||||
pod->size = res_size;
|
pod->size = res_size;
|
||||||
for (uint64_t i = 0; i < size(); i++) {
|
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)));
|
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) {
|
Result<Value> Dict::get(Arena& arena, Value& key) {
|
||||||
auto pos = TRY(find(arena, key));
|
auto pos = TRY(find(arena, key));
|
||||||
if (pos > size()) return ErrorCode::KeyError;
|
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) {
|
if (TRY(k.cmp(arena, key)) != 0) {
|
||||||
return ErrorCode::KeyError;
|
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) {
|
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) {
|
if (pos >= s) {
|
||||||
s += 1;
|
s += 1;
|
||||||
} else {
|
} 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;
|
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();
|
auto vpod = _value.get();
|
||||||
for (uint64_t i = 0, j = 0; i < s; i++, j++) {
|
for (uint64_t i = 0, j = 0; i < s; i++, j++) {
|
||||||
if (i == pos) {
|
if (i == pos) {
|
||||||
pod->data[i * 2] = OffPtr<PodObject>(pod, key.pod());
|
pod->data[i * 2] = key.pod();
|
||||||
pod->data[i * 2 + 1] = OffPtr<PodObject>(pod, value.pod());
|
pod->data[i * 2 + 1] = value.pod();
|
||||||
if (s > size() && i < s - 1) {
|
if (s > size() && i < s - 1) {
|
||||||
i++;
|
i++;
|
||||||
pod->data[i * 2] =
|
pod->data[i * 2] = _value->data[j * 2].get();
|
||||||
OffPtr<PodObject>(pod, _value->data[j * 2].get(vpod));
|
pod->data[i * 2 + 1] = _value->data[j * 2 + 1].get();
|
||||||
pod->data[i * 2 + 1] =
|
|
||||||
OffPtr<PodObject>(pod, _value->data[j * 2 + 1].get(vpod));
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
pod->data[i * 2] = OffPtr<PodObject>(pod, _value->data[j * 2].get(vpod));
|
pod->data[i * 2] = _value->data[j * 2].get();
|
||||||
pod->data[i * 2 + 1] =
|
pod->data[i * 2 + 1] = _value->data[j * 2 + 1].get();
|
||||||
OffPtr<PodObject>(pod, _value->data[j * 2 + 1].get(vpod));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -254,7 +251,7 @@ Result<uint64_t> Dict::find(Arena& arena, Value& key) {
|
||||||
uint64_t right = size();
|
uint64_t right = size();
|
||||||
uint64_t pos = (left + right) / 2;
|
uint64_t pos = (left + right) / 2;
|
||||||
while (left < right) {
|
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));
|
auto c = TRY(v.cmp(arena, key));
|
||||||
if (c == 0) {
|
if (c == 0) {
|
||||||
return pos;
|
return pos;
|
||||||
|
@ -291,9 +288,8 @@ Result<short> Dict::cmp(Arena& arena, Dict& rhs) {
|
||||||
short cmp = short(i == lsize) - short(j == rsize);
|
short cmp = short(i == lsize) - short(j == rsize);
|
||||||
if (cmp != 0) return cmp;
|
if (cmp != 0) return cmp;
|
||||||
|
|
||||||
Value lc = TRY(Value::create(arena, _value->data[i].get(_value.get())));
|
Value lc = TRY(Value::create(arena, _value->data[i].get()));
|
||||||
Value rc =
|
Value rc = TRY(Value::create(arena, rhs._value->data[j].get()));
|
||||||
TRY(Value::create(arena, rhs._value->data[j].get(rhs._value.get())));
|
|
||||||
cmp = TRY(lc.cmp(arena, rc));
|
cmp = TRY(lc.cmp(arena, rc));
|
||||||
if (cmp != 0) return cmp;
|
if (cmp != 0) return cmp;
|
||||||
i++;
|
i++;
|
||||||
|
|
|
@ -150,8 +150,12 @@ class Array : public Object {
|
||||||
|
|
||||||
auto pod = TRY(arena.alloc<PodArray>(res_size * sizeof(PodObject*)));
|
auto pod = TRY(arena.alloc<PodArray>(res_size * sizeof(PodObject*)));
|
||||||
pod->size = res_size;
|
pod->size = res_size;
|
||||||
memcpy(pod->data, _value->data, sizeof(PodObject*) * lhs_size);
|
for (uint64_t i = 0; i < size(); i++) {
|
||||||
memcpy(pod->data + lhs_size, rhs._value->data, sizeof(char) * rhs_size);
|
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)));
|
return Array(TRY(MkGcRoot(pod, arena)));
|
||||||
}
|
}
|
||||||
|
@ -161,7 +165,9 @@ class Array : public Object {
|
||||||
uint64_t res_size = end - start;
|
uint64_t res_size = end - start;
|
||||||
auto pod = TRY(arena.alloc<PodArray>(res_size * sizeof(PodObject*)));
|
auto pod = TRY(arena.alloc<PodArray>(res_size * sizeof(PodObject*)));
|
||||||
pod->size = res_size;
|
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)));
|
return Array(TRY(MkGcRoot(pod, arena)));
|
||||||
}
|
}
|
||||||
|
@ -326,10 +332,15 @@ class Dict : public Object {
|
||||||
uint64_t lhs_size = size();
|
uint64_t lhs_size = size();
|
||||||
uint64_t res_size = lhs_size + rhs_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;
|
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)));
|
return Dict(TRY(MkGcRoot(pod, arena)));
|
||||||
}
|
}
|
||||||
|
|
23
src/pod.hpp
23
src/pod.hpp
|
@ -24,13 +24,21 @@ class OffPtr {
|
||||||
public:
|
public:
|
||||||
OffPtr() : _offset(0) {}
|
OffPtr() : _offset(0) {}
|
||||||
template <class R>
|
template <class R>
|
||||||
OffPtr(R* base, T* ptr)
|
OffPtr(T* ptr) : _offset((ptr == 0) ? 0 : (uint8_t*)ptr - (uint8_t*)this){};
|
||||||
: _offset((ptr == 0) ? 0 : (uint8_t*)ptr - (uint8_t*)base){};
|
|
||||||
|
|
||||||
template <class R>
|
T* get() const {
|
||||||
T* get(R* base) {
|
|
||||||
if (_offset == 0) return 0;
|
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:
|
private:
|
||||||
|
@ -40,9 +48,10 @@ class OffPtr {
|
||||||
static_assert(sizeof(OffPtr<void>) == 8);
|
static_assert(sizeof(OffPtr<void>) == 8);
|
||||||
|
|
||||||
struct PodHeader {
|
struct PodHeader {
|
||||||
PodHeader(Tag tag) : tag(tag), forward(0) {}
|
PodHeader(Tag tag) : tag(tag), stat(0), forward(0) {}
|
||||||
Tag tag;
|
Tag tag;
|
||||||
int64_t forward : 56;
|
unsigned stat : 1;
|
||||||
|
int64_t forward : 55;
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(sizeof(PodHeader) == 8);
|
static_assert(sizeof(PodHeader) == 8);
|
||||||
|
|
|
@ -194,11 +194,8 @@ Result<String> Writer::write_dict(Dict& val) {
|
||||||
|
|
||||||
bool is_first = true;
|
bool is_first = true;
|
||||||
for (uint64_t i = 0; i < val.size(); i++) {
|
for (uint64_t i = 0; i < val.size(); i++) {
|
||||||
Value k = TRY(
|
Value k = TRY(Value::create(_arena, val._value->data[i * 2].get()));
|
||||||
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()));
|
||||||
|
|
||||||
Value v = TRY(Value::create(
|
|
||||||
_arena, val._value->data[i * 2 + 1].get(val._value.get())));
|
|
||||||
|
|
||||||
if (!is_first) res = TRY(res.concat(_arena, " "));
|
if (!is_first) res = TRY(res.concat(_arena, " "));
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue