aboutsummaryrefslogtreecommitdiff
path: root/src/section/common.c
diff options
context:
space:
mode:
authorXavier Del Campo Romero <xavi.dcr@tutanota.com>2023-11-26 22:43:30 +0100
committerXavier Del Campo Romero <xavi.dcr@tutanota.com>2024-04-21 01:51:24 +0200
commitf25b015e5b668028c34974bbb22faa4105c26690 (patch)
tree28f2b08c17b3585d06694ad74004d0617eadb785 /src/section/common.c
downloadnanowasm-sync-f25b015e5b668028c34974bbb22faa4105c26690.tar.gz
First commit
Diffstat (limited to 'src/section/common.c')
-rw-r--r--src/section/common.c150
1 files changed, 150 insertions, 0 deletions
diff --git a/src/section/common.c b/src/section/common.c
new file mode 100644
index 0000000..b768470
--- /dev/null
+++ b/src/section/common.c
@@ -0,0 +1,150 @@
+/*
+ * 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/.
+ */
+
+#include <nw/log.h>
+#include <nw/sections.h>
+#include <nw/types.h>
+#include <errno.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+
+int check_resizable_limits(FILE *const f, struct resizable_limits *const r)
+{
+ varuint1 flags;
+ varuint32 initial;
+
+ *r = (const struct resizable_limits){0};
+
+ if (varuint1_read(f, &flags))
+ {
+ LOG("%s: varuint1_read failed\n", __func__);
+ return -1;
+ }
+ else if (varuint32_read(f, &initial))
+ {
+ LOG("%s: varuint32_read failed\n", __func__);
+ return -1;
+ }
+
+ if (flags)
+ {
+ varuint32 maximum;
+
+ if (varuint32_read(f, &maximum))
+ {
+ LOG("%s: varuint32_read failed\n", __func__);
+ return -1;
+ }
+
+ r->max = maximum;
+ r->max_available = true;
+ }
+
+ static const unsigned long page_size = 64lu * 1024lu;
+
+ if (initial > UINT32_MAX / page_size)
+ {
+ LOG("%s: initial size (%lu) overflow \n", __func__,
+ (unsigned long)initial);
+ return 1;
+ }
+
+ r->sz = initial * page_size;
+ return 0;
+}
+
+size_t get_type_size(const enum value_type type)
+{
+ static const size_t list[] =
+ {
+ [VALUE_TYPE_I32] = sizeof (int32_t),
+ [VALUE_TYPE_I64] = sizeof (int64_t),
+ [VALUE_TYPE_F32] = sizeof (float),
+ [VALUE_TYPE_F64] = sizeof (double)
+ };
+
+ return list[type];
+}
+
+enum
+{
+ I32 = 0x7f,
+ I64 = 0x7e,
+ F32 = 0x7d,
+ F64 = 0x7c,
+ ANYFUNC = 0x70,
+ FUNC = 0x60,
+ BLOCK_TYPE = 0x40
+};
+
+int get_value_type(const varint7 type, enum value_type *const vtype)
+{
+ static const struct size
+ {
+ varint7 type;
+ enum value_type vtype;
+ } sizes[] =
+ {
+ {.type = I32, .vtype = VALUE_TYPE_I32},
+ {.type = I64, .vtype = VALUE_TYPE_I64},
+ {.type = F32, .vtype = VALUE_TYPE_F32},
+ {.type = F64, .vtype = VALUE_TYPE_F64},
+ /* TODO: check this. */
+ {.type = ANYFUNC, .vtype = VALUE_TYPE_I32},
+ /* TODO: check this. */
+ {.type = FUNC, .vtype = VALUE_TYPE_I32},
+ /* TODO: check this. */
+ {.type = BLOCK_TYPE, .vtype = VALUE_TYPE_I32}
+ };
+
+ for (size_t i = 0; i < sizeof sizes / sizeof *sizes; i++)
+ {
+ const struct size *const s = &sizes[i];
+
+ if (type == s->type)
+ {
+ *vtype = s->vtype;
+ return 0;
+ }
+ }
+
+ LOG("%s: unknown type %#hhx\n", __func__, (char)type);
+ return -1;
+}
+
+static int32_t swap_i32(const int32_t in)
+{
+ const int8_t *const p = (const int8_t *)&in;
+
+ return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
+}
+
+int32_t htoni32(const int32_t in)
+{
+ return swap_i32(in);
+}
+
+int32_t ntohi32(const int32_t in)
+{
+ return swap_i32(in);
+}
+
+const char *value_type_tostr(const enum value_type v)
+{
+ static const char *const s[] =
+ {
+#define X(x) [x] = #x,
+ VALUE_TYPES
+#undef X
+ };
+
+ return s[v];
+}