diff options
| author | Xavier Del Campo Romero <xavi.dcr@tutanota.com> | 2024-09-07 00:04:38 +0200 |
|---|---|---|
| committer | Xavier Del Campo Romero <xavi92@disroot.org> | 2025-11-06 14:38:40 +0100 |
| commit | 6d9d80362f9932bbc87e162b8ef7df06c73e27e1 (patch) | |
| tree | e3e228c63fe26f07503f226de7fb5086b3dc2286 /include | |
| download | nanowasm-6d9d80362f9932bbc87e162b8ef7df06c73e27e1.tar.gz | |
First commit
Diffstat (limited to 'include')
| -rw-r--r-- | include/nanowasm/dbg.h | 33 | ||||
| -rw-r--r-- | include/nanowasm/linear.h | 20 | ||||
| -rw-r--r-- | include/nanowasm/nw.h | 32 | ||||
| -rw-r--r-- | include/nanowasm/private.h | 675 | ||||
| -rw-r--r-- | include/nanowasm/types.h | 180 |
5 files changed, 940 insertions, 0 deletions
diff --git a/include/nanowasm/dbg.h b/include/nanowasm/dbg.h new file mode 100644 index 0000000..010a5c8 --- /dev/null +++ b/include/nanowasm/dbg.h @@ -0,0 +1,33 @@ +/* + * nanowasm, a tiny WebAssembly/Wasm interpreter + * Copyright (C) 2023-2025 Xavier Del Campo Romero + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#ifndef NW_DBG_H +#define NW_DBG_H + +#include <nanowasm/types.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + +void nw_dbg_init(struct nw_dbg *d, const struct nw_dbg_cfg *cfg); +void nw_dbg_local(struct nw_dbg *d, unsigned long index); +void nw_dbg_param(struct nw_dbg *d, unsigned long index); +void nw_dbg_global(struct nw_dbg *d, unsigned long index); +void nw_dbg_mem_load(struct nw_dbg *d, enum nw_type t, unsigned long offset); +void nw_dbg_bt(struct nw_dbg *d, unsigned depth); +int nw_dbg_value(const struct nw_dbg *d, struct nw_dbg_value *v); +int nw_dbg_pc(const struct nw_dbg *d, long *pc); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/nanowasm/linear.h b/include/nanowasm/linear.h new file mode 100644 index 0000000..71abf1c --- /dev/null +++ b/include/nanowasm/linear.h @@ -0,0 +1,20 @@ +/* + * nanowasm, a tiny WebAssembly/Wasm interpreter + * Copyright (C) 2023-2025 Xavier Del Campo Romero + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#ifndef NW_LINEAR_H +#define NW_LINEAR_H + +#include <nanowasm/types.h> + +enum nw_state nw_linear_load(struct nw_inst *i, struct nw_sm_io *io, + unsigned long offset); +enum nw_state nw_linear_store(struct nw_inst *i, struct nw_sm_io *io, + unsigned long offset); + +#endif diff --git a/include/nanowasm/nw.h b/include/nanowasm/nw.h new file mode 100644 index 0000000..093fa21 --- /dev/null +++ b/include/nanowasm/nw.h @@ -0,0 +1,32 @@ +/* + * nanowasm, a tiny WebAssembly/Wasm interpreter + * Copyright (C) 2023-2025 Xavier Del Campo Romero + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#ifndef NW_H +#define NW_H + +#include <nanowasm/types.h> +#include <nanowasm/linear.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + +void nw_init(struct nw_mod *m, const struct nw_mod_cfg *cfg); +enum nw_state nw_load(struct nw_mod *m, struct nw_mod_out *out); +int nw_start(struct nw_inst *i, const struct nw_inst_cfg *icfg); +enum nw_state nw_run(struct nw_inst *i); +const char *nw_lexc(const struct nw_mod *m); +const char *nw_rexc(const struct nw_inst *i); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/nanowasm/private.h b/include/nanowasm/private.h new file mode 100644 index 0000000..60fe383 --- /dev/null +++ b/include/nanowasm/private.h @@ -0,0 +1,675 @@ +/* + * nanowasm, a tiny WebAssembly/Wasm interpreter + * Copyright (C) 2023-2025 Xavier Del Campo Romero + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#ifndef NANOWASM_PRIVATE_H +#define NANOWASM_PRIVATE_H + +#if !defined(NW_H) && !defined(NW_TYPES_H) +#error Do not #include <nanowasm/private.h> directly. \ + Please either #include <nanowasm/nw.h> or <nanowasm/types.h> +#endif + +#include <stddef.h> + +typedef signed char nw_varint1; +typedef unsigned char nw_varuint1; +typedef signed char nw_varint7; +typedef unsigned char nw_varuint7; +typedef unsigned long nw_varuint32; +typedef long nw_varint32; +typedef struct nw_ull nw_varuint64; +typedef struct nw_ll nw_varint64; + +struct nw_interp; + +enum +{ + NW_SECTION_CUSTOM, + NW_SECTION_TYPE, + NW_SECTION_IMPORT, + NW_SECTION_FUNCTION, + NW_SECTION_TABLE, + NW_SECTION_MEMORY, + NW_SECTION_GLOBAL, + NW_SECTION_EXPORT, + NW_SECTION_START, + NW_SECTION_ELEMENT, + NW_SECTION_CODE, + NW_SECTION_DATA, + NW_SECTION_DATA_COUNT, + + NW_SECTIONS +}; + +enum +{ + NW_CUSTOM_TO, + NW_CUSTOM_FTI, + NW_CUSTOM_FBO, + NW_CUSTOM_LO, + NW_CUSTOM_ITI, + + NW_CUSTOM_SECTIONS +}; + +struct nw_sm_leb128 +{ + unsigned shift, bcnt; + struct nw_ull result; +}; + +struct nw_leuint32 +{ + unsigned char v[4]; +}; + +struct nw_leuint64 +{ + unsigned char v[8]; +}; + +struct nw_global +{ + nw_varuint1 mutability; + enum nw_type type; + union nw_value value; +}; + +struct nw_table +{ + unsigned long initial, max; + unsigned char data; +}; + +struct nw_return +{ + nw_varuint1 count; + enum nw_type type; +}; + +struct nw_fn +{ + nw_varuint32 index, param_count; + long param_types; + struct nw_return ret; +}; + +struct nw_frame +{ + nw_varuint32 local_count, body_size, block_i; + struct nw_fn fn; + struct nw_return prev_ret; + int child; + unsigned char prev_op; + size_t fr_start, local_start, local_end; + long start, pc; +}; + +struct nw_local_meta +{ + nw_varuint32 entry_count; + enum nw_type type; +}; + +struct nw_find_local +{ + nw_varuint32 index, entry_i; + struct nw_sm_io io; + struct nw_local_meta meta; + size_t addr; + enum nw_state (*next)(struct nw_interp *); +}; + +struct nw_find_param +{ + const struct nw_fn *fn; + struct nw_sm_leb128 leb128; + struct nw_sm_io io; + long pc; + nw_varuint32 index, param_i; + size_t sz; + enum nw_state (*next)(struct nw_interp *); + + struct nw_find_param_out + { + enum nw_type type; + size_t addr; + } out; +}; + +struct nw_get_import_type +{ + nw_varuint32 index; + struct nw_sm_io io; + struct nw_leuint32 value; + unsigned char kind; + enum nw_state (*next)(struct nw_interp *); + + struct nw_get_import_type_out + { + enum nw_kind kind; + } out; +}; + +union nw_i_sm +{ + struct nw_i_sm_b + { + unsigned char op; + struct nw_sm_io io; + struct nw_next next; + long pc; + void (*f)(struct nw_interp *); + } bytecode; + + struct nw_i_sm_unreachable + { + long offset; + } unreachable; + + struct nw_i_sm_i32_const + { + nw_varint32 value; + struct nw_sm_leb128 leb128; + struct nw_sm_io io; + } i32_const; + + struct nw_i_sm_i64_const + { + nw_varuint64 value; + struct nw_sm_leb128 leb128; + struct nw_sm_io io; + } i64_const; + + struct nw_i_sm_exp + { + enum nw_kind kind; + struct nw_sm_leb128 leb128; + nw_varuint32 count, entry_i, len, len_i; + const char *sym; + nw_varuint32 index; + long offset; + enum nw_state (*next)(struct nw_interp *); + } export; + + struct nw_i_sm_type + { + long pc; + struct nw_sm_io io; + struct nw_sm_leb128 leb128; + nw_varuint32 param_i, fn_index; + struct nw_leuint32 fti, to; + struct nw_get_import_type git; + enum nw_state (*next)(struct nw_interp *); + struct nw_fn out; + } type; + + struct nw_i_sm_ffn + { + void (*next)(struct nw_interp *); + struct nw_sm_io io; + struct nw_fn fn; + struct nw_leuint32 fbo; + } ffn; + + struct nw_i_sm_pl + { + long body_start; + struct nw_sm_leb128 leb128; + struct nw_sm_io io; + struct nw_frame fr; + nw_varuint32 param_i, local_i, local_count, entry_i; + union nw_value value; + enum nw_type type; + struct nw_local_meta meta; + } pl; + + struct nw_i_sm_sb + { + void (*next)(struct nw_interp *); + struct nw_sm_leb128 leb128; + struct nw_sm_io io; + } start_block; + + struct nw_i_sm_imm + { + void (*next)(struct nw_interp *); + struct nw_sm_leb128 leb128; + + struct nw_i_sm_imm_out + { + nw_varuint32 flags, offset; + } out; + } imm; + + struct nw_i_sm_load + { + unsigned long addr; + struct nw_sm_io io; + struct nw_i_sm_imm_out imm; + + union + { + char i8; + long i32; + struct nw_ll i64; + float f32; + double f64; + struct nw_leuint32 v32; + } value; + } load; + + struct nw_i_sm_store + { + unsigned long addr; + struct nw_sm_io io; + struct nw_i_sm_imm_out imm; + + union + { + long i32; + struct nw_ull i64; + float f32; + double f64; + struct nw_leuint32 v32; + struct nw_leuint64 v64; + } value; + } store; + + struct nw_i_sm_br + { + nw_varuint32 relative_depth; + struct nw_sm_leb128 leb128; + struct nw_sm_io io; + } br; + + struct nw_i_sm_br_if + { + nw_varuint32 relative_depth; + struct nw_sm_leb128 leb128; + struct nw_sm_io io; + union nw_value condition; + } br_if; + + struct nw_i_sm_call + { + nw_varuint32 index; + struct nw_sm_leb128 leb128; + } call; + + struct nw_i_sm_call_indirect + { + nw_varuint32 index, value; + struct nw_sm_leb128 leb128; + } call_indirect; + + struct nw_i_sm_end + { + long offset; + struct nw_sm_leb128 leb128; + } end; + + struct nw_i_sm_unwind + { + nw_varuint32 pending, entry_i; + size_t sz; + struct nw_sm_io io; + struct nw_sm_leb128 leb128; + struct nw_frame fr; + union nw_value retval, value; + struct nw_find_local fl; + } unwind; + + struct nw_i_sm_set_global + { + nw_varuint32 index; + struct nw_sm_leb128 leb128; + struct nw_sm_io io; + struct nw_global gl; + } set_global; + + struct nw_i_sm_get_global + { + nw_varuint32 index; + struct nw_sm_leb128 leb128; + struct nw_sm_io io; + struct nw_global gl; + } get_global; + + struct nw_i_sm_set_local + { + nw_varuint32 index; + struct nw_sm_leb128 leb128; + struct nw_sm_io io; + enum nw_state (*next)(struct nw_interp *); + + union + { + struct nw_find_local l; + struct nw_find_param p; + } f; + + struct nw_i_sm_set_local_out + { + union nw_value value; + enum nw_type type; + } out; + } set_local; + + struct nw_i_sm_tee_local + { + struct nw_sm_io io; + struct nw_i_sm_set_local_out in; + } tee_local; + + struct nw_i_sm_get_local + { + nw_varuint32 index; + struct nw_sm_leb128 leb128; + struct nw_sm_io io; + + union + { + struct nw_find_local l; + struct nw_find_param p; + } f; + + union nw_value value; + enum nw_type type; + } get_local; + + struct nw_i_sm_break + { + nw_varuint32 relative_depth, label_i; + struct nw_sm_io io; + long pc, lo; + struct nw_leuint32 offset, lpc, dst, n; + } brk; + + struct nw_i_sm_arithm + { + enum nw_type type; + struct nw_sm_io io; + union nw_value value; + + struct nw_i_sm_arithm_out + { + union nw_value left, right; + } out; + + int (*op)(const struct nw_i_sm_arithm_out *, union nw_value *); + } arithm; + + struct nw_i_sm_unary + { + enum nw_type type; + struct nw_sm_io io; + union nw_value in, out; + int (*op)(const union nw_value *, union nw_value *); + } unary; + + struct nw_i_sm_drop + { + struct nw_sm_io io; + union nw_value value; + } drop; + + struct nw_i_sm_call_import + { + enum nw_type type; + nw_varuint32 type_i, param_i; + struct nw_sm_leb128 leb128; + struct nw_sm_io io; + struct nw_fn fn; + struct nw_next next; + union nw_value value; + long pc; + size_t addr, sz; + const struct nw_import *imp; + } call_import; +}; + +struct nw_interp +{ + const void *set; + const char *exception; + int exit; + int retval; + struct nw_interp_cfg cfg; + enum nw_state (*next)(struct nw_interp *); + struct nw_frame fr; + union nw_i_sm sm; + void *state, *args; + enum nw_type push_type; + + struct + { + nw_varuint32 n_pages; + } linear, table; +}; + +union nw_sm +{ + struct nw_sm_cm + { + unsigned char buf[sizeof "\0asm" - 1]; + struct nw_sm_io io; + } check_magic; + + struct nw_sm_cv + { + unsigned char version[sizeof (struct nw_leuint32)]; + struct nw_sm_io io; + } check_version; + + struct nw_sm_st + { + nw_varuint32 entry_i, param_count, p_i; + struct nw_sm_leb128 leb128; + } type; + + struct nw_sm_imp + { + long mod_off, field_off; + nw_varuint32 entry_i, mod_len, field_len, len_i, imp_i; + struct nw_sm_leb128 leb128; + } import; + + struct nw_sm_fn + { + nw_varuint32 entry_i; + struct nw_sm_leb128 leb128; + } function; + + struct nw_sm_tb + { + nw_varuint32 count, entry_i; + nw_varint7 elem_type; + nw_varuint1 flags; + size_t out_sz; + struct nw_sm_leb128 leb128; + } table; + + struct nw_sm_mem + { + nw_varuint32 count; + nw_varuint1 flags; + struct nw_sm_leb128 leb128; + } memory; + + struct nw_sm_gl + { + nw_varuint32 entry_i; + struct nw_sm_leb128 leb128; + struct nw_interp interp; + union nw_value value; + } global; + + struct nw_sm_d + { + nw_varuint32 entry_i, index, size; + struct nw_sm_leb128 leb128; + struct nw_interp interp; + long value, offset; + } data; + + struct nw_sm_dc + { + struct nw_sm_leb128 leb128; + } data_count; + + struct nw_sm_exp + { + nw_varuint32 count, entry_i, field_len, len_i; + struct nw_sm_io io; + struct nw_sm_leb128 leb128; + } export; + + struct nw_sm_start + { + struct nw_sm_leb128 leb128; + } start; + + struct nw_sm_c + { + nw_varuint32 count, entry_i, body_size; + struct nw_sm_leb128 leb128; + struct nw_sm_io io; + long start, body_start, op_off; + unsigned long rem; + enum nw_state (*next)(struct nw_mod *); + unsigned char op; + + union + { + unsigned long f32; + struct nw_ull f64; + + struct nw_sm_c_t + { + nw_varuint32 count, i; + } target; + } u; + + struct nw_sm_c_fn + { + nw_varuint32 local_count, local_i, local_total; + unsigned blocks; + } fn; + } code; + + struct nw_sm_custom + { + nw_varuint32 name_len, len_i; + struct nw_sm_leb128 leb128; + unsigned char byte; + int candidate[NW_CUSTOM_SECTIONS]; + long start; + } custom; + + struct nw_sm_lo + { + struct nw_sm_io io; + } lo; +}; + +struct nw_mod +{ + nw_varuint32 type_count, data_count, global_count, import_count, + function_count; + long sections[NW_SECTIONS], c_sections[NW_CUSTOM_SECTIONS]; + enum nw_state (*next)(struct nw_mod *); + struct nw_mod_cfg cfg; + union nw_sm sm; + struct nw_mod_out out; + const char *exception; + + struct nw_mod_section + { + nw_varuint7 section; + nw_varuint32 len; + long offset, cur; + struct nw_sm_leb128 leb128; + } section; +}; + +struct nw_inst; + +union nw_inst_sm +{ + struct nw_inst_sm_gl + { + nw_varuint32 count, entry_i; + struct nw_sm_leb128 leb128; + struct nw_sm_io io; + struct nw_global out; + enum nw_state (*next)(struct nw_inst *); + } global; + + struct nw_inst_sm_d + { + char b; + nw_varuint32 count, index, size, entry_i, bytes_i; + struct nw_sm_leb128 leb128; + struct nw_sm_io io; + struct nw_global out; + unsigned long offset; + enum nw_state (*next)(struct nw_inst *); + } data; +}; + +struct nw_inst +{ + const char *entry; + struct nw_interp interp; + union nw_inst_sm sm; + enum nw_state (*next)(struct nw_inst *); +}; + +union nw_dbg_sm +{ + struct nw_dbg_sm_local + { + struct nw_sm_io io; + struct nw_find_local fl; + enum nw_state (*inext)(struct nw_interp *); + } local; + + struct nw_dbg_sm_param + { + struct nw_sm_io io; + struct nw_find_param fp; + enum nw_state (*inext)(struct nw_interp *); + } param; + + struct nw_dbg_sm_global + { + struct nw_sm_io io; + unsigned long index; + struct nw_global gl; + enum nw_state (*inext)(struct nw_interp *); + } global; + + struct nw_dbg_sm_mem_load + { + struct nw_sm_io io; + unsigned long offset; + enum nw_state (*inext)(struct nw_interp *); + } mem_load; +}; + +struct nw_dbg +{ + long pc; + struct nw_dbg_cfg cfg; + struct nw_dbg_value v; + union nw_dbg_sm sm; +}; + +#endif diff --git a/include/nanowasm/types.h b/include/nanowasm/types.h new file mode 100644 index 0000000..23cd4fa --- /dev/null +++ b/include/nanowasm/types.h @@ -0,0 +1,180 @@ +/* + * nanowasm, a tiny WebAssembly/Wasm interpreter + * Copyright (C) 2023-2025 Xavier Del Campo Romero + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#ifndef NW_TYPES_H +#define NW_TYPES_H + +#include <stddef.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + +struct nw_inst; + +enum nw_state +{ + NW_OK, + NW_AGAIN, + NW_FATAL +}; + +enum nw_kind +{ + NW_KIND_FUNCTION, + NW_KIND_TABLE, + NW_KIND_MEMORY, + NW_KIND_GLOBAL, + + NW_KINDS +}; + +struct nw_ull +{ + unsigned long low, hi; +}; + +struct nw_ll +{ + long low, hi; +}; + +union nw_value +{ + long i32; + struct nw_ll i64; + float f32; + double f64; +}; + +enum nw_type +{ + NW_TYPE_I32, + NW_TYPE_I64, + NW_TYPE_F32, + NW_TYPE_F64 +}; + +struct nw_args +{ + const union nw_value *args; + size_t n; +}; + +struct nw_next +{ + enum nw_state (*fn)(void *args, struct nw_next *next); + void *user; +}; + +struct nw_io_cfg +{ + int (*read)(void *buf, size_t n, void *user); + int (*eof)(void *user); + enum nw_state (*pc)(long offset, struct nw_next * next, void *user); + enum nw_state (*seek)(long offset, void *user); + enum nw_state (*tell)(long *offset, void *user); + void *user; +}; + +struct nw_sm_io +{ + void *buf; + size_t n, read; +}; + +struct nw_import +{ + enum nw_kind kind; + const char *module, *field; + + union + { + struct nw_import_fn + { + const char *signature; + enum nw_state (*fn)(const union nw_value *params, + union nw_value *ret, void *user, struct nw_next *next); + } function; + } u; +}; + +struct nw_import_index +{ + unsigned long index; +}; + +struct nw_mod_cfg +{ + const struct nw_import *imports; + struct nw_import_index *imp_indexes; + struct nw_io_cfg io; + size_t n_imports; +}; + +struct nw_interp_cfg +{ + size_t n_args; + void *user; + + struct nw_mem_cfg + { + int (*load)(unsigned long pos, void *src, size_t n, void *user); + int (*store)(unsigned long pos, const void *src, size_t n, void *user); + } global, linear, table; + + struct nw_fifo_cfg + { + int (*push)(const void *src, size_t n, void *user); + int (*pop)(void *dst, size_t n, void *user); + int (*read)(size_t offset, void *dst, size_t n, void *user); + int (*write)(size_t offset, const void *dst, size_t n, void *user); + size_t (*ptr)(void *user); + } stack; + + struct nw_io_cfg io; + const struct nw_mod *m; + union nw_value *args; +}; + +struct nw_inst_cfg +{ + const char *entry; + struct nw_interp_cfg interp_cfg; +}; + +struct nw_mod_out +{ + struct nw_mod_out_mem + { + unsigned long initial, max; + } linear, table; + + size_t global; +}; + +struct nw_dbg_cfg +{ + struct nw_inst *inst; +}; + +struct nw_dbg_value +{ + enum nw_type type; + union nw_value value; +}; + +#include <nanowasm/private.h> + +#ifdef __cplusplus +} +#endif + +#endif |
