dfilter: Replace bitwise sttype with arithmetic

Most of the bitwise codepaths are just duplicating code for
the arithmetic type. Parse bitwise expressions as arithmetic
instead.
This commit is contained in:
João Valverde 2022-04-03 22:49:16 +01:00
parent c98df5eef5
commit fb08c4b4a8
6 changed files with 18 additions and 218 deletions

View File

@ -326,32 +326,6 @@ gen_relation_in(dfwork_t *dfw, stnode_t *st_arg1, stnode_t *st_arg2)
set_nodelist_free(nodelist_head);
}
static dfvm_value_t *
gen_bitwise(dfwork_t *dfw, stnode_t *st_arg, GSList **jumps_ptr)
{
stnode_t *left, *right;
test_op_t st_op;
dfvm_value_t *reg_val, *val1, *val2;
dfvm_opcode_t op;
sttype_test_get(st_arg, &st_op, &left, &right);
switch (st_op) {
case OP_BITWISE_AND:
op = MK_BITWISE_AND;
break;
default:
ws_assert_not_reached();
break;
}
val1 = gen_entity(dfw, left, jumps_ptr);
val2 = gen_entity(dfw, right, jumps_ptr);
reg_val = dfvm_value_new_register(dfw->next_register++);
gen_relation_insn(dfw, op, val1, val2, reg_val, NULL);
return reg_val;
}
static dfvm_value_t *
gen_arithmetic(dfwork_t *dfw, stnode_t *st_arg, GSList **jumps_ptr)
{
@ -380,6 +354,9 @@ gen_arithmetic(dfwork_t *dfw, stnode_t *st_arg, GSList **jumps_ptr)
else if (st_op == OP_MODULO) {
op = DFVM_MODULO;
}
else if (st_op == OP_BITWISE_AND) {
op = MK_BITWISE_AND;
}
else {
ws_assert_not_reached();
}
@ -443,9 +420,6 @@ gen_entity(dfwork_t *dfw, stnode_t *st_arg, GSList **jumps_ptr)
else if (e_type == STTYPE_PCRE) {
val = dfvm_value_new_pcre(stnode_steal_data(st_arg));
}
else if (e_type == STTYPE_BITWISE) {
val = gen_bitwise(dfw, st_arg, jumps_ptr);
}
else if (e_type == STTYPE_ARITHMETIC) {
val = gen_arithmetic(dfw, st_arg, jumps_ptr);
}

View File

@ -127,7 +127,7 @@ logical_test(T) ::= entity(E).
sttype_test_set1_args(T, E);
}
logical_test(T) ::= bitwise_term(E).
logical_test(T) ::= arithmetic_term(E).
{
T = new_test(dfw, TEST_OP_NOTZERO, NULL);
sttype_test_set1_args(T, E);
@ -179,9 +179,9 @@ entity(E) ::= REF_OPEN REFERENCE(F) REF_CLOSE.
entity(E) ::= range(R). { E = R; }
entity(E) ::= function(F). { E = F; }
bitwise_term(T) ::= entity(F) BITWISE_AND(B) entity(M).
arithmetic_term(T) ::= entity(F) BITWISE_AND(B) entity(M).
{
T = stnode_new(STTYPE_BITWISE, NULL, df_lval_value(B));
T = stnode_new(STTYPE_ARITHMETIC, NULL, df_lval_value(B));
sttype_test_set2(T, OP_BITWISE_AND, F, M);
df_lval_free(B, FALSE);
}
@ -233,7 +233,6 @@ arithmetic_term(T) ::= entity(E) PERCENT(M) entity(N).
}
term(T) ::= entity(E). { T = E; }
term(T) ::= bitwise_term(E). { T = E; }
term(T) ::= arithmetic_term(E). { T = E; }

View File

@ -41,12 +41,6 @@ semcheck(dfwork_t *dfw, stnode_t *st_node);
static void
check_function(dfwork_t *dfw, stnode_t *st_node);
static ftenum_t
check_bitwise_entity(dfwork_t *dfw, stnode_t *st_node, stnode_t *st_arg, ftenum_t ftype);
static ftenum_t
check_bitwise_operation(dfwork_t *dfw, stnode_t *st_node);
static
ftenum_t
check_arithmetic_operation(dfwork_t *dfw, stnode_t *st_node, ftenum_t lhs_ftype);
@ -712,19 +706,6 @@ again:
else if (type2 == STTYPE_PCRE) {
ws_assert(st_op == TEST_OP_MATCHES);
}
else if (type2 == STTYPE_BITWISE) {
ftype2 = check_bitwise_operation(dfw, st_arg2);
if (!compatible_ftypes(ftype1, ftype2)) {
FAIL(dfw, "%s and %s are not of compatible types.",
stnode_todisplay(st_arg1), stnode_todisplay(st_arg2));
}
if (!can_func(ftype2)) {
FAIL(dfw, "%s (type=%s) cannot participate in specified comparison.",
stnode_todisplay(st_arg2), ftype_pretty_name(ftype2));
}
}
else if (type2 == STTYPE_ARITHMETIC) {
ftype2 = check_arithmetic_operation(dfw, st_arg2, ftype1);
@ -818,19 +799,6 @@ again:
else if (type2 == STTYPE_PCRE) {
ws_assert(st_op == TEST_OP_MATCHES);
}
else if (type2 == STTYPE_BITWISE) {
ftype2 = check_bitwise_operation(dfw, st_arg2);
if (!compatible_ftypes(FT_BYTES, ftype2)) {
FAIL(dfw, "%s and %s are not of compatible types.",
stnode_todisplay(st_arg1), stnode_todisplay(st_arg2));
}
if (!can_func(ftype2)) {
FAIL(dfw, "%s (type=%s) cannot participate in specified comparison.",
stnode_todisplay(st_arg2), ftype_pretty_name(ftype2));
}
}
else if (type2 == STTYPE_ARITHMETIC) {
ftype2 = check_arithmetic_operation(dfw, st_arg2, FT_BYTES);
@ -947,19 +915,6 @@ again:
else if (type2 == STTYPE_PCRE) {
ws_assert(st_op == TEST_OP_MATCHES);
}
else if (type2 == STTYPE_BITWISE) {
ftype2 = check_bitwise_operation(dfw, st_arg2);
if (!compatible_ftypes(ftype1, ftype2)) {
FAIL(dfw, "%s and %s are not of compatible types.",
stnode_todisplay(st_arg1), stnode_todisplay(st_arg2));
}
if (!can_func(ftype2)) {
FAIL(dfw, "%s (type=%s) cannot participate in specified comparison.",
stnode_todisplay(st_arg2), ftype_pretty_name(ftype2));
}
}
else if (type2 == STTYPE_ARITHMETIC) {
ftype2 = check_arithmetic_operation(dfw, st_arg2, ftype1);
@ -978,38 +933,6 @@ again:
}
}
static void
check_relation_LHS_BITWISE(dfwork_t *dfw, test_op_t st_op _U_,
FtypeCanFunc can_func _U_, gboolean allow_partial_value,
stnode_t *st_node _U_,
stnode_t *st_arg1, stnode_t *st_arg2)
{
stnode_t *bitwise_entity;
sttype_id_t bitwise_entity_type;
LOG_NODE(st_node);
/* (arg1: bitwise) <relop> (arg2: rhs) */
check_bitwise_operation(dfw, st_arg1);
sttype_test_get(st_arg1, NULL, &bitwise_entity, NULL);
bitwise_entity_type = stnode_type_id(bitwise_entity);
if (bitwise_entity_type == STTYPE_FIELD ||
bitwise_entity_type == STTYPE_REFERENCE) {
check_relation_LHS_FIELD(dfw, st_op, can_func, allow_partial_value, st_node, bitwise_entity, st_arg2);
}
else if (bitwise_entity_type == STTYPE_RANGE) {
check_relation_LHS_RANGE(dfw, st_op, can_func, allow_partial_value, st_node, bitwise_entity, st_arg2);
}
else if (bitwise_entity_type == STTYPE_FUNCTION) {
check_relation_LHS_FUNCTION(dfw, st_op, can_func, allow_partial_value, st_node, bitwise_entity, st_arg2);
}
else {
ws_assert_not_reached();
}
}
static void
check_relation_LHS_ARITHMETIC(dfwork_t *dfw, test_op_t st_op _U_,
FtypeCanFunc can_func _U_, gboolean allow_partial_value,
@ -1031,6 +954,9 @@ check_relation_LHS_ARITHMETIC(dfwork_t *dfw, test_op_t st_op _U_,
else if (entity_type == STTYPE_FUNCTION) {
check_relation_LHS_FUNCTION(dfw, st_op, can_func, allow_partial_value, st_node, entity, st_arg2);
}
else if (entity_type == STTYPE_RANGE) {
check_relation_LHS_RANGE(dfw, st_op, can_func, allow_partial_value, st_node, entity, st_arg2);
}
else {
ws_assert_not_reached();
}
@ -1060,10 +986,6 @@ check_relation(dfwork_t *dfw, test_op_t st_op,
check_relation_LHS_FUNCTION(dfw, st_op, can_func,
allow_partial_value, st_node, st_arg1, st_arg2);
break;
case STTYPE_BITWISE:
check_relation_LHS_BITWISE(dfw, st_op, can_func,
allow_partial_value, st_node, st_arg1, st_arg2);
break;
case STTYPE_ARITHMETIC:
check_relation_LHS_ARITHMETIC(dfw, st_op, can_func,
allow_partial_value, st_node, st_arg1, st_arg2);
@ -1219,8 +1141,7 @@ check_test(dfwork_t *dfw, stnode_t *st_node)
break;
case TEST_OP_NOTZERO:
ws_assert(stnode_type_id(st_arg1) == STTYPE_BITWISE);
check_bitwise_operation(dfw, st_arg1);
check_arithmetic_operation(dfw, st_arg1, FT_NONE);
break;
case TEST_OP_NOT:
@ -1260,96 +1181,6 @@ check_test(dfwork_t *dfw, stnode_t *st_node)
}
}
static ftenum_t
check_bitwise_entity(dfwork_t *dfw, stnode_t *st_node, stnode_t *st_arg, ftenum_t lhs_ftype)
{
header_field_info *hfinfo;
ftenum_t ftype;
fvalue_t *fvalue;
sttype_id_t type;
df_func_def_t *funcdef;
LOG_NODE(st_arg);
resolve_unparsed(dfw, st_arg);
type = stnode_type_id(st_arg);
if (type == STTYPE_FIELD || type == STTYPE_REFERENCE) {
hfinfo = stnode_data(st_arg);
ftype = hfinfo->type;
if (!ftype_can_bitwise_and(ftype)) {
FAIL(dfw, "%s (type=%s) cannot participate in %s comparison.",
hfinfo->abbrev, ftype_pretty_name(ftype),
stnode_todisplay(st_node));
}
return ftype;
}
else if (type == STTYPE_FUNCTION) {
check_function(dfw, st_arg);
funcdef = sttype_function_funcdef(st_arg);
ftype = funcdef->retval_ftype;
if (!ftype_can_bitwise_and(ftype)) {
FAIL(dfw, "Function %s (type=%s) cannot participate in %s comparison.",
funcdef->name, ftype_pretty_name(ftype),
stnode_todisplay(st_node));
}
return ftype;
}
else if (type == STTYPE_RANGE) {
check_drange_sanity(dfw, st_arg);
ftype = FT_BYTES;
if (!ftype_can_bitwise_and(ftype)) {
FAIL(dfw, "Range %s (type=%s) cannot participate in %s comparison.",
stnode_todisplay(st_arg), ftype_pretty_name(ftype),
stnode_todisplay(st_node));
}
return ftype;
}
else if (lhs_ftype != FT_NONE) {
/* numeric constant */
ftype = lhs_ftype;
fvalue = dfilter_fvalue_from_literal(dfw, ftype, st_arg, FALSE, NULL);
stnode_replace(st_arg, STTYPE_FVALUE, fvalue);
}
else {
FAIL(dfw, "Invalid bitwise operand %s in comparison %s.",
stnode_todisplay(st_arg), stnode_todisplay(st_arg));
}
return ftype;
}
static ftenum_t
check_bitwise_operation(dfwork_t *dfw, stnode_t *st_node)
{
test_op_t st_op;
stnode_t *st_arg1, *st_arg2;
ftenum_t ftype1, ftype2;
LOG_NODE(st_node);
sttype_test_get(st_node, &st_op, &st_arg1, &st_arg2);
ftype1 = check_bitwise_entity(dfw, st_node, st_arg1, FT_NONE);
ftype2 = check_bitwise_entity(dfw, st_node, st_arg2, ftype1);
if (!ftype_can_is_zero(ftype1)) {
FAIL(dfw, "Cannot test if %s is true", stnode_todisplay(st_arg1));
}
/* XXX This could be relaxed with type promotions. */
if (ftype1 != ftype2) {
FAIL(dfw, "%s %s %s: entities have different types",
stnode_todisplay(st_arg1),
stnode_todisplay(st_node),
stnode_todisplay(st_arg2));
}
return ftype1;
}
ftenum_t
check_arithmetic_entity(dfwork_t *dfw, FtypeCanFunc can_func, test_op_t st_op,
stnode_t *st_node, stnode_t *st_arg, ftenum_t lhs_ftype)
@ -1412,6 +1243,11 @@ check_arithmetic_entity(dfwork_t *dfw, FtypeCanFunc can_func, test_op_t st_op,
stnode_todisplay(st_node));
}
}
else if (type == STTYPE_RANGE) {
check_drange_sanity(dfw, st_arg);
ftype = FT_BYTES;
}
else {
FAIL(dfw, "%s is not a valid arithmetic operand for %s.",
stnode_todisplay(st_arg),
@ -1455,6 +1291,9 @@ check_arithmetic_operation(dfwork_t *dfw, stnode_t *st_node, ftenum_t lhs_ftype)
case OP_MODULO:
can_func = ftype_can_modulo;
break;
case OP_BITWISE_AND:
can_func = ftype_can_bitwise_and;
break;
default:
ws_assert_not_reached();
}

View File

@ -368,15 +368,6 @@ sttype_register_test(void)
test_dup,
test_tostr
};
/* XXX Bitwise ops are not "tests". */
static sttype_t bitwise_type = {
STTYPE_BITWISE,
"BITWISE",
test_new,
test_free,
test_dup,
test_tostr
};
static sttype_t arithmetic_type = {
STTYPE_ARITHMETIC,
"ARITHMETIC",
@ -387,7 +378,6 @@ sttype_register_test(void)
};
sttype_register(&test_type);
sttype_register(&bitwise_type);
sttype_register(&arithmetic_type);
}

View File

@ -392,7 +392,6 @@ visit_tree(wmem_strbuf_t *buf, stnode_t *node, int level)
stnode_t *left, *right;
if (stnode_type_id(node) == STTYPE_TEST ||
stnode_type_id(node) == STTYPE_BITWISE ||
stnode_type_id(node) == STTYPE_ARITHMETIC) {
wmem_strbuf_append_printf(buf, "%s:\n", stnode_todebug(node));
sttype_test_get(node, NULL, &left, &right);

View File

@ -33,7 +33,6 @@ typedef enum {
STTYPE_FUNCTION,
STTYPE_SET,
STTYPE_PCRE,
STTYPE_BITWISE,
STTYPE_ARITHMETIC,
STTYPE_NUM_TYPES
} sttype_id_t;