summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorYukihiro Matsumoto <[email protected]>2012-07-24 23:16:41 +0900
committerYukihiro Matsumoto <[email protected]>2012-07-24 23:16:41 +0900
commit88b638cf823741e3db204856e43f422229a1005c (patch)
treebdad0aae88a9dbb213ff0927596ab3370a38dfb4 /src
parent42b7d75a6728d4a17af68ee8e0bd4b0dabf7e9ab (diff)
downloadmruby-88b638cf823741e3db204856e43f422229a1005c.tar.gz
mruby-88b638cf823741e3db204856e43f422229a1005c.zip
instance_eval should set target_class in the block
Diffstat (limited to 'src')
-rw-r--r--src/kernel.c6
-rw-r--r--src/vm.c17
2 files changed, 18 insertions, 5 deletions
diff --git a/src/kernel.c b/src/kernel.c
index e75fcfc88..468891b23 100644
--- a/src/kernel.c
+++ b/src/kernel.c
@@ -555,6 +555,8 @@ mrb_obj_init_copy(mrb_state *mrb, mrb_value self)
return self;
}
+mrb_value mrb_yield_internal(mrb_state *mrb, mrb_value b, int argc, mrb_value *argv, mrb_value self, struct RClass *c);
+
/* 15.3.1.3.18 */
/*
* call-seq:
@@ -580,11 +582,13 @@ mrb_value
mrb_obj_instance_eval(mrb_state *mrb, mrb_value self)
{
mrb_value a, b;
+ mrb_value cv;
if (mrb_get_args(mrb, "|S&", &a, &b) == 1) {
mrb_raise(mrb, E_NOTIMP_ERROR, "instance_eval with string not implemented");
}
- return mrb_yield_with_self(mrb, b, 0, 0, self);
+ cv = mrb_singleton_class(mrb, self);
+ return mrb_yield_internal(mrb, b, 0, 0, self, mrb_class_ptr(cv));
}
int
diff --git a/src/vm.c b/src/vm.c
index bd3d05d81..62ef5069d 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -237,7 +237,7 @@ mrb_funcall_argv(mrb_state *mrb, mrb_value self, const char *name, int argc, mrb
}
mrb_value
-mrb_yield_with_self(mrb_state *mrb, mrb_value b, int argc, mrb_value *argv, mrb_value self)
+mrb_yield_internal(mrb_state *mrb, mrb_value b, int argc, mrb_value *argv, mrb_value self, struct RClass *c)
{
struct RProc *p;
mrb_sym mid = mrb->ci->mid;
@@ -251,7 +251,7 @@ mrb_yield_with_self(mrb_state *mrb, mrb_value b, int argc, mrb_value *argv, mrb_
ci->proc = p;
ci->stackidx = mrb->stack - mrb->stbase;
ci->argc = argc;
- ci->target_class = p->target_class;
+ ci->target_class = c;
ci->nregs = argc + 2;
ci->acc = -1;
mrb->stack = mrb->stack + n;
@@ -277,13 +277,17 @@ mrb_yield_with_self(mrb_state *mrb, mrb_value b, int argc, mrb_value *argv, mrb_
mrb_value
mrb_yield_argv(mrb_state *mrb, mrb_value b, int argc, mrb_value *argv)
{
- return mrb_yield_with_self(mrb, b, argc, argv, mrb->stack[0]);
+ struct RProc *p = mrb_proc_ptr(b);
+
+ return mrb_yield_internal(mrb, b, argc, argv, mrb->stack[0], p->target_class);
}
mrb_value
mrb_yield(mrb_state *mrb, mrb_value b, mrb_value v)
{
- return mrb_yield_with_self(mrb, b, 1, &v, mrb->stack[0]);
+ struct RProc *p = mrb_proc_ptr(b);
+
+ return mrb_yield_internal(mrb, b, 1, &v, mrb->stack[0], p->target_class);
}
static void
@@ -1564,6 +1568,11 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
CASE(OP_TCLASS) {
/* A B R(A) := target_class */
+ if (!mrb->ci->target_class) {
+ mrb_value exc = mrb_exc_new(mrb, E_TYPE_ERROR, "no target class or module", 25);
+ mrb->exc = (struct RObject*)mrb_object(exc);
+ goto L_RAISE;
+ }
regs[GETARG_A(i)] = mrb_obj_value(mrb->ci->target_class);
NEXT;
}