aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMattias EngdegÄrd2024-01-19 15:17:52 +0100
committerMattias EngdegÄrd2024-01-21 11:21:51 +0100
commitfec87a4b36a67688932e7bb7e1720bd2c4363a61 (patch)
tree8549ad5b17f75ba86a77e5fd8dea8a77bb3133af /src
parent0a07603ae8db41f69e83b1bfec6e28a92f737852 (diff)
downloademacs-fec87a4b36a67688932e7bb7e1720bd2c4363a61.tar.gz
emacs-fec87a4b36a67688932e7bb7e1720bd2c4363a61.zip
Add C macro for hash table iteration
This removes some boilerplate code and further reduces dependencies on hash table implementation internals. * src/lisp.h (DOHASH): New. * src/comp.c (compile_function, Fcomp__compile_ctxt_to_file): * src/composite.c (composition_gstring_cache_clear_font): * src/emacs-module.c (module_global_reference_p): * src/fns.c (Fmaphash): * src/json.c (lisp_to_json_nonscalar_1): * src/minibuf.c (Ftest_completion): * src/print.c (print): Use it instead of a hand-written loop.
Diffstat (limited to 'src')
-rw-r--r--src/comp.c40
-rw-r--r--src/composite.c12
-rw-r--r--src/emacs-module.c9
-rw-r--r--src/fns.c9
-rw-r--r--src/json.c47
-rw-r--r--src/lisp.h8
-rw-r--r--src/minibuf.c4
-rw-r--r--src/print.c12
8 files changed, 59 insertions, 82 deletions
diff --git a/src/comp.c b/src/comp.c
index 3f9e738d9a7..25c4cb2f22c 100644
--- a/src/comp.c
+++ b/src/comp.c
@@ -4330,11 +4330,10 @@ compile_function (Lisp_Object func)
4330 declare_block (Qentry); 4330 declare_block (Qentry);
4331 Lisp_Object blocks = CALL1I (comp-func-blocks, func); 4331 Lisp_Object blocks = CALL1I (comp-func-blocks, func);
4332 struct Lisp_Hash_Table *ht = XHASH_TABLE (blocks); 4332 struct Lisp_Hash_Table *ht = XHASH_TABLE (blocks);
4333 for (ptrdiff_t i = 0; i < HASH_TABLE_SIZE (ht); i++) 4333 DOHASH (ht, i)
4334 { 4334 {
4335 Lisp_Object block_name = HASH_KEY (ht, i); 4335 Lisp_Object block_name = HASH_KEY (ht, i);
4336 if (!EQ (block_name, Qentry) 4336 if (!EQ (block_name, Qentry))
4337 && !hash_unused_entry_key_p (block_name))
4338 declare_block (block_name); 4337 declare_block (block_name);
4339 } 4338 }
4340 4339
@@ -4344,24 +4343,21 @@ compile_function (Lisp_Object func)
4344 gcc_jit_lvalue_as_rvalue (comp.func_relocs)); 4343 gcc_jit_lvalue_as_rvalue (comp.func_relocs));
4345 4344
4346 4345
4347 for (ptrdiff_t i = 0; i < HASH_TABLE_SIZE (ht); i++) 4346 DOHASH (ht, i)
4348 { 4347 {
4349 Lisp_Object block_name = HASH_KEY (ht, i); 4348 Lisp_Object block_name = HASH_KEY (ht, i);
4350 if (!hash_unused_entry_key_p (block_name)) 4349 Lisp_Object block = HASH_VALUE (ht, i);
4350 Lisp_Object insns = CALL1I (comp-block-insns, block);
4351 if (NILP (block) || NILP (insns))
4352 xsignal1 (Qnative_ice,
4353 build_string ("basic block is missing or empty"));
4354
4355 comp.block = retrive_block (block_name);
4356 while (CONSP (insns))
4351 { 4357 {
4352 Lisp_Object block = HASH_VALUE (ht, i); 4358 Lisp_Object insn = XCAR (insns);
4353 Lisp_Object insns = CALL1I (comp-block-insns, block); 4359 emit_limple_insn (insn);
4354 if (NILP (block) || NILP (insns)) 4360 insns = XCDR (insns);
4355 xsignal1 (Qnative_ice,
4356 build_string ("basic block is missing or empty"));
4357
4358 comp.block = retrive_block (block_name);
4359 while (CONSP (insns))
4360 {
4361 Lisp_Object insn = XCAR (insns);
4362 emit_limple_insn (insn);
4363 insns = XCDR (insns);
4364 }
4365 } 4361 }
4366 } 4362 }
4367 const char *err = gcc_jit_context_get_first_error (comp.ctxt); 4363 const char *err = gcc_jit_context_get_first_error (comp.ctxt);
@@ -4965,14 +4961,10 @@ DEFUN ("comp--compile-ctxt-to-file", Fcomp__compile_ctxt_to_file,
4965 4961
4966 struct Lisp_Hash_Table *func_h = 4962 struct Lisp_Hash_Table *func_h =
4967 XHASH_TABLE (CALL1I (comp-ctxt-funcs-h, Vcomp_ctxt)); 4963 XHASH_TABLE (CALL1I (comp-ctxt-funcs-h, Vcomp_ctxt));
4968 for (ptrdiff_t i = 0; i < HASH_TABLE_SIZE (func_h); i++) 4964 DOHASH (func_h, i) declare_function (HASH_VALUE (func_h, i));
4969 if (!hash_unused_entry_key_p (HASH_KEY (func_h, i)))
4970 declare_function (HASH_VALUE (func_h, i));
4971 /* Compile all functions. Can't be done before because the 4965 /* Compile all functions. Can't be done before because the
4972 relocation structs has to be already defined. */ 4966 relocation structs has to be already defined. */
4973 for (ptrdiff_t i = 0; i < HASH_TABLE_SIZE (func_h); i++) 4967 DOHASH (func_h, i) compile_function (HASH_VALUE (func_h, i));
4974 if (!hash_unused_entry_key_p (HASH_KEY (func_h, i)))
4975 compile_function (HASH_VALUE (func_h, i));
4976 4968
4977 /* Work around bug#46495 (GCC PR99126). */ 4969 /* Work around bug#46495 (GCC PR99126). */
4978#if defined (WIDE_EMACS_INT) \ 4970#if defined (WIDE_EMACS_INT) \
diff --git a/src/composite.c b/src/composite.c
index 78c884dd72d..d9233fe0cc0 100644
--- a/src/composite.c
+++ b/src/composite.c
@@ -687,17 +687,13 @@ composition_gstring_cache_clear_font (Lisp_Object font_object)
687{ 687{
688 struct Lisp_Hash_Table *h = XHASH_TABLE (gstring_hash_table); 688 struct Lisp_Hash_Table *h = XHASH_TABLE (gstring_hash_table);
689 689
690 for (ptrdiff_t i = 0; i < HASH_TABLE_SIZE (h); ++i) 690 DOHASH (h, i)
691 { 691 {
692 Lisp_Object k = HASH_KEY (h, i); 692 Lisp_Object k = HASH_KEY (h, i);
693 Lisp_Object gstring = HASH_VALUE (h, i);
693 694
694 if (!hash_unused_entry_key_p (k)) 695 if (EQ (LGSTRING_FONT (gstring), font_object))
695 { 696 hash_remove_from_table (h, k);
696 Lisp_Object gstring = HASH_VALUE (h, i);
697
698 if (EQ (LGSTRING_FONT (gstring), font_object))
699 hash_remove_from_table (h, k);
700 }
701 } 697 }
702} 698}
703 699
diff --git a/src/emacs-module.c b/src/emacs-module.c
index 00ae33dfa2c..77dd2b9152c 100644
--- a/src/emacs-module.c
+++ b/src/emacs-module.c
@@ -410,12 +410,9 @@ module_global_reference_p (emacs_value v, ptrdiff_t *n)
410 struct Lisp_Hash_Table *h = XHASH_TABLE (Vmodule_refs_hash); 410 struct Lisp_Hash_Table *h = XHASH_TABLE (Vmodule_refs_hash);
411 /* Note that we can't use `hash_lookup' because V might be a local 411 /* Note that we can't use `hash_lookup' because V might be a local
412 reference that's identical to some global reference. */ 412 reference that's identical to some global reference. */
413 for (ptrdiff_t i = 0; i < HASH_TABLE_SIZE (h); ++i) 413 DOHASH (h, i)
414 { 414 if (&XMODULE_GLOBAL_REFERENCE (HASH_VALUE (h, i))->value == v)
415 if (!hash_unused_entry_key_p (HASH_KEY (h, i)) 415 return true;
416 && &XMODULE_GLOBAL_REFERENCE (HASH_VALUE (h, i))->value == v)
417 return true;
418 }
419 /* Only used for debugging, so we don't care about overflow, just 416 /* Only used for debugging, so we don't care about overflow, just
420 make sure the operation is defined. */ 417 make sure the operation is defined. */
421 ckd_add (n, *n, h->count); 418 ckd_add (n, *n, h->count);
diff --git a/src/fns.c b/src/fns.c
index 15bbd270311..4531b237824 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -5655,14 +5655,7 @@ FUNCTION is called with two arguments, KEY and VALUE.
5655 (Lisp_Object function, Lisp_Object table) 5655 (Lisp_Object function, Lisp_Object table)
5656{ 5656{
5657 struct Lisp_Hash_Table *h = check_hash_table (table); 5657 struct Lisp_Hash_Table *h = check_hash_table (table);
5658 5658 DOHASH (h, i) call2 (function, HASH_KEY (h, i), HASH_VALUE (h, i));
5659 for (ptrdiff_t i = 0; i < HASH_TABLE_SIZE (h); ++i)
5660 {
5661 Lisp_Object k = HASH_KEY (h, i);
5662 if (!hash_unused_entry_key_p (k))
5663 call2 (function, k, HASH_VALUE (h, i));
5664 }
5665
5666 return Qnil; 5659 return Qnil;
5667} 5660}
5668 5661
diff --git a/src/json.c b/src/json.c
index 266905f1c34..5434780ba13 100644
--- a/src/json.c
+++ b/src/json.c
@@ -361,33 +361,30 @@ lisp_to_json_nonscalar_1 (Lisp_Object lisp,
361 json = json_check (json_object ()); 361 json = json_check (json_object ());
362 count = SPECPDL_INDEX (); 362 count = SPECPDL_INDEX ();
363 record_unwind_protect_ptr (json_release_object, json); 363 record_unwind_protect_ptr (json_release_object, json);
364 for (ptrdiff_t i = 0; i < HASH_TABLE_SIZE (h); ++i) 364 DOHASH (h, i)
365 { 365 {
366 Lisp_Object key = HASH_KEY (h, i); 366 Lisp_Object key = HASH_KEY (h, i);
367 if (!hash_unused_entry_key_p (key)) 367 CHECK_STRING (key);
368 { 368 Lisp_Object ekey = json_encode (key);
369 CHECK_STRING (key); 369 /* We can't specify the length, so the string must be
370 Lisp_Object ekey = json_encode (key); 370 null-terminated. */
371 /* We can't specify the length, so the string must be 371 check_string_without_embedded_nulls (ekey);
372 null-terminated. */ 372 const char *key_str = SSDATA (ekey);
373 check_string_without_embedded_nulls (ekey); 373 /* Reject duplicate keys. These are possible if the hash
374 const char *key_str = SSDATA (ekey); 374 table test is not `equal'. */
375 /* Reject duplicate keys. These are possible if the hash 375 if (json_object_get (json, key_str) != NULL)
376 table test is not `equal'. */ 376 wrong_type_argument (Qjson_value_p, lisp);
377 if (json_object_get (json, key_str) != NULL) 377 int status
378 wrong_type_argument (Qjson_value_p, lisp); 378 = json_object_set_new (json, key_str,
379 int status 379 lisp_to_json (HASH_VALUE (h, i), conf));
380 = json_object_set_new (json, key_str, 380 if (status == -1)
381 lisp_to_json (HASH_VALUE (h, i), conf)); 381 {
382 if (status == -1) 382 /* A failure can be caused either by an invalid key or
383 { 383 by low memory. */
384 /* A failure can be caused either by an invalid key or 384 json_check_utf8 (ekey);
385 by low memory. */ 385 json_out_of_memory ();
386 json_check_utf8 (ekey); 386 }
387 json_out_of_memory (); 387 }
388 }
389 }
390 }
391 } 388 }
392 else if (NILP (lisp)) 389 else if (NILP (lisp))
393 return json_check (json_object ()); 390 return json_check (json_object ());
diff --git a/src/lisp.h b/src/lisp.h
index f0beafba42c..edea7cc23bb 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -2579,6 +2579,14 @@ hash_from_key (struct Lisp_Hash_Table *h, Lisp_Object key)
2579 return h->test->hashfn (key, h); 2579 return h->test->hashfn (key, h);
2580} 2580}
2581 2581
2582/* Hash table iteration construct (roughly an inlined maphash):
2583 Iterate IDXVAR as index over valid entries of TABLE.
2584 The body may remove the current entry or alter its value slot, but not
2585 mutate TABLE in any other way. */
2586#define DOHASH(TABLE, IDXVAR) \
2587 for (ptrdiff_t IDXVAR = 0; IDXVAR < (TABLE)->table_size; IDXVAR++) \
2588 if (!hash_unused_entry_key_p (HASH_KEY (TABLE, IDXVAR)))
2589
2582void hash_table_thaw (Lisp_Object hash_table); 2590void hash_table_thaw (Lisp_Object hash_table);
2583 2591
2584/* Default size for hash tables if not specified. */ 2592/* Default size for hash tables if not specified. */
diff --git a/src/minibuf.c b/src/minibuf.c
index 8198dc0f360..857b62d94f0 100644
--- a/src/minibuf.c
+++ b/src/minibuf.c
@@ -2114,10 +2114,10 @@ the values STRING, PREDICATE and `lambda'. */)
2114 goto found_matching_key; 2114 goto found_matching_key;
2115 } 2115 }
2116 else 2116 else
2117 for (i = 0; i < HASH_TABLE_SIZE (h); ++i) 2117 DOHASH (h, j)
2118 { 2118 {
2119 i = j;
2119 tem = HASH_KEY (h, i); 2120 tem = HASH_KEY (h, i);
2120 if (hash_unused_entry_key_p (tem)) continue;
2121 Lisp_Object strkey = (SYMBOLP (tem) ? Fsymbol_name (tem) : tem); 2121 Lisp_Object strkey = (SYMBOLP (tem) ? Fsymbol_name (tem) : tem);
2122 if (!STRINGP (strkey)) continue; 2122 if (!STRINGP (strkey)) continue;
2123 if (BASE_EQ (Fcompare_strings (string, Qnil, Qnil, 2123 if (BASE_EQ (Fcompare_strings (string, Qnil, Qnil,
diff --git a/src/print.c b/src/print.c
index 61999c096aa..c61fb3cd574 100644
--- a/src/print.c
+++ b/src/print.c
@@ -1285,15 +1285,9 @@ print (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
1285 { /* Remove unnecessary objects, which appear only once in OBJ; 1285 { /* Remove unnecessary objects, which appear only once in OBJ;
1286 that is, whose status is Qt. */ 1286 that is, whose status is Qt. */
1287 struct Lisp_Hash_Table *h = XHASH_TABLE (Vprint_number_table); 1287 struct Lisp_Hash_Table *h = XHASH_TABLE (Vprint_number_table);
1288 ptrdiff_t i; 1288 DOHASH (h, i)
1289 1289 if (EQ (HASH_VALUE (h, i), Qt))
1290 for (i = 0; i < HASH_TABLE_SIZE (h); ++i) 1290 Fremhash (HASH_KEY (h, i), Vprint_number_table);
1291 {
1292 Lisp_Object key = HASH_KEY (h, i);
1293 if (!hash_unused_entry_key_p (key)
1294 && EQ (HASH_VALUE (h, i), Qt))
1295 Fremhash (key, Vprint_number_table);
1296 }
1297 } 1291 }
1298 } 1292 }
1299 1293