SoW-2019-0002: Dynamic Snapshot
[deliverable/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
d5fc3224 439static int specialize_context_lookup(struct lttng_ctx *ctx,
47e5f13e
MD
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
d5fc3224 450 idx = specialize_context_lookup_name(ctx, runtime, insn);
47e5f13e
MD
451 if (idx < 0) {
452 return -ENOENT;
453 }
d5fc3224 454 ctx_field = &ctx->fields[idx];
47e5f13e
MD
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
d5fc3224 473static int specialize_app_context_lookup(struct lttng_ctx *ctx,
47e5f13e
MD
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);
d5fc3224 496 idx = lttng_get_context_index(ctx, name);
47e5f13e
MD
497 if (idx < 0) {
498 assert(lttng_context_is_app(name));
499 ret = lttng_ust_add_app_context_to_ctx_rcu(name,
d5fc3224 500 &ctx);
47e5f13e
MD
501 if (ret)
502 return ret;
d5fc3224 503 idx = lttng_get_context_index(ctx, name);
47e5f13e
MD
504 if (idx < 0)
505 return -ENOENT;
506 }
d5fc3224 507 ctx_field = &ctx->fields[idx];
47e5f13e
MD
508 field = &ctx_field->event_field;
509 ret = specialize_load_object(field, load, true);
510 if (ret)
511 goto end;
512 /* Specialize each get_symbol into a get_index. */
513 insn->op = FILTER_OP_GET_INDEX_U16;
514 memset(&gid, 0, sizeof(gid));
515 gid.ctx_index = idx;
516 gid.elem.type = load->object_type;
517 data_offset = bytecode_push_data(runtime, &gid,
518 __alignof__(gid), sizeof(gid));
519 if (data_offset < 0) {
520 ret = -EINVAL;
521 goto end;
522 }
523 ((struct get_index_u16 *) insn->data)->index = data_offset;
524 ret = 0;
525end:
526 free(name);
527 return ret;
528}
529
d5fc3224 530static int specialize_payload_lookup(const struct lttng_event_desc *event_desc,
47e5f13e
MD
531 struct bytecode_runtime *runtime,
532 struct load_op *insn,
533 struct vstack_load *load)
534{
535 const char *name;
536 uint16_t offset;
47e5f13e
MD
537 unsigned int i, nr_fields;
538 bool found = false;
539 uint32_t field_offset = 0;
540 const struct lttng_event_field *field;
541 int ret;
542 struct filter_get_index_data gid;
543 ssize_t data_offset;
544
d5fc3224 545 nr_fields = event_desc->nr_fields;
47e5f13e
MD
546 offset = ((struct get_symbol *) insn->data)->offset;
547 name = runtime->p.bc->bc.data + runtime->p.bc->bc.reloc_offset + offset;
548 for (i = 0; i < nr_fields; i++) {
d5fc3224 549 field = &event_desc->fields[i];
47e5f13e
MD
550 if (!strcmp(field->name, name)) {
551 found = true;
552 break;
553 }
554 /* compute field offset on stack */
555 switch (field->type.atype) {
556 case atype_integer:
557 case atype_enum:
558 field_offset += sizeof(int64_t);
559 break;
560 case atype_array:
561 case atype_sequence:
562 field_offset += sizeof(unsigned long);
563 field_offset += sizeof(void *);
564 break;
565 case atype_string:
566 field_offset += sizeof(void *);
567 break;
568 case atype_float:
569 field_offset += sizeof(double);
570 break;
571 default:
572 ret = -EINVAL;
573 goto end;
574 }
575 }
576 if (!found) {
577 ret = -EINVAL;
578 goto end;
579 }
580
581 ret = specialize_load_object(field, load, false);
582 if (ret)
583 goto end;
584
585 /* Specialize each get_symbol into a get_index. */
586 insn->op = FILTER_OP_GET_INDEX_U16;
587 memset(&gid, 0, sizeof(gid));
588 gid.offset = field_offset;
589 gid.elem.type = load->object_type;
590 data_offset = bytecode_push_data(runtime, &gid,
591 __alignof__(gid), sizeof(gid));
592 if (data_offset < 0) {
593 ret = -EINVAL;
594 goto end;
595 }
596 ((struct get_index_u16 *) insn->data)->index = data_offset;
597 ret = 0;
598end:
599 return ret;
600}
601
d5fc3224 602int lttng_filter_specialize_bytecode(const struct lttng_event_desc *event_desc,
47e5f13e 603 struct bytecode_runtime *bytecode)
97b58163
MD
604{
605 void *pc, *next_pc, *start_pc;
606 int ret = -EINVAL;
0305960f
MD
607 struct vstack _stack;
608 struct vstack *stack = &_stack;
d5fc3224 609 struct lttng_ctx *ctx = *bytecode->p.ctx;
97b58163 610
0305960f 611 vstack_init(stack);
97b58163 612
47e5f13e 613 start_pc = &bytecode->code[0];
97b58163
MD
614 for (pc = next_pc = start_pc; pc - start_pc < bytecode->len;
615 pc = next_pc) {
616 switch (*(filter_opcode_t *) pc) {
617 case FILTER_OP_UNKNOWN:
618 default:
619 ERR("unknown bytecode op %u\n",
620 (unsigned int) *(filter_opcode_t *) pc);
621 ret = -EINVAL;
622 goto end;
623
624 case FILTER_OP_RETURN:
93c591bb
MD
625 if (vstack_ax(stack)->type == REG_S64)
626 *(filter_opcode_t *) pc = FILTER_OP_RETURN_S64;
627 ret = 0;
628 goto end;
629
630 case FILTER_OP_RETURN_S64:
631 if (vstack_ax(stack)->type != REG_S64) {
632 ERR("Unexpected register type\n");
633 ret = -EINVAL;
634 goto end;
635 }
97b58163
MD
636 ret = 0;
637 goto end;
638
639 /* binary */
640 case FILTER_OP_MUL:
641 case FILTER_OP_DIV:
642 case FILTER_OP_MOD:
643 case FILTER_OP_PLUS:
644 case FILTER_OP_MINUS:
97b58163
MD
645 ERR("unsupported bytecode op %u\n",
646 (unsigned int) *(filter_opcode_t *) pc);
647 ret = -EINVAL;
648 goto end;
649
650 case FILTER_OP_EQ:
651 {
652 struct binary_op *insn = (struct binary_op *) pc;
653
0305960f 654 switch(vstack_ax(stack)->type) {
97b58163
MD
655 default:
656 ERR("unknown register type\n");
657 ret = -EINVAL;
658 goto end;
659
660 case REG_STRING:
53569322
MD
661 if (vstack_bx(stack)->type == REG_UNKNOWN)
662 break;
3151a51d
PP
663 if (vstack_bx(stack)->type == REG_STAR_GLOB_STRING)
664 insn->op = FILTER_OP_EQ_STAR_GLOB_STRING;
665 else
666 insn->op = FILTER_OP_EQ_STRING;
667 break;
668 case REG_STAR_GLOB_STRING:
669 if (vstack_bx(stack)->type == REG_UNKNOWN)
670 break;
671 insn->op = FILTER_OP_EQ_STAR_GLOB_STRING;
97b58163
MD
672 break;
673 case REG_S64:
53569322
MD
674 if (vstack_bx(stack)->type == REG_UNKNOWN)
675 break;
0305960f 676 if (vstack_bx(stack)->type == REG_S64)
97b58163
MD
677 insn->op = FILTER_OP_EQ_S64;
678 else
dbea82ec 679 insn->op = FILTER_OP_EQ_DOUBLE_S64;
97b58163
MD
680 break;
681 case REG_DOUBLE:
53569322
MD
682 if (vstack_bx(stack)->type == REG_UNKNOWN)
683 break;
dbea82ec
MD
684 if (vstack_bx(stack)->type == REG_S64)
685 insn->op = FILTER_OP_EQ_S64_DOUBLE;
686 else
687 insn->op = FILTER_OP_EQ_DOUBLE;
97b58163 688 break;
53569322
MD
689 case REG_UNKNOWN:
690 break; /* Dynamic typing. */
97b58163 691 }
0305960f
MD
692 /* Pop 2, push 1 */
693 if (vstack_pop(stack)) {
694 ret = -EINVAL;
695 goto end;
696 }
697 vstack_ax(stack)->type = REG_S64;
97b58163
MD
698 next_pc += sizeof(struct binary_op);
699 break;
700 }
701
702 case FILTER_OP_NE:
703 {
704 struct binary_op *insn = (struct binary_op *) pc;
705
0305960f 706 switch(vstack_ax(stack)->type) {
97b58163
MD
707 default:
708 ERR("unknown register type\n");
709 ret = -EINVAL;
710 goto end;
711
712 case REG_STRING:
53569322
MD
713 if (vstack_bx(stack)->type == REG_UNKNOWN)
714 break;
3151a51d
PP
715 if (vstack_bx(stack)->type == REG_STAR_GLOB_STRING)
716 insn->op = FILTER_OP_NE_STAR_GLOB_STRING;
717 else
718 insn->op = FILTER_OP_NE_STRING;
719 break;
720 case REG_STAR_GLOB_STRING:
721 if (vstack_bx(stack)->type == REG_UNKNOWN)
722 break;
723 insn->op = FILTER_OP_NE_STAR_GLOB_STRING;
97b58163
MD
724 break;
725 case REG_S64:
53569322
MD
726 if (vstack_bx(stack)->type == REG_UNKNOWN)
727 break;
0305960f 728 if (vstack_bx(stack)->type == REG_S64)
97b58163
MD
729 insn->op = FILTER_OP_NE_S64;
730 else
dbea82ec 731 insn->op = FILTER_OP_NE_DOUBLE_S64;
97b58163
MD
732 break;
733 case REG_DOUBLE:
53569322
MD
734 if (vstack_bx(stack)->type == REG_UNKNOWN)
735 break;
dbea82ec
MD
736 if (vstack_bx(stack)->type == REG_S64)
737 insn->op = FILTER_OP_NE_S64_DOUBLE;
738 else
739 insn->op = FILTER_OP_NE_DOUBLE;
97b58163 740 break;
53569322
MD
741 case REG_UNKNOWN:
742 break; /* Dynamic typing. */
97b58163 743 }
0305960f
MD
744 /* Pop 2, push 1 */
745 if (vstack_pop(stack)) {
746 ret = -EINVAL;
747 goto end;
748 }
749 vstack_ax(stack)->type = REG_S64;
97b58163
MD
750 next_pc += sizeof(struct binary_op);
751 break;
752 }
753
754 case FILTER_OP_GT:
755 {
756 struct binary_op *insn = (struct binary_op *) pc;
757
0305960f 758 switch(vstack_ax(stack)->type) {
97b58163
MD
759 default:
760 ERR("unknown register type\n");
761 ret = -EINVAL;
762 goto end;
763
3151a51d
PP
764 case REG_STAR_GLOB_STRING:
765 ERR("invalid register type for > binary operator\n");
766 ret = -EINVAL;
767 goto end;
97b58163 768 case REG_STRING:
53569322
MD
769 if (vstack_bx(stack)->type == REG_UNKNOWN)
770 break;
97b58163
MD
771 insn->op = FILTER_OP_GT_STRING;
772 break;
773 case REG_S64:
53569322
MD
774 if (vstack_bx(stack)->type == REG_UNKNOWN)
775 break;
0305960f 776 if (vstack_bx(stack)->type == REG_S64)
97b58163
MD
777 insn->op = FILTER_OP_GT_S64;
778 else
dbea82ec 779 insn->op = FILTER_OP_GT_DOUBLE_S64;
97b58163
MD
780 break;
781 case REG_DOUBLE:
53569322
MD
782 if (vstack_bx(stack)->type == REG_UNKNOWN)
783 break;
dbea82ec
MD
784 if (vstack_bx(stack)->type == REG_S64)
785 insn->op = FILTER_OP_GT_S64_DOUBLE;
786 else
787 insn->op = FILTER_OP_GT_DOUBLE;
97b58163 788 break;
53569322
MD
789 case REG_UNKNOWN:
790 break; /* Dynamic typing. */
97b58163 791 }
0305960f
MD
792 /* Pop 2, push 1 */
793 if (vstack_pop(stack)) {
794 ret = -EINVAL;
795 goto end;
796 }
797 vstack_ax(stack)->type = REG_S64;
97b58163
MD
798 next_pc += sizeof(struct binary_op);
799 break;
800 }
801
802 case FILTER_OP_LT:
803 {
804 struct binary_op *insn = (struct binary_op *) pc;
805
0305960f 806 switch(vstack_ax(stack)->type) {
97b58163
MD
807 default:
808 ERR("unknown register type\n");
809 ret = -EINVAL;
810 goto end;
811
3151a51d
PP
812 case REG_STAR_GLOB_STRING:
813 ERR("invalid register type for < binary operator\n");
814 ret = -EINVAL;
815 goto end;
97b58163 816 case REG_STRING:
53569322
MD
817 if (vstack_bx(stack)->type == REG_UNKNOWN)
818 break;
97b58163
MD
819 insn->op = FILTER_OP_LT_STRING;
820 break;
821 case REG_S64:
53569322
MD
822 if (vstack_bx(stack)->type == REG_UNKNOWN)
823 break;
0305960f 824 if (vstack_bx(stack)->type == REG_S64)
97b58163
MD
825 insn->op = FILTER_OP_LT_S64;
826 else
dbea82ec 827 insn->op = FILTER_OP_LT_DOUBLE_S64;
97b58163
MD
828 break;
829 case REG_DOUBLE:
53569322
MD
830 if (vstack_bx(stack)->type == REG_UNKNOWN)
831 break;
dbea82ec
MD
832 if (vstack_bx(stack)->type == REG_S64)
833 insn->op = FILTER_OP_LT_S64_DOUBLE;
834 else
835 insn->op = FILTER_OP_LT_DOUBLE;
97b58163 836 break;
53569322
MD
837 case REG_UNKNOWN:
838 break; /* Dynamic typing. */
97b58163 839 }
0305960f
MD
840 /* Pop 2, push 1 */
841 if (vstack_pop(stack)) {
842 ret = -EINVAL;
843 goto end;
844 }
845 vstack_ax(stack)->type = REG_S64;
97b58163
MD
846 next_pc += sizeof(struct binary_op);
847 break;
848 }
849
850 case FILTER_OP_GE:
851 {
852 struct binary_op *insn = (struct binary_op *) pc;
853
0305960f 854 switch(vstack_ax(stack)->type) {
97b58163
MD
855 default:
856 ERR("unknown register type\n");
857 ret = -EINVAL;
858 goto end;
859
3151a51d
PP
860 case REG_STAR_GLOB_STRING:
861 ERR("invalid register type for >= binary operator\n");
862 ret = -EINVAL;
863 goto end;
97b58163 864 case REG_STRING:
53569322
MD
865 if (vstack_bx(stack)->type == REG_UNKNOWN)
866 break;
97b58163
MD
867 insn->op = FILTER_OP_GE_STRING;
868 break;
869 case REG_S64:
53569322
MD
870 if (vstack_bx(stack)->type == REG_UNKNOWN)
871 break;
0305960f 872 if (vstack_bx(stack)->type == REG_S64)
97b58163
MD
873 insn->op = FILTER_OP_GE_S64;
874 else
dbea82ec 875 insn->op = FILTER_OP_GE_DOUBLE_S64;
97b58163
MD
876 break;
877 case REG_DOUBLE:
53569322
MD
878 if (vstack_bx(stack)->type == REG_UNKNOWN)
879 break;
dbea82ec
MD
880 if (vstack_bx(stack)->type == REG_S64)
881 insn->op = FILTER_OP_GE_S64_DOUBLE;
882 else
883 insn->op = FILTER_OP_GE_DOUBLE;
97b58163 884 break;
53569322
MD
885 case REG_UNKNOWN:
886 break; /* Dynamic typing. */
97b58163 887 }
0305960f
MD
888 /* Pop 2, push 1 */
889 if (vstack_pop(stack)) {
890 ret = -EINVAL;
891 goto end;
892 }
893 vstack_ax(stack)->type = REG_S64;
97b58163
MD
894 next_pc += sizeof(struct binary_op);
895 break;
896 }
897 case FILTER_OP_LE:
898 {
899 struct binary_op *insn = (struct binary_op *) pc;
900
0305960f 901 switch(vstack_ax(stack)->type) {
97b58163
MD
902 default:
903 ERR("unknown register type\n");
904 ret = -EINVAL;
905 goto end;
906
3151a51d
PP
907 case REG_STAR_GLOB_STRING:
908 ERR("invalid register type for <= binary operator\n");
909 ret = -EINVAL;
910 goto end;
97b58163 911 case REG_STRING:
53569322
MD
912 if (vstack_bx(stack)->type == REG_UNKNOWN)
913 break;
97b58163
MD
914 insn->op = FILTER_OP_LE_STRING;
915 break;
916 case REG_S64:
53569322
MD
917 if (vstack_bx(stack)->type == REG_UNKNOWN)
918 break;
0305960f 919 if (vstack_bx(stack)->type == REG_S64)
97b58163
MD
920 insn->op = FILTER_OP_LE_S64;
921 else
dbea82ec 922 insn->op = FILTER_OP_LE_DOUBLE_S64;
97b58163
MD
923 break;
924 case REG_DOUBLE:
53569322
MD
925 if (vstack_bx(stack)->type == REG_UNKNOWN)
926 break;
dbea82ec
MD
927 if (vstack_bx(stack)->type == REG_S64)
928 insn->op = FILTER_OP_LE_S64_DOUBLE;
929 else
930 insn->op = FILTER_OP_LE_DOUBLE;
97b58163 931 break;
53569322
MD
932 case REG_UNKNOWN:
933 break; /* Dynamic typing. */
97b58163 934 }
0305960f 935 vstack_ax(stack)->type = REG_S64;
97b58163
MD
936 next_pc += sizeof(struct binary_op);
937 break;
938 }
939
940 case FILTER_OP_EQ_STRING:
941 case FILTER_OP_NE_STRING:
942 case FILTER_OP_GT_STRING:
943 case FILTER_OP_LT_STRING:
944 case FILTER_OP_GE_STRING:
945 case FILTER_OP_LE_STRING:
3151a51d
PP
946 case FILTER_OP_EQ_STAR_GLOB_STRING:
947 case FILTER_OP_NE_STAR_GLOB_STRING:
97b58163
MD
948 case FILTER_OP_EQ_S64:
949 case FILTER_OP_NE_S64:
950 case FILTER_OP_GT_S64:
951 case FILTER_OP_LT_S64:
952 case FILTER_OP_GE_S64:
953 case FILTER_OP_LE_S64:
954 case FILTER_OP_EQ_DOUBLE:
955 case FILTER_OP_NE_DOUBLE:
956 case FILTER_OP_GT_DOUBLE:
957 case FILTER_OP_LT_DOUBLE:
958 case FILTER_OP_GE_DOUBLE:
959 case FILTER_OP_LE_DOUBLE:
dbea82ec
MD
960 case FILTER_OP_EQ_DOUBLE_S64:
961 case FILTER_OP_NE_DOUBLE_S64:
962 case FILTER_OP_GT_DOUBLE_S64:
963 case FILTER_OP_LT_DOUBLE_S64:
964 case FILTER_OP_GE_DOUBLE_S64:
965 case FILTER_OP_LE_DOUBLE_S64:
966 case FILTER_OP_EQ_S64_DOUBLE:
967 case FILTER_OP_NE_S64_DOUBLE:
968 case FILTER_OP_GT_S64_DOUBLE:
969 case FILTER_OP_LT_S64_DOUBLE:
970 case FILTER_OP_GE_S64_DOUBLE:
971 case FILTER_OP_LE_S64_DOUBLE:
0039e2d8
MD
972 case FILTER_OP_BIT_RSHIFT:
973 case FILTER_OP_BIT_LSHIFT:
47e5f13e
MD
974 case FILTER_OP_BIT_AND:
975 case FILTER_OP_BIT_OR:
976 case FILTER_OP_BIT_XOR:
97b58163 977 {
0305960f
MD
978 /* Pop 2, push 1 */
979 if (vstack_pop(stack)) {
980 ret = -EINVAL;
981 goto end;
982 }
983 vstack_ax(stack)->type = REG_S64;
97b58163
MD
984 next_pc += sizeof(struct binary_op);
985 break;
986 }
987
988 /* unary */
989 case FILTER_OP_UNARY_PLUS:
990 {
991 struct unary_op *insn = (struct unary_op *) pc;
992
0305960f 993 switch(vstack_ax(stack)->type) {
97b58163
MD
994 default:
995 ERR("unknown register type\n");
996 ret = -EINVAL;
997 goto end;
998
999 case REG_S64:
1000 insn->op = FILTER_OP_UNARY_PLUS_S64;
1001 break;
1002 case REG_DOUBLE:
1003 insn->op = FILTER_OP_UNARY_PLUS_DOUBLE;
1004 break;
53569322
MD
1005 case REG_UNKNOWN: /* Dynamic typing. */
1006 break;
97b58163 1007 }
0305960f 1008 /* Pop 1, push 1 */
97b58163
MD
1009 next_pc += sizeof(struct unary_op);
1010 break;
1011 }
1012
1013 case FILTER_OP_UNARY_MINUS:
1014 {
1015 struct unary_op *insn = (struct unary_op *) pc;
1016
0305960f 1017 switch(vstack_ax(stack)->type) {
97b58163
MD
1018 default:
1019 ERR("unknown register type\n");
1020 ret = -EINVAL;
1021 goto end;
1022
1023 case REG_S64:
1024 insn->op = FILTER_OP_UNARY_MINUS_S64;
1025 break;
1026 case REG_DOUBLE:
1027 insn->op = FILTER_OP_UNARY_MINUS_DOUBLE;
1028 break;
53569322
MD
1029 case REG_UNKNOWN: /* Dynamic typing. */
1030 break;
97b58163 1031 }
0305960f 1032 /* Pop 1, push 1 */
97b58163
MD
1033 next_pc += sizeof(struct unary_op);
1034 break;
1035 }
1036
1037 case FILTER_OP_UNARY_NOT:
1038 {
1039 struct unary_op *insn = (struct unary_op *) pc;
1040
0305960f 1041 switch(vstack_ax(stack)->type) {
97b58163
MD
1042 default:
1043 ERR("unknown register type\n");
1044 ret = -EINVAL;
1045 goto end;
1046
1047 case REG_S64:
1048 insn->op = FILTER_OP_UNARY_NOT_S64;
1049 break;
1050 case REG_DOUBLE:
1051 insn->op = FILTER_OP_UNARY_NOT_DOUBLE;
1052 break;
53569322
MD
1053 case REG_UNKNOWN: /* Dynamic typing. */
1054 break;
97b58163 1055 }
0305960f 1056 /* Pop 1, push 1 */
97b58163
MD
1057 next_pc += sizeof(struct unary_op);
1058 break;
1059 }
1060
0039e2d8
MD
1061 case FILTER_OP_UNARY_BIT_NOT:
1062 {
1063 /* Pop 1, push 1 */
1064 next_pc += sizeof(struct unary_op);
1065 break;
1066 }
1067
97b58163
MD
1068 case FILTER_OP_UNARY_PLUS_S64:
1069 case FILTER_OP_UNARY_MINUS_S64:
1070 case FILTER_OP_UNARY_NOT_S64:
1071 case FILTER_OP_UNARY_PLUS_DOUBLE:
1072 case FILTER_OP_UNARY_MINUS_DOUBLE:
1073 case FILTER_OP_UNARY_NOT_DOUBLE:
1074 {
0305960f 1075 /* Pop 1, push 1 */
97b58163
MD
1076 next_pc += sizeof(struct unary_op);
1077 break;
1078 }
1079
1080 /* logical */
1081 case FILTER_OP_AND:
1082 case FILTER_OP_OR:
1083 {
b9f4cd79
MD
1084 /* Continue to next instruction */
1085 /* Pop 1 when jump not taken */
1086 if (vstack_pop(stack)) {
1087 ret = -EINVAL;
1088 goto end;
1089 }
97b58163
MD
1090 next_pc += sizeof(struct logical_op);
1091 break;
1092 }
1093
77aa5901 1094 /* load field ref */
97b58163
MD
1095 case FILTER_OP_LOAD_FIELD_REF:
1096 {
1097 ERR("Unknown field ref type\n");
1098 ret = -EINVAL;
1099 goto end;
1100 }
77aa5901
MD
1101 /* get context ref */
1102 case FILTER_OP_GET_CONTEXT_REF:
1103 {
53569322
MD
1104 if (vstack_push(stack)) {
1105 ret = -EINVAL;
1106 goto end;
1107 }
1108 vstack_ax(stack)->type = REG_UNKNOWN;
1109 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1110 break;
77aa5901 1111 }
97b58163
MD
1112 case FILTER_OP_LOAD_FIELD_REF_STRING:
1113 case FILTER_OP_LOAD_FIELD_REF_SEQUENCE:
77aa5901 1114 case FILTER_OP_GET_CONTEXT_REF_STRING:
97b58163 1115 {
0305960f
MD
1116 if (vstack_push(stack)) {
1117 ret = -EINVAL;
1118 goto end;
1119 }
1120 vstack_ax(stack)->type = REG_STRING;
97b58163
MD
1121 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1122 break;
1123 }
1124 case FILTER_OP_LOAD_FIELD_REF_S64:
77aa5901 1125 case FILTER_OP_GET_CONTEXT_REF_S64:
97b58163 1126 {
0305960f
MD
1127 if (vstack_push(stack)) {
1128 ret = -EINVAL;
1129 goto end;
1130 }
1131 vstack_ax(stack)->type = REG_S64;
97b58163
MD
1132 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1133 break;
1134 }
1135 case FILTER_OP_LOAD_FIELD_REF_DOUBLE:
77aa5901 1136 case FILTER_OP_GET_CONTEXT_REF_DOUBLE:
97b58163 1137 {
0305960f
MD
1138 if (vstack_push(stack)) {
1139 ret = -EINVAL;
1140 goto end;
1141 }
1142 vstack_ax(stack)->type = REG_DOUBLE;
97b58163
MD
1143 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1144 break;
1145 }
1146
77aa5901 1147 /* load from immediate operand */
97b58163
MD
1148 case FILTER_OP_LOAD_STRING:
1149 {
1150 struct load_op *insn = (struct load_op *) pc;
1151
0305960f
MD
1152 if (vstack_push(stack)) {
1153 ret = -EINVAL;
1154 goto end;
1155 }
1156 vstack_ax(stack)->type = REG_STRING;
97b58163
MD
1157 next_pc += sizeof(struct load_op) + strlen(insn->data) + 1;
1158 break;
1159 }
1160
3151a51d
PP
1161 case FILTER_OP_LOAD_STAR_GLOB_STRING:
1162 {
1163 struct load_op *insn = (struct load_op *) pc;
1164
1165 if (vstack_push(stack)) {
1166 ret = -EINVAL;
1167 goto end;
1168 }
1169 vstack_ax(stack)->type = REG_STAR_GLOB_STRING;
1170 next_pc += sizeof(struct load_op) + strlen(insn->data) + 1;
1171 break;
1172 }
1173
97b58163
MD
1174 case FILTER_OP_LOAD_S64:
1175 {
0305960f
MD
1176 if (vstack_push(stack)) {
1177 ret = -EINVAL;
1178 goto end;
1179 }
1180 vstack_ax(stack)->type = REG_S64;
97b58163
MD
1181 next_pc += sizeof(struct load_op)
1182 + sizeof(struct literal_numeric);
1183 break;
1184 }
1185
1186 case FILTER_OP_LOAD_DOUBLE:
1187 {
0305960f
MD
1188 if (vstack_push(stack)) {
1189 ret = -EINVAL;
1190 goto end;
1191 }
1192 vstack_ax(stack)->type = REG_DOUBLE;
97b58163
MD
1193 next_pc += sizeof(struct load_op)
1194 + sizeof(struct literal_double);
1195 break;
1196 }
1197
1198 /* cast */
1199 case FILTER_OP_CAST_TO_S64:
1200 {
1201 struct cast_op *insn = (struct cast_op *) pc;
1202
0305960f 1203 switch (vstack_ax(stack)->type) {
97b58163
MD
1204 default:
1205 ERR("unknown register type\n");
1206 ret = -EINVAL;
1207 goto end;
1208
1209 case REG_STRING:
3151a51d 1210 case REG_STAR_GLOB_STRING:
97b58163
MD
1211 ERR("Cast op can only be applied to numeric or floating point registers\n");
1212 ret = -EINVAL;
1213 goto end;
1214 case REG_S64:
1215 insn->op = FILTER_OP_CAST_NOP;
1216 break;
1217 case REG_DOUBLE:
1218 insn->op = FILTER_OP_CAST_DOUBLE_TO_S64;
1219 break;
53569322
MD
1220 case REG_UNKNOWN:
1221 break;
97b58163 1222 }
0305960f
MD
1223 /* Pop 1, push 1 */
1224 vstack_ax(stack)->type = REG_S64;
97b58163
MD
1225 next_pc += sizeof(struct cast_op);
1226 break;
1227 }
1228 case FILTER_OP_CAST_DOUBLE_TO_S64:
1229 {
0305960f
MD
1230 /* Pop 1, push 1 */
1231 vstack_ax(stack)->type = REG_S64;
97b58163
MD
1232 next_pc += sizeof(struct cast_op);
1233 break;
1234 }
1235 case FILTER_OP_CAST_NOP:
1236 {
1237 next_pc += sizeof(struct cast_op);
1238 break;
1239 }
1240
47e5f13e
MD
1241 /*
1242 * Instructions for recursive traversal through composed types.
1243 */
1244 case FILTER_OP_GET_CONTEXT_ROOT:
1245 {
1246 if (vstack_push(stack)) {
1247 ret = -EINVAL;
1248 goto end;
1249 }
1250 vstack_ax(stack)->type = REG_PTR;
1251 vstack_ax(stack)->load.type = LOAD_ROOT_CONTEXT;
1252 next_pc += sizeof(struct load_op);
1253 break;
1254 }
1255 case FILTER_OP_GET_APP_CONTEXT_ROOT:
1256 {
1257 if (vstack_push(stack)) {
1258 ret = -EINVAL;
1259 goto end;
1260 }
1261 vstack_ax(stack)->type = REG_PTR;
1262 vstack_ax(stack)->load.type = LOAD_ROOT_APP_CONTEXT;
1263 next_pc += sizeof(struct load_op);
1264 break;
1265 }
1266 case FILTER_OP_GET_PAYLOAD_ROOT:
1267 {
1268 if (vstack_push(stack)) {
1269 ret = -EINVAL;
1270 goto end;
1271 }
1272 vstack_ax(stack)->type = REG_PTR;
1273 vstack_ax(stack)->load.type = LOAD_ROOT_PAYLOAD;
1274 next_pc += sizeof(struct load_op);
1275 break;
1276 }
1277
1278 case FILTER_OP_LOAD_FIELD:
1279 {
1280 struct load_op *insn = (struct load_op *) pc;
1281
1282 assert(vstack_ax(stack)->type == REG_PTR);
1283 /* Pop 1, push 1 */
1284 ret = specialize_load_field(vstack_ax(stack), insn);
1285 if (ret)
1286 goto end;
1287
1288 next_pc += sizeof(struct load_op);
1289 break;
1290 }
1291
1292 case FILTER_OP_LOAD_FIELD_S8:
1293 case FILTER_OP_LOAD_FIELD_S16:
1294 case FILTER_OP_LOAD_FIELD_S32:
1295 case FILTER_OP_LOAD_FIELD_S64:
1296 case FILTER_OP_LOAD_FIELD_U8:
1297 case FILTER_OP_LOAD_FIELD_U16:
1298 case FILTER_OP_LOAD_FIELD_U32:
1299 case FILTER_OP_LOAD_FIELD_U64:
1300 {
1301 /* Pop 1, push 1 */
1302 vstack_ax(stack)->type = REG_S64;
1303 next_pc += sizeof(struct load_op);
1304 break;
1305 }
1306
1307 case FILTER_OP_LOAD_FIELD_STRING:
1308 case FILTER_OP_LOAD_FIELD_SEQUENCE:
1309 {
1310 /* Pop 1, push 1 */
1311 vstack_ax(stack)->type = REG_STRING;
1312 next_pc += sizeof(struct load_op);
1313 break;
1314 }
1315
1316 case FILTER_OP_LOAD_FIELD_DOUBLE:
1317 {
1318 /* Pop 1, push 1 */
1319 vstack_ax(stack)->type = REG_DOUBLE;
1320 next_pc += sizeof(struct load_op);
1321 break;
1322 }
1323
1324 case FILTER_OP_GET_SYMBOL:
1325 {
1326 struct load_op *insn = (struct load_op *) pc;
1327
1328 dbg_printf("op get symbol\n");
1329 switch (vstack_ax(stack)->load.type) {
1330 case LOAD_OBJECT:
1331 ERR("Nested fields not implemented yet.");
1332 ret = -EINVAL;
1333 goto end;
1334 case LOAD_ROOT_CONTEXT:
1335 /* Lookup context field. */
d5fc3224 1336 ret = specialize_context_lookup(ctx,
47e5f13e
MD
1337 bytecode, insn,
1338 &vstack_ax(stack)->load);
1339 if (ret)
1340 goto end;
1341 break;
1342 case LOAD_ROOT_APP_CONTEXT:
1343 /* Lookup app context field. */
d5fc3224 1344 ret = specialize_app_context_lookup(ctx,
47e5f13e
MD
1345 bytecode, insn,
1346 &vstack_ax(stack)->load);
1347 if (ret)
1348 goto end;
1349 break;
1350 case LOAD_ROOT_PAYLOAD:
1351 /* Lookup event payload field. */
d5fc3224 1352 ret = specialize_payload_lookup(event_desc,
47e5f13e
MD
1353 bytecode, insn,
1354 &vstack_ax(stack)->load);
1355 if (ret)
1356 goto end;
1357 break;
1358 }
1359 next_pc += sizeof(struct load_op) + sizeof(struct get_symbol);
1360 break;
1361 }
1362
1363 case FILTER_OP_GET_SYMBOL_FIELD:
1364 {
1365 /* Always generated by specialize phase. */
1366 ret = -EINVAL;
1367 goto end;
1368 }
1369
1370 case FILTER_OP_GET_INDEX_U16:
1371 {
1372 struct load_op *insn = (struct load_op *) pc;
1373 struct get_index_u16 *index = (struct get_index_u16 *) insn->data;
1374
1375 dbg_printf("op get index u16\n");
1376 /* Pop 1, push 1 */
1377 ret = specialize_get_index(bytecode, insn, index->index,
1378 vstack_ax(stack), sizeof(*index));
1379 if (ret)
1380 goto end;
1381 next_pc += sizeof(struct load_op) + sizeof(struct get_index_u16);
1382 break;
1383 }
1384
1385 case FILTER_OP_GET_INDEX_U64:
1386 {
1387 struct load_op *insn = (struct load_op *) pc;
1388 struct get_index_u64 *index = (struct get_index_u64 *) insn->data;
1389
1390 dbg_printf("op get index u64\n");
1391 /* Pop 1, push 1 */
1392 ret = specialize_get_index(bytecode, insn, index->index,
1393 vstack_ax(stack), sizeof(*index));
1394 if (ret)
1395 goto end;
1396 next_pc += sizeof(struct load_op) + sizeof(struct get_index_u64);
1397 break;
1398 }
1399
97b58163
MD
1400 }
1401 }
1402end:
1403 return ret;
1404}
This page took 0.09466 seconds and 5 git commands to generate.