aboutsummaryrefslogtreecommitdiff
path: root/builtins
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2024-03-22 13:53:23 -0400
committerBruce Hill <bruce@bruce-hill.com>2024-03-22 13:53:23 -0400
commit20d75db79a2b74697d93f395e9d07f43f46e9c6b (patch)
tree887b3f629205644be2c5a3a0d73dc63b0ae963b7 /builtins
parentddee8692109b17750e1573ca7773c02726ac8f2b (diff)
Fix/improve assignment to arrays and tables
Diffstat (limited to 'builtins')
-rw-r--r--builtins/array.h14
1 files changed, 11 insertions, 3 deletions
diff --git a/builtins/array.h b/builtins/array.h
index 209a72e2..6375f6d4 100644
--- a/builtins/array.h
+++ b/builtins/array.h
@@ -11,12 +11,20 @@
#include "types.h"
// Convert negative indices to back-indexed without branching: index0 = index + (index < 0)*(len+1)) - 1
-#define $Array_get(type, x, i, filename, start, end) *({ \
- const array_t $arr = x; int64_t $index = (int64_t)(i); \
+#define $Array_get(item_type, arr_expr, index_expr, filename, start, end) *({ \
+ const array_t $arr = arr_expr; int64_t $index = (int64_t)(index_expr); \
int64_t $off = $index + ($index < 0) * ($arr.length + 1) - 1; \
if (__builtin_expect($off < 0 || $off >= $arr.length, 0)) \
fail_source(filename, start, end, "Invalid array index: %r (array has length %ld)\n", Int__as_text(&$index, USE_COLOR, NULL), $arr.length); \
- (type*)($arr.data + $arr.stride * $off);})
+ (item_type*)($arr.data + $arr.stride * $off);})
+#define $Array_set(item_type, arr_expr, index_expr, value_expr, typeinfo, filename, start, end) { \
+ array_t *$arr = arr_expr; int64_t $index = (int64_t)(index_expr); \
+ int64_t $off = $index + ($index < 0) * ($arr->length + 1) - 1; \
+ if (__builtin_expect($off < 0 || $off >= $arr->length, 0)) \
+ fail_source(filename, start, end, "Invalid array index: %r (array has length %ld)\n", Int__as_text(&$index, USE_COLOR, NULL), $arr->length); \
+ if ($arr->data_refcount > 0) \
+ Array__compact($arr, typeinfo); \
+ *(item_type*)($arr->data + $arr->stride * $off) = value_expr; }
#define $Array_get_unchecked(type, x, i) *({ const array_t $arr = x; int64_t $index = (int64_t)(i); \
int64_t $off = $index + ($index < 0) * ($arr.length + 1) - 1; \
(type*)($arr.data + $arr.stride * $off);})