diff options
Diffstat (limited to 'execute.c')
-rw-r--r-- | execute.c | 101 |
1 files changed, 71 insertions, 30 deletions
@@ -18,6 +18,10 @@ #include "builtin.h" struct jq_state { + void (*nomem_handler)(void *); + void *nomem_handler_data; + struct bytecode* bc; + struct stack stk; stack_ptr curr_frame; stack_ptr stk_top; @@ -223,6 +227,19 @@ uint16_t* stack_restore(jq_state *jq){ return retaddr; } +static void jq_reset(jq_state *jq) { + while (stack_restore(jq)) {} + + assert(jq->stk_top == 0); + assert(jq->fork_top == 0); + assert(jq->curr_frame == 0); + stack_reset(&jq->stk); + + if (jv_get_kind(jq->path) != JV_KIND_INVALID) + jv_free(jq->path); + jq->path = jv_null(); +} + void print_error(jv value) { assert(!jv_is_valid(value)); @@ -237,6 +254,8 @@ void print_error(jv value) { 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); assert(pc); @@ -636,31 +655,48 @@ jv jq_next(jq_state *jq) { } } +jq_state *jq_init(void) { + jq_state *jq; + jq = jv_mem_alloc_unguarded(sizeof(*jq)); + if (jq == NULL) + return NULL; + memset(jq, 0, sizeof(*jq)); + jq->debug_trace_enabled = 0; + jq->initial_execution = 1; + + stack_init(&jq->stk); + jq->stk_top = 0; + jq->fork_top = 0; + jq->curr_frame = 0; + + jq->path = jv_null(); + return jq; +} -void jq_init(struct bytecode* bc, jv input, jq_state **jq, int flags) { - jq_state *new_jq; - new_jq = jv_mem_alloc(sizeof(*new_jq)); - memset(new_jq, 0, sizeof(*new_jq)); - new_jq->path = jv_null(); - stack_init(&new_jq->stk); - new_jq->stk_top = 0; - new_jq->fork_top = 0; - new_jq->curr_frame = 0; +void jq_set_nomem_handler(jq_state *jq, void (*nomem_handler)(void *), void *data) { + jv_nomem_handler(nomem_handler, data); + jq->nomem_handler = nomem_handler; + jq->nomem_handler_data = data; +} + + +void jq_start(jq_state *jq, jv input, int flags) { + jv_nomem_handler(jq->nomem_handler, jq->nomem_handler_data); + jq_reset(jq); - struct closure top = {bc, -1}; - struct frame* top_frame = frame_push(new_jq, top, 0, 0); + struct closure top = {jq->bc, -1}; + struct frame* top_frame = frame_push(jq, top, 0, 0); top_frame->retdata = 0; top_frame->retaddr = 0; - stack_push(new_jq, input); - stack_save(new_jq, bc->code, stack_get_pos(new_jq)); + stack_push(jq, input); + stack_save(jq, jq->bc->code, stack_get_pos(jq)); if (flags & JQ_DEBUG_TRACE) { - new_jq->debug_trace_enabled = 1; + jq->debug_trace_enabled = 1; } else { - new_jq->debug_trace_enabled = 0; + jq->debug_trace_enabled = 0; } - new_jq->initial_execution = 1; - *jq = new_jq; + jq->initial_execution = 1; } void jq_teardown(jq_state **jq) { @@ -669,23 +705,24 @@ void jq_teardown(jq_state **jq) { return; *jq = NULL; - while (stack_restore(old_jq)) {} - - assert(old_jq->stk_top == 0); - assert(old_jq->fork_top == 0); - assert(old_jq->curr_frame == 0); - stack_free(&old_jq->stk); + jq_reset(old_jq); + bytecode_free(old_jq->bc); + old_jq->bc = 0; - jv_free(old_jq->path); jv_mem_free(old_jq); } -struct bytecode* jq_compile_args(const char* str, jv args) { +int jq_compile_args(jq_state *jq, const char* str, jv args) { + jv_nomem_handler(jq->nomem_handler, jq->nomem_handler_data); assert(jv_get_kind(args) == JV_KIND_ARRAY); struct locfile locations; locfile_init(&locations, str, strlen(str)); block program; - struct bytecode* bc = 0; + jq_reset(jq); + if (jq->bc) { + bytecode_free(jq->bc); + jq->bc = 0; + } int nerrors = jq_parse(&locations, &program); if (nerrors == 0) { for (int i=0; i<jv_array_length(jv_copy(args)); i++) { @@ -698,16 +735,20 @@ struct bytecode* jq_compile_args(const char* str, jv args) { jv_free(args); nerrors = builtins_bind(&program); if (nerrors == 0) { - nerrors = block_compile(program, &locations, &bc); + nerrors = block_compile(program, &locations, &jq->bc); } } if (nerrors) { fprintf(stderr, "%d compile %s\n", nerrors, nerrors > 1 ? "errors" : "error"); } locfile_free(&locations); - return bc; + return jq->bc != NULL; +} + +int jq_compile(jq_state *jq, const char* str) { + return jq_compile_args(jq, str, jv_array()); } -struct bytecode* jq_compile(const char* str) { - return jq_compile_args(str, jv_array()); +void jq_dump_disassembly(jq_state *jq, int indent) { + dump_disassembly(indent, jq->bc); } |