summaryrefslogtreecommitdiff
path: root/thread.c
diff options
context:
space:
mode:
Diffstat (limited to 'thread.c')
-rw-r--r--thread.c29
1 files changed, 16 insertions, 13 deletions
diff --git a/thread.c b/thread.c
index 360c6cb6b9..eb9b27f3d6 100644
--- a/thread.c
+++ b/thread.c
@@ -4705,12 +4705,10 @@ ID rb_frame_last_func(void);
*/
static VALUE
-recursive_list_access(void)
+recursive_list_access(VALUE sym)
{
rb_thread_t *th = GET_THREAD();
VALUE hash = threadptr_recursive_hash(th);
- 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();
@@ -4798,25 +4796,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 {
@@ -4850,9 +4846,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;
@@ -4874,8 +4872,8 @@ exec_recursive(VALUE (*func) (VALUE, VALUE, int), VALUE obj, VALUE pairid, VALUE
recursive_push(p.list, ID2SYM(recursive_key), 0);
recursive_push(p.list, p.objid, p.pairid);
result = rb_catch_protect(p.list, exec_recursive_i, (VALUE)&p, &state);
- recursive_pop(p.list, p.objid, p.pairid);
- recursive_pop(p.list, ID2SYM(recursive_key), 0);
+ if (!recursive_pop(p.list, p.objid, p.pairid)) goto invalid;
+ if (!recursive_pop(p.list, ID2SYM(recursive_key), 0)) goto invalid;
if (state) JUMP_TAG(state);
if (result == p.list) {
result = (*func)(obj, arg, TRUE);
@@ -4888,7 +4886,12 @@ exec_recursive(VALUE (*func) (VALUE, VALUE, int), VALUE obj, VALUE pairid, VALUE
result = (*func)(obj, arg, FALSE);
}
POP_TAG();
- recursive_pop(p.list, p.objid, p.pairid);
+ if (!recursive_pop(p.list, p.objid, p.pairid)) {
+ invalid:
+ rb_raise(rb_eTypeError, "invalid inspect_tbl pair_list "
+ "for %+"PRIsVALUE" in %+"PRIsVALUE,
+ sym, rb_thread_current());
+ }
if (state) JUMP_TAG(state);
}
}