Fix: syscall event rule: emission sites not compared in is_equal
[lttng-tools.git] / src / common / filter / filter-visitor-generate-ir.cpp
CommitLineData
953192ba
MD
1/*
2 * filter-visitor-generate-ir.c
3 *
4 * LTTng filter generate intermediate representation
5 *
ab5be9fa 6 * Copyright 2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
953192ba 7 *
ab5be9fa 8 * SPDX-License-Identifier: LGPL-2.1-only
953192ba 9 *
953192ba
MD
10 */
11
c9e313bc 12#include "filter-ast.hpp"
c9e313bc 13#include "filter-ir.hpp"
28ab034a 14#include "filter-parser.hpp"
953192ba 15
c9e313bc
SM
16#include <common/compat/errno.hpp>
17#include <common/macros.hpp>
18#include <common/string-utils/string-utils.hpp>
a187da1a 19
28ab034a
JG
20#include <inttypes.h>
21#include <stdio.h>
22#include <stdlib.h>
23#include <string.h>
24#include <unistd.h>
25
26static struct ir_op *
27generate_ir_recursive(struct filter_parser_ctx *ctx, struct filter_node *node, enum ir_side side);
953192ba 28
28ab034a 29static struct ir_op *make_op_root(struct ir_op *child, enum ir_side side)
953192ba
MD
30{
31 struct ir_op *op;
32
64803277 33 op = zmalloc<ir_op>();
953192ba
MD
34 if (!op)
35 return NULL;
36 switch (child->data_type) {
37 case IR_DATA_UNKNOWN:
38 default:
39 fprintf(stderr, "[error] Unknown root child data type\n");
7d8868f9 40 free(op);
953192ba
MD
41 return NULL;
42 case IR_DATA_STRING:
43 fprintf(stderr, "[error] String cannot be root data type\n");
7d8868f9 44 free(op);
953192ba
MD
45 return NULL;
46 case IR_DATA_NUMERIC:
47 case IR_DATA_FIELD_REF:
586dc72f 48 case IR_DATA_GET_CONTEXT_REF:
bff988fa 49 case IR_DATA_EXPRESSION:
953192ba
MD
50 /* ok */
51 break;
52 }
53 op->op = IR_OP_ROOT;
54 op->side = side;
55 op->data_type = child->data_type;
56 op->signedness = child->signedness;
57 op->u.root.child = child;
58 return op;
59}
60
28ab034a 61static enum ir_load_string_type get_literal_string_type(const char *string)
9f449915 62{
a0377dfe 63 LTTNG_ASSERT(string);
9f449915
PP
64
65 if (strutils_is_star_glob_pattern(string)) {
66 if (strutils_is_star_at_the_end_only_glob_pattern(string)) {
67 return IR_LOAD_STRING_TYPE_GLOB_STAR_END;
68 }
69
70 return IR_LOAD_STRING_TYPE_GLOB_STAR;
71 }
72
73 return IR_LOAD_STRING_TYPE_PLAIN;
74}
75
28ab034a 76static struct ir_op *make_op_load_string(const char *string, enum ir_side side)
953192ba
MD
77{
78 struct ir_op *op;
79
64803277 80 op = zmalloc<ir_op>();
953192ba
MD
81 if (!op)
82 return NULL;
83 op->op = IR_OP_LOAD;
84 op->data_type = IR_DATA_STRING;
85 op->signedness = IR_SIGN_UNKNOWN;
86 op->side = side;
9f449915
PP
87 op->u.load.u.string.type = get_literal_string_type(string);
88 op->u.load.u.string.value = strdup(string);
89 if (!op->u.load.u.string.value) {
953192ba
MD
90 free(op);
91 return NULL;
92 }
93 return op;
94}
95
28ab034a 96static struct ir_op *make_op_load_numeric(int64_t v, enum ir_side side)
953192ba
MD
97{
98 struct ir_op *op;
99
64803277 100 op = zmalloc<ir_op>();
953192ba
MD
101 if (!op)
102 return NULL;
103 op->op = IR_OP_LOAD;
104 op->data_type = IR_DATA_NUMERIC;
105 /* TODO: for now, all numeric values are signed */
106 op->signedness = IR_SIGNED;
107 op->side = side;
108 op->u.load.u.num = v;
109 return op;
110}
111
28ab034a 112static struct ir_op *make_op_load_float(double v, enum ir_side side)
e90d8561
MD
113{
114 struct ir_op *op;
115
64803277 116 op = zmalloc<ir_op>();
e90d8561
MD
117 if (!op)
118 return NULL;
119 op->op = IR_OP_LOAD;
120 op->data_type = IR_DATA_FLOAT;
121 op->signedness = IR_SIGN_UNKNOWN;
122 op->side = side;
123 op->u.load.u.flt = v;
124 return op;
125}
126
28ab034a 127static void free_load_expression(struct ir_load_expression *load_expression)
953192ba 128{
bff988fa 129 struct ir_load_expression_op *exp_op;
953192ba 130
bff988fa
MD
131 if (!load_expression)
132 return;
133 exp_op = load_expression->child;
134 for (;;) {
135 struct ir_load_expression_op *prev_exp_op;
661dfdd1 136
bff988fa
MD
137 if (!exp_op)
138 break;
139 switch (exp_op->type) {
140 case IR_LOAD_EXPRESSION_GET_CONTEXT_ROOT:
141 case IR_LOAD_EXPRESSION_GET_APP_CONTEXT_ROOT:
142 case IR_LOAD_EXPRESSION_GET_PAYLOAD_ROOT:
143 case IR_LOAD_EXPRESSION_GET_INDEX:
144 case IR_LOAD_EXPRESSION_LOAD_FIELD:
145 break;
146 case IR_LOAD_EXPRESSION_GET_SYMBOL:
147 free(exp_op->u.symbol);
148 break;
149 }
150 prev_exp_op = exp_op;
151 exp_op = exp_op->next;
152 free(prev_exp_op);
153 }
154 free(load_expression);
661dfdd1
MD
155}
156
bff988fa
MD
157/*
158 * Returns the first node of the chain, after initializing the next
159 * pointers.
160 */
28ab034a 161static struct filter_node *load_expression_get_forward_chain(struct filter_node *node)
661dfdd1 162{
bff988fa 163 struct filter_node *prev_node;
661dfdd1 164
bff988fa 165 for (;;) {
a0377dfe 166 LTTNG_ASSERT(node->type == NODE_EXPRESSION);
bff988fa
MD
167 prev_node = node;
168 node = node->u.expression.prev;
169 if (!node) {
170 break;
171 }
172 node->u.expression.next = prev_node;
953192ba 173 }
bff988fa 174 return prev_node;
953192ba
MD
175}
176
28ab034a 177static struct ir_load_expression *create_load_expression(struct filter_node *node)
586dc72f 178{
bff988fa
MD
179 struct ir_load_expression *load_exp;
180 struct ir_load_expression_op *load_exp_op, *prev_op;
b53d4e59 181 const char *str;
586dc72f 182
bff988fa
MD
183 /* Get forward chain. */
184 node = load_expression_get_forward_chain(node);
185 if (!node)
586dc72f 186 return NULL;
64803277 187 load_exp = zmalloc<ir_load_expression>();
bff988fa
MD
188 if (!load_exp)
189 return NULL;
190
191 /* Root */
64803277 192 load_exp_op = zmalloc<ir_load_expression_op>();
bff988fa
MD
193 if (!load_exp_op)
194 goto error;
195 load_exp->child = load_exp_op;
196 str = node->u.expression.u.string;
197 if (!strcmp(str, "$ctx")) {
198 load_exp_op->type = IR_LOAD_EXPRESSION_GET_CONTEXT_ROOT;
199 node = node->u.expression.next;
200 if (!node) {
201 fprintf(stderr, "[error] Expecting identifier after \'%s\'\n", str);
202 goto error;
203 }
204 str = node->u.expression.u.string;
205 } else if (!strcmp(str, "$app")) {
206 load_exp_op->type = IR_LOAD_EXPRESSION_GET_APP_CONTEXT_ROOT;
207 node = node->u.expression.next;
208 if (!node) {
209 fprintf(stderr, "[error] Expecting identifier after \'%s\'\n", str);
210 goto error;
211 }
212 str = node->u.expression.u.string;
213 } else if (str[0] == '$') {
214 fprintf(stderr, "[error] Unexpected identifier \'%s\'\n", str);
661dfdd1 215 goto error;
bff988fa
MD
216 } else {
217 load_exp_op->type = IR_LOAD_EXPRESSION_GET_PAYLOAD_ROOT;
661dfdd1 218 }
bff988fa
MD
219
220 for (;;) {
221 struct filter_node *bracket_node;
222
223 prev_op = load_exp_op;
64803277 224 load_exp_op = zmalloc<ir_load_expression_op>();
bff988fa
MD
225 if (!load_exp_op)
226 goto error;
227 prev_op->next = load_exp_op;
228 load_exp_op->type = IR_LOAD_EXPRESSION_GET_SYMBOL;
229 load_exp_op->u.symbol = strdup(str);
230 if (!load_exp_op->u.symbol)
231 goto error;
232
233 /* Explore brackets from current node. */
28ab034a
JG
234 for (bracket_node = node->u.expression.next_bracket; bracket_node != NULL;
235 bracket_node = bracket_node->u.expression.next_bracket) {
bff988fa 236 prev_op = load_exp_op;
4062406e 237 if (bracket_node->type != NODE_EXPRESSION ||
28ab034a
JG
238 bracket_node->u.expression.type != AST_EXP_CONSTANT) {
239 fprintf(stderr,
240 "[error] Expecting constant index in array expression\n");
241 goto error;
242 }
64803277 243 load_exp_op = zmalloc<ir_load_expression_op>();
bff988fa
MD
244 if (!load_exp_op)
245 goto error;
246 prev_op->next = load_exp_op;
247 load_exp_op->type = IR_LOAD_EXPRESSION_GET_INDEX;
248 load_exp_op->u.index = bracket_node->u.expression.u.constant;
249 }
250 /* Go to next chain element. */
251 node = node->u.expression.next;
252 if (!node)
253 break;
254 str = node->u.expression.u.string;
255 }
256 /* Add final load field */
257 prev_op = load_exp_op;
64803277 258 load_exp_op = zmalloc<ir_load_expression_op>();
bff988fa
MD
259 if (!load_exp_op)
260 goto error;
261 prev_op->next = load_exp_op;
262 load_exp_op->type = IR_LOAD_EXPRESSION_LOAD_FIELD;
263 return load_exp;
661dfdd1
MD
264
265error:
bff988fa 266 free_load_expression(load_exp);
661dfdd1
MD
267 return NULL;
268}
269
28ab034a 270static struct ir_op *make_op_load_expression(struct filter_node *node, enum ir_side side)
661dfdd1
MD
271{
272 struct ir_op *op;
273
64803277 274 op = zmalloc<ir_op>();
661dfdd1 275 if (!op)
586dc72f 276 return NULL;
661dfdd1 277 op->op = IR_OP_LOAD;
bff988fa 278 op->data_type = IR_DATA_EXPRESSION;
661dfdd1
MD
279 op->signedness = IR_SIGN_DYN;
280 op->side = side;
bff988fa
MD
281 op->u.load.u.expression = create_load_expression(node);
282 if (!op->u.load.u.expression) {
661dfdd1
MD
283 goto error;
284 }
586dc72f 285 return op;
661dfdd1
MD
286
287error:
bff988fa 288 free_load_expression(op->u.load.u.expression);
661dfdd1
MD
289 free(op);
290 return NULL;
586dc72f
MD
291}
292
28ab034a
JG
293static struct ir_op *make_op_unary(enum unary_op_type unary_op_type,
294 const char *op_str,
295 enum ir_op_signedness signedness,
296 struct ir_op *child,
297 enum ir_side side)
953192ba
MD
298{
299 struct ir_op *op = NULL;
300
301 if (child->data_type == IR_DATA_STRING) {
28ab034a
JG
302 fprintf(stderr,
303 "[error] unary operation '%s' not allowed on string literal\n",
304 op_str);
953192ba
MD
305 goto error;
306 }
307
64803277 308 op = zmalloc<ir_op>();
953192ba
MD
309 if (!op)
310 return NULL;
311 op->op = IR_OP_UNARY;
312 op->data_type = child->data_type;
313 op->signedness = signedness;
314 op->side = side;
315 op->u.unary.type = unary_op_type;
316 op->u.unary.child = child;
317 return op;
318
319error:
320 free(op);
321 return NULL;
322}
323
324/*
325 * unary + is pretty much useless.
326 */
28ab034a 327static struct ir_op *make_op_unary_plus(struct ir_op *child, enum ir_side side)
953192ba 328{
28ab034a 329 return make_op_unary(AST_UNARY_PLUS, "+", child->signedness, child, side);
953192ba
MD
330}
331
28ab034a 332static struct ir_op *make_op_unary_minus(struct ir_op *child, enum ir_side side)
953192ba 333{
28ab034a 334 return make_op_unary(AST_UNARY_MINUS, "-", child->signedness, child, side);
953192ba
MD
335}
336
28ab034a 337static struct ir_op *make_op_unary_not(struct ir_op *child, enum ir_side side)
953192ba 338{
28ab034a 339 return make_op_unary(AST_UNARY_NOT, "!", child->signedness, child, side);
953192ba
MD
340}
341
28ab034a 342static struct ir_op *make_op_unary_bit_not(struct ir_op *child, enum ir_side side)
116d3c01 343{
28ab034a 344 return make_op_unary(AST_UNARY_BIT_NOT, "~", child->signedness, child, side);
116d3c01
MD
345}
346
28ab034a
JG
347static struct ir_op *make_op_binary_compare(enum op_type bin_op_type,
348 const char *op_str,
349 struct ir_op *left,
350 struct ir_op *right,
351 enum ir_side side)
953192ba
MD
352{
353 struct ir_op *op = NULL;
354
28ab034a 355 if (left->data_type == IR_DATA_UNKNOWN || right->data_type == IR_DATA_UNKNOWN) {
953192ba
MD
356 fprintf(stderr, "[error] binary operation '%s' has unknown operand type\n", op_str);
357 goto error;
953192ba 358 }
28ab034a
JG
359 if ((left->data_type == IR_DATA_STRING &&
360 (right->data_type == IR_DATA_NUMERIC || right->data_type == IR_DATA_FLOAT)) ||
361 ((left->data_type == IR_DATA_NUMERIC || left->data_type == IR_DATA_FLOAT) &&
362 right->data_type == IR_DATA_STRING)) {
953192ba
MD
363 fprintf(stderr, "[error] binary operation '%s' operand type mismatch\n", op_str);
364 goto error;
365 }
366
64803277 367 op = zmalloc<ir_op>();
953192ba
MD
368 if (!op)
369 return NULL;
370 op->op = IR_OP_BINARY;
371 op->u.binary.type = bin_op_type;
372 op->u.binary.left = left;
373 op->u.binary.right = right;
374
375 /* we return a boolean, represented as signed numeric */
376 op->data_type = IR_DATA_NUMERIC;
377 op->signedness = IR_SIGNED;
378 op->side = side;
379
380 return op;
381
382error:
383 free(op);
384 return NULL;
385}
386
28ab034a 387static struct ir_op *make_op_binary_eq(struct ir_op *left, struct ir_op *right, enum ir_side side)
953192ba
MD
388{
389 return make_op_binary_compare(AST_OP_EQ, "==", left, right, side);
390}
391
28ab034a 392static struct ir_op *make_op_binary_ne(struct ir_op *left, struct ir_op *right, enum ir_side side)
953192ba
MD
393{
394 return make_op_binary_compare(AST_OP_NE, "!=", left, right, side);
395}
396
28ab034a 397static struct ir_op *make_op_binary_gt(struct ir_op *left, struct ir_op *right, enum ir_side side)
953192ba
MD
398{
399 return make_op_binary_compare(AST_OP_GT, ">", left, right, side);
400}
401
28ab034a 402static struct ir_op *make_op_binary_lt(struct ir_op *left, struct ir_op *right, enum ir_side side)
953192ba
MD
403{
404 return make_op_binary_compare(AST_OP_LT, "<", left, right, side);
405}
406
28ab034a 407static struct ir_op *make_op_binary_ge(struct ir_op *left, struct ir_op *right, enum ir_side side)
953192ba
MD
408{
409 return make_op_binary_compare(AST_OP_GE, ">=", left, right, side);
410}
411
28ab034a 412static struct ir_op *make_op_binary_le(struct ir_op *left, struct ir_op *right, enum ir_side side)
953192ba
MD
413{
414 return make_op_binary_compare(AST_OP_LE, "<=", left, right, side);
415}
416
28ab034a
JG
417static struct ir_op *make_op_binary_logical(enum op_type bin_op_type,
418 const char *op_str,
419 struct ir_op *left,
420 struct ir_op *right,
421 enum ir_side side)
953192ba
MD
422{
423 struct ir_op *op = NULL;
424
28ab034a 425 if (left->data_type == IR_DATA_UNKNOWN || right->data_type == IR_DATA_UNKNOWN) {
953192ba
MD
426 fprintf(stderr, "[error] binary operation '%s' has unknown operand type\n", op_str);
427 goto error;
953192ba 428 }
28ab034a
JG
429 if (left->data_type == IR_DATA_STRING || right->data_type == IR_DATA_STRING) {
430 fprintf(stderr,
431 "[error] logical binary operation '%s' cannot have string operand\n",
432 op_str);
953192ba
MD
433 goto error;
434 }
435
64803277 436 op = zmalloc<ir_op>();
953192ba
MD
437 if (!op)
438 return NULL;
439 op->op = IR_OP_LOGICAL;
440 op->u.binary.type = bin_op_type;
441 op->u.binary.left = left;
442 op->u.binary.right = right;
443
444 /* we return a boolean, represented as signed numeric */
445 op->data_type = IR_DATA_NUMERIC;
446 op->signedness = IR_SIGNED;
447 op->side = side;
448
449 return op;
450
451error:
452 free(op);
453 return NULL;
454}
455
28ab034a
JG
456static struct ir_op *make_op_binary_bitwise(enum op_type bin_op_type,
457 const char *op_str,
458 struct ir_op *left,
459 struct ir_op *right,
460 enum ir_side side)
bff988fa
MD
461{
462 struct ir_op *op = NULL;
463
28ab034a
JG
464 if (left->data_type == IR_DATA_UNKNOWN || right->data_type == IR_DATA_UNKNOWN) {
465 fprintf(stderr,
466 "[error] bitwise binary operation '%s' has unknown operand type\n",
467 op_str);
bff988fa 468 goto error;
bff988fa 469 }
28ab034a
JG
470 if (left->data_type == IR_DATA_STRING || right->data_type == IR_DATA_STRING) {
471 fprintf(stderr,
472 "[error] bitwise binary operation '%s' cannot have string operand\n",
473 op_str);
bff988fa
MD
474 goto error;
475 }
28ab034a
JG
476 if (left->data_type == IR_DATA_FLOAT || right->data_type == IR_DATA_FLOAT) {
477 fprintf(stderr,
478 "[error] bitwise binary operation '%s' cannot have floating point operand\n",
479 op_str);
bff988fa
MD
480 goto error;
481 }
482
64803277 483 op = zmalloc<ir_op>();
bff988fa
MD
484 if (!op)
485 return NULL;
486 op->op = IR_OP_BINARY;
487 op->u.binary.type = bin_op_type;
488 op->u.binary.left = left;
489 op->u.binary.right = right;
490
491 /* we return a signed numeric */
492 op->data_type = IR_DATA_NUMERIC;
493 op->signedness = IR_SIGNED;
494 op->side = side;
495
496 return op;
497
498error:
499 free(op);
500 return NULL;
501}
502
28ab034a
JG
503static struct ir_op *
504make_op_binary_logical_and(struct ir_op *left, struct ir_op *right, enum ir_side side)
953192ba
MD
505{
506 return make_op_binary_logical(AST_OP_AND, "&&", left, right, side);
507}
508
28ab034a
JG
509static struct ir_op *
510make_op_binary_logical_or(struct ir_op *left, struct ir_op *right, enum ir_side side)
953192ba
MD
511{
512 return make_op_binary_logical(AST_OP_OR, "||", left, right, side);
513}
514
28ab034a
JG
515static struct ir_op *
516make_op_binary_bitwise_rshift(struct ir_op *left, struct ir_op *right, enum ir_side side)
116d3c01
MD
517{
518 return make_op_binary_bitwise(AST_OP_BIT_RSHIFT, ">>", left, right, side);
519}
520
28ab034a
JG
521static struct ir_op *
522make_op_binary_bitwise_lshift(struct ir_op *left, struct ir_op *right, enum ir_side side)
116d3c01
MD
523{
524 return make_op_binary_bitwise(AST_OP_BIT_LSHIFT, "<<", left, right, side);
525}
526
28ab034a
JG
527static struct ir_op *
528make_op_binary_bitwise_and(struct ir_op *left, struct ir_op *right, enum ir_side side)
bff988fa
MD
529{
530 return make_op_binary_bitwise(AST_OP_BIT_AND, "&", left, right, side);
531}
532
28ab034a
JG
533static struct ir_op *
534make_op_binary_bitwise_or(struct ir_op *left, struct ir_op *right, enum ir_side side)
bff988fa
MD
535{
536 return make_op_binary_bitwise(AST_OP_BIT_OR, "|", left, right, side);
537}
538
28ab034a
JG
539static struct ir_op *
540make_op_binary_bitwise_xor(struct ir_op *left, struct ir_op *right, enum ir_side side)
bff988fa
MD
541{
542 return make_op_binary_bitwise(AST_OP_BIT_XOR, "^", left, right, side);
543}
544
28ab034a 545static void filter_free_ir_recursive(struct ir_op *op)
953192ba
MD
546{
547 if (!op)
548 return;
549 switch (op->op) {
550 case IR_OP_UNKNOWN:
551 default:
28ab034a 552 fprintf(stderr, "[error] Unknown op type in %s\n", __func__);
953192ba
MD
553 break;
554 case IR_OP_ROOT:
555 filter_free_ir_recursive(op->u.root.child);
556 break;
557 case IR_OP_LOAD:
558 switch (op->data_type) {
559 case IR_DATA_STRING:
9f449915 560 free(op->u.load.u.string.value);
953192ba 561 break;
28ab034a 562 case IR_DATA_FIELD_REF: /* fall-through */
586dc72f 563 case IR_DATA_GET_CONTEXT_REF:
953192ba
MD
564 free(op->u.load.u.ref);
565 break;
bff988fa
MD
566 case IR_DATA_EXPRESSION:
567 free_load_expression(op->u.load.u.expression);
953192ba
MD
568 default:
569 break;
570 }
571 break;
572 case IR_OP_UNARY:
573 filter_free_ir_recursive(op->u.unary.child);
574 break;
575 case IR_OP_BINARY:
576 filter_free_ir_recursive(op->u.binary.left);
577 filter_free_ir_recursive(op->u.binary.right);
578 break;
579 case IR_OP_LOGICAL:
580 filter_free_ir_recursive(op->u.logical.left);
581 filter_free_ir_recursive(op->u.logical.right);
582 break;
583 }
584 free(op);
585}
586
28ab034a
JG
587static struct ir_op *
588make_expression(struct filter_parser_ctx *ctx, struct filter_node *node, enum ir_side side)
953192ba
MD
589{
590 switch (node->u.expression.type) {
591 case AST_EXP_UNKNOWN:
592 default:
593 fprintf(stderr, "[error] %s: unknown expression type\n", __func__);
594 return NULL;
595
596 case AST_EXP_STRING:
597 return make_op_load_string(node->u.expression.u.string, side);
598 case AST_EXP_CONSTANT:
28ab034a 599 return make_op_load_numeric(node->u.expression.u.constant, side);
e90d8561 600 case AST_EXP_FLOAT_CONSTANT:
28ab034a 601 return make_op_load_float(node->u.expression.u.float_constant, side);
953192ba 602 case AST_EXP_IDENTIFIER:
586dc72f 603 case AST_EXP_GLOBAL_IDENTIFIER:
bff988fa 604 return make_op_load_expression(node, side);
953192ba 605 case AST_EXP_NESTED:
28ab034a 606 return generate_ir_recursive(ctx, node->u.expression.u.child, side);
953192ba
MD
607 }
608}
609
28ab034a
JG
610static struct ir_op *
611make_op(struct filter_parser_ctx *ctx, struct filter_node *node, enum ir_side side)
953192ba
MD
612{
613 struct ir_op *op = NULL, *lchild, *rchild;
614 const char *op_str = "?";
615
616 switch (node->u.op.type) {
617 case AST_OP_UNKNOWN:
618 default:
619 fprintf(stderr, "[error] %s: unknown binary op type\n", __func__);
620 return NULL;
621
622 /*
bff988fa
MD
623 * The following binary operators other than comparators and
624 * logical and/or are not supported yet.
953192ba
MD
625 */
626 case AST_OP_MUL:
627 op_str = "*";
628 goto error_not_supported;
629 case AST_OP_DIV:
630 op_str = "/";
631 goto error_not_supported;
632 case AST_OP_MOD:
633 op_str = "%";
634 goto error_not_supported;
635 case AST_OP_PLUS:
636 op_str = "+";
637 goto error_not_supported;
638 case AST_OP_MINUS:
639 op_str = "-";
640 goto error_not_supported;
bff988fa 641
116d3c01
MD
642 case AST_OP_BIT_RSHIFT:
643 case AST_OP_BIT_LSHIFT:
bff988fa
MD
644 case AST_OP_BIT_AND:
645 case AST_OP_BIT_OR:
646 case AST_OP_BIT_XOR:
647 lchild = generate_ir_recursive(ctx, node->u.op.lchild, IR_LEFT);
648 if (!lchild)
649 return NULL;
650 rchild = generate_ir_recursive(ctx, node->u.op.rchild, IR_RIGHT);
651 if (!rchild) {
652 filter_free_ir_recursive(lchild);
653 return NULL;
654 }
655 break;
953192ba
MD
656
657 case AST_OP_EQ:
658 case AST_OP_NE:
659 case AST_OP_GT:
660 case AST_OP_LT:
661 case AST_OP_GE:
662 case AST_OP_LE:
663 lchild = generate_ir_recursive(ctx, node->u.op.lchild, IR_LEFT);
664 if (!lchild)
665 return NULL;
666 rchild = generate_ir_recursive(ctx, node->u.op.rchild, IR_RIGHT);
667 if (!rchild) {
668 filter_free_ir_recursive(lchild);
669 return NULL;
670 }
671 break;
672
673 case AST_OP_AND:
674 case AST_OP_OR:
675 /*
676 * Both children considered as left, since we need to
677 * populate R0.
678 */
679 lchild = generate_ir_recursive(ctx, node->u.op.lchild, IR_LEFT);
680 if (!lchild)
681 return NULL;
682 rchild = generate_ir_recursive(ctx, node->u.op.rchild, IR_LEFT);
683 if (!rchild) {
684 filter_free_ir_recursive(lchild);
685 return NULL;
686 }
687 break;
688 }
689
690 switch (node->u.op.type) {
691 case AST_OP_AND:
692 op = make_op_binary_logical_and(lchild, rchild, side);
693 break;
694 case AST_OP_OR:
695 op = make_op_binary_logical_or(lchild, rchild, side);
696 break;
697 case AST_OP_EQ:
698 op = make_op_binary_eq(lchild, rchild, side);
699 break;
700 case AST_OP_NE:
701 op = make_op_binary_ne(lchild, rchild, side);
702 break;
703 case AST_OP_GT:
704 op = make_op_binary_gt(lchild, rchild, side);
705 break;
706 case AST_OP_LT:
707 op = make_op_binary_lt(lchild, rchild, side);
708 break;
709 case AST_OP_GE:
710 op = make_op_binary_ge(lchild, rchild, side);
711 break;
712 case AST_OP_LE:
713 op = make_op_binary_le(lchild, rchild, side);
714 break;
116d3c01
MD
715 case AST_OP_BIT_RSHIFT:
716 op = make_op_binary_bitwise_rshift(lchild, rchild, side);
717 break;
718 case AST_OP_BIT_LSHIFT:
719 op = make_op_binary_bitwise_lshift(lchild, rchild, side);
720 break;
bff988fa
MD
721 case AST_OP_BIT_AND:
722 op = make_op_binary_bitwise_and(lchild, rchild, side);
723 break;
724 case AST_OP_BIT_OR:
725 op = make_op_binary_bitwise_or(lchild, rchild, side);
726 break;
727 case AST_OP_BIT_XOR:
728 op = make_op_binary_bitwise_xor(lchild, rchild, side);
729 break;
953192ba
MD
730 default:
731 break;
732 }
733
734 if (!op) {
735 filter_free_ir_recursive(rchild);
736 filter_free_ir_recursive(lchild);
737 }
738 return op;
739
740error_not_supported:
28ab034a 741 fprintf(stderr, "[error] %s: binary operation '%s' not supported\n", __func__, op_str);
953192ba
MD
742 return NULL;
743}
744
28ab034a
JG
745static struct ir_op *
746make_unary_op(struct filter_parser_ctx *ctx, struct filter_node *node, enum ir_side side)
953192ba
MD
747{
748 switch (node->u.unary_op.type) {
749 case AST_UNARY_UNKNOWN:
750 default:
751 fprintf(stderr, "[error] %s: unknown unary op type\n", __func__);
752 return NULL;
753
754 case AST_UNARY_PLUS:
755 {
756 struct ir_op *op, *child;
757
28ab034a 758 child = generate_ir_recursive(ctx, node->u.unary_op.child, side);
953192ba
MD
759 if (!child)
760 return NULL;
761 op = make_op_unary_plus(child, side);
762 if (!op) {
763 filter_free_ir_recursive(child);
764 return NULL;
765 }
766 return op;
767 }
768 case AST_UNARY_MINUS:
769 {
770 struct ir_op *op, *child;
771
28ab034a 772 child = generate_ir_recursive(ctx, node->u.unary_op.child, side);
953192ba
MD
773 if (!child)
774 return NULL;
775 op = make_op_unary_minus(child, side);
776 if (!op) {
777 filter_free_ir_recursive(child);
778 return NULL;
779 }
780 return op;
781 }
782 case AST_UNARY_NOT:
783 {
784 struct ir_op *op, *child;
785
28ab034a 786 child = generate_ir_recursive(ctx, node->u.unary_op.child, side);
953192ba
MD
787 if (!child)
788 return NULL;
789 op = make_op_unary_not(child, side);
790 if (!op) {
791 filter_free_ir_recursive(child);
792 return NULL;
793 }
794 return op;
795 }
bff988fa 796 case AST_UNARY_BIT_NOT:
ab78f161 797 {
116d3c01
MD
798 struct ir_op *op, *child;
799
28ab034a 800 child = generate_ir_recursive(ctx, node->u.unary_op.child, side);
116d3c01
MD
801 if (!child)
802 return NULL;
803 op = make_op_unary_bit_not(child, side);
804 if (!op) {
805 filter_free_ir_recursive(child);
806 return NULL;
807 }
808 return op;
ab78f161 809 }
953192ba 810 }
ab78f161 811
ab78f161 812 return NULL;
953192ba
MD
813}
814
28ab034a
JG
815static struct ir_op *
816generate_ir_recursive(struct filter_parser_ctx *ctx, struct filter_node *node, enum ir_side side)
953192ba
MD
817{
818 switch (node->type) {
819 case NODE_UNKNOWN:
820 default:
821 fprintf(stderr, "[error] %s: unknown node type\n", __func__);
822 return NULL;
823
824 case NODE_ROOT:
825 {
826 struct ir_op *op, *child;
827
28ab034a 828 child = generate_ir_recursive(ctx, node->u.root.child, side);
953192ba
MD
829 if (!child)
830 return NULL;
831 op = make_op_root(child, side);
832 if (!op) {
833 filter_free_ir_recursive(child);
834 return NULL;
835 }
836 return op;
837 }
838 case NODE_EXPRESSION:
839 return make_expression(ctx, node, side);
840 case NODE_OP:
841 return make_op(ctx, node, side);
842 case NODE_UNARY_OP:
843 return make_unary_op(ctx, node, side);
844 }
845 return 0;
846}
847
953192ba
MD
848void filter_ir_free(struct filter_parser_ctx *ctx)
849{
850 filter_free_ir_recursive(ctx->ir_root);
851 ctx->ir_root = NULL;
852}
853
854int filter_visitor_ir_generate(struct filter_parser_ctx *ctx)
855{
856 struct ir_op *op;
857
858 op = generate_ir_recursive(ctx, &ctx->ast->root, IR_LEFT);
859 if (!op) {
860 return -EINVAL;
861 }
862 ctx->ir_root = op;
863 return 0;
864}
This page took 0.113762 seconds and 4 git commands to generate.