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 /src/op/check | |
| download | nanowasm-6d9d80362f9932bbc87e162b8ef7df06c73e27e1.tar.gz | |
First commit
Diffstat (limited to 'src/op/check')
| -rw-r--r-- | src/op/check/CMakeLists.txt | 24 | ||||
| -rw-r--r-- | src/op/check/block.c | 43 | ||||
| -rw-r--r-- | src/op/check/br_table.c | 78 | ||||
| -rw-r--r-- | src/op/check/call.c | 40 | ||||
| -rw-r--r-- | src/op/check/end.c | 36 | ||||
| -rw-r--r-- | src/op/check/global_index.c | 40 | ||||
| -rw-r--r-- | src/op/check/i64_const.c | 32 | ||||
| -rw-r--r-- | src/op/check/local_index.c | 43 | ||||
| -rw-r--r-- | src/op/check/memory_immediate.c | 47 | ||||
| -rw-r--r-- | src/op/check/misc.c | 34 | ||||
| -rw-r--r-- | src/op/check/no_immediate.c | 23 | ||||
| -rw-r--r-- | src/op/check/relative_depth.c | 40 | ||||
| -rw-r--r-- | src/op/check/uint32.c | 36 | ||||
| -rw-r--r-- | src/op/check/uint64.c | 36 | ||||
| -rw-r--r-- | src/op/check/varint32.c | 32 | ||||
| -rw-r--r-- | src/op/check/varuint1.c | 32 |
16 files changed, 616 insertions, 0 deletions
diff --git a/src/op/check/CMakeLists.txt b/src/op/check/CMakeLists.txt new file mode 100644 index 0000000..0745eb5 --- /dev/null +++ b/src/op/check/CMakeLists.txt @@ -0,0 +1,24 @@ +# 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/. + +target_sources(${PROJECT_NAME} PRIVATE + block.c + br_table.c + call.c + end.c + global_index.c + i64_const.c + local_index.c + memory_immediate.c + misc.c + no_immediate.c + relative_depth.c + varint32.c + varuint1.c + uint32.c + uint64.c +) diff --git a/src/op/check/block.c b/src/op/check/block.c new file mode 100644 index 0000000..7d5176e --- /dev/null +++ b/src/op/check/block.c @@ -0,0 +1,43 @@ +/* + * 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/. + */ + +#include <nanowasm/nw.h> +#include <nw/io.h> +#include <nw/log.h> +#include <nw/ops.h> +#include <nw/types.h> + +static enum nw_state get_type(struct nw_mod *const m) +{ + nw_varint7 type; + const struct nw_io_cfg *const cfg = &m->cfg.io; + struct nw_sm_c *const c = &m->sm.code; + struct nw_sm_leb128 *const l = &c->leb128; + const enum nw_state n = nwp_varint7(cfg, l, &type, cfg->user); + enum nw_type t; + + if (n) + return n; + else if (nwp_get_type(type, &t) && type != 0x40) + { +#ifdef NW_LOG + nwp_log("invalid block_type %#x\n", (unsigned)type); +#endif + return NW_FATAL; + } + + c->fn.blocks++; + m->next = m->sm.code.next; + return NW_AGAIN; +} + +void nwp_op_check_block(struct nw_mod *const m) +{ + m->next = get_type; +} diff --git a/src/op/check/br_table.c b/src/op/check/br_table.c new file mode 100644 index 0000000..d104669 --- /dev/null +++ b/src/op/check/br_table.c @@ -0,0 +1,78 @@ +/* + * 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/. + */ + +#include <nanowasm/nw.h> +#include <nw/io.h> +#include <nw/ops.h> + +static enum nw_state loop(struct nw_mod *m); + +static enum nw_state get_default_target(struct nw_mod *const m) +{ + const struct nw_io_cfg *const cfg = &m->cfg.io; + struct nw_sm_c *const c = &m->sm.code; + struct nw_sm_leb128 *const l = &c->leb128; + nw_varuint32 target; + const enum nw_state n = nwp_varuint32(cfg, l, &target, cfg->user); + + if (n) + return n; + + m->next = c->next; + return NW_AGAIN; +} + +static enum nw_state get_entry(struct nw_mod *const m) +{ + const struct nw_io_cfg *const cfg = &m->cfg.io; + struct nw_sm_c *const c = &m->sm.code; + struct nw_sm_c_t *const t = &c->u.target; + struct nw_sm_leb128 *const l = &c->leb128; + nw_varuint32 entry; + const enum nw_state n = nwp_varuint32(cfg, l, &entry, cfg->user); + + if (n) + return n; + + t->i++; + m->next = loop; + return NW_AGAIN; +} + +static enum nw_state loop(struct nw_mod *const m) +{ + const struct nw_sm_c *const c = &m->sm.code; + const struct nw_sm_c_t *const t = &c->u.target; + + m->next = t->i >= t->count ? get_default_target : get_entry; + return NW_AGAIN; +} + +static enum nw_state get_target_count(struct nw_mod *const m) +{ + const struct nw_io_cfg *const cfg = &m->cfg.io; + struct nw_sm_c *const c = &m->sm.code; + struct nw_sm_leb128 *const l = &c->leb128; + struct nw_sm_c_t *const t = &c->u.target; + const enum nw_state n = nwp_varuint32(cfg, l, &t->count, cfg->user); + + if (n) + return n; + + m->next = loop; + return NW_AGAIN; +} + +void nwp_op_check_br_table(struct nw_mod *const m) +{ + static const struct nw_sm_c_t t = {0}; + + m->sm.code.u.target = t; + m->next = get_target_count; +} diff --git a/src/op/check/call.c b/src/op/check/call.c new file mode 100644 index 0000000..7b02032 --- /dev/null +++ b/src/op/check/call.c @@ -0,0 +1,40 @@ +/* + * 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/. + */ + +#include <nanowasm/nw.h> +#include <nw/io.h> +#include <nw/log.h> +#include <nw/ops.h> + +static enum nw_state get_index(struct nw_mod *const m) +{ + nw_varuint32 index; + const struct nw_io_cfg *const cfg = &m->cfg.io; + struct nw_sm_c *const c = &m->sm.code; + struct nw_sm_leb128 *const l = &c->leb128; + const enum nw_state n = nwp_varuint32(cfg, l, &index, cfg->user); + + if (n) + return n; + else if (index >= c->count + m->cfg.n_imports) + { +#ifdef NW_LOG + nwp_log("invalid function index %lu\n", (unsigned long)index); +#endif + return NW_FATAL; + } + + m->next = m->sm.code.next; + return NW_AGAIN; +} + +void nwp_op_check_call(struct nw_mod *const m) +{ + m->next = get_index; +} diff --git a/src/op/check/end.c b/src/op/check/end.c new file mode 100644 index 0000000..8ec6bf7 --- /dev/null +++ b/src/op/check/end.c @@ -0,0 +1,36 @@ +/* + * 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/. + */ + +#include <nanowasm/nw.h> +#include <nw/io.h> +#include <nw/log.h> +#include <nw/ops.h> + +static enum nw_state run(struct nw_mod *const m) +{ + struct nw_sm_c *const c = &m->sm.code; + struct nw_sm_c_fn *const fn = &c->fn; + + if (!fn->blocks) + { +#ifdef NW_LOG + nwp_log("unexpected end in function %lu\n", (unsigned long)c->entry_i); +#endif + return NW_FATAL; + } + + fn->blocks--; + m->next = c->next; + return NW_AGAIN; +} + +void nwp_op_check_end(struct nw_mod *const m) +{ + m->next = run; +} diff --git a/src/op/check/global_index.c b/src/op/check/global_index.c new file mode 100644 index 0000000..b3a18bb --- /dev/null +++ b/src/op/check/global_index.c @@ -0,0 +1,40 @@ +/* + * 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/. + */ + +#include <nanowasm/nw.h> +#include <nw/io.h> +#include <nw/log.h> +#include <nw/ops.h> + +static enum nw_state get_index(struct nw_mod *const m) +{ + nw_varuint32 index; + const struct nw_io_cfg *const cfg = &m->cfg.io; + struct nw_sm_c *const c = &m->sm.code; + struct nw_sm_leb128 *const l = &c->leb128; + const enum nw_state n = nwp_varuint32(cfg, l, &index, cfg->user); + + if (n) + return n; + else if (index >= m->global_count) + { +#ifdef NW_LOG + nwp_log("invalid global index %lu\n", (unsigned long)index); +#endif + return NW_FATAL; + } + + m->next = c->next; + return NW_AGAIN; +} + +void nwp_op_check_global_index(struct nw_mod *const m) +{ + m->next = get_index; +} diff --git a/src/op/check/i64_const.c b/src/op/check/i64_const.c new file mode 100644 index 0000000..e283642 --- /dev/null +++ b/src/op/check/i64_const.c @@ -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/. + */ + +#include <nanowasm/nw.h> +#include <nw/io.h> +#include <nw/ops.h> + +static enum nw_state get_value(struct nw_mod *const m) +{ + nw_varint64 value; + const struct nw_io_cfg *const cfg = &m->cfg.io; + struct nw_sm_c *const c = &m->sm.code; + struct nw_sm_leb128 *const l = &c->leb128; + const enum nw_state n = nwp_varint64(cfg, l, &value, cfg->user); + + if (n) + return n; + + m->next = c->next; + return NW_AGAIN; +} + +void nwp_op_check_varint64(struct nw_mod *const m) +{ + m->next = get_value; +} diff --git a/src/op/check/local_index.c b/src/op/check/local_index.c new file mode 100644 index 0000000..a6df9ad --- /dev/null +++ b/src/op/check/local_index.c @@ -0,0 +1,43 @@ +/* + * 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/. + */ + +#include <nanowasm/nw.h> +#include <nw/io.h> +#include <nw/log.h> +#include <nw/ops.h> + +static enum nw_state get_index(struct nw_mod *const m) +{ + nw_varuint32 index; + const struct nw_io_cfg *const cfg = &m->cfg.io; + struct nw_sm_c *const c = &m->sm.code; + struct nw_sm_leb128 *const l = &c->leb128; + const enum nw_state n = nwp_varuint32(cfg, l, &index, cfg->user); + + if (n) + return n; +#if 0 + else if (index >= c->fn.local_total) + { + LOG("%s: invalid local index %lu in function %lu\n", __func__, + (unsigned long)index, (unsigned long)c->entry_i); + return NW_FATAL; + } +#else + /* TODO: take function parameters into account for local_total*/ +#endif + + m->next = c->next; + return NW_AGAIN; +} + +void nwp_op_check_local_index(struct nw_mod *const m) +{ + m->next = get_index; +} diff --git a/src/op/check/memory_immediate.c b/src/op/check/memory_immediate.c new file mode 100644 index 0000000..98aae52 --- /dev/null +++ b/src/op/check/memory_immediate.c @@ -0,0 +1,47 @@ +/* + * 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/. + */ + +#include <nanowasm/nw.h> +#include <nw/io.h> +#include <nw/ops.h> + +static enum nw_state get_offset(struct nw_mod *const m) +{ + nw_varuint32 offset; + const struct nw_io_cfg *const cfg = &m->cfg.io; + struct nw_sm_c *const c = &m->sm.code; + struct nw_sm_leb128 *const l = &c->leb128; + const enum nw_state n = nwp_varuint32(cfg, l, &offset, cfg->user); + + if (n) + return n; + + m->next = m->sm.code.next; + return NW_AGAIN; +} + +static enum nw_state get_flags(struct nw_mod *const m) +{ + nw_varuint32 flags; + const struct nw_io_cfg *const cfg = &m->cfg.io; + struct nw_sm_c *const c = &m->sm.code; + struct nw_sm_leb128 *const l = &c->leb128; + const enum nw_state n = nwp_varuint32(cfg, l, &flags, cfg->user); + + if (n) + return n; + + m->next = get_offset; + return NW_AGAIN; +} + +void nwp_op_check_memory_immediate(struct nw_mod *const m) +{ + m->next = get_flags; +} diff --git a/src/op/check/misc.c b/src/op/check/misc.c new file mode 100644 index 0000000..fc89d21 --- /dev/null +++ b/src/op/check/misc.c @@ -0,0 +1,34 @@ +/* + * 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/. + */ + +#include <nanowasm/nw.h> +#include <nw/io.h> +#include <nw/ops.h> + +static enum nw_state run(struct nw_mod *const m) +{ + unsigned char op; + const struct nw_io_cfg *const cfg = &m->cfg.io; + struct nw_sm_io io = {0}; + enum nw_state n; + + io.buf = &op; + io.n = sizeof op; + + if ((n = nwp_io_read(cfg, &io, cfg->user))) + return n; + + m->next = m->sm.code.next; + return NW_AGAIN; +} + +void nwp_op_check_misc(struct nw_mod *const m) +{ + m->next = run; +} diff --git a/src/op/check/no_immediate.c b/src/op/check/no_immediate.c new file mode 100644 index 0000000..86cd22c --- /dev/null +++ b/src/op/check/no_immediate.c @@ -0,0 +1,23 @@ +/* + * 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/. + */ + +#include <nanowasm/nw.h> +#include <nw/io.h> +#include <nw/ops.h> + +static enum nw_state run(struct nw_mod *const m) +{ + m->next = m->sm.code.next; + return NW_AGAIN; +} + +void nwp_op_check_no_immediate(struct nw_mod *const m) +{ + m->next = run; +} diff --git a/src/op/check/relative_depth.c b/src/op/check/relative_depth.c new file mode 100644 index 0000000..41011b8 --- /dev/null +++ b/src/op/check/relative_depth.c @@ -0,0 +1,40 @@ +/* + * 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/. + */ + +#include <nanowasm/nw.h> +#include <nw/io.h> +#include <nw/log.h> +#include <nw/ops.h> + +static enum nw_state get_relative_depth(struct nw_mod *const m) +{ + nw_varuint32 relative_depth; + const struct nw_io_cfg *const cfg = &m->cfg.io; + struct nw_sm_c *const c = &m->sm.code; + struct nw_sm_leb128 *const l = &c->leb128; + const enum nw_state n = nwp_varuint32(cfg, l, &relative_depth, cfg->user); + + if (n) + return n; + else if (relative_depth >= c->fn.blocks) + { +#ifdef NW_LOG + nwp_log("invalid relative depth %lu\n", (unsigned long)relative_depth); +#endif + return NW_FATAL; + } + + m->next = c->next; + return NW_AGAIN; +} + +void nwp_op_check_relative_depth(struct nw_mod *const m) +{ + m->next = get_relative_depth; +} diff --git a/src/op/check/uint32.c b/src/op/check/uint32.c new file mode 100644 index 0000000..28aa852 --- /dev/null +++ b/src/op/check/uint32.c @@ -0,0 +1,36 @@ +/* + * 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/. + */ + +#include <nanowasm/nw.h> +#include <nw/io.h> +#include <nw/ops.h> + +static enum nw_state get_value(struct nw_mod *const m) +{ + const struct nw_io_cfg *const cfg = &m->cfg.io; + struct nw_sm_c *const c = &m->sm.code; + const enum nw_state n = nwp_io_read(cfg, &c->io, cfg->user); + + if (n) + return n; + + m->next = c->next; + return NW_AGAIN; +} + +void nwp_op_check_uint32(struct nw_mod *const m) +{ + struct nw_sm_c *const c = &m->sm.code; + struct nw_sm_io io = {0}; + + io.buf = &c->u; + io.n = sizeof (struct nw_leuint32); + c->io = io; + m->next = get_value; +} diff --git a/src/op/check/uint64.c b/src/op/check/uint64.c new file mode 100644 index 0000000..a925999 --- /dev/null +++ b/src/op/check/uint64.c @@ -0,0 +1,36 @@ +/* + * 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/. + */ + +#include <nanowasm/nw.h> +#include <nw/io.h> +#include <nw/ops.h> + +static enum nw_state get_value(struct nw_mod *const m) +{ + const struct nw_io_cfg *const cfg = &m->cfg.io; + struct nw_sm_c *const c = &m->sm.code; + const enum nw_state n = nwp_io_read(cfg, &c->io, cfg->user); + + if (n) + return n; + + m->next = c->next; + return NW_AGAIN; +} + +void nwp_op_check_uint64(struct nw_mod *const m) +{ + struct nw_sm_c *const c = &m->sm.code; + struct nw_sm_io io = {0}; + + io.buf = &c->u; + io.n = sizeof (struct nw_leuint64); + c->io = io; + m->next = get_value; +} diff --git a/src/op/check/varint32.c b/src/op/check/varint32.c new file mode 100644 index 0000000..aff3904 --- /dev/null +++ b/src/op/check/varint32.c @@ -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/. + */ + +#include <nanowasm/nw.h> +#include <nw/io.h> +#include <nw/ops.h> + +static enum nw_state get_value(struct nw_mod *const m) +{ + nw_varint32 value; + const struct nw_io_cfg *const cfg = &m->cfg.io; + struct nw_sm_c *const c = &m->sm.code; + struct nw_sm_leb128 *const l = &c->leb128; + const enum nw_state n = nwp_varint32(cfg, l, &value, cfg->user); + + if (n) + return n; + + m->next = c->next; + return NW_AGAIN; +} + +void nwp_op_check_varint32(struct nw_mod *const m) +{ + m->next = get_value; +} diff --git a/src/op/check/varuint1.c b/src/op/check/varuint1.c new file mode 100644 index 0000000..87ef6c4 --- /dev/null +++ b/src/op/check/varuint1.c @@ -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/. + */ + +#include <nanowasm/nw.h> +#include <nw/io.h> +#include <nw/ops.h> + +static enum nw_state get_value(struct nw_mod *const m) +{ + nw_varuint1 value; + const struct nw_io_cfg *const cfg = &m->cfg.io; + struct nw_sm_c *const c = &m->sm.code; + struct nw_sm_leb128 *const l = &c->leb128; + const enum nw_state n = nwp_varuint1(cfg, l, &value, cfg->user); + + if (n) + return n; + + m->next = c->next; + return NW_AGAIN; +} + +void nwp_op_check_varuint1(struct nw_mod *const m) +{ + m->next = get_value; +} |
