1/* @ajax/wasm-instr: one instruction at a time from a body or a constant expression.
2 *
3 * wasm_rd_instr reads the opcode (and the sub-opcode of a prefixed one), looks it up in
4 * @ajax/wasm-opcodes and reads its immediates into a wasm_instr. It checks encodings only (an
5 * unknown opcode, a malformed LEB, a bad block type byte); typing is @ajax/wasm-validate's. */
6#ifndef WASM_INSTR_H
7#define WASM_INSTR_H
89#include "wasm/opcodes.h"
10#include "wasm/reader.h"
1112#include <stdbool.h>
13#include <stdint.h>
1415/* Block types: WASM_BT_EMPTY, a value type (the byte), or a type index (>= 0). */
16#define WASM_BT_EMPTY (-64)
1718typedef struct {
19 uint32_t op;
20 wasm_opinfo info;
21 size_t offset; /* of the opcode */
22 uint32_t a, b; /* indices: label, function, local, global, table, type, data, element */
23 uint32_t align, mem; /* memarg: log2 alignment, memory index */
24 uint64_t moffset; /* memarg offset */
25 int64_t i; /* i32.const (sign-extended) and i64.const */
26 uint32_t f32; /* f32.const bits */
27 uint64_t f64; /* f64.const bits */
28 int64_t blocktype; /* WASM_BT_EMPTY, -(0x80 - valtype) for a value type, or a type index */
29 wasm_valtype bt_val; /* the value type when blocktype is one */
30 uint32_t ntargets; /* br_table: targets before the default */
31 const uint8_t *targets; /* br_table: the encoded targets (wasm_instr_target reads them) */
32 uint32_t nselect; /* select t*: how many types (1 in practice) */
33 wasm_valtype select_type;
34 wasm_valtype reftype; /* ref.null */
35 uint8_t lane; /* SIMD lane immediate */
36 const uint8_t *v128; /* SIMD 16-byte immediate */
37} wasm_instr;
3839/* Reads one instruction. false (and the reader's failure set) on a malformed or unknown one. */
40bool wasm_rd_instr(wasm_reader *r, wasm_instr *out);
4142/* br_table's targets: out must hold ntargets + 1 (the default last). */
43void wasm_instr_targets(const wasm_instr *in, uint32_t *out);
4445/* Whether a block type is a value type (and which), empty, or a type index. */
46static inline bool wasm_bt_is_index(const wasm_instr *in) { return in->blocktype >= 0; }
4748#endif