declare_block (Qentry);
Lisp_Object blocks = CALL1I (comp-func-blocks, func);
struct Lisp_Hash_Table *ht = XHASH_TABLE (blocks);
- DOHASH (ht, block_name, block)
- if (!EQ (block_name, Qentry))
- declare_block (block_name);
+ DOHASH_SAFE (ht, i)
+ {
+ Lisp_Object block_name = HASH_KEY (ht, i);
+ if (!EQ (block_name, Qentry))
+ declare_block (block_name);
+ }
gcc_jit_block_add_assignment (retrive_block (Qentry),
NULL,
gcc_jit_lvalue_as_rvalue (comp.func_relocs));
- DOHASH (ht, block_name, block)
+ DOHASH_SAFE (ht, i)
{
+ Lisp_Object block_name = HASH_KEY (ht, i);
+ Lisp_Object block = HASH_VALUE (ht, i);
Lisp_Object insns = CALL1I (comp-block-insns, block);
if (NILP (block) || NILP (insns))
xsignal1 (Qnative_ice,
struct Lisp_Hash_Table *func_h =
XHASH_TABLE (CALL1I (comp-ctxt-funcs-h, Vcomp_ctxt));
- DOHASH (func_h, k, v)
- declare_function (v);
+ DOHASH_SAFE (func_h, i)
+ declare_function (HASH_VALUE (func_h, i));
/* Compile all functions. Can't be done before because the
relocation structs has to be already defined. */
- DOHASH (func_h, k, v)
- compile_function (v);
+ DOHASH_SAFE (func_h, i)
+ compile_function (HASH_VALUE (func_h, i));
/* Work around bug#46495 (GCC PR99126). */
#if defined (WIDE_EMACS_INT) \
}
/* Iterate K and V as key and value of valid entries in hash table H.
- 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)) \
- ; \
+ 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), \
+ *dohash_##k##_##v##_base = dohash_##k##_##v##_kv, \
+ k, v; \
+ 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); \
+ eassert (dohash_##k##_##v##_base == (h)->key_and_value \
+ && dohash_##k##_##v##_end \
+ == dohash_##k##_##v##_base \
+ + 2 * HASH_TABLE_SIZE (h)), \
+ dohash_##k##_##v##_kv += 2) \
+ if (hash_unused_entry_key_p (k)) \
+ ; \
else
+/* Iterate I as index of valid entries in hash table H.
+ Unlike DOHASH, this construct copes with arbitrary table mutations
+ in the body. The consequences of such mutations are limited to
+ whether and in what order entries are encountered by the loop
+ (which is usually bad enough), but not crashing or corrupting the
+ Lisp state. */
+#define DOHASH_SAFE(h, i) \
+ for (ptrdiff_t i = 0; i < HASH_TABLE_SIZE (h); i++) \
+ if (hash_unused_entry_key_p (HASH_KEY (h, i))) \
+ ; \
+ else
void hash_table_thaw (Lisp_Object hash_table);