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