/* * 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 int varuint1_read(FILE *const f, varuint1 *const out) { unsigned long long value; if (leb128_read_unsigned(f, 1, &value)) return -1; *out = value; return 0; } int varint7_read(FILE *const f, varint7 *const out) { long long value; if (leb128_read_signed(f, 7, &value)) return -1; *out = value; return 0; } int varuint7_read(FILE *const f, varuint7 *const out) { unsigned long long value; if (leb128_read_unsigned(f, 7, &value)) return -1; *out = value; return 0; } int varuint32_read(FILE *const f, varuint32 *out) { unsigned long long value; if (leb128_read_unsigned(f, 32, &value)) return -1; *out = value; return 0; } int varint32_read(FILE *const f, varint32 *const out) { long long value; if (leb128_read_signed(f, 32, &value)) return -1; *out = value; return 0; } int varuint64_read(FILE *const f, varuint64 *const out) { unsigned long long value; if (leb128_read_unsigned(f, 64, &value)) return -1; *out = value; return 0; } int varint64_read(FILE *const f, varint64 *const out) { long long value; if (leb128_read_signed(f, 64, &value)) return -1; *out = value; 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 little_endian_i32(const int32_t in) { const union { uint8_t a[4]; uint32_t b; } v = { .b = in }; return v.a[0] | (v.a[1] << 8l) | (v.a[2] << 16l) | (v.a[3] << 24l); } int32_t htoni32(const int32_t in) { return little_endian_i32(in); } int32_t ntohi32(const int32_t in) { return little_endian_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]; }