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