aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dfilter/dfvm.h
diff options
context:
space:
mode:
authorJoão Valverde <j@v6e.pt>2022-04-16 02:42:20 +0100
committerJoão Valverde <j@v6e.pt>2022-04-18 17:10:31 +0100
commitfab32ea0cb5ccbce9327c861f4819b8a6e3980d9 (patch)
treea079ec80c18831281bf7cd1e6afb888bcbcdb9fc /epan/dfilter/dfvm.h
parent92c1519dfef8c42d3899e60beed226cd040a212e (diff)
dfilter: Allow arithmetic expressions as function arguments
This allows writing moderately complex expressions, for example a float epsilon test (#16483): Filter: {abs(_ws.ftypes.double - 1) / max(abs(_ws.ftypes.double), abs(1))} < 0.01 Syntax tree: 0 TEST_LT: 1 OP_DIVIDE: 2 FUNCTION(abs#1): 3 OP_SUBTRACT: 4 FIELD(_ws.ftypes.double) 4 FVALUE(1 <FT_DOUBLE>) 2 FUNCTION(max#2): 3 FUNCTION(abs#1): 4 FIELD(_ws.ftypes.double) 3 FUNCTION(abs#1): 4 FVALUE(1 <FT_DOUBLE>) 1 FVALUE(0.01 <FT_DOUBLE>) Instructions: 00000 READ_TREE _ws.ftypes.double -> reg#1 00001 IF_FALSE_GOTO 3 00002 SUBRACT reg#1 - 1 <FT_DOUBLE> -> reg#2 00003 STACK_PUSH reg#2 00004 CALL_FUNCTION abs(reg#2) -> reg#0 00005 STACK_POP 1 00006 IF_FALSE_GOTO 24 00007 READ_TREE _ws.ftypes.double -> reg#1 00008 IF_FALSE_GOTO 9 00009 STACK_PUSH reg#1 00010 CALL_FUNCTION abs(reg#1) -> reg#4 00011 STACK_POP 1 00012 IF_FALSE_GOTO 13 00013 STACK_PUSH reg#4 00014 STACK_PUSH 1 <FT_DOUBLE> 00015 CALL_FUNCTION abs(1 <FT_DOUBLE>) -> reg#5 00016 STACK_POP 1 00017 IF_FALSE_GOTO 18 00018 STACK_PUSH reg#5 00019 CALL_FUNCTION max(reg#5, reg#4) -> reg#3 00020 STACK_POP 2 00021 IF_FALSE_GOTO 24 00022 DIVIDE reg#0 / reg#3 -> reg#6 00023 ANY_LT reg#6 < 0.01 <FT_DOUBLE> 00024 RETURN We now use a stack to pass arguments to the function. The stack is implemented as a list of lists (list of registers). Arguments may still be non-existent to functions (this is a feature). Functions must check for nil arguments (NULL lists) and handle that case. It's somewhat complicated to allow literal values and test compatibility for different types, both because of lack of type information with unparsed/literal and also because it is an underdeveloped area in the code. In my limited testing it was good enough and useful, further enhancements are left for future work.
Diffstat (limited to 'epan/dfilter/dfvm.h')
-rw-r--r--epan/dfilter/dfvm.h8
1 files changed, 8 insertions, 0 deletions
diff --git a/epan/dfilter/dfvm.h b/epan/dfilter/dfvm.h
index 565e5568fd..c29608ed50 100644
--- a/epan/dfilter/dfvm.h
+++ b/epan/dfilter/dfvm.h
@@ -76,10 +76,15 @@ typedef enum {
DFVM_DIVIDE,
DFVM_MODULO,
CALL_FUNCTION,
+ STACK_PUSH,
+ STACK_POP,
ANY_IN_RANGE
} dfvm_opcode_t;
+const char *
+dfvm_opcode_tostr(dfvm_opcode_t code);
+
typedef struct {
int id;
dfvm_opcode_t op;
@@ -122,6 +127,9 @@ dfvm_value_new_funcdef(df_func_def_t *funcdef);
dfvm_value_t*
dfvm_value_new_pcre(ws_regex_t *re);
+dfvm_value_t*
+dfvm_value_new_guint(guint num);
+
void
dfvm_dump(FILE *f, dfilter_t *df);