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
This commit is contained in:
usa 2015-01-14 07:04:09 +00:00
parent e6a5f817d6
commit 9120d051e1
5 changed files with 50 additions and 11 deletions

View file

@ -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.

13
eval.c
View file

@ -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

View file

@ -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

View file

@ -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);
}

View file

@ -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