mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
vm.c: super in bmethod
* vm_eval.c (vm_call_super): allow bound proc method to call super method. * vm_insnhelper.c (vm_yield_with_cfunc): push defined class and bound proc method entry to the control frame. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@48348 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
ad58f04833
commit
26ae645501
7 changed files with 61 additions and 7 deletions
|
@ -1,3 +1,12 @@
|
|||
Sun Nov 9 23:25:49 2014 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||
|
||||
* vm_eval.c (vm_call_super): allow bound proc method to call super
|
||||
method.
|
||||
|
||||
* vm_insnhelper.c (vm_yield_with_cfunc): push defined class and
|
||||
bound proc method entry to the control frame.
|
||||
|
||||
|
||||
Sun Nov 9 22:46:13 2014 Tanaka Akira <akr@fsij.org>
|
||||
|
||||
* test/open-uri: Test server log in server thread.
|
||||
|
|
23
ext/-test-/proc/call_super.c
Normal file
23
ext/-test-/proc/call_super.c
Normal file
|
@ -0,0 +1,23 @@
|
|||
#include "ruby.h"
|
||||
|
||||
static VALUE
|
||||
bug_proc_call_super(VALUE yieldarg, VALUE procarg)
|
||||
{
|
||||
VALUE args[2];
|
||||
args[0] = yieldarg;
|
||||
args[1] = procarg;
|
||||
return rb_call_super(2, args);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
bug_proc_make_caller(VALUE self, VALUE procarg)
|
||||
{
|
||||
return rb_proc_new(bug_proc_call_super, procarg);
|
||||
}
|
||||
|
||||
void
|
||||
Init_call_super(VALUE klass)
|
||||
{
|
||||
rb_define_method(klass, "call_super", bug_proc_call_super, 1);
|
||||
rb_define_singleton_method(klass, "make_caller", bug_proc_make_caller, 1);
|
||||
}
|
7
ext/-test-/proc/extconf.rb
Normal file
7
ext/-test-/proc/extconf.rb
Normal file
|
@ -0,0 +1,7 @@
|
|||
$INCFLAGS << " -I$(topdir) -I$(top_srcdir)"
|
||||
$srcs = Dir[File.join($srcdir, "*.{#{SRC_EXT.join(%q{,})}}")]
|
||||
inits = $srcs.map {|s| File.basename(s, ".*")}
|
||||
inits.delete("init")
|
||||
inits.map! {|s|"X(#{s})"}
|
||||
$defs << "-DTEST_INIT_FUNCS(X)=\"#{inits.join(' ')}\""
|
||||
create_makefile("-test-/proc")
|
11
ext/-test-/proc/init.c
Normal file
11
ext/-test-/proc/init.c
Normal file
|
@ -0,0 +1,11 @@
|
|||
#include "ruby.h"
|
||||
|
||||
#define init(n) {void Init_##n(VALUE klass); Init_##n(klass);}
|
||||
|
||||
void
|
||||
Init_proc(void)
|
||||
{
|
||||
VALUE mBug = rb_define_module("Bug");
|
||||
VALUE klass = rb_define_module_under(mBug, "Proc");
|
||||
TEST_INIT_FUNCS(init);
|
||||
}
|
3
vm.c
3
vm.c
|
@ -825,7 +825,8 @@ invoke_block_from_c(rb_thread_t *th, const rb_block_t *block,
|
|||
return ret;
|
||||
}
|
||||
else {
|
||||
return vm_yield_with_cfunc(th, block, self, argc, argv, blockptr);
|
||||
return vm_yield_with_cfunc(th, block, self, defined_class,
|
||||
argc, argv, blockptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -265,7 +265,7 @@ vm_call_super(rb_thread_t *th, int argc, const VALUE *argv)
|
|||
rb_method_entry_t *me;
|
||||
rb_control_frame_t *cfp = th->cfp;
|
||||
|
||||
if (cfp->iseq || NIL_P(cfp->klass)) {
|
||||
if (RUBY_VM_NORMAL_ISEQ_P(cfp->iseq) || NIL_P(cfp->klass)) {
|
||||
rb_bug("vm_call_super: should not be reached");
|
||||
}
|
||||
|
||||
|
|
|
@ -1969,7 +1969,8 @@ block_proc_is_lambda(const VALUE procval)
|
|||
|
||||
static inline VALUE
|
||||
vm_yield_with_cfunc(rb_thread_t *th, const rb_block_t *block,
|
||||
VALUE self, int argc, const VALUE *argv,
|
||||
VALUE self, VALUE defined_class,
|
||||
int argc, const VALUE *argv,
|
||||
const rb_block_t *blockargptr)
|
||||
{
|
||||
NODE *ifunc = (NODE *) block->iseq;
|
||||
|
@ -1998,9 +1999,10 @@ vm_yield_with_cfunc(rb_thread_t *th, const rb_block_t *block,
|
|||
blockarg = Qnil;
|
||||
}
|
||||
|
||||
vm_push_frame(th, (rb_iseq_t *)ifunc, VM_FRAME_MAGIC_IFUNC, self,
|
||||
0, VM_ENVVAL_PREV_EP_PTR(block->ep), 0,
|
||||
th->cfp->sp, 1, 0, 0);
|
||||
vm_push_frame(th, (rb_iseq_t *)ifunc, VM_FRAME_MAGIC_IFUNC,
|
||||
self, defined_class,
|
||||
VM_ENVVAL_PREV_EP_PTR(block->ep), 0,
|
||||
th->cfp->sp, 1, th->passed_bmethod_me, 0);
|
||||
|
||||
val = (*ifunc->nd_cfnc) (arg, ifunc->nd_tval, argc, argv, blockarg);
|
||||
|
||||
|
@ -2065,7 +2067,8 @@ vm_invoke_block(rb_thread_t *th, rb_control_frame_t *reg_cfp, rb_call_info_t *ci
|
|||
else {
|
||||
VALUE val;
|
||||
CALLER_SETUP_ARG(th->cfp, ci);
|
||||
val = vm_yield_with_cfunc(th, block, block->self, ci->argc, STACK_ADDR_FROM_TOP(ci->argc), 0);
|
||||
val = vm_yield_with_cfunc(th, block, block->self, block->klass,
|
||||
ci->argc, STACK_ADDR_FROM_TOP(ci->argc), 0);
|
||||
POPN(ci->argc); /* TODO: should put before C/yield? */
|
||||
return val;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue