summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/mruby.h1
-rw-r--r--src/kernel.c6
-rw-r--r--src/vm.c17
3 files changed, 18 insertions, 6 deletions
diff --git a/include/mruby.h b/include/mruby.h
index 7abf66cb9..4fd7bccd5 100644
--- a/include/mruby.h
+++ b/include/mruby.h
@@ -464,7 +464,6 @@ NUM2CHR(mrb_value x)
mrb_value mrb_yield(mrb_state *mrb, mrb_value v, mrb_value blk);
mrb_value mrb_yield_argv(mrb_state *mrb, mrb_value b, int argc, mrb_value *argv);
-mrb_value mrb_yield_with_self(mrb_state *mrb, mrb_value b, int argc, mrb_value *argv, mrb_value self);
mrb_value mrb_class_new_instance(mrb_state *mrb, int, mrb_value*, struct RClass *);
mrb_value mrb_class_new_instance_m(mrb_state *mrb, mrb_value klass);
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;
}