1
0
Fork 0
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:
nobu 2014-11-09 14:25:52 +00:00
parent ad58f04833
commit 26ae645501
7 changed files with 61 additions and 7 deletions

View file

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

View 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);
}

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

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

View file

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

View file

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