/* * 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 #include #include #include #include #include #include #include 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]; }