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