diff --git a/ChangeLog b/ChangeLog index f696a9d01a..ae29f934eb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +Sat Dec 1 13:24:47 2007 Koichi Sasada + + * insnhelper.ci (vm_yield_with_cfunc): fix to passing argc on third + parameter of IFUNC. [ruby-dev:32329] + + * enumerator.c: fix to pass exact number of argument. + + * eval.c (rb_yield_values2): added. + + * include/ruby/ruby.h: ditto. + + * bootstraptest/test_knownbug.rb: move a fixed test. + + * bootstraptest/test_block.rb: ditto. + Sat Dec 1 03:34:32 2007 Nobuyoshi Nakada * parse.y (newline_node): always remove NODE_BEGIN. diff --git a/bootstraptest/test_block.rb b/bootstraptest/test_block.rb index d90f5ede89..b4334ee44f 100644 --- a/bootstraptest/test_block.rb +++ b/bootstraptest/test_block.rb @@ -441,4 +441,17 @@ assert_equal 'ok', %q{ :ng end }, '[ruby-dev:31472]' +assert_equal 'ok', %q{ + class C + def each + yield [1,2] + yield 1,2 + end + end + vs1 = [] + C.new.each {|*v| vs1 << v } + vs2 = [] + C.new.to_enum.each {|*v| vs2 << v } + vs1 == vs2 ? :ok : :ng +}, '[ruby-dev:32329]' diff --git a/bootstraptest/test_knownbug.rb b/bootstraptest/test_knownbug.rb index 947a944225..c4104b666c 100644 --- a/bootstraptest/test_knownbug.rb +++ b/bootstraptest/test_knownbug.rb @@ -10,20 +10,6 @@ assert_normal_exit %q{ YAML.load("2000-01-01 00:00:00.#{"0"*1000} +00:00\n") }, '[ruby-core:13735]' -assert_equal 'ok', %q{ - class C - def each - yield [1,2] - yield 1,2 - end - end - vs1 = [] - C.new.each {|*v| vs1 << v } - vs2 = [] - C.new.to_enum.each {|*v| vs2 << v } - vs1 == vs2 ? :ok : :ng -}, '[ruby-dev:32329]' - assert_equal '..f00000000', %q{ sprintf("%x", -2**32) }, '[ruby-dev:32351]' diff --git a/enumerator.c b/enumerator.c index 487ce51bb9..ffa892adea 100644 --- a/enumerator.c +++ b/enumerator.c @@ -36,7 +36,7 @@ proc_call(VALUE proc, VALUE args) } struct enumerator; -typedef VALUE enum_iter(VALUE, struct enumerator *); +typedef VALUE enum_iter(VALUE, struct enumerator *, VALUE); struct enumerator { VALUE method; @@ -77,7 +77,7 @@ enumerator_ptr(VALUE obj) } static VALUE -enumerator_iter_i(VALUE i, struct enumerator *e) +enumerator_iter_i(VALUE i, struct enumerator *e, VALUE argc) { return rb_yield(proc_call(e->proc, i)); } @@ -224,6 +224,17 @@ enumerator_allocate(VALUE klass) enumerator_mark, -1, ptr); } +static VALUE +enumerator_each_i(VALUE v, VALUE enum_obj, VALUE argc) +{ + if (argc == 1) { + return rb_yield(v); + } + else { + return rb_yield_values2(argc, RARRAY_PTR(v)); + } +} + static VALUE enumerator_init(VALUE enum_obj, VALUE obj, VALUE meth, int argc, VALUE *argv) { @@ -235,7 +246,7 @@ enumerator_init(VALUE enum_obj, VALUE obj, VALUE meth, int argc, VALUE *argv) ptr->iter = enumerator_iter_i; } else { - ptr->iter = (enum_iter *)rb_yield; + ptr->iter = (enum_iter *)enumerator_each_i; } if (argc) ptr->args = rb_ary_new4(argc, argv); ptr->fib = 0; diff --git a/eval.c b/eval.c index 17371a8d5f..6cfd503e60 100644 --- a/eval.c +++ b/eval.c @@ -952,6 +952,12 @@ rb_yield_values(int n, ...) return rb_yield_0(n, argv); } +VALUE +rb_yield_values2(int argc, VALUE *argv) +{ + return rb_yield_0(argc, argv); +} + VALUE rb_yield_splat(VALUE values) { diff --git a/include/ruby/ruby.h b/include/ruby/ruby.h index fd8e9a6064..b0b5153b66 100644 --- a/include/ruby/ruby.h +++ b/include/ruby/ruby.h @@ -772,6 +772,7 @@ PRINTF_ARGS(void rb_compile_warn(const char *, int, const char*, ...), 3, 4); VALUE rb_each(VALUE); VALUE rb_yield(VALUE); VALUE rb_yield_values(int n, ...); +VALUE rb_yield_values2(int n, VALUE *argv); VALUE rb_yield_splat(VALUE); int rb_block_given_p(void); void rb_need_block(void); diff --git a/insnhelper.ci b/insnhelper.ci index 12ce484612..743cd64dff 100644 --- a/insnhelper.ci +++ b/insnhelper.ci @@ -661,7 +661,7 @@ vm_yield_with_cfunc(rb_thread_t *th, rb_block_t *block, self, (VALUE)block->dfp, 0, th->cfp->sp, block->lfp, 1); - val = (*ifunc->nd_cfnc) (arg, ifunc->nd_tval, Qnil); + val = (*ifunc->nd_cfnc) (arg, ifunc->nd_tval, (VALUE) argc); th->cfp++; return val;