diff options
-rw-r--r-- | ChangeLog | 10 | ||||
-rw-r--r-- | eval.c | 13 | ||||
-rw-r--r-- | test/ruby/test_objectspace.rb | 7 | ||||
-rw-r--r-- | thread.c | 5 |
4 files changed, 34 insertions, 1 deletions
@@ -1,3 +1,13 @@ +Tue Dec 9 10:16:24 2014 Nobuyoshi Nakada <nobu@ruby-lang.org> + + * eval.c (rb_frame_last_func): return the most recent frame method + name. + + * thread.c (recursive_list_access): use the last method name, + instead of the current method name which can be unset in some + cases, not to use a symbol by the invalid ID. + [ruby-core:66742] [Bug #10579] + Sun Dec 7 19:36:12 2014 Kazuki Tsujimoto <kazuki@callcc.net> * ext/socket/basicsocket.c, ext/socket/sockssocket.c: @@ -1030,6 +1030,19 @@ prev_frame_func(void) return frame_func_id(prev_cfp); } +ID +rb_frame_last_func(void) +{ + rb_thread_t *th = GET_THREAD(); + rb_control_frame_t *cfp = th->cfp; + ID mid; + + while (!(mid = frame_func_id(cfp)) && + (cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp), + !RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(th, cfp))); + return mid; +} + /* * call-seq: * append_features(mod) -> mod diff --git a/test/ruby/test_objectspace.rb b/test/ruby/test_objectspace.rb index 4b8ae74a3c..d519041f0b 100644 --- a/test/ruby/test_objectspace.rb +++ b/test/ruby/test_objectspace.rb @@ -102,4 +102,11 @@ End } End end + + def test_each_object_recursive_key + assert_normal_exit(<<-'end;', '[ruby-core:66742] [Bug #10579]') + h = {["foo"]=>nil} + p Thread.current[:__recursive_key__] + end; + end end @@ -4696,6 +4696,8 @@ threadptr_recursive_hash_set(rb_thread_t *th, VALUE hash) th->local_storage_recursive_hash = hash; } +ID rb_frame_last_func(void); + /* * Returns the current "recursive list" used to detect recursion. * This list is a hash table, unique for the current thread and for @@ -4707,7 +4709,8 @@ recursive_list_access(void) { rb_thread_t *th = GET_THREAD(); VALUE hash = threadptr_recursive_hash(th); - VALUE sym = ID2SYM(rb_frame_this_func()); + ID mid = rb_frame_last_func(); + VALUE sym = mid ? ID2SYM(mid) : ID2SYM(idNULL); VALUE list; if (NIL_P(hash) || !RB_TYPE_P(hash, T_HASH)) { hash = ident_hash_new(); |