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/routines/section/custom.c | |
| download | nanowasm-6d9d80362f9932bbc87e162b8ef7df06c73e27e1.tar.gz | |
First commit
Diffstat (limited to 'src/routines/section/custom.c')
| -rw-r--r-- | src/routines/section/custom.c | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/src/routines/section/custom.c b/src/routines/section/custom.c new file mode 100644 index 0000000..926f46b --- /dev/null +++ b/src/routines/section/custom.c @@ -0,0 +1,145 @@ +/* + * 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/routines.h> +#include <string.h> + +static enum nw_state get_byte(struct nw_mod *); + +static enum nw_state skip(struct nw_mod *const m) +{ + const struct nw_sm_custom *const c = &m->sm.custom; + const struct nw_io_cfg *const cfg = &m->cfg.io; + const enum nw_state n = cfg->seek(c->start, cfg->user); + + if (n) + return n; + + nwp_section_skip(m); + return NW_AGAIN; +} + +static enum nw_state compare(struct nw_mod *const m) +{ + struct nw_sm_custom *const c = &m->sm.custom; + const struct entry *out = NULL; + size_t i; + static const struct entry + { + const char *section; + void (*f)(struct nw_mod *); + } s[] = + { + {"nw_to", nwp_section_to}, + {"nw_fti", nwp_section_fti}, + {"nw_fbo", nwp_section_fbo}, + {"nw_lo", nwp_section_lo}, + {"nw_iti", nwp_section_iti} + }; + + for (i = 0; i < sizeof s / sizeof *s; i++) + { + int *const candidate = &c->candidate[i]; + const struct entry *const e = &s[i]; + + if (!*candidate) + continue; + else if (strlen(e->section) != c->name_len + || e->section[c->len_i] != c->byte) + { + *candidate = 0; + continue; + } + + out = e; + break; + } + + if (++c->len_i >= c->name_len) + { + if (out) + { + if (m->c_sections[out - s]) + { +#ifdef NW_LOG + nwp_log("duplicate section: %s\n", out->section); +#endif + return NW_FATAL; + } + + out->f(m); + } + else + m->next = skip; + } + else + m->next = get_byte; + + return NW_AGAIN; +} + +static enum nw_state get_byte(struct nw_mod *const m) +{ + const struct nw_io_cfg *const cfg = &m->cfg.io; + struct nw_sm_custom *const c = &m->sm.custom; + struct nw_sm_io io = {0}; + enum nw_state n; + + io.buf = &c->byte; + io.n = sizeof c->byte; + + if ((n = nwp_io_read(cfg, &io, cfg->user))) + return n; + + m->next = compare; + return NW_AGAIN; +} + +static enum nw_state get_name_len(struct nw_mod *const m) +{ + const struct nw_io_cfg *const cfg = &m->cfg.io; + struct nw_sm_custom *const c = &m->sm.custom; + struct nw_sm_leb128 *const l = &c->leb128; + const enum nw_state n = nwp_varuint32(cfg, l, &c->name_len, cfg->user); + + if (n) + return n; + + m->next = get_byte; + return NW_AGAIN; +} + +static enum nw_state get_start(struct nw_mod *const m) +{ + struct nw_sm_custom *const c = &m->sm.custom; + const struct nw_io_cfg *const cfg = &m->cfg.io; + const enum nw_state n = cfg->tell(&c->start, cfg->user); + + if (n) + return n; + + m->next = get_name_len; + return NW_AGAIN; +} + +void nwp_section_custom(struct nw_mod *const m) +{ + const struct nw_sm_custom c = {0}; + struct nw_sm_custom *const pc = &m->sm.custom; + size_t i; + + m->next = get_start; + *pc = c; + + for (i = 0; i < sizeof pc->candidate / sizeof *pc->candidate; i++) + pc->candidate[i] = 1; +} |
