summaryrefslogtreecommitdiffstats
path: root/execute.c
diff options
context:
space:
mode:
Diffstat (limited to 'execute.c')
-rw-r--r--execute.c101
1 files changed, 71 insertions, 30 deletions
diff --git a/execute.c b/execute.c
index bbf94e5a..3be4abe0 100644
--- a/execute.c
+++ b/execute.c
@@ -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);
}