dfilter: Remove existence test syntax tree nodes

After some experimentation I don't think these two existence tests
belong in the grammar, it's an implementation detail and removing it
might avoid some artificial constraints.
This commit is contained in:
João Valverde 2022-04-04 11:33:38 +01:00
parent fb08c4b4a8
commit 20afbd46ec
5 changed files with 55 additions and 68 deletions

View File

@ -430,6 +430,47 @@ gen_entity(dfwork_t *dfw, stnode_t *st_arg, GSList **jumps_ptr)
return val;
}
static void
gen_exists(dfwork_t *dfw, stnode_t *st_node)
{
dfvm_insn_t *insn;
header_field_info *hfinfo;
hfinfo = stnode_data(st_node);
/* Rewind to find the first field of this name. */
while (hfinfo->same_name_prev_id != -1) {
hfinfo = proto_registrar_get_nth(hfinfo->same_name_prev_id);
}
insn = dfvm_insn_new(CHECK_EXISTS);
insn->arg1 = dfvm_value_new_hfinfo(hfinfo);
dfw_append_insn(dfw, insn);
/* Record the FIELD_ID in hash of interesting fields. */
while (hfinfo) {
g_hash_table_insert(dfw->interesting_fields,
GINT_TO_POINTER(hfinfo->id),
GUINT_TO_POINTER(TRUE));
hfinfo = hfinfo->same_name_next;
}
}
static void
gen_notzero(dfwork_t *dfw, stnode_t *st_node)
{
dfvm_insn_t *insn;
dfvm_value_t *val1;
GSList *jumps = NULL;
val1 = gen_arithmetic(dfw, st_node, &jumps);
insn = dfvm_insn_new(ALL_ZERO);
insn->arg1 = dfvm_value_ref(val1);
dfw_append_insn(dfw, insn);
insn = dfvm_insn_new(NOT);
dfw_append_insn(dfw, insn);
g_slist_foreach(jumps, fixup_jumps, dfw);
g_slist_free(jumps);
}
static void
gen_test(dfwork_t *dfw, stnode_t *st_node)
@ -437,10 +478,8 @@ gen_test(dfwork_t *dfw, stnode_t *st_node)
test_op_t st_op;
stnode_t *st_arg1, *st_arg2;
dfvm_insn_t *insn;
dfvm_value_t *jmp, *val1;
GSList *jumps = NULL;
dfvm_value_t *jmp;
header_field_info *hfinfo;
sttype_test_get(st_node, &st_op, &st_arg1, &st_arg2);
@ -449,39 +488,6 @@ gen_test(dfwork_t *dfw, stnode_t *st_node)
ws_assert_not_reached();
break;
case TEST_OP_EXISTS:
hfinfo = stnode_data(st_arg1);
/* Rewind to find the first field of this name. */
while (hfinfo->same_name_prev_id != -1) {
hfinfo = proto_registrar_get_nth(hfinfo->same_name_prev_id);
}
insn = dfvm_insn_new(CHECK_EXISTS);
insn->arg1 = dfvm_value_new_hfinfo(hfinfo);
dfw_append_insn(dfw, insn);
/* Record the FIELD_ID in hash of interesting fields. */
while (hfinfo) {
g_hash_table_insert(dfw->interesting_fields,
GINT_TO_POINTER(hfinfo->id),
GUINT_TO_POINTER(TRUE));
hfinfo = hfinfo->same_name_next;
}
break;
case TEST_OP_NOTZERO:
val1 = gen_entity(dfw, st_arg1, &jumps);
insn = dfvm_insn_new(ALL_ZERO);
insn->arg1 = dfvm_value_ref(val1);
dfw_append_insn(dfw, insn);
insn = dfvm_insn_new(NOT);
dfw_append_insn(dfw, insn);
g_slist_foreach(jumps, fixup_jumps, dfw);
g_slist_free(jumps);
jumps = NULL;
break;
case TEST_OP_NOT:
gencode(dfw, st_arg1);
insn = dfvm_insn_new(NOT);
@ -575,6 +581,12 @@ gencode(dfwork_t *dfw, stnode_t *st_node)
case STTYPE_TEST:
gen_test(dfw, st_node);
break;
case STTYPE_FIELD:
gen_exists(dfw, st_node);
break;
case STTYPE_ARITHMETIC:
gen_notzero(dfw, st_node);
break;
default:
ws_assert_not_reached();
}

View File

@ -123,14 +123,12 @@ logical_test(T) ::= TEST_NOT(L) expr(E).
logical_test(T) ::= entity(E).
{
T = new_test(dfw, TEST_OP_EXISTS, NULL);
sttype_test_set1_args(T, E);
T = E;
}
logical_test(T) ::= arithmetic_term(E).
{
T = new_test(dfw, TEST_OP_NOTZERO, NULL);
sttype_test_set1_args(T, E);
T = E;
}

View File

@ -470,6 +470,7 @@ check_exists(dfwork_t *dfw, stnode_t *st_arg1)
switch (stnode_type_id(st_arg1)) {
case STTYPE_FIELD:
case STTYPE_ARITHMETIC:
/* This is OK */
break;
case STTYPE_REFERENCE:
@ -477,7 +478,6 @@ check_exists(dfwork_t *dfw, stnode_t *st_arg1)
case STTYPE_UNPARSED:
case STTYPE_LITERAL:
case STTYPE_CHARCONST:
case STTYPE_ARITHMETIC:
FAIL(dfw, "%s is neither a field nor a protocol name.",
stnode_todisplay(st_arg1));
break;
@ -1136,14 +1136,6 @@ check_test(dfwork_t *dfw, stnode_t *st_node)
ws_assert_not_reached();
break;
case TEST_OP_EXISTS:
check_exists(dfw, st_arg1);
break;
case TEST_OP_NOTZERO:
check_arithmetic_operation(dfw, st_arg1, FT_NONE);
break;
case TEST_OP_NOT:
semcheck(dfw, st_arg1);
break;
@ -1316,14 +1308,15 @@ semcheck(dfwork_t *dfw, stnode_t *st_node)
{
LOG_NODE(st_node);
/* The parser assures that the top-most syntax-tree
* node will be a TEST node, no matter what. So assert that. */
switch (stnode_type_id(st_node)) {
case STTYPE_TEST:
check_test(dfw, st_node);
break;
case STTYPE_ARITHMETIC:
check_arithmetic_operation(dfw, st_node, FT_NONE);
break;
default:
ws_assert_not_reached();
check_exists(dfw, st_node);
}
}

View File

@ -70,9 +70,6 @@ test_todisplay(test_op_t op)
const char *s = "<notset>";
switch(op) {
case TEST_OP_EXISTS:
s = "<exists>";
break;
case TEST_OP_NOT:
s = "!";
break;
@ -125,9 +122,6 @@ test_todisplay(test_op_t op)
case OP_MODULO:
s = "%";
break;
case TEST_OP_NOTZERO:
s = "<notzero>";
break;
case TEST_OP_CONTAINS:
s = "contains";
break;
@ -150,9 +144,6 @@ test_todebug(test_op_t op)
const char *s = "<notset>";
switch(op) {
case TEST_OP_EXISTS:
s = "TEST_EXISTS";
break;
case TEST_OP_NOT:
s = "TEST_NOT";
break;
@ -207,9 +198,6 @@ test_todebug(test_op_t op)
case OP_MODULO:
s = "OP_MODULO";
break;
case TEST_OP_NOTZERO:
s = "TEST_NOTZERO";
break;
case TEST_OP_CONTAINS:
s = "TEST_CONTAINS";
break;
@ -246,9 +234,7 @@ num_operands(test_op_t op)
switch(op) {
case TEST_OP_UNINITIALIZED:
break;
case TEST_OP_EXISTS:
case TEST_OP_NOT:
case TEST_OP_NOTZERO:
case OP_UNARY_MINUS:
return 1;
case TEST_OP_AND:

View File

@ -39,7 +39,6 @@ typedef enum {
typedef enum {
TEST_OP_UNINITIALIZED,
TEST_OP_EXISTS,
TEST_OP_NOT,
TEST_OP_AND,
TEST_OP_OR,
@ -58,7 +57,6 @@ typedef enum {
OP_MULTIPLY,
OP_DIVIDE,
OP_MODULO,
TEST_OP_NOTZERO,
TEST_OP_CONTAINS,
TEST_OP_MATCHES,
TEST_OP_IN