diff --git a/src/arena.cpp b/src/arena.cpp index 5dc31b8..01cd5c7 100644 --- a/src/arena.cpp +++ b/src/arena.cpp @@ -133,14 +133,14 @@ Result 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(nobj, first); - nobj->rest = OffPtr(nobj, rest); + nobj->first = first; + nobj->rest = rest; return nobj; } @@ -150,8 +150,8 @@ Result 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(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 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(nobj, TRY(gc_pod(val))); + PodObject* val = obj->data[i].get(); + nobj->data[i] = TRY(gc_pod(val)); } return nobj; // return ErrorCode::NotImplemented; diff --git a/src/common.cpp b/src/common.cpp index 5ca0a53..46346c2 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -9,7 +9,7 @@ Syntax::Syntax(String filename, String modulename, Value expression) {} Result Syntax::get_value(Arena& arena) { - return Value::create(arena, _value->expression.get(&*_value)); + return Value::create(arena, _value->expression.get()); } Result Value::create(Arena& arena, PodObject* obj) { @@ -122,18 +122,18 @@ Result Bool::copy(Arena& arena) const { Result Pair::create(Arena& arena, Value& first, Value& rest) { auto pod = TRY(arena.alloc()); pod->header.tag = Tag::Pair; - pod->first = OffPtr(pod, first.pod()); - pod->rest = OffPtr(pod, rest.pod()); + pod->first = first.pod(); + pod->rest = rest.pod(); return Pair(TRY(MkGcRoot(pod, arena))); } Result Pair::first(Arena& arena) { - auto val = _value->first.get(pod()); + auto val = _value->first.get(); return Value::create(arena, val); } Result 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 debug_print(Arena& arena, Value& val) { Result 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::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(pod, _value->data[i].get(_value.get())); + pod->data[i] = _value->data[i].get(); } - pod->data[size()] = OffPtr(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 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::insert(Arena& arena, Value& key, Value& value) { @@ -219,7 +219,7 @@ Result 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::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(pod, key.pod()); - pod->data[i * 2 + 1] = OffPtr(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(pod, _value->data[j * 2].get(vpod)); - pod->data[i * 2 + 1] = - OffPtr(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(pod, _value->data[j * 2].get(vpod)); - pod->data[i * 2 + 1] = - OffPtr(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 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 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++; diff --git a/src/common.hpp b/src/common.hpp index 07fd6e6..b255e05 100644 --- a/src/common.hpp +++ b/src/common.hpp @@ -150,8 +150,12 @@ class Array : public Object { auto pod = TRY(arena.alloc(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(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(res_size * sizeof(PodObject*))); + auto pod = TRY(arena.alloc(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))); } diff --git a/src/pod.hpp b/src/pod.hpp index 5ccf7ad..15e8aab 100644 --- a/src/pod.hpp +++ b/src/pod.hpp @@ -24,13 +24,21 @@ class OffPtr { public: OffPtr() : _offset(0) {} template - 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 - 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& operator=(const OffPtr& rhs) { + _offset = (uint8_t*)rhs.get() - (uint8_t*)this; + return *this; + } + + OffPtr& operator=(T* rhs) { + _offset = (uint8_t*)rhs - (uint8_t*)this; + return *this; } private: @@ -40,9 +48,10 @@ class OffPtr { static_assert(sizeof(OffPtr) == 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); diff --git a/src/writer.cpp b/src/writer.cpp index 6ab1182..5ac6d91 100644 --- a/src/writer.cpp +++ b/src/writer.cpp @@ -194,11 +194,8 @@ Result 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, " "));