Merge branch 'dearblue-reorganize-ci'

parents e13f34e3 bec4d30d
...@@ -151,13 +151,14 @@ typedef void* (*mrb_allocf) (struct mrb_state *mrb, void*, size_t, void *ud); ...@@ -151,13 +151,14 @@ typedef void* (*mrb_allocf) (struct mrb_state *mrb, void*, size_t, void *ud);
typedef struct { typedef struct {
mrb_sym mid; mrb_sym mid;
const struct RProc *proc; const struct RProc *proc;
mrb_value *stackent; mrb_value *stack;
struct REnv *env; const mrb_code *pc; /* current address on iseq of this proc */
const mrb_code *pc; /* return address */ int16_t argc;
const mrb_code *err; /* error position */ int16_t acc;
mrb_int argc; union {
mrb_int acc; struct REnv *env;
struct RClass *target_class; struct RClass *target_class;
} u;
} mrb_callinfo; } mrb_callinfo;
enum mrb_fiber_state { enum mrb_fiber_state {
...@@ -172,8 +173,7 @@ enum mrb_fiber_state { ...@@ -172,8 +173,7 @@ enum mrb_fiber_state {
struct mrb_context { struct mrb_context {
struct mrb_context *prev; struct mrb_context *prev;
mrb_value *stack; /* stack of virtual machine */ mrb_value *stbase, *stend; /* stack of virtual machine */
mrb_value *stbase, *stend;
mrb_callinfo *ci; mrb_callinfo *ci;
mrb_callinfo *cibase, *ciend; mrb_callinfo *cibase, *ciend;
......
...@@ -136,6 +136,74 @@ MRB_API mrb_value mrb_proc_cfunc_env_get(mrb_state *mrb, mrb_int idx); ...@@ -136,6 +136,74 @@ 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 void
mrb_vm_ci_proc_set(mrb_callinfo *ci, const struct RProc *p)
{
ci->proc = p;
ci->pc = (p && !MRB_PROC_CFUNC_P(p)) ? p->body.irep->iseq : NULL;
}
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);
} }
...@@ -683,7 +683,7 @@ main(int argc, char **argv) ...@@ -683,7 +683,7 @@ main(int argc, char **argv)
} }
p(mrb, result, 1); p(mrb, result, 1);
#ifndef MRB_NO_MIRB_UNDERSCORE #ifndef MRB_NO_MIRB_UNDERSCORE
*(mrb->c->stack + 1) = result; *(mrb->c->ci->stack + 1) = result;
#endif #endif
} }
} }
......
...@@ -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->stack, 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);
...@@ -115,7 +115,7 @@ exec_irep(mrb_state *mrb, mrb_value self, struct RProc *proc) ...@@ -115,7 +115,7 @@ exec_irep(mrb_state *mrb, mrb_value self, struct RProc *proc)
return ret; return ret;
} }
/* clear block */ /* clear block */
mrb->c->stack[1] = mrb_nil_value(); mrb->c->ci->stack[1] = mrb_nil_value();
return mrb_exec_irep(mrb, self, proc); return mrb_exec_irep(mrb, self, proc);
} }
...@@ -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 {
......
...@@ -93,7 +93,6 @@ fiber_init(mrb_state *mrb, mrb_value self) ...@@ -93,7 +93,6 @@ fiber_init(mrb_state *mrb, mrb_value self)
} }
c->stbase = (mrb_value *)mrb_malloc(mrb, slen*sizeof(mrb_value)); c->stbase = (mrb_value *)mrb_malloc(mrb, slen*sizeof(mrb_value));
c->stend = c->stbase + slen; c->stend = c->stbase + slen;
c->stack = c->stbase;
#ifdef MRB_NAN_BOXING #ifdef MRB_NAN_BOXING
{ {
...@@ -110,20 +109,19 @@ fiber_init(mrb_state *mrb, mrb_value self) ...@@ -110,20 +109,19 @@ fiber_init(mrb_state *mrb, mrb_value self)
#endif #endif
/* copy receiver from a block */ /* copy receiver from a block */
c->stack[0] = mrb->c->stack[0]; c->stbase[0] = mrb->c->ci->stack[0];
/* initialize callinfo stack */ /* initialize callinfo stack */
c->cibase = (mrb_callinfo *)mrb_calloc(mrb, FIBER_CI_INIT_SIZE, sizeof(mrb_callinfo)); c->cibase = (mrb_callinfo *)mrb_calloc(mrb, FIBER_CI_INIT_SIZE, sizeof(mrb_callinfo));
c->ciend = c->cibase + FIBER_CI_INIT_SIZE; c->ciend = c->cibase + FIBER_CI_INIT_SIZE;
c->ci = c->cibase; c->ci = c->cibase;
c->ci->stackent = c->stack;
/* 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; mrb_vm_ci_proc_set(ci, 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->stack = c->stbase;
ci[1] = ci[0]; ci[1] = ci[0];
c->ci++; /* push dummy callinfo */ c->ci++; /* push dummy callinfo */
...@@ -154,7 +152,7 @@ fiber_result(mrb_state *mrb, const mrb_value *a, mrb_int len) ...@@ -154,7 +152,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)
...@@ -214,7 +212,7 @@ fiber_switch(mrb_state *mrb, mrb_value self, mrb_int len, const mrb_value *a, mr ...@@ -214,7 +212,7 @@ fiber_switch(mrb_state *mrb, mrb_value self, mrb_int len, const mrb_value *a, mr
mrb_raise(mrb, E_FIBER_ERROR, "double resume (current)"); mrb_raise(mrb, E_FIBER_ERROR, "double resume (current)");
} }
mrb_stack_extend(mrb, len+2); /* for receiver and (optional) block */ mrb_stack_extend(mrb, len+2); /* for receiver and (optional) block */
b = c->stack+1; b = c->stbase+1;
e = b + len; e = b + len;
while (b<e) { while (b<e) {
*b++ = *a++; *b++ = *a++;
...@@ -223,7 +221,7 @@ fiber_switch(mrb_state *mrb, mrb_value self, mrb_int len, const mrb_value *a, mr ...@@ -223,7 +221,7 @@ fiber_switch(mrb_state *mrb, mrb_value self, mrb_int len, const mrb_value *a, mr
c->ci--; /* pop dummy callinfo */ c->ci--; /* pop dummy callinfo */
} }
c->cibase->argc = (int)len; c->cibase->argc = (int)len;
value = c->stack[0] = MRB_PROC_ENV(c->cibase->proc)->stack[0]; value = c->stbase[0] = MRB_PROC_ENV(c->cibase->proc)->stack[0];
} }
else { else {
value = fiber_result(mrb, a, len); value = fiber_result(mrb, a, len);
...@@ -231,7 +229,7 @@ fiber_switch(mrb_state *mrb, mrb_value self, mrb_int len, const mrb_value *a, mr ...@@ -231,7 +229,7 @@ fiber_switch(mrb_state *mrb, mrb_value self, mrb_int len, const mrb_value *a, mr
if (vmexec) { if (vmexec) {
c->vmexec = TRUE; c->vmexec = TRUE;
value = mrb_vm_exec(mrb, c->ci->proc, c->cibase->pc); value = mrb_vm_exec(mrb, c->ci->proc, c->ci->pc);
mrb->c = old_c; mrb->c = old_c;
} }
else { else {
...@@ -357,7 +355,6 @@ mrb_fiber_yield(mrb_state *mrb, mrb_int len, const mrb_value *a) ...@@ -357,7 +355,6 @@ mrb_fiber_yield(mrb_state *mrb, mrb_int len, const mrb_value *a)
if (c->vmexec) { if (c->vmexec) {
c->vmexec = FALSE; c->vmexec = FALSE;
mrb->c->ci->acc = CI_ACC_RESUMED; mrb->c->ci->acc = CI_ACC_RESUMED;
c->cibase->pc = c->ci->pc;
c->ci--; /* pop callinfo for yield */ c->ci--; /* pop callinfo for yield */
} }
MARK_CONTEXT_MODIFY(mrb->c); MARK_CONTEXT_MODIFY(mrb->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);
} }
......
...@@ -29,7 +29,7 @@ mrb_value mrb_exc_inspect(mrb_state *mrb, mrb_value exc); ...@@ -29,7 +29,7 @@ mrb_value mrb_exc_inspect(mrb_state *mrb, mrb_value exc);
mrb_value mrb_unpack_backtrace(mrb_state *mrb, mrb_value backtrace); mrb_value mrb_unpack_backtrace(mrb_state *mrb, mrb_value backtrace);
static void static void
each_backtrace(mrb_state *mrb, ptrdiff_t ciidx, const mrb_code *pc0, each_backtrace_func func, void *data) each_backtrace(mrb_state *mrb, ptrdiff_t ciidx, each_backtrace_func func, void *data)
{ {
ptrdiff_t i; ptrdiff_t i;
...@@ -50,15 +50,11 @@ each_backtrace(mrb_state *mrb, ptrdiff_t ciidx, const mrb_code *pc0, each_backtr ...@@ -50,15 +50,11 @@ each_backtrace(mrb_state *mrb, ptrdiff_t ciidx, const mrb_code *pc0, each_backtr
irep = ci->proc->body.irep; irep = ci->proc->body.irep;
if (!irep) continue; if (!irep) continue;
if (mrb->c->cibase[i].err) { if (mrb->c->cibase[i].pc) {
pc = mrb->c->cibase[i].err; pc = &mrb->c->cibase[i].pc[-1];
}
else if (i+1 <= ciidx) {
if (!mrb->c->cibase[i + 1].pc) continue;
pc = &mrb->c->cibase[i+1].pc[-1];
} }
else { else {
pc = pc0; continue;
} }
loc.lineno = mrb_debug_get_line(mrb, irep, pc - irep->iseq); loc.lineno = mrb_debug_get_line(mrb, irep, pc - irep->iseq);
...@@ -159,12 +155,12 @@ packed_backtrace(mrb_state *mrb) ...@@ -159,12 +155,12 @@ packed_backtrace(mrb_state *mrb)
int size; int size;
void *ptr; void *ptr;
each_backtrace(mrb, ciidx, mrb->c->ci->pc, count_backtrace_i, &len); each_backtrace(mrb, ciidx, count_backtrace_i, &len);
size = len * sizeof(struct backtrace_location); size = len * sizeof(struct backtrace_location);
ptr = mrb_malloc(mrb, size); ptr = mrb_malloc(mrb, size);
backtrace = mrb_data_object_alloc(mrb, NULL, ptr, &bt_type); backtrace = mrb_data_object_alloc(mrb, NULL, ptr, &bt_type);
backtrace->flags = (uint32_t)len; backtrace->flags = (uint32_t)len;
each_backtrace(mrb, ciidx, mrb->c->ci->pc, pack_backtrace_i, &ptr); each_backtrace(mrb, ciidx, pack_backtrace_i, &ptr);
return mrb_obj_value(backtrace); return mrb_obj_value(backtrace);
} }
......
...@@ -815,7 +815,7 @@ mrb_get_argc(mrb_state *mrb) ...@@ -815,7 +815,7 @@ mrb_get_argc(mrb_state *mrb)
mrb_int argc = mrb->c->ci->argc; mrb_int argc = mrb->c->ci->argc;
if (argc < 0) { if (argc < 0) {
struct RArray *a = mrb_ary_ptr(mrb->c->stack[1]); struct RArray *a = mrb_ary_ptr(mrb->c->ci->stack[1]);
argc = ARY_LEN(a); argc = ARY_LEN(a);
} }
...@@ -826,7 +826,7 @@ MRB_API const mrb_value* ...@@ -826,7 +826,7 @@ MRB_API const mrb_value*
mrb_get_argv(mrb_state *mrb) mrb_get_argv(mrb_state *mrb)
{ {
mrb_int argc = mrb->c->ci->argc; mrb_int argc = mrb->c->ci->argc;
mrb_value *array_argv = mrb->c->stack + 1; mrb_value *array_argv = mrb->c->ci->stack + 1;
if (argc < 0) { if (argc < 0) {
struct RArray *a = mrb_ary_ptr(*array_argv); struct RArray *a = mrb_ary_ptr(*array_argv);
...@@ -839,7 +839,7 @@ MRB_API mrb_value ...@@ -839,7 +839,7 @@ MRB_API mrb_value
mrb_get_arg1(mrb_state *mrb) mrb_get_arg1(mrb_state *mrb)
{ {
mrb_int argc = mrb->c->ci->argc; mrb_int argc = mrb->c->ci->argc;
mrb_value *array_argv = mrb->c->stack + 1; mrb_value *array_argv = mrb->c->ci->stack + 1;
if (argc < 0) { if (argc < 0) {
struct RArray *a = mrb_ary_ptr(*array_argv); struct RArray *a = mrb_ary_ptr(*array_argv);
...@@ -894,7 +894,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) ...@@ -894,7 +894,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
mrb_int i = 0; mrb_int i = 0;
va_list ap; va_list ap;
mrb_int argc = mrb->c->ci->argc; mrb_int argc = mrb->c->ci->argc;
mrb_value *array_argv = mrb->c->stack+1; mrb_value *array_argv = mrb->c->ci->stack+1;
mrb_bool argv_on_stack = argc >= 0; mrb_bool argv_on_stack = argc >= 0;
mrb_bool opt = FALSE; mrb_bool opt = FALSE;
mrb_bool opt_skip = TRUE; mrb_bool opt_skip = TRUE;
...@@ -1207,10 +1207,10 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) ...@@ -1207,10 +1207,10 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
p = va_arg(ap, mrb_value*); p = va_arg(ap, mrb_value*);
if (mrb->c->ci->argc < 0) { if (mrb->c->ci->argc < 0) {
bp = mrb->c->stack + 2; bp = mrb->c->ci->stack + 2;
} }
else { else {
bp = mrb->c->stack + mrb->c->ci->argc + 1; bp = mrb->c->ci->stack + mrb->c->ci->argc + 1;
} }
if (altmode && mrb_nil_p(*bp)) { if (altmode && mrb_nil_p(*bp)) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given"); mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given");
......
...@@ -626,11 +626,14 @@ mark_context_stack(mrb_state *mrb, struct mrb_context *c) ...@@ -626,11 +626,14 @@ mark_context_stack(mrb_state *mrb, struct mrb_context *c)
size_t e; size_t e;
mrb_value nil; mrb_value nil;
if (c->stack == NULL) return; if (c->stbase == NULL) return;
e = c->stack - c->stbase;
if (c->ci) { if (c->ci) {
e = (c->ci->stack ? c->ci->stack - c->stbase : 0);
e += ci_nregs(c->ci); e += ci_nregs(c->ci);
} }
else {
e = 0;
}
if (c->stbase + e > c->stend) e = c->stend - c->stbase; if (c->stbase + e > c->stend) e = c->stend - c->stbase;
for (i=0; i<e; i++) { for (i=0; i<e; i++) {
mrb_value v = c->stbase[i]; mrb_value v = c->stbase[i];
...@@ -660,9 +663,8 @@ mark_context(mrb_state *mrb, struct mrb_context *c) ...@@ -660,9 +663,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 +842,7 @@ obj_free(mrb_state *mrb, struct RBasic *obj, int end) ...@@ -840,7 +842,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);
...@@ -1002,7 +1004,7 @@ gc_gray_counts(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj) ...@@ -1002,7 +1004,7 @@ gc_gray_counts(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj)
if (!c || c->status == MRB_FIBER_TERMINATED) break; if (!c || c->status == MRB_FIBER_TERMINATED) break;
/* mark stack */ /* mark stack */
i = c->stack - c->stbase; i = c->ci->stack - c->stbase;
if (c->ci) { if (c->ci) {
i += ci_nregs(c->ci); i += ci_nregs(c->ci);
......
...@@ -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);
...@@ -186,7 +185,7 @@ mrb_f_block_given_p_m(mrb_state *mrb, mrb_value self) ...@@ -186,7 +185,7 @@ mrb_f_block_given_p_m(mrb_state *mrb, mrb_value self)
bp = &e->stack[bidx]; bp = &e->stack[bidx];
} }
else { else {
bp = ci[1].stackent+1; bp = ci->stack+1;
if (ci->argc >= 0) { if (ci->argc >= 0) {
bp += ci->argc; bp += ci->argc;
} }
......
...@@ -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;
...@@ -85,14 +85,14 @@ closure_setup(mrb_state *mrb, struct RProc *p) ...@@ -85,14 +85,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, ci->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;
} }
...@@ -213,7 +213,7 @@ mrb_proc_s_new(mrb_state *mrb, mrb_value proc_class) ...@@ -213,7 +213,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;
......
This diff is collapsed.
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