diff --git a/CMakeLists.txt b/CMakeLists.txt index f3dceaf..824a46a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -47,6 +47,7 @@ enable_testing() set(CPP_TESTS dict + array ) diff --git a/src/common.cpp b/src/common.cpp index e095795..5ca0a53 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -184,9 +184,12 @@ Result Array::get(Arena& arena, Value& key) { Result Array::append(Arena& arena, Value& rhs) { uint64_t res_size = size() + 1; - auto pod = TRY(arena.alloc(res_size * sizeof(PodObject*))); + auto pod = TRY(arena.alloc(res_size * sizeof(OffPtr))); + pod->header.tag = Tag::Array; pod->size = res_size; - memcpy(pod->data, _value->data, sizeof(PodObject*) * size()); + for (uint64_t i = 0; i < size(); i++) { + pod->data[i] = OffPtr(pod, _value->data[i].get(_value.get())); + } pod->data[size()] = OffPtr(pod, rhs.pod()); return Array(TRY(MkGcRoot(pod, arena))); diff --git a/src/common.hpp b/src/common.hpp index 9eeef78..c850b73 100644 --- a/src/common.hpp +++ b/src/common.hpp @@ -140,6 +140,8 @@ class Array : public Object { virtual Result get(Arena& arena, Value& key) final; Result append(Arena& arena, Value& rhs); + template + Result append(Arena& arena, const V& value); Result concat(Arena& arena, Array& rhs) { uint64_t rhs_size = rhs.size(); @@ -766,3 +768,9 @@ Result Dict::insert(Arena& arena, const K& key, const V& value) { return insert(arena, k, v); } + +template +Result Array::append(Arena& arena, const V& value) { + Value v = TRY(Value::create(arena, value)); + return append(arena, v); +} diff --git a/test/array.cpp b/test/array.cpp new file mode 100644 index 0000000..994a96b --- /dev/null +++ b/test/array.cpp @@ -0,0 +1,26 @@ +#include "common.hpp" +#include "die.hpp" +#include "reader.hpp" +#include "test.hpp" +#include "writer.hpp" + +StaticArena<64 * 1024 * 1024> arena; + +TEST_CASE(array_append) { + auto a = DIEX(Array::create(arena)); + + a = DIEX(a.append(arena, 1)); + a = DIEX(a.append(arena, 2)); + a = DIEX(a.append(arena, 3)); + + DIEX(arena.gc()); + + auto s = DIEX(write_one(arena, a)); + + DIEX(arena.gc()); + + ASSERT_EQUALS(s, "[1 2 3]"); + + auto v = DIEX(a.get(arena, 1)); + ASSERT_EQUALS(v, 2); +}