fixup
This commit is contained in:
1 parent
3504bd9a2a
commit
b279713e47
3 files changed
+36
-50
No files matched your search
+16
-19
@@ -1002,16 +1002,8 @@ static int count_cfunctions(block b) {
|
|||||||
extern const char **environ;
|
extern const char **environ;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static jv env = {JV_KIND_INVALID, 0, 0, 0, {0}};
|
|
||||||
|
|
||||||
static void
|
|
||||||
free_env(void)
|
|
||||||
{
|
|
||||||
jv_free(env);
|
|
||||||
}
|
|
||||||
|
|
||||||
static jv
|
static jv
|
||||||
make_env(void)
|
make_env(jv env)
|
||||||
{
|
{
|
||||||
if (jv_is_valid(env))
|
if (jv_is_valid(env))
|
||||||
return jv_copy(env);
|
return jv_copy(env);
|
||||||
@@ -1026,19 +1018,21 @@ make_env(void)
|
|||||||
else
|
else
|
||||||
r = jv_object_set(r, jv_string_sized(environ[i], eq - environ[i]), jv_string(eq + 1));
|
r = jv_object_set(r, jv_string_sized(environ[i], eq - environ[i]), jv_string(eq + 1));
|
||||||
}
|
}
|
||||||
atexit(free_env);
|
return jv_copy(r);
|
||||||
return (env = jv_copy(r));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Expands call instructions into a calling sequence
|
// Expands call instructions into a calling sequence
|
||||||
static int expand_call_arglist(block* b) {
|
static int expand_call_arglist(block* b, jv args, jv *env) {
|
||||||
int errors = 0;
|
int errors = 0;
|
||||||
block ret = gen_noop();
|
block ret = gen_noop();
|
||||||
for (inst* curr; (curr = block_take(b));) {
|
for (inst* curr; (curr = block_take(b));) {
|
||||||
if (opcode_describe(curr->op)->flags & OP_HAS_BINDING) {
|
if (opcode_describe(curr->op)->flags & OP_HAS_BINDING) {
|
||||||
if (!curr->bound_by && curr->op == LOADV && strcmp(curr->symbol, "ENV") == 0) {
|
if (!curr->bound_by && curr->op == LOADV && strcmp(curr->symbol, "ENV") == 0) {
|
||||||
curr->op = LOADK;
|
curr->op = LOADK;
|
||||||
curr->imm.constant = make_env();
|
*env = curr->imm.constant = make_env(*env);
|
||||||
|
} else if (!curr->bound_by && curr->op == LOADV && jv_object_has(jv_copy(args), jv_string(curr->symbol))) {
|
||||||
|
curr->op = LOADK;
|
||||||
|
curr->imm.constant = jv_object_get(jv_copy(args), jv_string(curr->symbol));
|
||||||
} else if (!curr->bound_by) {
|
} else if (!curr->bound_by) {
|
||||||
if (curr->symbol[0] == '*' && curr->symbol[1] >= '1' && curr->symbol[1] <= '3' && curr->symbol[2] == '\0')
|
if (curr->symbol[0] == '*' && curr->symbol[1] >= '1' && curr->symbol[1] <= '3' && curr->symbol[2] == '\0')
|
||||||
locfile_locate(curr->locfile, curr->source, "jq: error: break used outside labeled control structure");
|
locfile_locate(curr->locfile, curr->source, "jq: error: break used outside labeled control structure");
|
||||||
@@ -1096,7 +1090,7 @@ static int expand_call_arglist(block* b) {
|
|||||||
i->subfn = gen_noop();
|
i->subfn = gen_noop();
|
||||||
inst_free(i);
|
inst_free(i);
|
||||||
// arguments should be pushed in reverse order, prepend them to prelude
|
// arguments should be pushed in reverse order, prepend them to prelude
|
||||||
errors += expand_call_arglist(&body);
|
errors += expand_call_arglist(&body, args, env);
|
||||||
prelude = BLOCK(gen_subexp(body), prelude);
|
prelude = BLOCK(gen_subexp(body), prelude);
|
||||||
actual_args++;
|
actual_args++;
|
||||||
}
|
}
|
||||||
@@ -1118,12 +1112,12 @@ static int expand_call_arglist(block* b) {
|
|||||||
return errors;
|
return errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int compile(struct bytecode* bc, block b, struct locfile* lf) {
|
static int compile(struct bytecode* bc, block b, struct locfile* lf, jv args, jv *env) {
|
||||||
int errors = 0;
|
int errors = 0;
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
int var_frame_idx = 0;
|
int var_frame_idx = 0;
|
||||||
bc->nsubfunctions = 0;
|
bc->nsubfunctions = 0;
|
||||||
errors += expand_call_arglist(&b);
|
errors += expand_call_arglist(&b, args, env);
|
||||||
b = BLOCK(b, gen_op_simple(RET));
|
b = BLOCK(b, gen_op_simple(RET));
|
||||||
jv localnames = jv_array();
|
jv localnames = jv_array();
|
||||||
for (inst* curr = b.first; curr; curr = curr->next) {
|
for (inst* curr = b.first; curr; curr = curr->next) {
|
||||||
@@ -1186,7 +1180,7 @@ static int compile(struct bytecode* bc, block b, struct locfile* lf) {
|
|||||||
params = jv_array_append(params, jv_string(param->symbol));
|
params = jv_array_append(params, jv_string(param->symbol));
|
||||||
}
|
}
|
||||||
subfn->debuginfo = jv_object_set(subfn->debuginfo, jv_string("params"), params);
|
subfn->debuginfo = jv_object_set(subfn->debuginfo, jv_string("params"), params);
|
||||||
errors += compile(subfn, curr->subfn, lf);
|
errors += compile(subfn, curr->subfn, lf, args, env);
|
||||||
curr->subfn = gen_noop();
|
curr->subfn = gen_noop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1251,7 +1245,7 @@ static int compile(struct bytecode* bc, block b, struct locfile* lf) {
|
|||||||
return errors;
|
return errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
int block_compile(block b, struct bytecode** out, struct locfile* lf) {
|
int block_compile(block b, struct bytecode** out, struct locfile* lf, jv args) {
|
||||||
struct bytecode* bc = jv_mem_alloc(sizeof(struct bytecode));
|
struct bytecode* bc = jv_mem_alloc(sizeof(struct bytecode));
|
||||||
bc->parent = 0;
|
bc->parent = 0;
|
||||||
bc->nclosures = 0;
|
bc->nclosures = 0;
|
||||||
@@ -1261,7 +1255,10 @@ int block_compile(block b, struct bytecode** out, struct locfile* lf) {
|
|||||||
bc->globals->cfunctions = jv_mem_alloc(sizeof(struct cfunction) * ncfunc);
|
bc->globals->cfunctions = jv_mem_alloc(sizeof(struct cfunction) * ncfunc);
|
||||||
bc->globals->cfunc_names = jv_array();
|
bc->globals->cfunc_names = jv_array();
|
||||||
bc->debuginfo = jv_object_set(jv_object(), jv_string("name"), jv_null());
|
bc->debuginfo = jv_object_set(jv_object(), jv_string("name"), jv_null());
|
||||||
int nerrors = compile(bc, b, lf);
|
jv env = jv_invalid();
|
||||||
|
int nerrors = compile(bc, b, lf, args, &env);
|
||||||
|
jv_free(args);
|
||||||
|
jv_free(env);
|
||||||
assert(bc->globals->ncfunctions == ncfunc);
|
assert(bc->globals->ncfunctions == ncfunc);
|
||||||
if (nerrors > 0) {
|
if (nerrors > 0) {
|
||||||
bytecode_free(bc);
|
bytecode_free(bc);
|
||||||
|
|||||||
+1
-1
@@ -77,7 +77,7 @@ block block_drop_unreferenced(block body);
|
|||||||
jv block_take_imports(block* body);
|
jv block_take_imports(block* body);
|
||||||
jv block_list_funcs(block body, int omit_underscores);
|
jv block_list_funcs(block body, int omit_underscores);
|
||||||
|
|
||||||
int block_compile(block, struct bytecode**, struct locfile*);
|
int block_compile(block, struct bytecode**, struct locfile*, jv);
|
||||||
|
|
||||||
void block_free(block);
|
void block_free(block);
|
||||||
|
|
||||||
|
|||||||
+19
-30
@@ -1066,6 +1066,23 @@ static struct bytecode *optimize(struct bytecode *bc) {
|
|||||||
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 || jv_get_kind(args) == JV_KIND_OBJECT);
|
assert(jv_get_kind(args) == JV_KIND_ARRAY || jv_get_kind(args) == JV_KIND_OBJECT);
|
||||||
@@ -1079,49 +1096,21 @@ int jq_compile_args(jq_state *jq, const char* str, jv args) {
|
|||||||
}
|
}
|
||||||
int nerrors = load_program(jq, locations, &program);
|
int nerrors = load_program(jq, locations, &program);
|
||||||
if (nerrors == 0) {
|
if (nerrors == 0) {
|
||||||
/*
|
|
||||||
* jq_compile_args() is a public function. It should always have
|
|
||||||
* been the case that args was an object, but originally it was an
|
|
||||||
* array.
|
|
||||||
*
|
|
||||||
* We have to do an O(N) binding operation for each argument given.
|
|
||||||
*
|
|
||||||
* The best way to address this might be to have a bind function
|
|
||||||
* that takes an object instead of a const block and a varname.
|
|
||||||
*
|
|
||||||
* However, with `--args` this can be avoided, as one can have a
|
|
||||||
* single such binding then: $ARGS.
|
|
||||||
*/
|
|
||||||
if (jv_get_kind(args) == JV_KIND_ARRAY) {
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
} else if (jv_get_kind(args) == JV_KIND_OBJECT) {
|
|
||||||
jv_object_foreach(args, name, 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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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) {
|
||||||
|
|||||||
Reference in new issue
Block a user