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:
parent
c98df5eef5
commit
fb08c4b4a8
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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; }
|
||||
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -33,7 +33,6 @@ typedef enum {
|
|||
STTYPE_FUNCTION,
|
||||
STTYPE_SET,
|
||||
STTYPE_PCRE,
|
||||
STTYPE_BITWISE,
|
||||
STTYPE_ARITHMETIC,
|
||||
STTYPE_NUM_TYPES
|
||||
} sttype_id_t;
|
||||
|
|
Loading…
Reference in New Issue