mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
Protect ensure clause lambdas from GC; fix #3491
This commit is contained in:
@@ -565,7 +565,7 @@ mark_context_stack(mrb_state *mrb, struct mrb_context *c)
|
||||
static void
|
||||
mark_context(mrb_state *mrb, struct mrb_context *c)
|
||||
{
|
||||
int i, e = 0;
|
||||
int i;
|
||||
mrb_callinfo *ci;
|
||||
|
||||
/* mark stack */
|
||||
@@ -574,16 +574,14 @@ mark_context(mrb_state *mrb, struct mrb_context *c)
|
||||
/* mark VM stack */
|
||||
if (c->cibase) {
|
||||
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->proc);
|
||||
mrb_gc_mark(mrb, (struct RBasic*)ci->target_class);
|
||||
}
|
||||
}
|
||||
/* 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]);
|
||||
}
|
||||
/* mark fibers */
|
||||
|
||||
@@ -296,6 +296,7 @@ ecall(mrb_state *mrb, int i)
|
||||
}
|
||||
p = mrb->c->ensure[i];
|
||||
if (!p) return;
|
||||
mrb->c->ensure[i] = NULL;
|
||||
if (mrb->c->ci->eidx > i)
|
||||
mrb->c->ci->eidx = i;
|
||||
cioff = mrb->c->ci - mrb->c->cibase;
|
||||
@@ -310,7 +311,6 @@ ecall(mrb_state *mrb, int i)
|
||||
mrb->c->stack = mrb->c->stack + ci[-1].nregs;
|
||||
exc = mrb->exc; mrb->exc = 0;
|
||||
mrb_run(mrb, p, *self);
|
||||
mrb->c->ensure[i] = NULL;
|
||||
mrb->c->ci = mrb->c->cibase + cioff;
|
||||
if (!mrb->exc) mrb->exc = exc;
|
||||
}
|
||||
@@ -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[mrb->c->ci->eidx++] = p;
|
||||
mrb->c->ensure[mrb->c->ci->eidx] = NULL;
|
||||
ARENA_RESTORE(mrb, ai);
|
||||
NEXT;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user