kit

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

wasm.h (19228B)


      1 #ifndef KIT_WASM_H
      2 #define KIT_WASM_H
      3 
      4 /* Shared Wasm binary/core: in-memory module model, binary decoder, WAT
      5  * parser, validator, encoder, and small instruction-kind helpers. This
      6  * header is the boundary between the format mechanics (decode/encode/
      7  * validate, all in src/wasm/) and the consumers that lower those modules
      8  * into something else (lang/wasm/cg.c lowers to native CG; src/arch/wasm/
      9  * builds modules from the CG backend; src/obj/wasm_emit.c flushes them).
     10  *
     11  * Types here use the public KitCompiler / KitHeap / KitWriter
     12  * aliases on purpose: this layer is callable from every Wasm caller in
     13  * the tree without depending on libkit internals beyond the public
     14  * frontend/CG headers. */
     15 
     16 #include <kit/cg.h>
     17 #include <kit/compile.h>
     18 #include <kit/core.h>
     19 #include <kit/frontend.h>
     20 #include <stdarg.h>
     21 #include <stddef.h>
     22 #include <stdint.h>
     23 #include <stdlib.h>
     24 #include <string.h>
     25 
     26 typedef enum WasmValType {
     27   WASM_VAL_I32 = 0x7f,
     28   WASM_VAL_I64 = 0x7e,
     29   WASM_VAL_F32 = 0x7d,
     30   WASM_VAL_F64 = 0x7c,
     31   WASM_VAL_FUNCREF = 0x70,
     32   WASM_VAL_EXTERNREF = 0x6f,
     33 } WasmValType;
     34 
     35 typedef enum WasmFeatureSet {
     36   WASM_FEATURE_THREADS = 1u << 0,
     37   WASM_FEATURE_TYPED_FUNC_REFS = 1u << 1,
     38   WASM_FEATURE_TAIL_CALLS = 1u << 2,
     39   WASM_FEATURE_MULTI_MEMORY = 1u << 3,
     40   WASM_FEATURE_MEMORY64 = 1u << 4,
     41   WASM_FEATURE_BULK_MEMORY = 1u << 5,
     42   WASM_FEATURE_NONTRAPPING_FTOI = 1u << 6,
     43 } WasmFeatureSet;
     44 
     45 typedef enum WasmInsnKind {
     46   WASM_INSN_UNREACHABLE,
     47   WASM_INSN_NOP,
     48   WASM_INSN_BLOCK,
     49   WASM_INSN_LOOP,
     50   WASM_INSN_IF,
     51   WASM_INSN_ELSE,
     52   WASM_INSN_END,
     53   WASM_INSN_BR,
     54   WASM_INSN_BR_IF,
     55   WASM_INSN_BR_TABLE,
     56   WASM_INSN_SELECT,
     57   WASM_INSN_F32_CONST,
     58   WASM_INSN_F64_CONST,
     59   WASM_INSN_I32_CONST,
     60   WASM_INSN_I64_CONST,
     61   WASM_INSN_LOCAL_GET,
     62   WASM_INSN_LOCAL_SET,
     63   WASM_INSN_LOCAL_TEE,
     64   WASM_INSN_CALL,
     65   WASM_INSN_CALL_INDIRECT,
     66   WASM_INSN_RETURN_CALL,
     67   WASM_INSN_RETURN_CALL_INDIRECT,
     68   WASM_INSN_REF_NULL,
     69   WASM_INSN_REF_FUNC,
     70   WASM_INSN_REF_IS_NULL,
     71   WASM_INSN_CALL_REF,
     72   WASM_INSN_RETURN_CALL_REF,
     73   WASM_INSN_GLOBAL_GET,
     74   WASM_INSN_GLOBAL_SET,
     75   WASM_INSN_RETURN,
     76   WASM_INSN_DROP,
     77   WASM_INSN_I32_LOAD,
     78   WASM_INSN_I64_LOAD,
     79   WASM_INSN_F32_LOAD,
     80   WASM_INSN_F64_LOAD,
     81   WASM_INSN_I32_LOAD8_S,
     82   WASM_INSN_I32_LOAD8_U,
     83   WASM_INSN_I32_LOAD16_S,
     84   WASM_INSN_I32_LOAD16_U,
     85   WASM_INSN_I64_LOAD8_S,
     86   WASM_INSN_I64_LOAD8_U,
     87   WASM_INSN_I64_LOAD16_S,
     88   WASM_INSN_I64_LOAD16_U,
     89   WASM_INSN_I64_LOAD32_S,
     90   WASM_INSN_I64_LOAD32_U,
     91   WASM_INSN_I32_STORE,
     92   WASM_INSN_I64_STORE,
     93   WASM_INSN_F32_STORE,
     94   WASM_INSN_F64_STORE,
     95   WASM_INSN_I32_STORE8,
     96   WASM_INSN_I32_STORE16,
     97   WASM_INSN_I64_STORE8,
     98   WASM_INSN_I64_STORE16,
     99   WASM_INSN_I64_STORE32,
    100   WASM_INSN_MEMORY_SIZE,
    101   WASM_INSN_MEMORY_GROW,
    102   WASM_INSN_ATOMIC_FENCE,
    103   WASM_INSN_I32_ATOMIC_LOAD,
    104   WASM_INSN_I64_ATOMIC_LOAD,
    105   WASM_INSN_I32_ATOMIC_LOAD8_U,
    106   WASM_INSN_I32_ATOMIC_LOAD16_U,
    107   WASM_INSN_I64_ATOMIC_LOAD8_U,
    108   WASM_INSN_I64_ATOMIC_LOAD16_U,
    109   WASM_INSN_I64_ATOMIC_LOAD32_U,
    110   WASM_INSN_I32_ATOMIC_STORE,
    111   WASM_INSN_I64_ATOMIC_STORE,
    112   WASM_INSN_I32_ATOMIC_STORE8,
    113   WASM_INSN_I32_ATOMIC_STORE16,
    114   WASM_INSN_I64_ATOMIC_STORE8,
    115   WASM_INSN_I64_ATOMIC_STORE16,
    116   WASM_INSN_I64_ATOMIC_STORE32,
    117   WASM_INSN_I32_ATOMIC_RMW_ADD,
    118   WASM_INSN_I64_ATOMIC_RMW_ADD,
    119   WASM_INSN_I32_ATOMIC_RMW_SUB,
    120   WASM_INSN_I64_ATOMIC_RMW_SUB,
    121   WASM_INSN_I32_ATOMIC_RMW_AND,
    122   WASM_INSN_I64_ATOMIC_RMW_AND,
    123   WASM_INSN_I32_ATOMIC_RMW_OR,
    124   WASM_INSN_I64_ATOMIC_RMW_OR,
    125   WASM_INSN_I32_ATOMIC_RMW_XOR,
    126   WASM_INSN_I64_ATOMIC_RMW_XOR,
    127   WASM_INSN_I32_ATOMIC_RMW_XCHG,
    128   WASM_INSN_I64_ATOMIC_RMW_XCHG,
    129   WASM_INSN_I32_ATOMIC_RMW_CMPXCHG,
    130   WASM_INSN_I64_ATOMIC_RMW_CMPXCHG,
    131   WASM_INSN_I32_ATOMIC_WAIT,
    132   WASM_INSN_I64_ATOMIC_WAIT,
    133   WASM_INSN_MEMORY_ATOMIC_NOTIFY,
    134   WASM_INSN_I32_ADD,
    135   WASM_INSN_I32_SUB,
    136   WASM_INSN_I32_MUL,
    137   WASM_INSN_I32_DIV_S,
    138   WASM_INSN_I32_DIV_U,
    139   WASM_INSN_I32_REM_S,
    140   WASM_INSN_I32_REM_U,
    141   WASM_INSN_I32_AND,
    142   WASM_INSN_I32_OR,
    143   WASM_INSN_I32_XOR,
    144   WASM_INSN_I32_SHL,
    145   WASM_INSN_I32_SHR_S,
    146   WASM_INSN_I32_SHR_U,
    147   WASM_INSN_I32_ROTL,
    148   WASM_INSN_I32_ROTR,
    149   WASM_INSN_I32_CLZ,
    150   WASM_INSN_I32_CTZ,
    151   WASM_INSN_I32_POPCNT,
    152   WASM_INSN_I32_EQZ,
    153   WASM_INSN_I32_EQ,
    154   WASM_INSN_I32_NE,
    155   WASM_INSN_I32_LT_S,
    156   WASM_INSN_I32_LT_U,
    157   WASM_INSN_I32_GT_S,
    158   WASM_INSN_I32_GT_U,
    159   WASM_INSN_I32_LE_S,
    160   WASM_INSN_I32_LE_U,
    161   WASM_INSN_I32_GE_S,
    162   WASM_INSN_I32_GE_U,
    163   WASM_INSN_I64_ADD,
    164   WASM_INSN_I64_SUB,
    165   WASM_INSN_I64_MUL,
    166   WASM_INSN_I64_DIV_S,
    167   WASM_INSN_I64_DIV_U,
    168   WASM_INSN_I64_REM_S,
    169   WASM_INSN_I64_REM_U,
    170   WASM_INSN_I64_AND,
    171   WASM_INSN_I64_OR,
    172   WASM_INSN_I64_XOR,
    173   WASM_INSN_I64_SHL,
    174   WASM_INSN_I64_SHR_S,
    175   WASM_INSN_I64_SHR_U,
    176   WASM_INSN_I64_ROTL,
    177   WASM_INSN_I64_ROTR,
    178   WASM_INSN_I64_CLZ,
    179   WASM_INSN_I64_CTZ,
    180   WASM_INSN_I64_POPCNT,
    181   WASM_INSN_I64_EQZ,
    182   WASM_INSN_I64_EQ,
    183   WASM_INSN_I64_NE,
    184   WASM_INSN_I64_LT_S,
    185   WASM_INSN_I64_LT_U,
    186   WASM_INSN_I64_GT_S,
    187   WASM_INSN_I64_GT_U,
    188   WASM_INSN_I64_LE_S,
    189   WASM_INSN_I64_LE_U,
    190   WASM_INSN_I64_GE_S,
    191   WASM_INSN_I64_GE_U,
    192   WASM_INSN_F32_ADD,
    193   WASM_INSN_F32_SUB,
    194   WASM_INSN_F32_MUL,
    195   WASM_INSN_F32_DIV,
    196   WASM_INSN_F32_EQ,
    197   WASM_INSN_F32_NE,
    198   WASM_INSN_F32_LT,
    199   WASM_INSN_F32_GT,
    200   WASM_INSN_F32_LE,
    201   WASM_INSN_F32_GE,
    202   WASM_INSN_F64_ADD,
    203   WASM_INSN_F64_SUB,
    204   WASM_INSN_F64_MUL,
    205   WASM_INSN_F64_DIV,
    206   WASM_INSN_F64_EQ,
    207   WASM_INSN_F64_NE,
    208   WASM_INSN_F64_LT,
    209   WASM_INSN_F64_GT,
    210   WASM_INSN_F64_LE,
    211   WASM_INSN_F64_GE,
    212   WASM_INSN_F32_NEG,
    213   WASM_INSN_F64_NEG,
    214   WASM_INSN_I32_WRAP_I64,
    215   WASM_INSN_I32_TRUNC_F32_S,
    216   WASM_INSN_I32_TRUNC_F32_U,
    217   WASM_INSN_I32_TRUNC_F64_S,
    218   WASM_INSN_I32_TRUNC_F64_U,
    219   WASM_INSN_I64_EXTEND_I32_S,
    220   WASM_INSN_I64_EXTEND_I32_U,
    221   WASM_INSN_I64_TRUNC_F32_S,
    222   WASM_INSN_I64_TRUNC_F32_U,
    223   WASM_INSN_I64_TRUNC_F64_S,
    224   WASM_INSN_I64_TRUNC_F64_U,
    225   WASM_INSN_F32_CONVERT_I32_S,
    226   WASM_INSN_F32_CONVERT_I32_U,
    227   WASM_INSN_F32_CONVERT_I64_S,
    228   WASM_INSN_F32_CONVERT_I64_U,
    229   WASM_INSN_F32_DEMOTE_F64,
    230   WASM_INSN_F64_CONVERT_I32_S,
    231   WASM_INSN_F64_CONVERT_I32_U,
    232   WASM_INSN_F64_CONVERT_I64_S,
    233   WASM_INSN_F64_CONVERT_I64_U,
    234   WASM_INSN_F64_PROMOTE_F32,
    235   WASM_INSN_I32_REINTERPRET_F32,
    236   WASM_INSN_I64_REINTERPRET_F64,
    237   WASM_INSN_F32_REINTERPRET_I32,
    238   WASM_INSN_F64_REINTERPRET_I64,
    239   /* Sign-extension operators (0xc0..0xc4). In-register sign extension from a
    240    * narrower width; part of the standard MVP-era instruction set. */
    241   WASM_INSN_I32_EXTEND8_S,
    242   WASM_INSN_I32_EXTEND16_S,
    243   WASM_INSN_I64_EXTEND8_S,
    244   WASM_INSN_I64_EXTEND16_S,
    245   WASM_INSN_I64_EXTEND32_S,
    246   /* Non-trapping float-to-int truncation (0xfc 0x00..0x07).
    247    * Gated by WASM_FEATURE_NONTRAPPING_FTOI. */
    248   WASM_INSN_I32_TRUNC_SAT_F32_S,
    249   WASM_INSN_I32_TRUNC_SAT_F32_U,
    250   WASM_INSN_I32_TRUNC_SAT_F64_S,
    251   WASM_INSN_I32_TRUNC_SAT_F64_U,
    252   WASM_INSN_I64_TRUNC_SAT_F32_S,
    253   WASM_INSN_I64_TRUNC_SAT_F32_U,
    254   WASM_INSN_I64_TRUNC_SAT_F64_S,
    255   WASM_INSN_I64_TRUNC_SAT_F64_U,
    256   /* Bulk memory ops (0xfc 0x08..0x11). Gated by WASM_FEATURE_BULK_MEMORY.
    257    * Immediate slots:
    258    *   memory.init:  imm = dataidx, memidx = memidx
    259    *   data.drop:    imm = dataidx
    260    *   memory.copy:  memidx = dst memidx, aux_idx = src memidx
    261    *   memory.fill:  memidx = memidx
    262    *   table.init:   imm = elemidx, aux_idx = tableidx
    263    *   elem.drop:    imm = elemidx
    264    *   table.copy:   aux_idx = src tableidx, imm = dst tableidx
    265    *   table.grow:   imm = tableidx
    266    *   table.size:   imm = tableidx
    267    *   table.fill:   imm = tableidx
    268    */
    269   WASM_INSN_MEMORY_INIT,
    270   WASM_INSN_DATA_DROP,
    271   WASM_INSN_MEMORY_COPY,
    272   WASM_INSN_MEMORY_FILL,
    273   WASM_INSN_TABLE_INIT,
    274   WASM_INSN_ELEM_DROP,
    275   WASM_INSN_TABLE_COPY,
    276   WASM_INSN_TABLE_GROW,
    277   WASM_INSN_TABLE_SIZE,
    278   WASM_INSN_TABLE_FILL,
    279 } WasmInsnKind;
    280 
    281 typedef struct WasmInsn {
    282   KitSrcLoc loc;
    283   uint8_t kind;
    284   uint8_t type;
    285   int64_t imm;
    286   double fp;
    287   uint32_t align;
    288   uint32_t memidx;
    289   uint64_t offset64;
    290   /* Secondary index slot for opcodes with two index immediates: memory.copy
    291    * (src memidx), table.init (tableidx), table.copy (src tableidx). */
    292   uint32_t aux_idx;
    293   /* br_table branch depths: targets[0..ntargets-1], the last being the
    294    * default. Heap-owned (m->heap), sized exactly ntargets, freed with the
    295    * function. A pointer rather than an inline array so a switch's jump table
    296    * can hold an arbitrary number of cases without bloating every other
    297    * instruction. Set via wasm_insn_set_targets. */
    298   uint32_t ntargets;
    299   uint32_t* targets;
    300 } WasmInsn;
    301 
    302 typedef struct WasmFunc {
    303   KitSrcLoc loc;
    304   char* name;
    305   uint32_t typeidx;
    306   int has_typeidx;
    307   int is_import;
    308   char* import_module;
    309   char* import_name;
    310   /* params/locals/local_names are heap-grown — no fixed limit. params holds
    311    * one WasmValType per function parameter (size = nparams, capacity =
    312    * cap_params); locals holds one WasmValType per declared local (size =
    313    * nlocals, capacity = cap_locals); local_names is a sparse array indexed by
    314    * wasm-local index (0..nparams+nlocals-1) and capacity-tracked separately. */
    315   WasmValType* params;
    316   uint32_t nparams;
    317   uint32_t cap_params;
    318   WasmValType* locals;
    319   uint32_t nlocals;
    320   uint32_t cap_locals;
    321   char** local_names;
    322   uint32_t cap_local_names;
    323   WasmValType results[1];
    324   uint32_t nresults;
    325   char* export_name;
    326   WasmInsn* insns;
    327   uint32_t ninsns;
    328   uint32_t cap_insns;
    329 } WasmFunc;
    330 
    331 typedef struct WasmFuncType {
    332   char* name;
    333   WasmValType* params;
    334   uint32_t nparams;
    335   uint32_t cap_params;
    336   WasmValType results[1];
    337   uint32_t nresults;
    338 } WasmFuncType;
    339 
    340 typedef struct WasmMemory {
    341   char* name;
    342   uint64_t min_pages;
    343   uint64_t max_pages;
    344   int has_max;
    345   int is64;
    346   int shared;
    347   int is_import;
    348   char* import_module;
    349   char* import_name;
    350   char* export_name;
    351 } WasmMemory;
    352 
    353 typedef enum WasmSegmentMode {
    354   WASM_SEG_ACTIVE = 0,
    355   WASM_SEG_PASSIVE = 1,
    356   WASM_SEG_DECLARATIVE = 2, /* element segments only */
    357 } WasmSegmentMode;
    358 
    359 /* A data segment carries an immutable byte buffer plus its placement mode.
    360  * Active segments are copied into memory `memidx` at constant offset `offset`
    361  * at module instantiation. Passive segments are sources for `memory.init` and
    362  * are otherwise inert until `data.drop` permanently zero-lengths them. */
    363 typedef struct WasmDataSegment {
    364   uint8_t mode;    /* WasmSegmentMode */
    365   uint32_t memidx; /* meaningful when mode == WASM_SEG_ACTIVE */
    366   int64_t offset;  /* active offset; signed to allow caller-relative builds */
    367   char* name;      /* optional WAT `$name`, NULL otherwise */
    368   uint8_t* bytes;
    369   uint64_t nbytes;
    370 } WasmDataSegment;
    371 
    372 typedef struct WasmTable {
    373   char* name;
    374   WasmValType elem_type;
    375   uint32_t min;
    376   uint32_t max;
    377   int has_max;
    378   int is_import;
    379   char* import_module;
    380   char* import_name;
    381   char* export_name;
    382 } WasmTable;
    383 
    384 typedef struct WasmGlobal {
    385   KitSrcLoc loc;
    386   char* name;
    387   WasmValType type;
    388   uint8_t mutable_;
    389   WasmInsn init;
    390   int is_import;
    391   char* import_module;
    392   char* import_name;
    393   char* export_name;
    394 } WasmGlobal;
    395 
    396 typedef struct WasmElemSegment {
    397   uint8_t mode;          /* WasmSegmentMode */
    398   WasmValType elem_type; /* funcref/externref/typed-funcref */
    399   uint32_t tableidx;     /* meaningful when mode == WASM_SEG_ACTIVE */
    400   int64_t offset;        /* active offset */
    401   char* name;            /* optional WAT `$name`, NULL otherwise */
    402   uint32_t* funcs;       /* heap-grown; each slot is a function index */
    403   uint32_t nfuncs;
    404   uint32_t cap_funcs;
    405 } WasmElemSegment;
    406 
    407 typedef struct WasmExport {
    408   char* name;
    409   uint8_t kind;
    410   uint32_t index;
    411 } WasmExport;
    412 
    413 typedef struct WasmCustom {
    414   char* name;
    415   uint8_t* data;
    416   uint32_t len;
    417 } WasmCustom;
    418 
    419 typedef struct WasmModule {
    420   KitHeap* heap;
    421   uint32_t file_id;
    422   KitSrcLoc current_loc;
    423   KitSrcLoc start_field_loc;
    424   WasmFuncType* types;
    425   uint32_t ntypes;
    426   uint32_t cap_types;
    427   WasmFunc* funcs;
    428   uint32_t nfuncs;
    429   uint32_t cap_funcs;
    430   WasmMemory* memories;
    431   uint32_t nmemories;
    432   uint32_t cap_memories;
    433   WasmTable* tables;
    434   uint32_t ntables;
    435   uint32_t cap_tables;
    436   WasmGlobal* globals;
    437   uint32_t nglobals;
    438   uint32_t cap_globals;
    439   WasmElemSegment* elems;
    440   uint32_t nelems;
    441   uint32_t cap_elems;
    442   WasmDataSegment* data;
    443   uint32_t ndata;
    444   uint32_t cap_data;
    445   WasmExport* exports;
    446   uint32_t nexports;
    447   uint32_t cap_exports;
    448   WasmCustom* customs;
    449   uint32_t ncustoms;
    450   uint32_t cap_customs;
    451   uint32_t start_func;
    452   int has_start;
    453   int has_target_features;
    454   uint32_t features;
    455 } WasmModule;
    456 
    457 KitSrcLoc wasm_loc(uint32_t line, uint32_t col);
    458 void wasm_error(KitCompiler* c, KitSrcLoc loc, const char* fmt, ...);
    459 void* wasm_realloc(KitHeap* h, void* p, size_t old_n, size_t new_n);
    460 char* wasm_strdup(KitHeap* h, const char* s, size_t len);
    461 void wasm_free_str(KitHeap* h, char** s);
    462 
    463 void wasm_module_init(WasmModule* m, KitHeap* heap);
    464 void wasm_module_free(WasmModule* m);
    465 WasmMemory* wasm_add_memory(KitCompiler* c, WasmModule* m);
    466 WasmFunc* wasm_add_func(KitCompiler* c, WasmModule* m);
    467 WasmFuncType* wasm_add_type(KitCompiler* c, WasmModule* m);
    468 uint32_t wasm_intern_func_type(KitCompiler* c, WasmModule* m,
    469                                const WasmFunc* f);
    470 WasmTable* wasm_add_table(KitCompiler* c, WasmModule* m);
    471 WasmGlobal* wasm_add_global(KitCompiler* c, WasmModule* m);
    472 WasmElemSegment* wasm_add_elem(KitCompiler* c, WasmModule* m);
    473 WasmDataSegment* wasm_add_data(KitCompiler* c, WasmModule* m);
    474 /* Append a function index to an element segment, growing as needed. */
    475 void wasm_elem_push_func(KitCompiler* c, WasmModule* m, WasmElemSegment* e,
    476                          uint32_t funcidx);
    477 /* Set/append a data segment's byte buffer. Copies `n` bytes from `src`. */
    478 void wasm_data_set_bytes(KitCompiler* c, WasmModule* m, WasmDataSegment* d,
    479                          const uint8_t* src, uint64_t n);
    480 WasmExport* wasm_add_export(KitCompiler* c, WasmModule* m);
    481 WasmCustom* wasm_add_custom(KitCompiler* c, WasmModule* m);
    482 /* Push a single parameter type onto a WasmFunc's signature, growing the
    483  * underlying array as needed. Returns the new parameter's wasm-local index. */
    484 uint32_t wasm_func_push_param(KitCompiler* c, WasmModule* m, WasmFunc* f,
    485                               WasmValType vt);
    486 /* Push a single declared local onto a WasmFunc. Returns the new local's
    487  * wasm-local index (i.e., nparams + (nlocals-1) after the push). */
    488 uint32_t wasm_func_push_local(KitCompiler* c, WasmModule* m, WasmFunc* f,
    489                               WasmValType vt);
    490 /* Bulk-set the params array from a source buffer. Reuses existing capacity
    491  * when possible; otherwise grows. */
    492 void wasm_func_set_params(KitCompiler* c, WasmModule* m, WasmFunc* f,
    493                           const WasmValType* src, uint32_t n);
    494 /* Assign a name to wasm-local index `idx`, growing local_names as needed.
    495  * `idx` may be any value < nparams + nlocals (or any future index the caller
    496  * intends to fill before encoding). */
    497 void wasm_func_set_local_name(KitCompiler* c, WasmModule* m, WasmFunc* f,
    498                               uint32_t idx, const char* name, size_t len);
    499 /* Push a single parameter type onto a WasmFuncType, growing as needed. */
    500 uint32_t wasm_type_push_param(KitCompiler* c, WasmModule* m, WasmFuncType* t,
    501                               WasmValType vt);
    502 
    503 void wasm_func_add_insn(KitCompiler* c, WasmModule* m, WasmFunc* f,
    504                         WasmInsnKind kind, int64_t imm);
    505 void wasm_func_add_mem_insn(KitCompiler* c, WasmModule* m, WasmFunc* f,
    506                             WasmInsnKind kind, uint32_t align, uint64_t offset,
    507                             uint32_t memidx);
    508 void wasm_func_add_fp_insn(KitCompiler* c, WasmModule* m, WasmFunc* f,
    509                            WasmInsnKind kind, double value);
    510 /* Replace `in`'s br_table target vector with a heap-owned copy of
    511  * `targets[0..ntargets)` (allocated from m->heap, freed with the function).
    512  * Any previous vector is released first. */
    513 void wasm_insn_set_targets(KitCompiler* c, WasmModule* m, WasmInsn* in,
    514                            const uint32_t* targets, uint32_t ntargets);
    515 
    516 int wasm_is_num_type(WasmValType vt);
    517 int wasm_is_ref_type(WasmValType vt);
    518 int wasm_is_frontend_value_type(WasmValType vt);
    519 int wasm_feature_enabled(const WasmModule* m, WasmFeatureSet feature);
    520 void wasm_require_feature(KitCompiler* c, const WasmModule* m,
    521                           WasmFeatureSet feature, const char* feature_name,
    522                           const char* what);
    523 int wasm_insn_is_load(WasmInsnKind kind);
    524 int wasm_insn_is_store(WasmInsnKind kind);
    525 int wasm_insn_is_atomic_load(WasmInsnKind kind);
    526 int wasm_insn_is_atomic_store(WasmInsnKind kind);
    527 int wasm_insn_is_atomic_rmw(WasmInsnKind kind);
    528 int wasm_insn_is_atomic_cmpxchg(WasmInsnKind kind);
    529 int wasm_insn_is_atomic_wait_notify(WasmInsnKind kind);
    530 int wasm_insn_is_atomic_mem(WasmInsnKind kind);
    531 int wasm_insn_is_mem(WasmInsnKind kind);
    532 /* WAT mnemonic for an instruction kind (e.g. "i32.add"); never NULL. */
    533 const char* wasm_insn_mnemonic(WasmInsnKind kind);
    534 WasmValType wasm_func_local_type(const WasmFunc* f, uint32_t index);
    535 uint32_t wasm_mem_width(uint8_t kind);
    536 int wasm_int_cmp_op(uint8_t kind, KitCgIntCmpOp* out);
    537 WasmValType wasm_load_result_type(uint8_t kind);
    538 WasmValType wasm_store_value_type(uint8_t kind);
    539 WasmValType wasm_atomic_value_type(uint8_t kind);
    540 KitCgAtomicOp wasm_atomic_rmw_op(uint8_t kind);
    541 int wasm_int_unop_kind(uint8_t kind, WasmValType* vt);
    542 int wasm_fp_unop_kind(uint8_t kind, WasmValType* vt);
    543 int wasm_fp_binop_kind(uint8_t kind, WasmValType* vt);
    544 int wasm_fp_cmp_kind(uint8_t kind, WasmValType* vt);
    545 int wasm_conversion_kind(uint8_t kind, WasmValType* src, WasmValType* dst);
    546 
    547 void wasm_parse_wat(KitCompiler* c, KitSlice name, const KitSlice* input,
    548                     WasmModule* out);
    549 /* Parses a sequence of WAT instructions (no (module ...) / (func ...) wrapper)
    550  * into the caller-supplied WasmFunc. The function must already have its
    551  * params/results/locals filled in. Direct (call $name) references resolve
    552  * against m->funcs[].name. Diagnostics are routed through KitCompiler. */
    553 void wasm_parse_wat_body(KitCompiler* c, WasmModule* m, WasmFunc* f,
    554                          const char* src, size_t len, KitSrcLoc loc);
    555 void wasm_decode_binary(KitCompiler* c, const KitSlice* input, WasmModule* out);
    556 /* Decode one instruction from data[pos..] into *out; returns bytes consumed (0
    557  * if none). `scratch` is a caller-owned reusable module (wasm_module_init) used
    558  * as an allocation-free decode buffer. Shares the opcode mapping with
    559  * wasm_decode_binary. Used by the disassembler. */
    560 size_t wasm_decode_one_insn(KitCompiler* c, WasmModule* scratch,
    561                             const uint8_t* data, size_t len, size_t pos,
    562                             WasmInsn* out);
    563 int wasm_is_binary(const KitSlice* input);
    564 void wasm_validate(WasmModule* m, KitCompiler* c);
    565 /* Validate a single function under the typed operand/control stack rules.
    566  * Used by wasm_validate and by callers that synthesize scratch functions
    567  * (e.g. the wasm-target inline-asm path). */
    568 void wasm_validate_func(KitCompiler* c, WasmModule* m, WasmFunc* f);
    569 void wasm_emit_cg_into(KitCompiler* c, KitCg* cg, const WasmModule* m);
    570 void wasm_emit_cg(KitCompiler* c, const KitCodeOptions* code_opts,
    571                   KitObjBuilder* out, const WasmModule* m);
    572 void wasm_encode(KitCompiler* c, const WasmModule* m, KitWriter* out);
    573 
    574 #endif