1
0
mirror of https://github.com/janet-lang/janet synced 2024-12-24 23:40:27 +00:00

Address #1005 - Fix janet_call stack clobbering on dirty stack.

This commit is contained in:
Calvin Rose 2022-08-02 12:13:22 -05:00
parent f443a3b3a1
commit 79c375b1af
2 changed files with 22 additions and 0 deletions

View File

@ -437,6 +437,8 @@ static Janet cfun_io_print_impl_x(int32_t argc, Janet *argv, int newline,
if (newline)
janet_buffer_push_u8(buf, '\n');
Janet args[1] = { janet_wrap_buffer(buf) };
/* Disable tracing */
fun->gc.flags &= ~JANET_FUNCFLAG_TRACE;
janet_call(fun, 1, args);
return janet_wrap_nil();
}
@ -552,6 +554,8 @@ static Janet cfun_io_printf_impl_x(int32_t argc, Janet *argv, int newline,
janet_buffer_format(buf, fmt, offset, argc, argv);
if (newline) janet_buffer_push_u8(buf, '\n');
Janet args[1] = { janet_wrap_buffer(buf) };
/* Disable tracing */
fun->gc.flags &= ~JANET_FUNCFLAG_TRACE;
janet_call(fun, 1, args);
return janet_wrap_nil();
}

View File

@ -1285,6 +1285,12 @@ JanetSignal janet_step(JanetFiber *fiber, Janet in, Janet *out) {
return signal;
}
static Janet void_cfunction(int32_t argc, Janet *argv) {
(void) argc;
(void) argv;
janet_panic("placeholder");
}
Janet janet_call(JanetFunction *fun, int32_t argc, const Janet *argv) {
/* Check entry conditions */
if (!janet_vm.fiber)
@ -1292,9 +1298,17 @@ Janet janet_call(JanetFunction *fun, int32_t argc, const Janet *argv) {
if (janet_vm.stackn >= JANET_RECURSION_GUARD)
janet_panic("C stack recursed too deeply");
/* Dirty stack */
int32_t dirty_stack = janet_vm.fiber->stacktop - janet_vm.fiber->stackstart;
if (dirty_stack) {
janet_fiber_cframe(janet_vm.fiber, void_cfunction);
}
/* Tracing */
if (fun->gc.flags & JANET_FUNCFLAG_TRACE) {
janet_vm.stackn++;
vm_do_trace(fun, argc, argv);
janet_vm.stackn--;
}
/* Push frame */
@ -1322,6 +1336,10 @@ Janet janet_call(JanetFunction *fun, int32_t argc, const Janet *argv) {
/* Teardown */
janet_vm.stackn = oldn;
janet_gcunlock(handle);
if (dirty_stack) {
janet_fiber_popframe(janet_vm.fiber);
janet_vm.fiber->stacktop += dirty_stack;
}
if (signal != JANET_SIGNAL_OK) {
janet_panicv(*janet_vm.return_reg);