diff options
| author | Bruce Hill <bruce@bruce-hill.com> | 2024-08-12 17:44:05 -0400 |
|---|---|---|
| committer | Bruce Hill <bruce@bruce-hill.com> | 2024-08-12 17:44:05 -0400 |
| commit | 6aabed4fcc6823466e78593b93ceadd095f7463f (patch) | |
| tree | 8d3e48568b1cd9a312a3d4c548aa67489fffaa39 /builtins | |
| parent | c139ba2aae50222595bc95db804ab5ded74ba51c (diff) | |
Fix some COW bugs for arrays/tables/sets
Diffstat (limited to 'builtins')
| -rw-r--r-- | builtins/array.h | 7 | ||||
| -rw-r--r-- | builtins/table.h | 3 |
2 files changed, 6 insertions, 4 deletions
diff --git a/builtins/array.h b/builtins/array.h index 4acf2664..9a5307a2 100644 --- a/builtins/array.h +++ b/builtins/array.h @@ -36,22 +36,23 @@ .stride=(int64_t)&items[1] - (int64_t)&items[0], \ .data=memcpy(GC_MALLOC(sizeof(items)), items, sizeof(items)), \ .atomic=0, \ - .data_refcount=1}; }) + .data_refcount=0}; }) #define TypedArrayN(t, N, ...) ({ t items[N] = {__VA_ARGS__}; \ (array_t){.length=N, \ .stride=(int64_t)&items[1] - (int64_t)&items[0], \ .data=memcpy(GC_MALLOC(sizeof(items)), items, sizeof(items)), \ .atomic=0, \ - .data_refcount=1}; }) + .data_refcount=0}; }) #define Array(x, ...) ({ __typeof(x) items[] = {x, __VA_ARGS__}; \ (array_t){.length=sizeof(items)/sizeof(items[0]), \ .stride=(int64_t)&items[1] - (int64_t)&items[0], \ .data=memcpy(is_atomic(x) ? GC_MALLOC_ATOMIC(sizeof(items)) : GC_MALLOC(sizeof(items)), items, sizeof(items)), \ .atomic=is_atomic(x), \ - .data_refcount=1}; }) + .data_refcount=0}; }) // Array refcounts use a saturating add, where once it's at the max value, it stays there. #define ARRAY_INCREF(arr) (arr).data_refcount += ((arr).data_refcount < ARRAY_MAX_DATA_REFCOUNT) #define ARRAY_DECREF(arr) (arr).data_refcount -= ((arr).data_refcount < ARRAY_MAX_DATA_REFCOUNT) +#define ARRAY_COPY(arr) ({ ARRAY_INCREF(arr); arr; }) #define Array$insert_value(arr, item_expr, index, padded_item_size) ({ __typeof(item_expr) item = item_expr; Array$insert(arr, &item, index, padded_item_size); }) void Array$insert(array_t *arr, const void *item, int64_t index, int64_t padded_item_size); diff --git a/builtins/table.h b/builtins/table.h index 842131e8..68231faf 100644 --- a/builtins/table.h +++ b/builtins/table.h @@ -69,7 +69,8 @@ bool Table$is_superset_of(table_t a, table_t b, bool strict, const TypeInfo *typ void Table$clear(table_t *t); table_t Table$sorted(table_t t, const TypeInfo *type); void Table$mark_copy_on_write(table_t *t); -#define TABLE_INCREF(t) ({ ARRAY_INCREF((t).entries); if ((t).bucket_info) (t).bucket_info.data_refcount += ((t).bucket_info.data_refcount < TABLE_MAX_DATA_REFCOUNT); }) +#define TABLE_INCREF(t) ({ ARRAY_INCREF((t).entries); if ((t).bucket_info) (t).bucket_info->data_refcount += ((t).bucket_info->data_refcount < TABLE_MAX_DATA_REFCOUNT); }) +#define TABLE_COPY(t) ({ TABLE_INCREF(t); t; }) int32_t Table$compare(const table_t *x, const table_t *y, const TypeInfo *type); bool Table$equal(const table_t *x, const table_t *y, const TypeInfo *type); uint32_t Table$hash(const table_t *t, const TypeInfo *type); |
