aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorXavier Del Campo Romero <xavi.dcr@tutanota.com>2024-09-07 00:04:38 +0200
committerXavier Del Campo Romero <xavi.dcr@tutanota.com>2024-10-05 08:17:21 +0200
commit144b7fe1415ff97497fa4ea3b95e8dd6b95d069e (patch)
tree68391f6ec2dba2879ca8255ee25ce39ebaa7d4ad /include
downloadnanowasm-1st.tar.gz
First commit1st
Diffstat (limited to 'include')
-rw-r--r--include/nanowasm/leb128.h34
-rw-r--r--include/nanowasm/nw.h31
-rw-r--r--include/nanowasm/types.h333
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