From b66c5c3b1b31581960bcb69d49b618d69ae2a87f Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Wed, 14 May 2025 10:23:16 +0900 Subject: [PATCH] Revert "[Bug #21331] Prohibit modification during stlike loop" This reverts commit bb180b87b43c45e17ff49735a26d7a188d5c8396, which caused "malloc during GC" error on wasm. --- hash.c | 78 ++++++------------------------------------ test/ruby/test_hash.rb | 8 ----- 2 files changed, 10 insertions(+), 76 deletions(-) diff --git a/hash.c b/hash.c index 4c25bd6336..2a2d5c31a4 100644 --- a/hash.c +++ b/hash.c @@ -880,7 +880,7 @@ ar_general_foreach(VALUE hash, st_foreach_check_callback_func *func, st_update_c return 0; case ST_REPLACE: if (replace) { - (*replace)(&key, &val, arg, TRUE); + retval = (*replace)(&key, &val, arg, TRUE); // TODO: pair should be same as pair before. pair = RHASH_AR_TABLE_REF(hash, i); @@ -1404,84 +1404,26 @@ hash_foreach_ensure(VALUE hash) return 0; } -struct hash_stlike_foreach_arg { - VALUE hash; - st_foreach_callback_func *func; - VALUE arg; -}; - -static VALUE -hash_stlike_foreach_call(VALUE args) -{ - struct hash_stlike_foreach_arg *argp = (void *)args; - VALUE hash = argp->hash; - st_foreach_callback_func *func = argp->func; - VALUE arg = argp->arg; - int ret; - - if (RHASH_AR_TABLE_P(hash)) { - ret = ar_foreach(hash, func, arg); - } - else { - ret = st_foreach(RHASH_ST_TABLE(hash), func, arg); - } - return (VALUE)ret; -} - int rb_hash_stlike_foreach(VALUE hash, st_foreach_callback_func *func, st_data_t arg) { - struct hash_stlike_foreach_arg args = { - .hash = hash, - .func = func, - .arg = arg, - }; - hash_iter_lev_inc(hash); - VALUE ret = rb_ensure(hash_stlike_foreach_call, (VALUE)&args, - hash_foreach_ensure, hash); - return (int)ret; -} - -struct hash_stlike_foreach_with_replace_arg { - VALUE hash; - st_foreach_check_callback_func *func; - st_update_callback_func *replace; - VALUE arg; -}; - -static VALUE -hash_stlike_foreach_with_replace_call(VALUE args) -{ - struct hash_stlike_foreach_with_replace_arg *argp = (void *)args; - VALUE hash = argp->hash; - st_foreach_check_callback_func *func = argp->func; - st_update_callback_func *replace = argp->replace; - VALUE arg = argp->arg; - int ret; - if (RHASH_AR_TABLE_P(hash)) { - ret = ar_foreach_with_replace(hash, func, replace, arg); + return ar_foreach(hash, func, arg); } else { - ret = st_foreach_with_replace(RHASH_ST_TABLE(hash), func, replace, arg); + return st_foreach(RHASH_ST_TABLE(hash), func, arg); } - return (VALUE)ret; } int -rb_hash_stlike_foreach_with_replace(VALUE hash, st_foreach_check_callback_func *func, - st_update_callback_func *replace, st_data_t arg) +rb_hash_stlike_foreach_with_replace(VALUE hash, st_foreach_check_callback_func *func, st_update_callback_func *replace, st_data_t arg) { - struct hash_stlike_foreach_with_replace_arg args = { - .hash = hash, - .func = func, - .replace = replace, - .arg = arg, - }; - hash_iter_lev_inc(hash); - VALUE ret = rb_ensure(hash_stlike_foreach_with_replace_call, (VALUE)&args, - hash_foreach_ensure, hash); - return (int)ret; + if (RHASH_AR_TABLE_P(hash)) { + return ar_foreach_with_replace(hash, func, replace, arg); + } + else { + return st_foreach_with_replace(RHASH_ST_TABLE(hash), func, replace, arg); + } } static VALUE diff --git a/test/ruby/test_hash.rb b/test/ruby/test_hash.rb index 76af5b6183..b6c18ea958 100644 --- a/test/ruby/test_hash.rb +++ b/test/ruby/test_hash.rb @@ -1853,14 +1853,6 @@ class TestHash < Test::Unit::TestCase end end assert_equal(@cls[a: 2, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7, h: 8, i: 9, j: 10], x) - - x = (1..1337).to_h {|k| [k, k]} - assert_raise_with_message(RuntimeError, /rehash during iteration/) do - x.transform_values! {|v| - x.rehash if v == 1337 - v * 2 - } - end end def hrec h, n, &b