kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

wasm_insn_table.h (3184B)


      1 #ifndef KIT_WASM_INSN_TABLE_H
      2 #define KIT_WASM_INSN_TABLE_H
      3 
      4 /* Single source of truth for the Wasm instruction set.
      5  *
      6  * WasmInsnKind is the same logical instruction described five different ways:
      7  * its opcode bytes (encode), its byte->kind map (decode), its WAT mnemonic
      8  * (disassembler), its mnemonic->kind map (WAT parser), and the operand class
      9  * that drives how immediates are read/written. Historically each of those was
     10  * its own ~200-arm switch that had to stay in lockstep. WASM_INSN_TABLE below
     11  * is that map, written once; encode/wat/disasm derive their behaviour from it
     12  * by O(1) row lookup or a linear scan, and the mnemonic helper reads a column.
     13  *
     14  * Decode keeps its hand-written arms: the per-opcode operand reads are genuinely
     15  * irregular (two index immediates, block-type bytes, br_table vectors, ...) and
     16  * are not worth forcing into a table; it still shares decode_body_insn so the
     17  * byte<->kind mapping lives in exactly one place there too. */
     18 
     19 #include "wasm/wasm.h"
     20 
     21 /* Opcode-space prefix for an instruction's encoding. */
     22 typedef enum WasmInsnPrefix {
     23   WASM_PREFIX_NONE = 0, /* single-byte opcode, `byte` is the opcode */
     24   WASM_PREFIX_FC = 1,   /* 0xfc-prefixed (misc: trunc_sat + bulk memory/table) */
     25   WASM_PREFIX_FE = 2,   /* 0xfe-prefixed (threads/atomics) */
     26 } WasmInsnPrefix;
     27 
     28 /* Operand-class column: how an instruction's immediates are spelled. Drives
     29  * encode (write), the disassembler's render_operands (read), and the WAT
     30  * parser's has_imm. Classes with a trailing comment of "has_imm" are the ones
     31  * for which the WAT grammar parses a single trailing immediate token. */
     32 typedef enum WasmOperandClass {
     33   WASM_OC_NONE = 0,      /* no immediate */
     34   WASM_OC_SLEB,          /* i32/i64.const signed leb (has_imm) */
     35   WASM_OC_FP,            /* f32/f64.const float literal (has_imm) */
     36   WASM_OC_IDX,           /* one uleb index immediate (has_imm) */
     37   WASM_OC_TYPED_REF,     /* call_ref/return_call_ref: uleb typeidx, but WAT
     38                           * takes the type from context, so no trailing token */
     39   WASM_OC_REF_NULL,      /* ref.null valtype (has_imm) */
     40   WASM_OC_CALL_INDIRECT, /* typeidx + tableidx */
     41   WASM_OC_BR_TABLE,      /* label vector + default */
     42   WASM_OC_BLOCK_TYPE,    /* block/loop/if: 0x40 blocktype byte */
     43   WASM_OC_MEMARG,        /* memory access: align/offset/memidx */
     44   WASM_OC_MEM_IDX,       /* memory.size/grow: single memidx */
     45   WASM_OC_BULK,          /* 0xfc bulk memory/table ops, irregular index slots */
     46   WASM_OC_FENCE,         /* atomic.fence: a single 0x00 byte */
     47 } WasmOperandClass;
     48 
     49 typedef struct WasmInsnInfo {
     50   uint8_t kind;          /* WasmInsnKind; rows are enum-indexed */
     51   uint8_t prefix;        /* WasmInsnPrefix */
     52   uint8_t byte;          /* opcode byte (PREFIX_NONE) or sub-opcode otherwise */
     53   uint8_t operand_class; /* WasmOperandClass */
     54   const char* mnemonic;  /* canonical WAT spelling; never NULL in-table */
     55 } WasmInsnInfo;
     56 
     57 /* Row for `kind`, or NULL if out of range. O(1). */
     58 const WasmInsnInfo* wasm_insn_info(WasmInsnKind kind);
     59 /* WAT operand-token presence derived from the operand class. */
     60 int wasm_operand_class_has_imm(WasmOperandClass oc);
     61 
     62 #endif