Protect ensure clause lambdas from GC; fix #3491

parent 6a992a25
...@@ -565,7 +565,7 @@ mark_context_stack(mrb_state *mrb, struct mrb_context *c) ...@@ -565,7 +565,7 @@ mark_context_stack(mrb_state *mrb, struct mrb_context *c)
static void static void
mark_context(mrb_state *mrb, struct mrb_context *c) mark_context(mrb_state *mrb, struct mrb_context *c)
{ {
int i, e = 0; int i;
mrb_callinfo *ci; mrb_callinfo *ci;
/* mark stack */ /* mark stack */
...@@ -574,16 +574,14 @@ mark_context(mrb_state *mrb, struct mrb_context *c) ...@@ -574,16 +574,14 @@ mark_context(mrb_state *mrb, struct mrb_context *c)
/* mark VM stack */ /* mark VM stack */
if (c->cibase) { if (c->cibase) {
for (ci = c->cibase; ci <= c->ci; ci++) { for (ci = c->cibase; ci <= c->ci; ci++) {
if (ci->eidx > e) {
e = ci->eidx;
}
mrb_gc_mark(mrb, (struct RBasic*)ci->env); mrb_gc_mark(mrb, (struct RBasic*)ci->env);
mrb_gc_mark(mrb, (struct RBasic*)ci->proc); mrb_gc_mark(mrb, (struct RBasic*)ci->proc);
mrb_gc_mark(mrb, (struct RBasic*)ci->target_class); mrb_gc_mark(mrb, (struct RBasic*)ci->target_class);
} }
} }
/* mark ensure stack */ /* mark ensure stack */
for (i=0; i<e; i++) { for (i=0; i<c->esize; i++) {
if (c->ensure[i] == NULL) break;
mrb_gc_mark(mrb, (struct RBasic*)c->ensure[i]); mrb_gc_mark(mrb, (struct RBasic*)c->ensure[i]);
} }
/* mark fibers */ /* mark fibers */
......
...@@ -296,6 +296,7 @@ ecall(mrb_state *mrb, int i) ...@@ -296,6 +296,7 @@ ecall(mrb_state *mrb, int i)
} }
p = mrb->c->ensure[i]; p = mrb->c->ensure[i];
if (!p) return; if (!p) return;
mrb->c->ensure[i] = NULL;
if (mrb->c->ci->eidx > i) if (mrb->c->ci->eidx > i)
mrb->c->ci->eidx = i; mrb->c->ci->eidx = i;
cioff = mrb->c->ci - mrb->c->cibase; cioff = mrb->c->ci - mrb->c->cibase;
...@@ -310,7 +311,6 @@ ecall(mrb_state *mrb, int i) ...@@ -310,7 +311,6 @@ ecall(mrb_state *mrb, int i)
mrb->c->stack = mrb->c->stack + ci[-1].nregs; mrb->c->stack = mrb->c->stack + ci[-1].nregs;
exc = mrb->exc; mrb->exc = 0; exc = mrb->exc; mrb->exc = 0;
mrb_run(mrb, p, *self); mrb_run(mrb, p, *self);
mrb->c->ensure[i] = NULL;
mrb->c->ci = mrb->c->cibase + cioff; mrb->c->ci = mrb->c->cibase + cioff;
if (!mrb->exc) mrb->exc = exc; if (!mrb->exc) mrb->exc = exc;
} }
...@@ -1148,6 +1148,7 @@ RETRY_TRY_BLOCK: ...@@ -1148,6 +1148,7 @@ RETRY_TRY_BLOCK:
mrb->c->ensure = (struct RProc **)mrb_realloc(mrb, mrb->c->ensure, sizeof(struct RProc*) * mrb->c->esize); mrb->c->ensure = (struct RProc **)mrb_realloc(mrb, mrb->c->ensure, sizeof(struct RProc*) * mrb->c->esize);
} }
mrb->c->ensure[mrb->c->ci->eidx++] = p; mrb->c->ensure[mrb->c->ci->eidx++] = p;
mrb->c->ensure[mrb->c->ci->eidx] = NULL;
ARENA_RESTORE(mrb, ai); ARENA_RESTORE(mrb, ai);
NEXT; NEXT;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment