diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/array.c | 2 | ||||
| -rw-r--r-- | src/class.c | 4 | ||||
| -rw-r--r-- | src/gc.c | 2 | ||||
| -rw-r--r-- | src/kernel.c | 4 | ||||
| -rw-r--r-- | src/vm.c | 18 |
5 files changed, 19 insertions, 11 deletions
diff --git a/src/array.c b/src/array.c index 86fb50e5c..8b6b9fa1e 100644 --- a/src/array.c +++ b/src/array.c @@ -169,7 +169,7 @@ ary_expand_capa(mrb_state *mrb, struct RArray *a, mrb_int len) { mrb_int capa = a->aux.capa; - if (len > ARY_MAX_SIZE) { + if (len > ARY_MAX_SIZE || len < 0) { size_error: mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big"); } diff --git a/src/class.c b/src/class.c index 0eea9b4dc..99ad14d81 100644 --- a/src/class.c +++ b/src/class.c @@ -902,7 +902,9 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) if (argc > i) { *pl = argc-i; if (*pl > 0) { - *var = ARGV + arg_i; + mrb_value args = mrb_ary_new_from_values(mrb, *pl, ARGV+arg_i); + RARRAY(args)->c = NULL; + *var = (mrb_value*)RARRAY_PTR(args); } i = argc; arg_i += *pl; @@ -579,6 +579,8 @@ mark_context(mrb_state *mrb, struct mrb_context *c) int i; mrb_callinfo *ci; + if (c->status == MRB_FIBER_TERMINATED) return; + /* mark VM stack */ mark_context_stack(mrb, c); diff --git a/src/kernel.c b/src/kernel.c index 20f52922d..f1d7700de 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -318,6 +318,7 @@ mrb_obj_clone(mrb_state *mrb, mrb_value self) } p = (struct RObject*)mrb_obj_alloc(mrb, mrb_type(self), mrb_obj_class(mrb, self)); p->c = mrb_singleton_class_clone(mrb, self); + mrb_field_write_barrier(mrb, (struct RBasic*)p, (struct RBasic*)p->c); clone = mrb_obj_value(p); init_copy(mrb, clone, self); @@ -410,11 +411,8 @@ mrb_obj_extend_m(mrb_state *mrb, mrb_value self) { mrb_value *argv; mrb_int argc; - mrb_value args; mrb_get_args(mrb, "*", &argv, &argc); - args = mrb_ary_new_from_values(mrb, argc, argv); - argv = (mrb_value*)RARRAY_PTR(args); return mrb_obj_extend(mrb, argc, argv, self); } @@ -1684,6 +1684,8 @@ RETRY_TRY_BLOCK: else { struct REnv *e = uvenv(mrb, lv-1); if (!e) goto L_NOSUPER; + if (MRB_ENV_STACK_LEN(e) <= m1+r+m2+1) + goto L_NOSUPER; stack = e->stack + 1; } if (r == 0) { @@ -1894,9 +1896,13 @@ RETRY_TRY_BLOCK: } /* call ensure only when we skip this callinfo */ if (ci[0].ridx == ci[-1].ridx) { + mrb_value *org_stbase = mrb->c->stbase; while (mrb->c->eidx > ci->epos) { ecall(mrb, --mrb->c->eidx); ci = mrb->c->ci; + if (org_stbase != mrb->c->stbase) { + stk = mrb->c->stack; + } } } } @@ -1985,21 +1991,21 @@ RETRY_TRY_BLOCK: if (!proc->env || !MRB_ENV_STACK_SHARED_P(proc->env)) { goto L_BREAK_ERROR; } + if (proc->env->cxt.c != mrb->c) { + goto L_BREAK_ERROR; + } + while (mrb->c->eidx > mrb->c->ci->epos) { + ecall(mrb, --mrb->c->eidx); + } /* break from fiber block */ if (mrb->c->ci == mrb->c->cibase && mrb->c->ci->pc) { struct mrb_context *c = mrb->c; - while (mrb->c->eidx > 0) { - ecall(mrb, --mrb->c->eidx); - } mrb->c = c->prev; c->prev = NULL; ci = mrb->c->ci; } if (ci->acc < 0) { - while (mrb->c->eidx > mrb->c->ci->epos) { - ecall(mrb, --mrb->c->eidx); - } ARENA_RESTORE(mrb, ai); mrb->c->vmexec = FALSE; mrb->exc = (struct RObject*)break_new(mrb, proc, v); |
