mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
primary mruby fiber implementation
This commit is contained in:
+17
-12
@@ -61,16 +61,8 @@ typedef struct {
|
||||
struct REnv *env;
|
||||
} mrb_callinfo;
|
||||
|
||||
enum gc_state {
|
||||
GC_STATE_NONE = 0,
|
||||
GC_STATE_MARK,
|
||||
GC_STATE_SWEEP
|
||||
};
|
||||
|
||||
typedef struct mrb_state {
|
||||
void *jmp;
|
||||
|
||||
mrb_allocf allocf;
|
||||
struct mrb_context {
|
||||
struct mrb_context *prev;
|
||||
|
||||
mrb_value *stack;
|
||||
mrb_value *stbase, *stend;
|
||||
@@ -82,10 +74,24 @@ typedef struct mrb_state {
|
||||
int rsize;
|
||||
struct RProc **ensure;
|
||||
int esize;
|
||||
};
|
||||
|
||||
enum gc_state {
|
||||
GC_STATE_NONE = 0,
|
||||
GC_STATE_MARK,
|
||||
GC_STATE_SWEEP
|
||||
};
|
||||
|
||||
typedef struct mrb_state {
|
||||
void *jmp;
|
||||
|
||||
mrb_allocf allocf;
|
||||
|
||||
struct mrb_context *c;
|
||||
struct mrb_context *root_c;
|
||||
|
||||
struct RObject *exc;
|
||||
struct iv_tbl *globals;
|
||||
|
||||
struct mrb_irep **irep;
|
||||
size_t irep_len, irep_capa;
|
||||
|
||||
@@ -140,7 +146,6 @@ typedef struct mrb_state {
|
||||
struct RClass *eStandardError_class;
|
||||
|
||||
void *ud; /* auxiliary data */
|
||||
|
||||
} mrb_state;
|
||||
|
||||
typedef mrb_value (*mrb_func_t)(mrb_state *mrb, mrb_value);
|
||||
|
||||
@@ -12,5 +12,6 @@
|
||||
|
||||
typedef void (each_object_callback)(mrb_state *mrb, struct RBasic* obj, void *data);
|
||||
void mrb_objspace_each_objects(mrb_state *mrb, each_object_callback* callback, void *data);
|
||||
void mrb_free_context(mrb_state *mrb, struct mrb_context *c);
|
||||
|
||||
#endif /* MRUBY_GC_H */
|
||||
|
||||
@@ -34,7 +34,8 @@ enum mrb_vtype {
|
||||
MRB_TT_FILE, /* 19 */
|
||||
MRB_TT_ENV, /* 20 */
|
||||
MRB_TT_DATA, /* 21 */
|
||||
MRB_TT_MAXDEFINE /* 22 */
|
||||
MRB_TT_FIBER, /* 22 */
|
||||
MRB_TT_MAXDEFINE /* 23 */
|
||||
};
|
||||
|
||||
typedef struct mrb_value {
|
||||
@@ -92,7 +93,8 @@ enum mrb_vtype {
|
||||
MRB_TT_FILE, /* 20 */
|
||||
MRB_TT_ENV, /* 21 */
|
||||
MRB_TT_DATA, /* 22 */
|
||||
MRB_TT_MAXDEFINE /* 23 */
|
||||
MRB_TT_FIBER, /* 23 */
|
||||
MRB_TT_MAXDEFINE /* 24 */
|
||||
};
|
||||
|
||||
#ifdef MRB_ENDIAN_BIG
|
||||
@@ -202,6 +204,11 @@ struct RObject {
|
||||
#define mrb_immediate_p(x) (mrb_type(x) <= MRB_TT_VOIDP)
|
||||
#define mrb_special_const_p(x) mrb_immediate_p(x)
|
||||
|
||||
struct RFiber {
|
||||
MRB_OBJECT_HEADER;
|
||||
struct mrb_context *cxt;
|
||||
};
|
||||
|
||||
static inline mrb_value
|
||||
mrb_fixnum_value(mrb_int i)
|
||||
{
|
||||
|
||||
@@ -44,6 +44,9 @@ MRuby::GemBox.new do |conf|
|
||||
# Use ObjectSpace class
|
||||
conf.gem :core => "mruby-objectspace"
|
||||
|
||||
# Use Fiber class
|
||||
conf.gem :core => "mruby-fiber"
|
||||
|
||||
# Generate mirb command
|
||||
conf.gem :core => "mruby-bin-mirb"
|
||||
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
MRuby::Gem::Specification.new('mruby-fiber') do |spec|
|
||||
spec.license = 'MIT'
|
||||
spec.authors = 'mruby developers'
|
||||
end
|
||||
@@ -0,0 +1,179 @@
|
||||
#include "mruby.h"
|
||||
#include "mruby/array.h"
|
||||
#include "mruby/class.h"
|
||||
#include "mruby/proc.h"
|
||||
|
||||
#define FIBER_STACK_INIT_SIZE 64
|
||||
#define FIBER_CI_INIT_SIZE 8
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* Fiber.new{...} -> obj
|
||||
*
|
||||
* Creates an fiber, whose execution is suspend until it explicitly
|
||||
* resumed using <code>Fibder#resume</code> method.
|
||||
* <code>resume</code>. Arguments passed to resume will be the value of
|
||||
* the <code>Fiber.yield</code> expression or will be passed as block
|
||||
* parameters to the fiber's block if this is the first <code>resume</code>.
|
||||
*
|
||||
* Alternatively, when resume is called it evaluates to the arguments passed
|
||||
* to the next <code>Fiber.yield</code> statement inside the fiber's block
|
||||
* or to the block value if it runs to completion without any
|
||||
* <code>Fiber.yield</code>
|
||||
*/
|
||||
static mrb_value
|
||||
fiber_init(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
static const struct mrb_context mrb_context_zero = { 0 };
|
||||
struct RFiber *f = (struct RFiber*)self.value.p;
|
||||
struct mrb_context *c;
|
||||
struct RProc *p;
|
||||
mrb_callinfo *ci;
|
||||
mrb_value blk;
|
||||
|
||||
mrb_get_args(mrb, "&", &blk);
|
||||
|
||||
if (mrb_nil_p(blk)) {
|
||||
mrb_raise(mrb, E_ARGUMENT_ERROR, "tried to create Fiber object without a block");
|
||||
}
|
||||
p = mrb_proc_ptr(blk);
|
||||
if (MRB_PROC_CFUNC_P(p)) {
|
||||
mrb_raise(mrb, E_ARGUMENT_ERROR, "tried to create Fiber from C defined method");
|
||||
}
|
||||
|
||||
f->cxt = (struct mrb_context*)mrb_malloc(mrb, sizeof(struct mrb_context));
|
||||
*f->cxt = mrb_context_zero;
|
||||
|
||||
/* initialize VM stack */
|
||||
c = f->cxt;
|
||||
c->stbase = (mrb_value *)mrb_calloc(mrb, FIBER_STACK_INIT_SIZE, sizeof(mrb_value));
|
||||
c->stend = c->stbase + FIBER_STACK_INIT_SIZE;
|
||||
c->stack = c->stbase;
|
||||
|
||||
/* copy receiver from a block */
|
||||
c->stack[0] = mrb->c->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;
|
||||
|
||||
/* adjust return callinfo */
|
||||
ci = c->ci;
|
||||
ci->target_class = p->target_class;
|
||||
ci->proc = p;
|
||||
ci->pc = p->body.irep->iseq;
|
||||
ci->nregs = p->body.irep->nregs;
|
||||
ci[1] = ci[0];
|
||||
c->ci++; /* push dummy callinfo */
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
static struct mrb_context*
|
||||
fiber_check(mrb_state *mrb, mrb_value fib)
|
||||
{
|
||||
struct RFiber *f = (struct RFiber*)fib.value.p;
|
||||
|
||||
if (!f->cxt) {
|
||||
mrb_raise(mrb, E_ARGUMENT_ERROR, "uninitialized Fiber");
|
||||
}
|
||||
return f->cxt;
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
fiber_result(mrb_state *mrb, mrb_value *a, int len)
|
||||
{
|
||||
if (len == 0) return mrb_nil_value();
|
||||
if (len == 1) return a[0];
|
||||
return mrb_ary_new_from_values(mrb, len, a);
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* fiber.resume(args, ...) -> obj
|
||||
*
|
||||
* Resumes the fiber from the point at which the last <code>Fiber.yield</code>
|
||||
* was called, or starts running it if it is the first call to
|
||||
* <code>resume</code>. Arguments passed to resume will be the value of
|
||||
* the <code>Fiber.yield</code> expression or will be passed as block
|
||||
* parameters to the fiber's block if this is the first <code>resume</code>.
|
||||
*
|
||||
* Alternatively, when resume is called it evaluates to the arguments passed
|
||||
* to the next <code>Fiber.yield</code> statement inside the fiber's block
|
||||
* or to the block value if it runs to completion without any
|
||||
* <code>Fiber.yield</code>
|
||||
*/
|
||||
static mrb_value
|
||||
fiber_resume(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
struct mrb_context *c = fiber_check(mrb, self);
|
||||
mrb_value *a;
|
||||
int len;
|
||||
|
||||
mrb_get_args(mrb, "*", &a, &len);
|
||||
if (!c->prev) { /* first call */
|
||||
mrb_value *b = c->stack+1;
|
||||
mrb_value *e = b + len;
|
||||
|
||||
while (b<e) {
|
||||
*b++ = *a++;
|
||||
}
|
||||
c->ci->argc = len;
|
||||
c->prev = mrb->c;
|
||||
mrb->c = c;
|
||||
|
||||
return c->ci->proc->env->stack[0];
|
||||
}
|
||||
if (c->ci == c->cibase) {
|
||||
mrb_raise(mrb, E_RUNTIME_ERROR, "resuming dead Fiber");
|
||||
}
|
||||
c->prev = mrb->c;
|
||||
mrb->c = c;
|
||||
return fiber_result(mrb, a, len);
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* Fiber.yield(args, ...) -> obj
|
||||
*
|
||||
* Yields control back to the context that resumed the fiber, passing
|
||||
* along any arguments that were passed to it. The fiber will resume
|
||||
* processing at this point when <code>resume</code> is called next.
|
||||
* Any arguments passed to the next <code>resume</code> will be the
|
||||
* value that this <code>Fiber.yield</code> expression evaluates to.
|
||||
*/
|
||||
static mrb_value
|
||||
fiber_yield(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
struct mrb_context *c = mrb->c;
|
||||
mrb_value *a;
|
||||
int len;
|
||||
|
||||
if (!c->prev) {
|
||||
mrb_raise(mrb, E_ARGUMENT_ERROR, "can't yield from root Fiber");
|
||||
}
|
||||
mrb_get_args(mrb, "*", &a, &len);
|
||||
|
||||
mrb->c = c->prev;
|
||||
return fiber_result(mrb, a, len);
|
||||
}
|
||||
|
||||
void
|
||||
mrb_mruby_fiber_gem_init(mrb_state* mrb)
|
||||
{
|
||||
struct RClass *c;
|
||||
|
||||
c = mrb_define_class(mrb, "Fiber", mrb->object_class);
|
||||
MRB_SET_INSTANCE_TT(c, MRB_TT_FIBER);
|
||||
|
||||
mrb_define_method(mrb, c, "initialize", fiber_init, MRB_ARGS_NONE());
|
||||
mrb_define_method(mrb, c, "resume", fiber_resume, MRB_ARGS_ANY());
|
||||
|
||||
mrb_define_class_method(mrb, c, "yield", fiber_yield, MRB_ARGS_ANY());
|
||||
}
|
||||
|
||||
void
|
||||
mrb_mruby_fiber_gem_final(mrb_state* mrb)
|
||||
{
|
||||
}
|
||||
@@ -132,7 +132,7 @@ mrb_struct_getmember(mrb_state *mrb, mrb_value obj, mrb_sym id)
|
||||
static mrb_value
|
||||
mrb_struct_ref(mrb_state *mrb, mrb_value obj)
|
||||
{
|
||||
return mrb_struct_getmember(mrb, obj, mrb->ci->mid);
|
||||
return mrb_struct_getmember(mrb, obj, mrb->c->ci->mid);
|
||||
}
|
||||
|
||||
static mrb_value mrb_struct_ref0(mrb_state* mrb, mrb_value obj) {return RSTRUCT_PTR(obj)[0];}
|
||||
@@ -191,7 +191,7 @@ mrb_struct_set(mrb_state *mrb, mrb_value obj, mrb_value val)
|
||||
mrb_value members, slot, *ptr, *ptr_members;
|
||||
|
||||
/* get base id */
|
||||
name = mrb_sym2name_len(mrb, mrb->ci->mid, &len);
|
||||
name = mrb_sym2name_len(mrb, mrb->c->ci->mid, &len);
|
||||
mid = mrb_intern2(mrb, name, len-1); /* omit last "=" */
|
||||
|
||||
members = mrb_struct_members(mrb, obj);
|
||||
|
||||
+3
-3
@@ -19,11 +19,11 @@ mrb_print_backtrace(mrb_state *mrb)
|
||||
|
||||
printf("trace:\n");
|
||||
ciidx = mrb_fixnum(mrb_obj_iv_get(mrb, mrb->exc, mrb_intern(mrb, "ciidx")));
|
||||
if (ciidx >= mrb->ciend - mrb->cibase)
|
||||
if (ciidx >= mrb->c->ciend - mrb->c->cibase)
|
||||
ciidx = 10; /* ciidx is broken... */
|
||||
|
||||
for (i = ciidx; i >= 0; i--) {
|
||||
ci = &mrb->cibase[i];
|
||||
ci = &mrb->c->cibase[i];
|
||||
filename = "(unknown)";
|
||||
line = -1;
|
||||
|
||||
@@ -38,7 +38,7 @@ mrb_print_backtrace(mrb_state *mrb)
|
||||
mrb_code *pc;
|
||||
|
||||
if (i+1 <= ciidx) {
|
||||
pc = mrb->cibase[i+1].pc;
|
||||
pc = mrb->c->cibase[i+1].pc;
|
||||
}
|
||||
else {
|
||||
pc = (mrb_code*)mrb_voidp(mrb_obj_iv_get(mrb, mrb->exc, mrb_intern(mrb, "lastpc")));
|
||||
|
||||
+6
-6
@@ -391,14 +391,14 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
|
||||
{
|
||||
char c;
|
||||
int i = 0;
|
||||
mrb_value *sp = mrb->stack + 1;
|
||||
mrb_value *sp = mrb->c->stack + 1;
|
||||
va_list ap;
|
||||
int argc = mrb->ci->argc;
|
||||
int argc = mrb->c->ci->argc;
|
||||
int opt = 0;
|
||||
|
||||
va_start(ap, format);
|
||||
if (argc < 0) {
|
||||
struct RArray *a = mrb_ary_ptr(mrb->stack[1]);
|
||||
struct RArray *a = mrb_ary_ptr(mrb->c->stack[1]);
|
||||
|
||||
argc = a->len;
|
||||
sp = a->ptr;
|
||||
@@ -620,11 +620,11 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
|
||||
mrb_value *p, *bp;
|
||||
|
||||
p = va_arg(ap, mrb_value*);
|
||||
if (mrb->ci->argc < 0) {
|
||||
bp = mrb->stack + 2;
|
||||
if (mrb->c->ci->argc < 0) {
|
||||
bp = mrb->c->stack + 2;
|
||||
}
|
||||
else {
|
||||
bp = mrb->stack + mrb->ci->argc + 1;
|
||||
bp = mrb->c->stack + mrb->c->ci->argc + 1;
|
||||
}
|
||||
*p = *bp;
|
||||
}
|
||||
|
||||
+3
-3
@@ -189,12 +189,12 @@ exc_equal(mrb_state *mrb, mrb_value exc)
|
||||
static void
|
||||
exc_debug_info(mrb_state *mrb, struct RObject *exc)
|
||||
{
|
||||
mrb_callinfo *ci = mrb->ci;
|
||||
mrb_callinfo *ci = mrb->c->ci;
|
||||
mrb_code *pc = ci->pc;
|
||||
|
||||
mrb_obj_iv_set(mrb, exc, mrb_intern2(mrb, "ciidx", 5), mrb_fixnum_value(ci - mrb->cibase));
|
||||
mrb_obj_iv_set(mrb, exc, mrb_intern2(mrb, "ciidx", 5), mrb_fixnum_value(ci - mrb->c->cibase));
|
||||
ci--;
|
||||
while (ci >= mrb->cibase) {
|
||||
while (ci >= mrb->c->cibase) {
|
||||
if (ci->proc && !MRB_PROC_CFUNC_P(ci->proc)) {
|
||||
mrb_irep *irep = ci->proc->body.irep;
|
||||
|
||||
|
||||
@@ -386,6 +386,35 @@ add_gray_list(mrb_state *mrb, struct RBasic *obj)
|
||||
mrb->gray_list = obj;
|
||||
}
|
||||
|
||||
static void
|
||||
mark_context(mrb_state *mrb, struct mrb_context *c)
|
||||
{
|
||||
size_t i;
|
||||
size_t e;
|
||||
mrb_callinfo *ci;
|
||||
|
||||
/* mark stack */
|
||||
e = c->stack - c->stbase;
|
||||
if (c->ci) e += c->ci->nregs;
|
||||
if (c->stbase + e > c->stend) e = c->stend - c->stbase;
|
||||
for (i=0; i<e; i++) {
|
||||
mrb_gc_mark_value(mrb, c->stbase[i]);
|
||||
}
|
||||
/* mark ensure stack */
|
||||
e = (c->ci) ? c->ci->eidx : 0;
|
||||
for (i=0; i<e; i++) {
|
||||
mrb_gc_mark(mrb, (struct RBasic*)c->ensure[i]);
|
||||
}
|
||||
/* mark closure */
|
||||
for (ci = c->cibase; ci <= c->ci; ci++) {
|
||||
if (!ci) continue;
|
||||
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);
|
||||
}
|
||||
if (c->prev) mark_context(mrb, c->prev);
|
||||
}
|
||||
|
||||
static void
|
||||
gc_mark_children(mrb_state *mrb, struct RBasic *obj)
|
||||
{
|
||||
@@ -438,6 +467,15 @@ gc_mark_children(mrb_state *mrb, struct RBasic *obj)
|
||||
}
|
||||
break;
|
||||
|
||||
case MRB_TT_FIBER:
|
||||
{
|
||||
struct mrb_context *c = ((struct RFiber*)obj)->cxt;
|
||||
|
||||
mark_context(mrb, c);
|
||||
((struct RFiber*)obj)->cxt = NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
case MRB_TT_ARRAY:
|
||||
{
|
||||
struct RArray *a = (struct RArray*)obj;
|
||||
@@ -517,6 +555,14 @@ obj_free(mrb_state *mrb, struct RBasic *obj)
|
||||
}
|
||||
break;
|
||||
|
||||
case MRB_TT_FIBER:
|
||||
{
|
||||
struct mrb_context *c = ((struct RFiber*)obj)->cxt;
|
||||
|
||||
mrb_free_context(mrb, c);
|
||||
}
|
||||
break;
|
||||
|
||||
case MRB_TT_ARRAY:
|
||||
if (obj->flags & MRB_ARY_SHARED)
|
||||
mrb_ary_decref(mrb, ((struct RArray*)obj)->aux.shared);
|
||||
@@ -557,9 +603,7 @@ static void
|
||||
root_scan_phase(mrb_state *mrb)
|
||||
{
|
||||
int j;
|
||||
size_t i;
|
||||
size_t e;
|
||||
mrb_callinfo *ci;
|
||||
size_t i, e;
|
||||
|
||||
if (!is_minor_gc(mrb)) {
|
||||
mrb->gray_list = 0;
|
||||
@@ -577,25 +621,8 @@ root_scan_phase(mrb_state *mrb)
|
||||
mrb_gc_mark(mrb, (struct RBasic*)mrb->top_self);
|
||||
/* mark exception */
|
||||
mrb_gc_mark(mrb, (struct RBasic*)mrb->exc);
|
||||
/* mark stack */
|
||||
e = mrb->stack - mrb->stbase;
|
||||
if (mrb->ci) e += mrb->ci->nregs;
|
||||
if (mrb->stbase + e > mrb->stend) e = mrb->stend - mrb->stbase;
|
||||
for (i=0; i<e; i++) {
|
||||
mrb_gc_mark_value(mrb, mrb->stbase[i]);
|
||||
}
|
||||
/* mark ensure stack */
|
||||
e = (mrb->ci) ? mrb->ci->eidx : 0;
|
||||
for (i=0; i<e; i++) {
|
||||
mrb_gc_mark(mrb, (struct RBasic*)mrb->ensure[i]);
|
||||
}
|
||||
/* mark closure */
|
||||
for (ci = mrb->cibase; ci <= mrb->ci; ci++) {
|
||||
if (!ci) continue;
|
||||
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);
|
||||
}
|
||||
|
||||
mark_context(mrb, mrb->c);
|
||||
/* mark irep pool */
|
||||
if (mrb->irep) {
|
||||
size_t len = mrb->irep_len;
|
||||
@@ -643,6 +670,30 @@ gc_gray_mark(mrb_state *mrb, struct RBasic *obj)
|
||||
children += (int)obj->flags;
|
||||
break;
|
||||
|
||||
case MRB_TT_FIBER:
|
||||
{
|
||||
struct mrb_context *c = ((struct RFiber*)obj)->cxt;
|
||||
size_t i;
|
||||
mrb_callinfo *ci;
|
||||
|
||||
/* mark stack */
|
||||
i = c->stack - c->stbase;
|
||||
if (c->ci) i += c->ci->nregs;
|
||||
if (c->stbase + i > c->stend) i = c->stend - c->stbase;
|
||||
children += i;
|
||||
|
||||
/* mark ensure stack */
|
||||
children += (c->ci) ? c->ci->eidx : 0;
|
||||
|
||||
/* mark closure */
|
||||
if (c->cibase) {
|
||||
for (i=0, ci = c->cibase; ci <= c->ci; i++, ci++)
|
||||
;
|
||||
}
|
||||
children += i;
|
||||
}
|
||||
break;
|
||||
|
||||
case MRB_TT_ARRAY:
|
||||
{
|
||||
struct RArray *a = (struct RArray*)obj;
|
||||
|
||||
+5
-5
@@ -214,19 +214,19 @@ mrb_f_send(mrb_state *mrb, mrb_value self)
|
||||
static mrb_value
|
||||
mrb_f_block_given_p_m(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_callinfo *ci = mrb->ci;
|
||||
mrb_callinfo *ci = mrb->c->ci;
|
||||
mrb_value *bp;
|
||||
mrb_bool given_p;
|
||||
|
||||
bp = mrb->stbase + ci->stackidx + 1;
|
||||
bp = mrb->c->stbase + ci->stackidx + 1;
|
||||
ci--;
|
||||
if (ci <= mrb->cibase) {
|
||||
if (ci <= mrb->c->cibase) {
|
||||
given_p = 0;
|
||||
}
|
||||
else {
|
||||
/* block_given? called within block; check upper scope */
|
||||
if (ci->proc->env && ci->proc->env->stack) {
|
||||
given_p = !(ci->proc->env->stack == mrb->stbase ||
|
||||
given_p = !(ci->proc->env->stack == mrb->c->stbase ||
|
||||
mrb_nil_p(ci->proc->env->stack[1]));
|
||||
}
|
||||
else {
|
||||
@@ -894,7 +894,7 @@ mrb_f_raise(mrb_state *mrb, mrb_value self)
|
||||
/* fall through */
|
||||
default:
|
||||
exc = mrb_make_exception(mrb, argc, a);
|
||||
mrb_obj_iv_set(mrb, mrb_obj_ptr(exc), mrb_intern2(mrb, "lastpc", 6), mrb_voidp_value(mrb->ci->pc));
|
||||
mrb_obj_iv_set(mrb, mrb_obj_ptr(exc), mrb_intern2(mrb, "lastpc", 6), mrb_voidp_value(mrb->c->ci->pc));
|
||||
mrb_exc_raise(mrb, exc);
|
||||
break;
|
||||
}
|
||||
|
||||
+9
-9
@@ -19,7 +19,7 @@ mrb_proc_new(mrb_state *mrb, mrb_irep *irep)
|
||||
struct RProc *p;
|
||||
|
||||
p = (struct RProc*)mrb_obj_alloc(mrb, MRB_TT_PROC, mrb->proc_class);
|
||||
p->target_class = (mrb->ci) ? mrb->ci->target_class : 0;
|
||||
p->target_class = (mrb->c->ci) ? mrb->c->ci->target_class : 0;
|
||||
p->body.irep = irep;
|
||||
p->env = 0;
|
||||
|
||||
@@ -31,16 +31,16 @@ closure_setup(mrb_state *mrb, struct RProc *p, int nlocals)
|
||||
{
|
||||
struct REnv *e;
|
||||
|
||||
if (!mrb->ci->env) {
|
||||
e = (struct REnv*)mrb_obj_alloc(mrb, MRB_TT_ENV, (struct RClass*)mrb->ci->proc->env);
|
||||
if (!mrb->c->ci->env) {
|
||||
e = (struct REnv*)mrb_obj_alloc(mrb, MRB_TT_ENV, (struct RClass*)mrb->c->ci->proc->env);
|
||||
e->flags= (unsigned int)nlocals;
|
||||
e->mid = mrb->ci->mid;
|
||||
e->cioff = mrb->ci - mrb->cibase;
|
||||
e->stack = mrb->stack;
|
||||
mrb->ci->env = e;
|
||||
e->mid = mrb->c->ci->mid;
|
||||
e->cioff = mrb->c->ci - mrb->c->cibase;
|
||||
e->stack = mrb->c->stack;
|
||||
mrb->c->ci->env = e;
|
||||
}
|
||||
else {
|
||||
e = mrb->ci->env;
|
||||
e = mrb->c->ci->env;
|
||||
}
|
||||
p->env = e;
|
||||
}
|
||||
@@ -50,7 +50,7 @@ mrb_closure_new(mrb_state *mrb, mrb_irep *irep)
|
||||
{
|
||||
struct RProc *p = mrb_proc_new(mrb, irep);
|
||||
|
||||
closure_setup(mrb, p, mrb->ci->proc->body.irep->nlocals);
|
||||
closure_setup(mrb, p, mrb->c->ci->proc->body.irep->nlocals);
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
+17
-4
@@ -25,6 +25,7 @@ mrb_state*
|
||||
mrb_open_allocf(mrb_allocf f, void *ud)
|
||||
{
|
||||
static const mrb_state mrb_state_zero = { 0 };
|
||||
static const struct mrb_context mrb_context_zero = { 0 };
|
||||
mrb_state *mrb = (mrb_state *)(f)(NULL, NULL, sizeof(mrb_state), ud);
|
||||
if (mrb == NULL) return NULL;
|
||||
|
||||
@@ -34,7 +35,11 @@ mrb_open_allocf(mrb_allocf f, void *ud)
|
||||
mrb->current_white_part = MRB_GC_WHITE_A;
|
||||
|
||||
mrb_init_heap(mrb);
|
||||
mrb->c = (struct mrb_context*)mrb_malloc(mrb, sizeof(struct mrb_context));
|
||||
*mrb->c = mrb_context_zero;
|
||||
mrb->root_c = mrb->c;
|
||||
mrb_init_core(mrb);
|
||||
|
||||
return mrb;
|
||||
}
|
||||
|
||||
@@ -106,6 +111,17 @@ mrb_irep_free(mrb_state *mrb, struct mrb_irep *irep)
|
||||
mrb_free(mrb, irep);
|
||||
}
|
||||
|
||||
void
|
||||
mrb_free_context(mrb_state *mrb, struct mrb_context *c)
|
||||
{
|
||||
if (!c) return;
|
||||
mrb_free(mrb, c->stbase);
|
||||
mrb_free(mrb, c->cibase);
|
||||
mrb_free(mrb, c->rescue);
|
||||
mrb_free(mrb, c->ensure);
|
||||
mrb_free(mrb, c);
|
||||
}
|
||||
|
||||
void
|
||||
mrb_close(mrb_state *mrb)
|
||||
{
|
||||
@@ -115,14 +131,11 @@ mrb_close(mrb_state *mrb)
|
||||
|
||||
/* free */
|
||||
mrb_gc_free_gv(mrb);
|
||||
mrb_free(mrb, mrb->stbase);
|
||||
mrb_free(mrb, mrb->cibase);
|
||||
for (i=0; i<mrb->irep_len; i++) {
|
||||
mrb_irep_free(mrb, mrb->irep[i]);
|
||||
}
|
||||
mrb_free(mrb, mrb->irep);
|
||||
mrb_free(mrb, mrb->rescue);
|
||||
mrb_free(mrb, mrb->ensure);
|
||||
mrb_free_context(mrb, mrb->root_c);
|
||||
mrb_free_symtbl(mrb);
|
||||
mrb_free_heap(mrb);
|
||||
mrb_alloca_free(mrb);
|
||||
|
||||
+11
-11
@@ -579,14 +579,14 @@ mrb_value
|
||||
mrb_vm_iv_get(mrb_state *mrb, mrb_sym sym)
|
||||
{
|
||||
/* get self */
|
||||
return mrb_iv_get(mrb, mrb->stack[0], sym);
|
||||
return mrb_iv_get(mrb, mrb->c->stack[0], sym);
|
||||
}
|
||||
|
||||
void
|
||||
mrb_vm_iv_set(mrb_state *mrb, mrb_sym sym, mrb_value v)
|
||||
{
|
||||
/* get self */
|
||||
mrb_iv_set(mrb, mrb->stack[0], sym, v);
|
||||
mrb_iv_set(mrb, mrb->c->stack[0], sym, v);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -763,9 +763,9 @@ mrb_cv_defined(mrb_state *mrb, mrb_value mod, mrb_sym sym)
|
||||
mrb_value
|
||||
mrb_vm_cv_get(mrb_state *mrb, mrb_sym sym)
|
||||
{
|
||||
struct RClass *c = mrb->ci->proc->target_class;
|
||||
struct RClass *c = mrb->c->ci->proc->target_class;
|
||||
|
||||
if (!c) c = mrb->ci->target_class;
|
||||
if (!c) c = mrb->c->ci->target_class;
|
||||
|
||||
return mrb_mod_cv_get(mrb, c, sym);
|
||||
}
|
||||
@@ -773,9 +773,9 @@ mrb_vm_cv_get(mrb_state *mrb, mrb_sym sym)
|
||||
void
|
||||
mrb_vm_cv_set(mrb_state *mrb, mrb_sym sym, mrb_value v)
|
||||
{
|
||||
struct RClass *c = mrb->ci->proc->target_class;
|
||||
struct RClass *c = mrb->c->ci->proc->target_class;
|
||||
|
||||
if (!c) c = mrb->ci->target_class;
|
||||
if (!c) c = mrb->c->ci->target_class;
|
||||
while (c) {
|
||||
if (c->iv) {
|
||||
iv_tbl *t = c->iv;
|
||||
@@ -788,7 +788,7 @@ mrb_vm_cv_set(mrb_state *mrb, mrb_sym sym, mrb_value v)
|
||||
}
|
||||
c = c->super;
|
||||
}
|
||||
c = mrb->ci->target_class;
|
||||
c = mrb->c->ci->target_class;
|
||||
if (!c->iv) {
|
||||
c->iv = iv_new(mrb);
|
||||
}
|
||||
@@ -868,9 +868,9 @@ mrb_const_get(mrb_state *mrb, mrb_value mod, mrb_sym sym)
|
||||
mrb_value
|
||||
mrb_vm_const_get(mrb_state *mrb, mrb_sym sym)
|
||||
{
|
||||
struct RClass *c = mrb->ci->proc->target_class;
|
||||
struct RClass *c = mrb->c->ci->proc->target_class;
|
||||
|
||||
if (!c) c = mrb->ci->target_class;
|
||||
if (!c) c = mrb->c->ci->target_class;
|
||||
if (c) {
|
||||
struct RClass *c2;
|
||||
mrb_value v;
|
||||
@@ -900,9 +900,9 @@ mrb_const_set(mrb_state *mrb, mrb_value mod, mrb_sym sym, mrb_value v)
|
||||
void
|
||||
mrb_vm_const_set(mrb_state *mrb, mrb_sym sym, mrb_value v)
|
||||
{
|
||||
struct RClass *c = mrb->ci->proc->target_class;
|
||||
struct RClass *c = mrb->c->ci->proc->target_class;
|
||||
|
||||
if (!c) c = mrb->ci->target_class;
|
||||
if (!c) c = mrb->c->ci->target_class;
|
||||
mrb_obj_iv_set(mrb, (struct RObject*)c, sym, v);
|
||||
}
|
||||
|
||||
|
||||
@@ -88,24 +88,26 @@ stack_copy(mrb_value *dst, const mrb_value *src, size_t size)
|
||||
static void
|
||||
stack_init(mrb_state *mrb)
|
||||
{
|
||||
/* assert(mrb->stack == NULL); */
|
||||
mrb->stbase = (mrb_value *)mrb_calloc(mrb, STACK_INIT_SIZE, sizeof(mrb_value));
|
||||
mrb->stend = mrb->stbase + STACK_INIT_SIZE;
|
||||
mrb->stack = mrb->stbase;
|
||||
struct mrb_context *c = mrb->c;
|
||||
|
||||
/* assert(mrb->ci == NULL); */
|
||||
mrb->cibase = (mrb_callinfo *)mrb_calloc(mrb, CALLINFO_INIT_SIZE, sizeof(mrb_callinfo));
|
||||
mrb->ciend = mrb->cibase + CALLINFO_INIT_SIZE;
|
||||
mrb->ci = mrb->cibase;
|
||||
mrb->ci->target_class = mrb->object_class;
|
||||
/* 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;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
static inline void
|
||||
envadjust(mrb_state *mrb, mrb_value *oldbase, mrb_value *newbase)
|
||||
{
|
||||
mrb_callinfo *ci = mrb->cibase;
|
||||
mrb_callinfo *ci = mrb->c->cibase;
|
||||
|
||||
while (ci <= mrb->ci) {
|
||||
while (ci <= mrb->c->ci) {
|
||||
struct REnv *e = ci->env;
|
||||
if (e && e->cioff >= 0) {
|
||||
ptrdiff_t off = e->stack - oldbase;
|
||||
@@ -121,13 +123,13 @@ envadjust(mrb_state *mrb, mrb_value *oldbase, mrb_value *newbase)
|
||||
static void
|
||||
stack_extend(mrb_state *mrb, int room, int keep)
|
||||
{
|
||||
if (mrb->stack + room >= mrb->stend) {
|
||||
if (mrb->c->stack + room >= mrb->c->stend) {
|
||||
int size, off;
|
||||
|
||||
mrb_value *oldbase = mrb->stbase;
|
||||
mrb_value *oldbase = mrb->c->stbase;
|
||||
|
||||
size = mrb->stend - mrb->stbase;
|
||||
off = mrb->stack - mrb->stbase;
|
||||
size = mrb->c->stend - mrb->c->stbase;
|
||||
off = mrb->c->stack - mrb->c->stbase;
|
||||
|
||||
/* do not leave uninitialized malloc region */
|
||||
if (keep > size) keep = size;
|
||||
@@ -140,10 +142,10 @@ stack_extend(mrb_state *mrb, int room, int keep)
|
||||
else
|
||||
size += room;
|
||||
|
||||
mrb->stbase = (mrb_value *)mrb_realloc(mrb, mrb->stbase, sizeof(mrb_value) * size);
|
||||
mrb->stack = mrb->stbase + off;
|
||||
mrb->stend = mrb->stbase + size;
|
||||
envadjust(mrb, oldbase, mrb->stbase);
|
||||
mrb->c->stbase = (mrb_value *)mrb_realloc(mrb, mrb->c->stbase, sizeof(mrb_value) * size);
|
||||
mrb->c->stack = mrb->c->stbase + off;
|
||||
mrb->c->stend = mrb->c->stbase + size;
|
||||
envadjust(mrb, oldbase, mrb->c->stbase);
|
||||
/* Raise an exception if the new stack size will be too large,
|
||||
to prevent infinite recursion. However, do this only after resizing the stack, so mrb_raise has stack space to work with. */
|
||||
if (size > MRB_STACK_MAX) {
|
||||
@@ -153,7 +155,7 @@ stack_extend(mrb_state *mrb, int room, int keep)
|
||||
|
||||
if (room > keep) {
|
||||
#ifndef MRB_NAN_BOXING
|
||||
stack_clear(&(mrb->stack[keep]), room - keep);
|
||||
stack_clear(&(mrb->c->stack[keep]), room - keep);
|
||||
#else
|
||||
int i;
|
||||
for (i=keep; i<room; i++) {
|
||||
@@ -166,7 +168,7 @@ stack_extend(mrb_state *mrb, int room, int keep)
|
||||
static inline struct REnv*
|
||||
uvenv(mrb_state *mrb, int up)
|
||||
{
|
||||
struct REnv *e = mrb->ci->proc->env;
|
||||
struct REnv *e = mrb->c->ci->proc->env;
|
||||
|
||||
while (up--) {
|
||||
if (!e) return 0;
|
||||
@@ -180,8 +182,8 @@ is_strict(mrb_state *mrb, struct REnv *e)
|
||||
{
|
||||
int cioff = e->cioff;
|
||||
|
||||
if (cioff >= 0 && mrb->cibase[cioff].proc &&
|
||||
MRB_PROC_STRICT_P(mrb->cibase[cioff].proc)) {
|
||||
if (cioff >= 0 && mrb->c->cibase[cioff].proc &&
|
||||
MRB_PROC_STRICT_P(mrb->c->cibase[cioff].proc)) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
@@ -203,29 +205,34 @@ top_env(mrb_state *mrb, struct RProc *proc)
|
||||
static mrb_callinfo*
|
||||
cipush(mrb_state *mrb)
|
||||
{
|
||||
int eidx = mrb->ci->eidx;
|
||||
int ridx = mrb->ci->ridx;
|
||||
struct mrb_context *c = mrb->c;
|
||||
mrb_callinfo *ci = c->ci;
|
||||
|
||||
if (mrb->ci + 1 == mrb->ciend) {
|
||||
size_t size = mrb->ci - mrb->cibase;
|
||||
int eidx = ci->eidx;
|
||||
int ridx = ci->ridx;
|
||||
|
||||
mrb->cibase = (mrb_callinfo *)mrb_realloc(mrb, mrb->cibase, sizeof(mrb_callinfo)*size*2);
|
||||
mrb->ci = mrb->cibase + size;
|
||||
mrb->ciend = mrb->cibase + size * 2;
|
||||
if (ci + 1 == c->ciend) {
|
||||
size_t size = ci - c->cibase;
|
||||
|
||||
c->cibase = (mrb_callinfo *)mrb_realloc(mrb, c->cibase, sizeof(mrb_callinfo)*size*2);
|
||||
ci = c->cibase + size;
|
||||
c->ciend = c->cibase + size * 2;
|
||||
}
|
||||
mrb->ci++;
|
||||
mrb->ci->nregs = 2; /* protect method_missing arg and block */
|
||||
mrb->ci->eidx = eidx;
|
||||
mrb->ci->ridx = ridx;
|
||||
mrb->ci->env = 0;
|
||||
return mrb->ci;
|
||||
ci = ++c->ci;
|
||||
ci->nregs = 2; /* protect method_missing arg and block */
|
||||
ci->eidx = eidx;
|
||||
ci->ridx = ridx;
|
||||
ci->env = 0;
|
||||
return ci;
|
||||
}
|
||||
|
||||
static void
|
||||
cipop(mrb_state *mrb)
|
||||
{
|
||||
if (mrb->ci->env) {
|
||||
struct REnv *e = mrb->ci->env;
|
||||
struct mrb_context *c = mrb->c;
|
||||
|
||||
if (c->ci->env) {
|
||||
struct REnv *e = c->ci->env;
|
||||
size_t len = (size_t)e->flags;
|
||||
mrb_value *p = (mrb_value *)mrb_malloc(mrb, sizeof(mrb_value)*len);
|
||||
|
||||
@@ -234,7 +241,7 @@ cipop(mrb_state *mrb)
|
||||
e->stack = p;
|
||||
}
|
||||
|
||||
mrb->ci--;
|
||||
c->ci--;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -242,23 +249,23 @@ ecall(mrb_state *mrb, int i)
|
||||
{
|
||||
struct RProc *p;
|
||||
mrb_callinfo *ci;
|
||||
mrb_value *self = mrb->stack;
|
||||
mrb_value *self = mrb->c->stack;
|
||||
struct RObject *exc;
|
||||
|
||||
p = mrb->ensure[i];
|
||||
p = mrb->c->ensure[i];
|
||||
if (!p) return;
|
||||
ci = cipush(mrb);
|
||||
ci->stackidx = mrb->stack - mrb->stbase;
|
||||
ci->stackidx = mrb->c->stack - mrb->c->stbase;
|
||||
ci->mid = ci[-1].mid;
|
||||
ci->acc = -1;
|
||||
ci->argc = 0;
|
||||
ci->proc = p;
|
||||
ci->nregs = p->body.irep->nregs;
|
||||
ci->target_class = p->target_class;
|
||||
mrb->stack = mrb->stack + ci[-1].nregs;
|
||||
mrb->c->stack = mrb->c->stack + ci[-1].nregs;
|
||||
exc = mrb->exc; mrb->exc = 0;
|
||||
mrb_run(mrb, p, *self);
|
||||
mrb->ensure[i] = NULL;
|
||||
mrb->c->ensure[i] = NULL;
|
||||
if (!mrb->exc) mrb->exc = exc;
|
||||
}
|
||||
|
||||
@@ -308,11 +315,11 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, int argc, mr
|
||||
|
||||
if (!mrb->jmp) {
|
||||
jmp_buf c_jmp;
|
||||
mrb_callinfo *old_ci = mrb->ci;
|
||||
mrb_callinfo *old_ci = mrb->c->ci;
|
||||
|
||||
if (setjmp(c_jmp) != 0) { /* error */
|
||||
while (old_ci != mrb->ci) {
|
||||
mrb->stack = mrb->stbase + mrb->ci->stackidx;
|
||||
while (old_ci != mrb->c->ci) {
|
||||
mrb->c->stack = mrb->c->stbase + mrb->c->ci->stackidx;
|
||||
cipop(mrb);
|
||||
}
|
||||
mrb->jmp = 0;
|
||||
@@ -332,10 +339,10 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, int argc, mr
|
||||
mrb_callinfo *ci;
|
||||
int n;
|
||||
|
||||
if (!mrb->stack) {
|
||||
if (!mrb->c->stack) {
|
||||
stack_init(mrb);
|
||||
}
|
||||
n = mrb->ci->nregs;
|
||||
n = mrb->c->ci->nregs;
|
||||
if (argc < 0) {
|
||||
mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative argc for funcall (%S)", mrb_fixnum_value(argc));
|
||||
}
|
||||
@@ -350,7 +357,7 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, int argc, mr
|
||||
ci = cipush(mrb);
|
||||
ci->mid = mid;
|
||||
ci->proc = p;
|
||||
ci->stackidx = mrb->stack - mrb->stbase;
|
||||
ci->stackidx = mrb->c->stack - mrb->c->stbase;
|
||||
ci->argc = argc;
|
||||
ci->target_class = p->target_class;
|
||||
if (MRB_PROC_CFUNC_P(p)) {
|
||||
@@ -360,25 +367,25 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, int argc, mr
|
||||
ci->nregs = p->body.irep->nregs + n;
|
||||
}
|
||||
ci->acc = -1;
|
||||
mrb->stack = mrb->stack + n;
|
||||
mrb->c->stack = mrb->c->stack + n;
|
||||
|
||||
stack_extend(mrb, ci->nregs, 0);
|
||||
mrb->stack[0] = self;
|
||||
mrb->c->stack[0] = self;
|
||||
if (undef) {
|
||||
mrb->stack[1] = mrb_symbol_value(undef);
|
||||
stack_copy(mrb->stack+2, argv, argc-1);
|
||||
mrb->c->stack[1] = mrb_symbol_value(undef);
|
||||
stack_copy(mrb->c->stack+2, argv, argc-1);
|
||||
}
|
||||
else if (argc > 0) {
|
||||
stack_copy(mrb->stack+1, argv, argc);
|
||||
stack_copy(mrb->c->stack+1, argv, argc);
|
||||
}
|
||||
mrb->stack[argc+1] = blk;
|
||||
mrb->c->stack[argc+1] = blk;
|
||||
|
||||
if (MRB_PROC_CFUNC_P(p)) {
|
||||
int ai = mrb_gc_arena_save(mrb);
|
||||
val = p->body.func(mrb, self);
|
||||
mrb_gc_arena_restore(mrb, ai);
|
||||
mrb_gc_protect(mrb, val);
|
||||
mrb->stack = mrb->stbase + mrb->ci->stackidx;
|
||||
mrb->c->stack = mrb->c->stbase + mrb->c->ci->stackidx;
|
||||
cipop(mrb);
|
||||
}
|
||||
else {
|
||||
@@ -398,9 +405,9 @@ mrb_value
|
||||
mrb_yield_internal(mrb_state *mrb, mrb_value b, int argc, mrb_value *argv, mrb_value self, struct RClass *c)
|
||||
{
|
||||
struct RProc *p;
|
||||
mrb_sym mid = mrb->ci->mid;
|
||||
mrb_sym mid = mrb->c->ci->mid;
|
||||
mrb_callinfo *ci;
|
||||
int n = mrb->ci->nregs;
|
||||
int n = mrb->c->ci->nregs;
|
||||
mrb_value val;
|
||||
|
||||
if (mrb_nil_p(b)) {
|
||||
@@ -410,7 +417,7 @@ mrb_yield_internal(mrb_state *mrb, mrb_value b, int argc, mrb_value *argv, mrb_v
|
||||
ci = cipush(mrb);
|
||||
ci->mid = mid;
|
||||
ci->proc = p;
|
||||
ci->stackidx = mrb->stack - mrb->stbase;
|
||||
ci->stackidx = mrb->c->stack - mrb->c->stbase;
|
||||
ci->argc = argc;
|
||||
ci->target_class = c;
|
||||
if (MRB_PROC_CFUNC_P(p)) {
|
||||
@@ -420,18 +427,18 @@ mrb_yield_internal(mrb_state *mrb, mrb_value b, int argc, mrb_value *argv, mrb_v
|
||||
ci->nregs = p->body.irep->nregs + 1;
|
||||
}
|
||||
ci->acc = -1;
|
||||
mrb->stack = mrb->stack + n;
|
||||
mrb->c->stack = mrb->c->stack + n;
|
||||
|
||||
stack_extend(mrb, ci->nregs, 0);
|
||||
mrb->stack[0] = self;
|
||||
mrb->c->stack[0] = self;
|
||||
if (argc > 0) {
|
||||
stack_copy(mrb->stack+1, argv, argc);
|
||||
stack_copy(mrb->c->stack+1, argv, argc);
|
||||
}
|
||||
mrb->stack[argc+1] = mrb_nil_value();
|
||||
mrb->c->stack[argc+1] = mrb_nil_value();
|
||||
|
||||
if (MRB_PROC_CFUNC_P(p)) {
|
||||
val = p->body.func(mrb, self);
|
||||
mrb->stack = mrb->stbase + mrb->ci->stackidx;
|
||||
mrb->c->stack = mrb->c->stbase + mrb->c->ci->stackidx;
|
||||
cipop(mrb);
|
||||
}
|
||||
else {
|
||||
@@ -445,7 +452,7 @@ mrb_yield_argv(mrb_state *mrb, mrb_value b, int argc, mrb_value *argv)
|
||||
{
|
||||
struct RProc *p = mrb_proc_ptr(b);
|
||||
|
||||
return mrb_yield_internal(mrb, b, argc, argv, mrb->stack[0], p->target_class);
|
||||
return mrb_yield_internal(mrb, b, argc, argv, mrb->c->stack[0], p->target_class);
|
||||
}
|
||||
|
||||
mrb_value
|
||||
@@ -453,7 +460,7 @@ mrb_yield(mrb_state *mrb, mrb_value b, mrb_value arg)
|
||||
{
|
||||
struct RProc *p = mrb_proc_ptr(b);
|
||||
|
||||
return mrb_yield_internal(mrb, b, 1, &arg, mrb->stack[0], p->target_class);
|
||||
return mrb_yield_internal(mrb, b, 1, &arg, mrb->c->stack[0], p->target_class);
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
@@ -484,14 +491,14 @@ argnum_error(mrb_state *mrb, int num)
|
||||
mrb_value exc;
|
||||
mrb_value str;
|
||||
|
||||
if (mrb->ci->mid) {
|
||||
if (mrb->c->ci->mid) {
|
||||
str = mrb_format(mrb, "'%S': wrong number of arguments (%S for %S)",
|
||||
mrb_sym2str(mrb, mrb->ci->mid),
|
||||
mrb_fixnum_value(mrb->ci->argc), mrb_fixnum_value(num));
|
||||
mrb_sym2str(mrb, mrb->c->ci->mid),
|
||||
mrb_fixnum_value(mrb->c->ci->argc), mrb_fixnum_value(num));
|
||||
}
|
||||
else {
|
||||
str = mrb_format(mrb, "wrong number of arguments (%S for %S)",
|
||||
mrb_fixnum_value(mrb->ci->argc), mrb_fixnum_value(num));
|
||||
mrb_fixnum_value(mrb->c->ci->argc), mrb_fixnum_value(num));
|
||||
}
|
||||
exc = mrb_exc_new3(mrb, E_ARGUMENT_ERROR, str);
|
||||
mrb->exc = mrb_obj_ptr(exc);
|
||||
@@ -577,13 +584,13 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
|
||||
else {
|
||||
goto L_RAISE;
|
||||
}
|
||||
if (!mrb->stack) {
|
||||
if (!mrb->c->stack) {
|
||||
stack_init(mrb);
|
||||
}
|
||||
stack_extend(mrb, irep->nregs, irep->nregs);
|
||||
mrb->ci->proc = proc;
|
||||
mrb->ci->nregs = irep->nregs + 1;
|
||||
regs = mrb->stack;
|
||||
mrb->c->ci->proc = proc;
|
||||
mrb->c->ci->nregs = irep->nregs + 1;
|
||||
regs = mrb->c->stack;
|
||||
regs[0] = self;
|
||||
|
||||
INIT_DISPATCH {
|
||||
@@ -769,12 +776,12 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
|
||||
|
||||
CASE(OP_ONERR) {
|
||||
/* sBx pc+=sBx on exception */
|
||||
if (mrb->rsize <= mrb->ci->ridx) {
|
||||
if (mrb->rsize == 0) mrb->rsize = 16;
|
||||
else mrb->rsize *= 2;
|
||||
mrb->rescue = (mrb_code **)mrb_realloc(mrb, mrb->rescue, sizeof(mrb_code*) * mrb->rsize);
|
||||
if (mrb->c->rsize <= mrb->c->ci->ridx) {
|
||||
if (mrb->c->rsize == 0) mrb->c->rsize = 16;
|
||||
else mrb->c->rsize *= 2;
|
||||
mrb->c->rescue = (mrb_code **)mrb_realloc(mrb, mrb->c->rescue, sizeof(mrb_code*) * mrb->c->rsize);
|
||||
}
|
||||
mrb->rescue[mrb->ci->ridx++] = pc + GETARG_sBx(i);
|
||||
mrb->c->rescue[mrb->c->ci->ridx++] = pc + GETARG_sBx(i);
|
||||
NEXT;
|
||||
}
|
||||
|
||||
@@ -789,7 +796,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
|
||||
int a = GETARG_A(i);
|
||||
|
||||
while (a--) {
|
||||
mrb->ci->ridx--;
|
||||
mrb->c->ci->ridx--;
|
||||
}
|
||||
NEXT;
|
||||
}
|
||||
@@ -806,12 +813,12 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
|
||||
|
||||
p = mrb_closure_new(mrb, mrb->irep[irep->idx+GETARG_Bx(i)]);
|
||||
/* push ensure_stack */
|
||||
if (mrb->esize <= mrb->ci->eidx) {
|
||||
if (mrb->esize == 0) mrb->esize = 16;
|
||||
else mrb->esize *= 2;
|
||||
mrb->ensure = (struct RProc **)mrb_realloc(mrb, mrb->ensure, sizeof(struct RProc*) * mrb->esize);
|
||||
if (mrb->c->esize <= mrb->c->ci->eidx) {
|
||||
if (mrb->c->esize == 0) mrb->c->esize = 16;
|
||||
else mrb->c->esize *= 2;
|
||||
mrb->c->ensure = (struct RProc **)mrb_realloc(mrb, mrb->c->ensure, sizeof(struct RProc*) * mrb->c->esize);
|
||||
}
|
||||
mrb->ensure[mrb->ci->eidx++] = p;
|
||||
mrb->c->ensure[mrb->c->ci->eidx++] = p;
|
||||
mrb_gc_arena_restore(mrb, ai);
|
||||
NEXT;
|
||||
}
|
||||
@@ -822,7 +829,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
|
||||
int a = GETARG_A(i);
|
||||
|
||||
for (n=0; n<a; n++) {
|
||||
ecall(mrb, --mrb->ci->eidx);
|
||||
ecall(mrb, --mrb->c->ci->eidx);
|
||||
}
|
||||
mrb_gc_arena_restore(mrb, ai);
|
||||
NEXT;
|
||||
@@ -880,7 +887,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
|
||||
ci = cipush(mrb);
|
||||
ci->mid = mid;
|
||||
ci->proc = m;
|
||||
ci->stackidx = mrb->stack - mrb->stbase;
|
||||
ci->stackidx = mrb->c->stack - mrb->c->stbase;
|
||||
if (n == CALL_MAXARGS) {
|
||||
ci->argc = -1;
|
||||
}
|
||||
@@ -898,7 +905,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
|
||||
ci->acc = a;
|
||||
|
||||
/* prepare stack */
|
||||
mrb->stack += a;
|
||||
mrb->c->stack += a;
|
||||
|
||||
if (MRB_PROC_CFUNC_P(m)) {
|
||||
if (n == CALL_MAXARGS) {
|
||||
@@ -908,17 +915,24 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
|
||||
ci->nregs = n + 2;
|
||||
}
|
||||
result = m->body.func(mrb, recv);
|
||||
mrb->stack[0] = result;
|
||||
mrb->c->stack[0] = result;
|
||||
mrb_gc_arena_restore(mrb, ai);
|
||||
if (mrb->exc) goto L_RAISE;
|
||||
/* pop stackpos */
|
||||
regs = mrb->stack = mrb->stbase + mrb->ci->stackidx;
|
||||
ci = mrb->c->ci;
|
||||
if (!MRB_PROC_CFUNC_P(ci[-1].proc)) {
|
||||
irep = ci[-1].proc->body.irep;
|
||||
pool = irep->pool;
|
||||
syms = irep->syms;
|
||||
}
|
||||
regs = mrb->c->stack = mrb->c->stbase + ci->stackidx;
|
||||
pc = ci->pc;
|
||||
cipop(mrb);
|
||||
NEXT;
|
||||
JUMP;
|
||||
}
|
||||
else {
|
||||
/* setup environment for calling method */
|
||||
proc = mrb->ci->proc = m;
|
||||
proc = mrb->c->ci->proc = m;
|
||||
irep = m->body.irep;
|
||||
pool = irep->pool;
|
||||
syms = irep->syms;
|
||||
@@ -929,7 +943,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
|
||||
else {
|
||||
stack_extend(mrb, irep->nregs, ci->argc+2);
|
||||
}
|
||||
regs = mrb->stack;
|
||||
regs = mrb->c->stack;
|
||||
pc = irep->iseq;
|
||||
JUMP;
|
||||
}
|
||||
@@ -943,11 +957,11 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
|
||||
CASE(OP_CALL) {
|
||||
/* A R(A) := self.call(frame.argc, frame.argv) */
|
||||
mrb_callinfo *ci;
|
||||
mrb_value recv = mrb->stack[0];
|
||||
mrb_value recv = mrb->c->stack[0];
|
||||
struct RProc *m = mrb_proc_ptr(recv);
|
||||
|
||||
/* replace callinfo */
|
||||
ci = mrb->ci;
|
||||
ci = mrb->c->ci;
|
||||
ci->target_class = m->target_class;
|
||||
ci->proc = m;
|
||||
if (m->env) {
|
||||
@@ -955,7 +969,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
|
||||
ci->mid = m->env->mid;
|
||||
}
|
||||
if (!m->env->stack) {
|
||||
m->env->stack = mrb->stack;
|
||||
m->env->stack = mrb->c->stack;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -965,12 +979,12 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
|
||||
mrb_gc_arena_restore(mrb, ai);
|
||||
if (mrb->exc) goto L_RAISE;
|
||||
/* pop stackpos */
|
||||
ci = mrb->ci;
|
||||
regs = mrb->stack = mrb->stbase + ci->stackidx;
|
||||
ci = mrb->c->ci;
|
||||
regs = mrb->c->stack = mrb->c->stbase + ci->stackidx;
|
||||
regs[ci->acc] = recv;
|
||||
pc = ci->pc;
|
||||
cipop(mrb);
|
||||
irep = mrb->ci->proc->body.irep;
|
||||
irep = mrb->c->ci->proc->body.irep;
|
||||
pool = irep->pool;
|
||||
syms = irep->syms;
|
||||
JUMP;
|
||||
@@ -980,7 +994,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
|
||||
proc = m;
|
||||
irep = m->body.irep;
|
||||
if (!irep) {
|
||||
mrb->stack[0] = mrb_nil_value();
|
||||
mrb->c->stack[0] = mrb_nil_value();
|
||||
goto L_RETURN;
|
||||
}
|
||||
pool = irep->pool;
|
||||
@@ -992,7 +1006,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
|
||||
else {
|
||||
stack_extend(mrb, irep->nregs, ci->argc+2);
|
||||
}
|
||||
regs = mrb->stack;
|
||||
regs = mrb->c->stack;
|
||||
regs[0] = m->env->stack[0];
|
||||
pc = m->body.irep->iseq;
|
||||
JUMP;
|
||||
@@ -1002,7 +1016,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
|
||||
CASE(OP_SUPER) {
|
||||
/* A B C R(A) := super(R(A+1),... ,R(A+C-1)) */
|
||||
mrb_value recv;
|
||||
mrb_callinfo *ci = mrb->ci;
|
||||
mrb_callinfo *ci = mrb->c->ci;
|
||||
struct RProc *m;
|
||||
struct RClass *c;
|
||||
mrb_sym mid = ci->mid;
|
||||
@@ -1010,7 +1024,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
|
||||
int n = GETARG_C(i);
|
||||
|
||||
recv = regs[0];
|
||||
c = mrb->ci->target_class->super;
|
||||
c = mrb->c->ci->target_class->super;
|
||||
m = mrb_method_search_vm(mrb, &c, mid);
|
||||
if (!m) {
|
||||
mid = mrb_intern2(mrb, "method_missing", 14);
|
||||
@@ -1028,7 +1042,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
|
||||
ci = cipush(mrb);
|
||||
ci->mid = mid;
|
||||
ci->proc = m;
|
||||
ci->stackidx = mrb->stack - mrb->stbase;
|
||||
ci->stackidx = mrb->c->stack - mrb->c->stbase;
|
||||
if (n == CALL_MAXARGS) {
|
||||
ci->argc = -1;
|
||||
}
|
||||
@@ -1039,15 +1053,15 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
|
||||
ci->pc = pc + 1;
|
||||
|
||||
/* prepare stack */
|
||||
mrb->stack += a;
|
||||
mrb->stack[0] = recv;
|
||||
mrb->c->stack += a;
|
||||
mrb->c->stack[0] = recv;
|
||||
|
||||
if (MRB_PROC_CFUNC_P(m)) {
|
||||
mrb->stack[0] = m->body.func(mrb, recv);
|
||||
mrb->c->stack[0] = m->body.func(mrb, recv);
|
||||
mrb_gc_arena_restore(mrb, ai);
|
||||
if (mrb->exc) goto L_RAISE;
|
||||
/* pop stackpos */
|
||||
regs = mrb->stack = mrb->stbase + mrb->ci->stackidx;
|
||||
regs = mrb->c->stack = mrb->c->stbase + mrb->c->ci->stackidx;
|
||||
cipop(mrb);
|
||||
NEXT;
|
||||
}
|
||||
@@ -1067,7 +1081,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
|
||||
else {
|
||||
stack_extend(mrb, irep->nregs, ci->argc+2);
|
||||
}
|
||||
regs = mrb->stack;
|
||||
regs = mrb->c->stack;
|
||||
pc = irep->iseq;
|
||||
JUMP;
|
||||
}
|
||||
@@ -1138,7 +1152,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
|
||||
int kd = (ax>>1)&0x1;
|
||||
int b = (ax>>0)& 0x1;
|
||||
*/
|
||||
int argc = mrb->ci->argc;
|
||||
int argc = mrb->c->ci->argc;
|
||||
mrb_value *argv = regs+1;
|
||||
mrb_value *argv0 = argv;
|
||||
int len = m1 + o + r + m2;
|
||||
@@ -1150,7 +1164,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
|
||||
argc = ary->len;
|
||||
mrb_gc_protect(mrb, regs[1]);
|
||||
}
|
||||
if (mrb->ci->proc && MRB_PROC_STRICT_P(mrb->ci->proc)) {
|
||||
if (mrb->c->ci->proc && MRB_PROC_STRICT_P(mrb->c->ci->proc)) {
|
||||
if (argc >= 0) {
|
||||
if (argc < m1 + m2 || (r == 0 && argc > len)) {
|
||||
argnum_error(mrb, m1+m2);
|
||||
@@ -1162,7 +1176,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
|
||||
argc = mrb_ary_ptr(argv[0])->len;
|
||||
argv = mrb_ary_ptr(argv[0])->ptr;
|
||||
}
|
||||
mrb->ci->argc = len;
|
||||
mrb->c->ci->argc = len;
|
||||
if (argc < len) {
|
||||
regs[len+1] = *blk; /* move block */
|
||||
if (argv0 != argv) {
|
||||
@@ -1219,11 +1233,11 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
|
||||
int eidx;
|
||||
|
||||
L_RAISE:
|
||||
ci = mrb->ci;
|
||||
ci = mrb->c->ci;
|
||||
mrb_obj_iv_ifnone(mrb, mrb->exc, mrb_intern2(mrb, "lastpc", 6), mrb_voidp_value(pc));
|
||||
mrb_obj_iv_ifnone(mrb, mrb->exc, mrb_intern2(mrb, "ciidx", 5), mrb_fixnum_value(ci - mrb->cibase));
|
||||
mrb_obj_iv_ifnone(mrb, mrb->exc, mrb_intern2(mrb, "ciidx", 5), mrb_fixnum_value(ci - mrb->c->cibase));
|
||||
eidx = ci->eidx;
|
||||
if (ci == mrb->cibase) {
|
||||
if (ci == mrb->c->cibase) {
|
||||
if (ci->ridx == 0) goto L_STOP;
|
||||
goto L_RESCUE;
|
||||
}
|
||||
@@ -1232,8 +1246,8 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
|
||||
}
|
||||
while (ci[0].ridx == ci[-1].ridx) {
|
||||
cipop(mrb);
|
||||
ci = mrb->ci;
|
||||
mrb->stack = mrb->stbase + ci[1].stackidx;
|
||||
ci = mrb->c->ci;
|
||||
mrb->c->stack = mrb->c->stbase + ci[1].stackidx;
|
||||
if (ci[1].acc < 0 && prev_jmp) {
|
||||
mrb->jmp = prev_jmp;
|
||||
longjmp(*(jmp_buf*)mrb->jmp, 1);
|
||||
@@ -1241,9 +1255,9 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
|
||||
while (eidx > ci->eidx) {
|
||||
ecall(mrb, --eidx);
|
||||
}
|
||||
if (ci == mrb->cibase) {
|
||||
if (ci == mrb->c->cibase) {
|
||||
if (ci->ridx == 0) {
|
||||
regs = mrb->stack = mrb->stbase;
|
||||
regs = mrb->c->stack = mrb->c->stbase;
|
||||
goto L_STOP;
|
||||
}
|
||||
break;
|
||||
@@ -1253,12 +1267,12 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
|
||||
irep = ci->proc->body.irep;
|
||||
pool = irep->pool;
|
||||
syms = irep->syms;
|
||||
regs = mrb->stack = mrb->stbase + ci[1].stackidx;
|
||||
pc = mrb->rescue[--ci->ridx];
|
||||
regs = mrb->c->stack = mrb->c->stbase + ci[1].stackidx;
|
||||
pc = mrb->c->rescue[--ci->ridx];
|
||||
}
|
||||
else {
|
||||
mrb_callinfo *ci = mrb->ci;
|
||||
int acc, eidx = mrb->ci->eidx;
|
||||
mrb_callinfo *ci = mrb->c->ci;
|
||||
int acc, eidx = mrb->c->ci->eidx;
|
||||
mrb_value v = regs[GETARG_A(i)];
|
||||
|
||||
switch (GETARG_B(i)) {
|
||||
@@ -1271,45 +1285,48 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
|
||||
localjump_error(mrb, LOCALJUMP_ERROR_RETURN);
|
||||
goto L_RAISE;
|
||||
}
|
||||
ci = mrb->cibase + e->cioff;
|
||||
if (ci == mrb->cibase) {
|
||||
ci = mrb->c->cibase + e->cioff;
|
||||
if (ci == mrb->c->cibase) {
|
||||
localjump_error(mrb, LOCALJUMP_ERROR_RETURN);
|
||||
goto L_RAISE;
|
||||
}
|
||||
mrb->ci = ci;
|
||||
mrb->c->ci = ci;
|
||||
break;
|
||||
}
|
||||
case OP_R_NORMAL:
|
||||
if (ci == mrb->cibase) {
|
||||
localjump_error(mrb, LOCALJUMP_ERROR_RETURN);
|
||||
goto L_RAISE;
|
||||
if (ci == mrb->c->cibase) {
|
||||
if (!mrb->c->prev) { /* toplevel return */
|
||||
localjump_error(mrb, LOCALJUMP_ERROR_RETURN);
|
||||
goto L_RAISE;
|
||||
}
|
||||
mrb->c = mrb->c->prev; /* automatic yield at the end */
|
||||
}
|
||||
ci = mrb->ci;
|
||||
ci = mrb->c->ci;
|
||||
break;
|
||||
case OP_R_BREAK:
|
||||
if (proc->env->cioff < 0) {
|
||||
localjump_error(mrb, LOCALJUMP_ERROR_BREAK);
|
||||
goto L_RAISE;
|
||||
}
|
||||
ci = mrb->ci = mrb->cibase + proc->env->cioff + 1;
|
||||
ci = mrb->c->ci = mrb->c->cibase + proc->env->cioff + 1;
|
||||
break;
|
||||
default:
|
||||
/* cannot happen */
|
||||
break;
|
||||
}
|
||||
while (eidx > mrb->ci[-1].eidx) {
|
||||
while (eidx > mrb->c->ci[-1].eidx) {
|
||||
ecall(mrb, --eidx);
|
||||
}
|
||||
cipop(mrb);
|
||||
acc = ci->acc;
|
||||
pc = ci->pc;
|
||||
regs = mrb->stack = mrb->stbase + ci->stackidx;
|
||||
regs = mrb->c->stack = mrb->c->stbase + ci->stackidx;
|
||||
if (acc < 0) {
|
||||
mrb->jmp = prev_jmp;
|
||||
return v;
|
||||
}
|
||||
DEBUG(printf("from :%s\n", mrb_sym2name(mrb, ci->mid)));
|
||||
proc = mrb->ci->proc;
|
||||
proc = mrb->c->ci->proc;
|
||||
irep = proc->body.irep;
|
||||
pool = irep->pool;
|
||||
syms = irep->syms;
|
||||
@@ -1347,7 +1364,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
|
||||
}
|
||||
|
||||
/* replace callinfo */
|
||||
ci = mrb->ci;
|
||||
ci = mrb->c->ci;
|
||||
ci->mid = mid;
|
||||
ci->target_class = m->target_class;
|
||||
if (n == CALL_MAXARGS) {
|
||||
@@ -1358,10 +1375,10 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
|
||||
}
|
||||
|
||||
/* move stack */
|
||||
value_move(mrb->stack, ®s[a], ci->argc+1);
|
||||
value_move(mrb->c->stack, ®s[a], ci->argc+1);
|
||||
|
||||
if (MRB_PROC_CFUNC_P(m)) {
|
||||
mrb->stack[0] = m->body.func(mrb, recv);
|
||||
mrb->c->stack[0] = m->body.func(mrb, recv);
|
||||
mrb_gc_arena_restore(mrb, ai);
|
||||
goto L_RETURN;
|
||||
}
|
||||
@@ -1376,7 +1393,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
|
||||
else {
|
||||
stack_extend(mrb, irep->nregs, ci->argc+2);
|
||||
}
|
||||
regs = mrb->stack;
|
||||
regs = mrb->c->stack;
|
||||
pc = irep->iseq;
|
||||
}
|
||||
JUMP;
|
||||
@@ -1854,7 +1871,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
|
||||
base = regs[a];
|
||||
super = regs[a+1];
|
||||
if (mrb_nil_p(base)) {
|
||||
base = mrb_obj_value(mrb->ci->target_class);
|
||||
base = mrb_obj_value(mrb->c->ci->target_class);
|
||||
}
|
||||
c = mrb_vm_define_class(mrb, base, super, id);
|
||||
regs[a] = mrb_obj_value(c);
|
||||
@@ -1871,7 +1888,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
|
||||
|
||||
base = regs[a];
|
||||
if (mrb_nil_p(base)) {
|
||||
base = mrb_obj_value(mrb->ci->target_class);
|
||||
base = mrb_obj_value(mrb->c->ci->target_class);
|
||||
}
|
||||
c = mrb_vm_define_module(mrb, base, id);
|
||||
regs[a] = mrb_obj_value(c);
|
||||
@@ -1891,23 +1908,23 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
|
||||
ci->pc = pc + 1;
|
||||
ci->acc = a;
|
||||
ci->mid = 0;
|
||||
ci->stackidx = mrb->stack - mrb->stbase;
|
||||
ci->stackidx = mrb->c->stack - mrb->c->stbase;
|
||||
ci->argc = 0;
|
||||
ci->target_class = mrb_class_ptr(recv);
|
||||
|
||||
/* prepare stack */
|
||||
mrb->stack += a;
|
||||
mrb->c->stack += a;
|
||||
|
||||
p = mrb_proc_new(mrb, mrb->irep[irep->idx+GETARG_Bx(i)]);
|
||||
p->target_class = ci->target_class;
|
||||
ci->proc = p;
|
||||
|
||||
if (MRB_PROC_CFUNC_P(p)) {
|
||||
mrb->stack[0] = p->body.func(mrb, recv);
|
||||
mrb->c->stack[0] = p->body.func(mrb, recv);
|
||||
mrb_gc_arena_restore(mrb, ai);
|
||||
if (mrb->exc) goto L_RAISE;
|
||||
/* pop stackpos */
|
||||
regs = mrb->stack = mrb->stbase + mrb->ci->stackidx;
|
||||
regs = mrb->c->stack = mrb->c->stbase + mrb->c->ci->stackidx;
|
||||
cipop(mrb);
|
||||
NEXT;
|
||||
}
|
||||
@@ -1917,7 +1934,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
|
||||
syms = irep->syms;
|
||||
stack_extend(mrb, irep->nregs, 1);
|
||||
ci->nregs = irep->nregs;
|
||||
regs = mrb->stack;
|
||||
regs = mrb->c->stack;
|
||||
pc = irep->iseq;
|
||||
JUMP;
|
||||
}
|
||||
@@ -1942,13 +1959,13 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
|
||||
|
||||
CASE(OP_TCLASS) {
|
||||
/* A B R(A) := target_class */
|
||||
if (!mrb->ci->target_class) {
|
||||
if (!mrb->c->ci->target_class) {
|
||||
static const char msg[] = "no target class or module";
|
||||
mrb_value exc = mrb_exc_new(mrb, E_TYPE_ERROR, msg, sizeof(msg) - 1);
|
||||
mrb->exc = mrb_obj_ptr(exc);
|
||||
goto L_RAISE;
|
||||
}
|
||||
regs[GETARG_A(i)] = mrb_obj_value(mrb->ci->target_class);
|
||||
regs[GETARG_A(i)] = mrb_obj_value(mrb->c->ci->target_class);
|
||||
NEXT;
|
||||
}
|
||||
|
||||
@@ -1974,7 +1991,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
|
||||
/* stop VM */
|
||||
L_STOP:
|
||||
{
|
||||
int n = mrb->ci->eidx;
|
||||
int n = mrb->c->ci->eidx;
|
||||
|
||||
while (n--) {
|
||||
ecall(mrb, n);
|
||||
|
||||
Reference in New Issue
Block a user