Fix undefined behavior bug with errors.

janet_vm_return_reg should only be set when janet_continue
is called. Otherwise, a panic may dump it's error message in
the wrong place, resulting in undefined behavior (often showing
the last return value or worse, segfaulting).
This commit is contained in:
Calvin Rose 2019-04-10 23:29:40 -04:00
parent d514eab627
commit 1596511175
2 changed files with 9 additions and 8 deletions

View File

@ -578,7 +578,6 @@ static JanetSignal run_vm(JanetFiber *fiber, Janet in, JanetFiberStatus status)
janet_fiber_cframe(fiber, janet_unwrap_cfunction(callee));
Janet ret = janet_unwrap_cfunction(callee)(argc, fiber->data + fiber->frame);
janet_fiber_popframe(fiber);
/*if (fiber->frame == 0) vm_return(JANET_SIGNAL_OK, ret);*/
stack = fiber->data + fiber->frame;
stack[A] = ret;
vm_checkgc_pcnext();
@ -638,6 +637,7 @@ static JanetSignal run_vm(JanetFiber *fiber, Janet in, JanetFiberStatus status)
if (sig != JANET_SIGNAL_OK && !(child->flags & (1 << sig)))
vm_return(sig, retreg);
fiber->child = NULL;
stack = fiber->data + fiber->frame;
stack[A] = retreg;
vm_checkgc_pcnext();
}
@ -749,9 +749,6 @@ static JanetSignal run_vm(JanetFiber *fiber, Janet in, JanetFiberStatus status)
}
Janet janet_call(JanetFunction *fun, int32_t argc, const Janet *argv) {
Janet ret;
Janet *old_return_reg = janet_vm_return_reg;
/* Check entry conditions */
if (!janet_vm_fiber)
janet_panic("janet_call failed because there is no current fiber");
@ -768,7 +765,6 @@ Janet janet_call(JanetFunction *fun, int32_t argc, const Janet *argv) {
/* Set up */
int32_t oldn = janet_vm_stackn++;
int handle = janet_gclock();
janet_vm_return_reg = &ret;
/* Run vm */
JanetSignal signal = run_vm(janet_vm_fiber,
@ -776,13 +772,12 @@ Janet janet_call(JanetFunction *fun, int32_t argc, const Janet *argv) {
JANET_STATUS_ALIVE);
/* Teardown */
janet_vm_return_reg = old_return_reg;
janet_vm_stackn = oldn;
janet_gcunlock(handle);
if (signal != JANET_SIGNAL_OK) janet_panicv(ret);
if (signal != JANET_SIGNAL_OK) janet_panicv(*janet_vm_return_reg);
return ret;
return *janet_vm_return_reg;
}
/* Enter the main vm loop */

View File

@ -351,6 +351,12 @@
(def t (put @{} :hi 1))
(assert (deep= t @{:hi 1}) "regression #24")
# Peg swallowing errors
(assert (try (peg/match ~(/ '1 ,(fn [x] (nil x))) "x") ([err] err))
"errors should not be swallowed")
(assert (try ((fn [x] (nil x))) ([err] err))
"errors should not be swallowed 2")
# Tuple types
(assert (= (tuple/type '(1 2 3)) :parens) "normal tuple")