Refactoring: namespace ust-abi.h content under regular prefix
[lttng-ust.git] / liblttng-ust / lttng-bytecode-specialize.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 specializer.
97b58163
MD
7 */
8
3fbec7dc 9#define _LGPL_SOURCE
b4051ad8 10#include <stddef.h>
fb31eb73 11#include <stdint.h>
b4051ad8 12
47e5f13e 13#include <lttng/align.h>
fc80554e
MJ
14
15#include "context-internal.h"
16#include "lttng-bytecode.h"
92495593 17#include "ust-events-internal.h"
97b58163 18
47e5f13e
MD
19static int lttng_fls(int val)
20{
21 int r = 32;
22 unsigned int x = (unsigned int) val;
23
24 if (!x)
25 return 0;
26 if (!(x & 0xFFFF0000U)) {
27 x <<= 16;
28 r -= 16;
29 }
30 if (!(x & 0xFF000000U)) {
31 x <<= 8;
32 r -= 8;
33 }
34 if (!(x & 0xF0000000U)) {
35 x <<= 4;
36 r -= 4;
37 }
38 if (!(x & 0xC0000000U)) {
39 x <<= 2;
40 r -= 2;
41 }
42 if (!(x & 0x80000000U)) {
43 r -= 1;
44 }
45 return r;
46}
47
48static int get_count_order(unsigned int count)
49{
50 int order;
51
52 order = lttng_fls(count) - 1;
53 if (count & (count - 1))
54 order++;
55 return order;
56}
57
58static ssize_t bytecode_reserve_data(struct bytecode_runtime *runtime,
59 size_t align, size_t len)
60{
61 ssize_t ret;
b72687b8 62 size_t padding = lttng_ust_offset_align(runtime->data_len, align);
47e5f13e
MD
63 size_t new_len = runtime->data_len + padding + len;
64 size_t new_alloc_len = new_len;
65 size_t old_alloc_len = runtime->data_alloc_len;
66
04aa13f8 67 if (new_len > BYTECODE_MAX_DATA_LEN)
47e5f13e
MD
68 return -EINVAL;
69
70 if (new_alloc_len > old_alloc_len) {
71 char *newptr;
72
73 new_alloc_len =
74 max_t(size_t, 1U << get_count_order(new_alloc_len), old_alloc_len << 1);
75 newptr = realloc(runtime->data, new_alloc_len);
76 if (!newptr)
77 return -ENOMEM;
78 runtime->data = newptr;
79 /* We zero directly the memory from start of allocation. */
80 memset(&runtime->data[old_alloc_len], 0, new_alloc_len - old_alloc_len);
81 runtime->data_alloc_len = new_alloc_len;
82 }
83 runtime->data_len += padding;
84 ret = runtime->data_len;
85 runtime->data_len += len;
86 return ret;
87}
88
89static ssize_t bytecode_push_data(struct bytecode_runtime *runtime,
90 const void *p, size_t align, size_t len)
91{
92 ssize_t offset;
93
94 offset = bytecode_reserve_data(runtime, align, len);
95 if (offset < 0)
96 return -ENOMEM;
97 memcpy(&runtime->data[offset], p, len);
98 return offset;
99}
100
101static int specialize_load_field(struct vstack_entry *stack_top,
102 struct load_op *insn)
103{
104 int ret;
105
106 switch (stack_top->load.type) {
107 case LOAD_OBJECT:
108 break;
109 case LOAD_ROOT_CONTEXT:
110 case LOAD_ROOT_APP_CONTEXT:
111 case LOAD_ROOT_PAYLOAD:
112 default:
04aa13f8 113 dbg_printf("Bytecode warning: cannot load root, missing field name.\n");
47e5f13e
MD
114 ret = -EINVAL;
115 goto end;
116 }
117 switch (stack_top->load.object_type) {
118 case OBJECT_TYPE_S8:
119 dbg_printf("op load field s8\n");
120 stack_top->type = REG_S64;
121 if (!stack_top->load.rev_bo)
04aa13f8 122 insn->op = BYTECODE_OP_LOAD_FIELD_S8;
47e5f13e
MD
123 break;
124 case OBJECT_TYPE_S16:
125 dbg_printf("op load field s16\n");
126 stack_top->type = REG_S64;
127 if (!stack_top->load.rev_bo)
04aa13f8 128 insn->op = BYTECODE_OP_LOAD_FIELD_S16;
47e5f13e
MD
129 break;
130 case OBJECT_TYPE_S32:
131 dbg_printf("op load field s32\n");
132 stack_top->type = REG_S64;
133 if (!stack_top->load.rev_bo)
04aa13f8 134 insn->op = BYTECODE_OP_LOAD_FIELD_S32;
47e5f13e
MD
135 break;
136 case OBJECT_TYPE_S64:
137 dbg_printf("op load field s64\n");
138 stack_top->type = REG_S64;
139 if (!stack_top->load.rev_bo)
04aa13f8 140 insn->op = BYTECODE_OP_LOAD_FIELD_S64;
47e5f13e 141 break;
70f9f7f9
FD
142 case OBJECT_TYPE_SIGNED_ENUM:
143 dbg_printf("op load field signed enumeration\n");
144 stack_top->type = REG_PTR;
145 break;
47e5f13e
MD
146 case OBJECT_TYPE_U8:
147 dbg_printf("op load field u8\n");
d97f9b78 148 stack_top->type = REG_U64;
04aa13f8 149 insn->op = BYTECODE_OP_LOAD_FIELD_U8;
47e5f13e
MD
150 break;
151 case OBJECT_TYPE_U16:
152 dbg_printf("op load field u16\n");
d97f9b78 153 stack_top->type = REG_U64;
47e5f13e 154 if (!stack_top->load.rev_bo)
04aa13f8 155 insn->op = BYTECODE_OP_LOAD_FIELD_U16;
47e5f13e
MD
156 break;
157 case OBJECT_TYPE_U32:
158 dbg_printf("op load field u32\n");
d97f9b78 159 stack_top->type = REG_U64;
47e5f13e 160 if (!stack_top->load.rev_bo)
04aa13f8 161 insn->op = BYTECODE_OP_LOAD_FIELD_U32;
47e5f13e
MD
162 break;
163 case OBJECT_TYPE_U64:
164 dbg_printf("op load field u64\n");
d97f9b78 165 stack_top->type = REG_U64;
47e5f13e 166 if (!stack_top->load.rev_bo)
04aa13f8 167 insn->op = BYTECODE_OP_LOAD_FIELD_U64;
47e5f13e 168 break;
70f9f7f9
FD
169 case OBJECT_TYPE_UNSIGNED_ENUM:
170 dbg_printf("op load field unsigned enumeration\n");
171 stack_top->type = REG_PTR;
172 break;
47e5f13e
MD
173 case OBJECT_TYPE_DOUBLE:
174 stack_top->type = REG_DOUBLE;
04aa13f8 175 insn->op = BYTECODE_OP_LOAD_FIELD_DOUBLE;
47e5f13e
MD
176 break;
177 case OBJECT_TYPE_STRING:
178 dbg_printf("op load field string\n");
179 stack_top->type = REG_STRING;
04aa13f8 180 insn->op = BYTECODE_OP_LOAD_FIELD_STRING;
47e5f13e
MD
181 break;
182 case OBJECT_TYPE_STRING_SEQUENCE:
183 dbg_printf("op load field string sequence\n");
184 stack_top->type = REG_STRING;
04aa13f8 185 insn->op = BYTECODE_OP_LOAD_FIELD_SEQUENCE;
47e5f13e
MD
186 break;
187 case OBJECT_TYPE_DYNAMIC:
188 dbg_printf("op load field dynamic\n");
189 stack_top->type = REG_UNKNOWN;
190 /* Don't specialize load op. */
191 break;
192 case OBJECT_TYPE_SEQUENCE:
193 case OBJECT_TYPE_ARRAY:
194 case OBJECT_TYPE_STRUCT:
195 case OBJECT_TYPE_VARIANT:
196 ERR("Sequences, arrays, struct and variant cannot be loaded (nested types).");
197 ret = -EINVAL;
198 goto end;
199 }
200 return 0;
201
202end:
203 return ret;
204}
205
206static int specialize_get_index_object_type(enum object_type *otype,
207 int signedness, uint32_t elem_len)
208{
209 switch (elem_len) {
210 case 8:
211 if (signedness)
212 *otype = OBJECT_TYPE_S8;
213 else
214 *otype = OBJECT_TYPE_U8;
215 break;
216 case 16:
217 if (signedness)
218 *otype = OBJECT_TYPE_S16;
219 else
220 *otype = OBJECT_TYPE_U16;
221 break;
222 case 32:
223 if (signedness)
224 *otype = OBJECT_TYPE_S32;
225 else
226 *otype = OBJECT_TYPE_U32;
227 break;
228 case 64:
229 if (signedness)
230 *otype = OBJECT_TYPE_S64;
231 else
232 *otype = OBJECT_TYPE_U64;
233 break;
234 default:
235 return -EINVAL;
236 }
237 return 0;
238}
239
240static int specialize_get_index(struct bytecode_runtime *runtime,
241 struct load_op *insn, uint64_t index,
242 struct vstack_entry *stack_top,
243 int idx_len)
244{
245 int ret;
04aa13f8 246 struct bytecode_get_index_data gid;
47e5f13e
MD
247 ssize_t data_offset;
248
249 memset(&gid, 0, sizeof(gid));
250 switch (stack_top->load.type) {
251 case LOAD_OBJECT:
252 switch (stack_top->load.object_type) {
253 case OBJECT_TYPE_ARRAY:
254 {
218deb69 255 const struct lttng_integer_type *integer_type;
47e5f13e
MD
256 const struct lttng_event_field *field;
257 uint32_t elem_len, num_elems;
258 int signedness;
259
260 field = stack_top->load.field;
218deb69 261 switch (field->type.atype) {
218deb69
MD
262 case atype_array_nestable:
263 if (field->type.u.array_nestable.elem_type->atype != atype_integer) {
264 ret = -EINVAL;
265 goto end;
266 }
267 integer_type = &field->type.u.array_nestable.elem_type->u.integer;
268 num_elems = field->type.u.array_nestable.length;
269 break;
270 default:
271 ret = -EINVAL;
272 goto end;
273 }
274 elem_len = integer_type->size;
275 signedness = integer_type->signedness;
47e5f13e
MD
276 if (index >= num_elems) {
277 ret = -EINVAL;
278 goto end;
279 }
280 ret = specialize_get_index_object_type(&stack_top->load.object_type,
281 signedness, elem_len);
282 if (ret)
283 goto end;
284 gid.offset = index * (elem_len / CHAR_BIT);
285 gid.array_len = num_elems * (elem_len / CHAR_BIT);
286 gid.elem.type = stack_top->load.object_type;
287 gid.elem.len = elem_len;
218deb69 288 if (integer_type->reverse_byte_order)
47e5f13e
MD
289 gid.elem.rev_bo = true;
290 stack_top->load.rev_bo = gid.elem.rev_bo;
291 break;
292 }
293 case OBJECT_TYPE_SEQUENCE:
294 {
218deb69 295 const struct lttng_integer_type *integer_type;
47e5f13e
MD
296 const struct lttng_event_field *field;
297 uint32_t elem_len;
298 int signedness;
299
300 field = stack_top->load.field;
218deb69 301 switch (field->type.atype) {
218deb69
MD
302 case atype_sequence_nestable:
303 if (field->type.u.sequence_nestable.elem_type->atype != atype_integer) {
304 ret = -EINVAL;
305 goto end;
306 }
307 integer_type = &field->type.u.sequence_nestable.elem_type->u.integer;
308 break;
309 default:
310 ret = -EINVAL;
311 goto end;
312 }
313 elem_len = integer_type->size;
314 signedness = integer_type->signedness;
47e5f13e
MD
315 ret = specialize_get_index_object_type(&stack_top->load.object_type,
316 signedness, elem_len);
317 if (ret)
318 goto end;
319 gid.offset = index * (elem_len / CHAR_BIT);
320 gid.elem.type = stack_top->load.object_type;
321 gid.elem.len = elem_len;
218deb69 322 if (integer_type->reverse_byte_order)
47e5f13e
MD
323 gid.elem.rev_bo = true;
324 stack_top->load.rev_bo = gid.elem.rev_bo;
325 break;
326 }
327 case OBJECT_TYPE_STRUCT:
328 /* Only generated by the specialize phase. */
329 case OBJECT_TYPE_VARIANT: /* Fall-through */
330 default:
331 ERR("Unexpected get index type %d",
332 (int) stack_top->load.object_type);
333 ret = -EINVAL;
334 goto end;
335 }
336 break;
337 case LOAD_ROOT_CONTEXT:
338 case LOAD_ROOT_APP_CONTEXT:
339 case LOAD_ROOT_PAYLOAD:
340 ERR("Index lookup for root field not implemented yet.");
341 ret = -EINVAL;
342 goto end;
343 }
344 data_offset = bytecode_push_data(runtime, &gid,
345 __alignof__(gid), sizeof(gid));
346 if (data_offset < 0) {
347 ret = -EINVAL;
348 goto end;
349 }
350 switch (idx_len) {
351 case 2:
352 ((struct get_index_u16 *) insn->data)->index = data_offset;
353 break;
354 case 8:
355 ((struct get_index_u64 *) insn->data)->index = data_offset;
356 break;
357 default:
358 ret = -EINVAL;
359 goto end;
360 }
361
362 return 0;
363
364end:
365 return ret;
366}
367
368static int specialize_context_lookup_name(struct lttng_ctx *ctx,
369 struct bytecode_runtime *bytecode,
370 struct load_op *insn)
371{
372 uint16_t offset;
373 const char *name;
374
375 offset = ((struct get_symbol *) insn->data)->offset;
362a65de 376 name = bytecode->p.priv->bc->bc.data + bytecode->p.priv->bc->bc.reloc_offset + offset;
47e5f13e
MD
377 return lttng_get_context_index(ctx, name);
378}
379
380static int specialize_load_object(const struct lttng_event_field *field,
381 struct vstack_load *load, bool is_context)
382{
383 load->type = LOAD_OBJECT;
d97f9b78 384
47e5f13e
MD
385 switch (field->type.atype) {
386 case atype_integer:
218deb69 387 if (field->type.u.integer.signedness)
47e5f13e
MD
388 load->object_type = OBJECT_TYPE_S64;
389 else
390 load->object_type = OBJECT_TYPE_U64;
391 load->rev_bo = false;
392 break;
218deb69 393 case atype_enum_nestable:
47e5f13e 394 {
218deb69 395 const struct lttng_integer_type *itype;
47e5f13e 396
8c3470ea 397 itype = &field->type.u.enum_nestable.container_type->u.integer;
47e5f13e 398 if (itype->signedness)
70f9f7f9 399 load->object_type = OBJECT_TYPE_SIGNED_ENUM;
47e5f13e 400 else
70f9f7f9 401 load->object_type = OBJECT_TYPE_UNSIGNED_ENUM;
47e5f13e
MD
402 load->rev_bo = false;
403 break;
404 }
218deb69
MD
405 case atype_array_nestable:
406 if (field->type.u.array_nestable.elem_type->atype != atype_integer) {
47e5f13e
MD
407 ERR("Array nesting only supports integer types.");
408 return -EINVAL;
409 }
410 if (is_context) {
411 load->object_type = OBJECT_TYPE_STRING;
412 } else {
218deb69 413 if (field->type.u.array_nestable.elem_type->u.integer.encoding == lttng_encode_none) {
47e5f13e
MD
414 load->object_type = OBJECT_TYPE_ARRAY;
415 load->field = field;
416 } else {
417 load->object_type = OBJECT_TYPE_STRING_SEQUENCE;
418 }
419 }
420 break;
218deb69
MD
421 case atype_sequence_nestable:
422 if (field->type.u.sequence_nestable.elem_type->atype != atype_integer) {
47e5f13e
MD
423 ERR("Sequence nesting only supports integer types.");
424 return -EINVAL;
425 }
426 if (is_context) {
427 load->object_type = OBJECT_TYPE_STRING;
428 } else {
218deb69 429 if (field->type.u.sequence_nestable.elem_type->u.integer.encoding == lttng_encode_none) {
47e5f13e
MD
430 load->object_type = OBJECT_TYPE_SEQUENCE;
431 load->field = field;
432 } else {
433 load->object_type = OBJECT_TYPE_STRING_SEQUENCE;
434 }
435 }
436 break;
218deb69 437
47e5f13e
MD
438 case atype_string:
439 load->object_type = OBJECT_TYPE_STRING;
440 break;
441 case atype_float:
442 load->object_type = OBJECT_TYPE_DOUBLE;
443 break;
444 case atype_dynamic:
445 load->object_type = OBJECT_TYPE_DYNAMIC;
8d3190bd 446 break;
47e5f13e
MD
447 default:
448 ERR("Unknown type: %d", (int) field->type.atype);
449 return -EINVAL;
450 }
451 return 0;
452}
453
b77aaa1b 454static int specialize_context_lookup(struct lttng_ctx *ctx,
47e5f13e
MD
455 struct bytecode_runtime *runtime,
456 struct load_op *insn,
457 struct vstack_load *load)
458{
459 int idx, ret;
460 struct lttng_ctx_field *ctx_field;
461 struct lttng_event_field *field;
04aa13f8 462 struct bytecode_get_index_data gid;
47e5f13e
MD
463 ssize_t data_offset;
464
b77aaa1b 465 idx = specialize_context_lookup_name(ctx, runtime, insn);
47e5f13e
MD
466 if (idx < 0) {
467 return -ENOENT;
468 }
b77aaa1b 469 ctx_field = &ctx->fields[idx];
47e5f13e
MD
470 field = &ctx_field->event_field;
471 ret = specialize_load_object(field, load, true);
472 if (ret)
473 return ret;
474 /* Specialize each get_symbol into a get_index. */
04aa13f8 475 insn->op = BYTECODE_OP_GET_INDEX_U16;
47e5f13e
MD
476 memset(&gid, 0, sizeof(gid));
477 gid.ctx_index = idx;
478 gid.elem.type = load->object_type;
6bbd9df3 479 gid.elem.rev_bo = load->rev_bo;
f3503ba9 480 gid.field = field;
47e5f13e
MD
481 data_offset = bytecode_push_data(runtime, &gid,
482 __alignof__(gid), sizeof(gid));
483 if (data_offset < 0) {
484 return -EINVAL;
485 }
486 ((struct get_index_u16 *) insn->data)->index = data_offset;
487 return 0;
488}
489
b77aaa1b 490static int specialize_app_context_lookup(struct lttng_ctx **pctx,
47e5f13e
MD
491 struct bytecode_runtime *runtime,
492 struct load_op *insn,
493 struct vstack_load *load)
494{
495 uint16_t offset;
496 const char *orig_name;
497 char *name = NULL;
498 int idx, ret;
499 struct lttng_ctx_field *ctx_field;
500 struct lttng_event_field *field;
04aa13f8 501 struct bytecode_get_index_data gid;
47e5f13e
MD
502 ssize_t data_offset;
503
504 offset = ((struct get_symbol *) insn->data)->offset;
362a65de 505 orig_name = runtime->p.priv->bc->bc.data + runtime->p.priv->bc->bc.reloc_offset + offset;
47e5f13e
MD
506 name = zmalloc(strlen(orig_name) + strlen("$app.") + 1);
507 if (!name) {
508 ret = -ENOMEM;
509 goto end;
510 }
511 strcpy(name, "$app.");
512 strcat(name, orig_name);
b77aaa1b 513 idx = lttng_get_context_index(*pctx, name);
47e5f13e
MD
514 if (idx < 0) {
515 assert(lttng_context_is_app(name));
516 ret = lttng_ust_add_app_context_to_ctx_rcu(name,
b77aaa1b 517 pctx);
47e5f13e
MD
518 if (ret)
519 return ret;
b77aaa1b 520 idx = lttng_get_context_index(*pctx, name);
47e5f13e
MD
521 if (idx < 0)
522 return -ENOENT;
523 }
b77aaa1b 524 ctx_field = &(*pctx)->fields[idx];
47e5f13e
MD
525 field = &ctx_field->event_field;
526 ret = specialize_load_object(field, load, true);
527 if (ret)
528 goto end;
529 /* Specialize each get_symbol into a get_index. */
04aa13f8 530 insn->op = BYTECODE_OP_GET_INDEX_U16;
47e5f13e
MD
531 memset(&gid, 0, sizeof(gid));
532 gid.ctx_index = idx;
533 gid.elem.type = load->object_type;
6bbd9df3 534 gid.elem.rev_bo = load->rev_bo;
f3503ba9 535 gid.field = field;
47e5f13e
MD
536 data_offset = bytecode_push_data(runtime, &gid,
537 __alignof__(gid), sizeof(gid));
538 if (data_offset < 0) {
539 ret = -EINVAL;
540 goto end;
541 }
542 ((struct get_index_u16 *) insn->data)->index = data_offset;
543 ret = 0;
544end:
545 free(name);
546 return ret;
547}
548
53b9d7db 549static int specialize_payload_lookup(const struct lttng_event_desc *event_desc,
47e5f13e
MD
550 struct bytecode_runtime *runtime,
551 struct load_op *insn,
552 struct vstack_load *load)
553{
554 const char *name;
555 uint16_t offset;
47e5f13e
MD
556 unsigned int i, nr_fields;
557 bool found = false;
558 uint32_t field_offset = 0;
559 const struct lttng_event_field *field;
560 int ret;
04aa13f8 561 struct bytecode_get_index_data gid;
47e5f13e
MD
562 ssize_t data_offset;
563
53b9d7db 564 nr_fields = event_desc->nr_fields;
47e5f13e 565 offset = ((struct get_symbol *) insn->data)->offset;
362a65de 566 name = runtime->p.priv->bc->bc.data + runtime->p.priv->bc->bc.reloc_offset + offset;
47e5f13e 567 for (i = 0; i < nr_fields; i++) {
53b9d7db 568 field = &event_desc->fields[i];
218deb69
MD
569 if (field->u.ext.nofilter) {
570 continue;
571 }
47e5f13e
MD
572 if (!strcmp(field->name, name)) {
573 found = true;
574 break;
575 }
576 /* compute field offset on stack */
577 switch (field->type.atype) {
578 case atype_integer:
218deb69 579 case atype_enum_nestable:
47e5f13e
MD
580 field_offset += sizeof(int64_t);
581 break;
218deb69 582 case atype_array_nestable:
218deb69 583 case atype_sequence_nestable:
47e5f13e
MD
584 field_offset += sizeof(unsigned long);
585 field_offset += sizeof(void *);
586 break;
587 case atype_string:
588 field_offset += sizeof(void *);
589 break;
590 case atype_float:
591 field_offset += sizeof(double);
592 break;
593 default:
594 ret = -EINVAL;
595 goto end;
596 }
597 }
598 if (!found) {
599 ret = -EINVAL;
600 goto end;
601 }
602
603 ret = specialize_load_object(field, load, false);
604 if (ret)
605 goto end;
606
607 /* Specialize each get_symbol into a get_index. */
04aa13f8 608 insn->op = BYTECODE_OP_GET_INDEX_U16;
47e5f13e
MD
609 memset(&gid, 0, sizeof(gid));
610 gid.offset = field_offset;
611 gid.elem.type = load->object_type;
6bbd9df3 612 gid.elem.rev_bo = load->rev_bo;
f3503ba9 613 gid.field = field;
47e5f13e
MD
614 data_offset = bytecode_push_data(runtime, &gid,
615 __alignof__(gid), sizeof(gid));
616 if (data_offset < 0) {
617 ret = -EINVAL;
618 goto end;
619 }
620 ((struct get_index_u16 *) insn->data)->index = data_offset;
621 ret = 0;
622end:
623 return ret;
624}
625
04aa13f8 626int lttng_bytecode_specialize(const struct lttng_event_desc *event_desc,
47e5f13e 627 struct bytecode_runtime *bytecode)
97b58163
MD
628{
629 void *pc, *next_pc, *start_pc;
630 int ret = -EINVAL;
0305960f
MD
631 struct vstack _stack;
632 struct vstack *stack = &_stack;
362a65de 633 struct lttng_ctx **pctx = bytecode->p.priv->pctx;
97b58163 634
0305960f 635 vstack_init(stack);
97b58163 636
47e5f13e 637 start_pc = &bytecode->code[0];
97b58163
MD
638 for (pc = next_pc = start_pc; pc - start_pc < bytecode->len;
639 pc = next_pc) {
04aa13f8
FD
640 switch (*(bytecode_opcode_t *) pc) {
641 case BYTECODE_OP_UNKNOWN:
97b58163
MD
642 default:
643 ERR("unknown bytecode op %u\n",
04aa13f8 644 (unsigned int) *(bytecode_opcode_t *) pc);
97b58163
MD
645 ret = -EINVAL;
646 goto end;
647
04aa13f8 648 case BYTECODE_OP_RETURN:
d97f9b78
MD
649 if (vstack_ax(stack)->type == REG_S64 ||
650 vstack_ax(stack)->type == REG_U64)
04aa13f8 651 *(bytecode_opcode_t *) pc = BYTECODE_OP_RETURN_S64;
93c591bb
MD
652 ret = 0;
653 goto end;
654
04aa13f8 655 case BYTECODE_OP_RETURN_S64:
d97f9b78
MD
656 if (vstack_ax(stack)->type != REG_S64 &&
657 vstack_ax(stack)->type != REG_U64) {
93c591bb
MD
658 ERR("Unexpected register type\n");
659 ret = -EINVAL;
660 goto end;
661 }
97b58163
MD
662 ret = 0;
663 goto end;
664
665 /* binary */
04aa13f8
FD
666 case BYTECODE_OP_MUL:
667 case BYTECODE_OP_DIV:
668 case BYTECODE_OP_MOD:
669 case BYTECODE_OP_PLUS:
670 case BYTECODE_OP_MINUS:
97b58163 671 ERR("unsupported bytecode op %u\n",
04aa13f8 672 (unsigned int) *(bytecode_opcode_t *) pc);
97b58163
MD
673 ret = -EINVAL;
674 goto end;
675
04aa13f8 676 case BYTECODE_OP_EQ:
97b58163
MD
677 {
678 struct binary_op *insn = (struct binary_op *) pc;
679
0305960f 680 switch(vstack_ax(stack)->type) {
97b58163
MD
681 default:
682 ERR("unknown register type\n");
683 ret = -EINVAL;
684 goto end;
685
686 case REG_STRING:
53569322
MD
687 if (vstack_bx(stack)->type == REG_UNKNOWN)
688 break;
3151a51d 689 if (vstack_bx(stack)->type == REG_STAR_GLOB_STRING)
04aa13f8 690 insn->op = BYTECODE_OP_EQ_STAR_GLOB_STRING;
3151a51d 691 else
04aa13f8 692 insn->op = BYTECODE_OP_EQ_STRING;
3151a51d
PP
693 break;
694 case REG_STAR_GLOB_STRING:
695 if (vstack_bx(stack)->type == REG_UNKNOWN)
696 break;
04aa13f8 697 insn->op = BYTECODE_OP_EQ_STAR_GLOB_STRING;
97b58163
MD
698 break;
699 case REG_S64:
d97f9b78 700 case REG_U64:
53569322
MD
701 if (vstack_bx(stack)->type == REG_UNKNOWN)
702 break;
d97f9b78
MD
703 if (vstack_bx(stack)->type == REG_S64 ||
704 vstack_bx(stack)->type == REG_U64)
04aa13f8 705 insn->op = BYTECODE_OP_EQ_S64;
97b58163 706 else
04aa13f8 707 insn->op = BYTECODE_OP_EQ_DOUBLE_S64;
97b58163
MD
708 break;
709 case REG_DOUBLE:
53569322
MD
710 if (vstack_bx(stack)->type == REG_UNKNOWN)
711 break;
d97f9b78
MD
712 if (vstack_bx(stack)->type == REG_S64 ||
713 vstack_bx(stack)->type == REG_U64)
04aa13f8 714 insn->op = BYTECODE_OP_EQ_S64_DOUBLE;
dbea82ec 715 else
04aa13f8 716 insn->op = BYTECODE_OP_EQ_DOUBLE;
97b58163 717 break;
53569322
MD
718 case REG_UNKNOWN:
719 break; /* Dynamic typing. */
97b58163 720 }
0305960f
MD
721 /* Pop 2, push 1 */
722 if (vstack_pop(stack)) {
723 ret = -EINVAL;
724 goto end;
725 }
726 vstack_ax(stack)->type = REG_S64;
97b58163
MD
727 next_pc += sizeof(struct binary_op);
728 break;
729 }
730
04aa13f8 731 case BYTECODE_OP_NE:
97b58163
MD
732 {
733 struct binary_op *insn = (struct binary_op *) pc;
734
0305960f 735 switch(vstack_ax(stack)->type) {
97b58163
MD
736 default:
737 ERR("unknown register type\n");
738 ret = -EINVAL;
739 goto end;
740
741 case REG_STRING:
53569322
MD
742 if (vstack_bx(stack)->type == REG_UNKNOWN)
743 break;
3151a51d 744 if (vstack_bx(stack)->type == REG_STAR_GLOB_STRING)
04aa13f8 745 insn->op = BYTECODE_OP_NE_STAR_GLOB_STRING;
3151a51d 746 else
04aa13f8 747 insn->op = BYTECODE_OP_NE_STRING;
3151a51d
PP
748 break;
749 case REG_STAR_GLOB_STRING:
750 if (vstack_bx(stack)->type == REG_UNKNOWN)
751 break;
04aa13f8 752 insn->op = BYTECODE_OP_NE_STAR_GLOB_STRING;
97b58163
MD
753 break;
754 case REG_S64:
d97f9b78 755 case REG_U64:
53569322
MD
756 if (vstack_bx(stack)->type == REG_UNKNOWN)
757 break;
d97f9b78
MD
758 if (vstack_bx(stack)->type == REG_S64 ||
759 vstack_bx(stack)->type == REG_U64)
04aa13f8 760 insn->op = BYTECODE_OP_NE_S64;
97b58163 761 else
04aa13f8 762 insn->op = BYTECODE_OP_NE_DOUBLE_S64;
97b58163
MD
763 break;
764 case REG_DOUBLE:
53569322
MD
765 if (vstack_bx(stack)->type == REG_UNKNOWN)
766 break;
d97f9b78
MD
767 if (vstack_bx(stack)->type == REG_S64 ||
768 vstack_bx(stack)->type == REG_U64)
04aa13f8 769 insn->op = BYTECODE_OP_NE_S64_DOUBLE;
dbea82ec 770 else
04aa13f8 771 insn->op = BYTECODE_OP_NE_DOUBLE;
97b58163 772 break;
53569322
MD
773 case REG_UNKNOWN:
774 break; /* Dynamic typing. */
97b58163 775 }
0305960f
MD
776 /* Pop 2, push 1 */
777 if (vstack_pop(stack)) {
778 ret = -EINVAL;
779 goto end;
780 }
781 vstack_ax(stack)->type = REG_S64;
97b58163
MD
782 next_pc += sizeof(struct binary_op);
783 break;
784 }
785
04aa13f8 786 case BYTECODE_OP_GT:
97b58163
MD
787 {
788 struct binary_op *insn = (struct binary_op *) pc;
789
0305960f 790 switch(vstack_ax(stack)->type) {
97b58163
MD
791 default:
792 ERR("unknown register type\n");
793 ret = -EINVAL;
794 goto end;
795
3151a51d
PP
796 case REG_STAR_GLOB_STRING:
797 ERR("invalid register type for > binary operator\n");
798 ret = -EINVAL;
799 goto end;
97b58163 800 case REG_STRING:
53569322
MD
801 if (vstack_bx(stack)->type == REG_UNKNOWN)
802 break;
04aa13f8 803 insn->op = BYTECODE_OP_GT_STRING;
97b58163
MD
804 break;
805 case REG_S64:
d97f9b78 806 case REG_U64:
53569322
MD
807 if (vstack_bx(stack)->type == REG_UNKNOWN)
808 break;
d97f9b78
MD
809 if (vstack_bx(stack)->type == REG_S64 ||
810 vstack_bx(stack)->type == REG_U64)
04aa13f8 811 insn->op = BYTECODE_OP_GT_S64;
97b58163 812 else
04aa13f8 813 insn->op = BYTECODE_OP_GT_DOUBLE_S64;
97b58163
MD
814 break;
815 case REG_DOUBLE:
53569322
MD
816 if (vstack_bx(stack)->type == REG_UNKNOWN)
817 break;
d97f9b78
MD
818 if (vstack_bx(stack)->type == REG_S64 ||
819 vstack_bx(stack)->type == REG_U64)
04aa13f8 820 insn->op = BYTECODE_OP_GT_S64_DOUBLE;
dbea82ec 821 else
04aa13f8 822 insn->op = BYTECODE_OP_GT_DOUBLE;
97b58163 823 break;
53569322
MD
824 case REG_UNKNOWN:
825 break; /* Dynamic typing. */
97b58163 826 }
0305960f
MD
827 /* Pop 2, push 1 */
828 if (vstack_pop(stack)) {
829 ret = -EINVAL;
830 goto end;
831 }
832 vstack_ax(stack)->type = REG_S64;
97b58163
MD
833 next_pc += sizeof(struct binary_op);
834 break;
835 }
836
04aa13f8 837 case BYTECODE_OP_LT:
97b58163
MD
838 {
839 struct binary_op *insn = (struct binary_op *) pc;
840
0305960f 841 switch(vstack_ax(stack)->type) {
97b58163
MD
842 default:
843 ERR("unknown register type\n");
844 ret = -EINVAL;
845 goto end;
846
3151a51d
PP
847 case REG_STAR_GLOB_STRING:
848 ERR("invalid register type for < binary operator\n");
849 ret = -EINVAL;
850 goto end;
97b58163 851 case REG_STRING:
53569322
MD
852 if (vstack_bx(stack)->type == REG_UNKNOWN)
853 break;
04aa13f8 854 insn->op = BYTECODE_OP_LT_STRING;
97b58163
MD
855 break;
856 case REG_S64:
d97f9b78 857 case REG_U64:
53569322
MD
858 if (vstack_bx(stack)->type == REG_UNKNOWN)
859 break;
d97f9b78
MD
860 if (vstack_bx(stack)->type == REG_S64 ||
861 vstack_bx(stack)->type == REG_U64)
04aa13f8 862 insn->op = BYTECODE_OP_LT_S64;
97b58163 863 else
04aa13f8 864 insn->op = BYTECODE_OP_LT_DOUBLE_S64;
97b58163
MD
865 break;
866 case REG_DOUBLE:
53569322
MD
867 if (vstack_bx(stack)->type == REG_UNKNOWN)
868 break;
d97f9b78
MD
869 if (vstack_bx(stack)->type == REG_S64 ||
870 vstack_bx(stack)->type == REG_U64)
04aa13f8 871 insn->op = BYTECODE_OP_LT_S64_DOUBLE;
dbea82ec 872 else
04aa13f8 873 insn->op = BYTECODE_OP_LT_DOUBLE;
97b58163 874 break;
53569322
MD
875 case REG_UNKNOWN:
876 break; /* Dynamic typing. */
97b58163 877 }
0305960f
MD
878 /* Pop 2, push 1 */
879 if (vstack_pop(stack)) {
880 ret = -EINVAL;
881 goto end;
882 }
883 vstack_ax(stack)->type = REG_S64;
97b58163
MD
884 next_pc += sizeof(struct binary_op);
885 break;
886 }
887
04aa13f8 888 case BYTECODE_OP_GE:
97b58163
MD
889 {
890 struct binary_op *insn = (struct binary_op *) pc;
891
0305960f 892 switch(vstack_ax(stack)->type) {
97b58163
MD
893 default:
894 ERR("unknown register type\n");
895 ret = -EINVAL;
896 goto end;
897
3151a51d
PP
898 case REG_STAR_GLOB_STRING:
899 ERR("invalid register type for >= binary operator\n");
900 ret = -EINVAL;
901 goto end;
97b58163 902 case REG_STRING:
53569322
MD
903 if (vstack_bx(stack)->type == REG_UNKNOWN)
904 break;
04aa13f8 905 insn->op = BYTECODE_OP_GE_STRING;
97b58163
MD
906 break;
907 case REG_S64:
d97f9b78 908 case REG_U64:
53569322
MD
909 if (vstack_bx(stack)->type == REG_UNKNOWN)
910 break;
d97f9b78
MD
911 if (vstack_bx(stack)->type == REG_S64 ||
912 vstack_bx(stack)->type == REG_U64)
04aa13f8 913 insn->op = BYTECODE_OP_GE_S64;
97b58163 914 else
04aa13f8 915 insn->op = BYTECODE_OP_GE_DOUBLE_S64;
97b58163
MD
916 break;
917 case REG_DOUBLE:
53569322
MD
918 if (vstack_bx(stack)->type == REG_UNKNOWN)
919 break;
d97f9b78
MD
920 if (vstack_bx(stack)->type == REG_S64 ||
921 vstack_bx(stack)->type == REG_U64)
04aa13f8 922 insn->op = BYTECODE_OP_GE_S64_DOUBLE;
dbea82ec 923 else
04aa13f8 924 insn->op = BYTECODE_OP_GE_DOUBLE;
97b58163 925 break;
53569322
MD
926 case REG_UNKNOWN:
927 break; /* Dynamic typing. */
97b58163 928 }
0305960f
MD
929 /* Pop 2, push 1 */
930 if (vstack_pop(stack)) {
931 ret = -EINVAL;
932 goto end;
933 }
d97f9b78 934 vstack_ax(stack)->type = REG_U64;
97b58163
MD
935 next_pc += sizeof(struct binary_op);
936 break;
937 }
04aa13f8 938 case BYTECODE_OP_LE:
97b58163
MD
939 {
940 struct binary_op *insn = (struct binary_op *) pc;
941
0305960f 942 switch(vstack_ax(stack)->type) {
97b58163
MD
943 default:
944 ERR("unknown register type\n");
945 ret = -EINVAL;
946 goto end;
947
3151a51d
PP
948 case REG_STAR_GLOB_STRING:
949 ERR("invalid register type for <= binary operator\n");
950 ret = -EINVAL;
951 goto end;
97b58163 952 case REG_STRING:
53569322
MD
953 if (vstack_bx(stack)->type == REG_UNKNOWN)
954 break;
04aa13f8 955 insn->op = BYTECODE_OP_LE_STRING;
97b58163
MD
956 break;
957 case REG_S64:
d97f9b78 958 case REG_U64:
53569322
MD
959 if (vstack_bx(stack)->type == REG_UNKNOWN)
960 break;
d97f9b78
MD
961 if (vstack_bx(stack)->type == REG_S64 ||
962 vstack_bx(stack)->type == REG_U64)
04aa13f8 963 insn->op = BYTECODE_OP_LE_S64;
97b58163 964 else
04aa13f8 965 insn->op = BYTECODE_OP_LE_DOUBLE_S64;
97b58163
MD
966 break;
967 case REG_DOUBLE:
53569322
MD
968 if (vstack_bx(stack)->type == REG_UNKNOWN)
969 break;
d97f9b78
MD
970 if (vstack_bx(stack)->type == REG_S64 ||
971 vstack_bx(stack)->type == REG_U64)
04aa13f8 972 insn->op = BYTECODE_OP_LE_S64_DOUBLE;
dbea82ec 973 else
04aa13f8 974 insn->op = BYTECODE_OP_LE_DOUBLE;
97b58163 975 break;
53569322
MD
976 case REG_UNKNOWN:
977 break; /* Dynamic typing. */
97b58163 978 }
0305960f 979 vstack_ax(stack)->type = REG_S64;
97b58163
MD
980 next_pc += sizeof(struct binary_op);
981 break;
982 }
983
04aa13f8
FD
984 case BYTECODE_OP_EQ_STRING:
985 case BYTECODE_OP_NE_STRING:
986 case BYTECODE_OP_GT_STRING:
987 case BYTECODE_OP_LT_STRING:
988 case BYTECODE_OP_GE_STRING:
989 case BYTECODE_OP_LE_STRING:
990 case BYTECODE_OP_EQ_STAR_GLOB_STRING:
991 case BYTECODE_OP_NE_STAR_GLOB_STRING:
992 case BYTECODE_OP_EQ_S64:
993 case BYTECODE_OP_NE_S64:
994 case BYTECODE_OP_GT_S64:
995 case BYTECODE_OP_LT_S64:
996 case BYTECODE_OP_GE_S64:
997 case BYTECODE_OP_LE_S64:
998 case BYTECODE_OP_EQ_DOUBLE:
999 case BYTECODE_OP_NE_DOUBLE:
1000 case BYTECODE_OP_GT_DOUBLE:
1001 case BYTECODE_OP_LT_DOUBLE:
1002 case BYTECODE_OP_GE_DOUBLE:
1003 case BYTECODE_OP_LE_DOUBLE:
1004 case BYTECODE_OP_EQ_DOUBLE_S64:
1005 case BYTECODE_OP_NE_DOUBLE_S64:
1006 case BYTECODE_OP_GT_DOUBLE_S64:
1007 case BYTECODE_OP_LT_DOUBLE_S64:
1008 case BYTECODE_OP_GE_DOUBLE_S64:
1009 case BYTECODE_OP_LE_DOUBLE_S64:
1010 case BYTECODE_OP_EQ_S64_DOUBLE:
1011 case BYTECODE_OP_NE_S64_DOUBLE:
1012 case BYTECODE_OP_GT_S64_DOUBLE:
1013 case BYTECODE_OP_LT_S64_DOUBLE:
1014 case BYTECODE_OP_GE_S64_DOUBLE:
1015 case BYTECODE_OP_LE_S64_DOUBLE:
d97f9b78
MD
1016 {
1017 /* Pop 2, push 1 */
1018 if (vstack_pop(stack)) {
1019 ret = -EINVAL;
1020 goto end;
1021 }
1022 vstack_ax(stack)->type = REG_S64;
1023 next_pc += sizeof(struct binary_op);
1024 break;
1025 }
1026
04aa13f8
FD
1027 case BYTECODE_OP_BIT_RSHIFT:
1028 case BYTECODE_OP_BIT_LSHIFT:
1029 case BYTECODE_OP_BIT_AND:
1030 case BYTECODE_OP_BIT_OR:
1031 case BYTECODE_OP_BIT_XOR:
97b58163 1032 {
0305960f
MD
1033 /* Pop 2, push 1 */
1034 if (vstack_pop(stack)) {
1035 ret = -EINVAL;
1036 goto end;
1037 }
1038 vstack_ax(stack)->type = REG_S64;
97b58163
MD
1039 next_pc += sizeof(struct binary_op);
1040 break;
1041 }
1042
1043 /* unary */
04aa13f8 1044 case BYTECODE_OP_UNARY_PLUS:
97b58163
MD
1045 {
1046 struct unary_op *insn = (struct unary_op *) pc;
1047
0305960f 1048 switch(vstack_ax(stack)->type) {
97b58163
MD
1049 default:
1050 ERR("unknown register type\n");
1051 ret = -EINVAL;
1052 goto end;
1053
1054 case REG_S64:
d97f9b78 1055 case REG_U64:
04aa13f8 1056 insn->op = BYTECODE_OP_UNARY_PLUS_S64;
97b58163
MD
1057 break;
1058 case REG_DOUBLE:
04aa13f8 1059 insn->op = BYTECODE_OP_UNARY_PLUS_DOUBLE;
97b58163 1060 break;
53569322
MD
1061 case REG_UNKNOWN: /* Dynamic typing. */
1062 break;
97b58163 1063 }
0305960f 1064 /* Pop 1, push 1 */
97b58163
MD
1065 next_pc += sizeof(struct unary_op);
1066 break;
1067 }
1068
04aa13f8 1069 case BYTECODE_OP_UNARY_MINUS:
97b58163
MD
1070 {
1071 struct unary_op *insn = (struct unary_op *) pc;
1072
0305960f 1073 switch(vstack_ax(stack)->type) {
97b58163
MD
1074 default:
1075 ERR("unknown register type\n");
1076 ret = -EINVAL;
1077 goto end;
1078
1079 case REG_S64:
d97f9b78 1080 case REG_U64:
04aa13f8 1081 insn->op = BYTECODE_OP_UNARY_MINUS_S64;
97b58163
MD
1082 break;
1083 case REG_DOUBLE:
04aa13f8 1084 insn->op = BYTECODE_OP_UNARY_MINUS_DOUBLE;
97b58163 1085 break;
53569322
MD
1086 case REG_UNKNOWN: /* Dynamic typing. */
1087 break;
97b58163 1088 }
0305960f 1089 /* Pop 1, push 1 */
97b58163
MD
1090 next_pc += sizeof(struct unary_op);
1091 break;
1092 }
1093
04aa13f8 1094 case BYTECODE_OP_UNARY_NOT:
97b58163
MD
1095 {
1096 struct unary_op *insn = (struct unary_op *) pc;
1097
0305960f 1098 switch(vstack_ax(stack)->type) {
97b58163
MD
1099 default:
1100 ERR("unknown register type\n");
1101 ret = -EINVAL;
1102 goto end;
1103
1104 case REG_S64:
d97f9b78 1105 case REG_U64:
04aa13f8 1106 insn->op = BYTECODE_OP_UNARY_NOT_S64;
97b58163
MD
1107 break;
1108 case REG_DOUBLE:
04aa13f8 1109 insn->op = BYTECODE_OP_UNARY_NOT_DOUBLE;
97b58163 1110 break;
53569322
MD
1111 case REG_UNKNOWN: /* Dynamic typing. */
1112 break;
97b58163 1113 }
0305960f 1114 /* Pop 1, push 1 */
97b58163
MD
1115 next_pc += sizeof(struct unary_op);
1116 break;
1117 }
1118
04aa13f8 1119 case BYTECODE_OP_UNARY_BIT_NOT:
0039e2d8
MD
1120 {
1121 /* Pop 1, push 1 */
1122 next_pc += sizeof(struct unary_op);
1123 break;
1124 }
1125
04aa13f8
FD
1126 case BYTECODE_OP_UNARY_PLUS_S64:
1127 case BYTECODE_OP_UNARY_MINUS_S64:
1128 case BYTECODE_OP_UNARY_NOT_S64:
1129 case BYTECODE_OP_UNARY_PLUS_DOUBLE:
1130 case BYTECODE_OP_UNARY_MINUS_DOUBLE:
1131 case BYTECODE_OP_UNARY_NOT_DOUBLE:
97b58163 1132 {
0305960f 1133 /* Pop 1, push 1 */
97b58163
MD
1134 next_pc += sizeof(struct unary_op);
1135 break;
1136 }
1137
1138 /* logical */
04aa13f8
FD
1139 case BYTECODE_OP_AND:
1140 case BYTECODE_OP_OR:
97b58163 1141 {
b9f4cd79
MD
1142 /* Continue to next instruction */
1143 /* Pop 1 when jump not taken */
1144 if (vstack_pop(stack)) {
1145 ret = -EINVAL;
1146 goto end;
1147 }
97b58163
MD
1148 next_pc += sizeof(struct logical_op);
1149 break;
1150 }
1151
77aa5901 1152 /* load field ref */
04aa13f8 1153 case BYTECODE_OP_LOAD_FIELD_REF:
97b58163
MD
1154 {
1155 ERR("Unknown field ref type\n");
1156 ret = -EINVAL;
1157 goto end;
1158 }
77aa5901 1159 /* get context ref */
04aa13f8 1160 case BYTECODE_OP_GET_CONTEXT_REF:
77aa5901 1161 {
53569322
MD
1162 if (vstack_push(stack)) {
1163 ret = -EINVAL;
1164 goto end;
1165 }
1166 vstack_ax(stack)->type = REG_UNKNOWN;
1167 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1168 break;
77aa5901 1169 }
04aa13f8
FD
1170 case BYTECODE_OP_LOAD_FIELD_REF_STRING:
1171 case BYTECODE_OP_LOAD_FIELD_REF_SEQUENCE:
1172 case BYTECODE_OP_GET_CONTEXT_REF_STRING:
97b58163 1173 {
0305960f
MD
1174 if (vstack_push(stack)) {
1175 ret = -EINVAL;
1176 goto end;
1177 }
1178 vstack_ax(stack)->type = REG_STRING;
97b58163
MD
1179 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1180 break;
1181 }
04aa13f8
FD
1182 case BYTECODE_OP_LOAD_FIELD_REF_S64:
1183 case BYTECODE_OP_GET_CONTEXT_REF_S64:
97b58163 1184 {
0305960f
MD
1185 if (vstack_push(stack)) {
1186 ret = -EINVAL;
1187 goto end;
1188 }
1189 vstack_ax(stack)->type = REG_S64;
97b58163
MD
1190 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1191 break;
1192 }
04aa13f8
FD
1193 case BYTECODE_OP_LOAD_FIELD_REF_DOUBLE:
1194 case BYTECODE_OP_GET_CONTEXT_REF_DOUBLE:
97b58163 1195 {
0305960f
MD
1196 if (vstack_push(stack)) {
1197 ret = -EINVAL;
1198 goto end;
1199 }
1200 vstack_ax(stack)->type = REG_DOUBLE;
97b58163
MD
1201 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1202 break;
1203 }
1204
77aa5901 1205 /* load from immediate operand */
04aa13f8 1206 case BYTECODE_OP_LOAD_STRING:
97b58163
MD
1207 {
1208 struct load_op *insn = (struct load_op *) pc;
1209
0305960f
MD
1210 if (vstack_push(stack)) {
1211 ret = -EINVAL;
1212 goto end;
1213 }
1214 vstack_ax(stack)->type = REG_STRING;
97b58163
MD
1215 next_pc += sizeof(struct load_op) + strlen(insn->data) + 1;
1216 break;
1217 }
1218
04aa13f8 1219 case BYTECODE_OP_LOAD_STAR_GLOB_STRING:
3151a51d
PP
1220 {
1221 struct load_op *insn = (struct load_op *) pc;
1222
1223 if (vstack_push(stack)) {
1224 ret = -EINVAL;
1225 goto end;
1226 }
1227 vstack_ax(stack)->type = REG_STAR_GLOB_STRING;
1228 next_pc += sizeof(struct load_op) + strlen(insn->data) + 1;
1229 break;
1230 }
1231
04aa13f8 1232 case BYTECODE_OP_LOAD_S64:
97b58163 1233 {
0305960f
MD
1234 if (vstack_push(stack)) {
1235 ret = -EINVAL;
1236 goto end;
1237 }
1238 vstack_ax(stack)->type = REG_S64;
97b58163
MD
1239 next_pc += sizeof(struct load_op)
1240 + sizeof(struct literal_numeric);
1241 break;
1242 }
1243
04aa13f8 1244 case BYTECODE_OP_LOAD_DOUBLE:
97b58163 1245 {
0305960f
MD
1246 if (vstack_push(stack)) {
1247 ret = -EINVAL;
1248 goto end;
1249 }
1250 vstack_ax(stack)->type = REG_DOUBLE;
97b58163
MD
1251 next_pc += sizeof(struct load_op)
1252 + sizeof(struct literal_double);
1253 break;
1254 }
1255
1256 /* cast */
04aa13f8 1257 case BYTECODE_OP_CAST_TO_S64:
97b58163
MD
1258 {
1259 struct cast_op *insn = (struct cast_op *) pc;
1260
0305960f 1261 switch (vstack_ax(stack)->type) {
97b58163
MD
1262 default:
1263 ERR("unknown register type\n");
1264 ret = -EINVAL;
1265 goto end;
1266
1267 case REG_STRING:
3151a51d 1268 case REG_STAR_GLOB_STRING:
97b58163
MD
1269 ERR("Cast op can only be applied to numeric or floating point registers\n");
1270 ret = -EINVAL;
1271 goto end;
1272 case REG_S64:
04aa13f8 1273 insn->op = BYTECODE_OP_CAST_NOP;
97b58163
MD
1274 break;
1275 case REG_DOUBLE:
04aa13f8 1276 insn->op = BYTECODE_OP_CAST_DOUBLE_TO_S64;
97b58163 1277 break;
53569322 1278 case REG_UNKNOWN:
d97f9b78 1279 case REG_U64:
53569322 1280 break;
97b58163 1281 }
0305960f
MD
1282 /* Pop 1, push 1 */
1283 vstack_ax(stack)->type = REG_S64;
97b58163
MD
1284 next_pc += sizeof(struct cast_op);
1285 break;
1286 }
04aa13f8 1287 case BYTECODE_OP_CAST_DOUBLE_TO_S64:
97b58163 1288 {
0305960f
MD
1289 /* Pop 1, push 1 */
1290 vstack_ax(stack)->type = REG_S64;
97b58163
MD
1291 next_pc += sizeof(struct cast_op);
1292 break;
1293 }
04aa13f8 1294 case BYTECODE_OP_CAST_NOP:
97b58163
MD
1295 {
1296 next_pc += sizeof(struct cast_op);
1297 break;
1298 }
1299
47e5f13e
MD
1300 /*
1301 * Instructions for recursive traversal through composed types.
1302 */
04aa13f8 1303 case BYTECODE_OP_GET_CONTEXT_ROOT:
47e5f13e
MD
1304 {
1305 if (vstack_push(stack)) {
1306 ret = -EINVAL;
1307 goto end;
1308 }
1309 vstack_ax(stack)->type = REG_PTR;
1310 vstack_ax(stack)->load.type = LOAD_ROOT_CONTEXT;
1311 next_pc += sizeof(struct load_op);
1312 break;
1313 }
04aa13f8 1314 case BYTECODE_OP_GET_APP_CONTEXT_ROOT:
47e5f13e
MD
1315 {
1316 if (vstack_push(stack)) {
1317 ret = -EINVAL;
1318 goto end;
1319 }
1320 vstack_ax(stack)->type = REG_PTR;
1321 vstack_ax(stack)->load.type = LOAD_ROOT_APP_CONTEXT;
1322 next_pc += sizeof(struct load_op);
1323 break;
1324 }
04aa13f8 1325 case BYTECODE_OP_GET_PAYLOAD_ROOT:
47e5f13e
MD
1326 {
1327 if (vstack_push(stack)) {
1328 ret = -EINVAL;
1329 goto end;
1330 }
1331 vstack_ax(stack)->type = REG_PTR;
1332 vstack_ax(stack)->load.type = LOAD_ROOT_PAYLOAD;
1333 next_pc += sizeof(struct load_op);
1334 break;
1335 }
1336
04aa13f8 1337 case BYTECODE_OP_LOAD_FIELD:
47e5f13e
MD
1338 {
1339 struct load_op *insn = (struct load_op *) pc;
1340
1341 assert(vstack_ax(stack)->type == REG_PTR);
1342 /* Pop 1, push 1 */
1343 ret = specialize_load_field(vstack_ax(stack), insn);
1344 if (ret)
1345 goto end;
1346
1347 next_pc += sizeof(struct load_op);
1348 break;
1349 }
1350
04aa13f8
FD
1351 case BYTECODE_OP_LOAD_FIELD_S8:
1352 case BYTECODE_OP_LOAD_FIELD_S16:
1353 case BYTECODE_OP_LOAD_FIELD_S32:
1354 case BYTECODE_OP_LOAD_FIELD_S64:
d97f9b78
MD
1355 {
1356 /* Pop 1, push 1 */
1357 vstack_ax(stack)->type = REG_S64;
1358 next_pc += sizeof(struct load_op);
1359 break;
1360 }
1361
04aa13f8
FD
1362 case BYTECODE_OP_LOAD_FIELD_U8:
1363 case BYTECODE_OP_LOAD_FIELD_U16:
1364 case BYTECODE_OP_LOAD_FIELD_U32:
1365 case BYTECODE_OP_LOAD_FIELD_U64:
47e5f13e
MD
1366 {
1367 /* Pop 1, push 1 */
d97f9b78 1368 vstack_ax(stack)->type = REG_U64;
47e5f13e
MD
1369 next_pc += sizeof(struct load_op);
1370 break;
1371 }
1372
04aa13f8
FD
1373 case BYTECODE_OP_LOAD_FIELD_STRING:
1374 case BYTECODE_OP_LOAD_FIELD_SEQUENCE:
47e5f13e
MD
1375 {
1376 /* Pop 1, push 1 */
1377 vstack_ax(stack)->type = REG_STRING;
1378 next_pc += sizeof(struct load_op);
1379 break;
1380 }
1381
04aa13f8 1382 case BYTECODE_OP_LOAD_FIELD_DOUBLE:
47e5f13e
MD
1383 {
1384 /* Pop 1, push 1 */
1385 vstack_ax(stack)->type = REG_DOUBLE;
1386 next_pc += sizeof(struct load_op);
1387 break;
1388 }
1389
04aa13f8 1390 case BYTECODE_OP_GET_SYMBOL:
47e5f13e
MD
1391 {
1392 struct load_op *insn = (struct load_op *) pc;
1393
1394 dbg_printf("op get symbol\n");
1395 switch (vstack_ax(stack)->load.type) {
1396 case LOAD_OBJECT:
1397 ERR("Nested fields not implemented yet.");
1398 ret = -EINVAL;
1399 goto end;
1400 case LOAD_ROOT_CONTEXT:
1401 /* Lookup context field. */
b77aaa1b 1402 ret = specialize_context_lookup(*pctx,
47e5f13e
MD
1403 bytecode, insn,
1404 &vstack_ax(stack)->load);
1405 if (ret)
1406 goto end;
1407 break;
1408 case LOAD_ROOT_APP_CONTEXT:
1409 /* Lookup app context field. */
b77aaa1b 1410 ret = specialize_app_context_lookup(pctx,
47e5f13e
MD
1411 bytecode, insn,
1412 &vstack_ax(stack)->load);
1413 if (ret)
1414 goto end;
1415 break;
1416 case LOAD_ROOT_PAYLOAD:
1417 /* Lookup event payload field. */
53b9d7db 1418 ret = specialize_payload_lookup(event_desc,
47e5f13e
MD
1419 bytecode, insn,
1420 &vstack_ax(stack)->load);
1421 if (ret)
1422 goto end;
1423 break;
1424 }
1425 next_pc += sizeof(struct load_op) + sizeof(struct get_symbol);
1426 break;
1427 }
1428
04aa13f8 1429 case BYTECODE_OP_GET_SYMBOL_FIELD:
47e5f13e
MD
1430 {
1431 /* Always generated by specialize phase. */
1432 ret = -EINVAL;
1433 goto end;
1434 }
1435
04aa13f8 1436 case BYTECODE_OP_GET_INDEX_U16:
47e5f13e
MD
1437 {
1438 struct load_op *insn = (struct load_op *) pc;
1439 struct get_index_u16 *index = (struct get_index_u16 *) insn->data;
1440
1441 dbg_printf("op get index u16\n");
1442 /* Pop 1, push 1 */
1443 ret = specialize_get_index(bytecode, insn, index->index,
1444 vstack_ax(stack), sizeof(*index));
1445 if (ret)
1446 goto end;
1447 next_pc += sizeof(struct load_op) + sizeof(struct get_index_u16);
1448 break;
1449 }
1450
04aa13f8 1451 case BYTECODE_OP_GET_INDEX_U64:
47e5f13e
MD
1452 {
1453 struct load_op *insn = (struct load_op *) pc;
1454 struct get_index_u64 *index = (struct get_index_u64 *) insn->data;
1455
1456 dbg_printf("op get index u64\n");
1457 /* Pop 1, push 1 */
1458 ret = specialize_get_index(bytecode, insn, index->index,
1459 vstack_ax(stack), sizeof(*index));
1460 if (ret)
1461 goto end;
1462 next_pc += sizeof(struct load_op) + sizeof(struct get_index_u64);
1463 break;
1464 }
1465
97b58163
MD
1466 }
1467 }
1468end:
1469 return ret;
1470}
This page took 0.10039 seconds and 4 git commands to generate.