diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2017-05-29 10:33:43 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2017-05-29 10:33:43 +0900 |
| commit | 02670ffa8d7e178164cc590c5ca01fe090a19ced (patch) | |
| tree | 105ac4c2f46de500e9f0cba869e9783b3133a04b /src | |
| parent | 9f634a6f8b78ac9099238407cf15d4abca9b808c (diff) | |
| download | mruby-02670ffa8d7e178164cc590c5ca01fe090a19ced.tar.gz mruby-02670ffa8d7e178164cc590c5ca01fe090a19ced.zip | |
Protect the returning value in OP_RETURN; fix #3669
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).
Diffstat (limited to 'src')
| -rw-r--r-- | src/vm.c | 5 |
1 files changed, 5 insertions, 0 deletions
@@ -1812,6 +1812,7 @@ RETRY_TRY_BLOCK: 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 */ @@ -1888,6 +1889,7 @@ RETRY_TRY_BLOCK: while (eidx > mrb->c->ci[-1].eidx) { ecall(mrb, --eidx); } + ARENA_RESTORE(mrb, ai); mrb->c->vmexec = FALSE; mrb->jmp = prev_jmp; return v; @@ -1913,6 +1915,7 @@ RETRY_TRY_BLOCK: 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; @@ -1922,6 +1925,7 @@ RETRY_TRY_BLOCK: 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; } @@ -1933,6 +1937,7 @@ RETRY_TRY_BLOCK: syms = irep->syms; regs[acc] = v; + ARENA_RESTORE(mrb, ai); } JUMP; } |
