ruby-changes:2865
From: ko1@a...
Date: 20 Dec 2007 16:08:11 +0900
Subject: [ruby-changes:2865] ko1 - Ruby:r14356 (trunk): * insnhelper.ci, vm.c, vm_core.h: change interface of
ko1 2007-12-20 16:07:35 +0900 (Thu, 20 Dec 2007) New Revision: 14356 Modified files: trunk/ChangeLog trunk/bootstraptest/test_block.rb trunk/bootstraptest/test_knownbug.rb trunk/cont.c trunk/eval_jump.ci trunk/insnhelper.ci trunk/insns.def trunk/proc.c trunk/signal.c trunk/thread.c trunk/vm.c trunk/vm_core.h Log: * insnhelper.ci, vm.c, vm_core.h: change interface of vm_invoke_block() to specify block ptr. [ruby-talk:266422] * cont.c, eval_jump.ci, insns.def, proc.c, signal.c, thread.c: apply above change. * bootstraptest/test_knownbug.rb: move fixed bug. * bootstraptest/test_block.rb: ditto. and add a test. http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/insnhelper.ci?r1=14356&r2=14355 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/cont.c?r1=14356&r2=14355 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/bootstraptest/test_block.rb?r1=14356&r2=14355 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/ChangeLog?r1=14356&r2=14355 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/thread.c?r1=14356&r2=14355 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/vm_core.h?r1=14356&r2=14355 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/signal.c?r1=14356&r2=14355 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/proc.c?r1=14356&r2=14355 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/vm.c?r1=14356&r2=14355 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/insns.def?r1=14356&r2=14355 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/eval_jump.ci?r1=14356&r2=14355 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/bootstraptest/test_knownbug.rb?r1=14356&r2=14355 Index: insns.def =================================================================== --- insns.def (revision 14355) +++ insns.def (revision 14356) @@ -879,13 +879,14 @@ { rb_block_t *blockptr; VALUE proc; + extern void rb_call_end_proc(VALUE data); blockptr = RUBY_VM_GET_BLOCK_PTR_IN_CFP(GET_CFP()); blockptr->iseq = blockiseq; blockptr->proc = 0; proc = vm_make_proc(th, GET_CFP(), blockptr); - rb_set_end_proc(call_end_proc, proc); + rb_set_end_proc(rb_call_end_proc, proc); } /** Index: ChangeLog =================================================================== --- ChangeLog (revision 14355) +++ ChangeLog (revision 14356) @@ -1,3 +1,15 @@ +Thu Dec 20 16:04:17 2007 Koichi Sasada <ko1@a...> + + * insnhelper.ci, vm.c, vm_core.h: change interface of + vm_invoke_block() to specify block ptr. [ruby-talk:266422] + + * cont.c, eval_jump.ci, insns.def, proc.c, signal.c, thread.c: + apply above change. + + * bootstraptest/test_knownbug.rb: move fixed bug. + + * bootstraptest/test_block.rb: ditto. and add a test. + Thu Dec 20 15:47:13 2007 Nobuyoshi Nakada <nobu@r...> * enc/iso_8859_{1..16}.c: renamed. Index: bootstraptest/test_knownbug.rb =================================================================== --- bootstraptest/test_knownbug.rb (revision 14355) +++ bootstraptest/test_knownbug.rb (revision 14356) @@ -11,27 +11,6 @@ }, '[ruby-dev:32404]' assert_equal 'ok', %q{ - class C - define_method(:foo) do |arg, &block| - if block then block.call else arg end - end - end - C.new.foo("ng") {"ok"} -}, '[ruby-talk:266422]' - -assert_equal 'ok', %q{ - STDERR.reopen(STDOUT) - class C - define_method(:foo) do |&block| - block.call if block - end - result = "ng" - new.foo() {result = "ok"} - result - end -} - -assert_equal 'ok', %q{ 1.times{ eval("break") } Index: bootstraptest/test_block.rb =================================================================== --- bootstraptest/test_block.rb (revision 14355) +++ bootstraptest/test_block.rb (revision 14356) @@ -472,3 +472,28 @@ GC.stress=false r.inspect }, '[ruby-dev:32567]' + +assert_equal NilClass.to_s, %q{ + r = false; 1.times{|&b| r = b}; r.class +} + +assert_equal 'ok', %q{ + class C + define_method(:foo) do |arg, &block| + if block then block.call else arg end + end + end + C.new.foo("ng") {"ok"} +}, '[ruby-talk:266422]' + +assert_equal 'ok', %q{ + STDERR.reopen(STDOUT) + class C + define_method(:foo) do |&block| + block.call if block + end + result = "ng" + new.foo() {result = "ok"} + result + end +} Index: vm_core.h =================================================================== --- vm_core.h (revision 14355) +++ vm_core.h (revision 14356) @@ -599,7 +599,8 @@ int rb_thread_method_id_and_class(rb_thread_t *th, ID *idp, VALUE *klassp); VALUE vm_eval_body(rb_thread_t *th); -VALUE vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc, VALUE self, int argc, VALUE *argv); +VALUE vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc, VALUE self, + int argc, VALUE *argv, rb_block_t *blockptr); VALUE vm_make_proc(rb_thread_t *th, rb_control_frame_t *cfp, rb_block_t *block); VALUE vm_make_env_object(rb_thread_t *th, rb_control_frame_t *cfp); VALUE vm_backtrace(rb_thread_t *, int); Index: eval_jump.ci =================================================================== --- eval_jump.ci (revision 14355) +++ eval_jump.ci (revision 14356) @@ -159,13 +159,10 @@ /* exit */ -static void call_end_proc _((VALUE data)); - -static void -call_end_proc(VALUE data) +void +rb_call_end_proc(VALUE data) { - /* TODO: fix me */ - proc_invoke(data, rb_ary_new2(0), Qundef, 0); + rb_proc_call(data, rb_ary_new()); } /* @@ -198,7 +195,7 @@ rb_raise(rb_eArgError, "called without a block"); } proc = rb_block_proc(); - rb_set_end_proc(call_end_proc, proc); + rb_set_end_proc(rb_call_end_proc, proc); return proc; } Index: proc.c =================================================================== --- proc.c (revision 14355) +++ proc.c (revision 14356) @@ -352,17 +352,6 @@ return rb_block_lambda(); } -VALUE -proc_invoke(VALUE self, VALUE args, VALUE alt_self, VALUE alt_class) -{ - rb_proc_t *proc; - GetProcPtr(self, proc); - - /* ignore self and klass */ - return vm_invoke_proc(GET_THREAD(), proc, proc->block.self, - RARRAY_LEN(args), RARRAY_PTR(args)); -} - /* CHECKME: are the argument checking semantics correct? */ /* @@ -401,23 +390,32 @@ proc_call(int argc, VALUE *argv, VALUE procval) { rb_proc_t *proc; + rb_block_t *blockptr = 0; GetProcPtr(procval, proc); - return vm_invoke_proc(GET_THREAD(), proc, proc->block.self, argc, argv); -} + if (BUILTIN_TYPE(proc->block.iseq) != T_NODE && + proc->block.iseq->arg_block != -1) { -static VALUE -proc_yield(int argc, VALUE *argv, VALUE procval) -{ - rb_proc_t *proc; - GetProcPtr(procval, proc); - return vm_invoke_proc(GET_THREAD(), proc, proc->block.self, argc, argv); + if (rb_block_given_p()) { + rb_proc_t *proc; + VALUE procval; + procval = rb_block_proc(); + GetProcPtr(procval, proc); + blockptr = &proc->block; + } + } + + return vm_invoke_proc(GET_THREAD(), proc, proc->block.self, + argc, argv, blockptr); } VALUE -rb_proc_call(VALUE proc, VALUE args) +rb_proc_call(VALUE self, VALUE args) { - return proc_invoke(proc, args, Qundef, 0); + rb_proc_t *proc; + GetProcPtr(self, proc); + return vm_invoke_proc(GET_THREAD(), proc, proc->block.self, + RARRAY_LEN(args), RARRAY_PTR(args), 0); } /* @@ -1489,7 +1487,7 @@ rb_define_singleton_method(rb_cProc, "new", rb_proc_s_new, -1); rb_define_method(rb_cProc, "call", proc_call, -1); rb_define_method(rb_cProc, "[]", proc_call, -1); - rb_define_method(rb_cProc, "yield", proc_yield, -1); + rb_define_method(rb_cProc, "yield", proc_call, -1); rb_define_method(rb_cProc, "to_proc", proc_to_proc, 0); rb_define_method(rb_cProc, "arity", proc_arity, 0); rb_define_method(rb_cProc, "clone", proc_clone, 0); Index: thread.c =================================================================== --- thread.c (revision 14355) +++ thread.c (revision 14356) @@ -321,7 +321,7 @@ th->local_lfp = proc->block.lfp; th->local_svar = Qnil; th->value = vm_invoke_proc(th, proc, proc->block.self, - RARRAY_LEN(args), RARRAY_PTR(args)); + RARRAY_LEN(args), RARRAY_PTR(args), 0); } else { th->value = (*th->first_func)((void *)th->first_args); Index: cont.c =================================================================== --- cont.c (revision 14355) +++ cont.c (revision 14356) @@ -596,7 +596,7 @@ th->local_lfp = proc->block.lfp; th->local_svar = Qnil; - cont->value = vm_invoke_proc(th, proc, proc->block.self, 1, &args); + cont->value = vm_invoke_proc(th, proc, proc->block.self, 1, &args, 0); } TH_POP_TAG(); Index: vm.c =================================================================== --- vm.c (revision 14355) +++ vm.c (revision 14356) @@ -465,8 +465,7 @@ } case NODE_ATTRSET:{ if (argc != 1) { - rb_raise(rb_eArgError, "wrong number of arguments (%d for 1)", - argc); + rb_raise(rb_eArgError, "wrong number of arguments (%d for 1)", argc); } val = rb_ivar_set(recv, body->nd_vid, argv[0]); break; @@ -481,7 +480,7 @@ } case NODE_BMETHOD:{ val = vm_call_bmethod(th, id, body->nd_cval, - recv, klass, argc, (VALUE *)argv); + recv, klass, argc, (VALUE *)argv, blockptr); break; } default: @@ -539,15 +538,16 @@ /* C -> Ruby: block */ static VALUE -invoke_block(rb_thread_t *th, rb_block_t *block, VALUE self, int argc, VALUE *argv) +invoke_block(rb_thread_t *th, rb_block_t *block, VALUE self, + int argc, VALUE *argv, rb_block_t *blockptr) { VALUE val; if (BUILTIN_TYPE(block->iseq) != T_NODE) { rb_iseq_t *iseq = block->iseq; rb_control_frame_t *cfp = th->cfp; + int i, opt_pc; const int arg_size = iseq->arg_size; const int type = block_proc_is_lambda(block->proc) ? FRAME_MAGIC_LAMBDA : FRAME_MAGIC_BLOCK; - int i, opt_pc; rb_vm_set_finish_env(th); @@ -557,22 +557,8 @@ cfp->sp[i] = argv[i]; } - if (iseq->arg_block == -1) { - opt_pc = vm_yield_setup_args(th, iseq, argc, cfp->sp, 0, - type == FRAME_MAGIC_LAMBDA); - } - else { - rb_block_t *blockptr = 0; - if (rb_block_given_p()) { - rb_proc_t *proc; - VALUE procval; - procval = rb_block_proc(); - GetProcPtr(procval, proc); - blockptr = &proc->block; - } - opt_pc = vm_yield_setup_args(th, iseq, argc, cfp->sp, - blockptr, type == FRAME_MAGIC_LAMBDA); - } + opt_pc = vm_yield_setup_args(th, iseq, argc, cfp->sp, blockptr, + type == FRAME_MAGIC_LAMBDA); vm_push_frame(th, iseq, type, self, GC_GUARDED_PTR(block->dfp), @@ -587,7 +573,7 @@ argc = 1; argv = &args; } - val = vm_yield_with_cfunc(th, block, block->self, argc, argv); + val = vm_yield_with_cfunc(th, block, self, argc, argv); } return val; } @@ -601,12 +587,12 @@ vm_localjump_error("no block given", Qnil, 0); } - return invoke_block(th, block, block->self, argc, argv); + return invoke_block(th, block, block->self, argc, argv, 0); } VALUE vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc, - VALUE self, int argc, VALUE *argv) + VALUE self, int argc, VALUE *argv, rb_block_t *blockptr) { VALUE val = Qundef; int state; @@ -618,7 +604,7 @@ TH_PUSH_TAG(th); if ((state = EXEC_TAG()) == 0) { th->safe_level = proc->safe_level; - val = invoke_block(th, &proc->block, self, argc, argv); + val = invoke_block(th, &proc->block, self, argc, argv, blockptr); } TH_POP_TAG(); Index: signal.c =================================================================== --- signal.c (revision 14355) +++ signal.c (revision 14356) @@ -557,7 +557,7 @@ rb_proc_t *proc; VALUE signum = INT2FIX(sig); GetProcPtr(cmd, proc); - vm_invoke_proc(GET_THREAD(), proc, proc->block.self, 1, &signum); + vm_invoke_proc(GET_THREAD(), proc, proc->block.self, 1, &signum, 0); } void Index: insnhelper.ci =================================================================== --- insnhelper.ci (revision 14355) +++ insnhelper.ci (revision 14356) @@ -391,7 +391,7 @@ static inline VALUE vm_call_bmethod(rb_thread_t *th, ID id, VALUE procval, VALUE recv, - VALUE klass, int argc, VALUE *argv) + VALUE klass, int argc, VALUE *argv, rb_block_t *blockptr) { rb_control_frame_t *cfp = th->cfp; rb_proc_t *proc; @@ -402,7 +402,7 @@ (cfp-2)->method_class = klass; GetProcPtr(procval, proc); - val = vm_invoke_proc(th, proc, recv, argc, argv); + val = vm_invoke_proc(th, proc, recv, argc, argv, blockptr); return val; } @@ -516,7 +516,7 @@ } case NODE_BMETHOD:{ VALUE *argv = cfp->sp - num; - val = vm_call_bmethod(th, id, node->nd_cval, recv, klass, num, argv); + val = vm_call_bmethod(th, id, node->nd_cval, recv, klass, num, argv, blockptr); cfp->sp += - num - 1; break; } @@ -1392,12 +1392,6 @@ } } -static void -call_end_proc(VALUE data) -{ - rb_proc_call(data, rb_ary_new2(0)); -} - static inline int check_cfunc(NODE *mn, void *func) { -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml