mirror of
https://github.com/janet-lang/janet
synced 2024-11-05 00:06:16 +00:00
Fix error behavior when calling functions with incorrect arities.
This commit is contained in:
parent
8dde89126e
commit
6b4824c2ab
@ -50,8 +50,7 @@ static JanetFiber *make_fiber(int32_t capacity) {
|
|||||||
/* Initialize a new fiber */
|
/* Initialize a new fiber */
|
||||||
JanetFiber *janet_fiber(JanetFunction *callee, int32_t capacity) {
|
JanetFiber *janet_fiber(JanetFunction *callee, int32_t capacity) {
|
||||||
JanetFiber *fiber = make_fiber(capacity);
|
JanetFiber *fiber = make_fiber(capacity);
|
||||||
if (janet_fiber_funcframe(fiber, callee))
|
if (janet_fiber_funcframe(fiber, callee)) return NULL;
|
||||||
janet_fiber_set_status(fiber, JANET_STATUS_ERROR);
|
|
||||||
return fiber;
|
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));
|
memcpy(fiber->data + fiber->stacktop, argv, argn * sizeof(Janet));
|
||||||
fiber->stacktop = newstacktop;
|
fiber->stacktop = newstacktop;
|
||||||
if (janet_fiber_funcframe(fiber, callee))
|
if (janet_fiber_funcframe(fiber, callee)) return NULL;
|
||||||
janet_fiber_set_status(fiber, JANET_STATUS_ERROR);
|
|
||||||
return fiber;
|
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 nextstacktop = nextframe + func->def->slotcount + JANET_FRAME_SIZE;
|
||||||
int32_t next_arity = fiber->stacktop - fiber->stackstart;
|
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) {
|
if (fiber->capacity < nextstacktop) {
|
||||||
janet_fiber_setcapacity(fiber, 2 * 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 */
|
/* Good return */
|
||||||
return 0;
|
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 next_arity = fiber->stacktop - fiber->stackstart;
|
||||||
int32_t stacksize;
|
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) {
|
if (fiber->capacity < nextstacktop) {
|
||||||
janet_fiber_setcapacity(fiber, 2 * 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)->pc = func->def->bytecode;
|
||||||
janet_fiber_frame(fiber)->flags |= JANET_STACKFRAME_TAILCALL;
|
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 */
|
/* Good return */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -988,6 +988,10 @@ JanetSignal janet_call(
|
|||||||
JanetFiber **f) {
|
JanetFiber **f) {
|
||||||
JanetFiber *fiber = janet_fiber_n(fun, 64, argv, argn);
|
JanetFiber *fiber = janet_fiber_n(fun, 64, argv, argn);
|
||||||
if (f) *f = fiber;
|
if (f) *f = fiber;
|
||||||
|
if (!fiber) {
|
||||||
|
*out = janet_cstringv("arity mismatch");
|
||||||
|
return JANET_SIGNAL_ERROR;
|
||||||
|
}
|
||||||
return janet_continue(fiber, janet_wrap_nil(), out);
|
return janet_continue(fiber, janet_wrap_nil(), out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,4 +70,8 @@
|
|||||||
(= (get res 3) 4)
|
(= (get res 3) 4)
|
||||||
(= (get res 5) 6)) "loop :pairs")
|
(= (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)
|
(end-suite)
|
||||||
|
Loading…
Reference in New Issue
Block a user