summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNobuyoshi Nakada <nobu@ruby-lang.org>2023-11-12 01:16:27 +0900
committerNobuyoshi Nakada <nobu@ruby-lang.org>2023-11-12 13:51:16 +0900
commit60e19a0b5fc9c067ee88751192dc56da618f5060 (patch)
tree95e4fc91401237558ad1c9c68fecfd5a272085f9
parent9ab64b1d70487055e8b7e02443546f524f1e7c9d (diff)
Just check if iteration level is non-zerov3_3_0_preview3
The level in ivar is no longer needed to check if iterating, only used for increment/decrement.
-rw-r--r--hash.c39
1 files changed, 16 insertions, 23 deletions
diff --git a/hash.c b/hash.c
index 951d7b62f1..e8613339ba 100644
--- a/hash.c
+++ b/hash.c
@@ -1307,17 +1307,10 @@ iter_lev_in_flags_set(VALUE hash, unsigned long lev)
RBASIC(hash)->flags = ((RBASIC(hash)->flags & ~RHASH_LEV_MASK) | ((VALUE)lev << RHASH_LEV_SHIFT));
}
-static unsigned long
-RHASH_ITER_LEV(VALUE hash)
+static inline bool
+hash_iterating_p(VALUE hash)
{
- unsigned long lev = iter_lev_in_flags(hash);
-
- if (lev == RHASH_LEV_MAX) {
- return iter_lev_in_ivar(hash);
- }
- else {
- return lev;
- }
+ return iter_lev_in_flags(hash) > 0;
}
static void
@@ -1436,7 +1429,7 @@ void rb_st_compact_table(st_table *tab);
static void
compact_after_delete(VALUE hash)
{
- if (RHASH_ITER_LEV(hash) == 0 && RHASH_ST_TABLE_P(hash)) {
+ if (!hash_iterating_p(hash) && RHASH_ST_TABLE_P(hash)) {
rb_st_compact_table(RHASH_ST_TABLE(hash));
}
}
@@ -1691,14 +1684,14 @@ tbl_update(VALUE hash, VALUE key, tbl_update_func func, st_data_t optional_arg)
return ret;
}
-#define UPDATE_CALLBACK(iter_lev, func) ((iter_lev) > 0 ? func##_noinsert : func##_insert)
+#define UPDATE_CALLBACK(iter_p, func) ((iter_p) ? func##_noinsert : func##_insert)
-#define RHASH_UPDATE_ITER(h, iter_lev, key, func, a) do { \
- tbl_update((h), (key), UPDATE_CALLBACK((iter_lev), func), (st_data_t)(a)); \
+#define RHASH_UPDATE_ITER(h, iter_p, key, func, a) do { \
+ tbl_update((h), (key), UPDATE_CALLBACK(iter_p, func), (st_data_t)(a)); \
} while (0)
#define RHASH_UPDATE(hash, key, func, arg) \
- RHASH_UPDATE_ITER(hash, RHASH_ITER_LEV(hash), key, func, arg)
+ RHASH_UPDATE_ITER(hash, hash_iterating_p(hash), key, func, arg)
static void
set_proc_default(VALUE hash, VALUE proc)
@@ -1986,7 +1979,7 @@ rb_hash_rehash(VALUE hash)
VALUE tmp;
st_table *tbl;
- if (RHASH_ITER_LEV(hash) > 0) {
+ if (hash_iterating_p(hash)) {
rb_raise(rb_eRuntimeError, "rehash during iteration");
}
rb_hash_modify_check(hash);
@@ -2465,7 +2458,7 @@ rb_hash_shift(VALUE hash)
rb_hash_modify_check(hash);
if (RHASH_AR_TABLE_P(hash)) {
var.key = Qundef;
- if (RHASH_ITER_LEV(hash) == 0) {
+ if (!hash_iterating_p(hash)) {
if (ar_shift(hash, &var.key, &var.val)) {
return rb_assoc_new(var.key, var.val);
}
@@ -2480,7 +2473,7 @@ rb_hash_shift(VALUE hash)
}
if (RHASH_ST_TABLE_P(hash)) {
var.key = Qundef;
- if (RHASH_ITER_LEV(hash) == 0) {
+ if (!hash_iterating_p(hash)) {
if (st_shift(RHASH_ST_TABLE(hash), &var.key, &var.val)) {
return rb_assoc_new(var.key, var.val);
}
@@ -2838,7 +2831,7 @@ rb_hash_clear(VALUE hash)
{
rb_hash_modify_check(hash);
- if (RHASH_ITER_LEV(hash) > 0) {
+ if (hash_iterating_p(hash)) {
rb_hash_foreach(hash, clear_i, 0);
}
else if (RHASH_AR_TABLE_P(hash)) {
@@ -2909,15 +2902,15 @@ NOINSERT_UPDATE_CALLBACK(hash_aset_str)
VALUE
rb_hash_aset(VALUE hash, VALUE key, VALUE val)
{
- unsigned long iter_lev = RHASH_ITER_LEV(hash);
+ bool iter_p = hash_iterating_p(hash);
rb_hash_modify(hash);
if (RHASH_TYPE(hash) == &identhash || rb_obj_class(key) != rb_cString) {
- RHASH_UPDATE_ITER(hash, iter_lev, key, hash_aset, val);
+ RHASH_UPDATE_ITER(hash, iter_p, key, hash_aset, val);
}
else {
- RHASH_UPDATE_ITER(hash, iter_lev, key, hash_aset_str, val);
+ RHASH_UPDATE_ITER(hash, iter_p, key, hash_aset_str, val);
}
return val;
}
@@ -2937,7 +2930,7 @@ rb_hash_replace(VALUE hash, VALUE hash2)
{
rb_hash_modify_check(hash);
if (hash == hash2) return hash;
- if (RHASH_ITER_LEV(hash) > 0) {
+ if (hash_iterating_p(hash)) {
rb_raise(rb_eRuntimeError, "can't replace hash during iteration");
}
hash2 = to_hash(hash2);