mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* 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. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@20980 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
f6e435fe87
commit
7c982059ea
4 changed files with 57 additions and 23 deletions
10
ChangeLog
10
ChangeLog
|
@ -1,3 +1,13 @@
|
|||
Thu Dec 25 12:49:12 2008 Koichi Sasada <ko1@atdot.net>
|
||||
|
||||
* 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@atdot.net>
|
||||
|
||||
* vm_insnhelper.c (vm_yield_with_cfunc): check block has Proc.
|
||||
|
|
|
@ -394,3 +394,27 @@ assert_equal 'ok', %q{
|
|||
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'
|
||||
|
|
22
proc.c
22
proc.c
|
@ -353,7 +353,6 @@ proc_new(VALUE klass, int is_lambda)
|
|||
!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 @@ proc_new(VALUE klass, int is_lambda)
|
|||
|
||||
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 @@ proc_new(VALUE klass, int is_lambda)
|
|||
}
|
||||
|
||||
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);
|
||||
|
|
24
vm.c
24
vm.c
|
@ -385,20 +385,18 @@ vm_stack_to_heap(rb_thread_t * const th)
|
|||
/* 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 @@ vm_make_proc(rb_thread_t *th, const rb_block_t *block, VALUE klass)
|
|||
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);
|
||||
|
|
Loading…
Add table
Reference in a new issue