Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tests: refactor constant folding tests #3233

Merged
merged 1 commit into from
Jan 25, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 8 additions & 68 deletions tests/shtest
Original file line number Diff line number Diff line change
Expand Up @@ -37,77 +37,17 @@ $VALGRIND $Q $JQ -Rse '. == "a\u0000b\nc\u0000d\ne"' $d/input
$VALGRIND $Q $JQ -Rne '[inputs] == ["a\u0000b", "c\u0000d", "e"]' $d/input

## Test constant folding

## XXX If we add a builtin to list the program's disassembly then we can
## move all of these into tests/all.test

# String constant folding (addition only)
nref=$($VALGRIND $Q $JQ -n --debug-dump-disasm '"foo"' | wc -l)
n=$($VALGRIND $Q $JQ -n --debug-dump-disasm '"foo" + "bar"' | wc -l)
if [ $n -ne $nref ]; then
echo "Constant expression folding for strings didn't work"
exit 1
fi

# Numeric constant folding (binary operators)
n=$($VALGRIND $Q $JQ -n --debug-dump-disasm '1+1' | wc -l)
if [ $n -ne $nref ]; then
echo "Constant expression folding for numbers didn't work"
exit 1
fi
n=$($VALGRIND $Q $JQ -n --debug-dump-disasm '1-1' | wc -l)
if [ $n -ne $nref ]; then
echo "Constant expression folding for numbers didn't work"
exit 1
fi
n=$($VALGRIND $Q $JQ -n --debug-dump-disasm '2*3' | wc -l)
if [ $n -ne $nref ]; then
echo "Constant expression folding for numbers didn't work"
exit 1
fi
n=$($VALGRIND $Q $JQ -n --debug-dump-disasm '9/3' | wc -l)
if [ $n -ne $nref ]; then
echo "Constant expression folding for numbers didn't work"
exit 1
fi
n=$($VALGRIND $Q $JQ -n --debug-dump-disasm '9%3' | wc -l)
if [ $n -ne $nref ]; then
echo "Constant expression folding for numbers didn't work"
exit 1
fi
n=$($VALGRIND $Q $JQ -n --debug-dump-disasm '9==3' | wc -l)
if [ $n -ne $nref ]; then
echo "Constant expression folding for numbers didn't work"
exit 1
fi
n=$($VALGRIND $Q $JQ -n --debug-dump-disasm '9!=3' | wc -l)
if [ $n -ne $nref ]; then
echo "Constant expression folding for numbers didn't work"
exit 1
fi
n=$($VALGRIND $Q $JQ -n --debug-dump-disasm '9<3' | wc -l)
if [ $n -ne $nref ]; then
echo "Constant expression folding for numbers didn't work"
exit 1
fi
n=$($VALGRIND $Q $JQ -n --debug-dump-disasm '9>3' | wc -l)
if [ $n -ne $nref ]; then
echo "Constant expression folding for numbers didn't work"
exit 1
fi
n=$($VALGRIND $Q $JQ -n --debug-dump-disasm '9<=3' | wc -l)
if [ $n -ne $nref ]; then
echo "Constant expression folding for numbers didn't work"
exit 1
fi
n=$($VALGRIND $Q $JQ -n --debug-dump-disasm '9>=3' | wc -l)
if [ $n -ne $nref ]; then
echo "Constant expression folding for numbers didn't work"
exit 1
fi
for exp in '1+1' '1-1' '2*3' '9/3' '9%3' '9==3' '9!=3' \
'9<3' '9>3' '9<=3' '9>=3' '1+2*3-4/5%6' '"foo" + "bar"'; do
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we constant fold and/or with constants? unary operators? something else?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't, unfortunately.

 $ jq -n --debug-dump-disasm 'false and false'
0000 TOP
0001 DUP
0002 LOADK false
0004 JUMP_F 0019
0006 POP
0007 LOADK false
0009 JUMP_F 0015
0011 LOADK true
0013 JUMP 0017
0015 LOADK false
0017 JUMP 0022
0019 POP
0020 LOADK false
0022 RET

false

 $ jq -n --debug-dump-disasm 'false or false'
0000 TOP
0001 DUP
0002 LOADK false
0004 JUMP_F 0011
0006 POP
0007 LOADK true
0009 JUMP 0022
0011 POP
0012 LOADK false
0014 JUMP_F 0020
0016 LOADK true
0018 JUMP 0022
0020 LOADK false
0022 RET

false

 $ jq -n --debug-dump-disasm '(-1)'
0000 TOP
0001 LOADK 1
0003 CALL_BUILTIN _negate
0006 RET

-1

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

jq/src/parser.y

Lines 202 to 231 in 588ff18

static block constant_fold(block a, block b, int op) {
if (!block_is_single(a) || !block_is_const(a) ||
!block_is_single(b) || !block_is_const(b))
return gen_noop();
jv jv_a = block_const(a);
block_free(a);
jv jv_b = block_const(b);
block_free(b);
jv res = jv_invalid();
switch (op) {
case '+': res = binop_plus(jv_a, jv_b); break;
case '-': res = binop_minus(jv_a, jv_b); break;
case '*': res = binop_multiply(jv_a, jv_b); break;
case '/': res = binop_divide(jv_a, jv_b); break;
case '%': res = binop_mod(jv_a, jv_b); break;
case EQ: res = binop_equal(jv_a, jv_b); break;
case NEQ: res = binop_notequal(jv_a, jv_b); break;
case '<': res = binop_less(jv_a, jv_b); break;
case '>': res = binop_greater(jv_a, jv_b); break;
case LESSEQ: res = binop_lesseq(jv_a, jv_b); break;
case GREATEREQ: res = binop_greatereq(jv_a, jv_b); break;
}
if (jv_is_valid(res))
return gen_const(res);
return gen_error(jv_invalid_get_msg(res));
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for digging, at lest for and/or i guess it's very uncommon that filters in practice have such constant expressions

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, unary operator should be constant folded.

n=$($VALGRIND $Q $JQ -n --debug-dump-disasm "$exp" | wc -l)
if [ $n -ne $nref ]; then
echo "Constant expression folding didn't work: $exp"
exit 1
fi
done

## Test JSON sequence support

cat > $d/expected <<EOF
jq: ignoring parse error: Truncated value at line 2, column 5
jq: ignoring parse error: Truncated value at line 2, column 25
Expand Down
Loading