Filter: Implement rshift, lshift, bit not operators
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Fri, 22 Sep 2017 00:13:17 +0000 (20:13 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Wed, 6 Jun 2018 20:28:14 +0000 (16:28 -0400)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
src/lib/lttng-ctl/filter/filter-ast.h
src/lib/lttng-ctl/filter/filter-bytecode.h
src/lib/lttng-ctl/filter/filter-parser.y
src/lib/lttng-ctl/filter/filter-visitor-generate-bytecode.c
src/lib/lttng-ctl/filter/filter-visitor-generate-ir.c
src/lib/lttng-ctl/filter/filter-visitor-xml.c
tests/regression/tools/filtering/test_invalid_filter
tests/regression/tools/filtering/test_unsupported_op
tests/regression/tools/filtering/test_valid_filter

index 4bf42fd3fa915f0abf93a7c083a6c15c8fff9183..c5c73b69e8b9ee18281e33bd1f47ccf05d2dfe95 100644 (file)
@@ -67,8 +67,8 @@ enum op_type {
        AST_OP_MOD,
        AST_OP_PLUS,
        AST_OP_MINUS,
-       AST_OP_RSHIFT,
-       AST_OP_LSHIFT,
+       AST_OP_BIT_RSHIFT,
+       AST_OP_BIT_LSHIFT,
        AST_OP_AND,
        AST_OP_OR,
        AST_OP_BIT_AND,
index a86963f73274dcb94ed3e26277dee940d9417b0f..a0913af8b28f2004e3e1f9ae708cbc9f195fc42f 100644 (file)
@@ -71,8 +71,8 @@ enum filter_op {
        FILTER_OP_MOD                           = 4,
        FILTER_OP_PLUS                          = 5,
        FILTER_OP_MINUS                         = 6,
-       FILTER_OP_RSHIFT                        = 7,
-       FILTER_OP_LSHIFT                        = 8,
+       FILTER_OP_BIT_RSHIFT                    = 7,
+       FILTER_OP_BIT_LSHIFT                    = 8,
        FILTER_OP_BIT_AND                       = 9,
        FILTER_OP_BIT_OR                        = 10,
        FILTER_OP_BIT_XOR                       = 11,
@@ -201,6 +201,8 @@ enum filter_op {
        FILTER_OP_LOAD_FIELD_SEQUENCE           = 96,
        FILTER_OP_LOAD_FIELD_DOUBLE             = 97,
 
+       FILTER_OP_UNARY_BIT_NOT                 = 98,
+
        NR_FILTER_OPS,
 };
 
index 7c4aebe8db3807ed4a2034bbccd95da625e0544d..2fa41ab405259d9eec1533ff47793a5d54cc3a26 100644 (file)
@@ -588,11 +588,11 @@ shift_expression
                {       $$ = $1;                                        }
        | shift_expression LEFT_OP additive_expression
                {
-                       $$ = make_op_node(parser_ctx, AST_OP_LSHIFT, $1, $3);
+                       $$ = make_op_node(parser_ctx, AST_OP_BIT_LSHIFT, $1, $3);
                }
        | shift_expression RIGHT_OP additive_expression
                {
-                       $$ = make_op_node(parser_ctx, AST_OP_RSHIFT, $1, $3);
+                       $$ = make_op_node(parser_ctx, AST_OP_BIT_RSHIFT, $1, $3);
                }
        ;
 
index d548da749e88ff2279b16b77673d290d4de7c16f..1ab98138e61e16f4120f3be7ae508b518dac65cc 100644 (file)
@@ -587,6 +587,9 @@ int visit_node_unary(struct filter_parser_ctx *ctx, struct ir_op *node)
        case AST_UNARY_NOT:
                insn.op = FILTER_OP_UNARY_NOT;
                return bytecode_push(&ctx->bytecode, &insn, 1, sizeof(insn));
+       case AST_UNARY_BIT_NOT:
+               insn.op = FILTER_OP_UNARY_BIT_NOT;
+               return bytecode_push(&ctx->bytecode, &insn, 1, sizeof(insn));
        }
 }
 
@@ -636,11 +639,11 @@ int visit_node_binary(struct filter_parser_ctx *ctx, struct ir_op *node)
        case AST_OP_MINUS:
                insn.op = FILTER_OP_MINUS;
                break;
-       case AST_OP_RSHIFT:
-               insn.op = FILTER_OP_RSHIFT;
+       case AST_OP_BIT_RSHIFT:
+               insn.op = FILTER_OP_BIT_RSHIFT;
                break;
-       case AST_OP_LSHIFT:
-               insn.op = FILTER_OP_LSHIFT;
+       case AST_OP_BIT_LSHIFT:
+               insn.op = FILTER_OP_BIT_LSHIFT;
                break;
        case AST_OP_BIT_AND:
                insn.op = FILTER_OP_BIT_AND;
index cd7930ad5476cb36e62f949d7a9ae818b4cf3723..a189c4e9bc904e387e59c0336e8fb7677e8715b0 100644 (file)
@@ -358,6 +358,13 @@ struct ir_op *make_op_unary_not(struct ir_op *child, enum ir_side side)
                        child, side);
 }
 
+static
+struct ir_op *make_op_unary_bit_not(struct ir_op *child, enum ir_side side)
+{
+       return make_op_unary(AST_UNARY_BIT_NOT, "~", child->signedness,
+                       child, side);
+}
+
 static
 struct ir_op *make_op_binary_compare(enum op_type bin_op_type,
                const char *op_str, struct ir_op *left, struct ir_op *right,
@@ -538,6 +545,20 @@ struct ir_op *make_op_binary_logical_or(struct ir_op *left, struct ir_op *right,
        return make_op_binary_logical(AST_OP_OR, "||", left, right, side);
 }
 
+static
+struct ir_op *make_op_binary_bitwise_rshift(struct ir_op *left, struct ir_op *right,
+               enum ir_side side)
+{
+       return make_op_binary_bitwise(AST_OP_BIT_RSHIFT, ">>", left, right, side);
+}
+
+static
+struct ir_op *make_op_binary_bitwise_lshift(struct ir_op *left, struct ir_op *right,
+               enum ir_side side)
+{
+       return make_op_binary_bitwise(AST_OP_BIT_LSHIFT, "<<", left, right, side);
+}
+
 static
 struct ir_op *make_op_binary_bitwise_and(struct ir_op *left, struct ir_op *right,
                enum ir_side side)
@@ -662,13 +683,9 @@ struct ir_op *make_op(struct filter_parser_ctx *ctx,
        case AST_OP_MINUS:
                op_str = "-";
                goto error_not_supported;
-       case AST_OP_RSHIFT:
-               op_str = ">>";
-               goto error_not_supported;
-       case AST_OP_LSHIFT:
-               op_str = "<<";
-               goto error_not_supported;
 
+       case AST_OP_BIT_RSHIFT:
+       case AST_OP_BIT_LSHIFT:
        case AST_OP_BIT_AND:
        case AST_OP_BIT_OR:
        case AST_OP_BIT_XOR:
@@ -740,6 +757,12 @@ struct ir_op *make_op(struct filter_parser_ctx *ctx,
        case AST_OP_LE:
                op = make_op_binary_le(lchild, rchild, side);
                break;
+       case AST_OP_BIT_RSHIFT:
+               op = make_op_binary_bitwise_rshift(lchild, rchild, side);
+               break;
+       case AST_OP_BIT_LSHIFT:
+               op = make_op_binary_bitwise_lshift(lchild, rchild, side);
+               break;
        case AST_OP_BIT_AND:
                op = make_op_binary_bitwise_and(lchild, rchild, side);
                break;
@@ -769,8 +792,6 @@ static
 struct ir_op *make_unary_op(struct filter_parser_ctx *ctx,
                struct filter_node *node, enum ir_side side)
 {
-       const char *op_str = "?";
-
        switch (node->u.unary_op.type) {
        case AST_UNARY_UNKNOWN:
        default:
@@ -824,14 +845,21 @@ struct ir_op *make_unary_op(struct filter_parser_ctx *ctx,
        }
        case AST_UNARY_BIT_NOT:
        {
-               op_str = "~";
-               goto error_not_supported;
+               struct ir_op *op, *child;
+
+               child = generate_ir_recursive(ctx, node->u.unary_op.child,
+                                       side);
+               if (!child)
+                       return NULL;
+               op = make_op_unary_bit_not(child, side);
+               if (!op) {
+                       filter_free_ir_recursive(child);
+                       return NULL;
+               }
+               return op;
        }
        }
 
-error_not_supported:
-       fprintf(stderr, "[error] %s: unary operation '%s' not supported\n",
-               __func__, op_str);
        return NULL;
 }
 
index 1e5812015d7237798dd459c09b2a3fb8a9205171..9352742a51c50d8c81a0afce2fe60973912682c0 100644 (file)
@@ -157,10 +157,10 @@ int recursive_visit_print(struct filter_node *node, FILE *stream, int indent)
                case AST_OP_MINUS:
                        fprintf(stream, "\"-\"");
                        break;
-               case AST_OP_RSHIFT:
+               case AST_OP_BIT_RSHIFT:
                        fprintf(stream, "\">>\"");
                        break;
-               case AST_OP_LSHIFT:
+               case AST_OP_BIT_LSHIFT:
                        fprintf(stream, "\"<<\"");
                        break;
                case AST_OP_AND:
index 2c45ee09e75170b0738bec630cb8d6a8d409f893..bea17340797bf94fab2df9ff9ff93599b4e76eda 100755 (executable)
@@ -25,8 +25,8 @@ EVENT_NAME="bogus"
 ENABLE_EVENT_STDERR="/tmp/invalid-filters-stderr"
 TRACE_PATH=$(mktemp -d)
 NUM_GLOBAL_TESTS=2
-NUM_UST_TESTS=144
-NUM_KERNEL_TESTS=144
+NUM_UST_TESTS=135
+NUM_KERNEL_TESTS=135
 NUM_TESTS=$(($NUM_UST_TESTS+$NUM_KERNEL_TESTS+$NUM_GLOBAL_TESTS))
 
 source $TESTDIR/utils/utils.sh
@@ -101,9 +101,6 @@ INVALID_FILTERS=(
                "intfield/1"
                "intfield+1"
                "intfield-1"
-               "intfield>>1"
-               "intfield<<1"
-               "~intfield"
                "1+11111-3333+1"
                "(1+2)*(55*666)"
                "1+2*55*666"
index 7395da0dd8043a9a679c5e6b827ba001982ef4e7..357e81c683187eca1c8a4adf342b1ff0afcb9262 100755 (executable)
@@ -25,8 +25,8 @@ EVENT_NAME="bogus"
 ENABLE_EVENT_STDERR="/tmp/unsupported-ops-enable"
 TRACE_PATH=$(mktemp -d)
 NUM_GLOBAL_TESTS=2
-NUM_UST_TESTS=32
-NUM_KERNEL_TESTS=32
+NUM_UST_TESTS=20
+NUM_KERNEL_TESTS=20
 NUM_TESTS=$(($NUM_UST_TESTS+$NUM_KERNEL_TESTS+$NUM_GLOBAL_TESTS))
 
 source $TESTDIR/utils/utils.sh
@@ -93,10 +93,9 @@ plan_tests $NUM_TESTS
 print_test_banner "$TEST_DESC"
 
 # Unsupported operators
-OP_STR=("MUL" "DIV" "MOD" "PLUS" "MINUS" "LSHIFT" "RSHIFT"
-       "UNARY_BIN_NOT")
+OP_STR=("MUL" "DIV" "MOD" "PLUS" "MINUS")
 
-OP_TKN=("*" "/" "%" "+" "-" "<<" ">>" "~")
+OP_TKN=("*" "/" "%" "+" "-")
 
 OP_COUNT=${#OP_STR[@]}
 
index a916b188441b8f97eaae026d085fc532227488d1..722a6f6ad94e6bcc7a6eb3e73d24dac86032d3d5 100755 (executable)
@@ -24,8 +24,8 @@ STATS_BIN="$TESTDIR/utils/babelstats.pl"
 SESSION_NAME="valid_filter"
 NR_ITER=100
 NUM_GLOBAL_TESTS=2
-NUM_UST_TESTS=1002
-NUM_KERNEL_TESTS=936
+NUM_UST_TESTS=1074
+NUM_KERNEL_TESTS=1008
 NUM_TESTS=$(($NUM_UST_TESTS+$NUM_KERNEL_TESTS+$NUM_GLOBAL_TESTS))
 
 source $TESTDIR/utils/utils.sh
@@ -682,6 +682,42 @@ UST_FILTERS=(
        true_statement
        "0xF00F0F ^ 0xFF0F00 == 0x0F000F"
 
+       true_statement
+       "(1 << 1) == 2"
+
+       true_statement
+       "(4 >> 1) == 2"
+
+       true_statement
+       "(1 << 8) == 256"
+
+       true_statement
+       "(262144 >> 16) == 4"
+
+       true_statement
+       "(~0 & 0xffff) == 0xffff"
+
+       true_statement
+       "(~0 & 0xffffffff) == 0xffffffff"
+
+       true_statement
+       "(~0 & 0xffffffffffffffff) == 0xffffffffffffffff"
+
+       true_statement
+       "-1==~0"
+
+       true_statement
+       "1<<1==2"       # C99 operator priority: comparator before bitwise
+
+       has_no_event
+       "!(1<<1==2)"    # C99 operator priority: comparator before bitwise
+
+       true_statement
+       "(1 << 32) == 4294967296"
+
+       true_statement
+       "(1 << 63) == 9223372036854775808"
+
        true_statement
        "arrfield1[2] & 1 == 1"
 
@@ -1107,6 +1143,42 @@ KERNEL_FILTERS=(
        true_statement
        "0xF00F0F ^ 0xFF0F00 == 0x0F000F"
 
+       true_statement
+       "(1 << 1) == 2"
+
+       true_statement
+       "(4 >> 1) == 2"
+
+       true_statement
+       "(1 << 8) == 256"
+
+       true_statement
+       "(262144 >> 16) == 4"
+
+       true_statement
+       "(~0 & 0xffff) == 0xffff"
+
+       true_statement
+       "(~0 & 0xffffffff) == 0xffffffff"
+
+       true_statement
+       "(~0 & 0xffffffffffffffff) == 0xffffffffffffffff"
+
+       true_statement
+       "-1==~0"
+
+       true_statement
+       "1<<1==2"       # C99 operator priority: comparator before bitwise
+
+       has_no_event
+       "!(1<<1==2)"    # C99 operator priority: comparator before bitwise
+
+       true_statement
+       "(1 << 32) == 4294967296"
+
+       true_statement
+       "(1 << 63) == 9223372036854775808"
+
        true_statement
        "arrfield1[2] & 1 == 1"
 
This page took 0.031624 seconds and 4 git commands to generate.