1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
/*
* 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 <nanowasm/nw.h>
#include <nw/io.h>
#include <nw/log.h>
#include <nw/routines.h>
static enum nw_state get_maximum(struct nw_mod *const m)
{
nw_varuint32 maximum;
const struct nw_io_cfg *const cfg = &m->cfg.io;
struct nw_sm_tb *const tb = &m->sm.table;
struct nw_sm_leb128 *const l = &tb->leb128;
const enum nw_state n = nwp_varuint32(cfg, l, &maximum);
if (n)
return n;
m->next = nwp_section_exit;
return NW_AGAIN;
}
static enum nw_state get_initial(struct nw_mod *const m)
{
const struct nw_io_cfg *const cfg = &m->cfg.io;
struct nw_sm_tb *const tb = &m->sm.table;
struct nw_sm_leb128 *const l = &tb->leb128;
nw_varuint32 initial;
const enum nw_state n = nwp_varuint32(cfg, l, &initial);
if (n)
return n;
m->next = tb->flags ? get_maximum : nwp_section_exit;
return NW_AGAIN;
}
static enum nw_state get_flags(struct nw_mod *const m)
{
const struct nw_io_cfg *const cfg = &m->cfg.io;
struct nw_sm_tb *const tb = &m->sm.table;
struct nw_sm_leb128 *const l = &tb->leb128;
const enum nw_state n = nwp_varuint1(cfg, l, &tb->flags);
if (n)
return n;
m->next = get_initial;
return NW_AGAIN;
}
static enum nw_state get_element_type(struct nw_mod *const m)
{
const struct nw_io_cfg *const cfg = &m->cfg.io;
struct nw_sm_tb *const tb = &m->sm.table;
struct nw_sm_leb128 *const l = &tb->leb128;
const enum nw_state n = nwp_varint7(cfg, l, &tb->elem_type);
if (n)
return n;
/* TODO: replace with enum? */
else if (tb->elem_type != 0x70)
{
LOG("%s: unexpected elem_type %hhx\n", __func__, (char)tb->elem_type);
return NW_FATAL;
}
m->next = get_flags;
return NW_AGAIN;
}
static enum nw_state entry_loop(struct nw_mod *const m)
{
const struct nw_sm_tb *const tb = &m->sm.table;
m->next = tb->entry_i < tb->count ? get_element_type : nwp_section_exit;
return NW_AGAIN;
}
static enum nw_state get_count(struct nw_mod *const m)
{
const struct nw_io_cfg *const cfg = &m->cfg.io;
struct nw_sm_tb *const tb = &m->sm.table;
struct nw_sm_leb128 *const l = &tb->leb128;
const enum nw_state n = nwp_varuint32(cfg, l, &tb->count);
if (n)
return n;
else if (tb->count > 1u)
{
LOG("%s: got %lu tables, but only 1 supported by the MVP\n", __func__,
(unsigned long)tb->count);
return NW_FATAL;
}
m->next = entry_loop;
return NW_AGAIN;
}
void nwp_section_table(struct nw_mod *const m)
{
m->next = get_count;
m->sm.table = (const struct nw_sm_tb){0};
}
|