Skip to content

Commit 5c7176b

Browse files
cjihrigcodebytere
authored andcommittedJun 9, 2020
deps: update to uvwasi 0.0.9
Notable changes: - A `DEBUG()` macro and `UVWASI_DEBUG_LOG` build option have been added to improve debugging. - Path length restrictions have been removed across the codebase. - Initial support for `poll_oneoff()` has been added on all platforms. The implementation is based on `uv_poll_t`'s. - A new `uvwasi_size_t` has been introduced across the WASI system call API. This provides consistent 32-bit `size_t`'s. - The cmake test targets are now only generated if uvwasi is the root project to avoid conflicts with targets from embedders. - `uv.h` has been removed from the public headers. - A serialization/deserialization API has been added to simplify the process of working with WASM memory. This also hides many WASI <--> WASM interfacing implementation details from embedders. - A memory corruption bug on Windows related to path resolution has been fixed. PR-URL: #33445 Fixes: #33403 Reviewed-By: Michaël Zasso <targos@protonmail.com> Reviewed-By: Jiawen Geng <technicalcute@gmail.com>
1 parent e67df04 commit 5c7176b

14 files changed

+1619
-584
lines changed
 

‎deps/uvwasi/include/uvwasi.h

+55-51
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,12 @@
55
extern "C" {
66
#endif
77

8-
#include "uv.h"
8+
#include "wasi_serdes.h"
99
#include "wasi_types.h"
10-
#include "fd_table.h"
1110

1211
#define UVWASI_VERSION_MAJOR 0
1312
#define UVWASI_VERSION_MINOR 0
14-
#define UVWASI_VERSION_PATCH 8
13+
#define UVWASI_VERSION_PATCH 9
1514
#define UVWASI_VERSION_HEX ((UVWASI_VERSION_MAJOR << 16) | \
1615
(UVWASI_VERSION_MINOR << 8) | \
1716
(UVWASI_VERSION_PATCH))
@@ -35,16 +34,18 @@ typedef struct uvwasi_mem_s {
3534
uvwasi_realloc realloc;
3635
} uvwasi_mem_t;
3736

37+
struct uvwasi_fd_table_t;
38+
3839
typedef struct uvwasi_s {
39-
struct uvwasi_fd_table_t fds;
40-
size_t argc;
40+
struct uvwasi_fd_table_t* fds;
41+
uvwasi_size_t argc;
4142
char** argv;
4243
char* argv_buf;
43-
size_t argv_buf_size;
44-
size_t envc;
44+
uvwasi_size_t argv_buf_size;
45+
uvwasi_size_t envc;
4546
char** env;
4647
char* env_buf;
47-
size_t env_buf_size;
48+
uvwasi_size_t env_buf_size;
4849
const uvwasi_mem_t* allocator;
4950
} uvwasi_t;
5051

@@ -54,12 +55,12 @@ typedef struct uvwasi_preopen_s {
5455
} uvwasi_preopen_t;
5556

5657
typedef struct uvwasi_options_s {
57-
size_t fd_table_size;
58-
size_t preopenc;
58+
uvwasi_size_t fd_table_size;
59+
uvwasi_size_t preopenc;
5960
uvwasi_preopen_t* preopens;
60-
size_t argc;
61-
char** argv;
62-
char** envp;
61+
uvwasi_size_t argc;
62+
const char** argv;
63+
const char** envp;
6364
uvwasi_fd_t in;
6465
uvwasi_fd_t out;
6566
uvwasi_fd_t err;
@@ -69,17 +70,18 @@ typedef struct uvwasi_options_s {
6970
/* Embedder API. */
7071
uvwasi_errno_t uvwasi_init(uvwasi_t* uvwasi, uvwasi_options_t* options);
7172
void uvwasi_destroy(uvwasi_t* uvwasi);
73+
/* Use int instead of uv_file to avoid needing uv.h */
7274
uvwasi_errno_t uvwasi_embedder_remap_fd(uvwasi_t* uvwasi,
7375
const uvwasi_fd_t fd,
74-
uv_file new_host_fd);
76+
int new_host_fd);
7577
const char* uvwasi_embedder_err_code_to_string(uvwasi_errno_t code);
7678

7779

7880
/* WASI system call API. */
7981
uvwasi_errno_t uvwasi_args_get(uvwasi_t* uvwasi, char** argv, char* argv_buf);
8082
uvwasi_errno_t uvwasi_args_sizes_get(uvwasi_t* uvwasi,
81-
size_t* argc,
82-
size_t* argv_buf_size);
83+
uvwasi_size_t* argc,
84+
uvwasi_size_t* argv_buf_size);
8385
uvwasi_errno_t uvwasi_clock_res_get(uvwasi_t* uvwasi,
8486
uvwasi_clockid_t clock_id,
8587
uvwasi_timestamp_t* resolution);
@@ -91,8 +93,8 @@ uvwasi_errno_t uvwasi_environ_get(uvwasi_t* uvwasi,
9193
char** environment,
9294
char* environ_buf);
9395
uvwasi_errno_t uvwasi_environ_sizes_get(uvwasi_t* uvwasi,
94-
size_t* environ_count,
95-
size_t* environ_buf_size);
96+
uvwasi_size_t* environ_count,
97+
uvwasi_size_t* environ_buf_size);
9698
uvwasi_errno_t uvwasi_fd_advise(uvwasi_t* uvwasi,
9799
uvwasi_fd_t fd,
98100
uvwasi_filesize_t offset,
@@ -129,33 +131,33 @@ uvwasi_errno_t uvwasi_fd_filestat_set_times(uvwasi_t* uvwasi,
129131
uvwasi_errno_t uvwasi_fd_pread(uvwasi_t* uvwasi,
130132
uvwasi_fd_t fd,
131133
const uvwasi_iovec_t* iovs,
132-
size_t iovs_len,
134+
uvwasi_size_t iovs_len,
133135
uvwasi_filesize_t offset,
134-
size_t* nread);
136+
uvwasi_size_t* nread);
135137
uvwasi_errno_t uvwasi_fd_prestat_get(uvwasi_t* uvwasi,
136138
uvwasi_fd_t fd,
137139
uvwasi_prestat_t* buf);
138140
uvwasi_errno_t uvwasi_fd_prestat_dir_name(uvwasi_t* uvwasi,
139141
uvwasi_fd_t fd,
140142
char* path,
141-
size_t path_len);
143+
uvwasi_size_t path_len);
142144
uvwasi_errno_t uvwasi_fd_pwrite(uvwasi_t* uvwasi,
143145
uvwasi_fd_t fd,
144146
const uvwasi_ciovec_t* iovs,
145-
size_t iovs_len,
147+
uvwasi_size_t iovs_len,
146148
uvwasi_filesize_t offset,
147-
size_t* nwritten);
149+
uvwasi_size_t* nwritten);
148150
uvwasi_errno_t uvwasi_fd_read(uvwasi_t* uvwasi,
149151
uvwasi_fd_t fd,
150152
const uvwasi_iovec_t* iovs,
151-
size_t iovs_len,
152-
size_t* nread);
153+
uvwasi_size_t iovs_len,
154+
uvwasi_size_t* nread);
153155
uvwasi_errno_t uvwasi_fd_readdir(uvwasi_t* uvwasi,
154156
uvwasi_fd_t fd,
155157
void* buf,
156-
size_t buf_len,
158+
uvwasi_size_t buf_len,
157159
uvwasi_dircookie_t cookie,
158-
size_t* bufused);
160+
uvwasi_size_t* bufused);
159161
uvwasi_errno_t uvwasi_fd_renumber(uvwasi_t* uvwasi,
160162
uvwasi_fd_t from,
161163
uvwasi_fd_t to);
@@ -171,39 +173,39 @@ uvwasi_errno_t uvwasi_fd_tell(uvwasi_t* uvwasi,
171173
uvwasi_errno_t uvwasi_fd_write(uvwasi_t* uvwasi,
172174
uvwasi_fd_t fd,
173175
const uvwasi_ciovec_t* iovs,
174-
size_t iovs_len,
175-
size_t* nwritten);
176+
uvwasi_size_t iovs_len,
177+
uvwasi_size_t* nwritten);
176178
uvwasi_errno_t uvwasi_path_create_directory(uvwasi_t* uvwasi,
177179
uvwasi_fd_t fd,
178180
const char* path,
179-
size_t path_len);
181+
uvwasi_size_t path_len);
180182
uvwasi_errno_t uvwasi_path_filestat_get(uvwasi_t* uvwasi,
181183
uvwasi_fd_t fd,
182184
uvwasi_lookupflags_t flags,
183185
const char* path,
184-
size_t path_len,
186+
uvwasi_size_t path_len,
185187
uvwasi_filestat_t* buf);
186188
uvwasi_errno_t uvwasi_path_filestat_set_times(uvwasi_t* uvwasi,
187189
uvwasi_fd_t fd,
188190
uvwasi_lookupflags_t flags,
189191
const char* path,
190-
size_t path_len,
192+
uvwasi_size_t path_len,
191193
uvwasi_timestamp_t st_atim,
192194
uvwasi_timestamp_t st_mtim,
193195
uvwasi_fstflags_t fst_flags);
194196
uvwasi_errno_t uvwasi_path_link(uvwasi_t* uvwasi,
195197
uvwasi_fd_t old_fd,
196198
uvwasi_lookupflags_t old_flags,
197199
const char* old_path,
198-
size_t old_path_len,
200+
uvwasi_size_t old_path_len,
199201
uvwasi_fd_t new_fd,
200202
const char* new_path,
201-
size_t new_path_len);
203+
uvwasi_size_t new_path_len);
202204
uvwasi_errno_t uvwasi_path_open(uvwasi_t* uvwasi,
203205
uvwasi_fd_t dirfd,
204206
uvwasi_lookupflags_t dirflags,
205207
const char* path,
206-
size_t path_len,
208+
uvwasi_size_t path_len,
207209
uvwasi_oflags_t o_flags,
208210
uvwasi_rights_t fs_rights_base,
209211
uvwasi_rights_t fs_rights_inheriting,
@@ -212,53 +214,55 @@ uvwasi_errno_t uvwasi_path_open(uvwasi_t* uvwasi,
212214
uvwasi_errno_t uvwasi_path_readlink(uvwasi_t* uvwasi,
213215
uvwasi_fd_t fd,
214216
const char* path,
215-
size_t path_len,
217+
uvwasi_size_t path_len,
216218
char* buf,
217-
size_t buf_len,
218-
size_t* bufused);
219+
uvwasi_size_t buf_len,
220+
uvwasi_size_t* bufused);
219221
uvwasi_errno_t uvwasi_path_remove_directory(uvwasi_t* uvwasi,
220222
uvwasi_fd_t fd,
221223
const char* path,
222-
size_t path_len);
224+
uvwasi_size_t path_len);
223225
uvwasi_errno_t uvwasi_path_rename(uvwasi_t* uvwasi,
224226
uvwasi_fd_t old_fd,
225227
const char* old_path,
226-
size_t old_path_len,
228+
uvwasi_size_t old_path_len,
227229
uvwasi_fd_t new_fd,
228230
const char* new_path,
229-
size_t new_path_len);
231+
uvwasi_size_t new_path_len);
230232
uvwasi_errno_t uvwasi_path_symlink(uvwasi_t* uvwasi,
231233
const char* old_path,
232-
size_t old_path_len,
234+
uvwasi_size_t old_path_len,
233235
uvwasi_fd_t fd,
234236
const char* new_path,
235-
size_t new_path_len);
237+
uvwasi_size_t new_path_len);
236238
uvwasi_errno_t uvwasi_path_unlink_file(uvwasi_t* uvwasi,
237239
uvwasi_fd_t fd,
238240
const char* path,
239-
size_t path_len);
241+
uvwasi_size_t path_len);
240242
uvwasi_errno_t uvwasi_poll_oneoff(uvwasi_t* uvwasi,
241243
const uvwasi_subscription_t* in,
242244
uvwasi_event_t* out,
243-
size_t nsubscriptions,
244-
size_t* nevents);
245+
uvwasi_size_t nsubscriptions,
246+
uvwasi_size_t* nevents);
245247
uvwasi_errno_t uvwasi_proc_exit(uvwasi_t* uvwasi, uvwasi_exitcode_t rval);
246248
uvwasi_errno_t uvwasi_proc_raise(uvwasi_t* uvwasi, uvwasi_signal_t sig);
247-
uvwasi_errno_t uvwasi_random_get(uvwasi_t* uvwasi, void* buf, size_t buf_len);
249+
uvwasi_errno_t uvwasi_random_get(uvwasi_t* uvwasi,
250+
void* buf,
251+
uvwasi_size_t buf_len);
248252
uvwasi_errno_t uvwasi_sched_yield(uvwasi_t* uvwasi);
249253
uvwasi_errno_t uvwasi_sock_recv(uvwasi_t* uvwasi,
250254
uvwasi_fd_t sock,
251255
const uvwasi_iovec_t* ri_data,
252-
size_t ri_data_len,
256+
uvwasi_size_t ri_data_len,
253257
uvwasi_riflags_t ri_flags,
254-
size_t* ro_datalen,
258+
uvwasi_size_t* ro_datalen,
255259
uvwasi_roflags_t* ro_flags);
256260
uvwasi_errno_t uvwasi_sock_send(uvwasi_t* uvwasi,
257261
uvwasi_fd_t sock,
258262
const uvwasi_ciovec_t* si_data,
259-
size_t si_data_len,
263+
uvwasi_size_t si_data_len,
260264
uvwasi_siflags_t si_flags,
261-
size_t* so_datalen);
265+
uvwasi_size_t* so_datalen);
262266
uvwasi_errno_t uvwasi_sock_shutdown(uvwasi_t* uvwasi,
263267
uvwasi_fd_t sock,
264268
uvwasi_sdflags_t how);

‎deps/uvwasi/include/wasi_serdes.h

+145
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
#ifndef __UVWASI_SERDES_H__
2+
#define __UVWASI_SERDES_H__
3+
4+
#include "wasi_types.h"
5+
6+
/* Basic uint{8,16,32,64}_t read/write functions. */
7+
8+
#define BASIC_TYPE_(name, type) \
9+
void uvwasi_serdes_write_##name(void* ptr, size_t offset, type value); \
10+
type uvwasi_serdes_read_##name(const void* ptr, size_t offset); \
11+
12+
#define BASIC_TYPE(type) BASIC_TYPE_(type, type)
13+
#define BASIC_TYPE_UVWASI(type) BASIC_TYPE_(type, uvwasi_##type)
14+
15+
#define UVWASI_SERDES_SIZE_uint8_t sizeof(uint8_t)
16+
BASIC_TYPE(uint8_t)
17+
#define UVWASI_SERDES_SIZE_uint16_t sizeof(uint16_t)
18+
BASIC_TYPE(uint16_t)
19+
#define UVWASI_SERDES_SIZE_uint32_t sizeof(uint32_t)
20+
BASIC_TYPE(uint32_t)
21+
#define UVWASI_SERDES_SIZE_uint64_t sizeof(uint64_t)
22+
BASIC_TYPE(uint64_t)
23+
24+
#define UVWASI_SERDES_SIZE_advice_t sizeof(uvwasi_advice_t)
25+
BASIC_TYPE_UVWASI(advice_t)
26+
#define UVWASI_SERDES_SIZE_clockid_t sizeof(uvwasi_clockid_t)
27+
BASIC_TYPE_UVWASI(clockid_t)
28+
#define UVWASI_SERDES_SIZE_device_t sizeof(uvwasi_device_t)
29+
BASIC_TYPE_UVWASI(device_t)
30+
#define UVWASI_SERDES_SIZE_dircookie_t sizeof(uvwasi_dircookie_t)
31+
BASIC_TYPE_UVWASI(dircookie_t)
32+
#define UVWASI_SERDES_SIZE_eventrwflags_t sizeof(uvwasi_eventrwflags_t)
33+
BASIC_TYPE_UVWASI(eventrwflags_t)
34+
#define UVWASI_SERDES_SIZE_eventtype_t sizeof(uvwasi_eventtype_t)
35+
BASIC_TYPE_UVWASI(eventtype_t)
36+
#define UVWASI_SERDES_SIZE_exitcode_t sizeof(uvwasi_exitcode_t)
37+
BASIC_TYPE_UVWASI(exitcode_t)
38+
#define UVWASI_SERDES_SIZE_fd_t sizeof(uvwasi_fd_t)
39+
BASIC_TYPE_UVWASI(fd_t)
40+
#define UVWASI_SERDES_SIZE_fdflags_t sizeof(uvwasi_fdflags_t)
41+
BASIC_TYPE_UVWASI(fdflags_t)
42+
#define UVWASI_SERDES_SIZE_filesize_t sizeof(uvwasi_filesize_t)
43+
BASIC_TYPE_UVWASI(filesize_t)
44+
#define UVWASI_SERDES_SIZE_fstflags_t sizeof(uvwasi_fstflags_t)
45+
BASIC_TYPE_UVWASI(fstflags_t)
46+
#define UVWASI_SERDES_SIZE_inode_t sizeof(uvwasi_inode_t)
47+
BASIC_TYPE_UVWASI(inode_t)
48+
#define UVWASI_SERDES_SIZE_linkcount_t sizeof(uvwasi_linkcount_t)
49+
BASIC_TYPE_UVWASI(linkcount_t)
50+
#define UVWASI_SERDES_SIZE_lookupflags_t sizeof(uvwasi_lookupflags_t)
51+
BASIC_TYPE_UVWASI(lookupflags_t)
52+
#define UVWASI_SERDES_SIZE_oflags_t sizeof(uvwasi_oflags_t)
53+
BASIC_TYPE_UVWASI(oflags_t)
54+
#define UVWASI_SERDES_SIZE_preopentype_t sizeof(uvwasi_preopentype_t)
55+
BASIC_TYPE_UVWASI(preopentype_t)
56+
#define UVWASI_SERDES_SIZE_riflags_t sizeof(uvwasi_riflags_t)
57+
BASIC_TYPE_UVWASI(riflags_t)
58+
#define UVWASI_SERDES_SIZE_rights_t sizeof(uvwasi_rights_t)
59+
BASIC_TYPE_UVWASI(rights_t)
60+
#define UVWASI_SERDES_SIZE_roflags_t sizeof(uvwasi_roflags_t)
61+
BASIC_TYPE_UVWASI(roflags_t)
62+
#define UVWASI_SERDES_SIZE_sdflags_t sizeof(uvwasi_sdflags_t)
63+
BASIC_TYPE_UVWASI(sdflags_t)
64+
#define UVWASI_SERDES_SIZE_siflags_t sizeof(uvwasi_siflags_t)
65+
BASIC_TYPE_UVWASI(siflags_t)
66+
#define UVWASI_SERDES_SIZE_size_t sizeof(uvwasi_size_t)
67+
BASIC_TYPE_UVWASI(size_t)
68+
#define UVWASI_SERDES_SIZE_inode_t sizeof(uvwasi_inode_t)
69+
BASIC_TYPE_UVWASI(inode_t)
70+
#define UVWASI_SERDES_SIZE_signal_t sizeof(uvwasi_signal_t)
71+
BASIC_TYPE_UVWASI(signal_t)
72+
#define UVWASI_SERDES_SIZE_subclockflags_t sizeof(uvwasi_subclockflags_t)
73+
BASIC_TYPE_UVWASI(subclockflags_t)
74+
#define UVWASI_SERDES_SIZE_timestamp_t sizeof(uvwasi_timestamp_t)
75+
BASIC_TYPE_UVWASI(timestamp_t)
76+
#define UVWASI_SERDES_SIZE_userdata_t sizeof(uvwasi_userdata_t)
77+
BASIC_TYPE_UVWASI(userdata_t)
78+
#define UVWASI_SERDES_SIZE_whence_t sizeof(uvwasi_whence_t)
79+
BASIC_TYPE_UVWASI(whence_t)
80+
81+
#undef BASIC_TYPE_UVWASI
82+
#undef BASIC_TYPE
83+
#undef BASIC_TYPE_
84+
85+
/* WASI structure read/write functions. */
86+
87+
#define STRUCT(name) \
88+
void uvwasi_serdes_write_##name(void* ptr, \
89+
size_t offset, \
90+
const uvwasi_##name* value); \
91+
void uvwasi_serdes_read_##name(const void* ptr, \
92+
size_t offset, \
93+
uvwasi_##name* value);
94+
95+
/* iovs currently only need to be read from WASM memory. */
96+
#define IOVS_STRUCT(name) \
97+
uvwasi_errno_t uvwasi_serdes_read_##name(const void* ptr, \
98+
size_t end, \
99+
size_t offset, \
100+
uvwasi_##name* value);
101+
102+
#define UVWASI_SERDES_SIZE_ciovec_t 8
103+
IOVS_STRUCT(ciovec_t)
104+
105+
#define UVWASI_SERDES_SIZE_iovec_t 8
106+
IOVS_STRUCT(iovec_t)
107+
108+
#define UVWASI_SERDES_SIZE_fdstat_t 24
109+
STRUCT(fdstat_t)
110+
111+
#define UVWASI_SERDES_SIZE_filestat_t 64
112+
STRUCT(filestat_t)
113+
114+
#define UVWASI_SERDES_SIZE_prestat_t 8
115+
STRUCT(prestat_t)
116+
117+
#define UVWASI_SERDES_SIZE_event_t 32
118+
STRUCT(event_t)
119+
120+
#define UVWASI_SERDES_SIZE_subscription_t 48
121+
STRUCT(subscription_t)
122+
123+
#undef STRUCT
124+
#undef IOVS_STRUCT
125+
126+
uvwasi_errno_t uvwasi_serdes_readv_ciovec_t(const void* ptr,
127+
size_t end,
128+
size_t offset,
129+
uvwasi_ciovec_t* iovs,
130+
uvwasi_size_t iovs_len);
131+
132+
uvwasi_errno_t uvwasi_serdes_readv_iovec_t(const void* ptr,
133+
size_t end,
134+
size_t offset,
135+
uvwasi_iovec_t* iovs,
136+
uvwasi_size_t iovs_len);
137+
138+
/* Helper functions for memory bounds checking. */
139+
int uvwasi_serdes_check_bounds(size_t offset, size_t end, size_t size);
140+
int uvwasi_serdes_check_array_bounds(size_t offset,
141+
size_t end,
142+
size_t size,
143+
size_t count);
144+
145+
#endif /* __UVWASI_SERDES_H__ */

‎deps/uvwasi/include/wasi_types.h

+5-3
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
/* API: https://github.com/WebAssembly/WASI/blob/master/phases/snapshot/docs.md */
88

9+
typedef uint32_t uvwasi_size_t;
10+
911
typedef uint8_t uvwasi_advice_t;
1012
#define UVWASI_ADVICE_NORMAL 0
1113
#define UVWASI_ADVICE_SEQUENTIAL 1
@@ -16,7 +18,7 @@ typedef uint8_t uvwasi_advice_t;
1618

1719
typedef struct uvwasi_ciovec_s {
1820
const void* buf;
19-
size_t buf_len;
21+
uvwasi_size_t buf_len;
2022
} uvwasi_ciovec_t;
2123

2224
typedef uint32_t uvwasi_clockid_t;
@@ -152,7 +154,7 @@ typedef uint64_t uvwasi_inode_t;
152154

153155
typedef struct uvwasi_iovec_s {
154156
void* buf;
155-
size_t buf_len;
157+
uvwasi_size_t buf_len;
156158
} uvwasi_iovec_t;
157159

158160
typedef uint64_t uvwasi_linkcount_t;
@@ -173,7 +175,7 @@ typedef struct uvwasi_prestat_s {
173175
uvwasi_preopentype_t pr_type;
174176
union uvwasi_prestat_u {
175177
struct uvwasi_prestat_dir_t {
176-
size_t pr_name_len;
178+
uvwasi_size_t pr_name_len;
177179
} dir;
178180
} u;
179181
} uvwasi_prestat_t;

‎deps/uvwasi/src/debug.h

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#ifndef __UVWASI_DEBUG_H__
2+
#define __UVWASI_DEBUG_H__
3+
4+
#ifdef UVWASI_DEBUG_LOG
5+
# define __STDC_FORMAT_MACROS
6+
# include <inttypes.h>
7+
# define DEBUG(fmt, ...) \
8+
do { fprintf(stderr, fmt, __VA_ARGS__); } while (0)
9+
#else
10+
# define DEBUG(fmt, ...)
11+
#endif
12+
13+
#endif /* __UVWASI_DEBUG_H__ */

‎deps/uvwasi/src/fd_table.c

+15-11
Original file line numberDiff line numberDiff line change
@@ -181,26 +181,25 @@ uvwasi_errno_t uvwasi_fd_table_init(uvwasi_t* uvwasi,
181181
if (uvwasi == NULL || options == NULL || options->fd_table_size < 3)
182182
return UVWASI_EINVAL;
183183

184-
table = &uvwasi->fds;
185-
table->fds = NULL;
184+
table = uvwasi__malloc(uvwasi, sizeof(*table));
185+
if (table == NULL)
186+
return UVWASI_ENOMEM;
187+
186188
table->used = 0;
187189
table->size = options->fd_table_size;
188190
table->fds = uvwasi__calloc(uvwasi,
189191
options->fd_table_size,
190192
sizeof(struct uvwasi_fd_wrap_t*));
191-
192-
if (table->fds == NULL)
193+
if (table->fds == NULL) {
194+
uvwasi__free(uvwasi, table);
193195
return UVWASI_ENOMEM;
196+
}
194197

195198
r = uv_rwlock_init(&table->rwlock);
196199
if (r != 0) {
197200
err = uvwasi__translate_uv_error(r);
198-
/* Free table->fds and set it to NULL here. This is done explicitly instead
199-
of jumping to error_exit because uvwasi_fd_table_free() relies on fds
200-
being NULL to know whether or not to destroy the rwlock.
201-
*/
202201
uvwasi__free(uvwasi, table->fds);
203-
table->fds = NULL;
202+
uvwasi__free(uvwasi, table);
204203
return err;
205204
}
206205

@@ -217,6 +216,7 @@ uvwasi_errno_t uvwasi_fd_table_init(uvwasi_t* uvwasi,
217216
if (err != UVWASI_ESUCCESS)
218217
goto error_exit;
219218

219+
uvwasi->fds = table;
220220
return UVWASI_ESUCCESS;
221221
error_exit:
222222
uvwasi_fd_table_free(uvwasi, table);
@@ -228,12 +228,14 @@ void uvwasi_fd_table_free(uvwasi_t* uvwasi, struct uvwasi_fd_table_t* table) {
228228
struct uvwasi_fd_wrap_t* entry;
229229
uint32_t i;
230230

231-
if (table == NULL)
231+
if (uvwasi == NULL || table == NULL)
232232
return;
233233

234234
for (i = 0; i < table->size; i++) {
235235
entry = table->fds[i];
236-
if (entry == NULL) continue;
236+
237+
if (entry == NULL)
238+
continue;
237239

238240
uv_mutex_destroy(&entry->mutex);
239241
uvwasi__free(uvwasi, entry);
@@ -246,6 +248,8 @@ void uvwasi_fd_table_free(uvwasi_t* uvwasi, struct uvwasi_fd_table_t* table) {
246248
table->used = 0;
247249
uv_rwlock_destroy(&table->rwlock);
248250
}
251+
252+
uvwasi__free(uvwasi, table);
249253
}
250254

251255

File renamed without changes.

‎deps/uvwasi/src/path_resolver.c

+24-28
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
#endif /* _WIN32 */
1616

1717

18-
static int uvwasi__is_absolute_path(const char* path, size_t path_len) {
18+
static int uvwasi__is_absolute_path(const char* path, uvwasi_size_t path_len) {
1919
/* It's expected that only Unix style paths will be generated by WASI. */
2020
return path != NULL && path_len > 0 && path[0] == '/';
2121
}
@@ -33,9 +33,9 @@ static char* uvwasi__strchr_slash(const char* s) {
3333

3434

3535
uvwasi_errno_t uvwasi__normalize_path(const char* path,
36-
size_t path_len,
36+
uvwasi_size_t path_len,
3737
char* normalized_path,
38-
size_t normalized_len) {
38+
uvwasi_size_t normalized_len) {
3939
const char* cur;
4040
char* ptr;
4141
char* next;
@@ -125,9 +125,9 @@ uvwasi_errno_t uvwasi__normalize_path(const char* path,
125125

126126

127127
static int uvwasi__is_path_sandboxed(const char* path,
128-
size_t path_len,
128+
uvwasi_size_t path_len,
129129
const char* fd_path,
130-
size_t fd_path_len) {
130+
uvwasi_size_t fd_path_len) {
131131
char* ptr;
132132
int remaining_len;
133133

@@ -173,9 +173,9 @@ static uvwasi_errno_t uvwasi__normalize_absolute_path(
173173
const uvwasi_t* uvwasi,
174174
const struct uvwasi_fd_wrap_t* fd,
175175
const char* path,
176-
size_t path_len,
176+
uvwasi_size_t path_len,
177177
char** normalized_path,
178-
size_t* normalized_len
178+
uvwasi_size_t* normalized_len
179179
) {
180180
/* This function resolves an absolute path to the provided file descriptor.
181181
If the file descriptor's path is relative, then this operation will fail
@@ -224,9 +224,9 @@ static uvwasi_errno_t uvwasi__normalize_relative_path(
224224
const uvwasi_t* uvwasi,
225225
const struct uvwasi_fd_wrap_t* fd,
226226
const char* path,
227-
size_t path_len,
227+
uvwasi_size_t path_len,
228228
char** normalized_path,
229-
size_t* normalized_len
229+
uvwasi_size_t* normalized_len
230230
) {
231231
/* This function resolves a relative path to the provided file descriptor.
232232
The relative path is concatenated to the file descriptor's path, and then
@@ -298,9 +298,9 @@ static uvwasi_errno_t uvwasi__resolve_path_to_host(
298298
const uvwasi_t* uvwasi,
299299
const struct uvwasi_fd_wrap_t* fd,
300300
const char* path,
301-
size_t path_len,
301+
uvwasi_size_t path_len,
302302
char** resolved_path,
303-
size_t* resolved_len
303+
uvwasi_size_t* resolved_len
304304
) {
305305
/* Return the normalized path, but resolved to the host's real path. */
306306
char* res_path;
@@ -309,7 +309,7 @@ static uvwasi_errno_t uvwasi__resolve_path_to_host(
309309
int fake_path_len;
310310
int stripped_len;
311311
#ifdef _WIN32
312-
size_t i;
312+
uvwasi_size_t i;
313313
#endif /* _WIN32 */
314314

315315
real_path_len = strlen(fd->real_path);
@@ -351,6 +351,7 @@ static uvwasi_errno_t uvwasi__resolve_path_to_host(
351351

352352
#ifdef _WIN32
353353
/* Replace / with \ on Windows. */
354+
res_path = *resolved_path;
354355
for (i = real_path_len; i < *resolved_len; i++) {
355356
if (res_path[i] == '/')
356357
res_path[i] = '\\';
@@ -364,18 +365,18 @@ static uvwasi_errno_t uvwasi__resolve_path_to_host(
364365
uvwasi_errno_t uvwasi__resolve_path(const uvwasi_t* uvwasi,
365366
const struct uvwasi_fd_wrap_t* fd,
366367
const char* path,
367-
size_t path_len,
368-
char* resolved_path,
368+
uvwasi_size_t path_len,
369+
char** resolved_path,
369370
uvwasi_lookupflags_t flags) {
370371
uv_fs_t req;
371372
uvwasi_errno_t err;
372373
const char* input;
373374
char* host_path;
374375
char* normalized_path;
375376
char* link_target;
376-
size_t input_len;
377-
size_t host_path_len;
378-
size_t normalized_len;
377+
uvwasi_size_t input_len;
378+
uvwasi_size_t host_path_len;
379+
uvwasi_size_t normalized_len;
379380
int follow_count;
380381
int r;
381382

@@ -418,14 +419,6 @@ uvwasi_errno_t uvwasi__resolve_path(const uvwasi_t* uvwasi,
418419
if (err != UVWASI_ESUCCESS)
419420
goto exit;
420421

421-
/* TODO(cjihrig): Currently performing a bounds check here. The TODO is to
422-
stop allocating resolved_path in every caller and instead return the
423-
path allocated in this function. */
424-
if (host_path_len > PATH_MAX_BYTES) {
425-
err = UVWASI_ENOBUFS;
426-
goto exit;
427-
}
428-
429422
if ((flags & UVWASI_LOOKUP_SYMLINK_FOLLOW) == UVWASI_LOOKUP_SYMLINK_FOLLOW) {
430423
r = uv_fs_readlink(NULL, &req, host_path, NULL);
431424

@@ -482,11 +475,14 @@ uvwasi_errno_t uvwasi__resolve_path(const uvwasi_t* uvwasi,
482475
}
483476

484477
exit:
485-
if (err == UVWASI_ESUCCESS)
486-
memcpy(resolved_path, host_path, host_path_len + 1);
478+
if (err == UVWASI_ESUCCESS) {
479+
*resolved_path = host_path;
480+
} else {
481+
*resolved_path = NULL;
482+
uvwasi__free(uvwasi, host_path);
483+
}
487484

488485
uvwasi__free(uvwasi, link_target);
489486
uvwasi__free(uvwasi, normalized_path);
490-
uvwasi__free(uvwasi, host_path);
491487
return err;
492488
}

‎deps/uvwasi/src/path_resolver.h

+5-14
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,19 @@
11
#ifndef __UVWASI_PATH_RESOLVER_H__
22
#define __UVWASI_PATH_RESOLVER_H__
33

4+
#include "fd_table.h"
45
#include "uvwasi.h"
56

6-
/* TODO(cjihrig): PATH_MAX_BYTES shouldn't be stack allocated. On Windows, paths
7-
can be 32k long, and this PATH_MAX_BYTES is an artificial limitation. */
8-
#ifdef _WIN32
9-
/* MAX_PATH is in characters, not bytes. Make sure we have enough headroom. */
10-
# define PATH_MAX_BYTES (MAX_PATH * 4)
11-
#else
12-
# include <limits.h>
13-
# define PATH_MAX_BYTES (PATH_MAX)
14-
#endif
15-
167
uvwasi_errno_t uvwasi__normalize_path(const char* path,
17-
size_t path_len,
8+
uvwasi_size_t path_len,
189
char* normalized_path,
19-
size_t normalized_len);
10+
uvwasi_size_t normalized_len);
2011

2112
uvwasi_errno_t uvwasi__resolve_path(const uvwasi_t* uvwasi,
2213
const struct uvwasi_fd_wrap_t* fd,
2314
const char* path,
24-
size_t path_len,
25-
char* resolved_path,
15+
uvwasi_size_t path_len,
16+
char** resolved_path,
2617
uvwasi_lookupflags_t flags);
2718

2819
#endif /* __UVWASI_PATH_RESOLVER_H__ */

‎deps/uvwasi/src/poll_oneoff.c

+267
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,267 @@
1+
#include "uv.h"
2+
#include "poll_oneoff.h"
3+
#include "uv_mapping.h"
4+
#include "uvwasi_alloc.h"
5+
6+
7+
static void poll_cb(uv_poll_t* handle, int status, int events) {
8+
struct uvwasi_poll_oneoff_state_t* state;
9+
struct uvwasi__poll_fdevent_t* event;
10+
11+
uv_poll_stop(handle);
12+
event = uv_handle_get_data((uv_handle_t*) handle);
13+
event->revents = events;
14+
15+
if (status != 0)
16+
event->error = UVWASI_EIO;
17+
18+
state = uv_loop_get_data(handle->loop);
19+
state->result++;
20+
}
21+
22+
23+
static void timeout_cb(uv_timer_t* handle) {
24+
struct uvwasi_poll_oneoff_state_t* state;
25+
uvwasi_size_t i;
26+
27+
state = uv_loop_get_data(handle->loop);
28+
29+
for (i = 0; i < state->handle_cnt; i++)
30+
uv_poll_stop(&state->poll_handles[i]);
31+
}
32+
33+
34+
uvwasi_errno_t uvwasi__poll_oneoff_state_init(
35+
uvwasi_t* uvwasi,
36+
struct uvwasi_poll_oneoff_state_t* state,
37+
uvwasi_size_t max_fds
38+
) {
39+
uvwasi_errno_t err;
40+
int r;
41+
42+
if (uvwasi == NULL || state == NULL)
43+
return UVWASI_EINVAL;
44+
45+
state->uvwasi = NULL;
46+
state->timeout = 0;
47+
state->has_timer = 0;
48+
state->fdevents = NULL;
49+
state->poll_handles = NULL;
50+
state->max_fds = 0;
51+
state->fdevent_cnt = 0;
52+
state->handle_cnt = 0;
53+
state->result = 0;
54+
55+
r = uv_loop_init(&state->loop);
56+
if (r != 0)
57+
return uvwasi__translate_uv_error(r);
58+
59+
if (max_fds > 0) {
60+
state->fdevents = uvwasi__calloc(uvwasi,
61+
max_fds,
62+
sizeof(*state->fdevents));
63+
if (state->fdevents == NULL) {
64+
err = UVWASI_ENOMEM;
65+
goto error_exit;
66+
}
67+
68+
state->poll_handles = uvwasi__calloc(uvwasi,
69+
max_fds,
70+
sizeof(*state->poll_handles));
71+
if (state->poll_handles == NULL) {
72+
err = UVWASI_ENOMEM;
73+
goto error_exit;
74+
}
75+
}
76+
77+
uv_loop_set_data(&state->loop, (void*) state);
78+
state->uvwasi = uvwasi;
79+
state->max_fds = max_fds;
80+
81+
return UVWASI_ESUCCESS;
82+
83+
error_exit:
84+
uv_loop_close(&state->loop);
85+
uvwasi__free(state->uvwasi, state->fdevents);
86+
uvwasi__free(state->uvwasi, state->poll_handles);
87+
return err;
88+
}
89+
90+
91+
uvwasi_errno_t uvwasi__poll_oneoff_state_cleanup(
92+
struct uvwasi_poll_oneoff_state_t* state
93+
) {
94+
struct uvwasi__poll_fdevent_t* event;
95+
uvwasi_size_t i;
96+
int r;
97+
98+
if (state == NULL)
99+
return UVWASI_EINVAL;
100+
101+
if (state->has_timer != 0) {
102+
state->timeout = 0;
103+
state->has_timer = 0;
104+
uv_close((uv_handle_t*) &state->timer, NULL);
105+
}
106+
107+
for (i = 0; i < state->fdevent_cnt; i++) {
108+
event = &state->fdevents[i];
109+
110+
if (event->is_duplicate_fd == 0 && event->wrap != NULL)
111+
uv_mutex_unlock(&event->wrap->mutex);
112+
}
113+
114+
for (i = 0; i < state->handle_cnt; i++)
115+
uv_close((uv_handle_t*) &state->poll_handles[i], NULL);
116+
117+
state->max_fds = 0;
118+
state->fdevent_cnt = 0;
119+
state->handle_cnt = 0;
120+
121+
uvwasi__free(state->uvwasi, state->fdevents);
122+
uvwasi__free(state->uvwasi, state->poll_handles);
123+
state->fdevents = NULL;
124+
state->poll_handles = NULL;
125+
state->uvwasi = NULL;
126+
127+
r = uv_loop_close(&state->loop);
128+
if (r != 0)
129+
return uvwasi__translate_uv_error(r);
130+
131+
return UVWASI_ESUCCESS;
132+
}
133+
134+
135+
uvwasi_errno_t uvwasi__poll_oneoff_state_set_timer(
136+
struct uvwasi_poll_oneoff_state_t* state,
137+
uvwasi_timestamp_t timeout
138+
) {
139+
int r;
140+
141+
if (state == NULL)
142+
return UVWASI_EINVAL;
143+
144+
r = uv_timer_init(&state->loop, &state->timer);
145+
if (r != 0)
146+
return uvwasi__translate_uv_error(r);
147+
148+
/* Convert WASI timeout from nanoseconds to milliseconds for libuv. */
149+
state->timeout = timeout / 1000000;
150+
state->has_timer = 1;
151+
return UVWASI_ESUCCESS;
152+
}
153+
154+
155+
uvwasi_errno_t uvwasi__poll_oneoff_state_add_fdevent(
156+
struct uvwasi_poll_oneoff_state_t* state,
157+
uvwasi_subscription_t* subscription
158+
) {
159+
struct uvwasi__poll_fdevent_t* event;
160+
struct uvwasi__poll_fdevent_t* dup;
161+
uv_poll_t* poll_handle;
162+
uvwasi_eventtype_t type;
163+
uvwasi_rights_t rights;
164+
uvwasi_fd_t fd;
165+
uvwasi_errno_t err;
166+
uvwasi_size_t i;
167+
int r;
168+
169+
if (state == NULL)
170+
return UVWASI_EINVAL;
171+
172+
event = &state->fdevents[state->fdevent_cnt];
173+
fd = subscription->u.fd_readwrite.fd;
174+
type = subscription->type;
175+
176+
if (type == UVWASI_EVENTTYPE_FD_READ) {
177+
event->events = UV_DISCONNECT | UV_READABLE;
178+
rights = UVWASI_RIGHT_POLL_FD_READWRITE | UVWASI_RIGHT_FD_READ;
179+
} else if (type == UVWASI_EVENTTYPE_FD_WRITE) {
180+
event->events = UV_DISCONNECT | UV_WRITABLE;
181+
rights = UVWASI_RIGHT_POLL_FD_READWRITE | UVWASI_RIGHT_FD_WRITE;
182+
} else {
183+
return UVWASI_EINVAL;
184+
}
185+
186+
/* Check if the same file descriptor is already being polled. If so, use the
187+
wrap and poll handle from the first descriptor. The reasons are that libuv
188+
does not support polling the same fd more than once at the same time, and
189+
uvwasi has the fd's mutex locked. */
190+
event->is_duplicate_fd = 0;
191+
for (i = 0; i < state->fdevent_cnt; i++) {
192+
dup = &state->fdevents[i];
193+
if (dup->wrap->id == fd) {
194+
event->is_duplicate_fd = 1;
195+
event->wrap = dup->wrap;
196+
event->poll_handle = dup->poll_handle;
197+
err = event->error;
198+
goto poll_config_done;
199+
}
200+
}
201+
202+
/* Get the file descriptor. If UVWASI_EBADF is returned, continue on, but
203+
don't do any polling with the handle. */
204+
err = uvwasi_fd_table_get(state->uvwasi->fds, fd, &event->wrap, rights, 0);
205+
if (err == UVWASI_EBADF)
206+
event->wrap = NULL;
207+
else if (err != UVWASI_ESUCCESS)
208+
return err;
209+
210+
if (err == UVWASI_ESUCCESS) {
211+
/* The fd is valid, so setup the poll handle. */
212+
poll_handle = &state->poll_handles[state->handle_cnt];
213+
r = uv_poll_init(&state->loop, poll_handle, event->wrap->fd);
214+
215+
if (r != 0) {
216+
/* If uv_poll_init() fails (for example on Windows because only sockets
217+
are supported), set the error for this event to UVWASI_EBADF, but don't
218+
do any polling with the handle. */
219+
uv_mutex_unlock(&event->wrap->mutex);
220+
return uvwasi__translate_uv_error(r);
221+
} else {
222+
r = uv_poll_start(poll_handle,
223+
event->events,
224+
poll_cb);
225+
if (r != 0) {
226+
uv_mutex_unlock(&event->wrap->mutex);
227+
uv_close((uv_handle_t*) poll_handle, NULL);
228+
return uvwasi__translate_uv_error(r);
229+
}
230+
231+
uv_handle_set_data((uv_handle_t*) poll_handle,
232+
(void*) &state->fdevents[state->fdevent_cnt]);
233+
event->poll_handle = poll_handle;
234+
state->handle_cnt++;
235+
}
236+
}
237+
238+
poll_config_done:
239+
event->type = type;
240+
event->userdata = subscription->userdata;
241+
event->error = err;
242+
event->revents = 0;
243+
state->fdevent_cnt++;
244+
return UVWASI_ESUCCESS;
245+
}
246+
247+
248+
uvwasi_errno_t uvwasi__poll_oneoff_run(
249+
struct uvwasi_poll_oneoff_state_t* state
250+
) {
251+
int r;
252+
253+
if (state->has_timer == 1) {
254+
r = uv_timer_start(&state->timer, timeout_cb, state->timeout, 0);
255+
if (r != 0)
256+
return uvwasi__translate_uv_error(r);
257+
258+
if (state->fdevent_cnt > 0)
259+
uv_unref((uv_handle_t*) &state->timer);
260+
}
261+
262+
r = uv_run(&state->loop, UV_RUN_DEFAULT);
263+
if (r != 0)
264+
return uvwasi__translate_uv_error(r);
265+
266+
return UVWASI_ESUCCESS;
267+
}

‎deps/uvwasi/src/poll_oneoff.h

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#ifndef __UVWASI_POLL_ONEOFF_H__
2+
#define __UVWASI_POLL_ONEOFF_H__
3+
4+
#include "fd_table.h"
5+
#include "wasi_types.h"
6+
7+
struct uvwasi_s;
8+
9+
struct uvwasi__poll_fdevent_t {
10+
struct uvwasi_fd_wrap_t* wrap;
11+
uvwasi_userdata_t userdata;
12+
uvwasi_eventtype_t type;
13+
uvwasi_errno_t error;
14+
uv_poll_t* poll_handle;
15+
int is_duplicate_fd;
16+
int events;
17+
int revents;
18+
};
19+
20+
struct uvwasi_poll_oneoff_state_t {
21+
struct uvwasi_s* uvwasi;
22+
struct uvwasi__poll_fdevent_t* fdevents;
23+
uv_poll_t* poll_handles;
24+
uv_timer_t timer;
25+
uint64_t timeout;
26+
uv_loop_t loop;
27+
uvwasi_size_t max_fds;
28+
int has_timer;
29+
uvwasi_size_t fdevent_cnt;
30+
uvwasi_size_t handle_cnt;
31+
int result;
32+
};
33+
34+
35+
uvwasi_errno_t uvwasi__poll_oneoff_state_init(
36+
struct uvwasi_s* uvwasi,
37+
struct uvwasi_poll_oneoff_state_t* state,
38+
uvwasi_size_t max_fds
39+
);
40+
41+
uvwasi_errno_t uvwasi__poll_oneoff_state_cleanup(
42+
struct uvwasi_poll_oneoff_state_t* state
43+
);
44+
45+
uvwasi_errno_t uvwasi__poll_oneoff_state_set_timer(
46+
struct uvwasi_poll_oneoff_state_t* state,
47+
uvwasi_timestamp_t timeout
48+
);
49+
50+
uvwasi_errno_t uvwasi__poll_oneoff_state_add_fdevent(
51+
struct uvwasi_poll_oneoff_state_t* state,
52+
uvwasi_subscription_t* subscription
53+
);
54+
55+
uvwasi_errno_t uvwasi__poll_oneoff_run(
56+
struct uvwasi_poll_oneoff_state_t* state
57+
);
58+
59+
60+
#endif /* __UVWASI_POLL_ONEOFF_H__ */

‎deps/uvwasi/src/uvwasi.c

+530-131
Large diffs are not rendered by default.

‎deps/uvwasi/src/wasi_serdes.c

+259
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,259 @@
1+
#include "wasi_serdes.h"
2+
#include "wasi_types.h"
3+
4+
void uvwasi_serdes_write_uint64_t(void* ptr,
5+
size_t offset,
6+
uint64_t value) {
7+
uvwasi_serdes_write_uint32_t(ptr, offset, (uint32_t) value);
8+
uvwasi_serdes_write_uint32_t(ptr, offset + 4, value >> 32);
9+
}
10+
11+
void uvwasi_serdes_write_uint32_t(void* ptr,
12+
size_t offset,
13+
uint32_t value) {
14+
uvwasi_serdes_write_uint16_t(ptr, offset, (uint16_t) value);
15+
uvwasi_serdes_write_uint16_t(ptr, offset + 2, value >> 16);
16+
}
17+
18+
void uvwasi_serdes_write_uint16_t(void* ptr,
19+
size_t offset,
20+
uint16_t value) {
21+
uvwasi_serdes_write_uint8_t(ptr, offset, (uint8_t) value);
22+
uvwasi_serdes_write_uint8_t(ptr, offset + 1, value >> 8);
23+
}
24+
25+
void uvwasi_serdes_write_uint8_t(void* ptr,
26+
size_t offset,
27+
uint8_t value) {
28+
((uint8_t*) ptr)[offset] = value;
29+
}
30+
31+
uint64_t uvwasi_serdes_read_uint64_t(const void* ptr, size_t offset) {
32+
uint64_t low = uvwasi_serdes_read_uint32_t(ptr, offset);
33+
uint64_t high = uvwasi_serdes_read_uint32_t(ptr, offset + 4);
34+
return low | (high << 32);
35+
}
36+
37+
uint32_t uvwasi_serdes_read_uint32_t(const void* ptr, size_t offset) {
38+
uint32_t low = uvwasi_serdes_read_uint16_t(ptr, offset);
39+
uint32_t high = uvwasi_serdes_read_uint16_t(ptr, offset + 2);
40+
return low | (high << 16);
41+
}
42+
43+
uint16_t uvwasi_serdes_read_uint16_t(const void* ptr, size_t offset) {
44+
uint16_t low = uvwasi_serdes_read_uint8_t(ptr, offset);
45+
uint16_t high = uvwasi_serdes_read_uint8_t(ptr, offset + 1);
46+
return low | (high << 8);
47+
}
48+
49+
uint8_t uvwasi_serdes_read_uint8_t(const void* ptr, size_t offset) {
50+
return ((const uint8_t*) ptr)[offset];
51+
}
52+
53+
#define TYPE_SWITCH switch (value->type)
54+
55+
#define ALL_TYPES(STRUCT, FIELD, ALIAS) \
56+
\
57+
ALIAS(advice_t, uint8_t) \
58+
ALIAS(clockid_t, uint32_t) \
59+
ALIAS(device_t, uint64_t) \
60+
ALIAS(dircookie_t, uint64_t) \
61+
ALIAS(errno_t, uint16_t) \
62+
ALIAS(eventrwflags_t, uint16_t) \
63+
ALIAS(eventtype_t, uint8_t) \
64+
ALIAS(exitcode_t, uint32_t) \
65+
ALIAS(fd_t, uint32_t) \
66+
ALIAS(fdflags_t, uint16_t) \
67+
ALIAS(filesize_t, uint64_t) \
68+
ALIAS(filetype_t, uint8_t) \
69+
ALIAS(fstflags_t, uint16_t) \
70+
ALIAS(inode_t, uint64_t) \
71+
ALIAS(linkcount_t, uint64_t) \
72+
ALIAS(lookupflags_t, uint32_t) \
73+
ALIAS(oflags_t, uint16_t) \
74+
ALIAS(preopentype_t, uint8_t) \
75+
ALIAS(riflags_t, uint16_t) \
76+
ALIAS(rights_t, uint64_t) \
77+
ALIAS(roflags_t, uint16_t) \
78+
ALIAS(sdflags_t, uint8_t) \
79+
ALIAS(siflags_t, uint16_t) \
80+
ALIAS(signal_t, uint8_t) \
81+
ALIAS(size_t, uint32_t) \
82+
ALIAS(subclockflags_t, uint16_t) \
83+
ALIAS(timestamp_t, uint64_t) \
84+
ALIAS(userdata_t, uint64_t) \
85+
ALIAS(whence_t, uint8_t) \
86+
\
87+
STRUCT(fdstat_t) { \
88+
FIELD( 0, filetype_t, fs_filetype); \
89+
FIELD( 2, fdflags_t, fs_flags); \
90+
FIELD( 8, rights_t, fs_rights_base); \
91+
FIELD(16, rights_t, fs_rights_inheriting); \
92+
} \
93+
\
94+
STRUCT(filestat_t) { \
95+
FIELD( 0, device_t, st_dev); \
96+
FIELD( 8, inode_t, st_ino); \
97+
FIELD(16, filetype_t, st_filetype); \
98+
FIELD(24, linkcount_t, st_nlink); \
99+
FIELD(32, filesize_t, st_size); \
100+
FIELD(40, timestamp_t, st_atim); \
101+
FIELD(48, timestamp_t, st_mtim); \
102+
FIELD(56, timestamp_t, st_ctim); \
103+
} \
104+
\
105+
STRUCT(prestat_t) { \
106+
FIELD(0, preopentype_t, pr_type); \
107+
FIELD(4, uint32_t, u.dir.pr_name_len); \
108+
} \
109+
\
110+
STRUCT(event_t) { \
111+
FIELD( 0, userdata_t, userdata); \
112+
FIELD( 8, errno_t, error); \
113+
FIELD(10, eventtype_t, type); \
114+
TYPE_SWITCH { \
115+
case UVWASI_EVENTTYPE_FD_READ: \
116+
case UVWASI_EVENTTYPE_FD_WRITE: \
117+
FIELD(16, filesize_t, u.fd_readwrite.nbytes); \
118+
FIELD(24, eventrwflags_t, u.fd_readwrite.flags); \
119+
} \
120+
} \
121+
\
122+
STRUCT(subscription_t) { \
123+
FIELD(0, userdata_t, userdata); \
124+
FIELD(8, eventtype_t, type); \
125+
TYPE_SWITCH { \
126+
case UVWASI_EVENTTYPE_CLOCK: \
127+
FIELD(16, clockid_t, u.clock.clock_id); \
128+
FIELD(24, timestamp_t, u.clock.timeout); \
129+
FIELD(32, timestamp_t, u.clock.precision); \
130+
FIELD(40, subclockflags_t, u.clock.flags); \
131+
break; \
132+
case UVWASI_EVENTTYPE_FD_READ: \
133+
case UVWASI_EVENTTYPE_FD_WRITE: \
134+
FIELD(16, fd_t, u.fd_readwrite.fd); \
135+
} \
136+
} \
137+
138+
#define WRITE_STRUCT(name) \
139+
void uvwasi_serdes_write_##name(void* ptr, \
140+
size_t offset, \
141+
const uvwasi_##name* value) \
142+
143+
#define READ_STRUCT(name) \
144+
void uvwasi_serdes_read_##name(const void* ptr, \
145+
size_t offset, \
146+
uvwasi_##name* value) \
147+
148+
#define WRITE_FIELD(field_offset, type, field) \
149+
do { \
150+
uvwasi_serdes_write_##type(ptr, offset + field_offset, value->field); \
151+
} while (0) \
152+
153+
#define READ_FIELD(field_offset, type, field) \
154+
do { \
155+
value->field = uvwasi_serdes_read_##type(ptr, offset + field_offset); \
156+
} while (0) \
157+
158+
#define WRITE_ALIAS(new_name, old_name) \
159+
void uvwasi_serdes_write_##new_name(void* ptr, \
160+
size_t offset, \
161+
uvwasi_##new_name value) { \
162+
uvwasi_serdes_write_##old_name(ptr, offset, value); \
163+
} \
164+
165+
#define READ_ALIAS(new_name, old_name) \
166+
uvwasi_##new_name uvwasi_serdes_read_##new_name(const void* ptr, \
167+
size_t offset) { \
168+
return uvwasi_serdes_read_##old_name(ptr, offset); \
169+
} \
170+
171+
ALL_TYPES(WRITE_STRUCT, WRITE_FIELD, WRITE_ALIAS)
172+
ALL_TYPES(READ_STRUCT, READ_FIELD, READ_ALIAS)
173+
174+
175+
uvwasi_errno_t uvwasi_serdes_read_ciovec_t(const void* ptr,
176+
size_t end,
177+
size_t offset,
178+
uvwasi_ciovec_t* value) {
179+
uint32_t buf_ptr;
180+
181+
buf_ptr = uvwasi_serdes_read_uint32_t(ptr, offset);
182+
value->buf_len = uvwasi_serdes_read_size_t(ptr, offset + 4);
183+
184+
if (!uvwasi_serdes_check_bounds(buf_ptr, end, value->buf_len))
185+
return UVWASI_EOVERFLOW;
186+
187+
value->buf = ((uint8_t*) ptr + buf_ptr);
188+
return UVWASI_ESUCCESS;
189+
}
190+
191+
192+
uvwasi_errno_t uvwasi_serdes_read_iovec_t(const void* ptr,
193+
size_t end,
194+
size_t offset,
195+
uvwasi_iovec_t* value) {
196+
uint32_t buf_ptr;
197+
198+
buf_ptr = uvwasi_serdes_read_uint32_t(ptr, offset);
199+
value->buf_len = uvwasi_serdes_read_size_t(ptr, offset + 4);
200+
201+
if (!uvwasi_serdes_check_bounds(buf_ptr, end, value->buf_len))
202+
return UVWASI_EOVERFLOW;
203+
204+
value->buf = ((uint8_t*) ptr + buf_ptr);
205+
return UVWASI_ESUCCESS;
206+
}
207+
208+
209+
uvwasi_errno_t uvwasi_serdes_readv_ciovec_t(const void* ptr,
210+
size_t end,
211+
size_t offset,
212+
uvwasi_ciovec_t* iovs,
213+
uvwasi_size_t iovs_len) {
214+
uvwasi_errno_t err;
215+
uvwasi_size_t i;
216+
217+
for (i = 0; i < iovs_len; i++) {
218+
err = uvwasi_serdes_read_ciovec_t(ptr, end, offset, &iovs[i]);
219+
if (err != UVWASI_ESUCCESS)
220+
return err;
221+
offset += UVWASI_SERDES_SIZE_ciovec_t;
222+
}
223+
224+
return UVWASI_ESUCCESS;
225+
}
226+
227+
228+
uvwasi_errno_t uvwasi_serdes_readv_iovec_t(const void* ptr,
229+
size_t end,
230+
size_t offset,
231+
uvwasi_iovec_t* iovs,
232+
uvwasi_size_t iovs_len) {
233+
uvwasi_errno_t err;
234+
uvwasi_size_t i;
235+
236+
for (i = 0; i < iovs_len; i++) {
237+
err = uvwasi_serdes_read_iovec_t(ptr, end, offset, &iovs[i]);
238+
if (err != UVWASI_ESUCCESS)
239+
return err;
240+
offset += UVWASI_SERDES_SIZE_iovec_t;
241+
}
242+
243+
return UVWASI_ESUCCESS;
244+
}
245+
246+
247+
int uvwasi_serdes_check_bounds(size_t offset, size_t end, size_t size) {
248+
return end > offset && size <= (end - offset);
249+
}
250+
251+
252+
int uvwasi_serdes_check_array_bounds(size_t offset,
253+
size_t end,
254+
size_t size,
255+
size_t count) {
256+
return end > offset &&
257+
((count * size) / size == count) &&
258+
(count * size <= end - offset);
259+
}

‎deps/uvwasi/uvwasi.gyp

+2
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@
1212
'src/clocks.c',
1313
'src/fd_table.c',
1414
'src/path_resolver.c',
15+
'src/poll_oneoff.c',
1516
'src/uv_mapping.c',
1617
'src/uvwasi.c',
1718
'src/wasi_rights.c',
19+
'src/wasi_serdes.c',
1820
],
1921
'dependencies': [
2022
'../uv/uv.gyp:libuv',

‎src/node_wasi.cc

+239-346
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)
Please sign in to comment.