"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "execute.c" between
jq-1.5.tar.gz and jq-1.6.tar.gz

About: jq is a lightweight and flexible command-line JSON processor.

execute.c  (jq-1.5):execute.c  (jq-1.6)
skipping to change at line 43 skipping to change at line 43
stack_ptr stk_top; stack_ptr stk_top;
stack_ptr fork_top; stack_ptr fork_top;
jv path; jv path;
jv value_at_path; jv value_at_path;
int subexp_nest; int subexp_nest;
int debug_trace_enabled; int debug_trace_enabled;
int initial_execution; int initial_execution;
unsigned next_label; unsigned next_label;
int halted;
jv exit_code;
jv error_message;
jv attrs; jv attrs;
jq_input_cb input_cb; jq_input_cb input_cb;
void *input_cb_data; void *input_cb_data;
jq_msg_cb debug_cb; jq_msg_cb debug_cb;
void *debug_cb_data; void *debug_cb_data;
}; };
struct closure { struct closure {
struct bytecode* bc; // jq bytecode struct bytecode* bc; // jq bytecode
stack_ptr env; // jq stack address of closed frame stack_ptr env; // jq stack address of closed frame
skipping to change at line 67 skipping to change at line 71
struct closure closure; struct closure closure;
jv localvar; jv localvar;
}; };
// jq function call frame // jq function call frame
struct frame { struct frame {
struct bytecode* bc; // jq bytecode for callee struct bytecode* bc; // jq bytecode for callee
stack_ptr env; // jq stack address of frame to return to stack_ptr env; // jq stack address of frame to return to
stack_ptr retdata; // jq stack address to unwind to on RET stack_ptr retdata; // jq stack address to unwind to on RET
uint16_t* retaddr; // jq bytecode return address uint16_t* retaddr; // jq bytecode return address
union frame_entry entries[0]; // nclosures + nlocals union frame_entry entries[]; // nclosures + nlocals
}; };
static int frame_size(struct bytecode* bc) { static int frame_size(struct bytecode* bc) {
return sizeof(struct frame) + sizeof(union frame_entry) * (bc->nclosures + bc- >nlocals); return sizeof(struct frame) + sizeof(union frame_entry) * (bc->nclosures + bc- >nlocals);
} }
static struct frame* frame_current(struct jq_state* jq) { static struct frame* frame_current(struct jq_state* jq) {
struct frame* fp = stack_block(&jq->stk, jq->curr_frame); struct frame* fp = stack_block(&jq->stk, jq->curr_frame);
stack_ptr next = *stack_block_next(&jq->stk, jq->curr_frame); stack_ptr next = *stack_block_next(&jq->stk, jq->curr_frame);
skipping to change at line 244 skipping to change at line 248
int n2 = jv_array_length(jv_copy(jq->path)); int n2 = jv_array_length(jv_copy(jq->path));
assert(n2 == n1 + 1); assert(n2 == n1 + 1);
jv_free(jq->value_at_path); jv_free(jq->value_at_path);
jq->value_at_path = value_at_path; jq->value_at_path = value_at_path;
} else { } else {
jv_free(component); jv_free(component);
jv_free(value_at_path); jv_free(value_at_path);
} }
} }
/* For f_getpath() */
jv
_jq_path_append(jq_state *jq, jv v, jv p, jv value_at_path) {
if (jq->subexp_nest != 0 ||
jv_get_kind(jq->path) != JV_KIND_ARRAY ||
!jv_is_valid(value_at_path)) {
jv_free(v);
jv_free(p);
return value_at_path;
}
if (!jv_identical(v, jv_copy(jq->value_at_path))) {
jv_free(p);
return value_at_path;
}
if (jv_get_kind(p) == JV_KIND_ARRAY)
jq->path = jv_array_concat(jq->path, p);
else
jq->path = jv_array_append(jq->path, p);
jv_free(jq->value_at_path);
return jv_copy(jq->value_at_path = value_at_path);
}
uint16_t* stack_restore(jq_state *jq){ uint16_t* stack_restore(jq_state *jq){
while (!stack_pop_will_free(&jq->stk, jq->fork_top)) { while (!stack_pop_will_free(&jq->stk, jq->fork_top)) {
if (stack_pop_will_free(&jq->stk, jq->stk_top)) { if (stack_pop_will_free(&jq->stk, jq->stk_top)) {
jv_free(stack_pop(jq)); jv_free(stack_pop(jq));
} else if (stack_pop_will_free(&jq->stk, jq->curr_frame)) { } else if (stack_pop_will_free(&jq->stk, jq->curr_frame)) {
frame_pop(jq); frame_pop(jq);
} else { } else {
assert(0); assert(0);
} }
} }
skipping to change at line 287 skipping to change at line 313
static void jq_reset(jq_state *jq) { static void jq_reset(jq_state *jq) {
while (stack_restore(jq)) {} while (stack_restore(jq)) {}
assert(jq->stk_top == 0); assert(jq->stk_top == 0);
assert(jq->fork_top == 0); assert(jq->fork_top == 0);
assert(jq->curr_frame == 0); assert(jq->curr_frame == 0);
stack_reset(&jq->stk); stack_reset(&jq->stk);
jv_free(jq->error); jv_free(jq->error);
jq->error = jv_null(); jq->error = jv_null();
jq->halted = 0;
jv_free(jq->exit_code);
jv_free(jq->error_message);
if (jv_get_kind(jq->path) != JV_KIND_INVALID) if (jv_get_kind(jq->path) != JV_KIND_INVALID)
jv_free(jq->path); jv_free(jq->path);
jq->path = jv_null(); jq->path = jv_null();
jv_free(jq->value_at_path); jv_free(jq->value_at_path);
jq->value_at_path = jv_null(); jq->value_at_path = jv_null();
jq->subexp_nest = 0; jq->subexp_nest = 0;
} }
void jq_report_error(jq_state *jq, jv value) { void jq_report_error(jq_state *jq, jv value) {
assert(jq->err_cb); assert(jq->err_cb);
skipping to change at line 322 skipping to change at line 351
jv_nomem_handler(jq->nomem_handler, jq->nomem_handler_data); jv_nomem_handler(jq->nomem_handler, jq->nomem_handler_data);
uint16_t* pc = stack_restore(jq); uint16_t* pc = stack_restore(jq);
assert(pc); assert(pc);
int raising; int raising;
int backtracking = !jq->initial_execution; int backtracking = !jq->initial_execution;
jq->initial_execution = 0; jq->initial_execution = 0;
assert(jv_get_kind(jq->error) == JV_KIND_NULL); assert(jv_get_kind(jq->error) == JV_KIND_NULL);
while (1) { while (1) {
if (jq->halted) {
if (jq->debug_trace_enabled)
printf("\t<halted>\n");
return jv_invalid();
}
uint16_t opcode = *pc; uint16_t opcode = *pc;
raising = 0; raising = 0;
if (jq->debug_trace_enabled) { if (jq->debug_trace_enabled) {
dump_operation(frame_current(jq)->bc, pc); dump_operation(frame_current(jq)->bc, pc);
printf("\t"); printf("\t");
const struct opcode_description* opdesc = opcode_describe(opcode); const struct opcode_description* opdesc = opcode_describe(opcode);
stack_ptr param = 0; stack_ptr param = 0;
if (!backtracking) { if (!backtracking) {
int stack_in = opdesc->stack_in; int stack_in = opdesc->stack_in;
if (stack_in == -1) stack_in = pc[1]; if (stack_in == -1) stack_in = pc[1];
param = jq->stk_top;
for (int i=0; i<stack_in; i++) { for (int i=0; i<stack_in; i++) {
if (i == 0) { if (i != 0) {
param = jq->stk_top;
} else {
printf(" | "); printf(" | ");
param = *stack_block_next(&jq->stk, param); param = *stack_block_next(&jq->stk, param);
} }
if (!param) break; if (!param) break;
jv_dump(jv_copy(*(jv*)stack_block(&jq->stk, param)), JV_PRINT_REFCOUNT ); jv_dump(jv_copy(*(jv*)stack_block(&jq->stk, param)), JV_PRINT_REFCOUNT );
//printf("<%d>", jv_get_refcnt(param->val)); //printf("<%d>", jv_get_refcnt(param->val));
//printf(" -- "); //printf(" -- ");
//jv_dump(jv_copy(jq->path), 0); //jv_dump(jv_copy(jq->path), 0);
} }
if (jq->debug_trace_enabled & JQ_DEBUG_TRACE_DETAIL) {
while ((param = *stack_block_next(&jq->stk, param))) {
printf(" || ");
jv_dump(jv_copy(*(jv*)stack_block(&jq->stk, param)), JV_PRINT_REFCOU
NT);
}
}
} else { } else {
printf("\t<backtracking>"); printf("\t<backtracking>");
} }
printf("\n"); printf("\n");
} }
if (backtracking) { if (backtracking) {
opcode = ON_BACKTRACK(opcode); opcode = ON_BACKTRACK(opcode);
backtracking = 0; backtracking = 0;
skipping to change at line 419 skipping to change at line 458
case SUBEXP_END: { case SUBEXP_END: {
assert(jq->subexp_nest > 0); assert(jq->subexp_nest > 0);
jq->subexp_nest--; jq->subexp_nest--;
jv a = stack_pop(jq); jv a = stack_pop(jq);
jv b = stack_pop(jq); jv b = stack_pop(jq);
stack_push(jq, a); stack_push(jq, a);
stack_push(jq, b); stack_push(jq, b);
break; break;
} }
case PUSHK_UNDER: {
jv v = jv_array_get(jv_copy(frame_current(jq)->bc->constants), *pc++);
assert(jv_is_valid(v));
jv v2 = stack_pop(jq);
stack_push(jq, v);
stack_push(jq, v2);
break;
}
case POP: { case POP: {
jv_free(stack_pop(jq)); jv_free(stack_pop(jq));
break; break;
} }
case APPEND: { case APPEND: {
jv v = stack_pop(jq); jv v = stack_pop(jq);
uint16_t level = *pc++; uint16_t level = *pc++;
uint16_t vidx = *pc++; uint16_t vidx = *pc++;
jv* var = frame_local_var(jq, vidx, level); jv* var = frame_local_var(jq, vidx, level);
skipping to change at line 516 skipping to change at line 564
printf("V%d = ", v); printf("V%d = ", v);
jv_dump(jv_copy(*var), 0); jv_dump(jv_copy(*var), 0);
printf(" (%d)\n", jv_get_refcnt(*var)); printf(" (%d)\n", jv_get_refcnt(*var));
} }
jv_free(stack_popn(jq)); jv_free(stack_popn(jq));
stack_push(jq, *var); stack_push(jq, *var);
*var = jv_null(); *var = jv_null();
break; break;
} }
case STOREVN:
stack_save(jq, pc - 1, stack_get_pos(jq));
case STOREV: { case STOREV: {
uint16_t level = *pc++; uint16_t level = *pc++;
uint16_t v = *pc++; uint16_t v = *pc++;
jv* var = frame_local_var(jq, v, level); jv* var = frame_local_var(jq, v, level);
jv val = stack_pop(jq); jv val = stack_pop(jq);
if (jq->debug_trace_enabled) { if (jq->debug_trace_enabled) {
printf("V%d = ", v); printf("V%d = ", v);
jv_dump(jv_copy(val), 0); jv_dump(jv_copy(val), 0);
printf(" (%d)\n", jv_get_refcnt(val)); printf(" (%d)\n", jv_get_refcnt(val));
} }
jv_free(*var); jv_free(*var);
*var = val; *var = val;
break; break;
} }
case ON_BACKTRACK(STOREVN): {
uint16_t level = *pc++;
uint16_t v = *pc++;
jv* var = frame_local_var(jq, v, level);
jv_free(*var);
*var = jv_null();
goto do_backtrack;
break;
}
case STORE_GLOBAL: { case STORE_GLOBAL: {
// Get the constant // Get the constant
jv val = jv_array_get(jv_copy(frame_current(jq)->bc->constants), *pc++); jv val = jv_array_get(jv_copy(frame_current(jq)->bc->constants), *pc++);
assert(jv_is_valid(val)); assert(jv_is_valid(val));
// Store the var // Store the var
uint16_t level = *pc++; uint16_t level = *pc++;
uint16_t v = *pc++; uint16_t v = *pc++;
jv* var = frame_local_var(jq, v, level); jv* var = frame_local_var(jq, v, level);
if (jq->debug_trace_enabled) { if (jq->debug_trace_enabled) {
skipping to change at line 740 skipping to change at line 800
jq->error = jv_null(); jq->error = jv_null();
return error; return error;
} }
return jv_invalid(); return jv_invalid();
} }
backtracking = 1; backtracking = 1;
break; break;
} }
case FORK_OPT: case FORK_OPT:
case DESTRUCTURE_ALT:
case FORK: { case FORK: {
stack_save(jq, pc - 1, stack_get_pos(jq)); stack_save(jq, pc - 1, stack_get_pos(jq));
pc++; // skip offset this time pc++; // skip offset this time
break; break;
} }
case ON_BACKTRACK(FORK_OPT): { case ON_BACKTRACK(FORK_OPT):
case ON_BACKTRACK(DESTRUCTURE_ALT): {
if (jv_is_valid(jq->error)) { if (jv_is_valid(jq->error)) {
// `try EXP ...` backtracked here (no value, `empty`), so we backtrack m ore // `try EXP ...` backtracked here (no value, `empty`), so we backtrack m ore
jv_free(stack_pop(jq)); jv_free(stack_pop(jq));
goto do_backtrack; goto do_backtrack;
} }
// `try EXP ...` exception caught in EXP // `try EXP ...` exception caught in EXP
jv_free(stack_pop(jq)); // free the input // DESTRUCTURE_ALT doesn't want the error message on the stack,
stack_push(jq, jv_invalid_get_msg(jq->error)); // push the error's messag // as we would just want to throw it away anyway.
e if (opcode != ON_BACKTRACK(DESTRUCTURE_ALT)) {
jv_free(stack_pop(jq)); // free the input
stack_push(jq, jv_invalid_get_msg(jq->error)); // push the error's mess
age
} else {
jv_free(jq->error);
}
jq->error = jv_null(); jq->error = jv_null();
uint16_t offset = *pc++; uint16_t offset = *pc++;
pc += offset; pc += offset;
break; break;
} }
case ON_BACKTRACK(FORK): { case ON_BACKTRACK(FORK): {
if (raising) goto do_backtrack; if (raising) goto do_backtrack;
uint16_t offset = *pc++; uint16_t offset = *pc++;
pc += offset; pc += offset;
break; break;
skipping to change at line 933 skipping to change at line 1001
jq->bc = 0; jq->bc = 0;
jq->next_label = 0; jq->next_label = 0;
stack_init(&jq->stk); stack_init(&jq->stk);
jq->stk_top = 0; jq->stk_top = 0;
jq->fork_top = 0; jq->fork_top = 0;
jq->curr_frame = 0; jq->curr_frame = 0;
jq->error = jv_null(); jq->error = jv_null();
jq->halted = 0;
jq->exit_code = jv_invalid();
jq->error_message = jv_invalid();
jq->err_cb = default_err_cb; jq->err_cb = default_err_cb;
jq->err_cb_data = stderr; jq->err_cb_data = stderr;
jq->attrs = jv_object(); jq->attrs = jv_object();
jq->path = jv_null(); jq->path = jv_null();
jq->value_at_path = jv_null(); jq->value_at_path = jv_null();
return jq; return jq;
} }
void jq_set_error_cb(jq_state *jq, jq_msg_cb cb, void *data) { void jq_set_error_cb(jq_state *jq, jq_msg_cb cb, void *data) {
skipping to change at line 974 skipping to change at line 1046
jv_nomem_handler(jq->nomem_handler, jq->nomem_handler_data); jv_nomem_handler(jq->nomem_handler, jq->nomem_handler_data);
jq_reset(jq); jq_reset(jq);
struct closure top = {jq->bc, -1}; struct closure top = {jq->bc, -1};
struct frame* top_frame = frame_push(jq, top, 0, 0); struct frame* top_frame = frame_push(jq, top, 0, 0);
top_frame->retdata = 0; top_frame->retdata = 0;
top_frame->retaddr = 0; top_frame->retaddr = 0;
stack_push(jq, input); stack_push(jq, input);
stack_save(jq, jq->bc->code, stack_get_pos(jq)); stack_save(jq, jq->bc->code, stack_get_pos(jq));
if (flags & JQ_DEBUG_TRACE) { jq->debug_trace_enabled = flags & JQ_DEBUG_TRACE_ALL;
jq->debug_trace_enabled = 1;
} else {
jq->debug_trace_enabled = 0;
}
jq->initial_execution = 1; jq->initial_execution = 1;
} }
void jq_teardown(jq_state **jq) { void jq_teardown(jq_state **jq) {
jq_state *old_jq = *jq; jq_state *old_jq = *jq;
if (old_jq == NULL) if (old_jq == NULL)
return; return;
*jq = NULL; *jq = NULL;
jq_reset(old_jq); jq_reset(old_jq);
skipping to change at line 1066 skipping to change at line 1134
return bc; return bc;
} }
static struct bytecode *optimize(struct bytecode *bc) { static struct bytecode *optimize(struct bytecode *bc) {
for (int i=0; i<bc->nsubfunctions; i++) { for (int i=0; i<bc->nsubfunctions; i++) {
bc->subfunctions[i] = optimize(bc->subfunctions[i]); bc->subfunctions[i] = optimize(bc->subfunctions[i]);
} }
return optimize_code(bc); return optimize_code(bc);
} }
static jv
args2obj(jv args)
{
if (jv_get_kind(args) == JV_KIND_OBJECT)
return args;
assert(jv_get_kind(args) == JV_KIND_ARRAY);
jv r = jv_object();
jv kk = jv_string("name");
jv vk = jv_string("value");
jv_array_foreach(args, i, v)
r = jv_object_set(r, jv_object_get(jv_copy(v), kk), jv_object_get(v, vk));
jv_free(args);
jv_free(kk);
jv_free(vk);
return r;
}
int jq_compile_args(jq_state *jq, 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); jv_nomem_handler(jq->nomem_handler, jq->nomem_handler_data);
assert(jv_get_kind(args) == JV_KIND_ARRAY); assert(jv_get_kind(args) == JV_KIND_ARRAY || jv_get_kind(args) == JV_KIND_OBJE CT);
struct locfile* locations; struct locfile* locations;
locations = locfile_init(jq, "<top-level>", str, strlen(str)); locations = locfile_init(jq, "<top-level>", str, strlen(str));
block program; block program;
jq_reset(jq); jq_reset(jq);
if (jq->bc) { if (jq->bc) {
bytecode_free(jq->bc); bytecode_free(jq->bc);
jq->bc = 0; jq->bc = 0;
} }
int nerrors = load_program(jq, locations, &program); int nerrors = load_program(jq, locations, &program);
if (nerrors == 0) { if (nerrors == 0) {
jv_array_foreach(args, i, arg) {
jv name = jv_object_get(jv_copy(arg), jv_string("name"));
jv value = jv_object_get(arg, jv_string("value"));
program = gen_var_binding(gen_const(value), jv_string_value(name), program
);
jv_free(name);
}
nerrors = builtins_bind(jq, &program); nerrors = builtins_bind(jq, &program);
if (nerrors == 0) { if (nerrors == 0) {
nerrors = block_compile(program, &jq->bc, locations); nerrors = block_compile(program, &jq->bc, locations, args = args2obj(args) );
} }
} } else
jv_free(args);
if (nerrors) if (nerrors)
jq_report_error(jq, jv_string_fmt("jq: %d compile %s", nerrors, nerrors > 1 ? "errors" : "error")); jq_report_error(jq, jv_string_fmt("jq: %d compile %s", nerrors, nerrors > 1 ? "errors" : "error"));
if (jq->bc) if (jq->bc)
jq->bc = optimize(jq->bc); jq->bc = optimize(jq->bc);
jv_free(args);
locfile_free(locations); locfile_free(locations);
return jq->bc != NULL; return jq->bc != NULL;
} }
int jq_compile(jq_state *jq, const char* str) { int jq_compile(jq_state *jq, const char* str) {
return jq_compile_args(jq, str, jv_array()); return jq_compile_args(jq, str, jv_object());
} }
jv jq_get_jq_origin(jq_state *jq) { jv jq_get_jq_origin(jq_state *jq) {
return jq_get_attr(jq, jv_string("JQ_ORIGIN")); return jq_get_attr(jq, jv_string("JQ_ORIGIN"));
} }
jv jq_get_prog_origin(jq_state *jq) { jv jq_get_prog_origin(jq_state *jq) {
return jq_get_attr(jq, jv_string("PROGRAM_ORIGIN")); return jq_get_attr(jq, jv_string("PROGRAM_ORIGIN"));
} }
skipping to change at line 1153 skipping to change at line 1231
void jq_set_debug_cb(jq_state *jq, jq_msg_cb cb, void *data) { void jq_set_debug_cb(jq_state *jq, jq_msg_cb cb, void *data) {
jq->debug_cb = cb; jq->debug_cb = cb;
jq->debug_cb_data = data; jq->debug_cb_data = data;
} }
void jq_get_debug_cb(jq_state *jq, jq_msg_cb *cb, void **data) { void jq_get_debug_cb(jq_state *jq, jq_msg_cb *cb, void **data) {
*cb = jq->debug_cb; *cb = jq->debug_cb;
*data = jq->debug_cb_data; *data = jq->debug_cb_data;
} }
void
jq_halt(jq_state *jq, jv exit_code, jv error_message)
{
assert(!jq->halted);
jq->halted = 1;
jq->exit_code = exit_code;
jq->error_message = error_message;
}
int
jq_halted(jq_state *jq)
{
return jq->halted;
}
jv jq_get_exit_code(jq_state *jq)
{
return jv_copy(jq->exit_code);
}
jv jq_get_error_message(jq_state *jq)
{
return jv_copy(jq->error_message);
}
 End of changes. 24 change blocks. 
26 lines changed or deleted 104 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)