diff options
| author | Xavier Del Campo Romero <xavi.dcr@tutanota.com> | 2023-11-26 22:43:30 +0100 |
|---|---|---|
| committer | Xavier Del Campo Romero <xavi.dcr@tutanota.com> | 2024-04-21 01:51:24 +0200 |
| commit | f25b015e5b668028c34974bbb22faa4105c26690 (patch) | |
| tree | 28f2b08c17b3585d06694ad74004d0617eadb785 /src/section/common.c | |
| download | nanowasm-sync-f25b015e5b668028c34974bbb22faa4105c26690.tar.gz | |
First commit
Diffstat (limited to 'src/section/common.c')
| -rw-r--r-- | src/section/common.c | 150 |
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 *)∈ + + 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]; +} |
