diff --git a/src/ant.c b/src/ant.c index c6a6809..16d5276 100644 --- a/src/ant.c +++ b/src/ant.c @@ -2672,7 +2672,6 @@ static ant_offset_t dense_grow(ant_t *js, ant_value_t arr, ant_offset_t needed) obj->u.array.data = next; obj->u.array.cap = (uint32_t)new_cap; - if (obj->u.array.len > obj->u.array.cap) obj->u.array.len = obj->u.array.cap; obj->fast_array = 1; return (ant_offset_t)(uintptr_t)obj; } @@ -2730,6 +2729,7 @@ shape_lookup:; } static inline void arr_set(ant_t *js, ant_value_t arr, ant_offset_t idx, ant_value_t val) { + ant_offset_t cur_len = get_array_length(js, arr); ant_offset_t doff = get_dense_buf(arr); if (doff) { @@ -2756,7 +2756,7 @@ static inline void arr_set(ant_t *js, ant_value_t arr, ant_offset_t idx, ant_val } dense_set(js, doff, idx, val); - array_len_set(js, arr, idx + 1); + if (idx >= cur_len) array_len_set(js, arr, idx + 1); return; } diff --git a/tests/test_array_sparse_descending_length.cjs b/tests/test_array_sparse_descending_length.cjs new file mode 100644 index 0000000..1dbc448 --- /dev/null +++ b/tests/test_array_sparse_descending_length.cjs @@ -0,0 +1,24 @@ +const assert = require("node:assert"); + +const arr = []; +for (let n = 128, i = 0; i < 111; i++) { + arr[--n] = i; +} + +assert.equal(arr.length, 128); +assert.equal(arr[127], 0); +assert.equal(arr[31], 96); +assert.equal(arr[30], 97); +assert.equal(arr[17], 110); +assert.equal(arr[16], undefined); +assert.equal(Object.keys(arr).length, 111); + +const mixed = []; +mixed[127] = "tail"; +mixed[31] = "lower"; + +assert.equal(mixed.length, 128); +assert.equal(mixed[127], "tail"); +assert.equal(mixed[31], "lower"); + +console.log("OK: sparse descending array writes preserve length");