@scriptc/cli-darwin-x64 0.2.2 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/THIRD_PARTY_NOTICES +1 -1
- package/dist/bin/scriptc +0 -0
- package/dist/bin/scriptc.json +1 -1
- package/dist/lib/declarations/scriptc-node-fallback.d.ts +99 -27
- package/dist/lib/llvm/bin/scriptc-llvm-codegen +0 -0
- package/dist/lib/llvm/package.json +1 -1
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_array.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_assert.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_async.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_bigint.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_bytes_io.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_cycle.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_events.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_exception.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_file_handle.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_json.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_lib.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_map.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_node_builtin.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_regex.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_string.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_symbol.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_url.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_url_params.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_util_compare.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_util_style.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_array.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_assert.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_async.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_bigint.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_bytes_io.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_cycle.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_events.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_exception.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_file_handle.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_island.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_json.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_lib.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_map.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_node_builtin.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_regex.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_string.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_symbol.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_url.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_url_params.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_util_compare.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_util_style.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_web.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_array.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_assert.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_bigint.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_bytes_io.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_cycle.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_exception.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_json.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_lib.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_map.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_node_builtin.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_regex.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_string.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_symbol.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_url.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_url_params.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_array.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_assert.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_bigint.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_bytes_io.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_cycle.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_exception.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_json.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_lib.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_map.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_node_builtin.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_regex.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_string.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_symbol.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_url.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_url_params.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_array.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_assert.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_bigint.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_bytes_io.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_cycle.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_exception.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_json.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_lib.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_map.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_node_builtin.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_regex.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_string.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_symbol.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_url.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_url_params.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_array.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_assert.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_bigint.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_bytes_io.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_cycle.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_exception.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_json.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_lib.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_map.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_node_builtin.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_regex.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_string.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_symbol.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_url.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_url_params.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_array.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_assert.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_async.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_bigint.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_bytes_io.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_cycle.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_events.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_exception.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_file_handle.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_json.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_lib.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_map.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_node_builtin.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_regex.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_string.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_symbol.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_url.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_url_params.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_util_compare.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_util_style.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_array.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_assert.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_async.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_bigint.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_bytes_io.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_cycle.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_events.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_exception.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_file_handle.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_island.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_json.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_lib.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_map.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_node_builtin.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_regex.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_string.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_symbol.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_url.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_url_params.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_util_compare.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_util_style.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_web.o +0 -0
- package/dist/lib/runtime-darwin-x64/package.json +1 -1
- package/dist/lib/runtime-darwin-x64/runtime-pack.json +399 -273
- package/dist/lib/runtime-sources/package.json +1 -1
- package/dist/lib/runtime-sources/src/scr_array.c +55 -34
- package/dist/lib/runtime-sources/src/scr_assert.c +26 -0
- package/dist/lib/runtime-sources/src/scr_async.c +44 -0
- package/dist/lib/runtime-sources/src/scr_bigint.c +15 -0
- package/dist/lib/runtime-sources/src/scr_bytes_io.c +305 -48
- package/dist/lib/runtime-sources/src/scr_cycle.c +84 -60
- package/dist/lib/runtime-sources/src/scr_events.c +9 -0
- package/dist/lib/runtime-sources/src/scr_exception.c +1 -0
- package/dist/lib/runtime-sources/src/scr_file_handle.c +11 -0
- package/dist/lib/runtime-sources/src/scr_island.c +1001 -417
- package/dist/lib/runtime-sources/src/scr_island_manifest.h +11 -7
- package/dist/lib/runtime-sources/src/scr_json.c +150 -13
- package/dist/lib/runtime-sources/src/scr_lib.c +424 -28
- package/dist/lib/runtime-sources/src/scr_map.c +236 -40
- package/dist/lib/runtime-sources/src/scr_node_builtin.c +78 -0
- package/dist/lib/runtime-sources/src/scr_regex.c +112 -8
- package/dist/lib/runtime-sources/src/scr_runtime.h +108 -14
- package/dist/lib/runtime-sources/src/scr_string.c +29 -0
- package/dist/lib/runtime-sources/src/scr_symbol.c +5 -0
- package/dist/lib/runtime-sources/src/scr_system_errors.h +573 -0
- package/dist/lib/runtime-sources/src/scr_url.c +515 -59
- package/dist/lib/runtime-sources/src/scr_url_internal.h +6 -0
- package/dist/lib/runtime-sources/src/scr_url_params.c +10 -0
- package/dist/lib/runtime-sources/src/scr_util_compare.c +222 -0
- package/dist/lib/runtime-sources/src/scr_util_style.c +337 -0
- package/dist/lib/runtime-sources/src/scr_web.c +720 -238
- package/package.json +1 -1
|
@@ -59,6 +59,16 @@ static uint64_t scr_map_hash_str(const ScrStr *k) {
|
|
|
59
59
|
return scr_map_fnv1a((const unsigned char *)k->data, k->len);
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
+
/* Mix the complete normalized number or identity word. Float exponents
|
|
63
|
+
* and aligned pointers need high bits to reach the low bucket-index bits. */
|
|
64
|
+
static uint64_t scr_map_hash_word(uint64_t value) {
|
|
65
|
+
value ^= value >> 30;
|
|
66
|
+
value *= UINT64_C(0xbf58476d1ce4e5b9);
|
|
67
|
+
value ^= value >> 27;
|
|
68
|
+
value *= UINT64_C(0x94d049bb133111eb);
|
|
69
|
+
return value ^ (value >> 31);
|
|
70
|
+
}
|
|
71
|
+
|
|
62
72
|
/* ── slot packing (8-byte slots, like ScrArr) ──────────────────────────── */
|
|
63
73
|
|
|
64
74
|
static uint64_t scr_map_slot_from_f64(double v) {
|
|
@@ -98,12 +108,7 @@ static uint64_t scr_map_hash_dyn(const ScrDyn *d) {
|
|
|
98
108
|
case SCR_DYN_NULL: value = 0; break;
|
|
99
109
|
case SCR_DYN_BOOL: value = d->v.b; break;
|
|
100
110
|
case SCR_DYN_NUM: value = scr_map_f64_bits(d->v.num); break;
|
|
101
|
-
case SCR_DYN_BIGINT:
|
|
102
|
-
ScrStr *text = scr_bigint_to_string(d->v.bigint, 10);
|
|
103
|
-
uint64_t hash = scr_map_hash_str(text);
|
|
104
|
-
scr_str_release(text);
|
|
105
|
-
return hash;
|
|
106
|
-
}
|
|
111
|
+
case SCR_DYN_BIGINT: return scr_bigint_hash(d->v.bigint);
|
|
107
112
|
case SCR_DYN_STR: return scr_map_hash_str(d->v.str);
|
|
108
113
|
case SCR_DYN_SYMBOL: value = scr_map_slot_from_ptr(d->v.symbol.value); break;
|
|
109
114
|
case SCR_DYN_FUNC: value = scr_map_slot_from_ptr(d->v.fn.class_obj ? (void *)d->v.fn.class_obj : (void *)d->v.fn.clo); break;
|
|
@@ -122,7 +127,7 @@ static uint64_t scr_map_hash_dyn(const ScrDyn *d) {
|
|
|
122
127
|
case SCR_DYN_JSVAL: value = 0; break;
|
|
123
128
|
default: value = scr_map_slot_from_ptr((void *)d); break;
|
|
124
129
|
}
|
|
125
|
-
return
|
|
130
|
+
return scr_map_hash_word(value) ^ kind;
|
|
126
131
|
}
|
|
127
132
|
|
|
128
133
|
static bool scr_map_dyn_eq(const ScrDyn *a, const ScrDyn *b) {
|
|
@@ -135,16 +140,50 @@ static bool scr_map_dyn_eq(const ScrDyn *a, const ScrDyn *b) {
|
|
|
135
140
|
return scr_dyn_strict_eq(a, b);
|
|
136
141
|
}
|
|
137
142
|
|
|
143
|
+
static uint64_t scr_map_hash_union(const ScrMap *m, const ScrUnion *key) {
|
|
144
|
+
ScrMapKeyKind kind = (ScrMapKeyKind)m->union_keys[key->tag];
|
|
145
|
+
switch (kind) {
|
|
146
|
+
case SCR_MAP_KEY_STR: return scr_map_hash_str(scr_union_peek(key));
|
|
147
|
+
case SCR_MAP_KEY_BIGINT: return scr_bigint_hash(scr_union_peek(key));
|
|
148
|
+
case SCR_MAP_KEY_F64: return scr_map_hash_word(scr_map_f64_bits(scr_map_slot_to_f64(key->slot)));
|
|
149
|
+
case SCR_MAP_KEY_NULL:
|
|
150
|
+
case SCR_MAP_KEY_UNDEFINED: return scr_map_hash_word((uint64_t)kind);
|
|
151
|
+
default: return scr_map_hash_word(key->slot);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
static bool scr_map_union_eq(const ScrMap *m, const ScrUnion *a, const ScrUnion *b) {
|
|
156
|
+
ScrMapKeyKind kind = (ScrMapKeyKind)m->union_keys[a->tag];
|
|
157
|
+
if (kind != (ScrMapKeyKind)m->union_keys[b->tag]) return false;
|
|
158
|
+
switch (kind) {
|
|
159
|
+
case SCR_MAP_KEY_STR: return scr_str_eq(scr_union_peek(a), scr_union_peek(b));
|
|
160
|
+
case SCR_MAP_KEY_BIGINT: return scr_bigint_eq(scr_union_peek(a), scr_union_peek(b));
|
|
161
|
+
case SCR_MAP_KEY_F64:
|
|
162
|
+
return scr_map_f64_bits(scr_map_slot_to_f64(a->slot)) == scr_map_f64_bits(scr_map_slot_to_f64(b->slot));
|
|
163
|
+
case SCR_MAP_KEY_NULL:
|
|
164
|
+
case SCR_MAP_KEY_UNDEFINED: return true;
|
|
165
|
+
default: return a->slot == b->slot;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
138
169
|
static uint64_t scr_map_hash_key(const ScrMap *m, uint64_t key) {
|
|
139
170
|
if (m->key_kind == SCR_MAP_KEY_STR) return scr_map_hash_str((ScrStr *)scr_map_slot_to_ptr(key));
|
|
140
171
|
if (m->key_kind == SCR_MAP_KEY_DYN) return scr_map_hash_dyn((ScrDyn *)scr_map_slot_to_ptr(key));
|
|
172
|
+
if (m->key_kind == SCR_MAP_KEY_BIGINT) return scr_bigint_hash(scr_map_slot_to_ptr(key));
|
|
173
|
+
if (m->key_kind == SCR_MAP_KEY_UNION_VALUE) return scr_map_hash_union(m, scr_map_slot_to_ptr(key));
|
|
141
174
|
uint64_t identity = scr_map_identity(m, key);
|
|
142
|
-
return
|
|
175
|
+
return scr_map_hash_word(identity);
|
|
143
176
|
}
|
|
144
177
|
|
|
145
178
|
/* Stored keys are pre-normalized, so bit equality IS SameValueZero for f64
|
|
146
179
|
* keys (probe keys normalize through the same function). */
|
|
147
180
|
static bool scr_map_key_eq(const ScrMap *m, uint64_t stored, uint64_t probe) {
|
|
181
|
+
if (m->key_kind == SCR_MAP_KEY_UNION_VALUE) {
|
|
182
|
+
return scr_map_union_eq(m, scr_map_slot_to_ptr(stored), scr_map_slot_to_ptr(probe));
|
|
183
|
+
}
|
|
184
|
+
if (m->key_kind == SCR_MAP_KEY_BIGINT) {
|
|
185
|
+
return scr_bigint_eq(scr_map_slot_to_ptr(stored), scr_map_slot_to_ptr(probe));
|
|
186
|
+
}
|
|
148
187
|
if (m->key_kind == SCR_MAP_KEY_DYN) {
|
|
149
188
|
return scr_map_dyn_eq((ScrDyn *)scr_map_slot_to_ptr(stored), (ScrDyn *)scr_map_slot_to_ptr(probe));
|
|
150
189
|
}
|
|
@@ -156,18 +195,25 @@ static bool scr_map_key_eq(const ScrMap *m, uint64_t stored, uint64_t probe) {
|
|
|
156
195
|
}
|
|
157
196
|
|
|
158
197
|
/* ── lookup ────────────────────────────────────────────────────────────
|
|
159
|
-
* Returns the
|
|
160
|
-
*
|
|
161
|
-
|
|
198
|
+
* Returns the matching bucket, or the empty bucket where a new key belongs.
|
|
199
|
+
* A zero entry hash marks a tombstone; cached hashes reject unrelated keys
|
|
200
|
+
* before equality and survive table growth without hashing the keys again.
|
|
201
|
+
* Remap zero to one so every live entry has a nonzero hash. */
|
|
202
|
+
static size_t scr_map_probe(const ScrMap *m, uint64_t hash, uint64_t key) {
|
|
162
203
|
if (m->nbuckets == 0) return SCR_MAP_EMPTY;
|
|
163
204
|
size_t mask = m->nbuckets - 1;
|
|
164
205
|
for (size_t i = hash & mask;; i = (i + 1) & mask) {
|
|
165
206
|
size_t b = m->buckets[i];
|
|
166
|
-
if (b == SCR_MAP_EMPTY) return
|
|
167
|
-
if (m->entries[b].
|
|
207
|
+
if (b == SCR_MAP_EMPTY) return i;
|
|
208
|
+
if (m->entries[b].hash == hash && scr_map_key_eq(m, m->entries[b].key, key)) return i;
|
|
168
209
|
}
|
|
169
210
|
}
|
|
170
211
|
|
|
212
|
+
static size_t scr_map_find(const ScrMap *m, uint64_t hash, uint64_t key) {
|
|
213
|
+
size_t slot = scr_map_probe(m, hash ? hash : 1, key);
|
|
214
|
+
return slot == SCR_MAP_EMPTY ? SCR_MAP_EMPTY : m->buckets[slot];
|
|
215
|
+
}
|
|
216
|
+
|
|
171
217
|
/* Rebuild the bucket table (size must be a power of two >= 2 * nentries):
|
|
172
218
|
* only live entries are inserted, in dense order — dead markers vanish. */
|
|
173
219
|
static void scr_map_rebuild_buckets(ScrMap *m, size_t nbuckets) {
|
|
@@ -179,8 +225,8 @@ static void scr_map_rebuild_buckets(ScrMap *m, size_t nbuckets) {
|
|
|
179
225
|
m->nbuckets = nbuckets;
|
|
180
226
|
size_t mask = nbuckets - 1;
|
|
181
227
|
for (size_t e = 0; e < m->nentries; e++) {
|
|
182
|
-
|
|
183
|
-
|
|
228
|
+
uint64_t hash = m->entries[e].hash;
|
|
229
|
+
if (!hash) continue;
|
|
184
230
|
size_t i = hash & mask;
|
|
185
231
|
while (buckets[i] != SCR_MAP_EMPTY) i = (i + 1) & mask;
|
|
186
232
|
buckets[i] = e;
|
|
@@ -192,7 +238,7 @@ static void scr_map_rebuild_buckets(ScrMap *m, size_t nbuckets) {
|
|
|
192
238
|
static void scr_map_compact(ScrMap *m) {
|
|
193
239
|
size_t w = 0;
|
|
194
240
|
for (size_t r = 0; r < m->nentries; r++) {
|
|
195
|
-
if (m->entries[r].
|
|
241
|
+
if (m->entries[r].hash) m->entries[w++] = m->entries[r];
|
|
196
242
|
}
|
|
197
243
|
m->nentries = w;
|
|
198
244
|
if (m->nbuckets > 0) scr_map_rebuild_buckets(m, m->nbuckets);
|
|
@@ -229,10 +275,15 @@ static void scr_map_reserve_append(ScrMap *m) {
|
|
|
229
275
|
|
|
230
276
|
/* ── entry release helpers ─────────────────────────────────────────────── */
|
|
231
277
|
|
|
278
|
+
static bool scr_map_ref_key(ScrMapKeyKind kind) {
|
|
279
|
+
return kind == SCR_MAP_KEY_REF || kind == SCR_MAP_KEY_UNION_REF || kind == SCR_MAP_KEY_DYN ||
|
|
280
|
+
kind == SCR_MAP_KEY_BIGINT || kind == SCR_MAP_KEY_UNION_VALUE;
|
|
281
|
+
}
|
|
282
|
+
|
|
232
283
|
static void scr_map_release_key(ScrMap *m, uint64_t key) {
|
|
233
284
|
if (m->key_kind == SCR_MAP_KEY_STR) {
|
|
234
285
|
scr_str_release((ScrStr *)scr_map_slot_to_ptr(key));
|
|
235
|
-
} else if (m->key_kind
|
|
286
|
+
} else if (scr_map_ref_key(m->key_kind)) {
|
|
236
287
|
m->key_release(scr_map_slot_to_ptr(key));
|
|
237
288
|
}
|
|
238
289
|
}
|
|
@@ -243,10 +294,14 @@ static void scr_map_release_val(ScrMap *m, uint64_t val) {
|
|
|
243
294
|
|
|
244
295
|
/* ── lifecycle ─────────────────────────────────────────────────────────── */
|
|
245
296
|
|
|
297
|
+
void scr_map_union_keys(ScrMap *map, const uint8_t *kinds) {
|
|
298
|
+
map->union_keys = kinds;
|
|
299
|
+
}
|
|
300
|
+
|
|
246
301
|
static void scr_map_trace(void *o, ScrTraceVisit visit, void *ctx) {
|
|
247
302
|
ScrMap *m = (ScrMap *)o;
|
|
248
303
|
for (size_t e = 0; e < m->nentries; e++) {
|
|
249
|
-
if (!m->entries[e].
|
|
304
|
+
if (!m->entries[e].hash) continue;
|
|
250
305
|
if (m->key_trace) visit(scr_map_slot_to_ptr(m->entries[e].key), ctx);
|
|
251
306
|
if (m->val_trace) visit(scr_map_slot_to_ptr(m->entries[e].val), ctx);
|
|
252
307
|
}
|
|
@@ -258,7 +313,7 @@ static void scr_map_gcfree(void *o) {
|
|
|
258
313
|
ScrMap *m = (ScrMap *)o;
|
|
259
314
|
scr_weak_dispose(m);
|
|
260
315
|
for (size_t e = 0; e < m->nentries; e++) {
|
|
261
|
-
if (!m->entries[e].
|
|
316
|
+
if (!m->entries[e].hash) continue;
|
|
262
317
|
if (!m->key_trace) scr_map_release_key(m, m->entries[e].key);
|
|
263
318
|
if (!m->val_trace) scr_map_release_val(m, m->entries[e].val);
|
|
264
319
|
}
|
|
@@ -318,7 +373,7 @@ void scr_map_release(ScrMap *m) {
|
|
|
318
373
|
scr_weak_dispose(m);
|
|
319
374
|
if (m->key_trace || m->val_trace) scr_cyc_on_dead(m);
|
|
320
375
|
for (size_t e = 0; e < m->nentries; e++) {
|
|
321
|
-
if (!m->entries[e].
|
|
376
|
+
if (!m->entries[e].hash) continue;
|
|
322
377
|
scr_map_release_key(m, m->entries[e].key);
|
|
323
378
|
scr_map_release_val(m, m->entries[e].val);
|
|
324
379
|
}
|
|
@@ -344,8 +399,8 @@ double scr_map_size(const ScrMap *m) { return (double)m->nlive; }
|
|
|
344
399
|
|
|
345
400
|
void scr_map_clear(ScrMap *m) {
|
|
346
401
|
for (size_t e = 0; e < m->nentries; e++) {
|
|
347
|
-
if (!m->entries[e].
|
|
348
|
-
m->entries[e].
|
|
402
|
+
if (!m->entries[e].hash) continue;
|
|
403
|
+
m->entries[e].hash = 0;
|
|
349
404
|
scr_map_release_key(m, m->entries[e].key);
|
|
350
405
|
scr_map_release_val(m, m->entries[e].val);
|
|
351
406
|
}
|
|
@@ -363,7 +418,7 @@ void scr_map_clear(ScrMap *m) {
|
|
|
363
418
|
|
|
364
419
|
bool scr_map_has_f64(const ScrMap *m, double key) {
|
|
365
420
|
uint64_t k = scr_map_f64_bits(key);
|
|
366
|
-
return scr_map_find(m,
|
|
421
|
+
return scr_map_find(m, scr_map_hash_word(k), k) != SCR_MAP_EMPTY;
|
|
367
422
|
}
|
|
368
423
|
|
|
369
424
|
bool scr_map_has_str(const ScrMap *m, const ScrStr *key) {
|
|
@@ -373,7 +428,7 @@ bool scr_map_has_str(const ScrMap *m, const ScrStr *key) {
|
|
|
373
428
|
|
|
374
429
|
static bool scr_map_delete_found(ScrMap *m, size_t e) {
|
|
375
430
|
if (e == SCR_MAP_EMPTY) return false;
|
|
376
|
-
m->entries[e].
|
|
431
|
+
m->entries[e].hash = 0; /* bucket slot stays: probe chains intact */
|
|
377
432
|
m->nlive--;
|
|
378
433
|
scr_map_release_key(m, m->entries[e].key);
|
|
379
434
|
scr_map_release_val(m, m->entries[e].val);
|
|
@@ -382,7 +437,7 @@ static bool scr_map_delete_found(ScrMap *m, size_t e) {
|
|
|
382
437
|
|
|
383
438
|
bool scr_map_delete_f64(ScrMap *m, double key) {
|
|
384
439
|
uint64_t k = scr_map_f64_bits(key);
|
|
385
|
-
return scr_map_delete_found(m, scr_map_find(m,
|
|
440
|
+
return scr_map_delete_found(m, scr_map_find(m, scr_map_hash_word(k), k));
|
|
386
441
|
}
|
|
387
442
|
|
|
388
443
|
bool scr_map_delete_str(ScrMap *m, const ScrStr *key) {
|
|
@@ -412,18 +467,28 @@ bool scr_map_delete_ref(ScrMap *m, const void *key) {
|
|
|
412
467
|
* insertion slot. */
|
|
413
468
|
|
|
414
469
|
static void scr_map_set(ScrMap *m, uint64_t hash, uint64_t key, uint64_t val) {
|
|
415
|
-
|
|
470
|
+
hash = hash ? hash : 1;
|
|
471
|
+
size_t slot = scr_map_probe(m, hash, key);
|
|
472
|
+
size_t e = slot == SCR_MAP_EMPTY ? SCR_MAP_EMPTY : m->buckets[slot];
|
|
416
473
|
if (e != SCR_MAP_EMPTY) {
|
|
417
474
|
uint64_t old = m->entries[e].val;
|
|
418
475
|
m->entries[e].val = val; /* unlink before releasing (cycle collector) */
|
|
419
476
|
scr_map_release_val(m, old);
|
|
420
477
|
return;
|
|
421
478
|
}
|
|
479
|
+
size_t old_entries = m->nentries, old_buckets = m->nbuckets;
|
|
422
480
|
scr_map_reserve_append(m);
|
|
481
|
+
/* Growth or compaction can move the insertion bucket. Otherwise keep the
|
|
482
|
+
* empty slot from the first probe instead of walking the chain twice. */
|
|
483
|
+
if (m->nentries != old_entries || m->nbuckets != old_buckets) {
|
|
484
|
+
size_t mask = m->nbuckets - 1;
|
|
485
|
+
slot = hash & mask;
|
|
486
|
+
while (m->buckets[slot] != SCR_MAP_EMPTY) slot = (slot + 1) & mask;
|
|
487
|
+
}
|
|
423
488
|
size_t idx = m->nentries++;
|
|
424
489
|
m->entries[idx].key = key;
|
|
425
490
|
m->entries[idx].val = val;
|
|
426
|
-
m->entries[idx].
|
|
491
|
+
m->entries[idx].hash = hash;
|
|
427
492
|
m->nlive++;
|
|
428
493
|
if (m->key_kind == SCR_MAP_KEY_STR) {
|
|
429
494
|
scr_str_retain((ScrStr *)scr_map_slot_to_ptr(key)); /* key is borrowed */
|
|
@@ -436,18 +501,21 @@ static void scr_map_set(ScrMap *m, uint64_t hash, uint64_t key, uint64_t val) {
|
|
|
436
501
|
} else {
|
|
437
502
|
m->key_retain(scr_map_slot_to_ptr(key));
|
|
438
503
|
}
|
|
439
|
-
} else if (m->key_kind ==
|
|
504
|
+
} else if (m->key_kind == SCR_MAP_KEY_UNION_VALUE &&
|
|
505
|
+
m->union_keys[((ScrUnion *)scr_map_slot_to_ptr(key))->tag] == SCR_MAP_KEY_F64 &&
|
|
506
|
+
((ScrUnion *)scr_map_slot_to_ptr(key))->slot == UINT64_C(0x8000000000000000)) {
|
|
507
|
+
/* Normalize stored -0 without mutating the caller's immutable box. */
|
|
508
|
+
ScrUnion *u = scr_map_slot_to_ptr(key);
|
|
509
|
+
m->entries[idx].key = scr_map_slot_from_ptr(scr_union_new_f64(u->tag, 0));
|
|
510
|
+
} else if (scr_map_ref_key(m->key_kind)) {
|
|
440
511
|
m->key_retain(scr_map_slot_to_ptr(key)); /* key is borrowed */
|
|
441
512
|
}
|
|
442
|
-
|
|
443
|
-
size_t i = hash & mask;
|
|
444
|
-
while (m->buckets[i] != SCR_MAP_EMPTY) i = (i + 1) & mask;
|
|
445
|
-
m->buckets[i] = idx;
|
|
513
|
+
m->buckets[slot] = idx;
|
|
446
514
|
}
|
|
447
515
|
|
|
448
516
|
static void scr_map_set_f64_key(ScrMap *m, double key, uint64_t val) {
|
|
449
517
|
uint64_t k = scr_map_f64_bits(key); /* stores +0 for -0, canonical NaN */
|
|
450
|
-
scr_map_set(m,
|
|
518
|
+
scr_map_set(m, scr_map_hash_word(k), k, val);
|
|
451
519
|
}
|
|
452
520
|
|
|
453
521
|
static void scr_map_set_str_key(ScrMap *m, ScrStr *key, uint64_t val) {
|
|
@@ -501,7 +569,7 @@ ScrMap *scr_set_new_ref(void *(*elem_retain)(void *), void (*elem_release)(void
|
|
|
501
569
|
|
|
502
570
|
static size_t scr_map_find_f64(const ScrMap *m, double key) {
|
|
503
571
|
uint64_t k = scr_map_f64_bits(key);
|
|
504
|
-
return scr_map_find(m,
|
|
572
|
+
return scr_map_find(m, scr_map_hash_word(k), k);
|
|
505
573
|
}
|
|
506
574
|
|
|
507
575
|
static size_t scr_map_find_str(const ScrMap *m, const ScrStr *key) {
|
|
@@ -568,17 +636,63 @@ void *scr_map_get_ref_ref(const ScrMap *m, const void *key) {
|
|
|
568
636
|
return m->val_retain(scr_map_slot_to_ptr(m->entries[e].val));
|
|
569
637
|
}
|
|
570
638
|
|
|
639
|
+
/* Boolean keys use unboxed 0/1 slots and the same probe path. */
|
|
640
|
+
static size_t scr_map_find_bool(const ScrMap *m, bool key) {
|
|
641
|
+
uint64_t slot = key ? 1 : 0;
|
|
642
|
+
return scr_map_find(m, scr_map_hash_word(slot), slot);
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
bool scr_map_has_bool(const ScrMap *m, bool key) {
|
|
646
|
+
return scr_map_find_bool(m, key) != SCR_MAP_EMPTY;
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
bool scr_map_delete_bool(ScrMap *m, bool key) {
|
|
650
|
+
return scr_map_delete_found(m, scr_map_find_bool(m, key));
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
void scr_map_set_bool_f64(ScrMap *m, bool key, double value) {
|
|
654
|
+
scr_map_set(m, scr_map_hash_word(key ? 1 : 0), key ? 1 : 0, scr_map_slot_from_f64(value));
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
void scr_map_set_bool_bool(ScrMap *m, bool key, bool value) {
|
|
658
|
+
scr_map_set(m, scr_map_hash_word(key ? 1 : 0), key ? 1 : 0, value ? 1 : 0);
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
void scr_map_set_bool_ref(ScrMap *m, bool key, void *value) {
|
|
662
|
+
scr_map_set(m, scr_map_hash_word(key ? 1 : 0), key ? 1 : 0, scr_map_slot_from_ptr(value));
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
bool scr_map_get_bool_f64(const ScrMap *m, bool key, double *out) {
|
|
666
|
+
size_t entry = scr_map_find_bool(m, key);
|
|
667
|
+
if (entry == SCR_MAP_EMPTY) return false;
|
|
668
|
+
*out = scr_map_slot_to_f64(m->entries[entry].val);
|
|
669
|
+
return true;
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
bool scr_map_get_bool_bool(const ScrMap *m, bool key, bool *out) {
|
|
673
|
+
size_t entry = scr_map_find_bool(m, key);
|
|
674
|
+
if (entry == SCR_MAP_EMPTY) return false;
|
|
675
|
+
*out = m->entries[entry].val != 0;
|
|
676
|
+
return true;
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
void *scr_map_get_bool_ref(const ScrMap *m, bool key) {
|
|
680
|
+
size_t entry = scr_map_find_bool(m, key);
|
|
681
|
+
if (entry == SCR_MAP_EMPTY) return NULL;
|
|
682
|
+
return m->val_retain(scr_map_slot_to_ptr(m->entries[entry].val));
|
|
683
|
+
}
|
|
684
|
+
|
|
571
685
|
/* ── iteration primitives (the forEach desugar) ────────────────────────── */
|
|
572
686
|
|
|
573
687
|
double scr_map_iter_count(const ScrMap *m) { return (double)m->nentries; }
|
|
574
688
|
|
|
575
689
|
bool scr_map_iter_live(const ScrMap *m, double i) {
|
|
576
690
|
if (!(i >= 0) || i >= (double)m->nentries) return false;
|
|
577
|
-
return m->entries[(size_t)i].
|
|
691
|
+
return m->entries[(size_t)i].hash;
|
|
578
692
|
}
|
|
579
693
|
|
|
580
694
|
static const ScrMapEntry *scr_map_iter_at(const ScrMap *m, double i) {
|
|
581
|
-
if (!(i >= 0) || i >= (double)m->nentries || !m->entries[(size_t)i].
|
|
695
|
+
if (!(i >= 0) || i >= (double)m->nentries || !m->entries[(size_t)i].hash) {
|
|
582
696
|
scr_trap("scriptc: internal error: map iteration index out of range\n");
|
|
583
697
|
}
|
|
584
698
|
return &m->entries[(size_t)i];
|
|
@@ -588,6 +702,10 @@ double scr_map_iter_key_f64(const ScrMap *m, double i) {
|
|
|
588
702
|
return scr_map_slot_to_f64(scr_map_iter_at(m, i)->key);
|
|
589
703
|
}
|
|
590
704
|
|
|
705
|
+
bool scr_map_iter_key_bool(const ScrMap *m, double i) {
|
|
706
|
+
return scr_map_iter_at(m, i)->key != 0;
|
|
707
|
+
}
|
|
708
|
+
|
|
591
709
|
ScrStr *scr_map_iter_key_str(const ScrMap *m, double i) {
|
|
592
710
|
return scr_str_retain((ScrStr *)scr_map_slot_to_ptr(scr_map_iter_at(m, i)->key));
|
|
593
711
|
}
|
|
@@ -649,6 +767,75 @@ void scr_map_dyn_set(ScrMap *map, const ScrDyn *key, const ScrDyn *value, bool s
|
|
|
649
767
|
scr_map_release_key(map, key_slot);
|
|
650
768
|
}
|
|
651
769
|
|
|
770
|
+
/* Copy only live entries. The source is borrowed, contains unique keys,
|
|
771
|
+
* and runs no user code while traversed, so cached hashes remain valid. */
|
|
772
|
+
ScrMap *scr_map_clone(const ScrMap *source, bool keys_only) {
|
|
773
|
+
ScrMap *out = scr_map_new_typed(source->key_kind, keys_only ? SCR_MAP_VAL_F64 : source->val_kind,
|
|
774
|
+
source->key_retain, source->key_release, source->key_trace,
|
|
775
|
+
keys_only ? NULL : source->val_retain, keys_only ? NULL : source->val_release,
|
|
776
|
+
keys_only ? NULL : source->val_trace);
|
|
777
|
+
out->union_keys = source->union_keys;
|
|
778
|
+
size_t count = source->nlive;
|
|
779
|
+
if (!count) return out;
|
|
780
|
+
if (count > SIZE_MAX / sizeof(ScrMapEntry) || count > SIZE_MAX / 2 / sizeof(size_t)) scr_map_oom();
|
|
781
|
+
out->entries = malloc(count * sizeof(ScrMapEntry));
|
|
782
|
+
if (!out->entries) scr_map_oom();
|
|
783
|
+
out->ecap = count;
|
|
784
|
+
for (size_t i = 0; i < source->nentries; i++) {
|
|
785
|
+
const ScrMapEntry *entry = &source->entries[i];
|
|
786
|
+
if (!entry->hash) continue;
|
|
787
|
+
ScrMapEntry *copy = &out->entries[out->nentries++];
|
|
788
|
+
*copy = *entry;
|
|
789
|
+
if (out->key_kind == SCR_MAP_KEY_STR) scr_str_retain(scr_map_slot_to_ptr(copy->key));
|
|
790
|
+
else if (scr_map_ref_key(out->key_kind)) out->key_retain(scr_map_slot_to_ptr(copy->key));
|
|
791
|
+
if (keys_only) copy->val = 0;
|
|
792
|
+
else if (out->val_kind == SCR_MAP_VAL_REF) out->val_retain(scr_map_slot_to_ptr(copy->val));
|
|
793
|
+
}
|
|
794
|
+
out->nlive = count;
|
|
795
|
+
size_t buckets = 16;
|
|
796
|
+
while (buckets < 2 * count) {
|
|
797
|
+
if (buckets > SIZE_MAX / 2 / sizeof(size_t)) scr_map_oom();
|
|
798
|
+
buckets *= 2;
|
|
799
|
+
}
|
|
800
|
+
scr_map_rebuild_buckets(out, buckets);
|
|
801
|
+
return out;
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
/* A generic view can be backed by typed slots. Its copy must accept new
|
|
805
|
+
* JavaScript values independently of that backing's narrower adapters. */
|
|
806
|
+
ScrMap *scr_map_clone_dyn(const ScrMap *source, bool keys_only) {
|
|
807
|
+
ScrMap *out = scr_map_new_typed(SCR_MAP_KEY_DYN, keys_only ? SCR_MAP_VAL_F64 : SCR_MAP_VAL_REF,
|
|
808
|
+
scr_dyn_retain_v, scr_dyn_release_v, scr_dyn_trace_v,
|
|
809
|
+
keys_only ? NULL : scr_dyn_retain_v, keys_only ? NULL : scr_dyn_release_v,
|
|
810
|
+
keys_only ? NULL : scr_dyn_trace_v);
|
|
811
|
+
for (size_t i = 0; i < source->nentries; i++) {
|
|
812
|
+
if (!source->entries[i].hash) continue;
|
|
813
|
+
ScrDyn *key = scr_map_dyn_key(source, (double)i);
|
|
814
|
+
uint64_t value = keys_only ? 0 : scr_map_slot_from_ptr(scr_map_dyn_value(source, (double)i));
|
|
815
|
+
scr_map_set(out, scr_map_hash_dyn(key), scr_map_slot_from_ptr(key), value);
|
|
816
|
+
scr_dyn_release(key);
|
|
817
|
+
}
|
|
818
|
+
return out;
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
void scr_map_values_into(ScrMap *set, const ScrMap *source, bool checked) {
|
|
822
|
+
for (size_t i = 0; i < source->nentries; i++) {
|
|
823
|
+
if (!source->entries[i].hash) continue;
|
|
824
|
+
uint64_t value = checked ? scr_map_slot_from_ptr(scr_map_dyn_value(source, (double)i)) : source->entries[i].val;
|
|
825
|
+
if (set->key_kind == SCR_MAP_KEY_F64) value = scr_map_f64_bits(scr_map_slot_to_f64(value));
|
|
826
|
+
scr_map_set(set, scr_map_hash_key(set, value), value, 0);
|
|
827
|
+
if (checked) scr_dyn_release(scr_map_slot_to_ptr(value));
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
ScrArr *scr_set_to_arr_dyn(const ScrMap *map) {
|
|
832
|
+
ScrArr *out = scr_arr_new_ref(scr_dyn_retain_v, scr_dyn_release_v, scr_dyn_trace_v, map->nlive);
|
|
833
|
+
for (size_t i = 0; i < map->nentries; i++) {
|
|
834
|
+
if (scr_map_iter_live(map, (double)i)) scr_arr_push_ref(out, scr_map_dyn_key(map, (double)i));
|
|
835
|
+
}
|
|
836
|
+
return out;
|
|
837
|
+
}
|
|
838
|
+
|
|
652
839
|
void *scr_map_iter_val_ref(const ScrMap *m, double i) {
|
|
653
840
|
return m->val_retain(scr_map_slot_to_ptr(scr_map_iter_at(m, i)->val)); /* +1 */
|
|
654
841
|
}
|
|
@@ -675,14 +862,23 @@ void scr_map_iter_exit(ScrMap *m) {
|
|
|
675
862
|
void scr_set_add_all(ScrMap *set, ScrArr *values) {
|
|
676
863
|
size_t n = values->len;
|
|
677
864
|
for (size_t i = 0; i < n; i++) {
|
|
678
|
-
|
|
865
|
+
/* Packed values stay owned by the seed array throughout construction.
|
|
866
|
+
* Avoid taking a temporary owner only to release it after insertion.
|
|
867
|
+
* Sparse/missing positions retain the existing accessor semantics. */
|
|
868
|
+
if (i < values->cap && values->present[i] == SCR_ARR_VALUE) {
|
|
869
|
+
uint64_t key = values->data[i];
|
|
870
|
+
if (set->key_kind == SCR_MAP_KEY_F64) key = scr_map_f64_bits(scr_map_slot_to_f64(key));
|
|
871
|
+
scr_map_set(set, scr_map_hash_key(set, key), key, 0);
|
|
872
|
+
} else if (values->elem == SCR_ELEM_STR) {
|
|
679
873
|
ScrStr *s = (ScrStr *)scr_arr_get_ref(values, (double)i); /* +1 */
|
|
680
874
|
scr_map_set_str_f64(set, s, 0); /* borrows; retains stored copy */
|
|
681
875
|
scr_str_release(s);
|
|
682
|
-
} else if (set->key_kind
|
|
876
|
+
} else if (scr_map_ref_key(set->key_kind)) {
|
|
683
877
|
void *p = scr_arr_get_ref(values, (double)i); /* +1 */
|
|
684
878
|
scr_map_set_ref_f64(set, p, 0); /* borrows; retains stored copy */
|
|
685
879
|
set->key_release(p);
|
|
880
|
+
} else if (set->key_kind == SCR_MAP_KEY_BOOL) {
|
|
881
|
+
scr_map_set_bool_f64(set, scr_arr_get_bool(values, (double)i), 0);
|
|
686
882
|
} else {
|
|
687
883
|
scr_map_set_f64_f64(set, scr_arr_get_f64(values, (double)i), 0);
|
|
688
884
|
}
|
|
@@ -721,7 +917,7 @@ ScrArr *scr_map_keys_js_order(const ScrMap *m) {
|
|
|
721
917
|
size_t nidx = 0;
|
|
722
918
|
struct { uint32_t v; ScrStr *k; } *idx = NULL;
|
|
723
919
|
for (size_t i = 0; i < n; i++) {
|
|
724
|
-
if (!m->entries[i].
|
|
920
|
+
if (!m->entries[i].hash) continue;
|
|
725
921
|
ScrStr *k = (ScrStr *)scr_map_slot_to_ptr(m->entries[i].key);
|
|
726
922
|
uint32_t v;
|
|
727
923
|
if (!scr_map_key_array_index(k, &v)) continue;
|
|
@@ -742,7 +938,7 @@ ScrArr *scr_map_keys_js_order(const ScrMap *m) {
|
|
|
742
938
|
}
|
|
743
939
|
free(idx);
|
|
744
940
|
for (size_t i = 0; i < n; i++) {
|
|
745
|
-
if (!m->entries[i].
|
|
941
|
+
if (!m->entries[i].hash) continue;
|
|
746
942
|
ScrStr *k = (ScrStr *)scr_map_slot_to_ptr(m->entries[i].key);
|
|
747
943
|
uint32_t v;
|
|
748
944
|
if (scr_map_key_array_index(k, &v)) continue;
|
|
@@ -1,11 +1,89 @@
|
|
|
1
1
|
/* Native builtin export objects. The compiler supplies the existing static
|
|
2
2
|
* callable implementations; this unit owns lookup, identity, and mutations. */
|
|
3
3
|
#include "scr_runtime.h"
|
|
4
|
+
#include "scr_system_errors.h"
|
|
4
5
|
|
|
5
6
|
#include <stdlib.h>
|
|
6
7
|
#include <string.h>
|
|
7
8
|
#include <math.h>
|
|
8
9
|
|
|
10
|
+
typedef struct { int value; const char *name; const char *message; } ScrSystemError;
|
|
11
|
+
#define SCR_SYSTEM_ERROR(name, message) { SCR_NODE_UV__##name, #name, message },
|
|
12
|
+
static const ScrSystemError scr_system_errors[] = {
|
|
13
|
+
SCR_NODE_UV_ERRNO_MAP(SCR_SYSTEM_ERROR)
|
|
14
|
+
};
|
|
15
|
+
#undef SCR_SYSTEM_ERROR
|
|
16
|
+
|
|
17
|
+
static bool scr_system_error_number(const ScrDyn *error, double *number) {
|
|
18
|
+
if (!error || error->kind != SCR_DYN_NUM) {
|
|
19
|
+
scr_dyn_arg_type_fail("err", "of type number", error ? error : scr_dyn_undefined());
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
double n = error->v.num;
|
|
23
|
+
if (!(isfinite(n) && n < 0 && trunc(n) == n && n >= -9007199254740991.0)) {
|
|
24
|
+
char received[48];
|
|
25
|
+
scr_num_received(n, received);
|
|
26
|
+
if (n == 0 && signbit(n)) strcpy(received, "-0");
|
|
27
|
+
ScrJsonBuf buffer;
|
|
28
|
+
scr_jb_init(&buffer);
|
|
29
|
+
scr_jb_puts(&buffer, "The value of \"err\" is out of range. It must be a negative integer. Received ");
|
|
30
|
+
scr_jb_puts(&buffer, received);
|
|
31
|
+
ScrStr *message = scr_jb_finish(&buffer);
|
|
32
|
+
scr_throw_error_msg_code(SCR_ERR_RANGE, message->data, message->len, "ERR_OUT_OF_RANGE");
|
|
33
|
+
scr_str_release(message);
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
*number = n;
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
static ScrStr *scr_system_error_lookup(double number, bool message) {
|
|
41
|
+
/* Node's name helper looks up the original safe integer. Its message
|
|
42
|
+
* binding uses V8's saturating Int32 extraction instead. */
|
|
43
|
+
double lookup = message && number < -2147483648.0 ? -2147483648.0 : number;
|
|
44
|
+
for (size_t i = 0; i < sizeof scr_system_errors / sizeof scr_system_errors[0]; i++) {
|
|
45
|
+
if (lookup == scr_system_errors[i].value) {
|
|
46
|
+
const char *text = message ? scr_system_errors[i].message : scr_system_errors[i].name;
|
|
47
|
+
return scr_str_new(text, strlen(text));
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
ScrJsonBuf buffer;
|
|
51
|
+
scr_jb_init(&buffer);
|
|
52
|
+
scr_jb_puts(&buffer, "Unknown system error ");
|
|
53
|
+
ScrStr *rendered = scr_f64_to_scrstr(lookup);
|
|
54
|
+
scr_jb_put_str(&buffer, rendered);
|
|
55
|
+
scr_str_release(rendered);
|
|
56
|
+
return scr_jb_finish(&buffer);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
ScrStr *scr_util_system_error_name(const ScrDyn *error) {
|
|
60
|
+
double number;
|
|
61
|
+
return scr_system_error_number(error, &number) ? scr_system_error_lookup(number, false) : NULL;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
ScrStr *scr_util_system_error_message(const ScrDyn *error) {
|
|
65
|
+
double number;
|
|
66
|
+
return scr_system_error_number(error, &number) ? scr_system_error_lookup(number, true) : NULL;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
ScrDyn *scr_util_system_error_entries(void) {
|
|
70
|
+
ScrDyn *entries = scr_dyn_new_arr();
|
|
71
|
+
for (size_t i = 0; i < sizeof scr_system_errors / sizeof scr_system_errors[0]; i++) {
|
|
72
|
+
const ScrSystemError *error = &scr_system_errors[i];
|
|
73
|
+
ScrDyn *entry = scr_dyn_new_arr(), *pair = scr_dyn_new_arr();
|
|
74
|
+
ScrStr *name = scr_str_new(error->name, strlen(error->name));
|
|
75
|
+
ScrStr *message = scr_str_new(error->message, strlen(error->message));
|
|
76
|
+
scr_dyn_arr_push(pair, scr_dyn_new_str(name));
|
|
77
|
+
scr_dyn_arr_push(pair, scr_dyn_new_str(message));
|
|
78
|
+
scr_str_release(name);
|
|
79
|
+
scr_str_release(message);
|
|
80
|
+
scr_dyn_arr_push(entry, scr_dyn_new_num(error->value));
|
|
81
|
+
scr_dyn_arr_push(entry, pair);
|
|
82
|
+
scr_dyn_arr_push(entries, entry);
|
|
83
|
+
}
|
|
84
|
+
return entries;
|
|
85
|
+
}
|
|
86
|
+
|
|
9
87
|
static SCR_TL ScrDyn *scr_global_known;
|
|
10
88
|
static SCR_TL ScrDyn *scr_global_own;
|
|
11
89
|
static SCR_TL bool scr_global_cleanup_registered;
|