diff options
| author | Xavier Del Campo Romero <xavi.dcr@tutanota.com> | 2024-09-07 00:04:38 +0200 |
|---|---|---|
| committer | Xavier Del Campo Romero <xavi.dcr@tutanota.com> | 2024-10-05 08:17:21 +0200 |
| commit | 144b7fe1415ff97497fa4ea3b95e8dd6b95d069e (patch) | |
| tree | 68391f6ec2dba2879ca8255ee25ce39ebaa7d4ad /include | |
| download | nanowasm-1st.tar.gz | |
First commit1st
Diffstat (limited to 'include')
| -rw-r--r-- | include/nanowasm/leb128.h | 34 | ||||
| -rw-r--r-- | include/nanowasm/nw.h | 31 | ||||
| -rw-r--r-- | include/nanowasm/types.h | 333 |
3 files changed, 398 insertions, 0 deletions
diff --git a/include/nanowasm/leb128.h b/include/nanowasm/leb128.h new file mode 100644 index 0000000..8213789 --- /dev/null +++ b/include/nanowasm/leb128.h @@ -0,0 +1,34 @@ +/* + * nanowasm, a tiny WebAssembly/Wasm interpreter + * Copyright (C) 2023-2024 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 WASM_LEB128_H +#define WASM_LEB128_H + +#include <stdint.h> +#include <stdbool.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + +typedef bool nw_varint1; +typedef bool nw_varuint1; +typedef int8_t nw_varint7; +typedef uint8_t nw_varuint7; +typedef uint32_t nw_varuint32; +typedef int32_t nw_varint32; +typedef uint64_t nw_varuint64; +typedef int64_t nw_varint64; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/nanowasm/nw.h b/include/nanowasm/nw.h new file mode 100644 index 0000000..ede5442 --- /dev/null +++ b/include/nanowasm/nw.h @@ -0,0 +1,31 @@ +/* + * nanowasm, a tiny WebAssembly/Wasm interpreter + * Copyright (C) 2023-2024 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_H +#define NANOWASM_H + +#include <nanowasm/types.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); +int nw_start(const struct nw_inst_cfg *icfg, struct nw_inst *i); +enum nw_state nw_run(struct nw_inst *i); +const char *nw_exception(const struct nw_inst *i); +int nw_stop(struct nw_inst *i); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/nanowasm/types.h b/include/nanowasm/types.h new file mode 100644 index 0000000..c839f17 --- /dev/null +++ b/include/nanowasm/types.h @@ -0,0 +1,333 @@ +/* + * nanowasm, a tiny WebAssembly/Wasm interpreter + * Copyright (C) 2023-2024 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_TYPES_H +#define NANOWASM_TYPES_H + +#include <nanowasm/leb128.h> +#include <stdbool.h> +#include <stddef.h> +#include <stdint.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + +struct nw_interp; + +union nw_value +{ + long i32; + long long i64; + float f32; + double f64; + /* TODO: define {de}serialization between Wasm and host. */ + void *p; +}; + +enum nw_type +{ + NW_TYPE_I32, + NW_TYPE_I64, + NW_TYPE_F32, + NW_TYPE_F64 +}; + +enum nw_kind +{ + NW_KIND_FUNCTION, + NW_KIND_TABLE, + NW_KIND_MEMORY, + NW_KIND_GLOBAL, + + NW_KINDS +}; + +struct nw_args +{ + const union nw_value *args; + size_t n; +}; + +struct nw_buf +{ + void *buf; + size_t n; +}; + +enum nw_state +{ + NW_OK, + NW_AGAIN, + NW_FATAL +}; + +enum nw_whence +{ + NW_SEEK_SET, + NW_SEEK_CUR, + NW_SEEK_END +}; + +struct nw_io_cfg +{ + int (*read)(void *buf, size_t n, void *user); + int (*eof)(void *user); + enum nw_state (*seek)(long offset, enum nw_whence whence, void *user); + enum nw_state (*tell)(long *offset, void *user); + void *user; +}; + +struct nw_sm_io +{ + void *buf; + size_t n, read; +}; + +struct nw_sm_leb128 +{ + unsigned long long result; + unsigned shift, bcnt; +}; + +struct nw_interp_cfg +{ + struct nw_buf stack, heap, global; + struct nw_io_cfg io; + const struct nw_mod *m; +}; + +union nw_interp_sm +{ + struct nw_i_sm_b + { + uint8_t op; + struct nw_sm_io io; + } bytecode; + + struct nw_i_sm_i32_const + { + struct nw_sm_leb128 leb128; + } i32_const; + + struct nw_i_sm_exp + { + struct nw_sm_leb128 leb128; + nw_varuint32 count, entry_i, len, len_i; + const char *sym; + enum nw_kind kind; + nw_varuint32 index; + enum nw_state (*next)(struct nw_interp *); + } export; + + struct nw_i_sm_type + { + struct nw_sm_leb128 leb128; + nw_varuint32 index, count, entry_i, type_index, param_i; + enum nw_state (*next)(struct nw_interp *); + + struct nw_i_sm_type_out + { + nw_varuint32 count, param_count; + nw_varint7 form, return_type; + nw_varuint1 return_count; + } out; + } type; +}; + +struct nw_interp +{ + const void *set; + const char *exception; + bool exit; + int retval; + struct nw_interp_cfg cfg; + size_t stack_i, global_i; + struct nw_frame *fp; + struct nw_gframe *gfp; + enum nw_state (*next)(struct nw_interp *); + union nw_interp_sm sm; +}; + +union nw_sm +{ + struct nw_sm_cm + { + struct nw_sm_io io; + uint8_t buf[sizeof "\0asm" - 1]; + } check_magic; + + struct nw_sm_cv + { + struct nw_sm_io io; + uint32_t version; + } check_version; + + struct nw_sm_st + { + struct nw_sm_leb128 leb128; + nw_varuint32 count, entry_i, param_count, p_i; + } type; + + struct nw_sm_imp + { + struct nw_sm_leb128 leb128; + long mod_off, field_off; + nw_varuint32 count, entry_i, mod_len, field_len, len_i, imp_i; + } import; + + struct nw_sm_fn + { + struct nw_sm_leb128 leb128; + nw_varuint32 count, entry_i; + } function; + + struct nw_sm_tb + { + struct nw_sm_leb128 leb128; + nw_varuint32 count, entry_i; + nw_varint7 elem_type; + nw_varuint1 flags; + } table; + + struct nw_sm_mem + { + struct nw_sm_leb128 leb128; + nw_varuint32 count, entry_i; + nw_varuint1 flags; + } memory; + + struct nw_sm_gl + { + struct nw_sm_leb128 leb128; + nw_varuint32 entry_i; + struct nw_interp interp; + bool mutable; + enum nw_type type; + + union + { + int32_t i32; + int64_t i64; + float f32; + double f64; + } value; + } global; + + struct nw_sm_exp + { + struct nw_sm_io io; + struct nw_sm_leb128 leb128; + nw_varuint32 count, entry_i, field_len, len_i; + } export; + + struct nw_sm_start + { + struct nw_sm_leb128 leb128; + } start; + + struct nw_sm_c + { + struct nw_sm_leb128 leb128; + nw_varuint32 count, entry_i, body_size; + long start, op_off; + unsigned long rem; + enum nw_state (*next)(struct nw_mod *); + uint8_t op; + + struct nw_sm_c_fn + { + nw_varuint32 local_count, local_i, local_total; + unsigned blocks; + } fn; + + struct nw_sm_c_fn_type + { + enum nw_state (*next)(struct nw_mod *); + } func_type; + } code; +}; + +struct nw_mod_cfg +{ + const struct nw_import + { + enum nw_kind kind; + const char *module, *field; + + union + { + struct nw_import_fn + { + const char *signature; + int (*fn)(const struct nw_args *params, + union nw_value *ret, void *user); + } function; + } u; + } *imports; + + struct nw_io_cfg io; + size_t n_imports; + void *user; +}; + +struct nw_inst_cfg +{ + struct nw_interp_cfg interp_cfg; +}; + +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_SECTIONS +}; + +struct nw_mod +{ + long sections[NW_SECTIONS]; + size_t data_len, heap_len; + enum nw_state (*next)(struct nw_mod *); + struct nw_mod_cfg cfg; + union nw_sm sm; + nw_varuint32 global_count; + + struct nw_mod_section + { + struct nw_sm_leb128 leb128; + nw_varuint7 section; + nw_varuint32 len; + long offset; + } section; +}; + +struct nw_inst +{ + struct nw_interp interp; +}; + +#define NW_BUF(sz) (const struct nw_buf){.buf = (char [sz]){0}, .n = (sz)} + +#ifdef __cplusplus +} +#endif + +#endif |
