mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
Merge branch 'dearblue-reorganize-ci'
This commit is contained in:
+9
-9
@@ -151,13 +151,14 @@ typedef void* (*mrb_allocf) (struct mrb_state *mrb, void*, size_t, void *ud);
|
||||
typedef struct {
|
||||
mrb_sym mid;
|
||||
const struct RProc *proc;
|
||||
mrb_value *stackent;
|
||||
struct REnv *env;
|
||||
const mrb_code *pc; /* return address */
|
||||
const mrb_code *err; /* error position */
|
||||
mrb_int argc;
|
||||
mrb_int acc;
|
||||
struct RClass *target_class;
|
||||
mrb_value *stack;
|
||||
const mrb_code *pc; /* current address on iseq of this proc */
|
||||
int16_t argc;
|
||||
int16_t acc;
|
||||
union {
|
||||
struct REnv *env;
|
||||
struct RClass *target_class;
|
||||
} u;
|
||||
} mrb_callinfo;
|
||||
|
||||
enum mrb_fiber_state {
|
||||
@@ -172,8 +173,7 @@ enum mrb_fiber_state {
|
||||
struct mrb_context {
|
||||
struct mrb_context *prev;
|
||||
|
||||
mrb_value *stack; /* stack of virtual machine */
|
||||
mrb_value *stbase, *stend;
|
||||
mrb_value *stbase, *stend; /* stack of virtual machine */
|
||||
|
||||
mrb_callinfo *ci;
|
||||
mrb_callinfo *cibase, *ciend;
|
||||
|
||||
@@ -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);
|
||||
|
||||
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
|
||||
|
||||
#endif /* MRUBY_PROC_H */
|
||||
|
||||
+2
-2
@@ -218,8 +218,8 @@ module MRuby
|
||||
f.puts %Q[ mrb_close(mrb);]
|
||||
f.puts %Q[ exit(EXIT_FAILURE);]
|
||||
f.puts %Q[ }]
|
||||
f.puts %Q[ struct REnv *e = mrb->c->cibase->env;]
|
||||
f.puts %Q[ mrb->c->cibase->env = NULL;]
|
||||
f.puts %Q[ struct REnv *e = mrb_vm_ci_env(mrb->c->cibase);]
|
||||
f.puts %Q[ mrb_vm_ci_env_set(mrb->c->cibase, NULL);]
|
||||
f.puts %Q[ mrb_env_unshare(mrb, e);]
|
||||
end
|
||||
f.puts %Q[ mrb_gc_arena_restore(mrb, ai);]
|
||||
|
||||
@@ -516,8 +516,8 @@ main(int argc, char **argv)
|
||||
}
|
||||
mrb_load_file_cxt(mrb, lfp, cxt);
|
||||
fclose(lfp);
|
||||
e = mrb->c->cibase->env;
|
||||
mrb->c->cibase->env = NULL;
|
||||
e = mrb_vm_ci_env(mrb->c->cibase);
|
||||
mrb_vm_ci_env_set(mrb->c->cibase, NULL);
|
||||
mrb_env_unshare(mrb, e);
|
||||
mrbc_cleanup_local_variables(mrb, cxt);
|
||||
}
|
||||
@@ -658,8 +658,8 @@ main(int argc, char **argv)
|
||||
mrb_codedump_all(mrb, proc);
|
||||
}
|
||||
/* adjust stack length of toplevel environment */
|
||||
if (mrb->c->cibase->env) {
|
||||
struct REnv *e = mrb->c->cibase->env;
|
||||
if (mrb->c->cibase->u.env) {
|
||||
struct REnv *e = mrb_vm_ci_env(mrb->c->cibase);
|
||||
if (e && MRB_ENV_LEN(e) < proc->body.irep->nlocals) {
|
||||
MRB_ENV_SET_LEN(e, proc->body.irep->nlocals);
|
||||
}
|
||||
@@ -683,7 +683,7 @@ main(int argc, char **argv)
|
||||
}
|
||||
p(mrb, result, 1);
|
||||
#ifndef MRB_NO_MIRB_UNDERSCORE
|
||||
*(mrb->c->stack + 1) = result;
|
||||
*(mrb->c->ci->stack + 1) = result;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -333,8 +333,8 @@ main(int argc, char **argv)
|
||||
v = mrb_load_detect_file_cxt(mrb, lfp, c);
|
||||
}
|
||||
fclose(lfp);
|
||||
e = mrb->c->cibase->env;
|
||||
mrb->c->cibase->env = NULL;
|
||||
e = mrb_vm_ci_env(mrb->c->cibase);
|
||||
mrb_vm_ci_env_set(mrb->c->cibase, NULL);
|
||||
mrb_env_unshare(mrb, e);
|
||||
mrbc_cleanup_local_variables(mrb, c);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "mruby.h"
|
||||
#include "mruby/class.h"
|
||||
#include "mruby/string.h"
|
||||
#include "mruby/proc.h"
|
||||
|
||||
static mrb_value
|
||||
mrb_mod_name(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) {
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
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);
|
||||
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)
|
||||
}
|
||||
MRB_PROC_SET_TARGET_CLASS(proc, target);
|
||||
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);
|
||||
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
|
||||
target_class = MRB_PROC_TARGET_CLASS(ci->proc);
|
||||
}
|
||||
if (ci->proc && !MRB_PROC_CFUNC_P(ci->proc)) {
|
||||
if (ci->env) {
|
||||
e = ci->env;
|
||||
if ((e = mrb_vm_ci_env(ci)) != NULL) {
|
||||
/* do nothing, because e is assigned already */
|
||||
}
|
||||
else {
|
||||
e = mrb_env_new(mrb, mrb->c, ci, ci->proc->body.irep->nlocals, ci[1].stackent, target_class);
|
||||
ci->env = e;
|
||||
e = mrb_env_new(mrb, mrb->c, ci, ci->proc->body.irep->nlocals, ci->stack, target_class);
|
||||
ci->u.env = e;
|
||||
}
|
||||
proc->e.env = e;
|
||||
proc->flags |= MRB_PROC_ENVSET;
|
||||
mrb_field_write_barrier(mrb, (struct RBasic*)proc, (struct RBasic*)e);
|
||||
}
|
||||
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_parser_free(p);
|
||||
@@ -115,7 +115,7 @@ exec_irep(mrb_state *mrb, mrb_value self, struct RProc *proc)
|
||||
return ret;
|
||||
}
|
||||
/* clear block */
|
||||
mrb->c->stack[1] = mrb_nil_value();
|
||||
mrb->c->ci->stack[1] = mrb_nil_value();
|
||||
return mrb_exec_irep(mrb, self, proc);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
MRB_PROC_SET_TARGET_CLASS(proc, mrb_class_ptr(cv));
|
||||
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);
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -93,7 +93,6 @@ fiber_init(mrb_state *mrb, mrb_value self)
|
||||
}
|
||||
c->stbase = (mrb_value *)mrb_malloc(mrb, slen*sizeof(mrb_value));
|
||||
c->stend = c->stbase + slen;
|
||||
c->stack = c->stbase;
|
||||
|
||||
#ifdef MRB_NAN_BOXING
|
||||
{
|
||||
@@ -110,20 +109,19 @@ fiber_init(mrb_state *mrb, mrb_value self)
|
||||
#endif
|
||||
|
||||
/* copy receiver from a block */
|
||||
c->stack[0] = mrb->c->stack[0];
|
||||
c->stbase[0] = mrb->c->ci->stack[0];
|
||||
|
||||
/* initialize callinfo stack */
|
||||
c->cibase = (mrb_callinfo *)mrb_calloc(mrb, FIBER_CI_INIT_SIZE, sizeof(mrb_callinfo));
|
||||
c->ciend = c->cibase + FIBER_CI_INIT_SIZE;
|
||||
c->ci = c->cibase;
|
||||
c->ci->stackent = c->stack;
|
||||
|
||||
/* adjust return callinfo */
|
||||
ci = c->ci;
|
||||
ci->target_class = MRB_PROC_TARGET_CLASS(p);
|
||||
ci->proc = p;
|
||||
mrb_vm_ci_target_class_set(ci, MRB_PROC_TARGET_CLASS(p));
|
||||
mrb_vm_ci_proc_set(ci, 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];
|
||||
c->ci++; /* push dummy callinfo */
|
||||
|
||||
@@ -154,7 +152,7 @@ fiber_result(mrb_state *mrb, const mrb_value *a, mrb_int len)
|
||||
}
|
||||
|
||||
/* 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
|
||||
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
|
||||
mrb_raise(mrb, E_FIBER_ERROR, "double resume (current)");
|
||||
}
|
||||
mrb_stack_extend(mrb, len+2); /* for receiver and (optional) block */
|
||||
b = c->stack+1;
|
||||
b = c->stbase+1;
|
||||
e = b + len;
|
||||
while (b<e) {
|
||||
*b++ = *a++;
|
||||
@@ -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->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 {
|
||||
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
|
||||
|
||||
if (vmexec) {
|
||||
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;
|
||||
}
|
||||
else {
|
||||
@@ -357,7 +355,6 @@ mrb_fiber_yield(mrb_state *mrb, mrb_int len, const mrb_value *a)
|
||||
if (c->vmexec) {
|
||||
c->vmexec = FALSE;
|
||||
mrb->c->ci->acc = CI_ACC_RESUMED;
|
||||
c->cibase->pc = c->ci->pc;
|
||||
c->ci--; /* pop callinfo for yield */
|
||||
}
|
||||
MARK_CONTEXT_MODIFY(mrb->c);
|
||||
|
||||
@@ -105,7 +105,7 @@ mrb_obj_instance_exec(mrb_state *mrb, mrb_value self)
|
||||
if (mrb->c->ci->acc < 0) {
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
+6
-10
@@ -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);
|
||||
|
||||
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;
|
||||
|
||||
@@ -50,15 +50,11 @@ each_backtrace(mrb_state *mrb, ptrdiff_t ciidx, const mrb_code *pc0, each_backtr
|
||||
irep = ci->proc->body.irep;
|
||||
if (!irep) continue;
|
||||
|
||||
if (mrb->c->cibase[i].err) {
|
||||
pc = mrb->c->cibase[i].err;
|
||||
}
|
||||
else if (i+1 <= ciidx) {
|
||||
if (!mrb->c->cibase[i + 1].pc) continue;
|
||||
pc = &mrb->c->cibase[i+1].pc[-1];
|
||||
if (mrb->c->cibase[i].pc) {
|
||||
pc = &mrb->c->cibase[i].pc[-1];
|
||||
}
|
||||
else {
|
||||
pc = pc0;
|
||||
continue;
|
||||
}
|
||||
|
||||
loc.lineno = mrb_debug_get_line(mrb, irep, pc - irep->iseq);
|
||||
@@ -159,12 +155,12 @@ packed_backtrace(mrb_state *mrb)
|
||||
int size;
|
||||
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);
|
||||
ptr = mrb_malloc(mrb, size);
|
||||
backtrace = mrb_data_object_alloc(mrb, NULL, ptr, &bt_type);
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
+6
-6
@@ -815,7 +815,7 @@ mrb_get_argc(mrb_state *mrb)
|
||||
mrb_int argc = mrb->c->ci->argc;
|
||||
|
||||
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);
|
||||
}
|
||||
@@ -826,7 +826,7 @@ MRB_API const mrb_value*
|
||||
mrb_get_argv(mrb_state *mrb)
|
||||
{
|
||||
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) {
|
||||
struct RArray *a = mrb_ary_ptr(*array_argv);
|
||||
|
||||
@@ -839,7 +839,7 @@ MRB_API mrb_value
|
||||
mrb_get_arg1(mrb_state *mrb)
|
||||
{
|
||||
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) {
|
||||
struct RArray *a = mrb_ary_ptr(*array_argv);
|
||||
|
||||
@@ -894,7 +894,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
|
||||
mrb_int i = 0;
|
||||
va_list ap;
|
||||
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 opt = FALSE;
|
||||
mrb_bool opt_skip = TRUE;
|
||||
@@ -1207,10 +1207,10 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
|
||||
|
||||
p = va_arg(ap, mrb_value*);
|
||||
if (mrb->c->ci->argc < 0) {
|
||||
bp = mrb->c->stack + 2;
|
||||
bp = mrb->c->ci->stack + 2;
|
||||
}
|
||||
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)) {
|
||||
mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given");
|
||||
|
||||
@@ -626,11 +626,14 @@ mark_context_stack(mrb_state *mrb, struct mrb_context *c)
|
||||
size_t e;
|
||||
mrb_value nil;
|
||||
|
||||
if (c->stack == NULL) return;
|
||||
e = c->stack - c->stbase;
|
||||
if (c->stbase == NULL) return;
|
||||
if (c->ci) {
|
||||
e = (c->ci->stack ? c->ci->stack - c->stbase : 0);
|
||||
e += ci_nregs(c->ci);
|
||||
}
|
||||
else {
|
||||
e = 0;
|
||||
}
|
||||
if (c->stbase + e > c->stend) e = c->stend - c->stbase;
|
||||
for (i=0; i<e; i++) {
|
||||
mrb_value v = c->stbase[i];
|
||||
@@ -660,9 +663,8 @@ mark_context(mrb_state *mrb, struct mrb_context *c)
|
||||
/* mark call stack */
|
||||
if (c->cibase) {
|
||||
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->target_class);
|
||||
mrb_gc_mark(mrb, (struct RBasic*)ci->u.target_class);
|
||||
}
|
||||
}
|
||||
/* mark fibers */
|
||||
@@ -840,7 +842,7 @@ obj_free(mrb_state *mrb, struct RBasic *obj, int end)
|
||||
mrb_callinfo *ce = c->cibase;
|
||||
|
||||
while (ce <= ci) {
|
||||
struct REnv *e = ci->env;
|
||||
struct REnv *e = ci->u.env;
|
||||
if (e && !mrb_object_dead_p(mrb, (struct RBasic*)e) &&
|
||||
e->tt == MRB_TT_ENV && MRB_ENV_ONSTACK_P(e)) {
|
||||
mrb_env_unshare(mrb, e);
|
||||
@@ -1002,7 +1004,7 @@ gc_gray_counts(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj)
|
||||
if (!c || c->status == MRB_FIBER_TERMINATED) break;
|
||||
|
||||
/* mark stack */
|
||||
i = c->stack - c->stbase;
|
||||
i = c->ci->stack - c->stbase;
|
||||
|
||||
if (c->ci) {
|
||||
i += ci_nregs(c->ci);
|
||||
|
||||
+2
-3
@@ -176,8 +176,7 @@ mrb_f_block_given_p_m(mrb_state *mrb, mrb_value self)
|
||||
if (bidx < 0) return mrb_false_value();
|
||||
bp = &e->stack[bidx];
|
||||
}
|
||||
else if (ci->env) {
|
||||
e = ci->env;
|
||||
else if ((e = mrb_vm_ci_env(ci)) != NULL) {
|
||||
/* top-level does not have block slot (always false) */
|
||||
if (e->stack == mrb->c->stbase) return mrb_false_value();
|
||||
bidx = env_bidx(e);
|
||||
@@ -186,7 +185,7 @@ mrb_f_block_given_p_m(mrb_state *mrb, mrb_value self)
|
||||
bp = &e->stack[bidx];
|
||||
}
|
||||
else {
|
||||
bp = ci[1].stackent+1;
|
||||
bp = ci->stack+1;
|
||||
if (ci->argc >= 0) {
|
||||
bp += ci->argc;
|
||||
}
|
||||
|
||||
+6
-6
@@ -46,7 +46,7 @@ mrb_proc_new(mrb_state *mrb, const mrb_irep *irep)
|
||||
tc = MRB_PROC_TARGET_CLASS(ci->proc);
|
||||
}
|
||||
if (tc == NULL) {
|
||||
tc = ci->target_class;
|
||||
tc = mrb_vm_ci_target_class(ci);
|
||||
}
|
||||
p->upper = ci->proc;
|
||||
p->e.target_class = tc;
|
||||
@@ -85,14 +85,14 @@ closure_setup(mrb_state *mrb, struct RProc *p)
|
||||
const struct RProc *up = p->upper;
|
||||
struct REnv *e = NULL;
|
||||
|
||||
if (ci && ci->env) {
|
||||
e = ci->env;
|
||||
if (ci && (e = mrb_vm_ci_env(ci)) != NULL) {
|
||||
/* do nothing, because e is assigned already */
|
||||
}
|
||||
else if (up) {
|
||||
struct RClass *tc = MRB_PROC_TARGET_CLASS(p);
|
||||
|
||||
e = mrb_env_new(mrb, mrb->c, ci, up->body.irep->nlocals, mrb->c->stack, tc);
|
||||
ci->env = e;
|
||||
e = mrb_env_new(mrb, mrb->c, ci, up->body.irep->nlocals, ci->stack, tc);
|
||||
ci->u.env = e;
|
||||
if (MRB_PROC_ENV_P(up) && MRB_PROC_ENV(up)->cxt == NULL) {
|
||||
e->mid = MRB_PROC_ENV(up)->mid;
|
||||
}
|
||||
@@ -213,7 +213,7 @@ mrb_proc_s_new(mrb_state *mrb, mrb_value proc_class)
|
||||
proc = mrb_obj_value(p);
|
||||
mrb_funcall_with_block(mrb, proc, MRB_SYM(initialize), 0, NULL, proc);
|
||||
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;
|
||||
}
|
||||
return proc;
|
||||
|
||||
@@ -127,14 +127,13 @@ stack_init(mrb_state *mrb)
|
||||
/* mrb_assert(mrb->stack == NULL); */
|
||||
c->stbase = (mrb_value *)mrb_calloc(mrb, STACK_INIT_SIZE, sizeof(mrb_value));
|
||||
c->stend = c->stbase + STACK_INIT_SIZE;
|
||||
c->stack = c->stbase;
|
||||
|
||||
/* mrb_assert(ci == NULL); */
|
||||
c->cibase = (mrb_callinfo *)mrb_calloc(mrb, CALLINFO_INIT_SIZE, sizeof(mrb_callinfo));
|
||||
c->ciend = c->cibase + CALLINFO_INIT_SIZE;
|
||||
c->ci = c->cibase;
|
||||
c->ci->target_class = mrb->object_class;
|
||||
c->ci->stackent = c->stack;
|
||||
c->ci->u.target_class = mrb->object_class;
|
||||
c->ci->stack = c->stbase;
|
||||
}
|
||||
|
||||
static inline void
|
||||
@@ -144,7 +143,7 @@ envadjust(mrb_state *mrb, mrb_value *oldbase, mrb_value *newbase, size_t oldsize
|
||||
|
||||
if (newbase == oldbase) return;
|
||||
while (ci <= mrb->c->ci) {
|
||||
struct REnv *e = ci->env;
|
||||
struct REnv *e = mrb_vm_ci_env(ci);
|
||||
mrb_value *st;
|
||||
|
||||
if (e && MRB_ENV_ONSTACK_P(e) &&
|
||||
@@ -154,7 +153,7 @@ envadjust(mrb_state *mrb, mrb_value *oldbase, mrb_value *newbase, size_t oldsize
|
||||
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);
|
||||
|
||||
if (e && MRB_ENV_ONSTACK_P(e) &&
|
||||
@@ -165,7 +164,7 @@ envadjust(mrb_state *mrb, mrb_value *oldbase, mrb_value *newbase, size_t oldsize
|
||||
}
|
||||
}
|
||||
|
||||
ci->stackent = newbase + (ci->stackent - oldbase);
|
||||
ci->stack = newbase + (ci->stack - oldbase);
|
||||
ci++;
|
||||
}
|
||||
}
|
||||
@@ -179,7 +178,7 @@ stack_extend_alloc(mrb_state *mrb, mrb_int room)
|
||||
mrb_value *newstack;
|
||||
size_t oldsize = mrb->c->stend - mrb->c->stbase;
|
||||
size_t size = oldsize;
|
||||
size_t off = mrb->c->stack - mrb->c->stbase;
|
||||
size_t off = mrb->c->ci->stack ? mrb->c->stend - mrb->c->ci->stack : 0;
|
||||
|
||||
if (off > size) size = off;
|
||||
#ifdef MRB_STACK_EXTEND_DOUBLING
|
||||
@@ -204,7 +203,6 @@ stack_extend_alloc(mrb_state *mrb, mrb_int room)
|
||||
stack_clear(&(newstack[oldsize]), size - oldsize);
|
||||
envadjust(mrb, oldbase, newstack, oldsize);
|
||||
mrb->c->stbase = newstack;
|
||||
mrb->c->stack = mrb->c->stbase + off;
|
||||
mrb->c->stend = mrb->c->stbase + size;
|
||||
|
||||
/* Raise an exception if the new stack size will be too large,
|
||||
@@ -217,7 +215,7 @@ stack_extend_alloc(mrb_state *mrb, mrb_int room)
|
||||
MRB_API void
|
||||
mrb_stack_extend(mrb_state *mrb, mrb_int room)
|
||||
{
|
||||
if (mrb->c->stack + room >= mrb->c->stend) {
|
||||
if (!mrb->c->ci->stack || mrb->c->ci->stack + room >= mrb->c->stend) {
|
||||
stack_extend_alloc(mrb, room);
|
||||
}
|
||||
}
|
||||
@@ -240,7 +238,7 @@ uvenv(mrb_state *mrb, mrb_int up)
|
||||
|
||||
while (cb <= ci) {
|
||||
if (ci->proc == proc) {
|
||||
return ci->env;
|
||||
return mrb_vm_ci_env(ci);
|
||||
}
|
||||
ci--;
|
||||
}
|
||||
@@ -264,7 +262,7 @@ top_proc(mrb_state *mrb, const struct RProc *proc)
|
||||
#define CI_ACC_RESUMED -3
|
||||
|
||||
static inline mrb_callinfo*
|
||||
cipush(mrb_state *mrb, const mrb_code *pc, mrb_int push_stacks, mrb_int acc,
|
||||
cipush(mrb_state *mrb, mrb_int push_stacks, mrb_int acc,
|
||||
struct RClass *target_class, const struct RProc *proc, mrb_sym mid, mrb_int argc)
|
||||
{
|
||||
struct mrb_context *c = mrb->c;
|
||||
@@ -279,15 +277,11 @@ cipush(mrb_state *mrb, const mrb_code *pc, mrb_int push_stacks, mrb_int acc,
|
||||
}
|
||||
ci = ++c->ci;
|
||||
ci->mid = mid;
|
||||
ci->proc = proc;
|
||||
ci->stackent = c->stack;
|
||||
ci->pc = pc;
|
||||
mrb_vm_ci_proc_set(ci, proc);
|
||||
ci->stack = ci[-1].stack + push_stacks;
|
||||
ci->argc = argc;
|
||||
ci->acc = acc;
|
||||
ci->target_class = target_class;
|
||||
ci->err = 0;
|
||||
ci->env = 0;
|
||||
c->stack += push_stacks;
|
||||
ci->u.target_class = target_class;
|
||||
|
||||
return ci;
|
||||
}
|
||||
@@ -302,7 +296,7 @@ mrb_env_unshare(mrb_state *mrb, struct REnv *e)
|
||||
|
||||
if (!MRB_ENV_ONSTACK_P(e)) 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);
|
||||
if (len > 0) {
|
||||
stack_copy(p, e->stack, len);
|
||||
@@ -317,9 +311,8 @@ static inline mrb_callinfo*
|
||||
cipop(mrb_state *mrb)
|
||||
{
|
||||
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;
|
||||
c->ci--;
|
||||
if (env) mrb_env_unshare(mrb, env);
|
||||
return c->ci;
|
||||
@@ -428,7 +421,7 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc
|
||||
mrb_int n = ci_nregs(mrb->c->ci);
|
||||
ptrdiff_t voff = -1;
|
||||
|
||||
if (!mrb->c->stack) {
|
||||
if (!mrb->c->stbase) {
|
||||
stack_init(mrb);
|
||||
}
|
||||
if (argc < 0) {
|
||||
@@ -445,13 +438,13 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc
|
||||
}
|
||||
mrb_ary_unshift(mrb, args, mrb_symbol_value(mid));
|
||||
mrb_stack_extend(mrb, n+2);
|
||||
mrb->c->stack[n+1] = args;
|
||||
mrb->c->ci->stack[n+1] = args;
|
||||
argc = -1;
|
||||
}
|
||||
if (mrb->c->ci - mrb->c->cibase > MRB_FUNCALL_DEPTH_MAX) {
|
||||
mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err));
|
||||
}
|
||||
ci = cipush(mrb, NULL, n, 0, c, NULL, mid, argc);
|
||||
ci = cipush(mrb, n, 0, c, NULL, mid, argc);
|
||||
if (argc < 0) argc = 1;
|
||||
if (mrb->c->stbase <= argv && argv < mrb->c->stend) {
|
||||
voff = argv - mrb->c->stbase;
|
||||
@@ -459,7 +452,7 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc
|
||||
if (argc >= CALL_MAXARGS) {
|
||||
mrb_value args = mrb_ary_new_from_values(mrb, argc, argv);
|
||||
|
||||
mrb->c->stack[1] = args;
|
||||
mrb->c->ci->stack[1] = args;
|
||||
ci->argc = -1;
|
||||
argc = 1;
|
||||
}
|
||||
@@ -467,7 +460,7 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc
|
||||
if (MRB_METHOD_PROC_P(m)) {
|
||||
struct RProc *p = MRB_METHOD_PROC(m);
|
||||
|
||||
ci->proc = p;
|
||||
mrb_vm_ci_proc_set(ci, p);
|
||||
if (!MRB_PROC_CFUNC_P(p)) {
|
||||
mrb_stack_extend(mrb, p->body.irep->nregs + argc);
|
||||
}
|
||||
@@ -475,11 +468,11 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc
|
||||
if (voff >= 0) {
|
||||
argv = mrb->c->stbase + voff;
|
||||
}
|
||||
mrb->c->stack[0] = self;
|
||||
mrb->c->ci->stack[0] = self;
|
||||
if (ci->argc > 0) {
|
||||
stack_copy(mrb->c->stack+1, argv, argc);
|
||||
stack_copy(mrb->c->ci->stack+1, argv, argc);
|
||||
}
|
||||
mrb->c->stack[argc+1] = blk;
|
||||
mrb->c->ci->stack[argc+1] = blk;
|
||||
|
||||
if (MRB_METHOD_CFUNC_P(m)) {
|
||||
ci->acc = CI_ACC_DIRECT;
|
||||
@@ -508,8 +501,8 @@ mrb_exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p)
|
||||
mrb_callinfo *ci = mrb->c->ci;
|
||||
mrb_int keep, nregs;
|
||||
|
||||
mrb->c->stack[0] = self;
|
||||
ci->proc = p;
|
||||
mrb->c->ci->stack[0] = self;
|
||||
mrb_vm_ci_proc_set(ci, p);
|
||||
if (MRB_PROC_CFUNC_P(p)) {
|
||||
return MRB_PROC_CFUNC(p)(mrb, self);
|
||||
}
|
||||
@@ -521,10 +514,10 @@ mrb_exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p)
|
||||
}
|
||||
else {
|
||||
mrb_stack_extend(mrb, nregs);
|
||||
stack_clear(mrb->c->stack+keep, nregs-keep);
|
||||
stack_clear(mrb->c->ci->stack+keep, nregs-keep);
|
||||
}
|
||||
|
||||
cipush(mrb, p->body.irep->iseq, 0, 0, NULL, NULL, 0, 0);
|
||||
cipush(mrb, 0, 0, NULL, NULL, 0, 0);
|
||||
|
||||
return self;
|
||||
}
|
||||
@@ -573,8 +566,8 @@ mrb_f_send(mrb_state *mrb, mrb_value self)
|
||||
}
|
||||
|
||||
ci->mid = name;
|
||||
ci->target_class = c;
|
||||
regs = mrb->c->stack+1;
|
||||
ci->u.target_class = c;
|
||||
regs = mrb->c->ci->stack+1;
|
||||
/* remove first symbol from arguments */
|
||||
if (ci->argc >= 0) {
|
||||
for (i=0,len=ci->argc; i<len; i++) {
|
||||
@@ -588,7 +581,7 @@ mrb_f_send(mrb_state *mrb, mrb_value self)
|
||||
|
||||
if (MRB_METHOD_CFUNC_P(m)) {
|
||||
if (MRB_METHOD_PROC_P(m)) {
|
||||
ci->proc = MRB_METHOD_PROC(m);
|
||||
mrb_vm_ci_proc_set(ci, MRB_METHOD_PROC(m));
|
||||
}
|
||||
return MRB_METHOD_CFUNC(m)(mrb, self);
|
||||
}
|
||||
@@ -609,25 +602,25 @@ eval_under(mrb_state *mrb, mrb_value self, mrb_value blk, struct RClass *c)
|
||||
if (ci->acc == CI_ACC_DIRECT) {
|
||||
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);
|
||||
ci->proc = p;
|
||||
mrb_vm_ci_proc_set(ci, p);
|
||||
ci->argc = 1;
|
||||
ci->mid = ci[-1].mid;
|
||||
if (MRB_PROC_CFUNC_P(p)) {
|
||||
mrb_stack_extend(mrb, 3);
|
||||
mrb->c->stack[0] = self;
|
||||
mrb->c->stack[1] = self;
|
||||
mrb->c->stack[2] = mrb_nil_value();
|
||||
mrb->c->ci->stack[0] = self;
|
||||
mrb->c->ci->stack[1] = self;
|
||||
mrb->c->ci->stack[2] = mrb_nil_value();
|
||||
return MRB_PROC_CFUNC(p)(mrb, self);
|
||||
}
|
||||
nregs = p->body.irep->nregs;
|
||||
if (nregs < 3) nregs = 3;
|
||||
mrb_stack_extend(mrb, nregs);
|
||||
mrb->c->stack[0] = self;
|
||||
mrb->c->stack[1] = self;
|
||||
stack_clear(mrb->c->stack+2, nregs-2);
|
||||
ci = cipush(mrb, p->body.irep->iseq, 0, 0, NULL, NULL, 0, 0);
|
||||
mrb->c->ci->stack[0] = self;
|
||||
mrb->c->ci->stack[1] = self;
|
||||
stack_clear(mrb->c->ci->stack+2, nregs-2);
|
||||
ci = cipush(mrb, 0, 0, NULL, NULL, 0, 0);
|
||||
|
||||
return self;
|
||||
}
|
||||
@@ -703,7 +696,7 @@ mrb_yield_with_class(mrb_state *mrb, mrb_value b, mrb_int argc, const mrb_value
|
||||
mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err));
|
||||
}
|
||||
p = mrb_proc_ptr(b);
|
||||
ci = cipush(mrb, NULL, n, CI_ACC_SKIP, c, p, mid, 0 /* dummy */);
|
||||
ci = cipush(mrb, n, CI_ACC_SKIP, c, p, mid, 0 /* dummy */);
|
||||
if (argc >= CALL_MAXARGS) {
|
||||
ci->argc = -1;
|
||||
n = 3;
|
||||
@@ -713,15 +706,15 @@ mrb_yield_with_class(mrb_state *mrb, mrb_value b, mrb_int argc, const mrb_value
|
||||
n = argc + 2;
|
||||
}
|
||||
mrb_stack_extend(mrb, n);
|
||||
mrb->c->stack[0] = self;
|
||||
mrb->c->ci->stack[0] = self;
|
||||
if (ci->argc < 0) {
|
||||
mrb->c->stack[1] = mrb_ary_new_from_values(mrb, argc, argv);
|
||||
mrb->c->ci->stack[1] = mrb_ary_new_from_values(mrb, argc, argv);
|
||||
argc = 1;
|
||||
}
|
||||
else if (argc > 0) {
|
||||
stack_copy(mrb->c->stack+1, argv, argc);
|
||||
stack_copy(mrb->c->ci->stack+1, argv, argc);
|
||||
}
|
||||
mrb->c->stack[argc+1] = mrb_nil_value();
|
||||
mrb->c->ci->stack[argc+1] = mrb_nil_value();
|
||||
|
||||
if (MRB_PROC_CFUNC_P(p)) {
|
||||
val = MRB_PROC_CFUNC(p)(mrb, self);
|
||||
@@ -766,8 +759,8 @@ mrb_yield_cont(mrb_state *mrb, mrb_value b, mrb_value self, mrb_int argc, const
|
||||
ci = mrb->c->ci;
|
||||
|
||||
mrb_stack_extend(mrb, 3);
|
||||
mrb->c->stack[1] = mrb_ary_new_from_values(mrb, argc, argv);
|
||||
mrb->c->stack[2] = mrb_nil_value();
|
||||
mrb->c->ci->stack[1] = mrb_ary_new_from_values(mrb, argc, argv);
|
||||
mrb->c->ci->stack[2] = mrb_nil_value();
|
||||
ci->argc = -1;
|
||||
return mrb_exec_irep(mrb, self, p);
|
||||
}
|
||||
@@ -853,7 +846,7 @@ argnum_error(mrb_state *mrb, mrb_int num)
|
||||
mrb_int argc = mrb->c->ci->argc;
|
||||
|
||||
if (argc < 0) {
|
||||
mrb_value args = mrb->c->stack[1];
|
||||
mrb_value args = mrb->c->ci->stack[1];
|
||||
if (mrb_array_p(args)) {
|
||||
argc = RARRAY_LEN(args);
|
||||
}
|
||||
@@ -933,8 +926,6 @@ prepare_tagged_break(mrb_state *mrb, uint32_t tag, const struct RProc *proc, mrb
|
||||
} while (0); \
|
||||
} while (0)
|
||||
|
||||
#define ERR_PC_SET(mrb) mrb->c->ci->err = pc0;
|
||||
#define ERR_PC_CLR(mrb) mrb->c->ci->err = 0;
|
||||
#ifdef MRB_USE_DEBUG_HOOK
|
||||
#define CODE_FETCH_HOOK(mrb, irep, pc, regs) if ((mrb)->code_fetch_hook) (mrb)->code_fetch_hook((mrb), (irep), (pc), (regs));
|
||||
#else
|
||||
@@ -956,7 +947,7 @@ prepare_tagged_break(mrb_state *mrb, uint32_t tag, const struct RProc *proc, mrb
|
||||
#ifndef DIRECT_THREADED
|
||||
|
||||
#define INIT_DISPATCH for (;;) { insn = BYTECODE_DECODER(*pc); CODE_FETCH_HOOK(mrb, irep, pc, regs); switch (insn) {
|
||||
#define CASE(insn,ops) case insn: pc0=pc++; FETCH_ ## ops (); pc_save = pc;
|
||||
#define CASE(insn,ops) case insn: pc++; FETCH_ ## ops (); mrb->c->ci->pc = pc;
|
||||
#define NEXT goto L_END_DISPATCH
|
||||
#define JUMP NEXT
|
||||
#define END_DISPATCH L_END_DISPATCH:;}}
|
||||
@@ -964,7 +955,7 @@ prepare_tagged_break(mrb_state *mrb, uint32_t tag, const struct RProc *proc, mrb
|
||||
#else
|
||||
|
||||
#define INIT_DISPATCH JUMP; return mrb_nil_value();
|
||||
#define CASE(insn,ops) L_ ## insn: pc0=pc++; FETCH_ ## ops (); pc_save = pc;
|
||||
#define CASE(insn,ops) L_ ## insn: pc++; FETCH_ ## ops (); mrb->c->ci->pc = pc;
|
||||
#define NEXT insn=BYTECODE_DECODER(*pc); CODE_FETCH_HOOK(mrb, irep, pc, regs); goto *optable[insn]
|
||||
#define JUMP NEXT
|
||||
|
||||
@@ -981,14 +972,14 @@ mrb_vm_run(mrb_state *mrb, const struct RProc *proc, mrb_value self, mrb_int sta
|
||||
ptrdiff_t cioff = c->ci - c->cibase;
|
||||
mrb_int nregs = irep->nregs;
|
||||
|
||||
if (!c->stack) {
|
||||
if (!c->stbase) {
|
||||
stack_init(mrb);
|
||||
}
|
||||
if (stack_keep > nregs)
|
||||
nregs = stack_keep;
|
||||
mrb_stack_extend(mrb, nregs);
|
||||
stack_clear(c->stack + stack_keep, nregs - stack_keep);
|
||||
c->stack[0] = self;
|
||||
stack_clear(c->ci->stack + stack_keep, nregs - stack_keep);
|
||||
c->ci->stack[0] = self;
|
||||
result = mrb_vm_exec(mrb, proc, irep->iseq);
|
||||
if (mrb->c != c) {
|
||||
if (mrb->c->fib) {
|
||||
@@ -1005,7 +996,7 @@ mrb_vm_run(mrb_state *mrb, const struct RProc *proc, mrb_value self, mrb_int sta
|
||||
static mrb_bool
|
||||
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_exc_set(mrb, exc);
|
||||
return FALSE;
|
||||
@@ -1019,8 +1010,6 @@ MRB_API mrb_value
|
||||
mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc)
|
||||
{
|
||||
/* mrb_assert(MRB_PROC_CFUNC_P(proc)) */
|
||||
const mrb_code *pc0 = pc;
|
||||
const mrb_code *volatile pc_save = pc;
|
||||
const mrb_irep *irep = proc->body.irep;
|
||||
const mrb_pool_value *pool = irep->pool;
|
||||
const mrb_sym *syms = irep->syms;
|
||||
@@ -1055,9 +1044,9 @@ RETRY_TRY_BLOCK:
|
||||
goto L_RAISE;
|
||||
}
|
||||
mrb->jmp = &c_jmp;
|
||||
mrb->c->ci->proc = proc;
|
||||
mrb_vm_ci_proc_set(mrb->c->ci, proc);
|
||||
|
||||
#define regs (mrb->c->stack)
|
||||
#define regs (mrb->c->ci->stack)
|
||||
INIT_DISPATCH {
|
||||
CASE(OP_NOP, Z) {
|
||||
/* do nothing */
|
||||
@@ -1202,9 +1191,7 @@ RETRY_TRY_BLOCK:
|
||||
|
||||
CASE(OP_GETCV, BB) {
|
||||
mrb_value val;
|
||||
ERR_PC_SET(mrb);
|
||||
val = mrb_vm_cv_get(mrb, syms[b]);
|
||||
ERR_PC_CLR(mrb);
|
||||
regs[a] = val;
|
||||
NEXT;
|
||||
}
|
||||
@@ -1218,9 +1205,7 @@ RETRY_TRY_BLOCK:
|
||||
mrb_value val;
|
||||
mrb_sym sym = syms[b];
|
||||
|
||||
ERR_PC_SET(mrb);
|
||||
val = mrb_vm_const_get(mrb, sym);
|
||||
ERR_PC_CLR(mrb);
|
||||
regs[a] = val;
|
||||
NEXT;
|
||||
}
|
||||
@@ -1233,9 +1218,7 @@ RETRY_TRY_BLOCK:
|
||||
CASE(OP_GETMCNST, BB) {
|
||||
mrb_value val;
|
||||
|
||||
ERR_PC_SET(mrb);
|
||||
val = mrb_const_get(mrb, regs[a], syms[b]);
|
||||
ERR_PC_CLR(mrb);
|
||||
regs[a] = val;
|
||||
NEXT;
|
||||
}
|
||||
@@ -1437,7 +1420,6 @@ RETRY_TRY_BLOCK:
|
||||
m = mrb_method_search_vm(mrb, &cls, missing);
|
||||
if (MRB_METHOD_UNDEF_P(m) || (missing == mrb->c->ci->mid && mrb_obj_eq(mrb, regs[0], recv))) {
|
||||
mrb_value args = (argc < 0) ? regs[a+1] : mrb_ary_new_from_values(mrb, c, regs+a+1);
|
||||
ERR_PC_SET(mrb);
|
||||
mrb_method_missing(mrb, mid, recv, args);
|
||||
}
|
||||
if (argc >= 0) {
|
||||
@@ -1453,13 +1435,13 @@ RETRY_TRY_BLOCK:
|
||||
}
|
||||
|
||||
/* push callinfo */
|
||||
ci = cipush(mrb, pc, a, a, cls, NULL, mid, argc);
|
||||
ci = cipush(mrb, a, a, cls, NULL, mid, argc);
|
||||
|
||||
if (MRB_METHOD_CFUNC_P(m)) {
|
||||
if (MRB_METHOD_PROC_P(m)) {
|
||||
struct RProc *p = MRB_METHOD_PROC(m);
|
||||
|
||||
ci->proc = p;
|
||||
mrb_vm_ci_proc_set(ci, p);
|
||||
recv = p->body.func(mrb, recv);
|
||||
}
|
||||
else if (MRB_METHOD_NOARG_P(m) &&
|
||||
@@ -1476,11 +1458,11 @@ RETRY_TRY_BLOCK:
|
||||
ci = mrb->c->ci;
|
||||
if (mrb_proc_p(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;
|
||||
}
|
||||
}
|
||||
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) {
|
||||
mrb->jmp = prev_jmp;
|
||||
return recv;
|
||||
@@ -1493,15 +1475,15 @@ RETRY_TRY_BLOCK:
|
||||
syms = irep->syms;
|
||||
}
|
||||
}
|
||||
mrb->c->stack[0] = recv;
|
||||
mrb->c->ci->stack[0] = recv;
|
||||
/* pop stackpos */
|
||||
ci = cipop(mrb);
|
||||
pc = ci->pc;
|
||||
cipop(mrb);
|
||||
JUMP;
|
||||
}
|
||||
else {
|
||||
/* setup environment for calling method */
|
||||
proc = ci->proc = MRB_METHOD_PROC(m);
|
||||
mrb_vm_ci_proc_set(ci, (proc = MRB_METHOD_PROC(m)));
|
||||
irep = proc->body.irep;
|
||||
pool = irep->pool;
|
||||
syms = irep->syms;
|
||||
@@ -1513,13 +1495,13 @@ RETRY_TRY_BLOCK:
|
||||
|
||||
CASE(OP_CALL, Z) {
|
||||
mrb_callinfo *ci;
|
||||
mrb_value recv = mrb->c->stack[0];
|
||||
mrb_value recv = mrb->c->ci->stack[0];
|
||||
struct RProc *m = mrb_proc_ptr(recv);
|
||||
|
||||
/* replace callinfo */
|
||||
ci = mrb->c->ci;
|
||||
ci->target_class = MRB_PROC_TARGET_CLASS(m);
|
||||
ci->proc = m;
|
||||
ci->u.target_class = MRB_PROC_TARGET_CLASS(m);
|
||||
mrb_vm_ci_proc_set(ci, m);
|
||||
if (MRB_PROC_ENV_P(m)) {
|
||||
ci->mid = MRB_PROC_ENV(m)->mid;
|
||||
}
|
||||
@@ -1531,9 +1513,8 @@ RETRY_TRY_BLOCK:
|
||||
mrb_gc_arena_shrink(mrb, ai);
|
||||
if (mrb->exc) goto L_RAISE;
|
||||
/* pop stackpos */
|
||||
ci = mrb->c->ci;
|
||||
ci = cipop(mrb);
|
||||
pc = ci->pc;
|
||||
cipop(mrb);
|
||||
regs[ci->acc] = recv;
|
||||
irep = mrb->c->ci->proc->body.irep;
|
||||
pool = irep->pool;
|
||||
@@ -1545,7 +1526,7 @@ RETRY_TRY_BLOCK:
|
||||
proc = m;
|
||||
irep = m->body.irep;
|
||||
if (!irep) {
|
||||
mrb->c->stack[0] = mrb_nil_value();
|
||||
mrb->c->ci->stack[0] = mrb_nil_value();
|
||||
a = 0;
|
||||
c = OP_R_NORMAL;
|
||||
goto L_RETURN;
|
||||
@@ -1591,10 +1572,10 @@ RETRY_TRY_BLOCK:
|
||||
goto L_RAISE;
|
||||
}
|
||||
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) {
|
||||
target_class = ci->target_class;
|
||||
target_class = mrb_vm_ci_target_class(ci);
|
||||
if (target_class->tt != MRB_TT_ICLASS) {
|
||||
mrb_value exc = mrb_exc_new_lit(mrb, E_RUNTIME_ERROR, "superclass info lost [mruby limitations]");
|
||||
mrb_exc_set(mrb, exc);
|
||||
@@ -1627,7 +1608,6 @@ RETRY_TRY_BLOCK:
|
||||
m = mrb_method_search_vm(mrb, &cls, missing);
|
||||
if (MRB_METHOD_UNDEF_P(m)) {
|
||||
mrb_value args = (argc < 0) ? regs[a+1] : mrb_ary_new_from_values(mrb, b, regs+a+1);
|
||||
ERR_PC_SET(mrb);
|
||||
mrb_method_missing(mrb, mid, recv, args);
|
||||
}
|
||||
mid = missing;
|
||||
@@ -1643,23 +1623,23 @@ RETRY_TRY_BLOCK:
|
||||
}
|
||||
|
||||
/* push callinfo */
|
||||
ci = cipush(mrb, pc, a, 0, cls, NULL, mid, argc);
|
||||
ci = cipush(mrb, a, 0, cls, NULL, mid, argc);
|
||||
|
||||
/* prepare stack */
|
||||
mrb->c->stack[0] = recv;
|
||||
mrb->c->ci->stack[0] = recv;
|
||||
|
||||
if (MRB_METHOD_CFUNC_P(m)) {
|
||||
mrb_value v;
|
||||
|
||||
if (MRB_METHOD_PROC_P(m)) {
|
||||
ci->proc = MRB_METHOD_PROC(m);
|
||||
mrb_vm_ci_proc_set(ci, MRB_METHOD_PROC(m));
|
||||
}
|
||||
v = MRB_METHOD_CFUNC(m)(mrb, recv);
|
||||
mrb_gc_arena_restore(mrb, ai);
|
||||
if (mrb->exc) goto L_RAISE;
|
||||
ci = mrb->c->ci;
|
||||
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) {
|
||||
mrb->jmp = prev_jmp;
|
||||
return v;
|
||||
@@ -1672,9 +1652,9 @@ RETRY_TRY_BLOCK:
|
||||
syms = irep->syms;
|
||||
}
|
||||
}
|
||||
mrb->c->stack[0] = v;
|
||||
mrb->c->ci->stack[0] = v;
|
||||
ci = cipop(mrb);
|
||||
pc = ci->pc;
|
||||
cipop(mrb);
|
||||
JUMP;
|
||||
}
|
||||
else {
|
||||
@@ -1682,7 +1662,7 @@ RETRY_TRY_BLOCK:
|
||||
ci->acc = a;
|
||||
|
||||
/* setup environment for calling method */
|
||||
proc = ci->proc = MRB_METHOD_PROC(m);
|
||||
mrb_vm_ci_proc_set(ci, (proc = MRB_METHOD_PROC(m)));
|
||||
irep = proc->body.irep;
|
||||
pool = irep->pool;
|
||||
syms = irep->syms;
|
||||
@@ -1700,7 +1680,7 @@ RETRY_TRY_BLOCK:
|
||||
mrb_int lv = (b>>0)&0xf;
|
||||
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;
|
||||
|
||||
L_NOSUPER:
|
||||
@@ -1951,7 +1931,7 @@ RETRY_TRY_BLOCK:
|
||||
struct RProc *p = mrb_proc_ptr(blk);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -1973,13 +1953,13 @@ RETRY_TRY_BLOCK:
|
||||
mrb->jmp = prev_jmp;
|
||||
MRB_THROW(prev_jmp);
|
||||
}
|
||||
pc = ci[1].pc;
|
||||
pc = ci[0].pc;
|
||||
if (ci == mrb->c->cibase) {
|
||||
ch = catch_handler_find(mrb, ci, pc, MRB_CATCH_FILTER_ALL);
|
||||
if (ch == NULL) {
|
||||
L_FTOP: /* fiber top */
|
||||
if (mrb->c == mrb->root_c) {
|
||||
mrb->c->stack = mrb->c->stbase;
|
||||
mrb->c->ci->stack = mrb->c->stbase;
|
||||
goto L_STOP;
|
||||
}
|
||||
else {
|
||||
@@ -2004,9 +1984,6 @@ RETRY_TRY_BLOCK:
|
||||
irep = proc->body.irep;
|
||||
pool = irep->pool;
|
||||
syms = irep->syms;
|
||||
if (ci < ci0) {
|
||||
mrb->c->stack = ci[1].stackent;
|
||||
}
|
||||
mrb_stack_extend(mrb, irep->nregs);
|
||||
pc = irep->iseq + mrb_irep_catch_handler_unpack(ch->target);
|
||||
}
|
||||
@@ -2056,8 +2033,8 @@ RETRY_TRY_BLOCK:
|
||||
UNWIND_ENSURE(mrb, ci, pc, RBREAK_TAG_RETURN_BLOCK, proc, v);
|
||||
}
|
||||
CHECKPOINT_END(RBREAK_TAG_RETURN_BLOCK);
|
||||
pc = ci->pc;
|
||||
ci = cipop(mrb);
|
||||
pc = ci->pc;
|
||||
}
|
||||
proc = ci->proc;
|
||||
mrb->exc = NULL; /* clear break object */
|
||||
@@ -2169,7 +2146,6 @@ RETRY_TRY_BLOCK:
|
||||
mrb_assert(!"wrong break tag");
|
||||
}
|
||||
}
|
||||
mrb->c->stack = ci->stackent;
|
||||
while (mrb->c->cibase < ci && ci[-1].proc != proc->upper) {
|
||||
if (ci[-1].acc == CI_ACC_SKIP) {
|
||||
goto L_BREAK_ERROR;
|
||||
@@ -2181,8 +2157,8 @@ RETRY_TRY_BLOCK:
|
||||
UNWIND_ENSURE(mrb, ci, pc, RBREAK_TAG_BREAK_UPPER, proc, v);
|
||||
}
|
||||
CHECKPOINT_END(RBREAK_TAG_BREAK_UPPER);
|
||||
pc = ci->pc;
|
||||
ci = cipop(mrb);
|
||||
pc = ci->pc;
|
||||
}
|
||||
CHECKPOINT_RESTORE(RBREAK_TAG_BREAK_INTARGET) {
|
||||
/* do nothing */
|
||||
@@ -2203,7 +2179,7 @@ RETRY_TRY_BLOCK:
|
||||
mrb_assert(ci == mrb->c->ci);
|
||||
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->c->vmexec = FALSE;
|
||||
mrb->jmp = prev_jmp;
|
||||
@@ -2216,7 +2192,7 @@ RETRY_TRY_BLOCK:
|
||||
mrb->jmp = prev_jmp;
|
||||
return v;
|
||||
}
|
||||
pc = ci[1].pc;
|
||||
pc = ci[0].pc;
|
||||
DEBUG(fprintf(stderr, "from :%s\n", mrb_sym_name(mrb, ci->mid)));
|
||||
proc = mrb->c->ci->proc;
|
||||
irep = proc->body.irep;
|
||||
@@ -2750,7 +2726,7 @@ RETRY_TRY_BLOCK:
|
||||
p->flags |= MRB_PROC_SCOPE;
|
||||
|
||||
/* prepare call stack */
|
||||
cipush(mrb, pc, a, a, mrb_class_ptr(recv), p, 0, 0);
|
||||
cipush(mrb, a, a, mrb_class_ptr(recv), p, 0, 0);
|
||||
|
||||
irep = p->body.irep;
|
||||
pool = irep->pool;
|
||||
@@ -2780,7 +2756,7 @@ RETRY_TRY_BLOCK:
|
||||
|
||||
CASE(OP_TCLASS, B) {
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -2788,7 +2764,7 @@ RETRY_TRY_BLOCK:
|
||||
struct RClass *target;
|
||||
|
||||
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]);
|
||||
NEXT;
|
||||
}
|
||||
@@ -2796,7 +2772,7 @@ RETRY_TRY_BLOCK:
|
||||
struct RClass *target;
|
||||
|
||||
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]);
|
||||
NEXT;
|
||||
}
|
||||
@@ -2821,7 +2797,6 @@ RETRY_TRY_BLOCK:
|
||||
|
||||
mrb_assert((pool[a].tt&IREP_TT_NFLAG)==0);
|
||||
exc = mrb_exc_new(mrb, E_LOCALJUMP_ERROR, pool[a].u.str, len);
|
||||
ERR_PC_SET(mrb);
|
||||
mrb_exc_set(mrb, exc);
|
||||
goto L_RAISE;
|
||||
}
|
||||
@@ -2840,7 +2815,6 @@ RETRY_TRY_BLOCK:
|
||||
}
|
||||
CHECKPOINT_END(RBREAK_TAG_STOP);
|
||||
L_STOP:
|
||||
ERR_PC_CLR(mrb);
|
||||
mrb->jmp = prev_jmp;
|
||||
if (mrb->exc) {
|
||||
mrb_assert(mrb->exc->tt == MRB_TT_EXCEPTION);
|
||||
@@ -2858,7 +2832,7 @@ RETRY_TRY_BLOCK:
|
||||
ci = cipop(mrb);
|
||||
}
|
||||
exc_catched = TRUE;
|
||||
pc = pc_save;
|
||||
pc = ci->pc;
|
||||
goto RETRY_TRY_BLOCK;
|
||||
}
|
||||
MRB_END_EXC(&c_jmp);
|
||||
@@ -2884,10 +2858,10 @@ 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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
cipush(mrb, NULL, 0, CI_ACC_SKIP, mrb->object_class, NULL, 0, 0);
|
||||
cipush(mrb, 0, CI_ACC_SKIP, mrb->object_class, NULL, 0, 0);
|
||||
v = mrb_vm_run(mrb, proc, self, stack_keep);
|
||||
|
||||
return v;
|
||||
|
||||
Reference in New Issue
Block a user