Cleanup: apply `include-what-you-use` guideline for `uint*_t`
[lttng-ust.git] / liblttng-ust / lttng-filter-specialize.c
CommitLineData
97b58163
MD
1/*
2 * lttng-filter-specialize.c
3 *
4 * LTTng UST filter code specializer.
5 *
7e50015d 6 * Copyright (C) 2010-2016 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
97b58163 7 *
7e50015d
MD
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
97b58163 14 *
7e50015d
MD
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
97b58163 17 *
7e50015d
MD
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 * SOFTWARE.
97b58163
MD
25 */
26
3fbec7dc 27#define _LGPL_SOURCE
b4051ad8 28#include <stddef.h>
fb31eb73 29#include <stdint.h>
b4051ad8 30
97b58163 31#include "lttng-filter.h"
47e5f13e 32#include <lttng/align.h>
97b58163 33
47e5f13e
MD
34static int lttng_fls(int val)
35{
36 int r = 32;
37 unsigned int x = (unsigned int) val;
38
39 if (!x)
40 return 0;
41 if (!(x & 0xFFFF0000U)) {
42 x <<= 16;
43 r -= 16;
44 }
45 if (!(x & 0xFF000000U)) {
46 x <<= 8;
47 r -= 8;
48 }
49 if (!(x & 0xF0000000U)) {
50 x <<= 4;
51 r -= 4;
52 }
53 if (!(x & 0xC0000000U)) {
54 x <<= 2;
55 r -= 2;
56 }
57 if (!(x & 0x80000000U)) {
58 r -= 1;
59 }
60 return r;
61}
62
63static int get_count_order(unsigned int count)
64{
65 int order;
66
67 order = lttng_fls(count) - 1;
68 if (count & (count - 1))
69 order++;
70 return order;
71}
72
73static ssize_t bytecode_reserve_data(struct bytecode_runtime *runtime,
74 size_t align, size_t len)
75{
76 ssize_t ret;
77 size_t padding = offset_align(runtime->data_len, align);
78 size_t new_len = runtime->data_len + padding + len;
79 size_t new_alloc_len = new_len;
80 size_t old_alloc_len = runtime->data_alloc_len;
81
82 if (new_len > FILTER_MAX_DATA_LEN)
83 return -EINVAL;
84
85 if (new_alloc_len > old_alloc_len) {
86 char *newptr;
87
88 new_alloc_len =
89 max_t(size_t, 1U << get_count_order(new_alloc_len), old_alloc_len << 1);
90 newptr = realloc(runtime->data, new_alloc_len);
91 if (!newptr)
92 return -ENOMEM;
93 runtime->data = newptr;
94 /* We zero directly the memory from start of allocation. */
95 memset(&runtime->data[old_alloc_len], 0, new_alloc_len - old_alloc_len);
96 runtime->data_alloc_len = new_alloc_len;
97 }
98 runtime->data_len += padding;
99 ret = runtime->data_len;
100 runtime->data_len += len;
101 return ret;
102}
103
104static ssize_t bytecode_push_data(struct bytecode_runtime *runtime,
105 const void *p, size_t align, size_t len)
106{
107 ssize_t offset;
108
109 offset = bytecode_reserve_data(runtime, align, len);
110 if (offset < 0)
111 return -ENOMEM;
112 memcpy(&runtime->data[offset], p, len);
113 return offset;
114}
115
116static int specialize_load_field(struct vstack_entry *stack_top,
117 struct load_op *insn)
118{
119 int ret;
120
121 switch (stack_top->load.type) {
122 case LOAD_OBJECT:
123 break;
124 case LOAD_ROOT_CONTEXT:
125 case LOAD_ROOT_APP_CONTEXT:
126 case LOAD_ROOT_PAYLOAD:
127 default:
128 dbg_printf("Filter warning: cannot load root, missing field name.\n");
129 ret = -EINVAL;
130 goto end;
131 }
132 switch (stack_top->load.object_type) {
133 case OBJECT_TYPE_S8:
134 dbg_printf("op load field s8\n");
135 stack_top->type = REG_S64;
136 if (!stack_top->load.rev_bo)
137 insn->op = FILTER_OP_LOAD_FIELD_S8;
138 break;
139 case OBJECT_TYPE_S16:
140 dbg_printf("op load field s16\n");
141 stack_top->type = REG_S64;
142 if (!stack_top->load.rev_bo)
143 insn->op = FILTER_OP_LOAD_FIELD_S16;
144 break;
145 case OBJECT_TYPE_S32:
146 dbg_printf("op load field s32\n");
147 stack_top->type = REG_S64;
148 if (!stack_top->load.rev_bo)
149 insn->op = FILTER_OP_LOAD_FIELD_S32;
150 break;
151 case OBJECT_TYPE_S64:
152 dbg_printf("op load field s64\n");
153 stack_top->type = REG_S64;
154 if (!stack_top->load.rev_bo)
155 insn->op = FILTER_OP_LOAD_FIELD_S64;
156 break;
157 case OBJECT_TYPE_U8:
158 dbg_printf("op load field u8\n");
159 stack_top->type = REG_S64;
160 insn->op = FILTER_OP_LOAD_FIELD_U8;
161 break;
162 case OBJECT_TYPE_U16:
163 dbg_printf("op load field u16\n");
164 stack_top->type = REG_S64;
165 if (!stack_top->load.rev_bo)
166 insn->op = FILTER_OP_LOAD_FIELD_U16;
167 break;
168 case OBJECT_TYPE_U32:
169 dbg_printf("op load field u32\n");
170 stack_top->type = REG_S64;
171 if (!stack_top->load.rev_bo)
172 insn->op = FILTER_OP_LOAD_FIELD_U32;
173 break;
174 case OBJECT_TYPE_U64:
175 dbg_printf("op load field u64\n");
176 stack_top->type = REG_S64;
177 if (!stack_top->load.rev_bo)
178 insn->op = FILTER_OP_LOAD_FIELD_U64;
179 break;
180 case OBJECT_TYPE_DOUBLE:
181 stack_top->type = REG_DOUBLE;
182 insn->op = FILTER_OP_LOAD_FIELD_DOUBLE;
183 break;
184 case OBJECT_TYPE_STRING:
185 dbg_printf("op load field string\n");
186 stack_top->type = REG_STRING;
187 insn->op = FILTER_OP_LOAD_FIELD_STRING;
188 break;
189 case OBJECT_TYPE_STRING_SEQUENCE:
190 dbg_printf("op load field string sequence\n");
191 stack_top->type = REG_STRING;
192 insn->op = FILTER_OP_LOAD_FIELD_SEQUENCE;
193 break;
194 case OBJECT_TYPE_DYNAMIC:
195 dbg_printf("op load field dynamic\n");
196 stack_top->type = REG_UNKNOWN;
197 /* Don't specialize load op. */
198 break;
199 case OBJECT_TYPE_SEQUENCE:
200 case OBJECT_TYPE_ARRAY:
201 case OBJECT_TYPE_STRUCT:
202 case OBJECT_TYPE_VARIANT:
203 ERR("Sequences, arrays, struct and variant cannot be loaded (nested types).");
204 ret = -EINVAL;
205 goto end;
206 }
207 return 0;
208
209end:
210 return ret;
211}
212
213static int specialize_get_index_object_type(enum object_type *otype,
214 int signedness, uint32_t elem_len)
215{
216 switch (elem_len) {
217 case 8:
218 if (signedness)
219 *otype = OBJECT_TYPE_S8;
220 else
221 *otype = OBJECT_TYPE_U8;
222 break;
223 case 16:
224 if (signedness)
225 *otype = OBJECT_TYPE_S16;
226 else
227 *otype = OBJECT_TYPE_U16;
228 break;
229 case 32:
230 if (signedness)
231 *otype = OBJECT_TYPE_S32;
232 else
233 *otype = OBJECT_TYPE_U32;
234 break;
235 case 64:
236 if (signedness)
237 *otype = OBJECT_TYPE_S64;
238 else
239 *otype = OBJECT_TYPE_U64;
240 break;
241 default:
242 return -EINVAL;
243 }
244 return 0;
245}
246
247static int specialize_get_index(struct bytecode_runtime *runtime,
248 struct load_op *insn, uint64_t index,
249 struct vstack_entry *stack_top,
250 int idx_len)
251{
252 int ret;
253 struct filter_get_index_data gid;
254 ssize_t data_offset;
255
256 memset(&gid, 0, sizeof(gid));
257 switch (stack_top->load.type) {
258 case LOAD_OBJECT:
259 switch (stack_top->load.object_type) {
260 case OBJECT_TYPE_ARRAY:
261 {
262 const struct lttng_event_field *field;
263 uint32_t elem_len, num_elems;
264 int signedness;
265
266 field = stack_top->load.field;
267 elem_len = field->type.u.array.elem_type.u.basic.integer.size;
268 signedness = field->type.u.array.elem_type.u.basic.integer.signedness;
269 num_elems = field->type.u.array.length;
270 if (index >= num_elems) {
271 ret = -EINVAL;
272 goto end;
273 }
274 ret = specialize_get_index_object_type(&stack_top->load.object_type,
275 signedness, elem_len);
276 if (ret)
277 goto end;
278 gid.offset = index * (elem_len / CHAR_BIT);
279 gid.array_len = num_elems * (elem_len / CHAR_BIT);
280 gid.elem.type = stack_top->load.object_type;
281 gid.elem.len = elem_len;
282 if (field->type.u.array.elem_type.u.basic.integer.reverse_byte_order)
283 gid.elem.rev_bo = true;
284 stack_top->load.rev_bo = gid.elem.rev_bo;
285 break;
286 }
287 case OBJECT_TYPE_SEQUENCE:
288 {
289 const struct lttng_event_field *field;
290 uint32_t elem_len;
291 int signedness;
292
293 field = stack_top->load.field;
294 elem_len = field->type.u.sequence.elem_type.u.basic.integer.size;
295 signedness = field->type.u.sequence.elem_type.u.basic.integer.signedness;
296 ret = specialize_get_index_object_type(&stack_top->load.object_type,
297 signedness, elem_len);
298 if (ret)
299 goto end;
300 gid.offset = index * (elem_len / CHAR_BIT);
301 gid.elem.type = stack_top->load.object_type;
302 gid.elem.len = elem_len;
303 if (field->type.u.sequence.elem_type.u.basic.integer.reverse_byte_order)
304 gid.elem.rev_bo = true;
305 stack_top->load.rev_bo = gid.elem.rev_bo;
306 break;
307 }
308 case OBJECT_TYPE_STRUCT:
309 /* Only generated by the specialize phase. */
310 case OBJECT_TYPE_VARIANT: /* Fall-through */
311 default:
312 ERR("Unexpected get index type %d",
313 (int) stack_top->load.object_type);
314 ret = -EINVAL;
315 goto end;
316 }
317 break;
318 case LOAD_ROOT_CONTEXT:
319 case LOAD_ROOT_APP_CONTEXT:
320 case LOAD_ROOT_PAYLOAD:
321 ERR("Index lookup for root field not implemented yet.");
322 ret = -EINVAL;
323 goto end;
324 }
325 data_offset = bytecode_push_data(runtime, &gid,
326 __alignof__(gid), sizeof(gid));
327 if (data_offset < 0) {
328 ret = -EINVAL;
329 goto end;
330 }
331 switch (idx_len) {
332 case 2:
333 ((struct get_index_u16 *) insn->data)->index = data_offset;
334 break;
335 case 8:
336 ((struct get_index_u64 *) insn->data)->index = data_offset;
337 break;
338 default:
339 ret = -EINVAL;
340 goto end;
341 }
342
343 return 0;
344
345end:
346 return ret;
347}
348
349static int specialize_context_lookup_name(struct lttng_ctx *ctx,
350 struct bytecode_runtime *bytecode,
351 struct load_op *insn)
352{
353 uint16_t offset;
354 const char *name;
355
356 offset = ((struct get_symbol *) insn->data)->offset;
357 name = bytecode->p.bc->bc.data + bytecode->p.bc->bc.reloc_offset + offset;
358 return lttng_get_context_index(ctx, name);
359}
360
361static int specialize_load_object(const struct lttng_event_field *field,
362 struct vstack_load *load, bool is_context)
363{
364 load->type = LOAD_OBJECT;
365 /*
366 * LTTng-UST layout all integer fields as s64 on the stack for the filter.
367 */
368 switch (field->type.atype) {
369 case atype_integer:
370 if (field->type.u.basic.integer.signedness)
371 load->object_type = OBJECT_TYPE_S64;
372 else
373 load->object_type = OBJECT_TYPE_U64;
374 load->rev_bo = false;
375 break;
376 case atype_enum:
377 {
378 const struct lttng_integer_type *itype =
379 &field->type.u.basic.enumeration.container_type;
380
381 if (itype->signedness)
382 load->object_type = OBJECT_TYPE_S64;
383 else
384 load->object_type = OBJECT_TYPE_U64;
385 load->rev_bo = false;
386 break;
387 }
388 case atype_array:
389 if (field->type.u.array.elem_type.atype != atype_integer) {
390 ERR("Array nesting only supports integer types.");
391 return -EINVAL;
392 }
393 if (is_context) {
394 load->object_type = OBJECT_TYPE_STRING;
395 } else {
396 if (field->type.u.array.elem_type.u.basic.integer.encoding == lttng_encode_none) {
397 load->object_type = OBJECT_TYPE_ARRAY;
398 load->field = field;
399 } else {
400 load->object_type = OBJECT_TYPE_STRING_SEQUENCE;
401 }
402 }
403 break;
404 case atype_sequence:
405 if (field->type.u.sequence.elem_type.atype != atype_integer) {
406 ERR("Sequence nesting only supports integer types.");
407 return -EINVAL;
408 }
409 if (is_context) {
410 load->object_type = OBJECT_TYPE_STRING;
411 } else {
412 if (field->type.u.sequence.elem_type.u.basic.integer.encoding == lttng_encode_none) {
413 load->object_type = OBJECT_TYPE_SEQUENCE;
414 load->field = field;
415 } else {
416 load->object_type = OBJECT_TYPE_STRING_SEQUENCE;
417 }
418 }
419 break;
420 case atype_string:
421 load->object_type = OBJECT_TYPE_STRING;
422 break;
423 case atype_float:
424 load->object_type = OBJECT_TYPE_DOUBLE;
425 break;
426 case atype_dynamic:
427 load->object_type = OBJECT_TYPE_DYNAMIC;
8d3190bd 428 break;
47e5f13e
MD
429 case atype_struct:
430 ERR("Structure type cannot be loaded.");
431 return -EINVAL;
432 default:
433 ERR("Unknown type: %d", (int) field->type.atype);
434 return -EINVAL;
435 }
436 return 0;
437}
438
439static int specialize_context_lookup(struct lttng_session *session,
440 struct bytecode_runtime *runtime,
441 struct load_op *insn,
442 struct vstack_load *load)
443{
444 int idx, ret;
445 struct lttng_ctx_field *ctx_field;
446 struct lttng_event_field *field;
447 struct filter_get_index_data gid;
448 ssize_t data_offset;
449
450 idx = specialize_context_lookup_name(session->ctx, runtime, insn);
451 if (idx < 0) {
452 return -ENOENT;
453 }
454 ctx_field = &session->ctx->fields[idx];
455 field = &ctx_field->event_field;
456 ret = specialize_load_object(field, load, true);
457 if (ret)
458 return ret;
459 /* Specialize each get_symbol into a get_index. */
460 insn->op = FILTER_OP_GET_INDEX_U16;
461 memset(&gid, 0, sizeof(gid));
462 gid.ctx_index = idx;
463 gid.elem.type = load->object_type;
464 data_offset = bytecode_push_data(runtime, &gid,
465 __alignof__(gid), sizeof(gid));
466 if (data_offset < 0) {
467 return -EINVAL;
468 }
469 ((struct get_index_u16 *) insn->data)->index = data_offset;
470 return 0;
471}
472
473static int specialize_app_context_lookup(struct lttng_session *session,
474 struct bytecode_runtime *runtime,
475 struct load_op *insn,
476 struct vstack_load *load)
477{
478 uint16_t offset;
479 const char *orig_name;
480 char *name = NULL;
481 int idx, ret;
482 struct lttng_ctx_field *ctx_field;
483 struct lttng_event_field *field;
484 struct filter_get_index_data gid;
485 ssize_t data_offset;
486
487 offset = ((struct get_symbol *) insn->data)->offset;
488 orig_name = runtime->p.bc->bc.data + runtime->p.bc->bc.reloc_offset + offset;
489 name = zmalloc(strlen(orig_name) + strlen("$app.") + 1);
490 if (!name) {
491 ret = -ENOMEM;
492 goto end;
493 }
494 strcpy(name, "$app.");
495 strcat(name, orig_name);
496 idx = lttng_get_context_index(session->ctx, name);
497 if (idx < 0) {
498 assert(lttng_context_is_app(name));
499 ret = lttng_ust_add_app_context_to_ctx_rcu(name,
500 &session->ctx);
501 if (ret)
502 return ret;
503 idx = lttng_get_context_index(session->ctx,
504 name);
505 if (idx < 0)
506 return -ENOENT;
507 }
508 ctx_field = &session->ctx->fields[idx];
509 field = &ctx_field->event_field;
510 ret = specialize_load_object(field, load, true);
511 if (ret)
512 goto end;
513 /* Specialize each get_symbol into a get_index. */
514 insn->op = FILTER_OP_GET_INDEX_U16;
515 memset(&gid, 0, sizeof(gid));
516 gid.ctx_index = idx;
517 gid.elem.type = load->object_type;
518 data_offset = bytecode_push_data(runtime, &gid,
519 __alignof__(gid), sizeof(gid));
520 if (data_offset < 0) {
521 ret = -EINVAL;
522 goto end;
523 }
524 ((struct get_index_u16 *) insn->data)->index = data_offset;
525 ret = 0;
526end:
527 free(name);
528 return ret;
529}
530
531static int specialize_event_payload_lookup(struct lttng_event *event,
532 struct bytecode_runtime *runtime,
533 struct load_op *insn,
534 struct vstack_load *load)
535{
536 const char *name;
537 uint16_t offset;
538 const struct lttng_event_desc *desc = event->desc;
539 unsigned int i, nr_fields;
540 bool found = false;
541 uint32_t field_offset = 0;
542 const struct lttng_event_field *field;
543 int ret;
544 struct filter_get_index_data gid;
545 ssize_t data_offset;
546
547 nr_fields = desc->nr_fields;
548 offset = ((struct get_symbol *) insn->data)->offset;
549 name = runtime->p.bc->bc.data + runtime->p.bc->bc.reloc_offset + offset;
550 for (i = 0; i < nr_fields; i++) {
551 field = &desc->fields[i];
552 if (!strcmp(field->name, name)) {
553 found = true;
554 break;
555 }
556 /* compute field offset on stack */
557 switch (field->type.atype) {
558 case atype_integer:
559 case atype_enum:
560 field_offset += sizeof(int64_t);
561 break;
562 case atype_array:
563 case atype_sequence:
564 field_offset += sizeof(unsigned long);
565 field_offset += sizeof(void *);
566 break;
567 case atype_string:
568 field_offset += sizeof(void *);
569 break;
570 case atype_float:
571 field_offset += sizeof(double);
572 break;
573 default:
574 ret = -EINVAL;
575 goto end;
576 }
577 }
578 if (!found) {
579 ret = -EINVAL;
580 goto end;
581 }
582
583 ret = specialize_load_object(field, load, false);
584 if (ret)
585 goto end;
586
587 /* Specialize each get_symbol into a get_index. */
588 insn->op = FILTER_OP_GET_INDEX_U16;
589 memset(&gid, 0, sizeof(gid));
590 gid.offset = field_offset;
591 gid.elem.type = load->object_type;
592 data_offset = bytecode_push_data(runtime, &gid,
593 __alignof__(gid), sizeof(gid));
594 if (data_offset < 0) {
595 ret = -EINVAL;
596 goto end;
597 }
598 ((struct get_index_u16 *) insn->data)->index = data_offset;
599 ret = 0;
600end:
601 return ret;
602}
603
604int lttng_filter_specialize_bytecode(struct lttng_event *event,
605 struct bytecode_runtime *bytecode)
97b58163
MD
606{
607 void *pc, *next_pc, *start_pc;
608 int ret = -EINVAL;
0305960f
MD
609 struct vstack _stack;
610 struct vstack *stack = &_stack;
47e5f13e 611 struct lttng_session *session = bytecode->p.session;
97b58163 612
0305960f 613 vstack_init(stack);
97b58163 614
47e5f13e 615 start_pc = &bytecode->code[0];
97b58163
MD
616 for (pc = next_pc = start_pc; pc - start_pc < bytecode->len;
617 pc = next_pc) {
618 switch (*(filter_opcode_t *) pc) {
619 case FILTER_OP_UNKNOWN:
620 default:
621 ERR("unknown bytecode op %u\n",
622 (unsigned int) *(filter_opcode_t *) pc);
623 ret = -EINVAL;
624 goto end;
625
626 case FILTER_OP_RETURN:
93c591bb
MD
627 if (vstack_ax(stack)->type == REG_S64)
628 *(filter_opcode_t *) pc = FILTER_OP_RETURN_S64;
629 ret = 0;
630 goto end;
631
632 case FILTER_OP_RETURN_S64:
633 if (vstack_ax(stack)->type != REG_S64) {
634 ERR("Unexpected register type\n");
635 ret = -EINVAL;
636 goto end;
637 }
97b58163
MD
638 ret = 0;
639 goto end;
640
641 /* binary */
642 case FILTER_OP_MUL:
643 case FILTER_OP_DIV:
644 case FILTER_OP_MOD:
645 case FILTER_OP_PLUS:
646 case FILTER_OP_MINUS:
97b58163
MD
647 ERR("unsupported bytecode op %u\n",
648 (unsigned int) *(filter_opcode_t *) pc);
649 ret = -EINVAL;
650 goto end;
651
652 case FILTER_OP_EQ:
653 {
654 struct binary_op *insn = (struct binary_op *) pc;
655
0305960f 656 switch(vstack_ax(stack)->type) {
97b58163
MD
657 default:
658 ERR("unknown register type\n");
659 ret = -EINVAL;
660 goto end;
661
662 case REG_STRING:
53569322
MD
663 if (vstack_bx(stack)->type == REG_UNKNOWN)
664 break;
3151a51d
PP
665 if (vstack_bx(stack)->type == REG_STAR_GLOB_STRING)
666 insn->op = FILTER_OP_EQ_STAR_GLOB_STRING;
667 else
668 insn->op = FILTER_OP_EQ_STRING;
669 break;
670 case REG_STAR_GLOB_STRING:
671 if (vstack_bx(stack)->type == REG_UNKNOWN)
672 break;
673 insn->op = FILTER_OP_EQ_STAR_GLOB_STRING;
97b58163
MD
674 break;
675 case REG_S64:
53569322
MD
676 if (vstack_bx(stack)->type == REG_UNKNOWN)
677 break;
0305960f 678 if (vstack_bx(stack)->type == REG_S64)
97b58163
MD
679 insn->op = FILTER_OP_EQ_S64;
680 else
dbea82ec 681 insn->op = FILTER_OP_EQ_DOUBLE_S64;
97b58163
MD
682 break;
683 case REG_DOUBLE:
53569322
MD
684 if (vstack_bx(stack)->type == REG_UNKNOWN)
685 break;
dbea82ec
MD
686 if (vstack_bx(stack)->type == REG_S64)
687 insn->op = FILTER_OP_EQ_S64_DOUBLE;
688 else
689 insn->op = FILTER_OP_EQ_DOUBLE;
97b58163 690 break;
53569322
MD
691 case REG_UNKNOWN:
692 break; /* Dynamic typing. */
97b58163 693 }
0305960f
MD
694 /* Pop 2, push 1 */
695 if (vstack_pop(stack)) {
696 ret = -EINVAL;
697 goto end;
698 }
699 vstack_ax(stack)->type = REG_S64;
97b58163
MD
700 next_pc += sizeof(struct binary_op);
701 break;
702 }
703
704 case FILTER_OP_NE:
705 {
706 struct binary_op *insn = (struct binary_op *) pc;
707
0305960f 708 switch(vstack_ax(stack)->type) {
97b58163
MD
709 default:
710 ERR("unknown register type\n");
711 ret = -EINVAL;
712 goto end;
713
714 case REG_STRING:
53569322
MD
715 if (vstack_bx(stack)->type == REG_UNKNOWN)
716 break;
3151a51d
PP
717 if (vstack_bx(stack)->type == REG_STAR_GLOB_STRING)
718 insn->op = FILTER_OP_NE_STAR_GLOB_STRING;
719 else
720 insn->op = FILTER_OP_NE_STRING;
721 break;
722 case REG_STAR_GLOB_STRING:
723 if (vstack_bx(stack)->type == REG_UNKNOWN)
724 break;
725 insn->op = FILTER_OP_NE_STAR_GLOB_STRING;
97b58163
MD
726 break;
727 case REG_S64:
53569322
MD
728 if (vstack_bx(stack)->type == REG_UNKNOWN)
729 break;
0305960f 730 if (vstack_bx(stack)->type == REG_S64)
97b58163
MD
731 insn->op = FILTER_OP_NE_S64;
732 else
dbea82ec 733 insn->op = FILTER_OP_NE_DOUBLE_S64;
97b58163
MD
734 break;
735 case REG_DOUBLE:
53569322
MD
736 if (vstack_bx(stack)->type == REG_UNKNOWN)
737 break;
dbea82ec
MD
738 if (vstack_bx(stack)->type == REG_S64)
739 insn->op = FILTER_OP_NE_S64_DOUBLE;
740 else
741 insn->op = FILTER_OP_NE_DOUBLE;
97b58163 742 break;
53569322
MD
743 case REG_UNKNOWN:
744 break; /* Dynamic typing. */
97b58163 745 }
0305960f
MD
746 /* Pop 2, push 1 */
747 if (vstack_pop(stack)) {
748 ret = -EINVAL;
749 goto end;
750 }
751 vstack_ax(stack)->type = REG_S64;
97b58163
MD
752 next_pc += sizeof(struct binary_op);
753 break;
754 }
755
756 case FILTER_OP_GT:
757 {
758 struct binary_op *insn = (struct binary_op *) pc;
759
0305960f 760 switch(vstack_ax(stack)->type) {
97b58163
MD
761 default:
762 ERR("unknown register type\n");
763 ret = -EINVAL;
764 goto end;
765
3151a51d
PP
766 case REG_STAR_GLOB_STRING:
767 ERR("invalid register type for > binary operator\n");
768 ret = -EINVAL;
769 goto end;
97b58163 770 case REG_STRING:
53569322
MD
771 if (vstack_bx(stack)->type == REG_UNKNOWN)
772 break;
97b58163
MD
773 insn->op = FILTER_OP_GT_STRING;
774 break;
775 case REG_S64:
53569322
MD
776 if (vstack_bx(stack)->type == REG_UNKNOWN)
777 break;
0305960f 778 if (vstack_bx(stack)->type == REG_S64)
97b58163
MD
779 insn->op = FILTER_OP_GT_S64;
780 else
dbea82ec 781 insn->op = FILTER_OP_GT_DOUBLE_S64;
97b58163
MD
782 break;
783 case REG_DOUBLE:
53569322
MD
784 if (vstack_bx(stack)->type == REG_UNKNOWN)
785 break;
dbea82ec
MD
786 if (vstack_bx(stack)->type == REG_S64)
787 insn->op = FILTER_OP_GT_S64_DOUBLE;
788 else
789 insn->op = FILTER_OP_GT_DOUBLE;
97b58163 790 break;
53569322
MD
791 case REG_UNKNOWN:
792 break; /* Dynamic typing. */
97b58163 793 }
0305960f
MD
794 /* Pop 2, push 1 */
795 if (vstack_pop(stack)) {
796 ret = -EINVAL;
797 goto end;
798 }
799 vstack_ax(stack)->type = REG_S64;
97b58163
MD
800 next_pc += sizeof(struct binary_op);
801 break;
802 }
803
804 case FILTER_OP_LT:
805 {
806 struct binary_op *insn = (struct binary_op *) pc;
807
0305960f 808 switch(vstack_ax(stack)->type) {
97b58163
MD
809 default:
810 ERR("unknown register type\n");
811 ret = -EINVAL;
812 goto end;
813
3151a51d
PP
814 case REG_STAR_GLOB_STRING:
815 ERR("invalid register type for < binary operator\n");
816 ret = -EINVAL;
817 goto end;
97b58163 818 case REG_STRING:
53569322
MD
819 if (vstack_bx(stack)->type == REG_UNKNOWN)
820 break;
97b58163
MD
821 insn->op = FILTER_OP_LT_STRING;
822 break;
823 case REG_S64:
53569322
MD
824 if (vstack_bx(stack)->type == REG_UNKNOWN)
825 break;
0305960f 826 if (vstack_bx(stack)->type == REG_S64)
97b58163
MD
827 insn->op = FILTER_OP_LT_S64;
828 else
dbea82ec 829 insn->op = FILTER_OP_LT_DOUBLE_S64;
97b58163
MD
830 break;
831 case REG_DOUBLE:
53569322
MD
832 if (vstack_bx(stack)->type == REG_UNKNOWN)
833 break;
dbea82ec
MD
834 if (vstack_bx(stack)->type == REG_S64)
835 insn->op = FILTER_OP_LT_S64_DOUBLE;
836 else
837 insn->op = FILTER_OP_LT_DOUBLE;
97b58163 838 break;
53569322
MD
839 case REG_UNKNOWN:
840 break; /* Dynamic typing. */
97b58163 841 }
0305960f
MD
842 /* Pop 2, push 1 */
843 if (vstack_pop(stack)) {
844 ret = -EINVAL;
845 goto end;
846 }
847 vstack_ax(stack)->type = REG_S64;
97b58163
MD
848 next_pc += sizeof(struct binary_op);
849 break;
850 }
851
852 case FILTER_OP_GE:
853 {
854 struct binary_op *insn = (struct binary_op *) pc;
855
0305960f 856 switch(vstack_ax(stack)->type) {
97b58163
MD
857 default:
858 ERR("unknown register type\n");
859 ret = -EINVAL;
860 goto end;
861
3151a51d
PP
862 case REG_STAR_GLOB_STRING:
863 ERR("invalid register type for >= binary operator\n");
864 ret = -EINVAL;
865 goto end;
97b58163 866 case REG_STRING:
53569322
MD
867 if (vstack_bx(stack)->type == REG_UNKNOWN)
868 break;
97b58163
MD
869 insn->op = FILTER_OP_GE_STRING;
870 break;
871 case REG_S64:
53569322
MD
872 if (vstack_bx(stack)->type == REG_UNKNOWN)
873 break;
0305960f 874 if (vstack_bx(stack)->type == REG_S64)
97b58163
MD
875 insn->op = FILTER_OP_GE_S64;
876 else
dbea82ec 877 insn->op = FILTER_OP_GE_DOUBLE_S64;
97b58163
MD
878 break;
879 case REG_DOUBLE:
53569322
MD
880 if (vstack_bx(stack)->type == REG_UNKNOWN)
881 break;
dbea82ec
MD
882 if (vstack_bx(stack)->type == REG_S64)
883 insn->op = FILTER_OP_GE_S64_DOUBLE;
884 else
885 insn->op = FILTER_OP_GE_DOUBLE;
97b58163 886 break;
53569322
MD
887 case REG_UNKNOWN:
888 break; /* Dynamic typing. */
97b58163 889 }
0305960f
MD
890 /* Pop 2, push 1 */
891 if (vstack_pop(stack)) {
892 ret = -EINVAL;
893 goto end;
894 }
895 vstack_ax(stack)->type = REG_S64;
97b58163
MD
896 next_pc += sizeof(struct binary_op);
897 break;
898 }
899 case FILTER_OP_LE:
900 {
901 struct binary_op *insn = (struct binary_op *) pc;
902
0305960f 903 switch(vstack_ax(stack)->type) {
97b58163
MD
904 default:
905 ERR("unknown register type\n");
906 ret = -EINVAL;
907 goto end;
908
3151a51d
PP
909 case REG_STAR_GLOB_STRING:
910 ERR("invalid register type for <= binary operator\n");
911 ret = -EINVAL;
912 goto end;
97b58163 913 case REG_STRING:
53569322
MD
914 if (vstack_bx(stack)->type == REG_UNKNOWN)
915 break;
97b58163
MD
916 insn->op = FILTER_OP_LE_STRING;
917 break;
918 case REG_S64:
53569322
MD
919 if (vstack_bx(stack)->type == REG_UNKNOWN)
920 break;
0305960f 921 if (vstack_bx(stack)->type == REG_S64)
97b58163
MD
922 insn->op = FILTER_OP_LE_S64;
923 else
dbea82ec 924 insn->op = FILTER_OP_LE_DOUBLE_S64;
97b58163
MD
925 break;
926 case REG_DOUBLE:
53569322
MD
927 if (vstack_bx(stack)->type == REG_UNKNOWN)
928 break;
dbea82ec
MD
929 if (vstack_bx(stack)->type == REG_S64)
930 insn->op = FILTER_OP_LE_S64_DOUBLE;
931 else
932 insn->op = FILTER_OP_LE_DOUBLE;
97b58163 933 break;
53569322
MD
934 case REG_UNKNOWN:
935 break; /* Dynamic typing. */
97b58163 936 }
0305960f 937 vstack_ax(stack)->type = REG_S64;
97b58163
MD
938 next_pc += sizeof(struct binary_op);
939 break;
940 }
941
942 case FILTER_OP_EQ_STRING:
943 case FILTER_OP_NE_STRING:
944 case FILTER_OP_GT_STRING:
945 case FILTER_OP_LT_STRING:
946 case FILTER_OP_GE_STRING:
947 case FILTER_OP_LE_STRING:
3151a51d
PP
948 case FILTER_OP_EQ_STAR_GLOB_STRING:
949 case FILTER_OP_NE_STAR_GLOB_STRING:
97b58163
MD
950 case FILTER_OP_EQ_S64:
951 case FILTER_OP_NE_S64:
952 case FILTER_OP_GT_S64:
953 case FILTER_OP_LT_S64:
954 case FILTER_OP_GE_S64:
955 case FILTER_OP_LE_S64:
956 case FILTER_OP_EQ_DOUBLE:
957 case FILTER_OP_NE_DOUBLE:
958 case FILTER_OP_GT_DOUBLE:
959 case FILTER_OP_LT_DOUBLE:
960 case FILTER_OP_GE_DOUBLE:
961 case FILTER_OP_LE_DOUBLE:
dbea82ec
MD
962 case FILTER_OP_EQ_DOUBLE_S64:
963 case FILTER_OP_NE_DOUBLE_S64:
964 case FILTER_OP_GT_DOUBLE_S64:
965 case FILTER_OP_LT_DOUBLE_S64:
966 case FILTER_OP_GE_DOUBLE_S64:
967 case FILTER_OP_LE_DOUBLE_S64:
968 case FILTER_OP_EQ_S64_DOUBLE:
969 case FILTER_OP_NE_S64_DOUBLE:
970 case FILTER_OP_GT_S64_DOUBLE:
971 case FILTER_OP_LT_S64_DOUBLE:
972 case FILTER_OP_GE_S64_DOUBLE:
973 case FILTER_OP_LE_S64_DOUBLE:
0039e2d8
MD
974 case FILTER_OP_BIT_RSHIFT:
975 case FILTER_OP_BIT_LSHIFT:
47e5f13e
MD
976 case FILTER_OP_BIT_AND:
977 case FILTER_OP_BIT_OR:
978 case FILTER_OP_BIT_XOR:
97b58163 979 {
0305960f
MD
980 /* Pop 2, push 1 */
981 if (vstack_pop(stack)) {
982 ret = -EINVAL;
983 goto end;
984 }
985 vstack_ax(stack)->type = REG_S64;
97b58163
MD
986 next_pc += sizeof(struct binary_op);
987 break;
988 }
989
990 /* unary */
991 case FILTER_OP_UNARY_PLUS:
992 {
993 struct unary_op *insn = (struct unary_op *) pc;
994
0305960f 995 switch(vstack_ax(stack)->type) {
97b58163
MD
996 default:
997 ERR("unknown register type\n");
998 ret = -EINVAL;
999 goto end;
1000
1001 case REG_S64:
1002 insn->op = FILTER_OP_UNARY_PLUS_S64;
1003 break;
1004 case REG_DOUBLE:
1005 insn->op = FILTER_OP_UNARY_PLUS_DOUBLE;
1006 break;
53569322
MD
1007 case REG_UNKNOWN: /* Dynamic typing. */
1008 break;
97b58163 1009 }
0305960f 1010 /* Pop 1, push 1 */
97b58163
MD
1011 next_pc += sizeof(struct unary_op);
1012 break;
1013 }
1014
1015 case FILTER_OP_UNARY_MINUS:
1016 {
1017 struct unary_op *insn = (struct unary_op *) pc;
1018
0305960f 1019 switch(vstack_ax(stack)->type) {
97b58163
MD
1020 default:
1021 ERR("unknown register type\n");
1022 ret = -EINVAL;
1023 goto end;
1024
1025 case REG_S64:
1026 insn->op = FILTER_OP_UNARY_MINUS_S64;
1027 break;
1028 case REG_DOUBLE:
1029 insn->op = FILTER_OP_UNARY_MINUS_DOUBLE;
1030 break;
53569322
MD
1031 case REG_UNKNOWN: /* Dynamic typing. */
1032 break;
97b58163 1033 }
0305960f 1034 /* Pop 1, push 1 */
97b58163
MD
1035 next_pc += sizeof(struct unary_op);
1036 break;
1037 }
1038
1039 case FILTER_OP_UNARY_NOT:
1040 {
1041 struct unary_op *insn = (struct unary_op *) pc;
1042
0305960f 1043 switch(vstack_ax(stack)->type) {
97b58163
MD
1044 default:
1045 ERR("unknown register type\n");
1046 ret = -EINVAL;
1047 goto end;
1048
1049 case REG_S64:
1050 insn->op = FILTER_OP_UNARY_NOT_S64;
1051 break;
1052 case REG_DOUBLE:
1053 insn->op = FILTER_OP_UNARY_NOT_DOUBLE;
1054 break;
53569322
MD
1055 case REG_UNKNOWN: /* Dynamic typing. */
1056 break;
97b58163 1057 }
0305960f 1058 /* Pop 1, push 1 */
97b58163
MD
1059 next_pc += sizeof(struct unary_op);
1060 break;
1061 }
1062
0039e2d8
MD
1063 case FILTER_OP_UNARY_BIT_NOT:
1064 {
1065 /* Pop 1, push 1 */
1066 next_pc += sizeof(struct unary_op);
1067 break;
1068 }
1069
97b58163
MD
1070 case FILTER_OP_UNARY_PLUS_S64:
1071 case FILTER_OP_UNARY_MINUS_S64:
1072 case FILTER_OP_UNARY_NOT_S64:
1073 case FILTER_OP_UNARY_PLUS_DOUBLE:
1074 case FILTER_OP_UNARY_MINUS_DOUBLE:
1075 case FILTER_OP_UNARY_NOT_DOUBLE:
1076 {
0305960f 1077 /* Pop 1, push 1 */
97b58163
MD
1078 next_pc += sizeof(struct unary_op);
1079 break;
1080 }
1081
1082 /* logical */
1083 case FILTER_OP_AND:
1084 case FILTER_OP_OR:
1085 {
b9f4cd79
MD
1086 /* Continue to next instruction */
1087 /* Pop 1 when jump not taken */
1088 if (vstack_pop(stack)) {
1089 ret = -EINVAL;
1090 goto end;
1091 }
97b58163
MD
1092 next_pc += sizeof(struct logical_op);
1093 break;
1094 }
1095
77aa5901 1096 /* load field ref */
97b58163
MD
1097 case FILTER_OP_LOAD_FIELD_REF:
1098 {
1099 ERR("Unknown field ref type\n");
1100 ret = -EINVAL;
1101 goto end;
1102 }
77aa5901
MD
1103 /* get context ref */
1104 case FILTER_OP_GET_CONTEXT_REF:
1105 {
53569322
MD
1106 if (vstack_push(stack)) {
1107 ret = -EINVAL;
1108 goto end;
1109 }
1110 vstack_ax(stack)->type = REG_UNKNOWN;
1111 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1112 break;
77aa5901 1113 }
97b58163
MD
1114 case FILTER_OP_LOAD_FIELD_REF_STRING:
1115 case FILTER_OP_LOAD_FIELD_REF_SEQUENCE:
77aa5901 1116 case FILTER_OP_GET_CONTEXT_REF_STRING:
97b58163 1117 {
0305960f
MD
1118 if (vstack_push(stack)) {
1119 ret = -EINVAL;
1120 goto end;
1121 }
1122 vstack_ax(stack)->type = REG_STRING;
97b58163
MD
1123 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1124 break;
1125 }
1126 case FILTER_OP_LOAD_FIELD_REF_S64:
77aa5901 1127 case FILTER_OP_GET_CONTEXT_REF_S64:
97b58163 1128 {
0305960f
MD
1129 if (vstack_push(stack)) {
1130 ret = -EINVAL;
1131 goto end;
1132 }
1133 vstack_ax(stack)->type = REG_S64;
97b58163
MD
1134 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1135 break;
1136 }
1137 case FILTER_OP_LOAD_FIELD_REF_DOUBLE:
77aa5901 1138 case FILTER_OP_GET_CONTEXT_REF_DOUBLE:
97b58163 1139 {
0305960f
MD
1140 if (vstack_push(stack)) {
1141 ret = -EINVAL;
1142 goto end;
1143 }
1144 vstack_ax(stack)->type = REG_DOUBLE;
97b58163
MD
1145 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1146 break;
1147 }
1148
77aa5901 1149 /* load from immediate operand */
97b58163
MD
1150 case FILTER_OP_LOAD_STRING:
1151 {
1152 struct load_op *insn = (struct load_op *) pc;
1153
0305960f
MD
1154 if (vstack_push(stack)) {
1155 ret = -EINVAL;
1156 goto end;
1157 }
1158 vstack_ax(stack)->type = REG_STRING;
97b58163
MD
1159 next_pc += sizeof(struct load_op) + strlen(insn->data) + 1;
1160 break;
1161 }
1162
3151a51d
PP
1163 case FILTER_OP_LOAD_STAR_GLOB_STRING:
1164 {
1165 struct load_op *insn = (struct load_op *) pc;
1166
1167 if (vstack_push(stack)) {
1168 ret = -EINVAL;
1169 goto end;
1170 }
1171 vstack_ax(stack)->type = REG_STAR_GLOB_STRING;
1172 next_pc += sizeof(struct load_op) + strlen(insn->data) + 1;
1173 break;
1174 }
1175
97b58163
MD
1176 case FILTER_OP_LOAD_S64:
1177 {
0305960f
MD
1178 if (vstack_push(stack)) {
1179 ret = -EINVAL;
1180 goto end;
1181 }
1182 vstack_ax(stack)->type = REG_S64;
97b58163
MD
1183 next_pc += sizeof(struct load_op)
1184 + sizeof(struct literal_numeric);
1185 break;
1186 }
1187
1188 case FILTER_OP_LOAD_DOUBLE:
1189 {
0305960f
MD
1190 if (vstack_push(stack)) {
1191 ret = -EINVAL;
1192 goto end;
1193 }
1194 vstack_ax(stack)->type = REG_DOUBLE;
97b58163
MD
1195 next_pc += sizeof(struct load_op)
1196 + sizeof(struct literal_double);
1197 break;
1198 }
1199
1200 /* cast */
1201 case FILTER_OP_CAST_TO_S64:
1202 {
1203 struct cast_op *insn = (struct cast_op *) pc;
1204
0305960f 1205 switch (vstack_ax(stack)->type) {
97b58163
MD
1206 default:
1207 ERR("unknown register type\n");
1208 ret = -EINVAL;
1209 goto end;
1210
1211 case REG_STRING:
3151a51d 1212 case REG_STAR_GLOB_STRING:
97b58163
MD
1213 ERR("Cast op can only be applied to numeric or floating point registers\n");
1214 ret = -EINVAL;
1215 goto end;
1216 case REG_S64:
1217 insn->op = FILTER_OP_CAST_NOP;
1218 break;
1219 case REG_DOUBLE:
1220 insn->op = FILTER_OP_CAST_DOUBLE_TO_S64;
1221 break;
53569322
MD
1222 case REG_UNKNOWN:
1223 break;
97b58163 1224 }
0305960f
MD
1225 /* Pop 1, push 1 */
1226 vstack_ax(stack)->type = REG_S64;
97b58163
MD
1227 next_pc += sizeof(struct cast_op);
1228 break;
1229 }
1230 case FILTER_OP_CAST_DOUBLE_TO_S64:
1231 {
0305960f
MD
1232 /* Pop 1, push 1 */
1233 vstack_ax(stack)->type = REG_S64;
97b58163
MD
1234 next_pc += sizeof(struct cast_op);
1235 break;
1236 }
1237 case FILTER_OP_CAST_NOP:
1238 {
1239 next_pc += sizeof(struct cast_op);
1240 break;
1241 }
1242
47e5f13e
MD
1243 /*
1244 * Instructions for recursive traversal through composed types.
1245 */
1246 case FILTER_OP_GET_CONTEXT_ROOT:
1247 {
1248 if (vstack_push(stack)) {
1249 ret = -EINVAL;
1250 goto end;
1251 }
1252 vstack_ax(stack)->type = REG_PTR;
1253 vstack_ax(stack)->load.type = LOAD_ROOT_CONTEXT;
1254 next_pc += sizeof(struct load_op);
1255 break;
1256 }
1257 case FILTER_OP_GET_APP_CONTEXT_ROOT:
1258 {
1259 if (vstack_push(stack)) {
1260 ret = -EINVAL;
1261 goto end;
1262 }
1263 vstack_ax(stack)->type = REG_PTR;
1264 vstack_ax(stack)->load.type = LOAD_ROOT_APP_CONTEXT;
1265 next_pc += sizeof(struct load_op);
1266 break;
1267 }
1268 case FILTER_OP_GET_PAYLOAD_ROOT:
1269 {
1270 if (vstack_push(stack)) {
1271 ret = -EINVAL;
1272 goto end;
1273 }
1274 vstack_ax(stack)->type = REG_PTR;
1275 vstack_ax(stack)->load.type = LOAD_ROOT_PAYLOAD;
1276 next_pc += sizeof(struct load_op);
1277 break;
1278 }
1279
1280 case FILTER_OP_LOAD_FIELD:
1281 {
1282 struct load_op *insn = (struct load_op *) pc;
1283
1284 assert(vstack_ax(stack)->type == REG_PTR);
1285 /* Pop 1, push 1 */
1286 ret = specialize_load_field(vstack_ax(stack), insn);
1287 if (ret)
1288 goto end;
1289
1290 next_pc += sizeof(struct load_op);
1291 break;
1292 }
1293
1294 case FILTER_OP_LOAD_FIELD_S8:
1295 case FILTER_OP_LOAD_FIELD_S16:
1296 case FILTER_OP_LOAD_FIELD_S32:
1297 case FILTER_OP_LOAD_FIELD_S64:
1298 case FILTER_OP_LOAD_FIELD_U8:
1299 case FILTER_OP_LOAD_FIELD_U16:
1300 case FILTER_OP_LOAD_FIELD_U32:
1301 case FILTER_OP_LOAD_FIELD_U64:
1302 {
1303 /* Pop 1, push 1 */
1304 vstack_ax(stack)->type = REG_S64;
1305 next_pc += sizeof(struct load_op);
1306 break;
1307 }
1308
1309 case FILTER_OP_LOAD_FIELD_STRING:
1310 case FILTER_OP_LOAD_FIELD_SEQUENCE:
1311 {
1312 /* Pop 1, push 1 */
1313 vstack_ax(stack)->type = REG_STRING;
1314 next_pc += sizeof(struct load_op);
1315 break;
1316 }
1317
1318 case FILTER_OP_LOAD_FIELD_DOUBLE:
1319 {
1320 /* Pop 1, push 1 */
1321 vstack_ax(stack)->type = REG_DOUBLE;
1322 next_pc += sizeof(struct load_op);
1323 break;
1324 }
1325
1326 case FILTER_OP_GET_SYMBOL:
1327 {
1328 struct load_op *insn = (struct load_op *) pc;
1329
1330 dbg_printf("op get symbol\n");
1331 switch (vstack_ax(stack)->load.type) {
1332 case LOAD_OBJECT:
1333 ERR("Nested fields not implemented yet.");
1334 ret = -EINVAL;
1335 goto end;
1336 case LOAD_ROOT_CONTEXT:
1337 /* Lookup context field. */
1338 ret = specialize_context_lookup(session,
1339 bytecode, insn,
1340 &vstack_ax(stack)->load);
1341 if (ret)
1342 goto end;
1343 break;
1344 case LOAD_ROOT_APP_CONTEXT:
1345 /* Lookup app context field. */
1346 ret = specialize_app_context_lookup(session,
1347 bytecode, insn,
1348 &vstack_ax(stack)->load);
1349 if (ret)
1350 goto end;
1351 break;
1352 case LOAD_ROOT_PAYLOAD:
1353 /* Lookup event payload field. */
1354 ret = specialize_event_payload_lookup(event,
1355 bytecode, insn,
1356 &vstack_ax(stack)->load);
1357 if (ret)
1358 goto end;
1359 break;
1360 }
1361 next_pc += sizeof(struct load_op) + sizeof(struct get_symbol);
1362 break;
1363 }
1364
1365 case FILTER_OP_GET_SYMBOL_FIELD:
1366 {
1367 /* Always generated by specialize phase. */
1368 ret = -EINVAL;
1369 goto end;
1370 }
1371
1372 case FILTER_OP_GET_INDEX_U16:
1373 {
1374 struct load_op *insn = (struct load_op *) pc;
1375 struct get_index_u16 *index = (struct get_index_u16 *) insn->data;
1376
1377 dbg_printf("op get index u16\n");
1378 /* Pop 1, push 1 */
1379 ret = specialize_get_index(bytecode, insn, index->index,
1380 vstack_ax(stack), sizeof(*index));
1381 if (ret)
1382 goto end;
1383 next_pc += sizeof(struct load_op) + sizeof(struct get_index_u16);
1384 break;
1385 }
1386
1387 case FILTER_OP_GET_INDEX_U64:
1388 {
1389 struct load_op *insn = (struct load_op *) pc;
1390 struct get_index_u64 *index = (struct get_index_u64 *) insn->data;
1391
1392 dbg_printf("op get index u64\n");
1393 /* Pop 1, push 1 */
1394 ret = specialize_get_index(bytecode, insn, index->index,
1395 vstack_ax(stack), sizeof(*index));
1396 if (ret)
1397 goto end;
1398 next_pc += sizeof(struct load_op) + sizeof(struct get_index_u64);
1399 break;
1400 }
1401
97b58163
MD
1402 }
1403 }
1404end:
1405 return ret;
1406}
This page took 0.088374 seconds and 4 git commands to generate.