From ad004f10f3668d464d32ed8da18639da9bcc01bb Mon Sep 17 00:00:00 2001 From: Stefan Monnier Date: Wed, 24 Jan 2024 14:52:09 -0500 Subject: [PATCH] * src/lisp.h (DOHASH): Handle rehashing (bug#68690) I gave too much credit to the comment, and didn't realize that macro was used in places that didn't obey the comment. This macro is getting pretty hideous! --- src/lisp.h | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/src/lisp.h b/src/lisp.h index f822417ffb1..d07d9d14e2f 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -2604,20 +2604,30 @@ hash_from_key (struct Lisp_Hash_Table *h, Lisp_Object key) } /* Iterate K and V as key and value of valid entries in hash table H. - The body may remove the current entry or alter its value slot, but not - mutate TABLE in any other way. */ -#define DOHASH(h, k, v) \ - for (Lisp_Object *dohash_##k##_##v##_kv = (h)->key_and_value, \ - *dohash_##k##_##v##_end = dohash_##k##_##v##_kv \ - + 2 * HASH_TABLE_SIZE (h), \ - k, v; \ - dohash_##k##_##v##_kv < dohash_##k##_##v##_end \ - && (k = dohash_##k##_##v##_kv[0], \ - v = dohash_##k##_##v##_kv[1], /*maybe unsed*/ (void)v, \ - true); \ - dohash_##k##_##v##_kv += 2) \ - if (hash_unused_entry_key_p (k)) \ - ; \ + The body may mutate the hash-table. */ +#define DOHASH(h, k, v) \ + for (Lisp_Object *dohash_##k##_##v##_base = (h)->key_and_value, \ + *dohash_##k##_##v##_kv = dohash_##k##_##v##_base, \ + *dohash_##k##_##v##_end = dohash_##k##_##v##_base \ + + 2 * HASH_TABLE_SIZE (h), \ + k, v; \ + dohash_##k##_##v##_kv < dohash_##k##_##v##_end \ + && (dohash_##k##_##v##_base == (h)->key_and_value \ + /* The `key_and_value` table has been reallocated! */ \ + || (dohash_##k##_##v##_kv \ + = (dohash_##k##_##v##_kv - dohash_##k##_##v##_base) \ + + (h)->key_and_value, \ + dohash_##k##_##v##_base = (h)->key_and_value, \ + dohash_##k##_##v##_end = dohash_##k##_##v##_base \ + + 2 * HASH_TABLE_SIZE (h), \ + /* Check again, in case the table has shrunk. */ \ + dohash_##k##_##v##_kv < dohash_##k##_##v##_end)) \ + && (k = dohash_##k##_##v##_kv[0], \ + v = dohash_##k##_##v##_kv[1], /*maybe unused*/ (void)v, \ + true); \ + dohash_##k##_##v##_kv += 2) \ + if (hash_unused_entry_key_p (k)) \ + ; \ else -- 2.30.2