diff --git a/include/mruby/proc.h b/include/mruby/proc.h index 952f52912..451c2781f 100644 --- a/include/mruby/proc.h +++ b/include/mruby/proc.h @@ -16,6 +16,13 @@ */ MRB_BEGIN_DECL +/* + * env object (for internal used) + * + * - don't create multiple envs on one ci. + * - don't share a env to different ci. + * - don't attach a closed env to any ci. + */ struct REnv { MRB_OBJECT_HEADER; mrb_value *stack; diff --git a/src/vm.c b/src/vm.c index 01fa16346..d933be05e 100644 --- a/src/vm.c +++ b/src/vm.c @@ -130,7 +130,7 @@ stack_init(mrb_state *mrb) } static inline void -envadjust(mrb_state *mrb, mrb_value *oldbase, mrb_value *newbase, size_t oldsize) +envadjust(mrb_state *mrb, mrb_value *oldbase, mrb_value *newbase) { mrb_callinfo *ci = mrb->c->cibase; ptrdiff_t delta = newbase - oldbase; @@ -138,10 +138,11 @@ envadjust(mrb_state *mrb, mrb_value *oldbase, mrb_value *newbase, size_t oldsize if (delta == 0) return; while (ci <= mrb->c->ci) { struct REnv *e = mrb_vm_ci_env(ci); - mrb_value *st; - if (e && MRB_ENV_ONSTACK_P(e) && - (st = e->stack) && (size_t)(st - oldbase) < oldsize) { + if (e) { + mrb_assert(e->cxt == mrb->c && MRB_ENV_ONSTACK_P(e)); + mrb_assert(e->stack == ci->stack); + e->stack += delta; } ci->stack += delta; @@ -178,7 +179,7 @@ stack_extend_alloc(mrb_state *mrb, mrb_int room) newstack = (mrb_value*)mrb_realloc(mrb, mrb->c->stbase, sizeof(mrb_value) * size); stack_clear(&(newstack[oldsize]), size - oldsize); - envadjust(mrb, oldbase, newstack, oldsize); + envadjust(mrb, oldbase, newstack); mrb->c->stbase = newstack; mrb->c->stend = mrb->c->stbase + size;