summaryrefslogtreecommitdiff
path: root/vm.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-08-20 11:36:34 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-08-20 11:36:34 +0000
commitceece4650a1de6189f2705cbf8120f6679a1af8f (patch)
treea229595768c98c125e260ab1faabda9370807712 /vm.c
parentde83cb9b20f2fa6ee6bace04ff29462cedd02a6d (diff)
vm_insnhelper.c: iclass as klass in cfp
* vm_insnhelper.c (vm_call_method): follow iclasses as klass in cfp but not included modules. [ruby-core:47241] [Bug #6891] * vm_insnhelper.c (vm_call_bmethod): pass defined_class to follow proper ancestors. [ruby-core:47241] [Bug #6891] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36736 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'vm.c')
-rw-r--r--vm.c32
1 files changed, 24 insertions, 8 deletions
diff --git a/vm.c b/vm.c
index 443260ea43..277e33d27a 100644
--- a/vm.c
+++ b/vm.c
@@ -61,6 +61,10 @@ rb_vm_control_frame_block_ptr(rb_control_frame_t *cfp)
return VM_CF_BLOCK_PTR(cfp);
}
+static VALUE
+vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc, VALUE self, VALUE defined_class,
+ int argc, const VALUE *argv, const rb_block_t *blockptr);
+
#include "vm_insnhelper.h"
#include "vm_insnhelper.c"
#include "vm_exec.h"
@@ -577,7 +581,8 @@ rb_vm_make_proc(rb_thread_t *th, const rb_block_t *block, VALUE klass)
static inline VALUE
invoke_block_from_c(rb_thread_t *th, const rb_block_t *block,
VALUE self, int argc, const VALUE *argv,
- const rb_block_t *blockptr, const NODE *cref)
+ const rb_block_t *blockptr, const NODE *cref,
+ VALUE defined_class)
{
if (SPECIAL_CONST_P(block->iseq))
return Qnil;
@@ -599,7 +604,7 @@ invoke_block_from_c(rb_thread_t *th, const rb_block_t *block,
type == VM_FRAME_MAGIC_LAMBDA);
vm_push_frame(th, iseq, type | VM_FRAME_FLAG_FINISH,
- self, block->klass, /* th->passed_defined_class, */
+ self, defined_class,
VM_ENVVAL_PREV_EP_PTR(block->ep),
iseq->iseq_encoded + opt_pc,
cfp->sp + arg_size, iseq->local_size - arg_size,
@@ -633,19 +638,21 @@ static inline VALUE
vm_yield_with_cref(rb_thread_t *th, int argc, const VALUE *argv, const NODE *cref)
{
const rb_block_t *blockptr = check_block(th);
- return invoke_block_from_c(th, blockptr, blockptr->self, argc, argv, 0, cref);
+ return invoke_block_from_c(th, blockptr, blockptr->self, argc, argv, 0, cref,
+ blockptr->klass);
}
static inline VALUE
vm_yield(rb_thread_t *th, int argc, const VALUE *argv)
{
const rb_block_t *blockptr = check_block(th);
- return invoke_block_from_c(th, blockptr, blockptr->self, argc, argv, 0, 0);
+ return invoke_block_from_c(th, blockptr, blockptr->self, argc, argv, 0, 0,
+ blockptr->klass);
}
-VALUE
-rb_vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc, VALUE self,
- int argc, const VALUE *argv, const rb_block_t * blockptr)
+static VALUE
+vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc, VALUE self, VALUE defined_class,
+ int argc, const VALUE *argv, const rb_block_t *blockptr)
{
VALUE val = Qundef;
int state;
@@ -656,7 +663,8 @@ rb_vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc, VALUE self,
if (!proc->is_from_method) {
th->safe_level = proc->safe_level;
}
- val = invoke_block_from_c(th, &proc->block, self, argc, argv, blockptr, 0);
+ val = invoke_block_from_c(th, &proc->block, self, argc, argv, blockptr, 0,
+ defined_class);
}
TH_POP_TAG();
@@ -670,6 +678,14 @@ rb_vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc, VALUE self,
return val;
}
+VALUE
+rb_vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc,
+ int argc, const VALUE *argv, const rb_block_t *blockptr)
+{
+ return vm_invoke_proc(th, proc, proc->block.self, proc->block.klass,
+ argc, argv, blockptr);
+}
+
/* special variable */
static rb_control_frame_t *