mirror of
https://github.com/Nexoniarz/Finch.git
synced 2026-11-03 08:54:25 +00:00
Fix the two known limits: adding map keys while looping over the map is a runtime error; temporaries held by an expression are freed when try / or-blocks leave early. err usable after or, inner err shadows outer.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
b872be3176
commit
f9838dfe03
9 changed files with 228 additions and 17 deletions
|
|
@ -596,10 +596,11 @@ int finch_try_write_file(const FStr *path, const FStr *text, FStr *err) {
|
|||
}
|
||||
|
||||
// ---------- maps ----------
|
||||
// map[K]V = { entries; len; used; cap; index; icap }
|
||||
// map[K]V = { entries; len; used; cap; index; icap; adds }
|
||||
// entries: `used` slots of es bytes, each { uint64 hash; K key; V value }, in insertion order.
|
||||
// A removed entry keeps its slot (hash 0) until the next resize packs the slots.
|
||||
// index: icap slots (a power of two, at least 2 * cap): -1 empty, -2 removed, else an entry number.
|
||||
// adds: how many keys were ever added; a `for` over the map stops with an error if it changes.
|
||||
// The compiler stores, copies and drops keys and values; the runtime only finds and places entries.
|
||||
// Keys are compared byte for byte (numbers, chars, bools) or as text (kstr).
|
||||
|
||||
|
|
@ -608,6 +609,7 @@ typedef struct {
|
|||
int64_t len, used, cap;
|
||||
int64_t *index;
|
||||
int64_t icap;
|
||||
int64_t adds;
|
||||
} FMap;
|
||||
|
||||
static uint64_t map_hash(const void *key, int64_t ks, int kstr) {
|
||||
|
|
@ -699,6 +701,7 @@ int64_t finch_map_slot(FMap *m, const void *key, int64_t es, int64_t ks, int32_t
|
|||
while (m->index[s] >= 0) s = (s + 1) & (m->icap - 1);
|
||||
m->index[s] = i;
|
||||
m->len++;
|
||||
m->adds++;
|
||||
return i;
|
||||
}
|
||||
|
||||
|
|
@ -736,6 +739,10 @@ void finch_map_clone_raw(FMap *out, const FMap *m, int64_t es) {
|
|||
memcpy(out->index, m->index, (size_t)m->icap * sizeof(int64_t));
|
||||
}
|
||||
|
||||
__attribute__((noreturn, cold)) void finch_map_changed(const char *file, int64_t line) {
|
||||
finch_panic(file, line, "a key was added to the map while looping over it (collect the new keys, and add them after the loop)");
|
||||
}
|
||||
|
||||
__attribute__((noreturn, cold)) void finch_map_missing(const char *file, int64_t line, const FStr *key) {
|
||||
char msg[200];
|
||||
snprintf(msg, sizeof msg, "the key %.*s is not in the map (check with .has(key), or use .get(key, default))",
|
||||
|
|
|
|||
Loading…
Reference in a new issue