summaryrefslogtreecommitdiffhomepage
path: root/src/kernel.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel.c')
-rw-r--r--src/kernel.c74
1 files changed, 39 insertions, 35 deletions
diff --git a/src/kernel.c b/src/kernel.c
index 8670e0651..bd21ddf53 100644
--- a/src/kernel.c
+++ b/src/kernel.c
@@ -136,38 +136,38 @@ mrb_f_block_given_p_m(mrb_state *mrb, mrb_value self)
{
mrb_callinfo *ci = mrb->c->ci;
mrb_value *bp;
- mrb_bool given_p;
bp = ci->stackent + 1;
ci--;
if (ci <= mrb->c->cibase) {
- given_p = FALSE;
+ return mrb_false_value();
}
- else {
- /* block_given? called within block; check upper scope */
- if (ci->proc->env) {
- struct REnv *e = ci->proc->env;
- mrb_value *sp;
+ /* block_given? called within block; check upper scope */
+ if (ci->proc->env) {
+ struct REnv *e = ci->proc->env;
- while (e->c) {
- e = (struct REnv*)e->c;
- }
- sp = e->stack;
- if (sp) {
- /* top-level does not have block slot (alway false) */
- if (sp == mrb->c->stbase)
- return mrb_false_value();
- ci = mrb->c->cibase + e->cioff;
- bp = ci[1].stackent + 1;
- }
+ while (e->c) {
+ e = (struct REnv*)e->c;
}
- if (ci->argc > 0) {
- bp += ci->argc;
+ /* top-level does not have block slot (always false) */
+ if (e->stack == mrb->c->stbase)
+ return mrb_false_value();
+ if (e->stack && e->cioff < 0) {
+ /* use saved block arg position */
+ bp = &e->stack[-e->cioff];
+ ci = 0; /* no callinfo available */
+ }
+ else {
+ ci = e->cxt.c->cibase + e->cioff;
+ bp = ci[1].stackent + 1;
}
- given_p = !mrb_nil_p(*bp);
}
-
- return mrb_bool_value(given_p);
+ if (ci && ci->argc > 0) {
+ bp += ci->argc;
+ }
+ if (mrb_nil_p(*bp))
+ return mrb_false_value();
+ return mrb_true_value();
}
/* 15.3.1.3.7 */
@@ -199,11 +199,13 @@ mrb_singleton_class_clone(mrb_state *mrb, mrb_value obj)
/* copy singleton(unnamed) class */
struct RClass *clone = (struct RClass*)mrb_obj_alloc(mrb, klass->tt, mrb->class_class);
- if ((mrb_type(obj) == MRB_TT_CLASS) || (mrb_type(obj) == MRB_TT_SCLASS)) {
- clone->c = clone;
- }
- else {
+ switch (mrb_type(obj)) {
+ case MRB_TT_CLASS:
+ case MRB_TT_SCLASS:
+ break;
+ default:
clone->c = mrb_singleton_class_clone(mrb, mrb_obj_value(klass));
+ break;
}
clone->super = klass->super;
if (klass->iv) {
@@ -241,7 +243,12 @@ copy_class(mrb_state *mrb, mrb_value dst, mrb_value src)
c1->super = mrb_class_ptr(mrb_obj_dup(mrb, mrb_obj_value(c0)));
c1->super->flags |= MRB_FLAG_IS_ORIGIN;
}
- dc->mt = kh_copy(mt, mrb, sc->mt);
+ if (sc->mt) {
+ dc->mt = kh_copy(mt, mrb, sc->mt);
+ }
+ else {
+ dc->mt = kh_init(mt, mrb);
+ }
dc->super = sc->super;
MRB_SET_INSTANCE_TT(dc, MRB_INSTANCE_TT(sc));
}
@@ -311,6 +318,7 @@ mrb_obj_clone(mrb_state *mrb, mrb_value self)
}
p = (struct RObject*)mrb_obj_alloc(mrb, mrb_type(self), mrb_obj_class(mrb, self));
p->c = mrb_singleton_class_clone(mrb, self);
+ mrb_field_write_barrier(mrb, (struct RBasic*)p, (struct RBasic*)p->c);
clone = mrb_obj_value(p);
init_copy(mrb, clone, self);
@@ -403,11 +411,8 @@ mrb_obj_extend_m(mrb_state *mrb, mrb_value self)
{
mrb_value *argv;
mrb_int argc;
- mrb_value args;
mrb_get_args(mrb, "*", &argv, &argc);
- args = mrb_ary_new_from_values(mrb, argc, argv);
- argv = (mrb_value*)RARRAY_PTR(args);
return mrb_obj_extend(mrb, argc, argv, self);
}
@@ -867,7 +872,6 @@ mrb_f_raise(mrb_state *mrb, mrb_value self)
/* fall through */
default:
exc = mrb_make_exception(mrb, argc, a);
- mrb_obj_iv_set(mrb, mrb_obj_ptr(exc), mrb_intern_lit(mrb, "lastpc"), mrb_cptr_value(mrb, mrb->c->ci->pc));
mrb_exc_raise(mrb, exc);
break;
}
@@ -977,7 +981,7 @@ mrb_obj_missing(mrb_state *mrb, mrb_value mod)
mrb_value *a;
mrb_int alen;
- mrb_get_args(mrb, "n*", &name, &a, &alen);
+ mrb_get_args(mrb, "n*!", &name, &a, &alen);
mrb_method_missing(mrb, name, mod, mrb_ary_new_from_values(mrb, alen, a));
/* not reached */
return mrb_nil_value();
@@ -1160,8 +1164,8 @@ mrb_local_variables(mrb_state *mrb, mrb_value self)
while (e) {
if (MRB_ENV_STACK_SHARED_P(e) &&
- !MRB_PROC_CFUNC_P(mrb->c->cibase[e->cioff].proc)) {
- irep = mrb->c->cibase[e->cioff].proc->body.irep;
+ !MRB_PROC_CFUNC_P(e->cxt.c->cibase[e->cioff].proc)) {
+ irep = e->cxt.c->cibase[e->cioff].proc->body.irep;
if (irep->lv) {
for (i = 0; i + 1 < irep->nlocals; ++i) {
if (irep->lv[i].name) {