2 * lttng-filter-interpreter.c
4 * LTTng UST filter interpreter.
6 * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; only
11 * version 2.1 of the License.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 #include "lttng-filter.h"
27 * -2: unknown escape char.
32 int parse_char(const char **p
)
52 int stack_strcmp(struct estack
*stack
, const char *cmp_type
)
54 const char *p
= estack_bx(stack
)->u
.s
.str
, *q
= estack_ax(stack
)->u
.s
.str
;
61 if (unlikely(p
- estack_bx(stack
)->u
.s
.str
> estack_bx(stack
)->u
.s
.seq_len
|| *p
== '\0')) {
62 if (q
- estack_ax(stack
)->u
.s
.str
> estack_ax(stack
)->u
.s
.seq_len
|| *q
== '\0')
68 if (unlikely(q
- estack_ax(stack
)->u
.s
.str
> estack_ax(stack
)->u
.s
.seq_len
|| *q
== '\0')) {
69 if (p
- estack_bx(stack
)->u
.s
.str
> estack_bx(stack
)->u
.s
.seq_len
|| *p
== '\0')
75 if (estack_bx(stack
)->u
.s
.literal
) {
79 } else if (ret
== -2) {
82 /* else compare both char */
84 if (estack_ax(stack
)->u
.s
.literal
) {
88 } else if (ret
== -2) {
108 int lttng_filter_false(void *filter_data
,
109 const char *filter_stack_data
)
114 #ifdef INTERPRETER_USE_SWITCH
117 * Fallback for compilers that do not support taking address of labels.
121 start_pc = &bytecode->data[0]; \
122 for (pc = next_pc = start_pc; pc - start_pc < bytecode->len; \
124 dbg_printf("Executing op %s (%u)\n", \
125 print_op((unsigned int) *(filter_opcode_t *) pc), \
126 (unsigned int) *(filter_opcode_t *) pc); \
127 switch (*(filter_opcode_t *) pc) {
129 #define OP(name) case name
139 * Dispatch-table based interpreter.
143 start_pc = &bytecode->data[0]; \
144 pc = next_pc = start_pc; \
145 if (unlikely(pc - start_pc >= bytecode->len)) \
147 goto *dispatch[*(filter_opcode_t *) pc];
154 goto *dispatch[*(filter_opcode_t *) pc];
160 int lttng_filter_interpret_bytecode(void *filter_data
,
161 const char *filter_stack_data
)
163 struct bytecode_runtime
*bytecode
= filter_data
;
164 void *pc
, *next_pc
, *start_pc
;
167 struct estack _stack
;
168 struct estack
*stack
= &_stack
;
169 #ifndef INTERPRETER_USE_SWITCH
170 static void *dispatch
[NR_FILTER_OPS
] = {
171 [ FILTER_OP_UNKNOWN
] = &&LABEL_FILTER_OP_UNKNOWN
,
173 [ FILTER_OP_RETURN
] = &&LABEL_FILTER_OP_RETURN
,
176 [ FILTER_OP_MUL
] = &&LABEL_FILTER_OP_MUL
,
177 [ FILTER_OP_DIV
] = &&LABEL_FILTER_OP_DIV
,
178 [ FILTER_OP_MOD
] = &&LABEL_FILTER_OP_MOD
,
179 [ FILTER_OP_PLUS
] = &&LABEL_FILTER_OP_PLUS
,
180 [ FILTER_OP_MINUS
] = &&LABEL_FILTER_OP_MINUS
,
181 [ FILTER_OP_RSHIFT
] = &&LABEL_FILTER_OP_RSHIFT
,
182 [ FILTER_OP_LSHIFT
] = &&LABEL_FILTER_OP_LSHIFT
,
183 [ FILTER_OP_BIN_AND
] = &&LABEL_FILTER_OP_BIN_AND
,
184 [ FILTER_OP_BIN_OR
] = &&LABEL_FILTER_OP_BIN_OR
,
185 [ FILTER_OP_BIN_XOR
] = &&LABEL_FILTER_OP_BIN_XOR
,
187 /* binary comparators */
188 [ FILTER_OP_EQ
] = &&LABEL_FILTER_OP_EQ
,
189 [ FILTER_OP_NE
] = &&LABEL_FILTER_OP_NE
,
190 [ FILTER_OP_GT
] = &&LABEL_FILTER_OP_GT
,
191 [ FILTER_OP_LT
] = &&LABEL_FILTER_OP_LT
,
192 [ FILTER_OP_GE
] = &&LABEL_FILTER_OP_GE
,
193 [ FILTER_OP_LE
] = &&LABEL_FILTER_OP_LE
,
195 /* string binary comparator */
196 [ FILTER_OP_EQ_STRING
] = &&LABEL_FILTER_OP_EQ_STRING
,
197 [ FILTER_OP_NE_STRING
] = &&LABEL_FILTER_OP_NE_STRING
,
198 [ FILTER_OP_GT_STRING
] = &&LABEL_FILTER_OP_GT_STRING
,
199 [ FILTER_OP_LT_STRING
] = &&LABEL_FILTER_OP_LT_STRING
,
200 [ FILTER_OP_GE_STRING
] = &&LABEL_FILTER_OP_GE_STRING
,
201 [ FILTER_OP_LE_STRING
] = &&LABEL_FILTER_OP_LE_STRING
,
203 /* s64 binary comparator */
204 [ FILTER_OP_EQ_S64
] = &&LABEL_FILTER_OP_EQ_S64
,
205 [ FILTER_OP_NE_S64
] = &&LABEL_FILTER_OP_NE_S64
,
206 [ FILTER_OP_GT_S64
] = &&LABEL_FILTER_OP_GT_S64
,
207 [ FILTER_OP_LT_S64
] = &&LABEL_FILTER_OP_LT_S64
,
208 [ FILTER_OP_GE_S64
] = &&LABEL_FILTER_OP_GE_S64
,
209 [ FILTER_OP_LE_S64
] = &&LABEL_FILTER_OP_LE_S64
,
211 /* double binary comparator */
212 [ FILTER_OP_EQ_DOUBLE
] = &&LABEL_FILTER_OP_EQ_DOUBLE
,
213 [ FILTER_OP_NE_DOUBLE
] = &&LABEL_FILTER_OP_NE_DOUBLE
,
214 [ FILTER_OP_GT_DOUBLE
] = &&LABEL_FILTER_OP_GT_DOUBLE
,
215 [ FILTER_OP_LT_DOUBLE
] = &&LABEL_FILTER_OP_LT_DOUBLE
,
216 [ FILTER_OP_GE_DOUBLE
] = &&LABEL_FILTER_OP_GE_DOUBLE
,
217 [ FILTER_OP_LE_DOUBLE
] = &&LABEL_FILTER_OP_LE_DOUBLE
,
220 [ FILTER_OP_UNARY_PLUS
] = &&LABEL_FILTER_OP_UNARY_PLUS
,
221 [ FILTER_OP_UNARY_MINUS
] = &&LABEL_FILTER_OP_UNARY_MINUS
,
222 [ FILTER_OP_UNARY_NOT
] = &&LABEL_FILTER_OP_UNARY_NOT
,
223 [ FILTER_OP_UNARY_PLUS_S64
] = &&LABEL_FILTER_OP_UNARY_PLUS_S64
,
224 [ FILTER_OP_UNARY_MINUS_S64
] = &&LABEL_FILTER_OP_UNARY_MINUS_S64
,
225 [ FILTER_OP_UNARY_NOT_S64
] = &&LABEL_FILTER_OP_UNARY_NOT_S64
,
226 [ FILTER_OP_UNARY_PLUS_DOUBLE
] = &&LABEL_FILTER_OP_UNARY_PLUS_DOUBLE
,
227 [ FILTER_OP_UNARY_MINUS_DOUBLE
] = &&LABEL_FILTER_OP_UNARY_MINUS_DOUBLE
,
228 [ FILTER_OP_UNARY_NOT_DOUBLE
] = &&LABEL_FILTER_OP_UNARY_NOT_DOUBLE
,
231 [ FILTER_OP_AND
] = &&LABEL_FILTER_OP_AND
,
232 [ FILTER_OP_OR
] = &&LABEL_FILTER_OP_OR
,
235 [ FILTER_OP_LOAD_FIELD_REF
] = &&LABEL_FILTER_OP_LOAD_FIELD_REF
,
236 [ FILTER_OP_LOAD_FIELD_REF_STRING
] = &&LABEL_FILTER_OP_LOAD_FIELD_REF_STRING
,
237 [ FILTER_OP_LOAD_FIELD_REF_SEQUENCE
] = &&LABEL_FILTER_OP_LOAD_FIELD_REF_SEQUENCE
,
238 [ FILTER_OP_LOAD_FIELD_REF_S64
] = &&LABEL_FILTER_OP_LOAD_FIELD_REF_S64
,
239 [ FILTER_OP_LOAD_FIELD_REF_DOUBLE
] = &&LABEL_FILTER_OP_LOAD_FIELD_REF_DOUBLE
,
241 [ FILTER_OP_LOAD_STRING
] = &&LABEL_FILTER_OP_LOAD_STRING
,
242 [ FILTER_OP_LOAD_S64
] = &&LABEL_FILTER_OP_LOAD_S64
,
243 [ FILTER_OP_LOAD_DOUBLE
] = &&LABEL_FILTER_OP_LOAD_DOUBLE
,
246 [ FILTER_OP_CAST_TO_S64
] = &&LABEL_FILTER_OP_CAST_TO_S64
,
247 [ FILTER_OP_CAST_DOUBLE_TO_S64
] = &&LABEL_FILTER_OP_CAST_DOUBLE_TO_S64
,
248 [ FILTER_OP_CAST_NOP
] = &&LABEL_FILTER_OP_CAST_NOP
,
250 #endif /* #ifndef INTERPRETER_USE_SWITCH */
256 OP(FILTER_OP_UNKNOWN
):
257 OP(FILTER_OP_LOAD_FIELD_REF
):
258 #ifdef INTERPRETER_USE_SWITCH
260 #endif /* INTERPRETER_USE_SWITCH */
261 ERR("unknown bytecode op %u\n",
262 (unsigned int) *(filter_opcode_t
*) pc
);
266 OP(FILTER_OP_RETURN
):
267 retval
= !!estack_ax(stack
)->u
.v
;
277 OP(FILTER_OP_RSHIFT
):
278 OP(FILTER_OP_LSHIFT
):
279 OP(FILTER_OP_BIN_AND
):
280 OP(FILTER_OP_BIN_OR
):
281 OP(FILTER_OP_BIN_XOR
):
282 ERR("unsupported bytecode op %u\n",
283 (unsigned int) *(filter_opcode_t
*) pc
);
293 ERR("unsupported non-specialized bytecode op %u\n",
294 (unsigned int) *(filter_opcode_t
*) pc
);
298 OP(FILTER_OP_EQ_STRING
):
302 res
= (stack_strcmp(stack
, "==") == 0);
304 estack_ax(stack
)->u
.v
= res
;
305 estack_ax(stack
)->type
= REG_S64
;
306 next_pc
+= sizeof(struct binary_op
);
309 OP(FILTER_OP_NE_STRING
):
313 res
= (stack_strcmp(stack
, "!=") != 0);
315 estack_ax(stack
)->u
.v
= res
;
316 estack_ax(stack
)->type
= REG_S64
;
317 next_pc
+= sizeof(struct binary_op
);
320 OP(FILTER_OP_GT_STRING
):
324 res
= (stack_strcmp(stack
, ">") > 0);
326 estack_ax(stack
)->u
.v
= res
;
327 estack_ax(stack
)->type
= REG_S64
;
328 next_pc
+= sizeof(struct binary_op
);
331 OP(FILTER_OP_LT_STRING
):
335 res
= (stack_strcmp(stack
, "<") < 0);
337 estack_ax(stack
)->u
.v
= res
;
338 estack_ax(stack
)->type
= REG_S64
;
339 next_pc
+= sizeof(struct binary_op
);
342 OP(FILTER_OP_GE_STRING
):
346 res
= (stack_strcmp(stack
, ">=") >= 0);
348 estack_ax(stack
)->u
.v
= res
;
349 estack_ax(stack
)->type
= REG_S64
;
350 next_pc
+= sizeof(struct binary_op
);
353 OP(FILTER_OP_LE_STRING
):
357 res
= (stack_strcmp(stack
, "<=") <= 0);
359 estack_ax(stack
)->u
.v
= res
;
360 estack_ax(stack
)->type
= REG_S64
;
361 next_pc
+= sizeof(struct binary_op
);
365 OP(FILTER_OP_EQ_S64
):
369 res
= (estack_bx(stack
)->u
.v
== estack_ax(stack
)->u
.v
);
371 estack_ax(stack
)->u
.v
= res
;
372 estack_ax(stack
)->type
= REG_S64
;
373 next_pc
+= sizeof(struct binary_op
);
376 OP(FILTER_OP_NE_S64
):
380 res
= (estack_bx(stack
)->u
.v
!= estack_ax(stack
)->u
.v
);
382 estack_ax(stack
)->u
.v
= res
;
383 estack_ax(stack
)->type
= REG_S64
;
384 next_pc
+= sizeof(struct binary_op
);
387 OP(FILTER_OP_GT_S64
):
391 res
= (estack_bx(stack
)->u
.v
> estack_ax(stack
)->u
.v
);
393 estack_ax(stack
)->u
.v
= res
;
394 estack_ax(stack
)->type
= REG_S64
;
395 next_pc
+= sizeof(struct binary_op
);
398 OP(FILTER_OP_LT_S64
):
402 res
= (estack_bx(stack
)->u
.v
< estack_ax(stack
)->u
.v
);
404 estack_ax(stack
)->u
.v
= res
;
405 estack_ax(stack
)->type
= REG_S64
;
406 next_pc
+= sizeof(struct binary_op
);
409 OP(FILTER_OP_GE_S64
):
413 res
= (estack_bx(stack
)->u
.v
>= estack_ax(stack
)->u
.v
);
415 estack_ax(stack
)->u
.v
= res
;
416 estack_ax(stack
)->type
= REG_S64
;
417 next_pc
+= sizeof(struct binary_op
);
420 OP(FILTER_OP_LE_S64
):
424 res
= (estack_bx(stack
)->u
.v
<= estack_ax(stack
)->u
.v
);
426 estack_ax(stack
)->u
.v
= res
;
427 estack_ax(stack
)->type
= REG_S64
;
428 next_pc
+= sizeof(struct binary_op
);
432 OP(FILTER_OP_EQ_DOUBLE
):
436 if (unlikely(estack_ax(stack
)->type
== REG_S64
))
437 estack_ax(stack
)->u
.d
= (double) estack_ax(stack
)->u
.v
;
438 else if (unlikely(estack_bx(stack
)->type
== REG_S64
))
439 estack_bx(stack
)->u
.d
= (double) estack_bx(stack
)->u
.v
;
440 res
= (estack_bx(stack
)->u
.v
== estack_ax(stack
)->u
.v
);
442 estack_ax(stack
)->u
.v
= res
;
443 estack_ax(stack
)->type
= REG_S64
;
444 next_pc
+= sizeof(struct binary_op
);
447 OP(FILTER_OP_NE_DOUBLE
):
451 if (unlikely(estack_ax(stack
)->type
== REG_S64
))
452 estack_ax(stack
)->u
.d
= (double) estack_ax(stack
)->u
.v
;
453 else if (unlikely(estack_bx(stack
)->type
== REG_S64
))
454 estack_bx(stack
)->u
.d
= (double) estack_bx(stack
)->u
.v
;
455 res
= (estack_bx(stack
)->u
.v
!= estack_ax(stack
)->u
.v
);
457 estack_ax(stack
)->u
.v
= res
;
458 estack_ax(stack
)->type
= REG_S64
;
459 next_pc
+= sizeof(struct binary_op
);
462 OP(FILTER_OP_GT_DOUBLE
):
466 if (unlikely(estack_ax(stack
)->type
== REG_S64
))
467 estack_ax(stack
)->u
.d
= (double) estack_ax(stack
)->u
.v
;
468 else if (unlikely(estack_bx(stack
)->type
== REG_S64
))
469 estack_bx(stack
)->u
.d
= (double) estack_bx(stack
)->u
.v
;
470 res
= (estack_bx(stack
)->u
.v
> estack_ax(stack
)->u
.v
);
472 estack_ax(stack
)->u
.v
= res
;
473 estack_ax(stack
)->type
= REG_S64
;
474 next_pc
+= sizeof(struct binary_op
);
477 OP(FILTER_OP_LT_DOUBLE
):
481 if (unlikely(estack_ax(stack
)->type
== REG_S64
))
482 estack_ax(stack
)->u
.d
= (double) estack_ax(stack
)->u
.v
;
483 else if (unlikely(estack_bx(stack
)->type
== REG_S64
))
484 estack_bx(stack
)->u
.d
= (double) estack_bx(stack
)->u
.v
;
485 res
= (estack_bx(stack
)->u
.v
< estack_ax(stack
)->u
.v
);
487 estack_ax(stack
)->u
.v
= res
;
488 estack_ax(stack
)->type
= REG_S64
;
489 next_pc
+= sizeof(struct binary_op
);
492 OP(FILTER_OP_GE_DOUBLE
):
496 if (unlikely(estack_ax(stack
)->type
== REG_S64
))
497 estack_ax(stack
)->u
.d
= (double) estack_ax(stack
)->u
.v
;
498 else if (unlikely(estack_bx(stack
)->type
== REG_S64
))
499 estack_bx(stack
)->u
.d
= (double) estack_bx(stack
)->u
.v
;
500 res
= (estack_bx(stack
)->u
.v
>= estack_ax(stack
)->u
.v
);
502 estack_ax(stack
)->u
.v
= res
;
503 estack_ax(stack
)->type
= REG_S64
;
504 next_pc
+= sizeof(struct binary_op
);
507 OP(FILTER_OP_LE_DOUBLE
):
511 if (unlikely(estack_ax(stack
)->type
== REG_S64
))
512 estack_ax(stack
)->u
.d
= (double) estack_ax(stack
)->u
.v
;
513 else if (unlikely(estack_bx(stack
)->type
== REG_S64
))
514 estack_bx(stack
)->u
.d
= (double) estack_bx(stack
)->u
.v
;
515 res
= (estack_bx(stack
)->u
.v
<= estack_ax(stack
)->u
.v
);
517 estack_ax(stack
)->u
.v
= res
;
518 estack_ax(stack
)->type
= REG_S64
;
519 next_pc
+= sizeof(struct binary_op
);
524 OP(FILTER_OP_UNARY_PLUS
):
525 OP(FILTER_OP_UNARY_MINUS
):
526 OP(FILTER_OP_UNARY_NOT
):
527 ERR("unsupported non-specialized bytecode op %u\n",
528 (unsigned int) *(filter_opcode_t
*) pc
);
533 OP(FILTER_OP_UNARY_PLUS_S64
):
534 OP(FILTER_OP_UNARY_PLUS_DOUBLE
):
536 next_pc
+= sizeof(struct unary_op
);
539 OP(FILTER_OP_UNARY_MINUS_S64
):
541 estack_ax(stack
)->u
.v
= -estack_ax(stack
)->u
.v
;
542 next_pc
+= sizeof(struct unary_op
);
545 OP(FILTER_OP_UNARY_MINUS_DOUBLE
):
547 estack_ax(stack
)->u
.d
= -estack_ax(stack
)->u
.d
;
548 next_pc
+= sizeof(struct unary_op
);
551 OP(FILTER_OP_UNARY_NOT_S64
):
553 estack_ax(stack
)->u
.v
= !estack_ax(stack
)->u
.v
;
554 next_pc
+= sizeof(struct unary_op
);
557 OP(FILTER_OP_UNARY_NOT_DOUBLE
):
559 estack_ax(stack
)->u
.d
= !estack_ax(stack
)->u
.d
;
560 next_pc
+= sizeof(struct unary_op
);
567 struct logical_op
*insn
= (struct logical_op
*) pc
;
569 /* If AX is 0, skip and evaluate to 0 */
570 if (unlikely(estack_ax(stack
)->u
.v
== 0)) {
571 dbg_printf("Jumping to bytecode offset %u\n",
572 (unsigned int) insn
->skip_offset
);
573 next_pc
= start_pc
+ insn
->skip_offset
;
575 /* Pop 1 when jump not taken */
577 next_pc
+= sizeof(struct logical_op
);
583 struct logical_op
*insn
= (struct logical_op
*) pc
;
585 /* If AX is nonzero, skip and evaluate to 1 */
587 if (unlikely(estack_ax(stack
)->u
.v
!= 0)) {
588 estack_ax(stack
)->u
.v
= 1;
589 dbg_printf("Jumping to bytecode offset %u\n",
590 (unsigned int) insn
->skip_offset
);
591 next_pc
= start_pc
+ insn
->skip_offset
;
593 /* Pop 1 when jump not taken */
595 next_pc
+= sizeof(struct logical_op
);
602 OP(FILTER_OP_LOAD_FIELD_REF_STRING
):
604 struct load_op
*insn
= (struct load_op
*) pc
;
605 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
607 dbg_printf("load field ref offset %u type string\n",
610 estack_ax(stack
)->u
.s
.str
=
611 *(const char * const *) &filter_stack_data
[ref
->offset
];
612 if (unlikely(!estack_ax(stack
)->u
.s
.str
)) {
613 dbg_printf("Filter warning: loading a NULL string.\n");
617 estack_ax(stack
)->type
= REG_STRING
;
618 estack_ax(stack
)->u
.s
.seq_len
= UINT_MAX
;
619 estack_ax(stack
)->u
.s
.literal
= 0;
620 dbg_printf("ref load string %s\n", estack_ax(stack
)->u
.s
.str
);
621 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
625 OP(FILTER_OP_LOAD_FIELD_REF_SEQUENCE
):
627 struct load_op
*insn
= (struct load_op
*) pc
;
628 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
630 dbg_printf("load field ref offset %u type sequence\n",
633 estack_ax(stack
)->u
.s
.seq_len
=
634 *(unsigned long *) &filter_stack_data
[ref
->offset
];
635 estack_ax(stack
)->u
.s
.str
=
636 *(const char **) (&filter_stack_data
[ref
->offset
637 + sizeof(unsigned long)]);
638 if (unlikely(!estack_ax(stack
)->u
.s
.str
)) {
639 dbg_printf("Filter warning: loading a NULL sequence.\n");
643 estack_ax(stack
)->type
= REG_STRING
;
644 estack_ax(stack
)->u
.s
.literal
= 0;
645 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
649 OP(FILTER_OP_LOAD_FIELD_REF_S64
):
651 struct load_op
*insn
= (struct load_op
*) pc
;
652 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
654 dbg_printf("load field ref offset %u type s64\n",
657 memcpy(&estack_ax(stack
)->u
.v
, &filter_stack_data
[ref
->offset
],
658 sizeof(struct literal_numeric
));
659 estack_ax(stack
)->type
= REG_S64
;
660 dbg_printf("ref load s64 %" PRIi64
"\n", estack_ax(stack
)->u
.v
);
661 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
665 OP(FILTER_OP_LOAD_FIELD_REF_DOUBLE
):
667 struct load_op
*insn
= (struct load_op
*) pc
;
668 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
670 dbg_printf("load field ref offset %u type double\n",
673 memcpy(&estack_ax(stack
)->u
.d
, &filter_stack_data
[ref
->offset
],
674 sizeof(struct literal_double
));
675 estack_ax(stack
)->type
= REG_DOUBLE
;
676 dbg_printf("ref load double %g\n", estack_ax(stack
)->u
.d
);
677 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
681 OP(FILTER_OP_LOAD_STRING
):
683 struct load_op
*insn
= (struct load_op
*) pc
;
685 dbg_printf("load string %s\n", insn
->data
);
687 estack_ax(stack
)->type
= REG_STRING
;
688 estack_ax(stack
)->u
.s
.str
= insn
->data
;
689 estack_ax(stack
)->u
.s
.seq_len
= UINT_MAX
;
690 estack_ax(stack
)->u
.s
.literal
= 1;
691 next_pc
+= sizeof(struct load_op
) + strlen(insn
->data
) + 1;
695 OP(FILTER_OP_LOAD_S64
):
697 struct load_op
*insn
= (struct load_op
*) pc
;
700 memcpy(&estack_ax(stack
)->u
.v
, insn
->data
,
701 sizeof(struct literal_numeric
));
702 dbg_printf("load s64 %" PRIi64
"\n", estack_ax(stack
)->u
.v
);
703 estack_ax(stack
)->type
= REG_S64
;
704 next_pc
+= sizeof(struct load_op
)
705 + sizeof(struct literal_numeric
);
709 OP(FILTER_OP_LOAD_DOUBLE
):
711 struct load_op
*insn
= (struct load_op
*) pc
;
714 memcpy(&estack_ax(stack
)->u
.d
, insn
->data
,
715 sizeof(struct literal_double
));
716 dbg_printf("load s64 %g\n", estack_ax(stack
)->u
.d
);
717 estack_ax(stack
)->type
= REG_DOUBLE
;
718 next_pc
+= sizeof(struct load_op
)
719 + sizeof(struct literal_double
);
724 OP(FILTER_OP_CAST_TO_S64
):
725 ERR("unsupported non-specialized bytecode op %u\n",
726 (unsigned int) *(filter_opcode_t
*) pc
);
730 OP(FILTER_OP_CAST_DOUBLE_TO_S64
):
732 estack_ax(stack
)->u
.v
= (int64_t) estack_ax(stack
)->u
.d
;
733 estack_ax(stack
)->type
= REG_S64
;
734 next_pc
+= sizeof(struct cast_op
);
738 OP(FILTER_OP_CAST_NOP
):
740 next_pc
+= sizeof(struct cast_op
);
746 /* return 0 (discard) on error */