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