From 8bcdc9304ace5f2cc9bf662ab8998d75537e05f0 Mon Sep 17 00:00:00 2001 From: Emanuele Torre Date: Mon, 25 Nov 2024 18:59:08 +0100 Subject: [PATCH] jq_next: simplify CALL_BUILTIN implementation --- src/execute.c | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/src/execute.c b/src/execute.c index 6db30bc16a..356e6dfd02 100644 --- a/src/execute.c +++ b/src/execute.c @@ -341,8 +341,6 @@ static void set_error(jq_state *jq, jv value) { #define ON_BACKTRACK(op) ((op)+NUM_OPCODES) jv jq_next(jq_state *jq) { - jv cfunc_input[MAX_CFUNCTION_ARGS]; - jv_nomem_handler(jq->nomem_handler, jq->nomem_handler_data); uint16_t* pc = stack_restore(jq); @@ -909,33 +907,27 @@ jv jq_next(jq_state *jq) { case CALL_BUILTIN: { int nargs = *pc++; - jv top = stack_pop(jq); - jv* in = cfunc_input; - in[0] = top; - for (int i = 1; i < nargs; i++) { - in[i] = stack_pop(jq); - } struct cfunction* function = &frame_current(jq)->bc->globals->cfunctions[*pc++]; + jv in[MAX_CFUNCTION_ARGS]; + for (int i = 0; i < nargs; ++i) + in[i] = stack_pop(jq); + + jv top; switch (function->nargs) { case 1: top = function->fptr.a1(jq, in[0]); break; case 2: top = function->fptr.a2(jq, in[0], in[1]); break; case 3: top = function->fptr.a3(jq, in[0], in[1], in[2]); break; case 4: top = function->fptr.a4(jq, in[0], in[1], in[2], in[3]); break; - // FIXME: a) up to 7 arguments (input + 6), b) should assert - // because the compiler should not generate this error. - default: return jv_invalid_with_msg(jv_string("Function takes too many arguments")) + default: assert(0 && "Invalid number of arguments"); } - if (jv_is_valid(top)) { - stack_push(jq, top); - } else if (jv_invalid_has_msg(jv_copy(top))) { - set_error(jq, top); - goto do_backtrack; - } else { - // C-coded function returns invalid w/o msg? -> backtrack, as if - // it had returned `empty` + if (!jv_is_valid(top)) { + if (jv_invalid_has_msg(jv_copy(top))) + set_error(jq, top); goto do_backtrack; } + + stack_push(jq, top); break; }