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/io/leb128.c | |
| download | nanowasm-6d9d80362f9932bbc87e162b8ef7df06c73e27e1.tar.gz | |
First commit
Diffstat (limited to 'src/io/leb128.c')
| -rw-r--r-- | src/io/leb128.c | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/src/io/leb128.c b/src/io/leb128.c new file mode 100644 index 0000000..efb599b --- /dev/null +++ b/src/io/leb128.c @@ -0,0 +1,75 @@ +/* + * 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/. + */ + + +/* The functions below is a (somewhat heavily) modified version of that + * provided by the wac project: https://github.com/kanaka/wac + * + * Copyright (C) Joel Martin <github@martintribe.org> + * The wac project is licensed under the MPL 2.0 (Mozilla Public License + * 2.0). The text of the MPL 2.0 license is included below and can be + * found at https://www.mozilla.org/MPL/2.0/ + */ + +#include <nanowasm/types.h> +#include <nw/io.h> +#include <nw/log.h> + +enum nw_state nwp_leb128(const struct nw_io_cfg *const cfg, + struct nw_sm_leb128 *const l, const unsigned maxbits, const int sign, + void *const user) +{ + unsigned char byte; + + for (;;) + { + const int n = cfg->read(&byte, sizeof byte, user); + unsigned long v; + + if (n < 0) + return NW_FATAL; + else if (!n) + return NW_AGAIN; + + v = (unsigned long)(byte & 0x7f) << l->shift;; + + if (l->shift < 32) + l->result.low |= v; + else + l->result.hi |= v; + + l->shift += 7; + + if (!(byte & 0x80)) + break; + else if (++l->bcnt > (maxbits + 7u - 1u) / 7u) + { +#ifdef NW_LOG + long offset; + const enum nw_state n = cfg->tell(&offset, cfg->user); + + if (n) + return n; + + nwp_log("leb128 overflow, offset=%#lx\n", (unsigned long)offset); +#endif + return NW_FATAL; + } + } + + if (sign && (l->shift < maxbits) && (byte & 0x40)) + { + if (l->shift < 32) + l->result.low |= -1l << (l->shift); + else + l->result.hi |= -1l << (l->shift); + } + + return NW_OK; +} |
