1
0
Fork 0
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:
ko1 2008-12-25 03:51:35 +00:00
parent f6e435fe87
commit 7c982059ea
4 changed files with 57 additions and 23 deletions

View file

@ -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.

View file

@ -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
View file

@ -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
View file

@ -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);