diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2017-04-22 14:35:36 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2017-04-22 14:35:36 +0900 |
| commit | 5513fcee22ceab9293bff7815f961616c1fa3e83 (patch) | |
| tree | 917ae5efe1eff1f8b56342ba822137f9f450419c /src | |
| parent | 3b0a36d3993ff6c553b171c8bcb0e703a471ef5e (diff) | |
| download | mruby-5513fcee22ceab9293bff7815f961616c1fa3e83.tar.gz mruby-5513fcee22ceab9293bff7815f961616c1fa3e83.zip | |
Keep reference to mrb_context from env; fix #3619
Diffstat (limited to 'src')
| -rw-r--r-- | src/gc.c | 13 | ||||
| -rw-r--r-- | src/kernel.c | 6 | ||||
| -rw-r--r-- | src/proc.c | 2 | ||||
| -rw-r--r-- | src/vm.c | 24 |
4 files changed, 29 insertions, 16 deletions
@@ -593,8 +593,9 @@ mark_context(mrb_state *mrb, struct mrb_context *c) mrb_gc_mark(mrb, (struct RBasic*)c->ensure[i]); } /* mark fibers */ - if (c->prev && c->prev->fib) { - mrb_gc_mark(mrb, (struct RBasic*)c->prev->fib); + mrb_gc_mark(mrb, (struct RBasic*)c->fib); + if (c->prev) { + mark_context(mrb, c->prev); } } @@ -646,6 +647,9 @@ gc_mark_children(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj) struct REnv *e = (struct REnv*)obj; mrb_int i, len; + if (MRB_ENV_STACK_SHARED_P(e) && e->cxt.c->fib) { + mrb_gc_mark(mrb, (struct RBasic*)e->cxt.c->fib); + } len = MRB_ENV_STACK_LEN(e); for (i=0; i<len; i++) { mrb_gc_mark_value(mrb, e->stack[i]); @@ -878,13 +882,10 @@ root_scan_phase(mrb_state *mrb, mrb_gc *gc) mrb_gc_mark(mrb, (struct RBasic*)mrb->arena_err); #endif - mark_context(mrb, mrb->root_c); - if (mrb->root_c->fib) { - mrb_gc_mark(mrb, (struct RBasic*)mrb->root_c->fib); - } if (mrb->root_c != mrb->c) { mark_context(mrb, mrb->c); } + mark_context(mrb, mrb->root_c); } static size_t diff --git a/src/kernel.c b/src/kernel.c index ce304fd99..c1300ed70 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -158,7 +158,7 @@ mrb_f_block_given_p_m(mrb_state *mrb, mrb_value self) ci = 0; /* no callinfo available */ } else { - ci = mrb->c->cibase + e->cioff; + ci = e->cxt.c->cibase + e->cioff; bp = ci[1].stackent + 1; } } @@ -1165,8 +1165,8 @@ mrb_local_variables(mrb_state *mrb, mrb_value self) while (e) { if (MRB_ENV_STACK_SHARED_P(e) && - !MRB_PROC_CFUNC_P(mrb->c->cibase[e->cioff].proc)) { - irep = mrb->c->cibase[e->cioff].proc->body.irep; + !MRB_PROC_CFUNC_P(e->cxt.c->cibase[e->cioff].proc)) { + irep = e->cxt.c->cibase[e->cioff].proc->body.irep; if (irep->lv) { for (i = 0; i + 1 < irep->nlocals; ++i) { if (irep->lv[i].name) { diff --git a/src/proc.c b/src/proc.c index 3955c0a1a..ee4a493cd 100644 --- a/src/proc.c +++ b/src/proc.c @@ -41,7 +41,7 @@ env_new(mrb_state *mrb, int nlocals) e = (struct REnv*)mrb_obj_alloc(mrb, MRB_TT_ENV, (struct RClass*)mrb->c->ci->proc->env); MRB_SET_ENV_STACK_LEN(e, nlocals); - e->mid = mrb->c->ci->mid; + e->cxt.c = mrb->c; e->cioff = mrb->c->ci - mrb->c->cibase; e->stack = mrb->c->stack; @@ -201,8 +201,8 @@ is_strict(mrb_state *mrb, struct REnv *e) { int cioff = e->cioff; - if (MRB_ENV_STACK_SHARED_P(e) && mrb->c->cibase[cioff].proc && - MRB_PROC_STRICT_P(mrb->c->cibase[cioff].proc)) { + if (MRB_ENV_STACK_SHARED_P(e) && e->cxt.c->cibase[cioff].proc && + MRB_PROC_STRICT_P(e->cxt.c->cibase[cioff].proc)) { return TRUE; } return FALSE; @@ -264,8 +264,9 @@ mrb_env_unshare(mrb_state *mrb, struct REnv *e) MRB_ENV_UNSHARE_STACK(e); if (!e->c) { /* save block argument position (negated) */ - e->cioff = -mrb->c->cibase[cioff].argc-1; + e->cioff = -e->cxt.c->cibase[cioff].argc-1; } + e->cxt.mid = e->cxt.c->cibase[cioff].mid; p = (mrb_value *)mrb_malloc(mrb, sizeof(mrb_value)*len); if (len > 0) { stack_copy(p, e->stack, len); @@ -1236,6 +1237,10 @@ RETRY_TRY_BLOCK: bidx = a+n+1; } if (GET_OPCODE(i) != OP_SENDB) { + if (bidx >= mrb->c->ci->nregs) { + stack_extend(mrb, bidx+1); + mrb->c->ci->nregs = bidx+1; + } SET_NIL_VALUE(regs[bidx]); } else { @@ -1363,9 +1368,15 @@ RETRY_TRY_BLOCK: ci->target_class = m->target_class; ci->proc = m; if (m->env) { - if (m->env->mid) { - ci->mid = m->env->mid; + mrb_sym mid; + + if (MRB_ENV_STACK_SHARED_P(m->env)) { + mid = m->env->cxt.c->cibase[m->env->cioff].mid; + } + else { + mid = m->env->cxt.mid; } + if (mid) ci->mid = mid; if (!m->env->stack) { m->env->stack = mrb->c->stack; } @@ -1990,7 +2001,8 @@ RETRY_TRY_BLOCK: if (lv == 0) stack = regs + 1; else { struct REnv *e = uvenv(mrb, lv-1); - if (!e || e->mid == 0) { + if (!e || e->cioff == 0 || + (!MRB_ENV_STACK_SHARED_P(e) && e->cxt.mid == 0)) { localjump_error(mrb, LOCALJUMP_ERROR_YIELD); goto L_RAISE; } |
