From 7af88962eea41fd25b483f1e4ef750bfd8a999e8 Mon Sep 17 00:00:00 2001 From: Stephen Dolan Date: Fri, 21 Jun 2013 12:06:28 +0100 Subject: [PATCH] Move cfunction invocation code to the interpreter loop. --- builtin.c | 18 +----------------- builtin.h | 3 --- bytecode.h | 2 +- execute.c | 24 ++++++++++++++++++++---- 4 files changed, 22 insertions(+), 25 deletions(-) diff --git a/builtin.c b/builtin.c index a2adb1ac..bfad155d 100644 --- a/builtin.c +++ b/builtin.c @@ -3,29 +3,13 @@ #include "builtin.h" #include "compile.h" #include "jq_parser.h" +#include "bytecode.h" #include "locfile.h" #include "jv_aux.h" #include "jv_file.h" #include "jv_unicode.h" - -typedef jv (*func_1)(jv); -typedef jv (*func_2)(jv,jv); -typedef jv (*func_3)(jv,jv,jv); -typedef jv (*func_4)(jv,jv,jv,jv); -typedef jv (*func_5)(jv,jv,jv,jv,jv); -jv cfunction_invoke(struct cfunction* function, jv input[]) { - switch (function->nargs) { - case 1: return ((func_1)function->fptr)(input[0]); - case 2: return ((func_2)function->fptr)(input[0], input[1]); - case 3: return ((func_3)function->fptr)(input[0], input[1], input[2]); - case 4: return ((func_4)function->fptr)(input[0], input[1], input[2], input[3]); - case 5: return ((func_5)function->fptr)(input[0], input[1], input[2], input[3], input[4]); - default: return jv_invalid_with_msg(jv_string("Function takes too many arguments")); - } -} - static jv type_error(jv bad, const char* msg) { jv err = jv_invalid_with_msg(jv_string_fmt("%s %s", jv_kind_name(jv_get_kind(bad)), diff --git a/builtin.h b/builtin.h index 63562635..1aab133f 100644 --- a/builtin.h +++ b/builtin.h @@ -6,7 +6,4 @@ int builtins_bind(block*); -jv cfunction_invoke(struct cfunction* function, jv input[]); - - #endif diff --git a/bytecode.h b/bytecode.h index ba5fec3a..b81e1478 100644 --- a/bytecode.h +++ b/bytecode.h @@ -42,7 +42,7 @@ const struct opcode_description* opcode_describe(opcode op); #define MAX_CFUNCTION_ARGS 10 -typedef void (*cfunction_ptr)(void); +typedef void (*cfunction_ptr)(); struct cfunction { cfunction_ptr fptr; const char* name; diff --git a/execute.c b/execute.c index b43ad26a..ad7419b2 100644 --- a/execute.c +++ b/execute.c @@ -241,6 +241,8 @@ static void jq_reset(jq_state *jq) { } + + void print_error(jv value) { assert(!jv_is_valid(value)); jv msg = jv_invalid_get_msg(value); @@ -601,12 +603,26 @@ jv jq_next(jq_state *jq) { case CALL_BUILTIN: { int nargs = *pc++; jv top = stack_pop(jq); - cfunc_input[0] = top; + jv* in = cfunc_input; + in[0] = top; for (int i = 1; i < nargs; i++) { - cfunc_input[i] = stack_pop(jq); + in[i] = stack_pop(jq); } - struct cfunction* func = &frame_current(jq)->bc->globals->cfunctions[*pc++]; - top = cfunction_invoke(func, cfunc_input); + struct cfunction* function = &frame_current(jq)->bc->globals->cfunctions[*pc++]; + typedef jv (*func_1)(jv); + typedef jv (*func_2)(jv,jv); + typedef jv (*func_3)(jv,jv,jv); + typedef jv (*func_4)(jv,jv,jv,jv); + typedef jv (*func_5)(jv,jv,jv,jv,jv); + switch (function->nargs) { + case 1: top = ((func_1)function->fptr)(in[0]); break; + case 2: top = ((func_2)function->fptr)(in[0], in[1]); break; + case 3: top = ((func_3)function->fptr)(in[0], in[1], in[2]); break; + case 4: top = ((func_4)function->fptr)(in[0], in[1], in[2], in[3]); break; + case 5: top = ((func_5)function->fptr)(in[0], in[1], in[2], in[3], in[4]); break; + default: return jv_invalid_with_msg(jv_string("Function takes too many arguments")); + } + if (jv_is_valid(top)) { stack_push(jq, top); } else {