Commit 58e94427 authored by dearblue's avatar dearblue

Unified `target_class` and `env` of `mrb_callinfo`

If there is `env`, `env->c` means `target_class`.
parent b210cfa3
...@@ -152,12 +152,14 @@ typedef struct { ...@@ -152,12 +152,14 @@ typedef struct {
mrb_sym mid; mrb_sym mid;
const struct RProc *proc; const struct RProc *proc;
mrb_value *stackent; mrb_value *stackent;
struct REnv *env;
const mrb_code *pc; /* return address */ const mrb_code *pc; /* return address */
const mrb_code *err; /* error position */ const mrb_code *err; /* error position */
int16_t argc; int16_t argc;
int16_t acc; int16_t acc;
struct RClass *target_class; union {
struct REnv *env;
struct RClass *target_class;
} u;
} mrb_callinfo; } mrb_callinfo;
enum mrb_fiber_state { enum mrb_fiber_state {
......
...@@ -136,6 +136,67 @@ MRB_API mrb_value mrb_proc_cfunc_env_get(mrb_state *mrb, mrb_int idx); ...@@ -136,6 +136,67 @@ MRB_API mrb_value mrb_proc_cfunc_env_get(mrb_state *mrb, mrb_int idx);
MRB_API mrb_value mrb_load_proc(mrb_state *mrb, const struct RProc *proc); MRB_API mrb_value mrb_load_proc(mrb_state *mrb, const struct RProc *proc);
static inline struct RClass *
mrb_vm_ci_target_class(const mrb_callinfo *ci)
{
if (ci->u.env && ci->u.env->tt == MRB_TT_ENV) {
return ci->u.env->c;
}
else {
return ci->u.target_class;
}
}
static inline void
mrb_vm_ci_target_class_set(mrb_callinfo *ci, struct RClass *tc)
{
struct REnv *e = ci->u.env;
if (e) {
if (e->tt == MRB_TT_ENV) {
e->c = tc;
}
else {
ci->u.target_class = tc;
}
}
}
static inline struct REnv *
mrb_vm_ci_env(const mrb_callinfo *ci)
{
if (ci->u.env && ci->u.env->tt == MRB_TT_ENV) {
return ci->u.env;
}
else {
return NULL;
}
}
static inline void
mrb_vm_ci_env_set(mrb_callinfo *ci, struct REnv *e)
{
if (ci->u.env) {
if (ci->u.env->tt == MRB_TT_ENV) {
if (e) {
e->c = ci->u.env->c;
ci->u.env = e;
}
else {
ci->u.target_class = ci->u.env->c;
}
}
else {
if (e) {
e->c = ci->u.target_class;
ci->u.env = e;
}
}
}
else {
ci->u.env = e;
}
}
MRB_END_DECL MRB_END_DECL
#endif /* MRUBY_PROC_H */ #endif /* MRUBY_PROC_H */
...@@ -218,8 +218,8 @@ module MRuby ...@@ -218,8 +218,8 @@ module MRuby
f.puts %Q[ mrb_close(mrb);] f.puts %Q[ mrb_close(mrb);]
f.puts %Q[ exit(EXIT_FAILURE);] f.puts %Q[ exit(EXIT_FAILURE);]
f.puts %Q[ }] f.puts %Q[ }]
f.puts %Q[ struct REnv *e = mrb->c->cibase->env;] f.puts %Q[ struct REnv *e = mrb_vm_ci_env(mrb->c->cibase);]
f.puts %Q[ mrb->c->cibase->env = NULL;] f.puts %Q[ mrb_vm_ci_env_set(mrb->c->cibase, NULL);]
f.puts %Q[ mrb_env_unshare(mrb, e);] f.puts %Q[ mrb_env_unshare(mrb, e);]
end end
f.puts %Q[ mrb_gc_arena_restore(mrb, ai);] f.puts %Q[ mrb_gc_arena_restore(mrb, ai);]
......
...@@ -516,8 +516,8 @@ main(int argc, char **argv) ...@@ -516,8 +516,8 @@ main(int argc, char **argv)
} }
mrb_load_file_cxt(mrb, lfp, cxt); mrb_load_file_cxt(mrb, lfp, cxt);
fclose(lfp); fclose(lfp);
e = mrb->c->cibase->env; e = mrb_vm_ci_env(mrb->c->cibase);
mrb->c->cibase->env = NULL; mrb_vm_ci_env_set(mrb->c->cibase, NULL);
mrb_env_unshare(mrb, e); mrb_env_unshare(mrb, e);
mrbc_cleanup_local_variables(mrb, cxt); mrbc_cleanup_local_variables(mrb, cxt);
} }
...@@ -658,8 +658,8 @@ main(int argc, char **argv) ...@@ -658,8 +658,8 @@ main(int argc, char **argv)
mrb_codedump_all(mrb, proc); mrb_codedump_all(mrb, proc);
} }
/* adjust stack length of toplevel environment */ /* adjust stack length of toplevel environment */
if (mrb->c->cibase->env) { if (mrb->c->cibase->u.env) {
struct REnv *e = mrb->c->cibase->env; struct REnv *e = mrb_vm_ci_env(mrb->c->cibase);
if (e && MRB_ENV_LEN(e) < proc->body.irep->nlocals) { if (e && MRB_ENV_LEN(e) < proc->body.irep->nlocals) {
MRB_ENV_SET_LEN(e, proc->body.irep->nlocals); MRB_ENV_SET_LEN(e, proc->body.irep->nlocals);
} }
......
...@@ -333,8 +333,8 @@ main(int argc, char **argv) ...@@ -333,8 +333,8 @@ main(int argc, char **argv)
v = mrb_load_detect_file_cxt(mrb, lfp, c); v = mrb_load_detect_file_cxt(mrb, lfp, c);
} }
fclose(lfp); fclose(lfp);
e = mrb->c->cibase->env; e = mrb_vm_ci_env(mrb->c->cibase);
mrb->c->cibase->env = NULL; mrb_vm_ci_env_set(mrb->c->cibase, NULL);
mrb_env_unshare(mrb, e); mrb_env_unshare(mrb, e);
mrbc_cleanup_local_variables(mrb, c); mrbc_cleanup_local_variables(mrb, c);
} }
......
#include "mruby.h" #include "mruby.h"
#include "mruby/class.h" #include "mruby/class.h"
#include "mruby/string.h" #include "mruby/string.h"
#include "mruby/proc.h"
static mrb_value static mrb_value
mrb_mod_name(mrb_state *mrb, mrb_value self) mrb_mod_name(mrb_state *mrb, mrb_value self)
...@@ -51,7 +52,7 @@ mrb_mod_module_exec(mrb_state *mrb, mrb_value self) ...@@ -51,7 +52,7 @@ mrb_mod_module_exec(mrb_state *mrb, mrb_value self)
if (mrb->c->ci->acc < 0) { if (mrb->c->ci->acc < 0) {
return mrb_yield_with_class(mrb, blk, argc, argv, self, c); return mrb_yield_with_class(mrb, blk, argc, argv, self, c);
} }
mrb->c->ci->target_class = c; mrb_vm_ci_target_class_set(mrb->c->ci, c);
return mrb_yield_cont(mrb, blk, self, argc, argv); return mrb_yield_cont(mrb, blk, self, argc, argv);
} }
......
...@@ -6783,7 +6783,7 @@ mrb_load_exec(mrb_state *mrb, struct mrb_parser_state *p, mrbc_context *c) ...@@ -6783,7 +6783,7 @@ mrb_load_exec(mrb_state *mrb, struct mrb_parser_state *p, mrbc_context *c)
} }
MRB_PROC_SET_TARGET_CLASS(proc, target); MRB_PROC_SET_TARGET_CLASS(proc, target);
if (mrb->c->ci) { if (mrb->c->ci) {
mrb->c->ci->target_class = target; mrb_vm_ci_target_class_set(mrb->c->ci, target);
} }
v = mrb_top_run(mrb, proc, mrb_top_self(mrb), keep); v = mrb_top_run(mrb, proc, mrb_top_self(mrb), keep);
if (mrb->exc) return mrb_nil_value(); if (mrb->exc) return mrb_nil_value();
......
...@@ -12784,7 +12784,7 @@ mrb_load_exec(mrb_state *mrb, struct mrb_parser_state *p, mrbc_context *c) ...@@ -12784,7 +12784,7 @@ mrb_load_exec(mrb_state *mrb, struct mrb_parser_state *p, mrbc_context *c)
} }
MRB_PROC_SET_TARGET_CLASS(proc, target); MRB_PROC_SET_TARGET_CLASS(proc, target);
if (mrb->c->ci) { if (mrb->c->ci) {
mrb->c->ci->target_class = target; mrb_vm_ci_target_class_set(mrb->c->ci, target);
} }
v = mrb_top_run(mrb, proc, mrb_top_self(mrb), keep); v = mrb_top_run(mrb, proc, mrb_top_self(mrb), keep);
if (mrb->exc) return mrb_nil_value(); if (mrb->exc) return mrb_nil_value();
......
...@@ -79,19 +79,19 @@ create_proc_from_string(mrb_state *mrb, const char *s, mrb_int len, mrb_value bi ...@@ -79,19 +79,19 @@ create_proc_from_string(mrb_state *mrb, const char *s, mrb_int len, mrb_value bi
target_class = MRB_PROC_TARGET_CLASS(ci->proc); target_class = MRB_PROC_TARGET_CLASS(ci->proc);
} }
if (ci->proc && !MRB_PROC_CFUNC_P(ci->proc)) { if (ci->proc && !MRB_PROC_CFUNC_P(ci->proc)) {
if (ci->env) { if ((e = mrb_vm_ci_env(ci)) != NULL) {
e = ci->env; /* do nothing, because e is assigned already */
} }
else { else {
e = mrb_env_new(mrb, mrb->c, ci, ci->proc->body.irep->nlocals, ci[1].stackent, target_class); e = mrb_env_new(mrb, mrb->c, ci, ci->proc->body.irep->nlocals, ci[1].stackent, target_class);
ci->env = e; ci->u.env = e;
} }
proc->e.env = e; proc->e.env = e;
proc->flags |= MRB_PROC_ENVSET; proc->flags |= MRB_PROC_ENVSET;
mrb_field_write_barrier(mrb, (struct RBasic*)proc, (struct RBasic*)e); mrb_field_write_barrier(mrb, (struct RBasic*)proc, (struct RBasic*)e);
} }
proc->upper = ci->proc; proc->upper = ci->proc;
mrb->c->ci->target_class = target_class; mrb_vm_ci_target_class_set(mrb->c->ci, target_class);
/* mrb_codedump_all(mrb, proc); */ /* mrb_codedump_all(mrb, proc); */
mrb_parser_free(p); mrb_parser_free(p);
...@@ -157,7 +157,7 @@ f_instance_eval(mrb_state *mrb, mrb_value self) ...@@ -157,7 +157,7 @@ f_instance_eval(mrb_state *mrb, mrb_value self)
proc = create_proc_from_string(mrb, s, len, mrb_nil_value(), file, line); proc = create_proc_from_string(mrb, s, len, mrb_nil_value(), file, line);
MRB_PROC_SET_TARGET_CLASS(proc, mrb_class_ptr(cv)); MRB_PROC_SET_TARGET_CLASS(proc, mrb_class_ptr(cv));
mrb_assert(!MRB_PROC_CFUNC_P(proc)); mrb_assert(!MRB_PROC_CFUNC_P(proc));
mrb->c->ci->target_class = mrb_class_ptr(cv); mrb_vm_ci_target_class_set(mrb->c->ci, mrb_class_ptr(cv));
return exec_irep(mrb, self, proc); return exec_irep(mrb, self, proc);
} }
else { else {
......
...@@ -120,7 +120,7 @@ fiber_init(mrb_state *mrb, mrb_value self) ...@@ -120,7 +120,7 @@ fiber_init(mrb_state *mrb, mrb_value self)
/* adjust return callinfo */ /* adjust return callinfo */
ci = c->ci; ci = c->ci;
ci->target_class = MRB_PROC_TARGET_CLASS(p); mrb_vm_ci_target_class_set(ci, MRB_PROC_TARGET_CLASS(p));
ci->proc = p; ci->proc = p;
mrb_field_write_barrier(mrb, (struct RBasic*)mrb_obj_ptr(self), (struct RBasic*)p); mrb_field_write_barrier(mrb, (struct RBasic*)mrb_obj_ptr(self), (struct RBasic*)p);
ci->pc = p->body.irep->iseq; ci->pc = p->body.irep->iseq;
...@@ -154,7 +154,7 @@ fiber_result(mrb_state *mrb, const mrb_value *a, mrb_int len) ...@@ -154,7 +154,7 @@ fiber_result(mrb_state *mrb, const mrb_value *a, mrb_int len)
} }
/* mark return from context modifying method */ /* mark return from context modifying method */
#define MARK_CONTEXT_MODIFY(c) (c)->ci->target_class = NULL #define MARK_CONTEXT_MODIFY(c) (c)->ci->u.target_class = NULL
static void static void
fiber_check_cfunc(mrb_state *mrb, struct mrb_context *c) fiber_check_cfunc(mrb_state *mrb, struct mrb_context *c)
......
...@@ -105,7 +105,7 @@ mrb_obj_instance_exec(mrb_state *mrb, mrb_value self) ...@@ -105,7 +105,7 @@ mrb_obj_instance_exec(mrb_state *mrb, mrb_value self)
if (mrb->c->ci->acc < 0) { if (mrb->c->ci->acc < 0) {
return mrb_yield_with_class(mrb, blk, argc, argv, self, c); return mrb_yield_with_class(mrb, blk, argc, argv, self, c);
} }
mrb->c->ci->target_class = c; mrb_vm_ci_target_class_set(mrb->c->ci, c);
return mrb_yield_cont(mrb, blk, self, argc, argv); return mrb_yield_cont(mrb, blk, self, argc, argv);
} }
......
...@@ -660,9 +660,8 @@ mark_context(mrb_state *mrb, struct mrb_context *c) ...@@ -660,9 +660,8 @@ mark_context(mrb_state *mrb, struct mrb_context *c)
/* mark call stack */ /* mark call stack */
if (c->cibase) { if (c->cibase) {
for (ci = c->cibase; ci <= c->ci; ci++) { for (ci = c->cibase; ci <= c->ci; ci++) {
mrb_gc_mark(mrb, (struct RBasic*)ci->env);
mrb_gc_mark(mrb, (struct RBasic*)ci->proc); mrb_gc_mark(mrb, (struct RBasic*)ci->proc);
mrb_gc_mark(mrb, (struct RBasic*)ci->target_class); mrb_gc_mark(mrb, (struct RBasic*)ci->u.target_class);
} }
} }
/* mark fibers */ /* mark fibers */
...@@ -840,7 +839,7 @@ obj_free(mrb_state *mrb, struct RBasic *obj, int end) ...@@ -840,7 +839,7 @@ obj_free(mrb_state *mrb, struct RBasic *obj, int end)
mrb_callinfo *ce = c->cibase; mrb_callinfo *ce = c->cibase;
while (ce <= ci) { while (ce <= ci) {
struct REnv *e = ci->env; struct REnv *e = ci->u.env;
if (e && !mrb_object_dead_p(mrb, (struct RBasic*)e) && if (e && !mrb_object_dead_p(mrb, (struct RBasic*)e) &&
e->tt == MRB_TT_ENV && MRB_ENV_ONSTACK_P(e)) { e->tt == MRB_TT_ENV && MRB_ENV_ONSTACK_P(e)) {
mrb_env_unshare(mrb, e); mrb_env_unshare(mrb, e);
......
...@@ -176,8 +176,7 @@ mrb_f_block_given_p_m(mrb_state *mrb, mrb_value self) ...@@ -176,8 +176,7 @@ mrb_f_block_given_p_m(mrb_state *mrb, mrb_value self)
if (bidx < 0) return mrb_false_value(); if (bidx < 0) return mrb_false_value();
bp = &e->stack[bidx]; bp = &e->stack[bidx];
} }
else if (ci->env) { else if ((e = mrb_vm_ci_env(ci)) != NULL) {
e = ci->env;
/* top-level does not have block slot (always false) */ /* top-level does not have block slot (always false) */
if (e->stack == mrb->c->stbase) return mrb_false_value(); if (e->stack == mrb->c->stbase) return mrb_false_value();
bidx = env_bidx(e); bidx = env_bidx(e);
......
...@@ -46,7 +46,7 @@ mrb_proc_new(mrb_state *mrb, const mrb_irep *irep) ...@@ -46,7 +46,7 @@ mrb_proc_new(mrb_state *mrb, const mrb_irep *irep)
tc = MRB_PROC_TARGET_CLASS(ci->proc); tc = MRB_PROC_TARGET_CLASS(ci->proc);
} }
if (tc == NULL) { if (tc == NULL) {
tc = ci->target_class; tc = mrb_vm_ci_target_class(ci);
} }
p->upper = ci->proc; p->upper = ci->proc;
p->e.target_class = tc; p->e.target_class = tc;
...@@ -83,14 +83,14 @@ closure_setup(mrb_state *mrb, struct RProc *p) ...@@ -83,14 +83,14 @@ closure_setup(mrb_state *mrb, struct RProc *p)
const struct RProc *up = p->upper; const struct RProc *up = p->upper;
struct REnv *e = NULL; struct REnv *e = NULL;
if (ci && ci->env) { if (ci && (e = mrb_vm_ci_env(ci)) != NULL) {
e = ci->env; /* do nothing, because e is assigned already */
} }
else if (up) { else if (up) {
struct RClass *tc = MRB_PROC_TARGET_CLASS(p); struct RClass *tc = MRB_PROC_TARGET_CLASS(p);
e = mrb_env_new(mrb, mrb->c, ci, up->body.irep->nlocals, mrb->c->stack, tc); e = mrb_env_new(mrb, mrb->c, ci, up->body.irep->nlocals, mrb->c->stack, tc);
ci->env = e; ci->u.env = e;
if (MRB_PROC_ENV_P(up) && MRB_PROC_ENV(up)->cxt == NULL) { if (MRB_PROC_ENV_P(up) && MRB_PROC_ENV(up)->cxt == NULL) {
e->mid = MRB_PROC_ENV(up)->mid; e->mid = MRB_PROC_ENV(up)->mid;
} }
...@@ -211,7 +211,7 @@ mrb_proc_s_new(mrb_state *mrb, mrb_value proc_class) ...@@ -211,7 +211,7 @@ mrb_proc_s_new(mrb_state *mrb, mrb_value proc_class)
proc = mrb_obj_value(p); proc = mrb_obj_value(p);
mrb_funcall_with_block(mrb, proc, MRB_SYM(initialize), 0, NULL, proc); mrb_funcall_with_block(mrb, proc, MRB_SYM(initialize), 0, NULL, proc);
if (!MRB_PROC_STRICT_P(p) && if (!MRB_PROC_STRICT_P(p) &&
mrb->c->ci > mrb->c->cibase && MRB_PROC_ENV(p) == mrb->c->ci[-1].env) { mrb->c->ci > mrb->c->cibase && MRB_PROC_ENV(p) == mrb->c->ci[-1].u.env) {
p->flags |= MRB_PROC_ORPHAN; p->flags |= MRB_PROC_ORPHAN;
} }
return proc; return proc;
......
...@@ -133,7 +133,7 @@ stack_init(mrb_state *mrb) ...@@ -133,7 +133,7 @@ stack_init(mrb_state *mrb)
c->cibase = (mrb_callinfo *)mrb_calloc(mrb, CALLINFO_INIT_SIZE, sizeof(mrb_callinfo)); c->cibase = (mrb_callinfo *)mrb_calloc(mrb, CALLINFO_INIT_SIZE, sizeof(mrb_callinfo));
c->ciend = c->cibase + CALLINFO_INIT_SIZE; c->ciend = c->cibase + CALLINFO_INIT_SIZE;
c->ci = c->cibase; c->ci = c->cibase;
c->ci->target_class = mrb->object_class; c->ci->u.target_class = mrb->object_class;
c->ci->stackent = c->stack; c->ci->stackent = c->stack;
} }
...@@ -144,7 +144,7 @@ envadjust(mrb_state *mrb, mrb_value *oldbase, mrb_value *newbase, size_t oldsize ...@@ -144,7 +144,7 @@ envadjust(mrb_state *mrb, mrb_value *oldbase, mrb_value *newbase, size_t oldsize
if (newbase == oldbase) return; if (newbase == oldbase) return;
while (ci <= mrb->c->ci) { while (ci <= mrb->c->ci) {
struct REnv *e = ci->env; struct REnv *e = mrb_vm_ci_env(ci);
mrb_value *st; mrb_value *st;
if (e && MRB_ENV_ONSTACK_P(e) && if (e && MRB_ENV_ONSTACK_P(e) &&
...@@ -154,7 +154,7 @@ envadjust(mrb_state *mrb, mrb_value *oldbase, mrb_value *newbase, size_t oldsize ...@@ -154,7 +154,7 @@ envadjust(mrb_state *mrb, mrb_value *oldbase, mrb_value *newbase, size_t oldsize
e->stack = newbase + off; e->stack = newbase + off;
} }
if (ci->proc && MRB_PROC_ENV_P(ci->proc) && ci->env != MRB_PROC_ENV(ci->proc)) { if (ci->proc && MRB_PROC_ENV_P(ci->proc) && e != MRB_PROC_ENV(ci->proc)) {
e = MRB_PROC_ENV(ci->proc); e = MRB_PROC_ENV(ci->proc);
if (e && MRB_ENV_ONSTACK_P(e) && if (e && MRB_ENV_ONSTACK_P(e) &&
...@@ -240,7 +240,7 @@ uvenv(mrb_state *mrb, mrb_int up) ...@@ -240,7 +240,7 @@ uvenv(mrb_state *mrb, mrb_int up)
while (cb <= ci) { while (cb <= ci) {
if (ci->proc == proc) { if (ci->proc == proc) {
return ci->env; return mrb_vm_ci_env(ci);
} }
ci--; ci--;
} }
...@@ -284,9 +284,8 @@ cipush(mrb_state *mrb, const mrb_code *pc, mrb_int push_stacks, mrb_int acc, ...@@ -284,9 +284,8 @@ cipush(mrb_state *mrb, const mrb_code *pc, mrb_int push_stacks, mrb_int acc,
ci->pc = pc; ci->pc = pc;
ci->argc = argc; ci->argc = argc;
ci->acc = acc; ci->acc = acc;
ci->target_class = target_class; ci->u.target_class = target_class;
ci->err = 0; ci->err = 0;
ci->env = 0;
c->stack += push_stacks; c->stack += push_stacks;
return ci; return ci;
...@@ -302,7 +301,7 @@ mrb_env_unshare(mrb_state *mrb, struct REnv *e) ...@@ -302,7 +301,7 @@ mrb_env_unshare(mrb_state *mrb, struct REnv *e)
if (!MRB_ENV_ONSTACK_P(e)) return; if (!MRB_ENV_ONSTACK_P(e)) return;
if (e->cxt != mrb->c) return; if (e->cxt != mrb->c) return;
if (e == mrb->c->cibase->env) return; /* for mirb */ if (e == mrb_vm_ci_env(mrb->c->cibase)) return; /* for mirb */
p = (mrb_value *)mrb_malloc(mrb, sizeof(mrb_value)*len); p = (mrb_value *)mrb_malloc(mrb, sizeof(mrb_value)*len);
if (len > 0) { if (len > 0) {
stack_copy(p, e->stack, len); stack_copy(p, e->stack, len);
...@@ -317,7 +316,7 @@ static inline mrb_callinfo* ...@@ -317,7 +316,7 @@ static inline mrb_callinfo*
cipop(mrb_state *mrb) cipop(mrb_state *mrb)
{ {
struct mrb_context *c = mrb->c; struct mrb_context *c = mrb->c;
struct REnv *env = c->ci->env; struct REnv *env = mrb_vm_ci_env(c->ci);
mrb->c->stack = c->ci->stackent; mrb->c->stack = c->ci->stackent;
c->ci--; c->ci--;
...@@ -573,7 +572,7 @@ mrb_f_send(mrb_state *mrb, mrb_value self) ...@@ -573,7 +572,7 @@ mrb_f_send(mrb_state *mrb, mrb_value self)
} }
ci->mid = name; ci->mid = name;
ci->target_class = c; ci->u.target_class = c;
regs = mrb->c->stack+1; regs = mrb->c->stack+1;
/* remove first symbol from arguments */ /* remove first symbol from arguments */
if (ci->argc >= 0) { if (ci->argc >= 0) {
...@@ -609,7 +608,7 @@ eval_under(mrb_state *mrb, mrb_value self, mrb_value blk, struct RClass *c) ...@@ -609,7 +608,7 @@ eval_under(mrb_state *mrb, mrb_value self, mrb_value blk, struct RClass *c)
if (ci->acc == CI_ACC_DIRECT) { if (ci->acc == CI_ACC_DIRECT) {
return mrb_yield_with_class(mrb, blk, 1, &self, self, c); return mrb_yield_with_class(mrb, blk, 1, &self, self, c);
} }
ci->target_class = c; ci->u.target_class = c;
p = mrb_proc_ptr(blk); p = mrb_proc_ptr(blk);
ci->proc = p; ci->proc = p;
ci->argc = 1; ci->argc = 1;
...@@ -1005,7 +1004,7 @@ mrb_vm_run(mrb_state *mrb, const struct RProc *proc, mrb_value self, mrb_int sta ...@@ -1005,7 +1004,7 @@ mrb_vm_run(mrb_state *mrb, const struct RProc *proc, mrb_value self, mrb_int sta
static mrb_bool static mrb_bool
check_target_class(mrb_state *mrb) check_target_class(mrb_state *mrb)
{ {
if (!mrb->c->ci->target_class) { if (!mrb_vm_ci_target_class(mrb->c->ci)) {
mrb_value exc = mrb_exc_new_lit(mrb, E_TYPE_ERROR, "no target class or module"); mrb_value exc = mrb_exc_new_lit(mrb, E_TYPE_ERROR, "no target class or module");
mrb_exc_set(mrb, exc); mrb_exc_set(mrb, exc);
return FALSE; return FALSE;
...@@ -1476,11 +1475,11 @@ RETRY_TRY_BLOCK: ...@@ -1476,11 +1475,11 @@ RETRY_TRY_BLOCK:
ci = mrb->c->ci; ci = mrb->c->ci;
if (mrb_proc_p(blk)) { if (mrb_proc_p(blk)) {
struct RProc *p = mrb_proc_ptr(blk); struct RProc *p = mrb_proc_ptr(blk);
if (p && !MRB_PROC_STRICT_P(p) && MRB_PROC_ENV(p) == ci[-1].env) { if (p && !MRB_PROC_STRICT_P(p) && MRB_PROC_ENV(p) == mrb_vm_ci_env(&ci[-1])) {
p->flags |= MRB_PROC_ORPHAN; p->flags |= MRB_PROC_ORPHAN;
} }
} }
if (!ci->target_class) { /* return from context modifying method (resume/yield) */ if (!ci->u.target_class) { /* return from context modifying method (resume/yield) */
if (ci->acc == CI_ACC_RESUMED) { if (ci->acc == CI_ACC_RESUMED) {
mrb->jmp = prev_jmp; mrb->jmp = prev_jmp;
return recv; return recv;
...@@ -1518,7 +1517,7 @@ RETRY_TRY_BLOCK: ...@@ -1518,7 +1517,7 @@ RETRY_TRY_BLOCK:
/* replace callinfo */ /* replace callinfo */
ci = mrb->c->ci; ci = mrb->c->ci;
ci->target_class = MRB_PROC_TARGET_CLASS(m); ci->u.target_class = MRB_PROC_TARGET_CLASS(m);
ci->proc = m; ci->proc = m;
if (MRB_PROC_ENV_P(m)) { if (MRB_PROC_ENV_P(m)) {
ci->mid = MRB_PROC_ENV(m)->mid; ci->mid = MRB_PROC_ENV(m)->mid;
...@@ -1591,10 +1590,10 @@ RETRY_TRY_BLOCK: ...@@ -1591,10 +1590,10 @@ RETRY_TRY_BLOCK:
goto L_RAISE; goto L_RAISE;
} }
if (target_class->flags & MRB_FL_CLASS_IS_PREPENDED) { if (target_class->flags & MRB_FL_CLASS_IS_PREPENDED) {
target_class = ci->target_class; target_class = mrb_vm_ci_target_class(ci);
} }
else if (target_class->tt == MRB_TT_MODULE) { else if (target_class->tt == MRB_TT_MODULE) {
target_class = ci->target_class; target_class = mrb_vm_ci_target_class(ci);
if (target_class->tt != MRB_TT_ICLASS) { if (target_class->tt != MRB_TT_ICLASS) {
mrb_value exc = mrb_exc_new_lit(mrb, E_RUNTIME_ERROR, "superclass info lost [mruby limitations]"); mrb_value exc = mrb_exc_new_lit(mrb, E_RUNTIME_ERROR, "superclass info lost [mruby limitations]");
mrb_exc_set(mrb, exc); mrb_exc_set(mrb, exc);
...@@ -1659,7 +1658,7 @@ RETRY_TRY_BLOCK: ...@@ -1659,7 +1658,7 @@ RETRY_TRY_BLOCK:
if (mrb->exc) goto L_RAISE; if (mrb->exc) goto L_RAISE;
ci = mrb->c->ci; ci = mrb->c->ci;
mrb_assert(!mrb_break_p(v)); mrb_assert(!mrb_break_p(v));
if (!ci->target_class) { /* return from context modifying method (resume/yield) */ if (!mrb_vm_ci_target_class(ci)) { /* return from context modifying method (resume/yield) */
if (ci->acc == CI_ACC_RESUMED) { if (ci->acc == CI_ACC_RESUMED) {
mrb->jmp = prev_jmp; mrb->jmp = prev_jmp;
return v; return v;
...@@ -1700,7 +1699,7 @@ RETRY_TRY_BLOCK: ...@@ -1700,7 +1699,7 @@ RETRY_TRY_BLOCK:
mrb_int lv = (b>>0)&0xf; mrb_int lv = (b>>0)&0xf;
mrb_value *stack; mrb_value *stack;
if (mrb->c->ci->mid == 0 || mrb->c->ci->target_class == NULL) { if (mrb->c->ci->mid == 0 || mrb_vm_ci_target_class(mrb->c->ci) == NULL) {
mrb_value exc; mrb_value exc;
L_NOSUPER: L_NOSUPER:
...@@ -1951,7 +1950,7 @@ RETRY_TRY_BLOCK: ...@@ -1951,7 +1950,7 @@ RETRY_TRY_BLOCK:
struct RProc *p = mrb_proc_ptr(blk); struct RProc *p = mrb_proc_ptr(blk);
if (!MRB_PROC_STRICT_P(p) && if (!MRB_PROC_STRICT_P(p) &&
ci > mrb->c->cibase && MRB_PROC_ENV(p) == ci[-1].env) { ci > mrb->c->cibase && MRB_PROC_ENV(p) == mrb_vm_ci_env(&ci[-1])) {
p->flags |= MRB_PROC_ORPHAN; p->flags |= MRB_PROC_ORPHAN;
} }
} }
...@@ -2203,7 +2202,7 @@ RETRY_TRY_BLOCK: ...@@ -2203,7 +2202,7 @@ RETRY_TRY_BLOCK:
mrb_assert(ci == mrb->c->ci); mrb_assert(ci == mrb->c->ci);
mrb_assert(mrb->exc == NULL); mrb_assert(mrb->exc == NULL);
if (mrb->c->vmexec && !ci->target_class) { if (mrb->c->vmexec && !mrb_vm_ci_target_class(ci)) {
mrb_gc_arena_restore(mrb, ai); mrb_gc_arena_restore(mrb, ai);
mrb->c->vmexec = FALSE; mrb->c->vmexec = FALSE;
mrb->jmp = prev_jmp; mrb->jmp = prev_jmp;
...@@ -2780,7 +2779,7 @@ RETRY_TRY_BLOCK: ...@@ -2780,7 +2779,7 @@ RETRY_TRY_BLOCK:
CASE(OP_TCLASS, B) { CASE(OP_TCLASS, B) {
if (!check_target_class(mrb)) goto L_RAISE; if (!check_target_class(mrb)) goto L_RAISE;
regs[a] = mrb_obj_value(mrb->c->ci->target_class); regs[a] = mrb_obj_value(mrb_vm_ci_target_class(mrb->c->ci));
NEXT; NEXT;
} }
...@@ -2788,7 +2787,7 @@ RETRY_TRY_BLOCK: ...@@ -2788,7 +2787,7 @@ RETRY_TRY_BLOCK:
struct RClass *target; struct RClass *target;
if (!check_target_class(mrb)) goto L_RAISE; if (!check_target_class(mrb)) goto L_RAISE;
target = mrb->c->ci->target_class; target = mrb_vm_ci_target_class(mrb->c->ci);
mrb_alias_method(mrb, target, syms[a], syms[b]); mrb_alias_method(mrb, target, syms[a], syms[b]);
NEXT; NEXT;
} }
...@@ -2796,7 +2795,7 @@ RETRY_TRY_BLOCK: ...@@ -2796,7 +2795,7 @@ RETRY_TRY_BLOCK:
struct RClass *target; struct RClass *target;
if (!check_target_class(mrb)) goto L_RAISE; if (!check_target_class(mrb)) goto L_RAISE;
target = mrb->c->ci->target_class; target = mrb_vm_ci_target_class(mrb->c->ci);
mrb_undef_method_id(mrb, target, syms[a]); mrb_undef_method_id(mrb, target, syms[a]);
NEXT; NEXT;
} }
...@@ -2884,7 +2883,7 @@ mrb_top_run(mrb_state *mrb, const struct RProc *proc, mrb_value self, mrb_int st ...@@ -2884,7 +2883,7 @@ mrb_top_run(mrb_state *mrb, const struct RProc *proc, mrb_value self, mrb_int st
return mrb_vm_run(mrb, proc, self, stack_keep); return mrb_vm_run(mrb, proc, self, stack_keep);
} }
if (mrb->c->ci == mrb->c->cibase) { if (mrb->c->ci == mrb->c->cibase) {
mrb->c->ci->env = NULL; mrb_vm_ci_env_set(mrb->c->ci, NULL);
return mrb_vm_run(mrb, proc, self, stack_keep); return mrb_vm_run(mrb, proc, self, stack_keep);
} }
cipush(mrb, NULL, 0, CI_ACC_SKIP, mrb->object_class, NULL, 0, 0); cipush(mrb, NULL, 0, CI_ACC_SKIP, mrb->object_class, NULL, 0, 0);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment