mirror of
https://github.com/stedolan/jq.git
synced 2024-05-11 05:55:39 +00:00
Fold constant arrays
This commit is contained in:
62
compile.c
62
compile.c
@@ -499,8 +499,70 @@ block gen_both(block a, block b) {
|
|||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
block gen_const_array(block expr) {
|
||||||
|
/*
|
||||||
|
* An expr of all constant elements looks like this:
|
||||||
|
*
|
||||||
|
* 0009 FORK 0027
|
||||||
|
* 0011 FORK 0023
|
||||||
|
* 0013 FORK 0019
|
||||||
|
* 0015 LOADK 1
|
||||||
|
* 0017 JUMP 0021
|
||||||
|
* 0019 LOADK 2
|
||||||
|
* 0021 JUMP 0025
|
||||||
|
* 0023 LOADK 3
|
||||||
|
* 0025 JUMP 0029
|
||||||
|
* 0027 LOADK 4
|
||||||
|
*
|
||||||
|
* That's: N-1 commas for N elements, N LOADKs, and a JUMP between
|
||||||
|
* every LOADK. The sequence ends in a LOADK. Any deviation and it's
|
||||||
|
* not a list of constants.
|
||||||
|
*
|
||||||
|
* Here we check for this pattern almost exactly. We don't check that
|
||||||
|
* the targets of the FORK and JUMP instructions are in the right
|
||||||
|
* sequence.
|
||||||
|
*/
|
||||||
|
int all_const = 1;
|
||||||
|
int commas = 0;
|
||||||
|
int normal = 1;
|
||||||
|
jv a = jv_array();
|
||||||
|
for (inst *i = expr.first; i; i = i->next) {
|
||||||
|
if (i->op == FORK) {
|
||||||
|
commas++;
|
||||||
|
if (i->imm.target == NULL || i->imm.target->op != JUMP ||
|
||||||
|
jv_array_length(jv_copy(a)) > 0) {
|
||||||
|
normal = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (all_const && i->op == LOADK) {
|
||||||
|
if (i->next != NULL && i->next->op != JUMP) {
|
||||||
|
normal = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
a = jv_array_append(a, jv_copy(i->imm.constant));
|
||||||
|
} else if (i->op != JUMP || i->imm.target == NULL ||
|
||||||
|
i->imm.target->op != LOADK) {
|
||||||
|
all_const = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (all_const && normal &&
|
||||||
|
(expr.last == NULL || expr.last->op == LOADK) &&
|
||||||
|
jv_array_length(jv_copy(a)) == commas + 1) {
|
||||||
|
block_free(expr);
|
||||||
|
return gen_const(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
jv_free(a);
|
||||||
|
block b = {0,0};
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
block gen_collect(block expr) {
|
block gen_collect(block expr) {
|
||||||
|
block const_array = gen_const_array(expr);
|
||||||
|
if (const_array.first != NULL)
|
||||||
|
return const_array;
|
||||||
|
|
||||||
block array_var = gen_op_var_fresh(STOREV, "collect");
|
block array_var = gen_op_var_fresh(STOREV, "collect");
|
||||||
block c = BLOCK(gen_op_simple(DUP), gen_const(jv_array()), array_var);
|
block c = BLOCK(gen_op_simple(DUP), gen_const(jv_array()), array_var);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user