Skip to content

Commit

Permalink
Protect the returning value in OP_RETURN; fix #3669
Browse files Browse the repository at this point in the history
Even though the returning value is retrieved from the stack,
it may be freed if GC is caused during stack rewinding
(e.g. ensure calls).
  • Loading branch information
matz committed May 29, 2017
1 parent 9f634a6 commit 02670ff
Showing 1 changed file with 5 additions and 0 deletions.
5 changes: 5 additions & 0 deletions src/vm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1812,6 +1812,7 @@ mrb_vm_exec(mrb_state *mrb, struct RProc *proc, mrb_code *pc)
int acc, eidx = mrb->c->ci->eidx;
mrb_value v = regs[GETARG_A(i)];

mrb_gc_protect(mrb, v);
switch (GETARG_B(i)) {
case OP_R_RETURN:
/* Fall through to OP_R_NORMAL otherwise */
Expand Down Expand Up @@ -1888,6 +1889,7 @@ mrb_vm_exec(mrb_state *mrb, struct RProc *proc, mrb_code *pc)
while (eidx > mrb->c->ci[-1].eidx) {
ecall(mrb, --eidx);
}
ARENA_RESTORE(mrb, ai);
mrb->c->vmexec = FALSE;
mrb->jmp = prev_jmp;
return v;
Expand All @@ -1913,6 +1915,7 @@ mrb_vm_exec(mrb_state *mrb, struct RProc *proc, mrb_code *pc)
ecall(mrb, --eidx);
}
if (mrb->c->vmexec && !mrb->c->ci->target_class) {
ARENA_RESTORE(mrb, ai);
mrb->c->vmexec = FALSE;
mrb->jmp = prev_jmp;
return v;
Expand All @@ -1922,6 +1925,7 @@ mrb_vm_exec(mrb_state *mrb, struct RProc *proc, mrb_code *pc)
mrb->c->stack = ci->stackent;
cipop(mrb);
if (acc == CI_ACC_SKIP || acc == CI_ACC_DIRECT) {
ARENA_RESTORE(mrb, ai);
mrb->jmp = prev_jmp;
return v;
}
Expand All @@ -1933,6 +1937,7 @@ mrb_vm_exec(mrb_state *mrb, struct RProc *proc, mrb_code *pc)
syms = irep->syms;

regs[acc] = v;
ARENA_RESTORE(mrb, ai);
}
JUMP;
}
Expand Down

0 comments on commit 02670ff

Please sign in to comment.