ruby-changes:9442
From: ko1 <ko1@a...>
Date: Thu, 25 Dec 2008 12:52:17 +0900 (JST)
Subject: [ruby-changes:9442] Ruby:r20980 (trunk): * proc.c (proc_new): should use proc_dup() if block has Proc.
ko1 2008-12-25 12:51:35 +0900 (Thu, 25 Dec 2008) New Revision: 20980 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=20980 Log: * proc.c (proc_new): should use proc_dup() if block has Proc. * vm.c (vm_make_proc_from_block): should use rb_cProc for block. * vm.c (vm_make_proc): add an assertion. * bootstraptest/test_proc.rb: add a test. Modified files: trunk/ChangeLog trunk/bootstraptest/test_proc.rb trunk/proc.c trunk/vm.c Index: ChangeLog =================================================================== --- ChangeLog (revision 20979) +++ ChangeLog (revision 20980) @@ -1,3 +1,13 @@ +Thu Dec 25 12:49:12 2008 Koichi Sasada <ko1@a...> + + * proc.c (proc_new): should use proc_dup() if block has Proc. + + * vm.c (vm_make_proc_from_block): should use rb_cProc for block. + + * vm.c (vm_make_proc): add an assertion. + + * bootstraptest/test_proc.rb: add a test. + Thu Dec 25 12:44:27 2008 Koichi Sasada <ko1@a...> * vm_insnhelper.c (vm_yield_with_cfunc): check block has Proc. Index: bootstraptest/test_proc.rb =================================================================== --- bootstraptest/test_proc.rb (revision 20979) +++ bootstraptest/test_proc.rb (revision 20980) @@ -394,3 +394,27 @@ a_proc = give_it f.call_it(&give_it()) }, '[ruby-core:15711]' + +assert_equal 'foo!', %q{ + class FooProc < Proc + def initialize + @foo = "foo!" + end + + def bar + @foo + end + end + + def bar + FooProc.new &lambda{ + p 1 + } + end + + fp = bar(&lambda{ + p 2 + }) + + fp.bar +}, 'Subclass of Proc' Index: proc.c =================================================================== --- proc.c (revision 20979) +++ proc.c (revision 20980) @@ -353,7 +353,6 @@ !RUBY_VM_CLASS_SPECIAL_P(cfp->lfp[0])) { block = GC_GUARDED_PTR_REF(cfp->lfp[0]); - cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp); } else { cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp); @@ -363,15 +362,6 @@ block = GC_GUARDED_PTR_REF(cfp->lfp[0]); - if (block->proc) { - return block->proc; - } - - /* TODO: check more (cfp limit, called via cfunc, etc) */ - while (cfp->dfp != block->dfp) { - cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp); - } - if (is_lambda) { rb_warn("tried to create Proc object without a block"); } @@ -383,8 +373,16 @@ } procval = block->proc; - if (procval && RBASIC(procval)->klass == klass) { - return procval; + + if (procval) { + if (RBASIC(procval)->klass == klass) { + return procval; + } + else { + VALUE newprocval = proc_dup(procval); + RBASIC(newprocval)->klass = klass; + return newprocval; + } } procval = vm_make_proc(th, block, klass); Index: vm.c =================================================================== --- vm.c (revision 20979) +++ vm.c (revision 20980) @@ -385,20 +385,18 @@ /* Proc */ static VALUE -vm_make_proc_from_block(rb_thread_t *th, rb_block_t *block, VALUE klass) +vm_make_proc_from_block(rb_thread_t *th, rb_block_t *block) { - VALUE procval; + VALUE proc = block->proc; - procval = block->proc; - if (procval && RBASIC(procval)->klass == klass) { - return procval; + if (block->proc) { + return block->proc; } - procval = vm_make_proc(th, block, klass); - if (!block->proc) { - block->proc = procval; - } - return procval; + proc = vm_make_proc(th, block, rb_cProc); + block->proc = proc; + + return proc; } VALUE @@ -408,12 +406,16 @@ rb_proc_t *proc; rb_control_frame_t *cfp = RUBY_VM_GET_CFP_FROM_BLOCK_PTR(block); + if (block->proc) { + rb_bug("vm_make_proc: Proc value is already created."); + } + if (GC_GUARDED_PTR_REF(cfp->lfp[0])) { if (!RUBY_VM_CLASS_SPECIAL_P(cfp->lfp[0])) { rb_proc_t *p; blockprocval = vm_make_proc_from_block( - th, (rb_block_t *)GC_GUARDED_PTR_REF(*cfp->lfp), klass); + th, (rb_block_t *)GC_GUARDED_PTR_REF(*cfp->lfp)); GetProcPtr(blockprocval, p); *cfp->lfp = GC_GUARDED_PTR(&p->block); -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/