Restore cfunction arity in builtins/0

Count arguments up-front at definition/invocation instead of doing it at
bind time, which comes after generating builtins/0 since e843a4f.
This commit is contained in:
Muh Muhten authored and Nico Williams committed 2019-02-26 22:39:57 -06:00
1 parent abed751e96
commit 3ea0199e03
2 files changed
+23 -18

No files matched your search

+8 -18
View File
@@ -290,18 +290,6 @@ int block_has_only_binders(block binders, int bindflags) {
return 1; return 1;
} }
// Count a binder's (function) formal params
static int block_count_formals(block b) {
int args = 0;
if (b.first->op == CLOSURE_CREATE_C)
return b.first->imm.cfunc->nargs - 1;
for (inst* i = b.first->arglist.first; i; i = i->next) {
assert(i->op == CLOSURE_PARAM);
args++;
}
return args;
}
// Count a call site's actual params // Count a call site's actual params
static int block_count_actuals(block b) { static int block_count_actuals(block b) {
int args = 0; int args = 0;
@@ -326,8 +314,6 @@ static int block_bind_subblock_inner(int* any_unbound, block binder, block body,
assert(break_distance >= 0); assert(break_distance >= 0);
binder.first->bound_by = binder.first; binder.first->bound_by = binder.first;
if (binder.first->nformals == -1)
binder.first->nformals = block_count_formals(binder);
int nrefs = 0; int nrefs = 0;
for (inst* i = body.first; i; i = i->next) { for (inst* i = body.first; i; i = i->next) {
if (i->any_unbound == 0) if (i->any_unbound == 0)
@@ -341,8 +327,6 @@ static int block_bind_subblock_inner(int* any_unbound, block binder, block body,
break_distance <= 3 && (i->symbol[1] == '1' + break_distance) && break_distance <= 3 && (i->symbol[1] == '1' + break_distance) &&
i->symbol[2] == '\0'))) { i->symbol[2] == '\0'))) {
// bind this instruction // bind this instruction
if (i->op == CALL_JQ && i->nactuals == -1)
i->nactuals = block_count_actuals(i->arglist);
if (i->nactuals == -1 || i->nactuals == binder.first->nformals) { if (i->nactuals == -1 || i->nactuals == binder.first->nformals) {
i->bound_by = binder.first; i->bound_by = binder.first;
nrefs++; nrefs++;
@@ -566,7 +550,10 @@ block gen_import_meta(block import, block metadata) {
block gen_function(const char* name, block formals, block body) { block gen_function(const char* name, block formals, block body) {
inst* i = inst_new(CLOSURE_CREATE); inst* i = inst_new(CLOSURE_CREATE);
int nformals = 0;
for (inst* i = formals.last; i; i = i->prev) { for (inst* i = formals.last; i; i = i->prev) {
nformals++;
i->nformals = 0;
if (i->op == CLOSURE_PARAM_REGULAR) { if (i->op == CLOSURE_PARAM_REGULAR) {
i->op = CLOSURE_PARAM; i->op = CLOSURE_PARAM;
body = gen_var_binding(gen_call(i->symbol, gen_noop()), i->symbol, body); body = gen_var_binding(gen_call(i->symbol, gen_noop()), i->symbol, body);
@@ -576,6 +563,7 @@ block gen_function(const char* name, block formals, block body) {
i->subfn = body; i->subfn = body;
i->symbol = strdup(name); i->symbol = strdup(name);
i->any_unbound = -1; i->any_unbound = -1;
i->nformals = nformals;
i->arglist = formals; i->arglist = formals;
block b = inst_block(i); block b = inst_block(i);
block_bind_subblock(b, b, OP_IS_CALL_PSEUDO | OP_HAS_BINDING, 0); block_bind_subblock(b, b, OP_IS_CALL_PSEUDO | OP_HAS_BINDING, 0);
@@ -597,6 +585,7 @@ block gen_lambda(block body) {
block gen_call(const char* name, block args) { block gen_call(const char* name, block args) {
block b = gen_op_unbound(CALL_JQ, name); block b = gen_op_unbound(CALL_JQ, name);
b.first->arglist = args; b.first->arglist = args;
b.first->nactuals = block_count_actuals(b.first->arglist);
return b; return b;
} }
@@ -1106,7 +1095,8 @@ block gen_cbinding(const struct cfunction* cfunctions, int ncfunctions, block co
for (int cfunc=0; cfunc<ncfunctions; cfunc++) { for (int cfunc=0; cfunc<ncfunctions; cfunc++) {
inst* i = inst_new(CLOSURE_CREATE_C); inst* i = inst_new(CLOSURE_CREATE_C);
i->imm.cfunc = &cfunctions[cfunc]; i->imm.cfunc = &cfunctions[cfunc];
i->symbol = strdup(i->imm.cfunc->name); i->symbol = strdup(cfunctions[cfunc].name);
i->nformals = cfunctions[cfunc].nargs - 1;
i->any_unbound = 0; i->any_unbound = 0;
code = BLOCK(inst_block(i), code); code = BLOCK(inst_block(i), code);
} }
@@ -1174,7 +1164,7 @@ static int expand_call_arglist(block* b, jv args, jv *env) {
else if (curr->op == LOADV) else if (curr->op == LOADV)
locfile_locate(curr->locfile, curr->source, "jq: error: $%s is not defined", curr->symbol); locfile_locate(curr->locfile, curr->source, "jq: error: $%s is not defined", curr->symbol);
else else
locfile_locate(curr->locfile, curr->source, "jq: error: %s/%d is not defined", curr->symbol, block_count_actuals(curr->arglist)); locfile_locate(curr->locfile, curr->source, "jq: error: %s/%d is not defined", curr->symbol, curr->nactuals);
errors++; errors++;
// don't process this instruction if it's not well-defined // don't process this instruction if it's not well-defined
ret = BLOCK(ret, inst_block(curr)); ret = BLOCK(ret, inst_block(curr));
+15
View File
@@ -1646,4 +1646,19 @@ index("")
"" ""
null null
# check that dead code removal occurs after builtin it generation
builtins|length > 10
null
true
"-1"|IN(builtins[] / "/"|.[1])
null
false
all(builtins[] / "/"; .[1]|tonumber >= 0)
null
true
builtins|any(.[:1] == "_")
null
false