Add structure size field to struct lttng_event
[lttng-ust.git] / liblttng-ust / lttng-bytecode-interpreter.c
CommitLineData
97b58163 1/*
c0c0989a 2 * SPDX-License-Identifier: MIT
97b58163 3 *
7e50015d 4 * Copyright (C) 2010-2016 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
97b58163 5 *
c0c0989a 6 * LTTng UST bytecode interpreter.
97b58163
MD
7 */
8
3fbec7dc 9#define _LGPL_SOURCE
b4051ad8 10#include <stddef.h>
a63d0dc8 11#include <stdint.h>
f3503ba9 12
10544ee8 13#include <lttng/urcu/pointer.h>
3208818b 14#include <lttng/ust-endian.h>
f3503ba9 15#include <lttng/ust-events.h>
362a65de 16#include "ust-events-internal.h"
f3503ba9 17
04aa13f8 18#include "lttng-bytecode.h"
3151a51d 19#include "string-utils.h"
97b58163 20
f3503ba9 21
97b58163
MD
22/*
23 * -1: wildcard found.
24 * -2: unknown escape char.
25 * 0: normal char.
26 */
27
28static
29int parse_char(const char **p)
30{
31 switch (**p) {
32 case '\\':
33 (*p)++;
34 switch (**p) {
35 case '\\':
36 case '*':
37 return 0;
38 default:
39 return -2;
40 }
41 case '*':
42 return -1;
43 default:
44 return 0;
45 }
46}
47
3151a51d 48/*
a63d0dc8 49 * Returns SIZE_MAX if the string is null-terminated, or the number of
3151a51d
PP
50 * characters if not.
51 */
52static
53size_t get_str_or_seq_len(const struct estack_entry *entry)
54{
a63d0dc8 55 return entry->u.s.seq_len;
3151a51d
PP
56}
57
58static
59int stack_star_glob_match(struct estack *stack, int top, const char *cmp_type)
60{
61 const char *pattern;
62 const char *candidate;
63 size_t pattern_len;
64 size_t candidate_len;
65
66 /* Find out which side is the pattern vs. the candidate. */
67 if (estack_ax(stack, top)->u.s.literal_type == ESTACK_STRING_LITERAL_TYPE_STAR_GLOB) {
68 pattern = estack_ax(stack, top)->u.s.str;
69 pattern_len = get_str_or_seq_len(estack_ax(stack, top));
70 candidate = estack_bx(stack, top)->u.s.str;
71 candidate_len = get_str_or_seq_len(estack_bx(stack, top));
72 } else {
73 pattern = estack_bx(stack, top)->u.s.str;
74 pattern_len = get_str_or_seq_len(estack_bx(stack, top));
75 candidate = estack_ax(stack, top)->u.s.str;
76 candidate_len = get_str_or_seq_len(estack_ax(stack, top));
77 }
78
79 /* Perform the match. Returns 0 when the result is true. */
80 return !strutils_star_glob_match(pattern, pattern_len, candidate,
81 candidate_len);
82}
83
97b58163 84static
9b33aac4 85int stack_strcmp(struct estack *stack, int top, const char *cmp_type)
97b58163 86{
9b33aac4 87 const char *p = estack_bx(stack, top)->u.s.str, *q = estack_ax(stack, top)->u.s.str;
97b58163
MD
88 int ret;
89 int diff;
90
91 for (;;) {
92 int escaped_r0 = 0;
93
332335cd
MD
94 if (unlikely(p - estack_bx(stack, top)->u.s.str >= estack_bx(stack, top)->u.s.seq_len || *p == '\0')) {
95 if (q - estack_ax(stack, top)->u.s.str >= estack_ax(stack, top)->u.s.seq_len || *q == '\0') {
5cf8141d 96 return 0;
a0928c1e 97 } else {
3151a51d
PP
98 if (estack_ax(stack, top)->u.s.literal_type ==
99 ESTACK_STRING_LITERAL_TYPE_PLAIN) {
5cf8141d
MD
100 ret = parse_char(&q);
101 if (ret == -1)
102 return 0;
103 }
104 return -1;
a0928c1e 105 }
97b58163 106 }
332335cd 107 if (unlikely(q - estack_ax(stack, top)->u.s.str >= estack_ax(stack, top)->u.s.seq_len || *q == '\0')) {
3151a51d
PP
108 if (estack_bx(stack, top)->u.s.literal_type ==
109 ESTACK_STRING_LITERAL_TYPE_PLAIN) {
3e6a0694
MD
110 ret = parse_char(&p);
111 if (ret == -1)
112 return 0;
a0928c1e 113 }
3e6a0694 114 return 1;
97b58163 115 }
3151a51d
PP
116 if (estack_bx(stack, top)->u.s.literal_type ==
117 ESTACK_STRING_LITERAL_TYPE_PLAIN) {
97b58163
MD
118 ret = parse_char(&p);
119 if (ret == -1) {
120 return 0;
121 } else if (ret == -2) {
122 escaped_r0 = 1;
123 }
124 /* else compare both char */
125 }
3151a51d
PP
126 if (estack_ax(stack, top)->u.s.literal_type ==
127 ESTACK_STRING_LITERAL_TYPE_PLAIN) {
97b58163
MD
128 ret = parse_char(&q);
129 if (ret == -1) {
130 return 0;
131 } else if (ret == -2) {
132 if (!escaped_r0)
133 return -1;
134 } else {
135 if (escaped_r0)
136 return 1;
137 }
138 } else {
139 if (escaped_r0)
140 return 1;
141 }
142 diff = *p - *q;
143 if (diff != 0)
144 break;
145 p++;
146 q++;
147 }
148 return diff;
149}
150
04aa13f8 151uint64_t lttng_bytecode_filter_interpret_false(void *filter_data,
97b58163
MD
152 const char *filter_stack_data)
153{
04aa13f8 154 return LTTNG_INTERPRETER_DISCARD;
97b58163
MD
155}
156
d37ecb3f
FD
157uint64_t lttng_bytecode_capture_interpret_false(void *capture_data,
158 const char *capture_stack_data,
159 struct lttng_interpreter_output *output)
160{
161 return LTTNG_INTERPRETER_DISCARD;
162}
163
97b58163
MD
164#ifdef INTERPRETER_USE_SWITCH
165
166/*
167 * Fallback for compilers that do not support taking address of labels.
168 */
169
170#define START_OP \
171 start_pc = &bytecode->data[0]; \
172 for (pc = next_pc = start_pc; pc - start_pc < bytecode->len; \
173 pc = next_pc) { \
174 dbg_printf("Executing op %s (%u)\n", \
bf617e20 175 lttng_bytecode_print_op((unsigned int) *(bytecode_opcode_t *) pc), \
04aa13f8
FD
176 (unsigned int) *(bytecode_opcode_t *) pc); \
177 switch (*(bytecode_opcode_t *) pc) {
97b58163 178
53569322
MD
179#define OP(name) jump_target_##name: __attribute__((unused)); \
180 case name
97b58163
MD
181
182#define PO break
183
184#define END_OP } \
185 }
186
53569322
MD
187#define JUMP_TO(name) \
188 goto jump_target_##name
189
97b58163
MD
190#else
191
192/*
193 * Dispatch-table based interpreter.
194 */
195
196#define START_OP \
47e5f13e 197 start_pc = &bytecode->code[0]; \
97b58163
MD
198 pc = next_pc = start_pc; \
199 if (unlikely(pc - start_pc >= bytecode->len)) \
200 goto end; \
04aa13f8 201 goto *dispatch[*(bytecode_opcode_t *) pc];
97b58163
MD
202
203#define OP(name) \
204LABEL_##name
205
206#define PO \
207 pc = next_pc; \
04aa13f8 208 goto *dispatch[*(bytecode_opcode_t *) pc];
97b58163
MD
209
210#define END_OP
211
53569322
MD
212#define JUMP_TO(name) \
213 goto LABEL_##name
214
97b58163
MD
215#endif
216
d97f9b78
MD
217#define IS_INTEGER_REGISTER(reg_type) \
218 (reg_type == REG_U64 || reg_type == REG_S64)
219
47e5f13e
MD
220static int context_get_index(struct lttng_ctx *ctx,
221 struct load_ptr *ptr,
222 uint32_t idx)
223{
224
225 struct lttng_ctx_field *ctx_field;
226 struct lttng_event_field *field;
227 struct lttng_ctx_value v;
228
229 ctx_field = &ctx->fields[idx];
230 field = &ctx_field->event_field;
231 ptr->type = LOAD_OBJECT;
f3503ba9 232 ptr->field = field;
47e5f13e
MD
233
234 switch (field->type.atype) {
235 case atype_integer:
236 ctx_field->get_value(ctx_field, &v);
218deb69 237 if (field->type.u.integer.signedness) {
47e5f13e
MD
238 ptr->object_type = OBJECT_TYPE_S64;
239 ptr->u.s64 = v.u.s64;
240 ptr->ptr = &ptr->u.s64;
241 } else {
242 ptr->object_type = OBJECT_TYPE_U64;
243 ptr->u.u64 = v.u.s64; /* Cast. */
244 ptr->ptr = &ptr->u.u64;
245 }
246 break;
218deb69
MD
247 case atype_enum: /* Fall-through */
248 case atype_enum_nestable:
47e5f13e 249 {
218deb69 250 const struct lttng_integer_type *itype;
47e5f13e 251
218deb69
MD
252 if (field->type.atype == atype_enum) {
253 itype = &field->type.u.legacy.basic.enumeration.container_type;
254 } else {
255 itype = &field->type.u.enum_nestable.container_type->u.integer;
256 }
47e5f13e
MD
257 ctx_field->get_value(ctx_field, &v);
258 if (itype->signedness) {
70f9f7f9 259 ptr->object_type = OBJECT_TYPE_SIGNED_ENUM;
47e5f13e
MD
260 ptr->u.s64 = v.u.s64;
261 ptr->ptr = &ptr->u.s64;
262 } else {
70f9f7f9 263 ptr->object_type = OBJECT_TYPE_UNSIGNED_ENUM;
47e5f13e
MD
264 ptr->u.u64 = v.u.s64; /* Cast. */
265 ptr->ptr = &ptr->u.u64;
266 }
267 break;
268 }
269 case atype_array:
218deb69
MD
270 if (field->type.u.legacy.array.elem_type.atype != atype_integer) {
271 ERR("Array nesting only supports integer types.");
272 return -EINVAL;
273 }
274 if (field->type.u.legacy.array.elem_type.u.basic.integer.encoding == lttng_encode_none) {
275 ERR("Only string arrays are supported for contexts.");
276 return -EINVAL;
277 }
278 ptr->object_type = OBJECT_TYPE_STRING;
279 ctx_field->get_value(ctx_field, &v);
280 ptr->ptr = v.u.str;
281 break;
282 case atype_array_nestable:
283 if (field->type.u.array_nestable.elem_type->atype != atype_integer) {
47e5f13e
MD
284 ERR("Array nesting only supports integer types.");
285 return -EINVAL;
286 }
218deb69 287 if (field->type.u.array_nestable.elem_type->u.integer.encoding == lttng_encode_none) {
47e5f13e
MD
288 ERR("Only string arrays are supported for contexts.");
289 return -EINVAL;
290 }
291 ptr->object_type = OBJECT_TYPE_STRING;
292 ctx_field->get_value(ctx_field, &v);
293 ptr->ptr = v.u.str;
294 break;
295 case atype_sequence:
218deb69
MD
296 if (field->type.u.legacy.sequence.elem_type.atype != atype_integer) {
297 ERR("Sequence nesting only supports integer types.");
298 return -EINVAL;
299 }
300 if (field->type.u.legacy.sequence.elem_type.u.basic.integer.encoding == lttng_encode_none) {
301 ERR("Only string sequences are supported for contexts.");
302 return -EINVAL;
303 }
304 ptr->object_type = OBJECT_TYPE_STRING;
305 ctx_field->get_value(ctx_field, &v);
306 ptr->ptr = v.u.str;
307 break;
308 case atype_sequence_nestable:
309 if (field->type.u.sequence_nestable.elem_type->atype != atype_integer) {
47e5f13e
MD
310 ERR("Sequence nesting only supports integer types.");
311 return -EINVAL;
312 }
218deb69 313 if (field->type.u.sequence_nestable.elem_type->u.integer.encoding == lttng_encode_none) {
47e5f13e
MD
314 ERR("Only string sequences are supported for contexts.");
315 return -EINVAL;
316 }
317 ptr->object_type = OBJECT_TYPE_STRING;
318 ctx_field->get_value(ctx_field, &v);
319 ptr->ptr = v.u.str;
320 break;
321 case atype_string:
322 ptr->object_type = OBJECT_TYPE_STRING;
323 ctx_field->get_value(ctx_field, &v);
324 ptr->ptr = v.u.str;
325 break;
326 case atype_float:
327 ptr->object_type = OBJECT_TYPE_DOUBLE;
0245c698 328 ctx_field->get_value(ctx_field, &v);
47e5f13e
MD
329 ptr->u.d = v.u.d;
330 ptr->ptr = &ptr->u.d;
331 break;
332 case atype_dynamic:
333 ctx_field->get_value(ctx_field, &v);
334 switch (v.sel) {
335 case LTTNG_UST_DYNAMIC_TYPE_NONE:
336 return -EINVAL;
86133caf
FD
337 case LTTNG_UST_DYNAMIC_TYPE_U8:
338 case LTTNG_UST_DYNAMIC_TYPE_U16:
339 case LTTNG_UST_DYNAMIC_TYPE_U32:
340 case LTTNG_UST_DYNAMIC_TYPE_U64:
341 ptr->object_type = OBJECT_TYPE_U64;
342 ptr->u.u64 = v.u.u64;
343 ptr->ptr = &ptr->u.u64;
344 dbg_printf("context get index dynamic u64 %" PRIi64 "\n", ptr->u.u64);
345 break;
346 case LTTNG_UST_DYNAMIC_TYPE_S8:
347 case LTTNG_UST_DYNAMIC_TYPE_S16:
348 case LTTNG_UST_DYNAMIC_TYPE_S32:
47e5f13e
MD
349 case LTTNG_UST_DYNAMIC_TYPE_S64:
350 ptr->object_type = OBJECT_TYPE_S64;
351 ptr->u.s64 = v.u.s64;
352 ptr->ptr = &ptr->u.s64;
353 dbg_printf("context get index dynamic s64 %" PRIi64 "\n", ptr->u.s64);
354 break;
86133caf 355 case LTTNG_UST_DYNAMIC_TYPE_FLOAT:
47e5f13e
MD
356 case LTTNG_UST_DYNAMIC_TYPE_DOUBLE:
357 ptr->object_type = OBJECT_TYPE_DOUBLE;
358 ptr->u.d = v.u.d;
359 ptr->ptr = &ptr->u.d;
360 dbg_printf("context get index dynamic double %g\n", ptr->u.d);
361 break;
362 case LTTNG_UST_DYNAMIC_TYPE_STRING:
363 ptr->object_type = OBJECT_TYPE_STRING;
364 ptr->ptr = v.u.str;
365 dbg_printf("context get index dynamic string %s\n", (const char *) ptr->ptr);
366 break;
367 default:
04aa13f8 368 dbg_printf("Interpreter warning: unknown dynamic type (%d).\n", (int) v.sel);
47e5f13e
MD
369 return -EINVAL;
370 }
371 break;
372 case atype_struct:
373 ERR("Structure type cannot be loaded.");
374 return -EINVAL;
375 default:
376 ERR("Unknown type: %d", (int) field->type.atype);
377 return -EINVAL;
378 }
379 return 0;
380}
381
b77aaa1b 382static int dynamic_get_index(struct lttng_ctx *ctx,
47e5f13e
MD
383 struct bytecode_runtime *runtime,
384 uint64_t index, struct estack_entry *stack_top)
385{
386 int ret;
04aa13f8 387 const struct bytecode_get_index_data *gid;
47e5f13e 388
04aa13f8 389 gid = (const struct bytecode_get_index_data *) &runtime->data[index];
47e5f13e
MD
390 switch (stack_top->u.ptr.type) {
391 case LOAD_OBJECT:
392 switch (stack_top->u.ptr.object_type) {
393 case OBJECT_TYPE_ARRAY:
394 {
395 const char *ptr;
396
397 assert(gid->offset < gid->array_len);
398 /* Skip count (unsigned long) */
399 ptr = *(const char **) (stack_top->u.ptr.ptr + sizeof(unsigned long));
400 ptr = ptr + gid->offset;
401 stack_top->u.ptr.ptr = ptr;
402 stack_top->u.ptr.object_type = gid->elem.type;
403 stack_top->u.ptr.rev_bo = gid->elem.rev_bo;
f3503ba9
FD
404 assert(stack_top->u.ptr.field->type.atype == atype_array ||
405 stack_top->u.ptr.field->type.atype == atype_array_nestable);
47e5f13e
MD
406 stack_top->u.ptr.field = NULL;
407 break;
408 }
409 case OBJECT_TYPE_SEQUENCE:
410 {
411 const char *ptr;
412 size_t ptr_seq_len;
413
414 ptr = *(const char **) (stack_top->u.ptr.ptr + sizeof(unsigned long));
415 ptr_seq_len = *(unsigned long *) stack_top->u.ptr.ptr;
416 if (gid->offset >= gid->elem.len * ptr_seq_len) {
417 ret = -EINVAL;
418 goto end;
419 }
420 ptr = ptr + gid->offset;
421 stack_top->u.ptr.ptr = ptr;
422 stack_top->u.ptr.object_type = gid->elem.type;
423 stack_top->u.ptr.rev_bo = gid->elem.rev_bo;
f3503ba9
FD
424 assert(stack_top->u.ptr.field->type.atype == atype_sequence ||
425 stack_top->u.ptr.field->type.atype == atype_sequence_nestable);
47e5f13e
MD
426 stack_top->u.ptr.field = NULL;
427 break;
428 }
429 case OBJECT_TYPE_STRUCT:
430 ERR("Nested structures are not supported yet.");
431 ret = -EINVAL;
432 goto end;
433 case OBJECT_TYPE_VARIANT:
434 default:
435 ERR("Unexpected get index type %d",
436 (int) stack_top->u.ptr.object_type);
437 ret = -EINVAL;
438 goto end;
439 }
440 break;
441 case LOAD_ROOT_CONTEXT:
442 case LOAD_ROOT_APP_CONTEXT: /* Fall-through */
443 {
47e5f13e
MD
444 ret = context_get_index(ctx,
445 &stack_top->u.ptr,
446 gid->ctx_index);
447 if (ret) {
448 goto end;
449 }
450 break;
451 }
452 case LOAD_ROOT_PAYLOAD:
453 stack_top->u.ptr.ptr += gid->offset;
454 if (gid->elem.type == OBJECT_TYPE_STRING)
455 stack_top->u.ptr.ptr = *(const char * const *) stack_top->u.ptr.ptr;
456 stack_top->u.ptr.object_type = gid->elem.type;
457 stack_top->u.ptr.type = LOAD_OBJECT;
f3503ba9 458 stack_top->u.ptr.field = gid->field;
6bbd9df3 459 stack_top->u.ptr.rev_bo = gid->elem.rev_bo;
47e5f13e
MD
460 break;
461 }
d312cd35
FD
462
463 stack_top->type = REG_PTR;
464
47e5f13e
MD
465 return 0;
466
467end:
468 return ret;
469}
470
471static int dynamic_load_field(struct estack_entry *stack_top)
472{
473 int ret;
474
475 switch (stack_top->u.ptr.type) {
476 case LOAD_OBJECT:
477 break;
478 case LOAD_ROOT_CONTEXT:
479 case LOAD_ROOT_APP_CONTEXT:
480 case LOAD_ROOT_PAYLOAD:
481 default:
04aa13f8 482 dbg_printf("Interpreter warning: cannot load root, missing field name.\n");
47e5f13e
MD
483 ret = -EINVAL;
484 goto end;
485 }
486 switch (stack_top->u.ptr.object_type) {
487 case OBJECT_TYPE_S8:
488 dbg_printf("op load field s8\n");
489 stack_top->u.v = *(int8_t *) stack_top->u.ptr.ptr;
490 stack_top->type = REG_S64;
491 break;
492 case OBJECT_TYPE_S16:
493 {
494 int16_t tmp;
495
496 dbg_printf("op load field s16\n");
497 tmp = *(int16_t *) stack_top->u.ptr.ptr;
498 if (stack_top->u.ptr.rev_bo)
499 tmp = bswap_16(tmp);
500 stack_top->u.v = tmp;
501 stack_top->type = REG_S64;
502 break;
503 }
504 case OBJECT_TYPE_S32:
505 {
506 int32_t tmp;
507
508 dbg_printf("op load field s32\n");
509 tmp = *(int32_t *) stack_top->u.ptr.ptr;
510 if (stack_top->u.ptr.rev_bo)
511 tmp = bswap_32(tmp);
512 stack_top->u.v = tmp;
513 stack_top->type = REG_S64;
514 break;
515 }
516 case OBJECT_TYPE_S64:
517 {
518 int64_t tmp;
519
520 dbg_printf("op load field s64\n");
521 tmp = *(int64_t *) stack_top->u.ptr.ptr;
522 if (stack_top->u.ptr.rev_bo)
523 tmp = bswap_64(tmp);
524 stack_top->u.v = tmp;
525 stack_top->type = REG_S64;
526 break;
527 }
70f9f7f9
FD
528 case OBJECT_TYPE_SIGNED_ENUM:
529 {
530 int64_t tmp;
531
532 dbg_printf("op load field signed enumeration\n");
533 tmp = *(int64_t *) stack_top->u.ptr.ptr;
534 if (stack_top->u.ptr.rev_bo)
535 tmp = bswap_64(tmp);
536 stack_top->u.v = tmp;
537 stack_top->type = REG_S64;
538 break;
539 }
47e5f13e
MD
540 case OBJECT_TYPE_U8:
541 dbg_printf("op load field u8\n");
542 stack_top->u.v = *(uint8_t *) stack_top->u.ptr.ptr;
d97f9b78 543 stack_top->type = REG_U64;
47e5f13e
MD
544 break;
545 case OBJECT_TYPE_U16:
546 {
547 uint16_t tmp;
548
055d27d7 549 dbg_printf("op load field u16\n");
47e5f13e
MD
550 tmp = *(uint16_t *) stack_top->u.ptr.ptr;
551 if (stack_top->u.ptr.rev_bo)
552 tmp = bswap_16(tmp);
553 stack_top->u.v = tmp;
d97f9b78 554 stack_top->type = REG_U64;
47e5f13e
MD
555 break;
556 }
557 case OBJECT_TYPE_U32:
558 {
559 uint32_t tmp;
560
561 dbg_printf("op load field u32\n");
562 tmp = *(uint32_t *) stack_top->u.ptr.ptr;
563 if (stack_top->u.ptr.rev_bo)
564 tmp = bswap_32(tmp);
565 stack_top->u.v = tmp;
d97f9b78 566 stack_top->type = REG_U64;
47e5f13e
MD
567 break;
568 }
569 case OBJECT_TYPE_U64:
570 {
571 uint64_t tmp;
572
573 dbg_printf("op load field u64\n");
574 tmp = *(uint64_t *) stack_top->u.ptr.ptr;
575 if (stack_top->u.ptr.rev_bo)
576 tmp = bswap_64(tmp);
577 stack_top->u.v = tmp;
d97f9b78 578 stack_top->type = REG_U64;
47e5f13e
MD
579 break;
580 }
70f9f7f9
FD
581 case OBJECT_TYPE_UNSIGNED_ENUM:
582 {
583 uint64_t tmp;
584
585 dbg_printf("op load field unsigned enumeration\n");
586 tmp = *(uint64_t *) stack_top->u.ptr.ptr;
587 if (stack_top->u.ptr.rev_bo)
588 tmp = bswap_64(tmp);
589 stack_top->u.v = tmp;
590 stack_top->type = REG_U64;
591 break;
592 }
47e5f13e
MD
593 case OBJECT_TYPE_DOUBLE:
594 memcpy(&stack_top->u.d,
595 stack_top->u.ptr.ptr,
596 sizeof(struct literal_double));
597 stack_top->type = REG_DOUBLE;
598 break;
599 case OBJECT_TYPE_STRING:
600 {
601 const char *str;
602
603 dbg_printf("op load field string\n");
604 str = (const char *) stack_top->u.ptr.ptr;
605 stack_top->u.s.str = str;
606 if (unlikely(!stack_top->u.s.str)) {
04aa13f8 607 dbg_printf("Interpreter warning: loading a NULL string.\n");
47e5f13e
MD
608 ret = -EINVAL;
609 goto end;
610 }
611 stack_top->u.s.seq_len = SIZE_MAX;
612 stack_top->u.s.literal_type =
613 ESTACK_STRING_LITERAL_TYPE_NONE;
614 stack_top->type = REG_STRING;
615 break;
616 }
617 case OBJECT_TYPE_STRING_SEQUENCE:
618 {
619 const char *ptr;
620
621 dbg_printf("op load field string sequence\n");
622 ptr = stack_top->u.ptr.ptr;
623 stack_top->u.s.seq_len = *(unsigned long *) ptr;
624 stack_top->u.s.str = *(const char **) (ptr + sizeof(unsigned long));
625 stack_top->type = REG_STRING;
626 if (unlikely(!stack_top->u.s.str)) {
04aa13f8 627 dbg_printf("Interpreter warning: loading a NULL sequence.\n");
47e5f13e
MD
628 ret = -EINVAL;
629 goto end;
630 }
631 stack_top->u.s.literal_type =
632 ESTACK_STRING_LITERAL_TYPE_NONE;
633 break;
634 }
635 case OBJECT_TYPE_DYNAMIC:
636 /*
637 * Dynamic types in context are looked up
638 * by context get index.
639 */
640 ret = -EINVAL;
641 goto end;
642 case OBJECT_TYPE_SEQUENCE:
643 case OBJECT_TYPE_ARRAY:
644 case OBJECT_TYPE_STRUCT:
645 case OBJECT_TYPE_VARIANT:
646 ERR("Sequences, arrays, struct and variant cannot be loaded (nested types).");
647 ret = -EINVAL;
648 goto end;
649 }
650 return 0;
651
652end:
653 return ret;
654}
655
f3503ba9
FD
656static
657int lttng_bytecode_interpret_format_output(struct estack_entry *ax,
658 struct lttng_interpreter_output *output)
659{
660 int ret;
661
662again:
663 switch (ax->type) {
664 case REG_S64:
665 output->type = LTTNG_INTERPRETER_TYPE_S64;
666 output->u.s = ax->u.v;
667 break;
668 case REG_U64:
669 output->type = LTTNG_INTERPRETER_TYPE_U64;
670 output->u.u = (uint64_t) ax->u.v;
671 break;
672 case REG_DOUBLE:
673 output->type = LTTNG_INTERPRETER_TYPE_DOUBLE;
674 output->u.d = ax->u.d;
675 break;
676 case REG_STRING:
677 output->type = LTTNG_INTERPRETER_TYPE_STRING;
678 output->u.str.str = ax->u.s.str;
679 output->u.str.len = ax->u.s.seq_len;
680 break;
681 case REG_PTR:
682 switch (ax->u.ptr.object_type) {
683 case OBJECT_TYPE_S8:
684 case OBJECT_TYPE_S16:
685 case OBJECT_TYPE_S32:
686 case OBJECT_TYPE_S64:
687 case OBJECT_TYPE_U8:
688 case OBJECT_TYPE_U16:
689 case OBJECT_TYPE_U32:
690 case OBJECT_TYPE_U64:
691 case OBJECT_TYPE_DOUBLE:
692 case OBJECT_TYPE_STRING:
693 case OBJECT_TYPE_STRING_SEQUENCE:
694 ret = dynamic_load_field(ax);
695 if (ret)
696 return ret;
697 /* Retry after loading ptr into stack top. */
698 goto again;
699 case OBJECT_TYPE_SEQUENCE:
700 output->type = LTTNG_INTERPRETER_TYPE_SEQUENCE;
701 output->u.sequence.ptr = *(const char **) (ax->u.ptr.ptr + sizeof(unsigned long));
702 output->u.sequence.nr_elem = *(unsigned long *) ax->u.ptr.ptr;
703 output->u.sequence.nested_type = ax->u.ptr.field->type.u.sequence_nestable.elem_type;
704 break;
705 case OBJECT_TYPE_ARRAY:
706 /* Skip count (unsigned long) */
707 output->type = LTTNG_INTERPRETER_TYPE_SEQUENCE;
708 output->u.sequence.ptr = *(const char **) (ax->u.ptr.ptr + sizeof(unsigned long));
709 output->u.sequence.nr_elem = ax->u.ptr.field->type.u.array_nestable.length;
710 output->u.sequence.nested_type = ax->u.ptr.field->type.u.array_nestable.elem_type;
711 break;
70f9f7f9
FD
712 case OBJECT_TYPE_SIGNED_ENUM:
713 ret = dynamic_load_field(ax);
714 if (ret)
715 return ret;
716 output->type = LTTNG_INTERPRETER_TYPE_SIGNED_ENUM;
717 output->u.s = ax->u.v;
718 break;
719 case OBJECT_TYPE_UNSIGNED_ENUM:
720 ret = dynamic_load_field(ax);
721 if (ret)
722 return ret;
723 output->type = LTTNG_INTERPRETER_TYPE_UNSIGNED_ENUM;
724 output->u.u = ax->u.v;
725 break;
f3503ba9
FD
726 case OBJECT_TYPE_STRUCT:
727 case OBJECT_TYPE_VARIANT:
728 default:
729 return -EINVAL;
730 }
731
732 break;
733 case REG_STAR_GLOB_STRING:
734 case REG_UNKNOWN:
735 default:
736 return -EINVAL;
737 }
738
04aa13f8 739 return LTTNG_INTERPRETER_RECORD_FLAG;
f3503ba9
FD
740}
741
8a92ed2a 742/*
d37ecb3f
FD
743 * For `output` equal to NULL:
744 * Return 0 (discard), or raise the 0x1 flag (log event).
745 * Currently, other flags are kept for future extensions and have no
746 * effect.
747 * For `output` not equal to NULL:
748 * Return 0 on success, negative error value on error.
8a92ed2a 749 */
f3503ba9
FD
750static
751uint64_t bytecode_interpret(void *interpreter_data,
752 const char *interpreter_stack_data,
753 struct lttng_interpreter_output *output)
97b58163 754{
f3503ba9 755 struct bytecode_runtime *bytecode = interpreter_data;
362a65de 756 struct lttng_ctx *ctx = lttng_ust_rcu_dereference(*bytecode->p.priv->pctx);
97b58163
MD
757 void *pc, *next_pc, *start_pc;
758 int ret = -EINVAL;
8b82df15 759 uint64_t retval = 0;
0305960f
MD
760 struct estack _stack;
761 struct estack *stack = &_stack;
9b33aac4 762 register int64_t ax = 0, bx = 0;
53569322 763 register enum entry_type ax_t = REG_UNKNOWN, bx_t = REG_UNKNOWN;
04aa13f8 764 register int top = INTERPRETER_STACK_EMPTY;
97b58163 765#ifndef INTERPRETER_USE_SWITCH
04aa13f8
FD
766 static void *dispatch[NR_BYTECODE_OPS] = {
767 [ BYTECODE_OP_UNKNOWN ] = &&LABEL_BYTECODE_OP_UNKNOWN,
97b58163 768
04aa13f8 769 [ BYTECODE_OP_RETURN ] = &&LABEL_BYTECODE_OP_RETURN,
97b58163
MD
770
771 /* binary */
04aa13f8
FD
772 [ BYTECODE_OP_MUL ] = &&LABEL_BYTECODE_OP_MUL,
773 [ BYTECODE_OP_DIV ] = &&LABEL_BYTECODE_OP_DIV,
774 [ BYTECODE_OP_MOD ] = &&LABEL_BYTECODE_OP_MOD,
775 [ BYTECODE_OP_PLUS ] = &&LABEL_BYTECODE_OP_PLUS,
776 [ BYTECODE_OP_MINUS ] = &&LABEL_BYTECODE_OP_MINUS,
777 [ BYTECODE_OP_BIT_RSHIFT ] = &&LABEL_BYTECODE_OP_BIT_RSHIFT,
778 [ BYTECODE_OP_BIT_LSHIFT ] = &&LABEL_BYTECODE_OP_BIT_LSHIFT,
779 [ BYTECODE_OP_BIT_AND ] = &&LABEL_BYTECODE_OP_BIT_AND,
780 [ BYTECODE_OP_BIT_OR ] = &&LABEL_BYTECODE_OP_BIT_OR,
781 [ BYTECODE_OP_BIT_XOR ] = &&LABEL_BYTECODE_OP_BIT_XOR,
97b58163
MD
782
783 /* binary comparators */
04aa13f8
FD
784 [ BYTECODE_OP_EQ ] = &&LABEL_BYTECODE_OP_EQ,
785 [ BYTECODE_OP_NE ] = &&LABEL_BYTECODE_OP_NE,
786 [ BYTECODE_OP_GT ] = &&LABEL_BYTECODE_OP_GT,
787 [ BYTECODE_OP_LT ] = &&LABEL_BYTECODE_OP_LT,
788 [ BYTECODE_OP_GE ] = &&LABEL_BYTECODE_OP_GE,
789 [ BYTECODE_OP_LE ] = &&LABEL_BYTECODE_OP_LE,
97b58163
MD
790
791 /* string binary comparator */
04aa13f8
FD
792 [ BYTECODE_OP_EQ_STRING ] = &&LABEL_BYTECODE_OP_EQ_STRING,
793 [ BYTECODE_OP_NE_STRING ] = &&LABEL_BYTECODE_OP_NE_STRING,
794 [ BYTECODE_OP_GT_STRING ] = &&LABEL_BYTECODE_OP_GT_STRING,
795 [ BYTECODE_OP_LT_STRING ] = &&LABEL_BYTECODE_OP_LT_STRING,
796 [ BYTECODE_OP_GE_STRING ] = &&LABEL_BYTECODE_OP_GE_STRING,
797 [ BYTECODE_OP_LE_STRING ] = &&LABEL_BYTECODE_OP_LE_STRING,
97b58163 798
3151a51d 799 /* globbing pattern binary comparator */
04aa13f8
FD
800 [ BYTECODE_OP_EQ_STAR_GLOB_STRING ] = &&LABEL_BYTECODE_OP_EQ_STAR_GLOB_STRING,
801 [ BYTECODE_OP_NE_STAR_GLOB_STRING ] = &&LABEL_BYTECODE_OP_NE_STAR_GLOB_STRING,
3151a51d 802
97b58163 803 /* s64 binary comparator */
04aa13f8
FD
804 [ BYTECODE_OP_EQ_S64 ] = &&LABEL_BYTECODE_OP_EQ_S64,
805 [ BYTECODE_OP_NE_S64 ] = &&LABEL_BYTECODE_OP_NE_S64,
806 [ BYTECODE_OP_GT_S64 ] = &&LABEL_BYTECODE_OP_GT_S64,
807 [ BYTECODE_OP_LT_S64 ] = &&LABEL_BYTECODE_OP_LT_S64,
808 [ BYTECODE_OP_GE_S64 ] = &&LABEL_BYTECODE_OP_GE_S64,
809 [ BYTECODE_OP_LE_S64 ] = &&LABEL_BYTECODE_OP_LE_S64,
97b58163
MD
810
811 /* double binary comparator */
04aa13f8
FD
812 [ BYTECODE_OP_EQ_DOUBLE ] = &&LABEL_BYTECODE_OP_EQ_DOUBLE,
813 [ BYTECODE_OP_NE_DOUBLE ] = &&LABEL_BYTECODE_OP_NE_DOUBLE,
814 [ BYTECODE_OP_GT_DOUBLE ] = &&LABEL_BYTECODE_OP_GT_DOUBLE,
815 [ BYTECODE_OP_LT_DOUBLE ] = &&LABEL_BYTECODE_OP_LT_DOUBLE,
816 [ BYTECODE_OP_GE_DOUBLE ] = &&LABEL_BYTECODE_OP_GE_DOUBLE,
817 [ BYTECODE_OP_LE_DOUBLE ] = &&LABEL_BYTECODE_OP_LE_DOUBLE,
97b58163 818
dbea82ec 819 /* Mixed S64-double binary comparators */
04aa13f8
FD
820 [ BYTECODE_OP_EQ_DOUBLE_S64 ] = &&LABEL_BYTECODE_OP_EQ_DOUBLE_S64,
821 [ BYTECODE_OP_NE_DOUBLE_S64 ] = &&LABEL_BYTECODE_OP_NE_DOUBLE_S64,
822 [ BYTECODE_OP_GT_DOUBLE_S64 ] = &&LABEL_BYTECODE_OP_GT_DOUBLE_S64,
823 [ BYTECODE_OP_LT_DOUBLE_S64 ] = &&LABEL_BYTECODE_OP_LT_DOUBLE_S64,
824 [ BYTECODE_OP_GE_DOUBLE_S64 ] = &&LABEL_BYTECODE_OP_GE_DOUBLE_S64,
825 [ BYTECODE_OP_LE_DOUBLE_S64 ] = &&LABEL_BYTECODE_OP_LE_DOUBLE_S64,
826
827 [ BYTECODE_OP_EQ_S64_DOUBLE ] = &&LABEL_BYTECODE_OP_EQ_S64_DOUBLE,
828 [ BYTECODE_OP_NE_S64_DOUBLE ] = &&LABEL_BYTECODE_OP_NE_S64_DOUBLE,
829 [ BYTECODE_OP_GT_S64_DOUBLE ] = &&LABEL_BYTECODE_OP_GT_S64_DOUBLE,
830 [ BYTECODE_OP_LT_S64_DOUBLE ] = &&LABEL_BYTECODE_OP_LT_S64_DOUBLE,
831 [ BYTECODE_OP_GE_S64_DOUBLE ] = &&LABEL_BYTECODE_OP_GE_S64_DOUBLE,
832 [ BYTECODE_OP_LE_S64_DOUBLE ] = &&LABEL_BYTECODE_OP_LE_S64_DOUBLE,
dbea82ec 833
97b58163 834 /* unary */
04aa13f8
FD
835 [ BYTECODE_OP_UNARY_PLUS ] = &&LABEL_BYTECODE_OP_UNARY_PLUS,
836 [ BYTECODE_OP_UNARY_MINUS ] = &&LABEL_BYTECODE_OP_UNARY_MINUS,
837 [ BYTECODE_OP_UNARY_NOT ] = &&LABEL_BYTECODE_OP_UNARY_NOT,
838 [ BYTECODE_OP_UNARY_PLUS_S64 ] = &&LABEL_BYTECODE_OP_UNARY_PLUS_S64,
839 [ BYTECODE_OP_UNARY_MINUS_S64 ] = &&LABEL_BYTECODE_OP_UNARY_MINUS_S64,
840 [ BYTECODE_OP_UNARY_NOT_S64 ] = &&LABEL_BYTECODE_OP_UNARY_NOT_S64,
841 [ BYTECODE_OP_UNARY_PLUS_DOUBLE ] = &&LABEL_BYTECODE_OP_UNARY_PLUS_DOUBLE,
842 [ BYTECODE_OP_UNARY_MINUS_DOUBLE ] = &&LABEL_BYTECODE_OP_UNARY_MINUS_DOUBLE,
843 [ BYTECODE_OP_UNARY_NOT_DOUBLE ] = &&LABEL_BYTECODE_OP_UNARY_NOT_DOUBLE,
97b58163
MD
844
845 /* logical */
04aa13f8
FD
846 [ BYTECODE_OP_AND ] = &&LABEL_BYTECODE_OP_AND,
847 [ BYTECODE_OP_OR ] = &&LABEL_BYTECODE_OP_OR,
97b58163 848
77aa5901 849 /* load field ref */
04aa13f8
FD
850 [ BYTECODE_OP_LOAD_FIELD_REF ] = &&LABEL_BYTECODE_OP_LOAD_FIELD_REF,
851 [ BYTECODE_OP_LOAD_FIELD_REF_STRING ] = &&LABEL_BYTECODE_OP_LOAD_FIELD_REF_STRING,
852 [ BYTECODE_OP_LOAD_FIELD_REF_SEQUENCE ] = &&LABEL_BYTECODE_OP_LOAD_FIELD_REF_SEQUENCE,
853 [ BYTECODE_OP_LOAD_FIELD_REF_S64 ] = &&LABEL_BYTECODE_OP_LOAD_FIELD_REF_S64,
854 [ BYTECODE_OP_LOAD_FIELD_REF_DOUBLE ] = &&LABEL_BYTECODE_OP_LOAD_FIELD_REF_DOUBLE,
97b58163 855
77aa5901 856 /* load from immediate operand */
04aa13f8
FD
857 [ BYTECODE_OP_LOAD_STRING ] = &&LABEL_BYTECODE_OP_LOAD_STRING,
858 [ BYTECODE_OP_LOAD_STAR_GLOB_STRING ] = &&LABEL_BYTECODE_OP_LOAD_STAR_GLOB_STRING,
859 [ BYTECODE_OP_LOAD_S64 ] = &&LABEL_BYTECODE_OP_LOAD_S64,
860 [ BYTECODE_OP_LOAD_DOUBLE ] = &&LABEL_BYTECODE_OP_LOAD_DOUBLE,
97b58163
MD
861
862 /* cast */
04aa13f8
FD
863 [ BYTECODE_OP_CAST_TO_S64 ] = &&LABEL_BYTECODE_OP_CAST_TO_S64,
864 [ BYTECODE_OP_CAST_DOUBLE_TO_S64 ] = &&LABEL_BYTECODE_OP_CAST_DOUBLE_TO_S64,
865 [ BYTECODE_OP_CAST_NOP ] = &&LABEL_BYTECODE_OP_CAST_NOP,
77aa5901
MD
866
867 /* get context ref */
04aa13f8
FD
868 [ BYTECODE_OP_GET_CONTEXT_REF ] = &&LABEL_BYTECODE_OP_GET_CONTEXT_REF,
869 [ BYTECODE_OP_GET_CONTEXT_REF_STRING ] = &&LABEL_BYTECODE_OP_GET_CONTEXT_REF_STRING,
870 [ BYTECODE_OP_GET_CONTEXT_REF_S64 ] = &&LABEL_BYTECODE_OP_GET_CONTEXT_REF_S64,
871 [ BYTECODE_OP_GET_CONTEXT_REF_DOUBLE ] = &&LABEL_BYTECODE_OP_GET_CONTEXT_REF_DOUBLE,
47e5f13e
MD
872
873 /* Instructions for recursive traversal through composed types. */
04aa13f8
FD
874 [ BYTECODE_OP_GET_CONTEXT_ROOT ] = &&LABEL_BYTECODE_OP_GET_CONTEXT_ROOT,
875 [ BYTECODE_OP_GET_APP_CONTEXT_ROOT ] = &&LABEL_BYTECODE_OP_GET_APP_CONTEXT_ROOT,
876 [ BYTECODE_OP_GET_PAYLOAD_ROOT ] = &&LABEL_BYTECODE_OP_GET_PAYLOAD_ROOT,
877
878 [ BYTECODE_OP_GET_SYMBOL ] = &&LABEL_BYTECODE_OP_GET_SYMBOL,
879 [ BYTECODE_OP_GET_SYMBOL_FIELD ] = &&LABEL_BYTECODE_OP_GET_SYMBOL_FIELD,
880 [ BYTECODE_OP_GET_INDEX_U16 ] = &&LABEL_BYTECODE_OP_GET_INDEX_U16,
881 [ BYTECODE_OP_GET_INDEX_U64 ] = &&LABEL_BYTECODE_OP_GET_INDEX_U64,
882
883 [ BYTECODE_OP_LOAD_FIELD ] = &&LABEL_BYTECODE_OP_LOAD_FIELD,
884 [ BYTECODE_OP_LOAD_FIELD_S8 ] = &&LABEL_BYTECODE_OP_LOAD_FIELD_S8,
885 [ BYTECODE_OP_LOAD_FIELD_S16 ] = &&LABEL_BYTECODE_OP_LOAD_FIELD_S16,
886 [ BYTECODE_OP_LOAD_FIELD_S32 ] = &&LABEL_BYTECODE_OP_LOAD_FIELD_S32,
887 [ BYTECODE_OP_LOAD_FIELD_S64 ] = &&LABEL_BYTECODE_OP_LOAD_FIELD_S64,
888 [ BYTECODE_OP_LOAD_FIELD_U8 ] = &&LABEL_BYTECODE_OP_LOAD_FIELD_U8,
889 [ BYTECODE_OP_LOAD_FIELD_U16 ] = &&LABEL_BYTECODE_OP_LOAD_FIELD_U16,
890 [ BYTECODE_OP_LOAD_FIELD_U32 ] = &&LABEL_BYTECODE_OP_LOAD_FIELD_U32,
891 [ BYTECODE_OP_LOAD_FIELD_U64 ] = &&LABEL_BYTECODE_OP_LOAD_FIELD_U64,
892 [ BYTECODE_OP_LOAD_FIELD_STRING ] = &&LABEL_BYTECODE_OP_LOAD_FIELD_STRING,
893 [ BYTECODE_OP_LOAD_FIELD_SEQUENCE ] = &&LABEL_BYTECODE_OP_LOAD_FIELD_SEQUENCE,
894 [ BYTECODE_OP_LOAD_FIELD_DOUBLE ] = &&LABEL_BYTECODE_OP_LOAD_FIELD_DOUBLE,
895
896 [ BYTECODE_OP_UNARY_BIT_NOT ] = &&LABEL_BYTECODE_OP_UNARY_BIT_NOT,
897
898 [ BYTECODE_OP_RETURN_S64 ] = &&LABEL_BYTECODE_OP_RETURN_S64,
97b58163
MD
899 };
900#endif /* #ifndef INTERPRETER_USE_SWITCH */
901
902 START_OP
903
04aa13f8
FD
904 OP(BYTECODE_OP_UNKNOWN):
905 OP(BYTECODE_OP_LOAD_FIELD_REF):
97b58163
MD
906#ifdef INTERPRETER_USE_SWITCH
907 default:
908#endif /* INTERPRETER_USE_SWITCH */
47e5f13e 909 ERR("unknown bytecode op %u",
04aa13f8 910 (unsigned int) *(bytecode_opcode_t *) pc);
97b58163
MD
911 ret = -EINVAL;
912 goto end;
913
04aa13f8
FD
914 OP(BYTECODE_OP_RETURN):
915 /* LTTNG_INTERPRETER_DISCARD or LTTNG_INTERPRETER_RECORD_FLAG */
47e5f13e
MD
916 /* Handle dynamic typing. */
917 switch (estack_ax_t) {
918 case REG_S64:
d97f9b78 919 case REG_U64:
47e5f13e
MD
920 retval = !!estack_ax_v;
921 break;
922 case REG_DOUBLE:
923 case REG_STRING:
f3503ba9
FD
924 case REG_PTR:
925 if (!output) {
926 ret = -EINVAL;
927 goto end;
928 }
929 retval = 0;
930 break;
47e5f13e 931 case REG_STAR_GLOB_STRING:
f3503ba9 932 case REG_UNKNOWN:
47e5f13e
MD
933 default:
934 ret = -EINVAL;
935 goto end;
936 }
97b58163
MD
937 ret = 0;
938 goto end;
939
04aa13f8
FD
940 OP(BYTECODE_OP_RETURN_S64):
941 /* LTTNG_INTERPRETER_DISCARD or LTTNG_INTERPRETER_RECORD_FLAG */
93c591bb
MD
942 retval = !!estack_ax_v;
943 ret = 0;
944 goto end;
945
97b58163 946 /* binary */
04aa13f8
FD
947 OP(BYTECODE_OP_MUL):
948 OP(BYTECODE_OP_DIV):
949 OP(BYTECODE_OP_MOD):
950 OP(BYTECODE_OP_PLUS):
951 OP(BYTECODE_OP_MINUS):
47e5f13e 952 ERR("unsupported bytecode op %u",
04aa13f8 953 (unsigned int) *(bytecode_opcode_t *) pc);
97b58163
MD
954 ret = -EINVAL;
955 goto end;
956
04aa13f8 957 OP(BYTECODE_OP_EQ):
53569322
MD
958 {
959 /* Dynamic typing. */
960 switch (estack_ax_t) {
d97f9b78
MD
961 case REG_S64: /* Fall-through */
962 case REG_U64:
53569322 963 switch (estack_bx_t) {
d97f9b78
MD
964 case REG_S64: /* Fall-through */
965 case REG_U64:
04aa13f8 966 JUMP_TO(BYTECODE_OP_EQ_S64);
53569322 967 case REG_DOUBLE:
04aa13f8 968 JUMP_TO(BYTECODE_OP_EQ_DOUBLE_S64);
3151a51d
PP
969 case REG_STRING: /* Fall-through */
970 case REG_STAR_GLOB_STRING:
53569322
MD
971 ret = -EINVAL;
972 goto end;
973 default:
04aa13f8 974 ERR("Unknown interpreter register type (%d)",
53569322
MD
975 (int) estack_bx_t);
976 ret = -EINVAL;
977 goto end;
978 }
979 break;
980 case REG_DOUBLE:
981 switch (estack_bx_t) {
d97f9b78
MD
982 case REG_S64: /* Fall-through */
983 case REG_U64:
04aa13f8 984 JUMP_TO(BYTECODE_OP_EQ_S64_DOUBLE);
53569322 985 case REG_DOUBLE:
04aa13f8 986 JUMP_TO(BYTECODE_OP_EQ_DOUBLE);
3151a51d
PP
987 case REG_STRING: /* Fall-through */
988 case REG_STAR_GLOB_STRING:
53569322
MD
989 ret = -EINVAL;
990 goto end;
991 default:
04aa13f8 992 ERR("Unknown interpreter register type (%d)",
53569322
MD
993 (int) estack_bx_t);
994 ret = -EINVAL;
995 goto end;
996 }
997 break;
998 case REG_STRING:
999 switch (estack_bx_t) {
1000 case REG_S64: /* Fall-through */
d97f9b78 1001 case REG_U64: /* Fall-through */
53569322
MD
1002 case REG_DOUBLE:
1003 ret = -EINVAL;
1004 goto end;
1005 case REG_STRING:
04aa13f8 1006 JUMP_TO(BYTECODE_OP_EQ_STRING);
3151a51d 1007 case REG_STAR_GLOB_STRING:
04aa13f8 1008 JUMP_TO(BYTECODE_OP_EQ_STAR_GLOB_STRING);
3151a51d 1009 default:
04aa13f8 1010 ERR("Unknown interpreter register type (%d)",
3151a51d
PP
1011 (int) estack_bx_t);
1012 ret = -EINVAL;
1013 goto end;
1014 }
1015 break;
1016 case REG_STAR_GLOB_STRING:
1017 switch (estack_bx_t) {
1018 case REG_S64: /* Fall-through */
d97f9b78 1019 case REG_U64: /* Fall-through */
3151a51d
PP
1020 case REG_DOUBLE:
1021 ret = -EINVAL;
1022 goto end;
1023 case REG_STRING:
04aa13f8 1024 JUMP_TO(BYTECODE_OP_EQ_STAR_GLOB_STRING);
3151a51d
PP
1025 case REG_STAR_GLOB_STRING:
1026 ret = -EINVAL;
1027 goto end;
53569322 1028 default:
04aa13f8 1029 ERR("Unknown interpreter register type (%d)",
53569322
MD
1030 (int) estack_bx_t);
1031 ret = -EINVAL;
1032 goto end;
1033 }
1034 break;
1035 default:
04aa13f8 1036 ERR("Unknown interpreter register type (%d)",
53569322
MD
1037 (int) estack_ax_t);
1038 ret = -EINVAL;
1039 goto end;
1040 }
1041 }
04aa13f8 1042 OP(BYTECODE_OP_NE):
53569322
MD
1043 {
1044 /* Dynamic typing. */
1045 switch (estack_ax_t) {
d97f9b78
MD
1046 case REG_S64: /* Fall-through */
1047 case REG_U64:
53569322 1048 switch (estack_bx_t) {
d97f9b78
MD
1049 case REG_S64: /* Fall-through */
1050 case REG_U64:
04aa13f8 1051 JUMP_TO(BYTECODE_OP_NE_S64);
53569322 1052 case REG_DOUBLE:
04aa13f8 1053 JUMP_TO(BYTECODE_OP_NE_DOUBLE_S64);
3151a51d
PP
1054 case REG_STRING: /* Fall-through */
1055 case REG_STAR_GLOB_STRING:
53569322
MD
1056 ret = -EINVAL;
1057 goto end;
1058 default:
04aa13f8 1059 ERR("Unknown interpreter register type (%d)",
53569322
MD
1060 (int) estack_bx_t);
1061 ret = -EINVAL;
1062 goto end;
1063 }
1064 break;
1065 case REG_DOUBLE:
1066 switch (estack_bx_t) {
d97f9b78
MD
1067 case REG_S64: /* Fall-through */
1068 case REG_U64:
04aa13f8 1069 JUMP_TO(BYTECODE_OP_NE_S64_DOUBLE);
53569322 1070 case REG_DOUBLE:
04aa13f8 1071 JUMP_TO(BYTECODE_OP_NE_DOUBLE);
3151a51d
PP
1072 case REG_STRING: /* Fall-through */
1073 case REG_STAR_GLOB_STRING:
53569322
MD
1074 ret = -EINVAL;
1075 goto end;
1076 default:
04aa13f8 1077 ERR("Unknown interpreter register type (%d)",
53569322
MD
1078 (int) estack_bx_t);
1079 ret = -EINVAL;
1080 goto end;
1081 }
1082 break;
1083 case REG_STRING:
1084 switch (estack_bx_t) {
1085 case REG_S64: /* Fall-through */
d97f9b78 1086 case REG_U64:
53569322
MD
1087 case REG_DOUBLE:
1088 ret = -EINVAL;
1089 goto end;
1090 case REG_STRING:
04aa13f8 1091 JUMP_TO(BYTECODE_OP_NE_STRING);
3151a51d 1092 case REG_STAR_GLOB_STRING:
04aa13f8 1093 JUMP_TO(BYTECODE_OP_NE_STAR_GLOB_STRING);
3151a51d 1094 default:
04aa13f8 1095 ERR("Unknown interpreter register type (%d)",
3151a51d
PP
1096 (int) estack_bx_t);
1097 ret = -EINVAL;
1098 goto end;
1099 }
1100 break;
1101 case REG_STAR_GLOB_STRING:
1102 switch (estack_bx_t) {
1103 case REG_S64: /* Fall-through */
d97f9b78 1104 case REG_U64:
3151a51d
PP
1105 case REG_DOUBLE:
1106 ret = -EINVAL;
1107 goto end;
1108 case REG_STRING:
04aa13f8 1109 JUMP_TO(BYTECODE_OP_NE_STAR_GLOB_STRING);
3151a51d
PP
1110 case REG_STAR_GLOB_STRING:
1111 ret = -EINVAL;
1112 goto end;
53569322 1113 default:
04aa13f8 1114 ERR("Unknown interpreter register type (%d)",
53569322
MD
1115 (int) estack_bx_t);
1116 ret = -EINVAL;
1117 goto end;
1118 }
1119 break;
1120 default:
04aa13f8 1121 ERR("Unknown interpreter register type (%d)",
53569322
MD
1122 (int) estack_ax_t);
1123 ret = -EINVAL;
1124 goto end;
1125 }
1126 }
04aa13f8 1127 OP(BYTECODE_OP_GT):
53569322
MD
1128 {
1129 /* Dynamic typing. */
1130 switch (estack_ax_t) {
d97f9b78
MD
1131 case REG_S64: /* Fall-through */
1132 case REG_U64:
53569322 1133 switch (estack_bx_t) {
d97f9b78
MD
1134 case REG_S64: /* Fall-through */
1135 case REG_U64:
04aa13f8 1136 JUMP_TO(BYTECODE_OP_GT_S64);
53569322 1137 case REG_DOUBLE:
04aa13f8 1138 JUMP_TO(BYTECODE_OP_GT_DOUBLE_S64);
3151a51d
PP
1139 case REG_STRING: /* Fall-through */
1140 case REG_STAR_GLOB_STRING:
53569322
MD
1141 ret = -EINVAL;
1142 goto end;
1143 default:
04aa13f8 1144 ERR("Unknown interpreter register type (%d)",
53569322
MD
1145 (int) estack_bx_t);
1146 ret = -EINVAL;
1147 goto end;
1148 }
1149 break;
1150 case REG_DOUBLE:
1151 switch (estack_bx_t) {
d97f9b78
MD
1152 case REG_S64: /* Fall-through */
1153 case REG_U64:
04aa13f8 1154 JUMP_TO(BYTECODE_OP_GT_S64_DOUBLE);
53569322 1155 case REG_DOUBLE:
04aa13f8 1156 JUMP_TO(BYTECODE_OP_GT_DOUBLE);
3151a51d
PP
1157 case REG_STRING: /* Fall-through */
1158 case REG_STAR_GLOB_STRING:
53569322
MD
1159 ret = -EINVAL;
1160 goto end;
1161 default:
04aa13f8 1162 ERR("Unknown interpreter register type (%d)",
53569322
MD
1163 (int) estack_bx_t);
1164 ret = -EINVAL;
1165 goto end;
1166 }
1167 break;
1168 case REG_STRING:
1169 switch (estack_bx_t) {
1170 case REG_S64: /* Fall-through */
d97f9b78 1171 case REG_U64: /* Fall-through */
3151a51d
PP
1172 case REG_DOUBLE: /* Fall-through */
1173 case REG_STAR_GLOB_STRING:
53569322
MD
1174 ret = -EINVAL;
1175 goto end;
1176 case REG_STRING:
04aa13f8 1177 JUMP_TO(BYTECODE_OP_GT_STRING);
53569322 1178 default:
04aa13f8 1179 ERR("Unknown interpreter register type (%d)",
53569322
MD
1180 (int) estack_bx_t);
1181 ret = -EINVAL;
1182 goto end;
1183 }
1184 break;
1185 default:
04aa13f8 1186 ERR("Unknown interpreter register type (%d)",
53569322
MD
1187 (int) estack_ax_t);
1188 ret = -EINVAL;
1189 goto end;
1190 }
1191 }
04aa13f8 1192 OP(BYTECODE_OP_LT):
53569322
MD
1193 {
1194 /* Dynamic typing. */
1195 switch (estack_ax_t) {
d97f9b78
MD
1196 case REG_S64: /* Fall-through */
1197 case REG_U64:
53569322 1198 switch (estack_bx_t) {
d97f9b78
MD
1199 case REG_S64: /* Fall-through */
1200 case REG_U64:
04aa13f8 1201 JUMP_TO(BYTECODE_OP_LT_S64);
53569322 1202 case REG_DOUBLE:
04aa13f8 1203 JUMP_TO(BYTECODE_OP_LT_DOUBLE_S64);
3151a51d
PP
1204 case REG_STRING: /* Fall-through */
1205 case REG_STAR_GLOB_STRING:
53569322
MD
1206 ret = -EINVAL;
1207 goto end;
1208 default:
04aa13f8 1209 ERR("Unknown interpreter register type (%d)",
53569322
MD
1210 (int) estack_bx_t);
1211 ret = -EINVAL;
1212 goto end;
1213 }
1214 break;
1215 case REG_DOUBLE:
1216 switch (estack_bx_t) {
d97f9b78
MD
1217 case REG_S64: /* Fall-through */
1218 case REG_U64:
04aa13f8 1219 JUMP_TO(BYTECODE_OP_LT_S64_DOUBLE);
53569322 1220 case REG_DOUBLE:
04aa13f8 1221 JUMP_TO(BYTECODE_OP_LT_DOUBLE);
3151a51d
PP
1222 case REG_STRING: /* Fall-through */
1223 case REG_STAR_GLOB_STRING:
53569322
MD
1224 ret = -EINVAL;
1225 goto end;
1226 default:
04aa13f8 1227 ERR("Unknown interpreter register type (%d)",
53569322
MD
1228 (int) estack_bx_t);
1229 ret = -EINVAL;
1230 goto end;
1231 }
1232 break;
1233 case REG_STRING:
1234 switch (estack_bx_t) {
1235 case REG_S64: /* Fall-through */
d97f9b78 1236 case REG_U64: /* Fall-through */
3151a51d
PP
1237 case REG_DOUBLE: /* Fall-through */
1238 case REG_STAR_GLOB_STRING:
53569322
MD
1239 ret = -EINVAL;
1240 goto end;
1241 case REG_STRING:
04aa13f8 1242 JUMP_TO(BYTECODE_OP_LT_STRING);
53569322 1243 default:
04aa13f8 1244 ERR("Unknown interpreter register type (%d)",
53569322
MD
1245 (int) estack_bx_t);
1246 ret = -EINVAL;
1247 goto end;
1248 }
1249 break;
1250 default:
04aa13f8 1251 ERR("Unknown interpreter register type (%d)",
53569322
MD
1252 (int) estack_ax_t);
1253 ret = -EINVAL;
1254 goto end;
1255 }
1256 }
04aa13f8 1257 OP(BYTECODE_OP_GE):
53569322
MD
1258 {
1259 /* Dynamic typing. */
1260 switch (estack_ax_t) {
d97f9b78
MD
1261 case REG_S64: /* Fall-through */
1262 case REG_U64:
53569322 1263 switch (estack_bx_t) {
d97f9b78
MD
1264 case REG_S64: /* Fall-through */
1265 case REG_U64:
04aa13f8 1266 JUMP_TO(BYTECODE_OP_GE_S64);
53569322 1267 case REG_DOUBLE:
04aa13f8 1268 JUMP_TO(BYTECODE_OP_GE_DOUBLE_S64);
3151a51d
PP
1269 case REG_STRING: /* Fall-through */
1270 case REG_STAR_GLOB_STRING:
53569322
MD
1271 ret = -EINVAL;
1272 goto end;
1273 default:
04aa13f8 1274 ERR("Unknown interpreter register type (%d)",
53569322
MD
1275 (int) estack_bx_t);
1276 ret = -EINVAL;
1277 goto end;
1278 }
1279 break;
1280 case REG_DOUBLE:
1281 switch (estack_bx_t) {
d97f9b78
MD
1282 case REG_S64: /* Fall-through */
1283 case REG_U64:
04aa13f8 1284 JUMP_TO(BYTECODE_OP_GE_S64_DOUBLE);
53569322 1285 case REG_DOUBLE:
04aa13f8 1286 JUMP_TO(BYTECODE_OP_GE_DOUBLE);
3151a51d
PP
1287 case REG_STRING: /* Fall-through */
1288 case REG_STAR_GLOB_STRING:
53569322
MD
1289 ret = -EINVAL;
1290 goto end;
1291 default:
04aa13f8 1292 ERR("Unknown interpreter register type (%d)",
53569322
MD
1293 (int) estack_bx_t);
1294 ret = -EINVAL;
1295 goto end;
1296 }
1297 break;
1298 case REG_STRING:
1299 switch (estack_bx_t) {
1300 case REG_S64: /* Fall-through */
d97f9b78 1301 case REG_U64: /* Fall-through */
3151a51d
PP
1302 case REG_DOUBLE: /* Fall-through */
1303 case REG_STAR_GLOB_STRING:
53569322
MD
1304 ret = -EINVAL;
1305 goto end;
1306 case REG_STRING:
04aa13f8 1307 JUMP_TO(BYTECODE_OP_GE_STRING);
53569322 1308 default:
04aa13f8 1309 ERR("Unknown interpreter register type (%d)",
53569322
MD
1310 (int) estack_bx_t);
1311 ret = -EINVAL;
1312 goto end;
1313 }
1314 break;
1315 default:
04aa13f8 1316 ERR("Unknown interpreter register type (%d)",
53569322
MD
1317 (int) estack_ax_t);
1318 ret = -EINVAL;
1319 goto end;
1320 }
1321 }
04aa13f8 1322 OP(BYTECODE_OP_LE):
53569322
MD
1323 {
1324 /* Dynamic typing. */
1325 switch (estack_ax_t) {
d97f9b78
MD
1326 case REG_S64: /* Fall-through */
1327 case REG_U64:
53569322 1328 switch (estack_bx_t) {
d97f9b78
MD
1329 case REG_S64: /* Fall-through */
1330 case REG_U64:
04aa13f8 1331 JUMP_TO(BYTECODE_OP_LE_S64);
53569322 1332 case REG_DOUBLE:
04aa13f8 1333 JUMP_TO(BYTECODE_OP_LE_DOUBLE_S64);
3151a51d
PP
1334 case REG_STRING: /* Fall-through */
1335 case REG_STAR_GLOB_STRING:
53569322
MD
1336 ret = -EINVAL;
1337 goto end;
1338 default:
04aa13f8 1339 ERR("Unknown interpreter register type (%d)",
53569322
MD
1340 (int) estack_bx_t);
1341 ret = -EINVAL;
1342 goto end;
1343 }
1344 break;
1345 case REG_DOUBLE:
1346 switch (estack_bx_t) {
d97f9b78
MD
1347 case REG_S64: /* Fall-through */
1348 case REG_U64:
04aa13f8 1349 JUMP_TO(BYTECODE_OP_LE_S64_DOUBLE);
53569322 1350 case REG_DOUBLE:
04aa13f8 1351 JUMP_TO(BYTECODE_OP_LE_DOUBLE);
3151a51d
PP
1352 case REG_STRING: /* Fall-through */
1353 case REG_STAR_GLOB_STRING:
53569322
MD
1354 ret = -EINVAL;
1355 goto end;
1356 default:
04aa13f8 1357 ERR("Unknown interpreter register type (%d)",
53569322
MD
1358 (int) estack_bx_t);
1359 ret = -EINVAL;
1360 goto end;
1361 }
1362 break;
1363 case REG_STRING:
1364 switch (estack_bx_t) {
1365 case REG_S64: /* Fall-through */
d97f9b78 1366 case REG_U64: /* Fall-through */
3151a51d
PP
1367 case REG_DOUBLE: /* Fall-through */
1368 case REG_STAR_GLOB_STRING:
53569322
MD
1369 ret = -EINVAL;
1370 goto end;
1371 case REG_STRING:
04aa13f8 1372 JUMP_TO(BYTECODE_OP_LE_STRING);
53569322 1373 default:
04aa13f8 1374 ERR("Unknown interpreter register type (%d)",
53569322
MD
1375 (int) estack_bx_t);
1376 ret = -EINVAL;
1377 goto end;
1378 }
1379 break;
1380 default:
04aa13f8 1381 ERR("Unknown interpreter register type (%d)",
53569322
MD
1382 (int) estack_ax_t);
1383 ret = -EINVAL;
1384 goto end;
1385 }
1386 }
97b58163 1387
04aa13f8 1388 OP(BYTECODE_OP_EQ_STRING):
97b58163 1389 {
0305960f
MD
1390 int res;
1391
9b33aac4 1392 res = (stack_strcmp(stack, top, "==") == 0);
53569322 1393 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1394 estack_ax_v = res;
53569322 1395 estack_ax_t = REG_S64;
97b58163
MD
1396 next_pc += sizeof(struct binary_op);
1397 PO;
1398 }
04aa13f8 1399 OP(BYTECODE_OP_NE_STRING):
97b58163 1400 {
0305960f
MD
1401 int res;
1402
9b33aac4 1403 res = (stack_strcmp(stack, top, "!=") != 0);
53569322 1404 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1405 estack_ax_v = res;
53569322 1406 estack_ax_t = REG_S64;
97b58163
MD
1407 next_pc += sizeof(struct binary_op);
1408 PO;
1409 }
04aa13f8 1410 OP(BYTECODE_OP_GT_STRING):
97b58163 1411 {
0305960f
MD
1412 int res;
1413
9b33aac4 1414 res = (stack_strcmp(stack, top, ">") > 0);
53569322 1415 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1416 estack_ax_v = res;
53569322 1417 estack_ax_t = REG_S64;
97b58163
MD
1418 next_pc += sizeof(struct binary_op);
1419 PO;
1420 }
04aa13f8 1421 OP(BYTECODE_OP_LT_STRING):
97b58163 1422 {
0305960f
MD
1423 int res;
1424
9b33aac4 1425 res = (stack_strcmp(stack, top, "<") < 0);
53569322 1426 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1427 estack_ax_v = res;
53569322 1428 estack_ax_t = REG_S64;
97b58163
MD
1429 next_pc += sizeof(struct binary_op);
1430 PO;
1431 }
04aa13f8 1432 OP(BYTECODE_OP_GE_STRING):
97b58163 1433 {
0305960f
MD
1434 int res;
1435
9b33aac4 1436 res = (stack_strcmp(stack, top, ">=") >= 0);
53569322 1437 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1438 estack_ax_v = res;
53569322 1439 estack_ax_t = REG_S64;
97b58163
MD
1440 next_pc += sizeof(struct binary_op);
1441 PO;
1442 }
04aa13f8 1443 OP(BYTECODE_OP_LE_STRING):
97b58163 1444 {
0305960f
MD
1445 int res;
1446
9b33aac4 1447 res = (stack_strcmp(stack, top, "<=") <= 0);
53569322 1448 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1449 estack_ax_v = res;
53569322 1450 estack_ax_t = REG_S64;
97b58163
MD
1451 next_pc += sizeof(struct binary_op);
1452 PO;
1453 }
1454
04aa13f8 1455 OP(BYTECODE_OP_EQ_STAR_GLOB_STRING):
3151a51d
PP
1456 {
1457 int res;
1458
1459 res = (stack_star_glob_match(stack, top, "==") == 0);
1460 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1461 estack_ax_v = res;
1462 estack_ax_t = REG_S64;
1463 next_pc += sizeof(struct binary_op);
1464 PO;
1465 }
04aa13f8 1466 OP(BYTECODE_OP_NE_STAR_GLOB_STRING):
3151a51d
PP
1467 {
1468 int res;
1469
1470 res = (stack_star_glob_match(stack, top, "!=") != 0);
1471 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1472 estack_ax_v = res;
1473 estack_ax_t = REG_S64;
1474 next_pc += sizeof(struct binary_op);
1475 PO;
1476 }
1477
04aa13f8 1478 OP(BYTECODE_OP_EQ_S64):
97b58163 1479 {
0305960f
MD
1480 int res;
1481
9b33aac4 1482 res = (estack_bx_v == estack_ax_v);
53569322 1483 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1484 estack_ax_v = res;
53569322 1485 estack_ax_t = REG_S64;
97b58163
MD
1486 next_pc += sizeof(struct binary_op);
1487 PO;
1488 }
04aa13f8 1489 OP(BYTECODE_OP_NE_S64):
97b58163 1490 {
0305960f
MD
1491 int res;
1492
9b33aac4 1493 res = (estack_bx_v != estack_ax_v);
53569322 1494 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1495 estack_ax_v = res;
53569322 1496 estack_ax_t = REG_S64;
97b58163
MD
1497 next_pc += sizeof(struct binary_op);
1498 PO;
1499 }
04aa13f8 1500 OP(BYTECODE_OP_GT_S64):
97b58163 1501 {
0305960f
MD
1502 int res;
1503
9b33aac4 1504 res = (estack_bx_v > estack_ax_v);
53569322 1505 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1506 estack_ax_v = res;
53569322 1507 estack_ax_t = REG_S64;
97b58163
MD
1508 next_pc += sizeof(struct binary_op);
1509 PO;
1510 }
04aa13f8 1511 OP(BYTECODE_OP_LT_S64):
97b58163 1512 {
0305960f
MD
1513 int res;
1514
9b33aac4 1515 res = (estack_bx_v < estack_ax_v);
53569322 1516 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1517 estack_ax_v = res;
53569322 1518 estack_ax_t = REG_S64;
97b58163
MD
1519 next_pc += sizeof(struct binary_op);
1520 PO;
1521 }
04aa13f8 1522 OP(BYTECODE_OP_GE_S64):
97b58163 1523 {
0305960f
MD
1524 int res;
1525
9b33aac4 1526 res = (estack_bx_v >= estack_ax_v);
53569322 1527 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1528 estack_ax_v = res;
53569322 1529 estack_ax_t = REG_S64;
97b58163
MD
1530 next_pc += sizeof(struct binary_op);
1531 PO;
1532 }
04aa13f8 1533 OP(BYTECODE_OP_LE_S64):
97b58163 1534 {
0305960f
MD
1535 int res;
1536
9b33aac4 1537 res = (estack_bx_v <= estack_ax_v);
53569322 1538 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1539 estack_ax_v = res;
53569322 1540 estack_ax_t = REG_S64;
97b58163
MD
1541 next_pc += sizeof(struct binary_op);
1542 PO;
1543 }
1544
04aa13f8 1545 OP(BYTECODE_OP_EQ_DOUBLE):
97b58163 1546 {
0305960f
MD
1547 int res;
1548
9b33aac4 1549 res = (estack_bx(stack, top)->u.d == estack_ax(stack, top)->u.d);
53569322 1550 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1551 estack_ax_v = res;
53569322 1552 estack_ax_t = REG_S64;
97b58163
MD
1553 next_pc += sizeof(struct binary_op);
1554 PO;
1555 }
04aa13f8 1556 OP(BYTECODE_OP_NE_DOUBLE):
97b58163 1557 {
0305960f
MD
1558 int res;
1559
9b33aac4 1560 res = (estack_bx(stack, top)->u.d != estack_ax(stack, top)->u.d);
53569322 1561 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1562 estack_ax_v = res;
53569322 1563 estack_ax_t = REG_S64;
97b58163
MD
1564 next_pc += sizeof(struct binary_op);
1565 PO;
1566 }
04aa13f8 1567 OP(BYTECODE_OP_GT_DOUBLE):
97b58163 1568 {
0305960f
MD
1569 int res;
1570
9b33aac4 1571 res = (estack_bx(stack, top)->u.d > estack_ax(stack, top)->u.d);
53569322 1572 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1573 estack_ax_v = res;
53569322 1574 estack_ax_t = REG_S64;
97b58163
MD
1575 next_pc += sizeof(struct binary_op);
1576 PO;
1577 }
04aa13f8 1578 OP(BYTECODE_OP_LT_DOUBLE):
97b58163 1579 {
0305960f
MD
1580 int res;
1581
9b33aac4 1582 res = (estack_bx(stack, top)->u.d < estack_ax(stack, top)->u.d);
53569322 1583 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1584 estack_ax_v = res;
53569322 1585 estack_ax_t = REG_S64;
97b58163
MD
1586 next_pc += sizeof(struct binary_op);
1587 PO;
1588 }
04aa13f8 1589 OP(BYTECODE_OP_GE_DOUBLE):
97b58163 1590 {
0305960f
MD
1591 int res;
1592
9b33aac4 1593 res = (estack_bx(stack, top)->u.d >= estack_ax(stack, top)->u.d);
53569322 1594 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1595 estack_ax_v = res;
53569322 1596 estack_ax_t = REG_S64;
97b58163
MD
1597 next_pc += sizeof(struct binary_op);
1598 PO;
1599 }
04aa13f8 1600 OP(BYTECODE_OP_LE_DOUBLE):
97b58163 1601 {
0305960f
MD
1602 int res;
1603
9b33aac4 1604 res = (estack_bx(stack, top)->u.d <= estack_ax(stack, top)->u.d);
53569322 1605 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1606 estack_ax_v = res;
53569322 1607 estack_ax_t = REG_S64;
dbea82ec
MD
1608 next_pc += sizeof(struct binary_op);
1609 PO;
1610 }
1611
1612 /* Mixed S64-double binary comparators */
04aa13f8 1613 OP(BYTECODE_OP_EQ_DOUBLE_S64):
dbea82ec
MD
1614 {
1615 int res;
1616
9b33aac4 1617 res = (estack_bx(stack, top)->u.d == estack_ax_v);
53569322 1618 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1619 estack_ax_v = res;
53569322 1620 estack_ax_t = REG_S64;
dbea82ec
MD
1621 next_pc += sizeof(struct binary_op);
1622 PO;
1623 }
04aa13f8 1624 OP(BYTECODE_OP_NE_DOUBLE_S64):
dbea82ec
MD
1625 {
1626 int res;
1627
9b33aac4 1628 res = (estack_bx(stack, top)->u.d != estack_ax_v);
53569322 1629 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1630 estack_ax_v = res;
53569322 1631 estack_ax_t = REG_S64;
dbea82ec
MD
1632 next_pc += sizeof(struct binary_op);
1633 PO;
1634 }
04aa13f8 1635 OP(BYTECODE_OP_GT_DOUBLE_S64):
dbea82ec
MD
1636 {
1637 int res;
1638
9b33aac4 1639 res = (estack_bx(stack, top)->u.d > estack_ax_v);
53569322 1640 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1641 estack_ax_v = res;
53569322 1642 estack_ax_t = REG_S64;
dbea82ec
MD
1643 next_pc += sizeof(struct binary_op);
1644 PO;
1645 }
04aa13f8 1646 OP(BYTECODE_OP_LT_DOUBLE_S64):
dbea82ec
MD
1647 {
1648 int res;
1649
9b33aac4 1650 res = (estack_bx(stack, top)->u.d < estack_ax_v);
53569322 1651 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1652 estack_ax_v = res;
53569322 1653 estack_ax_t = REG_S64;
dbea82ec
MD
1654 next_pc += sizeof(struct binary_op);
1655 PO;
1656 }
04aa13f8 1657 OP(BYTECODE_OP_GE_DOUBLE_S64):
dbea82ec
MD
1658 {
1659 int res;
1660
9b33aac4 1661 res = (estack_bx(stack, top)->u.d >= estack_ax_v);
53569322 1662 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1663 estack_ax_v = res;
53569322 1664 estack_ax_t = REG_S64;
dbea82ec
MD
1665 next_pc += sizeof(struct binary_op);
1666 PO;
1667 }
04aa13f8 1668 OP(BYTECODE_OP_LE_DOUBLE_S64):
dbea82ec
MD
1669 {
1670 int res;
1671
9b33aac4 1672 res = (estack_bx(stack, top)->u.d <= estack_ax_v);
53569322 1673 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1674 estack_ax_v = res;
53569322 1675 estack_ax_t = REG_S64;
dbea82ec
MD
1676 next_pc += sizeof(struct binary_op);
1677 PO;
1678 }
1679
04aa13f8 1680 OP(BYTECODE_OP_EQ_S64_DOUBLE):
dbea82ec
MD
1681 {
1682 int res;
1683
9b33aac4 1684 res = (estack_bx_v == estack_ax(stack, top)->u.d);
53569322 1685 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1686 estack_ax_v = res;
53569322 1687 estack_ax_t = REG_S64;
dbea82ec
MD
1688 next_pc += sizeof(struct binary_op);
1689 PO;
1690 }
04aa13f8 1691 OP(BYTECODE_OP_NE_S64_DOUBLE):
dbea82ec
MD
1692 {
1693 int res;
1694
9b33aac4 1695 res = (estack_bx_v != estack_ax(stack, top)->u.d);
53569322 1696 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1697 estack_ax_v = res;
53569322 1698 estack_ax_t = REG_S64;
dbea82ec
MD
1699 next_pc += sizeof(struct binary_op);
1700 PO;
1701 }
04aa13f8 1702 OP(BYTECODE_OP_GT_S64_DOUBLE):
dbea82ec
MD
1703 {
1704 int res;
1705
9b33aac4 1706 res = (estack_bx_v > estack_ax(stack, top)->u.d);
53569322 1707 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1708 estack_ax_v = res;
53569322 1709 estack_ax_t = REG_S64;
dbea82ec
MD
1710 next_pc += sizeof(struct binary_op);
1711 PO;
1712 }
04aa13f8 1713 OP(BYTECODE_OP_LT_S64_DOUBLE):
dbea82ec
MD
1714 {
1715 int res;
1716
9b33aac4 1717 res = (estack_bx_v < estack_ax(stack, top)->u.d);
53569322 1718 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1719 estack_ax_v = res;
53569322 1720 estack_ax_t = REG_S64;
dbea82ec
MD
1721 next_pc += sizeof(struct binary_op);
1722 PO;
1723 }
04aa13f8 1724 OP(BYTECODE_OP_GE_S64_DOUBLE):
dbea82ec
MD
1725 {
1726 int res;
1727
9b33aac4 1728 res = (estack_bx_v >= estack_ax(stack, top)->u.d);
53569322 1729 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1730 estack_ax_v = res;
53569322 1731 estack_ax_t = REG_S64;
dbea82ec
MD
1732 next_pc += sizeof(struct binary_op);
1733 PO;
1734 }
04aa13f8 1735 OP(BYTECODE_OP_LE_S64_DOUBLE):
dbea82ec
MD
1736 {
1737 int res;
1738
9b33aac4 1739 res = (estack_bx_v <= estack_ax(stack, top)->u.d);
53569322 1740 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1741 estack_ax_v = res;
53569322 1742 estack_ax_t = REG_S64;
97b58163
MD
1743 next_pc += sizeof(struct binary_op);
1744 PO;
1745 }
04aa13f8 1746 OP(BYTECODE_OP_BIT_RSHIFT):
0039e2d8
MD
1747 {
1748 int64_t res;
1749
d97f9b78 1750 if (!IS_INTEGER_REGISTER(estack_ax_t) || !IS_INTEGER_REGISTER(estack_bx_t)) {
0039e2d8
MD
1751 ret = -EINVAL;
1752 goto end;
1753 }
d97f9b78 1754
3703f1d2
MD
1755 /* Catch undefined behavior. */
1756 if (caa_unlikely(estack_ax_v < 0 || estack_ax_v >= 64)) {
1757 ret = -EINVAL;
1758 goto end;
1759 }
4e8f9a89 1760 res = ((uint64_t) estack_bx_v >> (uint32_t) estack_ax_v);
0039e2d8
MD
1761 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1762 estack_ax_v = res;
d97f9b78 1763 estack_ax_t = REG_U64;
0039e2d8
MD
1764 next_pc += sizeof(struct binary_op);
1765 PO;
1766 }
04aa13f8 1767 OP(BYTECODE_OP_BIT_LSHIFT):
0039e2d8
MD
1768 {
1769 int64_t res;
1770
d97f9b78 1771 if (!IS_INTEGER_REGISTER(estack_ax_t) || !IS_INTEGER_REGISTER(estack_bx_t)) {
0039e2d8
MD
1772 ret = -EINVAL;
1773 goto end;
1774 }
d97f9b78 1775
3703f1d2
MD
1776 /* Catch undefined behavior. */
1777 if (caa_unlikely(estack_ax_v < 0 || estack_ax_v >= 64)) {
1778 ret = -EINVAL;
1779 goto end;
1780 }
4e8f9a89 1781 res = ((uint64_t) estack_bx_v << (uint32_t) estack_ax_v);
0039e2d8
MD
1782 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1783 estack_ax_v = res;
d97f9b78 1784 estack_ax_t = REG_U64;
0039e2d8
MD
1785 next_pc += sizeof(struct binary_op);
1786 PO;
1787 }
04aa13f8 1788 OP(BYTECODE_OP_BIT_AND):
47e5f13e
MD
1789 {
1790 int64_t res;
1791
d97f9b78 1792 if (!IS_INTEGER_REGISTER(estack_ax_t) || !IS_INTEGER_REGISTER(estack_bx_t)) {
47e5f13e
MD
1793 ret = -EINVAL;
1794 goto end;
1795 }
1796
4e8f9a89 1797 res = ((uint64_t) estack_bx_v & (uint64_t) estack_ax_v);
47e5f13e
MD
1798 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1799 estack_ax_v = res;
d97f9b78 1800 estack_ax_t = REG_U64;
47e5f13e
MD
1801 next_pc += sizeof(struct binary_op);
1802 PO;
1803 }
04aa13f8 1804 OP(BYTECODE_OP_BIT_OR):
47e5f13e
MD
1805 {
1806 int64_t res;
1807
d97f9b78 1808 if (!IS_INTEGER_REGISTER(estack_ax_t) || !IS_INTEGER_REGISTER(estack_bx_t)) {
47e5f13e
MD
1809 ret = -EINVAL;
1810 goto end;
1811 }
1812
4e8f9a89 1813 res = ((uint64_t) estack_bx_v | (uint64_t) estack_ax_v);
47e5f13e
MD
1814 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1815 estack_ax_v = res;
d97f9b78 1816 estack_ax_t = REG_U64;
47e5f13e
MD
1817 next_pc += sizeof(struct binary_op);
1818 PO;
1819 }
04aa13f8 1820 OP(BYTECODE_OP_BIT_XOR):
47e5f13e
MD
1821 {
1822 int64_t res;
1823
d97f9b78 1824 if (!IS_INTEGER_REGISTER(estack_ax_t) || !IS_INTEGER_REGISTER(estack_bx_t)) {
47e5f13e
MD
1825 ret = -EINVAL;
1826 goto end;
1827 }
1828
4e8f9a89 1829 res = ((uint64_t) estack_bx_v ^ (uint64_t) estack_ax_v);
47e5f13e
MD
1830 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1831 estack_ax_v = res;
d97f9b78 1832 estack_ax_t = REG_U64;
47e5f13e
MD
1833 next_pc += sizeof(struct binary_op);
1834 PO;
1835 }
97b58163
MD
1836
1837 /* unary */
04aa13f8 1838 OP(BYTECODE_OP_UNARY_PLUS):
53569322
MD
1839 {
1840 /* Dynamic typing. */
1841 switch (estack_ax_t) {
1842 case REG_S64: /* Fall-through. */
d97f9b78 1843 case REG_U64:
04aa13f8 1844 JUMP_TO(BYTECODE_OP_UNARY_PLUS_S64);
53569322 1845 case REG_DOUBLE:
04aa13f8 1846 JUMP_TO(BYTECODE_OP_UNARY_PLUS_DOUBLE);
3151a51d
PP
1847 case REG_STRING: /* Fall-through */
1848 case REG_STAR_GLOB_STRING:
53569322
MD
1849 ret = -EINVAL;
1850 goto end;
1851 default:
04aa13f8 1852 ERR("Unknown interpreter register type (%d)",
53569322
MD
1853 (int) estack_ax_t);
1854 ret = -EINVAL;
1855 goto end;
1856 }
1857 }
04aa13f8 1858 OP(BYTECODE_OP_UNARY_MINUS):
53569322
MD
1859 {
1860 /* Dynamic typing. */
1861 switch (estack_ax_t) {
d97f9b78
MD
1862 case REG_S64: /* Fall-through. */
1863 case REG_U64:
04aa13f8 1864 JUMP_TO(BYTECODE_OP_UNARY_MINUS_S64);
53569322 1865 case REG_DOUBLE:
04aa13f8 1866 JUMP_TO(BYTECODE_OP_UNARY_MINUS_DOUBLE);
3151a51d
PP
1867 case REG_STRING: /* Fall-through */
1868 case REG_STAR_GLOB_STRING:
53569322
MD
1869 ret = -EINVAL;
1870 goto end;
1871 default:
04aa13f8 1872 ERR("Unknown interpreter register type (%d)",
53569322
MD
1873 (int) estack_ax_t);
1874 ret = -EINVAL;
1875 goto end;
1876 }
1877 }
04aa13f8 1878 OP(BYTECODE_OP_UNARY_NOT):
53569322
MD
1879 {
1880 /* Dynamic typing. */
1881 switch (estack_ax_t) {
d97f9b78
MD
1882 case REG_S64: /* Fall-through. */
1883 case REG_U64:
04aa13f8 1884 JUMP_TO(BYTECODE_OP_UNARY_NOT_S64);
53569322 1885 case REG_DOUBLE:
04aa13f8 1886 JUMP_TO(BYTECODE_OP_UNARY_NOT_DOUBLE);
3151a51d
PP
1887 case REG_STRING: /* Fall-through */
1888 case REG_STAR_GLOB_STRING:
53569322
MD
1889 ret = -EINVAL;
1890 goto end;
1891 default:
04aa13f8 1892 ERR("Unknown interpreter register type (%d)",
53569322
MD
1893 (int) estack_ax_t);
1894 ret = -EINVAL;
1895 goto end;
1896 }
1897 next_pc += sizeof(struct unary_op);
1898 PO;
1899 }
97b58163 1900
04aa13f8 1901 OP(BYTECODE_OP_UNARY_BIT_NOT):
0039e2d8
MD
1902 {
1903 /* Dynamic typing. */
d97f9b78 1904 if (!IS_INTEGER_REGISTER(estack_ax_t)) {
0039e2d8
MD
1905 ret = -EINVAL;
1906 goto end;
1907 }
1908
4e8f9a89 1909 estack_ax_v = ~(uint64_t) estack_ax_v;
d97f9b78 1910 estack_ax_t = REG_U64;
0039e2d8
MD
1911 next_pc += sizeof(struct unary_op);
1912 PO;
1913 }
1914
04aa13f8
FD
1915 OP(BYTECODE_OP_UNARY_PLUS_S64):
1916 OP(BYTECODE_OP_UNARY_PLUS_DOUBLE):
97b58163
MD
1917 {
1918 next_pc += sizeof(struct unary_op);
1919 PO;
1920 }
04aa13f8 1921 OP(BYTECODE_OP_UNARY_MINUS_S64):
97b58163 1922 {
9b33aac4 1923 estack_ax_v = -estack_ax_v;
97b58163
MD
1924 next_pc += sizeof(struct unary_op);
1925 PO;
1926 }
04aa13f8 1927 OP(BYTECODE_OP_UNARY_MINUS_DOUBLE):
97b58163 1928 {
9b33aac4 1929 estack_ax(stack, top)->u.d = -estack_ax(stack, top)->u.d;
97b58163
MD
1930 next_pc += sizeof(struct unary_op);
1931 PO;
1932 }
04aa13f8 1933 OP(BYTECODE_OP_UNARY_NOT_S64):
97b58163 1934 {
9b33aac4 1935 estack_ax_v = !estack_ax_v;
d97f9b78 1936 estack_ax_t = REG_S64;
97b58163
MD
1937 next_pc += sizeof(struct unary_op);
1938 PO;
1939 }
04aa13f8 1940 OP(BYTECODE_OP_UNARY_NOT_DOUBLE):
97b58163 1941 {
53569322
MD
1942 estack_ax_v = !estack_ax(stack, top)->u.d;
1943 estack_ax_t = REG_S64;
97b58163
MD
1944 next_pc += sizeof(struct unary_op);
1945 PO;
1946 }
1947
1948 /* logical */
04aa13f8 1949 OP(BYTECODE_OP_AND):
97b58163
MD
1950 {
1951 struct logical_op *insn = (struct logical_op *) pc;
1952
d97f9b78 1953 if (estack_ax_t != REG_S64 && estack_ax_t != REG_U64) {
53569322
MD
1954 ret = -EINVAL;
1955 goto end;
1956 }
0305960f 1957 /* If AX is 0, skip and evaluate to 0 */
9b33aac4 1958 if (unlikely(estack_ax_v == 0)) {
97b58163
MD
1959 dbg_printf("Jumping to bytecode offset %u\n",
1960 (unsigned int) insn->skip_offset);
1961 next_pc = start_pc + insn->skip_offset;
1962 } else {
71c1ceeb 1963 /* Pop 1 when jump not taken */
53569322 1964 estack_pop(stack, top, ax, bx, ax_t, bx_t);
97b58163
MD
1965 next_pc += sizeof(struct logical_op);
1966 }
1967 PO;
1968 }
04aa13f8 1969 OP(BYTECODE_OP_OR):
97b58163
MD
1970 {
1971 struct logical_op *insn = (struct logical_op *) pc;
1972
d97f9b78 1973 if (estack_ax_t != REG_S64 && estack_ax_t != REG_U64) {
53569322
MD
1974 ret = -EINVAL;
1975 goto end;
1976 }
0305960f 1977 /* If AX is nonzero, skip and evaluate to 1 */
9b33aac4
MD
1978 if (unlikely(estack_ax_v != 0)) {
1979 estack_ax_v = 1;
97b58163
MD
1980 dbg_printf("Jumping to bytecode offset %u\n",
1981 (unsigned int) insn->skip_offset);
1982 next_pc = start_pc + insn->skip_offset;
1983 } else {
71c1ceeb 1984 /* Pop 1 when jump not taken */
53569322 1985 estack_pop(stack, top, ax, bx, ax_t, bx_t);
97b58163
MD
1986 next_pc += sizeof(struct logical_op);
1987 }
1988 PO;
1989 }
1990
1991
77aa5901 1992 /* load field ref */
04aa13f8 1993 OP(BYTECODE_OP_LOAD_FIELD_REF_STRING):
97b58163
MD
1994 {
1995 struct load_op *insn = (struct load_op *) pc;
1996 struct field_ref *ref = (struct field_ref *) insn->data;
1997
1998 dbg_printf("load field ref offset %u type string\n",
1999 ref->offset);
53569322 2000 estack_push(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 2001 estack_ax(stack, top)->u.s.str =
f3503ba9 2002 *(const char * const *) &interpreter_stack_data[ref->offset];
9b33aac4 2003 if (unlikely(!estack_ax(stack, top)->u.s.str)) {
04aa13f8 2004 dbg_printf("Interpreter warning: loading a NULL string.\n");
97b58163
MD
2005 ret = -EINVAL;
2006 goto end;
2007 }
a63d0dc8 2008 estack_ax(stack, top)->u.s.seq_len = SIZE_MAX;
3151a51d
PP
2009 estack_ax(stack, top)->u.s.literal_type =
2010 ESTACK_STRING_LITERAL_TYPE_NONE;
53569322 2011 estack_ax_t = REG_STRING;
9b33aac4 2012 dbg_printf("ref load string %s\n", estack_ax(stack, top)->u.s.str);
97b58163
MD
2013 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
2014 PO;
2015 }
2016
04aa13f8 2017 OP(BYTECODE_OP_LOAD_FIELD_REF_SEQUENCE):
97b58163
MD
2018 {
2019 struct load_op *insn = (struct load_op *) pc;
2020 struct field_ref *ref = (struct field_ref *) insn->data;
2021
2022 dbg_printf("load field ref offset %u type sequence\n",
2023 ref->offset);
53569322 2024 estack_push(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 2025 estack_ax(stack, top)->u.s.seq_len =
f3503ba9 2026 *(unsigned long *) &interpreter_stack_data[ref->offset];
9b33aac4 2027 estack_ax(stack, top)->u.s.str =
f3503ba9 2028 *(const char **) (&interpreter_stack_data[ref->offset
97b58163 2029 + sizeof(unsigned long)]);
53569322 2030 estack_ax_t = REG_STRING;
9b33aac4 2031 if (unlikely(!estack_ax(stack, top)->u.s.str)) {
04aa13f8 2032 dbg_printf("Interpreter warning: loading a NULL sequence.\n");
97b58163
MD
2033 ret = -EINVAL;
2034 goto end;
2035 }
3151a51d
PP
2036 estack_ax(stack, top)->u.s.literal_type =
2037 ESTACK_STRING_LITERAL_TYPE_NONE;
97b58163
MD
2038 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
2039 PO;
2040 }
2041
04aa13f8 2042 OP(BYTECODE_OP_LOAD_FIELD_REF_S64):
97b58163
MD
2043 {
2044 struct load_op *insn = (struct load_op *) pc;
2045 struct field_ref *ref = (struct field_ref *) insn->data;
2046
2047 dbg_printf("load field ref offset %u type s64\n",
2048 ref->offset);
53569322 2049 estack_push(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 2050 estack_ax_v =
f3503ba9 2051 ((struct literal_numeric *) &interpreter_stack_data[ref->offset])->v;
53569322 2052 estack_ax_t = REG_S64;
9b33aac4 2053 dbg_printf("ref load s64 %" PRIi64 "\n", estack_ax_v);
97b58163
MD
2054 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
2055 PO;
2056 }
2057
04aa13f8 2058 OP(BYTECODE_OP_LOAD_FIELD_REF_DOUBLE):
97b58163
MD
2059 {
2060 struct load_op *insn = (struct load_op *) pc;
2061 struct field_ref *ref = (struct field_ref *) insn->data;
2062
2063 dbg_printf("load field ref offset %u type double\n",
2064 ref->offset);
53569322 2065 estack_push(stack, top, ax, bx, ax_t, bx_t);
f3503ba9 2066 memcpy(&estack_ax(stack, top)->u.d, &interpreter_stack_data[ref->offset],
97b58163 2067 sizeof(struct literal_double));
53569322 2068 estack_ax_t = REG_DOUBLE;
9b33aac4 2069 dbg_printf("ref load double %g\n", estack_ax(stack, top)->u.d);
97b58163
MD
2070 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
2071 PO;
2072 }
2073
77aa5901 2074 /* load from immediate operand */
04aa13f8 2075 OP(BYTECODE_OP_LOAD_STRING):
97b58163
MD
2076 {
2077 struct load_op *insn = (struct load_op *) pc;
2078
2079 dbg_printf("load string %s\n", insn->data);
53569322 2080 estack_push(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 2081 estack_ax(stack, top)->u.s.str = insn->data;
a63d0dc8 2082 estack_ax(stack, top)->u.s.seq_len = SIZE_MAX;
3151a51d
PP
2083 estack_ax(stack, top)->u.s.literal_type =
2084 ESTACK_STRING_LITERAL_TYPE_PLAIN;
53569322 2085 estack_ax_t = REG_STRING;
97b58163
MD
2086 next_pc += sizeof(struct load_op) + strlen(insn->data) + 1;
2087 PO;
2088 }
2089
04aa13f8 2090 OP(BYTECODE_OP_LOAD_STAR_GLOB_STRING):
3151a51d
PP
2091 {
2092 struct load_op *insn = (struct load_op *) pc;
2093
2094 dbg_printf("load globbing pattern %s\n", insn->data);
2095 estack_push(stack, top, ax, bx, ax_t, bx_t);
2096 estack_ax(stack, top)->u.s.str = insn->data;
a63d0dc8 2097 estack_ax(stack, top)->u.s.seq_len = SIZE_MAX;
3151a51d
PP
2098 estack_ax(stack, top)->u.s.literal_type =
2099 ESTACK_STRING_LITERAL_TYPE_STAR_GLOB;
2100 estack_ax_t = REG_STAR_GLOB_STRING;
2101 next_pc += sizeof(struct load_op) + strlen(insn->data) + 1;
2102 PO;
2103 }
2104
04aa13f8 2105 OP(BYTECODE_OP_LOAD_S64):
97b58163
MD
2106 {
2107 struct load_op *insn = (struct load_op *) pc;
2108
53569322 2109 estack_push(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 2110 estack_ax_v = ((struct literal_numeric *) insn->data)->v;
53569322 2111 estack_ax_t = REG_S64;
9b33aac4 2112 dbg_printf("load s64 %" PRIi64 "\n", estack_ax_v);
97b58163
MD
2113 next_pc += sizeof(struct load_op)
2114 + sizeof(struct literal_numeric);
2115 PO;
2116 }
2117
04aa13f8 2118 OP(BYTECODE_OP_LOAD_DOUBLE):
97b58163
MD
2119 {
2120 struct load_op *insn = (struct load_op *) pc;
2121
53569322 2122 estack_push(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 2123 memcpy(&estack_ax(stack, top)->u.d, insn->data,
97b58163 2124 sizeof(struct literal_double));
53569322
MD
2125 estack_ax_t = REG_DOUBLE;
2126 dbg_printf("load double %g\n", estack_ax(stack, top)->u.d);
97b58163
MD
2127 next_pc += sizeof(struct load_op)
2128 + sizeof(struct literal_double);
2129 PO;
2130 }
2131
2132 /* cast */
04aa13f8 2133 OP(BYTECODE_OP_CAST_TO_S64):
53569322
MD
2134 {
2135 /* Dynamic typing. */
2136 switch (estack_ax_t) {
2137 case REG_S64:
04aa13f8 2138 JUMP_TO(BYTECODE_OP_CAST_NOP);
53569322 2139 case REG_DOUBLE:
04aa13f8 2140 JUMP_TO(BYTECODE_OP_CAST_DOUBLE_TO_S64);
d97f9b78
MD
2141 case REG_U64:
2142 estack_ax_t = REG_S64;
2143 next_pc += sizeof(struct cast_op);
3151a51d
PP
2144 case REG_STRING: /* Fall-through */
2145 case REG_STAR_GLOB_STRING:
53569322
MD
2146 ret = -EINVAL;
2147 goto end;
2148 default:
04aa13f8 2149 ERR("Unknown interpreter register type (%d)",
53569322
MD
2150 (int) estack_ax_t);
2151 ret = -EINVAL;
2152 goto end;
2153 }
2154 }
97b58163 2155
04aa13f8 2156 OP(BYTECODE_OP_CAST_DOUBLE_TO_S64):
97b58163 2157 {
9b33aac4 2158 estack_ax_v = (int64_t) estack_ax(stack, top)->u.d;
53569322 2159 estack_ax_t = REG_S64;
97b58163
MD
2160 next_pc += sizeof(struct cast_op);
2161 PO;
2162 }
2163
04aa13f8 2164 OP(BYTECODE_OP_CAST_NOP):
97b58163
MD
2165 {
2166 next_pc += sizeof(struct cast_op);
2167 PO;
2168 }
2169
77aa5901 2170 /* get context ref */
04aa13f8 2171 OP(BYTECODE_OP_GET_CONTEXT_REF):
53569322
MD
2172 {
2173 struct load_op *insn = (struct load_op *) pc;
2174 struct field_ref *ref = (struct field_ref *) insn->data;
53569322
MD
2175 struct lttng_ctx_field *ctx_field;
2176 struct lttng_ctx_value v;
2177
2178 dbg_printf("get context ref offset %u type dynamic\n",
2179 ref->offset);
53569322
MD
2180 ctx_field = &ctx->fields[ref->offset];
2181 ctx_field->get_value(ctx_field, &v);
2182 estack_push(stack, top, ax, bx, ax_t, bx_t);
2183 switch (v.sel) {
2184 case LTTNG_UST_DYNAMIC_TYPE_NONE:
2185 ret = -EINVAL;
2186 goto end;
2187 case LTTNG_UST_DYNAMIC_TYPE_S64:
2188 estack_ax_v = v.u.s64;
2189 estack_ax_t = REG_S64;
2190 dbg_printf("ref get context dynamic s64 %" PRIi64 "\n", estack_ax_v);
2191 break;
2192 case LTTNG_UST_DYNAMIC_TYPE_DOUBLE:
2193 estack_ax(stack, top)->u.d = v.u.d;
2194 estack_ax_t = REG_DOUBLE;
2195 dbg_printf("ref get context dynamic double %g\n", estack_ax(stack, top)->u.d);
2196 break;
2197 case LTTNG_UST_DYNAMIC_TYPE_STRING:
2198 estack_ax(stack, top)->u.s.str = v.u.str;
2199 if (unlikely(!estack_ax(stack, top)->u.s.str)) {
04aa13f8 2200 dbg_printf("Interpreter warning: loading a NULL string.\n");
53569322
MD
2201 ret = -EINVAL;
2202 goto end;
2203 }
a63d0dc8 2204 estack_ax(stack, top)->u.s.seq_len = SIZE_MAX;
3151a51d
PP
2205 estack_ax(stack, top)->u.s.literal_type =
2206 ESTACK_STRING_LITERAL_TYPE_NONE;
53569322
MD
2207 dbg_printf("ref get context dynamic string %s\n", estack_ax(stack, top)->u.s.str);
2208 estack_ax_t = REG_STRING;
2209 break;
2210 default:
04aa13f8 2211 dbg_printf("Interpreter warning: unknown dynamic type (%d).\n", (int) v.sel);
53569322
MD
2212 ret = -EINVAL;
2213 goto end;
2214 }
2215 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
2216 PO;
2217 }
2218
04aa13f8 2219 OP(BYTECODE_OP_GET_CONTEXT_REF_STRING):
77aa5901
MD
2220 {
2221 struct load_op *insn = (struct load_op *) pc;
2222 struct field_ref *ref = (struct field_ref *) insn->data;
2223 struct lttng_ctx_field *ctx_field;
53569322 2224 struct lttng_ctx_value v;
77aa5901
MD
2225
2226 dbg_printf("get context ref offset %u type string\n",
2227 ref->offset);
53569322 2228 ctx_field = &ctx->fields[ref->offset];
77aa5901 2229 ctx_field->get_value(ctx_field, &v);
53569322
MD
2230 estack_push(stack, top, ax, bx, ax_t, bx_t);
2231 estack_ax(stack, top)->u.s.str = v.u.str;
77aa5901 2232 if (unlikely(!estack_ax(stack, top)->u.s.str)) {
04aa13f8 2233 dbg_printf("Interpreter warning: loading a NULL string.\n");
77aa5901
MD
2234 ret = -EINVAL;
2235 goto end;
2236 }
a63d0dc8 2237 estack_ax(stack, top)->u.s.seq_len = SIZE_MAX;
3151a51d
PP
2238 estack_ax(stack, top)->u.s.literal_type =
2239 ESTACK_STRING_LITERAL_TYPE_NONE;
53569322 2240 estack_ax_t = REG_STRING;
77aa5901
MD
2241 dbg_printf("ref get context string %s\n", estack_ax(stack, top)->u.s.str);
2242 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
2243 PO;
2244 }
2245
04aa13f8 2246 OP(BYTECODE_OP_GET_CONTEXT_REF_S64):
77aa5901
MD
2247 {
2248 struct load_op *insn = (struct load_op *) pc;
2249 struct field_ref *ref = (struct field_ref *) insn->data;
2250 struct lttng_ctx_field *ctx_field;
53569322 2251 struct lttng_ctx_value v;
77aa5901
MD
2252
2253 dbg_printf("get context ref offset %u type s64\n",
2254 ref->offset);
53569322 2255 ctx_field = &ctx->fields[ref->offset];
77aa5901 2256 ctx_field->get_value(ctx_field, &v);
53569322
MD
2257 estack_push(stack, top, ax, bx, ax_t, bx_t);
2258 estack_ax_v = v.u.s64;
2259 estack_ax_t = REG_S64;
77aa5901
MD
2260 dbg_printf("ref get context s64 %" PRIi64 "\n", estack_ax_v);
2261 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
2262 PO;
2263 }
2264
04aa13f8 2265 OP(BYTECODE_OP_GET_CONTEXT_REF_DOUBLE):
77aa5901
MD
2266 {
2267 struct load_op *insn = (struct load_op *) pc;
2268 struct field_ref *ref = (struct field_ref *) insn->data;
2269 struct lttng_ctx_field *ctx_field;
53569322 2270 struct lttng_ctx_value v;
77aa5901
MD
2271
2272 dbg_printf("get context ref offset %u type double\n",
2273 ref->offset);
53569322 2274 ctx_field = &ctx->fields[ref->offset];
77aa5901 2275 ctx_field->get_value(ctx_field, &v);
53569322
MD
2276 estack_push(stack, top, ax, bx, ax_t, bx_t);
2277 memcpy(&estack_ax(stack, top)->u.d, &v.u.d, sizeof(struct literal_double));
2278 estack_ax_t = REG_DOUBLE;
77aa5901
MD
2279 dbg_printf("ref get context double %g\n", estack_ax(stack, top)->u.d);
2280 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
2281 PO;
2282 }
2283
04aa13f8 2284 OP(BYTECODE_OP_GET_CONTEXT_ROOT):
47e5f13e
MD
2285 {
2286 dbg_printf("op get context root\n");
2287 estack_push(stack, top, ax, bx, ax_t, bx_t);
2288 estack_ax(stack, top)->u.ptr.type = LOAD_ROOT_CONTEXT;
2289 /* "field" only needed for variants. */
2290 estack_ax(stack, top)->u.ptr.field = NULL;
2291 estack_ax_t = REG_PTR;
2292 next_pc += sizeof(struct load_op);
2293 PO;
2294 }
2295
04aa13f8 2296 OP(BYTECODE_OP_GET_APP_CONTEXT_ROOT):
47e5f13e
MD
2297 {
2298 dbg_printf("op get app context root\n");
2299 estack_push(stack, top, ax, bx, ax_t, bx_t);
2300 estack_ax(stack, top)->u.ptr.type = LOAD_ROOT_APP_CONTEXT;
2301 /* "field" only needed for variants. */
2302 estack_ax(stack, top)->u.ptr.field = NULL;
2303 estack_ax_t = REG_PTR;
2304 next_pc += sizeof(struct load_op);
2305 PO;
2306 }
2307
04aa13f8 2308 OP(BYTECODE_OP_GET_PAYLOAD_ROOT):
47e5f13e
MD
2309 {
2310 dbg_printf("op get app payload root\n");
2311 estack_push(stack, top, ax, bx, ax_t, bx_t);
2312 estack_ax(stack, top)->u.ptr.type = LOAD_ROOT_PAYLOAD;
f3503ba9 2313 estack_ax(stack, top)->u.ptr.ptr = interpreter_stack_data;
47e5f13e
MD
2314 /* "field" only needed for variants. */
2315 estack_ax(stack, top)->u.ptr.field = NULL;
2316 estack_ax_t = REG_PTR;
2317 next_pc += sizeof(struct load_op);
2318 PO;
2319 }
2320
04aa13f8 2321 OP(BYTECODE_OP_GET_SYMBOL):
47e5f13e
MD
2322 {
2323 dbg_printf("op get symbol\n");
2324 switch (estack_ax(stack, top)->u.ptr.type) {
2325 case LOAD_OBJECT:
2326 ERR("Nested fields not implemented yet.");
2327 ret = -EINVAL;
2328 goto end;
2329 case LOAD_ROOT_CONTEXT:
2330 case LOAD_ROOT_APP_CONTEXT:
2331 case LOAD_ROOT_PAYLOAD:
2332 /*
2333 * symbol lookup is performed by
2334 * specialization.
2335 */
2336 ret = -EINVAL;
2337 goto end;
2338 }
2339 next_pc += sizeof(struct load_op) + sizeof(struct get_symbol);
2340 PO;
2341 }
2342
04aa13f8 2343 OP(BYTECODE_OP_GET_SYMBOL_FIELD):
47e5f13e
MD
2344 {
2345 /*
2346 * Used for first variant encountered in a
2347 * traversal. Variants are not implemented yet.
2348 */
2349 ret = -EINVAL;
2350 goto end;
2351 }
2352
04aa13f8 2353 OP(BYTECODE_OP_GET_INDEX_U16):
47e5f13e
MD
2354 {
2355 struct load_op *insn = (struct load_op *) pc;
2356 struct get_index_u16 *index = (struct get_index_u16 *) insn->data;
2357
2358 dbg_printf("op get index u16\n");
b77aaa1b 2359 ret = dynamic_get_index(ctx, bytecode, index->index, estack_ax(stack, top));
47e5f13e
MD
2360 if (ret)
2361 goto end;
2362 estack_ax_v = estack_ax(stack, top)->u.v;
2363 estack_ax_t = estack_ax(stack, top)->type;
2364 next_pc += sizeof(struct load_op) + sizeof(struct get_index_u16);
2365 PO;
2366 }
2367
04aa13f8 2368 OP(BYTECODE_OP_GET_INDEX_U64):
47e5f13e
MD
2369 {
2370 struct load_op *insn = (struct load_op *) pc;
2371 struct get_index_u64 *index = (struct get_index_u64 *) insn->data;
2372
2373 dbg_printf("op get index u64\n");
b77aaa1b 2374 ret = dynamic_get_index(ctx, bytecode, index->index, estack_ax(stack, top));
47e5f13e
MD
2375 if (ret)
2376 goto end;
2377 estack_ax_v = estack_ax(stack, top)->u.v;
2378 estack_ax_t = estack_ax(stack, top)->type;
2379 next_pc += sizeof(struct load_op) + sizeof(struct get_index_u64);
2380 PO;
2381 }
2382
04aa13f8 2383 OP(BYTECODE_OP_LOAD_FIELD):
47e5f13e
MD
2384 {
2385 dbg_printf("op load field\n");
2386 ret = dynamic_load_field(estack_ax(stack, top));
2387 if (ret)
2388 goto end;
2389 estack_ax_v = estack_ax(stack, top)->u.v;
2390 estack_ax_t = estack_ax(stack, top)->type;
2391 next_pc += sizeof(struct load_op);
2392 PO;
2393 }
2394
04aa13f8 2395 OP(BYTECODE_OP_LOAD_FIELD_S8):
47e5f13e
MD
2396 {
2397 dbg_printf("op load field s8\n");
2398
2399 estack_ax_v = *(int8_t *) estack_ax(stack, top)->u.ptr.ptr;
2400 estack_ax_t = REG_S64;
2401 next_pc += sizeof(struct load_op);
2402 PO;
2403 }
04aa13f8 2404 OP(BYTECODE_OP_LOAD_FIELD_S16):
47e5f13e
MD
2405 {
2406 dbg_printf("op load field s16\n");
2407
2408 estack_ax_v = *(int16_t *) estack_ax(stack, top)->u.ptr.ptr;
2409 estack_ax_t = REG_S64;
2410 next_pc += sizeof(struct load_op);
2411 PO;
2412 }
04aa13f8 2413 OP(BYTECODE_OP_LOAD_FIELD_S32):
47e5f13e
MD
2414 {
2415 dbg_printf("op load field s32\n");
2416
2417 estack_ax_v = *(int32_t *) estack_ax(stack, top)->u.ptr.ptr;
2418 estack_ax_t = REG_S64;
2419 next_pc += sizeof(struct load_op);
2420 PO;
2421 }
04aa13f8 2422 OP(BYTECODE_OP_LOAD_FIELD_S64):
47e5f13e
MD
2423 {
2424 dbg_printf("op load field s64\n");
2425
2426 estack_ax_v = *(int64_t *) estack_ax(stack, top)->u.ptr.ptr;
2427 estack_ax_t = REG_S64;
2428 next_pc += sizeof(struct load_op);
2429 PO;
2430 }
04aa13f8 2431 OP(BYTECODE_OP_LOAD_FIELD_U8):
47e5f13e
MD
2432 {
2433 dbg_printf("op load field u8\n");
2434
2435 estack_ax_v = *(uint8_t *) estack_ax(stack, top)->u.ptr.ptr;
d97f9b78 2436 estack_ax_t = REG_U64;
47e5f13e
MD
2437 next_pc += sizeof(struct load_op);
2438 PO;
2439 }
04aa13f8 2440 OP(BYTECODE_OP_LOAD_FIELD_U16):
47e5f13e
MD
2441 {
2442 dbg_printf("op load field u16\n");
2443
2444 estack_ax_v = *(uint16_t *) estack_ax(stack, top)->u.ptr.ptr;
d97f9b78 2445 estack_ax_t = REG_U64;
47e5f13e
MD
2446 next_pc += sizeof(struct load_op);
2447 PO;
2448 }
04aa13f8 2449 OP(BYTECODE_OP_LOAD_FIELD_U32):
47e5f13e
MD
2450 {
2451 dbg_printf("op load field u32\n");
2452
2453 estack_ax_v = *(uint32_t *) estack_ax(stack, top)->u.ptr.ptr;
d97f9b78 2454 estack_ax_t = REG_U64;
47e5f13e
MD
2455 next_pc += sizeof(struct load_op);
2456 PO;
2457 }
04aa13f8 2458 OP(BYTECODE_OP_LOAD_FIELD_U64):
47e5f13e
MD
2459 {
2460 dbg_printf("op load field u64\n");
2461
2462 estack_ax_v = *(uint64_t *) estack_ax(stack, top)->u.ptr.ptr;
d97f9b78 2463 estack_ax_t = REG_U64;
47e5f13e
MD
2464 next_pc += sizeof(struct load_op);
2465 PO;
2466 }
04aa13f8 2467 OP(BYTECODE_OP_LOAD_FIELD_DOUBLE):
47e5f13e
MD
2468 {
2469 dbg_printf("op load field double\n");
2470
2471 memcpy(&estack_ax(stack, top)->u.d,
2472 estack_ax(stack, top)->u.ptr.ptr,
2473 sizeof(struct literal_double));
2474 estack_ax(stack, top)->type = REG_DOUBLE;
2475 next_pc += sizeof(struct load_op);
2476 PO;
2477 }
2478
04aa13f8 2479 OP(BYTECODE_OP_LOAD_FIELD_STRING):
47e5f13e
MD
2480 {
2481 const char *str;
2482
2483 dbg_printf("op load field string\n");
2484 str = (const char *) estack_ax(stack, top)->u.ptr.ptr;
2485 estack_ax(stack, top)->u.s.str = str;
2486 if (unlikely(!estack_ax(stack, top)->u.s.str)) {
04aa13f8 2487 dbg_printf("Interpreter warning: loading a NULL string.\n");
47e5f13e
MD
2488 ret = -EINVAL;
2489 goto end;
2490 }
2491 estack_ax(stack, top)->u.s.seq_len = SIZE_MAX;
2492 estack_ax(stack, top)->u.s.literal_type =
2493 ESTACK_STRING_LITERAL_TYPE_NONE;
2494 estack_ax(stack, top)->type = REG_STRING;
2495 next_pc += sizeof(struct load_op);
2496 PO;
2497 }
2498
04aa13f8 2499 OP(BYTECODE_OP_LOAD_FIELD_SEQUENCE):
47e5f13e
MD
2500 {
2501 const char *ptr;
2502
2503 dbg_printf("op load field string sequence\n");
2504 ptr = estack_ax(stack, top)->u.ptr.ptr;
2505 estack_ax(stack, top)->u.s.seq_len = *(unsigned long *) ptr;
2506 estack_ax(stack, top)->u.s.str = *(const char **) (ptr + sizeof(unsigned long));
2507 estack_ax(stack, top)->type = REG_STRING;
2508 if (unlikely(!estack_ax(stack, top)->u.s.str)) {
04aa13f8 2509 dbg_printf("Interpreter warning: loading a NULL sequence.\n");
47e5f13e
MD
2510 ret = -EINVAL;
2511 goto end;
2512 }
2513 estack_ax(stack, top)->u.s.literal_type =
2514 ESTACK_STRING_LITERAL_TYPE_NONE;
2515 next_pc += sizeof(struct load_op);
2516 PO;
2517 }
2518
97b58163
MD
2519 END_OP
2520end:
4526ba69 2521 /* Return _DISCARD on error. */
97b58163 2522 if (ret)
04aa13f8 2523 return LTTNG_INTERPRETER_DISCARD;
f3503ba9
FD
2524
2525 if (output) {
2526 return lttng_bytecode_interpret_format_output(estack_ax(stack, top),
2527 output);
2528 }
2529
97b58163
MD
2530 return retval;
2531}
2532
04aa13f8 2533uint64_t lttng_bytecode_filter_interpret(void *filter_data,
f3503ba9
FD
2534 const char *filter_stack_data)
2535{
2536 return bytecode_interpret(filter_data, filter_stack_data, NULL);
2537}
2538
d37ecb3f
FD
2539uint64_t lttng_bytecode_capture_interpret(void *capture_data,
2540 const char *capture_stack_data,
2541 struct lttng_interpreter_output *output)
2542{
2543 return bytecode_interpret(capture_data, capture_stack_data,
2544 (struct lttng_interpreter_output *) output);
2545}
2546
97b58163
MD
2547#undef START_OP
2548#undef OP
2549#undef PO
2550#undef END_OP
This page took 0.156272 seconds and 4 git commands to generate.