From 6b4824c2ab04fdd177da88d419fced2efb8dbd1e Mon Sep 17 00:00:00 2001 From: Calvin Rose Date: Sun, 30 Dec 2018 18:41:44 -0500 Subject: [PATCH] Fix error behavior when calling functions with incorrect arities. --- src/core/fiber.c | 34 ++++++++++++++++------------------ src/core/vm.c | 4 ++++ test/suite3.janet | 4 ++++ 3 files changed, 24 insertions(+), 18 deletions(-) diff --git a/src/core/fiber.c b/src/core/fiber.c index 0effde74..a4dc7afc 100644 --- a/src/core/fiber.c +++ b/src/core/fiber.c @@ -50,8 +50,7 @@ static JanetFiber *make_fiber(int32_t capacity) { /* Initialize a new fiber */ JanetFiber *janet_fiber(JanetFunction *callee, int32_t capacity) { JanetFiber *fiber = make_fiber(capacity); - if (janet_fiber_funcframe(fiber, callee)) - janet_fiber_set_status(fiber, JANET_STATUS_ERROR); + if (janet_fiber_funcframe(fiber, callee)) return NULL; return fiber; } @@ -65,8 +64,7 @@ JanetFiber *janet_fiber_n(JanetFunction *callee, int32_t capacity, const Janet * } memcpy(fiber->data + fiber->stacktop, argv, argn * sizeof(Janet)); fiber->stacktop = newstacktop; - if (janet_fiber_funcframe(fiber, callee)) - janet_fiber_set_status(fiber, JANET_STATUS_ERROR); + if (janet_fiber_funcframe(fiber, callee)) return NULL; return fiber; } @@ -132,6 +130,13 @@ int janet_fiber_funcframe(JanetFiber *fiber, JanetFunction *func) { int32_t nextstacktop = nextframe + func->def->slotcount + JANET_FRAME_SIZE; int32_t next_arity = fiber->stacktop - fiber->stackstart; + /* Check strict arity before messing with state */ + if (func->def->flags & JANET_FUNCDEF_FLAG_FIXARITY) { + if (func->def->arity != next_arity) { + return 1; + } + } + if (fiber->capacity < nextstacktop) { janet_fiber_setcapacity(fiber, 2 * nextstacktop); } @@ -163,13 +168,6 @@ int janet_fiber_funcframe(JanetFiber *fiber, JanetFunction *func) { } } - /* Check strict arity AFTER getting fiber to valid state. */ - if (func->def->flags & JANET_FUNCDEF_FLAG_FIXARITY) { - if (func->def->arity != next_arity) { - return 1; - } - } - /* Good return */ return 0; } @@ -198,6 +196,13 @@ int janet_fiber_funcframe_tail(JanetFiber *fiber, JanetFunction *func) { int32_t next_arity = fiber->stacktop - fiber->stackstart; int32_t stacksize; + /* Check strict arity before messing with state */ + if (func->def->flags & JANET_FUNCDEF_FLAG_FIXARITY) { + if (func->def->arity != next_arity) { + return 1; + } + } + if (fiber->capacity < nextstacktop) { janet_fiber_setcapacity(fiber, 2 * nextstacktop); } @@ -241,13 +246,6 @@ int janet_fiber_funcframe_tail(JanetFiber *fiber, JanetFunction *func) { janet_fiber_frame(fiber)->pc = func->def->bytecode; janet_fiber_frame(fiber)->flags |= JANET_STACKFRAME_TAILCALL; - /* Check strict arity AFTER getting fiber to valid state. */ - if (func->def->flags & JANET_FUNCDEF_FLAG_FIXARITY) { - if (func->def->arity != next_arity) { - return 1; - } - } - /* Good return */ return 0; } diff --git a/src/core/vm.c b/src/core/vm.c index 82407456..ec935f03 100644 --- a/src/core/vm.c +++ b/src/core/vm.c @@ -988,6 +988,10 @@ JanetSignal janet_call( JanetFiber **f) { JanetFiber *fiber = janet_fiber_n(fun, 64, argv, argn); if (f) *f = fiber; + if (!fiber) { + *out = janet_cstringv("arity mismatch"); + return JANET_SIGNAL_ERROR; + } return janet_continue(fiber, janet_wrap_nil(), out); } diff --git a/test/suite3.janet b/test/suite3.janet index 89855e66..f115f95b 100644 --- a/test/suite3.janet +++ b/test/suite3.janet @@ -70,4 +70,8 @@ (= (get res 3) 4) (= (get res 5) 6)) "loop :pairs") +# Another regression test - no segfaults +(defn afn [x] x) +(assert (= 1 (try (afn) ([err] 1))) "calling function with wrong arity does not segfault.") + (end-suite)