aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog10
-rw-r--r--eval.c13
-rw-r--r--test/ruby/test_objectspace.rb7
-rw-r--r--thread.c5
4 files changed, 34 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index 50520e4976..74fa222989 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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:
diff --git a/eval.c b/eval.c
index 8390c7dc31..dc5af43928 100644
--- a/eval.c
+++ b/eval.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
diff --git a/thread.c b/thread.c
index 25cc2143e9..360c6cb6b9 100644
--- a/thread.c
+++ b/thread.c
@@ -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();