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:
parent
fb08c4b4a8
commit
20afbd46ec
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue