summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-01-14 07:04:09 +0000
committerusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-01-14 07:04:09 +0000
commit9120d051e14a69d3c1e439d65d85a4a8060d62fb (patch)
tree1263a58684cbdedf82ed343a11b7bae00f441881
parente6a5f817d613dbd40cf2d19cd0705a1b4c377538 (diff)
merge revision(s) 48744,48752: [Backport #10579]
* 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] * thread.c (exec_recursive): use the same last method name as recursive_push in the error message when recursive_pop failed. [ruby-core:66742] [Bug #10579] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_0_0@49246 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog16
-rw-r--r--eval.c13
-rw-r--r--test/ruby/test_objectspace.rb7
-rw-r--r--thread.c23
-rw-r--r--version.h2
5 files changed, 50 insertions, 11 deletions
diff --git a/ChangeLog b/ChangeLog
index 8ea42388cd..72f18cd68e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+Wed Jan 14 15:57:26 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * thread.c (exec_recursive): use the same last method name as
+ recursive_push in the error message when recursive_pop failed.
+ [ruby-core:66742] [Bug #10579]
+
+Wed Jan 14 15:57:26 2015 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]
+
Wed Jan 14 15:54:18 2015 Aaron Patterson <aaron@tenderlovemaking.com>
* lib/resolv.rb: fall back if canonicalization fails.
diff --git a/eval.c b/eval.c
index ec563bc4f7..453795d7b8 100644
--- a/eval.c
+++ b/eval.c
@@ -931,6 +931,19 @@ rb_frame_caller(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 3127b61abe..16fe004a2a 100644
--- a/test/ruby/test_objectspace.rb
+++ b/test/ruby/test_objectspace.rb
@@ -84,4 +84,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 5be0855040..0923e8a093 100644
--- a/thread.c
+++ b/thread.c
@@ -4675,10 +4675,9 @@ static ID recursive_key;
*/
static VALUE
-recursive_list_access(void)
+recursive_list_access(VALUE sym)
{
volatile VALUE hash = rb_thread_local_aref(rb_thread_current(), recursive_key);
- VALUE sym = ID2SYM(rb_frame_this_func());
VALUE list;
if (NIL_P(hash) || !RB_TYPE_P(hash, T_HASH)) {
hash = rb_hash_new();
@@ -4769,25 +4768,23 @@ recursive_push(VALUE list, VALUE obj, VALUE paired_obj)
* Assumes the recursion list is valid.
*/
-static void
+static int
recursive_pop(VALUE list, VALUE obj, VALUE paired_obj)
{
if (paired_obj) {
VALUE pair_list = rb_hash_lookup2(list, obj, Qundef);
if (pair_list == Qundef) {
- VALUE symname = rb_inspect(ID2SYM(rb_frame_this_func()));
- VALUE thrname = rb_inspect(rb_thread_current());
- rb_raise(rb_eTypeError, "invalid inspect_tbl pair_list for %s in %s",
- StringValuePtr(symname), StringValuePtr(thrname));
+ return 0;
}
if (RB_TYPE_P(pair_list, T_HASH)) {
rb_hash_delete(pair_list, paired_obj);
if (!RHASH_EMPTY_P(pair_list)) {
- return; /* keep hash until is empty */
+ return 1; /* keep hash until is empty */
}
}
}
rb_hash_delete(list, obj);
+ return 1;
}
struct exec_recursive_params {
@@ -4832,9 +4829,11 @@ static VALUE
exec_recursive(VALUE (*func) (VALUE, VALUE, int), VALUE obj, VALUE pairid, VALUE arg, int outer)
{
VALUE result = Qundef;
+ const ID mid = rb_frame_last_func();
+ const VALUE sym = mid ? ID2SYM(mid) : ID2SYM(idNULL);
struct exec_recursive_params p;
int outermost;
- p.list = recursive_list_access();
+ p.list = recursive_list_access(sym);
p.objid = rb_obj_id(obj);
p.obj = obj;
p.pairid = pairid;
@@ -4853,7 +4852,11 @@ exec_recursive(VALUE (*func) (VALUE, VALUE, int), VALUE obj, VALUE pairid, VALUE
if (outermost) {
recursive_push(p.list, ID2SYM(recursive_key), 0);
result = rb_catch_obj(p.list, exec_recursive_i, (VALUE)&p);
- recursive_pop(p.list, ID2SYM(recursive_key), 0);
+ if (!recursive_pop(p.list, ID2SYM(recursive_key), 0)) {
+ rb_raise(rb_eTypeError, "invalid inspect_tbl pair_list "
+ "for %+"PRIsVALUE" in %+"PRIsVALUE,
+ sym, rb_thread_current());
+ }
if (result == p.list) {
result = (*func)(obj, arg, TRUE);
}
diff --git a/version.h b/version.h
index eeeee540c2..d0a815ca6a 100644
--- a/version.h
+++ b/version.h
@@ -1,6 +1,6 @@
#define RUBY_VERSION "2.0.0"
#define RUBY_RELEASE_DATE "2015-01-14"
-#define RUBY_PATCHLEVEL 607
+#define RUBY_PATCHLEVEL 608
#define RUBY_RELEASE_YEAR 2015
#define RUBY_RELEASE_MONTH 1