e$B1sF#$G$9!#e(B
[ruby-core:24794] e$B$H;w$?$h$&$JLdBj$O!"e(Brb_block_call
e$B$G$b5/$-$k$h$&$G$9!#e(B
$ ./ruby -e ’
class C
include Enumerable
alias :each :min
end
C.new.min
’
Segmentation fault
min e$B0J30$G$be(B Enumerable e$B$N%a%=%C%I$GBgDqMn$A$k$_$?$$$G$9!#e(B
rb_funcall_no_recursive e$B$r??;w$Fe(B rb_block_call_no_recursive
e$B$r:n$C$Fe(B
e$B8+$^$7$?!#e(B[ruby-dev:39592]
e$B$NAj8_:F5"$NLdBj$OF1$8$h$&$K$"$k$H;W$$$^$9!#e(B
e$B$3$NJ}?K$@$H$[$$9$Y$F$Ne(B rb_block_call
e$B$N8F$S=P$7$r=q$-49$($FLa$jCM$,e(B
Qundef
e$B$G$J$$$+$I$&$+%A%’%C%/$9$kI,MW$,$"$j$=$&$G$9!#2DFI@-$d@-G=$re(B
e$B5>@7$K$7$F$G$b!"$3$N$h$&$J0[>o$J%W%m%0%i%`$r5_:Q$9$Y$-$G$7$g$&$+e(B
(Qundef e$B$rJV$5$:D>@\Nc30$rEj$2$l$P$b$&>/$7$9$C$-$j$9$k!)e(B)
Index: enum.c
— enum.c (revision 25576)
+++ enum.c (working copy)
@@ -1101,7 +1101,10 @@
rb_block_call(obj, id_each, 0, 0, min_ii, (VALUE)result);
}
else {
- rb_block_call(obj, id_each, 0, 0, min_i, (VALUE)result);
- VALUE ret = rb_block_call_no_recursive(obj, id_each, 0, 0, min_i,
(VALUE)result, enum_min); - if (ret == Qundef) {
-
rb_raise(rb_eRuntimeError, "recursive call to Enumerable#min");
- }
}
if (result[0] == Qundef) return Qnil;
return result[0];
Index: vm_eval.c
===================================================================
— vm_eval.c (revision 25576)
+++ vm_eval.c (working copy)
@@ -815,7 +815,48 @@
return rb_iterate(iterate_method, (VALUE)&arg, bl_proc, data2);
}
+struct iter_method_arg_no_recursive {
- struct iter_method_arg arg;
- VALUE (*func)();
+};
+static VALUE
+iterate_method_no_recursive(VALUE obj)
+{
- const struct iter_method_arg_no_recursive * arg =
-
(struct iter_method_arg_no_recursive *) obj;
- rb_method_entry_t *me = rb_search_method_emtry(arg->arg.obj,
arg->arg.mid); - rb_thread_t *th = GET_THREAD();
- int call_status;
- if (!me) return Qundef;
- if (me->def && me->def->type == VM_METHOD_TYPE_CFUNC &&
- me->def->body.cfunc.func == arg->func)
- return Qundef;
- call_status = rb_method_call_status(th, me, CALL_FCALL, Qundef);
- if (call_status != NOEX_OK) {
- return Qundef;
- }
- stack_check();
- iterate_method((VALUE) &arg->arg);
+}
VALUE
+rb_block_call_no_recursive(VALUE obj, ID mid, int argc, VALUE * argv,
-
VALUE (*bl_proc) (ANYARGS), VALUE data2,
-
VALUE (*func)())
+{
- struct iter_method_arg_no_recursive arg;
- arg.arg.obj = obj;
- arg.arg.mid = mid;
- arg.arg.argc = argc;
- arg.arg.argv = argv;
- arg.func = func;
- return rb_iterate(iterate_method_no_recursive, (VALUE)&arg,
bl_proc, data2);
+}
+VALUE
rb_each(VALUE obj)
{
return rb_call(obj, idEach, 0, 0, CALL_FCALL);