1 //
2 // m3_api_esp_wasi.c
3 //
4 // Created by Volodymyr Shymanskyy on 01/07/20.
5 // Copyright © 2019 Volodymyr Shymanskyy. All rights reserved.
6 //
7
8 #define _POSIX_C_SOURCE 200809L
9
10 #include "m3_api_esp_wasi.h"
11
12 #include "m3/m3_env.h"
13 #include "m3/m3_exception.h"
14
15 #if defined(ESP32)
16
17 typedef uint32_t __wasi_size_t;
18 #include "m3/extra/wasi_core.h"
19
20 #include <sys/types.h>
21 #include <sys/stat.h>
22 #include <time.h>
23 #include <errno.h>
24 #include <stdio.h>
25 #include <fcntl.h>
26 #include <unistd.h>
27
28 typedef struct wasi_iovec_t
29 {
30 __wasi_size_t buf;
31 __wasi_size_t buf_len;
32 } wasi_iovec_t;
33
34 #define PREOPEN_CNT 3
35
36 typedef struct Preopen {
37 int fd;
38 char* path;
39 } Preopen;
40
41 Preopen preopen[PREOPEN_CNT] = {
42 { 0, "<stdin>" },
43 { 1, "<stdout>" },
44 { 2, "<stderr>" },
45 };
46
47 static
errno_to_wasi(int errnum)48 __wasi_errno_t errno_to_wasi(int errnum) {
49 switch (errnum) {
50 case EPERM: return __WASI_EPERM; break;
51 case ENOENT: return __WASI_ENOENT; break;
52 case ESRCH: return __WASI_ESRCH; break;
53 case EINTR: return __WASI_EINTR; break;
54 case EIO: return __WASI_EIO; break;
55 case ENXIO: return __WASI_ENXIO; break;
56 case E2BIG: return __WASI_E2BIG; break;
57 case ENOEXEC: return __WASI_ENOEXEC; break;
58 case EBADF: return __WASI_EBADF; break;
59 case ECHILD: return __WASI_ECHILD; break;
60 case EAGAIN: return __WASI_EAGAIN; break;
61 case ENOMEM: return __WASI_ENOMEM; break;
62 case EACCES: return __WASI_EACCES; break;
63 case EFAULT: return __WASI_EFAULT; break;
64 case EBUSY: return __WASI_EBUSY; break;
65 case EEXIST: return __WASI_EEXIST; break;
66 case EXDEV: return __WASI_EXDEV; break;
67 case ENODEV: return __WASI_ENODEV; break;
68 case ENOTDIR: return __WASI_ENOTDIR; break;
69 case EISDIR: return __WASI_EISDIR; break;
70 case EINVAL: return __WASI_EINVAL; break;
71 case ENFILE: return __WASI_ENFILE; break;
72 case EMFILE: return __WASI_EMFILE; break;
73 case ENOTTY: return __WASI_ENOTTY; break;
74 case ETXTBSY: return __WASI_ETXTBSY; break;
75 case EFBIG: return __WASI_EFBIG; break;
76 case ENOSPC: return __WASI_ENOSPC; break;
77 case ESPIPE: return __WASI_ESPIPE; break;
78 case EROFS: return __WASI_EROFS; break;
79 case EMLINK: return __WASI_EMLINK; break;
80 case EPIPE: return __WASI_EPIPE; break;
81 case EDOM: return __WASI_EDOM; break;
82 case ERANGE: return __WASI_ERANGE; break;
83 default: return __WASI_EINVAL;
84 }
85 }
86
87 static inline
convert_clockid(__wasi_clockid_t in)88 int convert_clockid(__wasi_clockid_t in) {
89 switch (in) {
90 case __WASI_CLOCK_MONOTONIC: return CLOCK_MONOTONIC;
91 //case __WASI_CLOCK_PROCESS_CPUTIME_ID: return CLOCK_PROCESS_CPUTIME_ID;
92 case __WASI_CLOCK_REALTIME: return CLOCK_REALTIME;
93 //case __WASI_CLOCK_THREAD_CPUTIME_ID: return CLOCK_THREAD_CPUTIME_ID;
94 default: return -1;
95 }
96 }
97
98 static inline
convert_timespec(const struct timespec * ts)99 __wasi_timestamp_t convert_timespec(const struct timespec *ts) {
100 if (ts->tv_sec < 0)
101 return 0;
102 if ((__wasi_timestamp_t)ts->tv_sec >= UINT64_MAX / 1000000000)
103 return UINT64_MAX;
104 return (__wasi_timestamp_t)ts->tv_sec * 1000000000 + ts->tv_nsec;
105 }
106
107
108 /*
109 * WASI API implementation
110 */
111
m3ApiRawFunction(m3_wasi_unstable_args_get)112 m3ApiRawFunction(m3_wasi_unstable_args_get)
113 {
114 m3ApiReturnType (uint32_t)
115 m3ApiGetArgMem (uint32_t * , argv)
116 m3ApiGetArgMem (char * , argv_buf)
117
118 if (runtime == NULL) { m3ApiReturn(__WASI_EINVAL); }
119
120 for (u32 i = 0; i < runtime->argc; ++i)
121 {
122 m3ApiWriteMem32(&argv[i], m3ApiPtrToOffset(argv_buf));
123
124 size_t len = strlen (runtime->argv[i]);
125 memcpy (argv_buf, runtime->argv[i], len);
126 argv_buf += len;
127 * argv_buf++ = 0;
128 }
129
130 m3ApiReturn(__WASI_ESUCCESS);
131 }
132
m3ApiRawFunction(m3_wasi_unstable_args_sizes_get)133 m3ApiRawFunction(m3_wasi_unstable_args_sizes_get)
134 {
135 m3ApiReturnType (uint32_t)
136 m3ApiGetArgMem (__wasi_size_t * , argc)
137 m3ApiGetArgMem (__wasi_size_t * , argv_buf_size)
138
139 if (runtime == NULL) { m3ApiReturn(__WASI_EINVAL); }
140
141 __wasi_size_t buflen = 0;
142 for (u32 i = 0; i < runtime->argc; ++i)
143 {
144 buflen += strlen (runtime->argv[i]) + 1;
145 }
146
147 m3ApiWriteMem32(argc, runtime->argc);
148 m3ApiWriteMem32(argv_buf_size, buflen);
149
150 m3ApiReturn(__WASI_ESUCCESS);
151 }
152
m3ApiRawFunction(m3_wasi_unstable_environ_get)153 m3ApiRawFunction(m3_wasi_unstable_environ_get)
154 {
155 m3ApiReturnType (uint32_t)
156 m3ApiGetArgMem (uint32_t * , env)
157 m3ApiGetArgMem (char * , env_buf)
158
159 if (runtime == NULL) { m3ApiReturn(__WASI_EINVAL); }
160 // TODO
161 m3ApiReturn(__WASI_ESUCCESS);
162 }
163
m3ApiRawFunction(m3_wasi_unstable_environ_sizes_get)164 m3ApiRawFunction(m3_wasi_unstable_environ_sizes_get)
165 {
166 m3ApiReturnType (uint32_t)
167 m3ApiGetArgMem (__wasi_size_t * , env_count)
168 m3ApiGetArgMem (__wasi_size_t * , env_buf_size)
169
170 if (runtime == NULL) { m3ApiReturn(__WASI_EINVAL); }
171
172 // TODO
173 m3ApiWriteMem32(env_count, 0);
174 m3ApiWriteMem32(env_buf_size, 0);
175
176 m3ApiReturn(__WASI_ESUCCESS);
177 }
178
m3ApiRawFunction(m3_wasi_unstable_fd_prestat_dir_name)179 m3ApiRawFunction(m3_wasi_unstable_fd_prestat_dir_name)
180 {
181 m3ApiReturnType (uint32_t)
182 m3ApiGetArg (__wasi_fd_t , fd)
183 m3ApiGetArgMem (char * , path)
184 m3ApiGetArg (__wasi_size_t , path_len)
185
186 if (runtime == NULL) { m3ApiReturn(__WASI_EINVAL); }
187 if (fd < 3 || fd >= PREOPEN_CNT) { m3ApiReturn(__WASI_EBADF); }
188 size_t slen = strlen(preopen[fd].path);
189 memcpy(path, preopen[fd].path, M3_MIN(slen, path_len));
190 m3ApiReturn(__WASI_ESUCCESS);
191 }
192
m3ApiRawFunction(m3_wasi_unstable_fd_prestat_get)193 m3ApiRawFunction(m3_wasi_unstable_fd_prestat_get)
194 {
195 m3ApiReturnType (uint32_t)
196 m3ApiGetArg (__wasi_fd_t , fd)
197 m3ApiGetArgMem (uint32_t * , buf) // TODO: use actual struct
198
199 if (runtime == NULL) { m3ApiReturn(__WASI_EINVAL); }
200 if (fd < 3 || fd >= PREOPEN_CNT) { m3ApiReturn(__WASI_EBADF); }
201 m3ApiWriteMem32(buf, __WASI_PREOPENTYPE_DIR);
202 m3ApiWriteMem32(buf+1, strlen(preopen[fd].path));
203 m3ApiReturn(__WASI_ESUCCESS);
204 }
205
m3ApiRawFunction(m3_wasi_unstable_fd_fdstat_get)206 m3ApiRawFunction(m3_wasi_unstable_fd_fdstat_get)
207 {
208 m3ApiReturnType (uint32_t)
209 m3ApiGetArg (__wasi_fd_t , fd)
210 m3ApiGetArgMem (__wasi_fdstat_t * , fdstat)
211
212 if (runtime == NULL || fdstat == NULL) { m3ApiReturn(__WASI_EINVAL); }
213
214 struct stat fd_stat;
215 int fl = fcntl(fd, F_GETFL);
216 if (fl < 0) { m3ApiReturn(errno_to_wasi(errno)); }
217 fstat(fd, &fd_stat);
218 int mode = fd_stat.st_mode;
219 fdstat->fs_filetype = (S_ISBLK(mode) ? __WASI_FILETYPE_BLOCK_DEVICE : 0) |
220 (S_ISCHR(mode) ? __WASI_FILETYPE_CHARACTER_DEVICE : 0) |
221 (S_ISDIR(mode) ? __WASI_FILETYPE_DIRECTORY : 0) |
222 (S_ISREG(mode) ? __WASI_FILETYPE_REGULAR_FILE : 0) |
223 //(S_ISSOCK(mode) ? __WASI_FILETYPE_SOCKET_STREAM : 0) |
224 (S_ISLNK(mode) ? __WASI_FILETYPE_SYMBOLIC_LINK : 0);
225 m3ApiWriteMem16(&fdstat->fs_flags,
226 ((fl & O_APPEND) ? __WASI_FDFLAG_APPEND : 0) |
227 //((fl & O_DSYNC) ? __WASI_FDFLAG_DSYNC : 0) |
228 ((fl & O_NONBLOCK) ? __WASI_FDFLAG_NONBLOCK : 0) |
229 //((fl & O_RSYNC) ? __WASI_FDFLAG_RSYNC : 0) |
230 ((fl & O_SYNC) ? __WASI_FDFLAG_SYNC : 0));
231 fdstat->fs_rights_base = (uint64_t)-1; // all rights
232 fdstat->fs_rights_inheriting = (uint64_t)-1; // all rights
233 m3ApiReturn(__WASI_ESUCCESS);
234 }
235
m3ApiRawFunction(m3_wasi_unstable_fd_fdstat_set_flags)236 m3ApiRawFunction(m3_wasi_unstable_fd_fdstat_set_flags)
237 {
238 m3ApiReturnType (uint32_t)
239 m3ApiGetArg (__wasi_fd_t , fd)
240 m3ApiGetArg (__wasi_fdflags_t , flags)
241
242 // TODO
243
244 m3ApiReturn(__WASI_ESUCCESS);
245 }
246
m3ApiRawFunction(m3_wasi_unstable_fd_seek)247 m3ApiRawFunction(m3_wasi_unstable_fd_seek)
248 {
249 m3ApiReturnType (uint32_t)
250 m3ApiGetArg (__wasi_fd_t , fd)
251 m3ApiGetArg (__wasi_filedelta_t , offset)
252 m3ApiGetArg (__wasi_whence_t , wasi_whence)
253 m3ApiGetArgMem (__wasi_filesize_t * , result)
254
255 if (runtime == NULL || result == NULL) { m3ApiReturn(__WASI_EINVAL); }
256
257 int whence;
258 switch (wasi_whence) {
259 case __WASI_WHENCE_CUR: whence = SEEK_CUR; break;
260 case __WASI_WHENCE_END: whence = SEEK_END; break;
261 case __WASI_WHENCE_SET: whence = SEEK_SET; break;
262 default: m3ApiReturn(__WASI_EINVAL);
263 }
264
265 int64_t ret;
266 ret = lseek(fd, offset, whence);
267 if (ret < 0) { m3ApiReturn(errno_to_wasi(errno)); }
268 m3ApiWriteMem64(result, ret);
269 m3ApiReturn(__WASI_ESUCCESS);
270 }
271
272
m3ApiRawFunction(m3_wasi_unstable_path_open)273 m3ApiRawFunction(m3_wasi_unstable_path_open)
274 {
275 m3ApiReturnType (uint32_t)
276 m3ApiGetArg (__wasi_fd_t , dirfd)
277 m3ApiGetArg (__wasi_lookupflags_t , dirflags)
278 m3ApiGetArgMem (const char * , path)
279 m3ApiGetArg (__wasi_size_t , path_len)
280 m3ApiGetArg (__wasi_oflags_t , oflags)
281 m3ApiGetArg (__wasi_rights_t , fs_rights_base)
282 m3ApiGetArg (__wasi_rights_t , fs_rights_inheriting)
283 m3ApiGetArg (__wasi_fdflags_t , fs_flags)
284 m3ApiGetArgMem (__wasi_fd_t * , fd)
285
286 if (path_len >= 512)
287 m3ApiReturn(__WASI_EINVAL);
288
289 // copy path so we can ensure it is NULL terminated
290 char host_path [path_len+1];
291
292 memcpy (host_path, path, path_len);
293 host_path[path_len] = '\0'; // NULL terminator
294
295 // TODO
296 m3ApiReturn(__WASI_ENOSYS);
297 }
298
m3ApiRawFunction(m3_wasi_unstable_fd_read)299 m3ApiRawFunction(m3_wasi_unstable_fd_read)
300 {
301 m3ApiReturnType (uint32_t)
302 m3ApiGetArg (__wasi_fd_t , fd)
303 m3ApiGetArgMem (wasi_iovec_t * , wasi_iovs)
304 m3ApiGetArg (__wasi_size_t , iovs_len)
305 m3ApiGetArgMem (__wasi_size_t * , nread)
306
307 if (runtime == NULL || nread == NULL) { m3ApiReturn(__WASI_EINVAL); }
308
309 ssize_t res = 0;
310 for (__wasi_size_t i = 0; i < iovs_len; i++) {
311 void* addr = m3ApiOffsetToPtr(m3ApiReadMem32(&wasi_iovs[i].buf));
312 size_t len = m3ApiReadMem32(&wasi_iovs[i].buf_len);
313 if (len == 0) continue;
314
315 int ret = read (fd, addr, len);
316 if (ret < 0) m3ApiReturn(errno_to_wasi(errno));
317 res += ret;
318 if ((size_t)ret < len) break;
319 }
320 m3ApiWriteMem32(nread, res);
321 m3ApiReturn(__WASI_ESUCCESS);
322 }
323
m3ApiRawFunction(m3_wasi_unstable_fd_write)324 m3ApiRawFunction(m3_wasi_unstable_fd_write)
325 {
326 m3ApiReturnType (uint32_t)
327 m3ApiGetArg (__wasi_fd_t , fd)
328 m3ApiGetArgMem (wasi_iovec_t * , wasi_iovs)
329 m3ApiGetArg (__wasi_size_t , iovs_len)
330 m3ApiGetArgMem (__wasi_size_t * , nwritten)
331
332 if (runtime == NULL || nwritten == NULL) { m3ApiReturn(__WASI_EINVAL); }
333
334 ssize_t res = 0;
335 for (__wasi_size_t i = 0; i < iovs_len; i++) {
336 void* addr = m3ApiOffsetToPtr(m3ApiReadMem32(&wasi_iovs[i].buf));
337 size_t len = m3ApiReadMem32(&wasi_iovs[i].buf_len);
338 if (len == 0) continue;
339
340 int ret = write (fd, addr, len);
341 if (ret < 0) m3ApiReturn(errno_to_wasi(errno));
342 res += ret;
343 if ((size_t)ret < len) break;
344 }
345 m3ApiWriteMem32(nwritten, res);
346 m3ApiReturn(__WASI_ESUCCESS);
347 }
348
m3ApiRawFunction(m3_wasi_unstable_fd_close)349 m3ApiRawFunction(m3_wasi_unstable_fd_close)
350 {
351 m3ApiReturnType (uint32_t)
352 m3ApiGetArg (__wasi_fd_t, fd)
353
354 int ret = close(fd);
355 m3ApiReturn(ret == 0 ? __WASI_ESUCCESS : ret);
356 }
357
m3ApiRawFunction(m3_wasi_unstable_fd_datasync)358 m3ApiRawFunction(m3_wasi_unstable_fd_datasync)
359 {
360 m3ApiReturnType (uint32_t)
361 m3ApiGetArg (__wasi_fd_t, fd)
362
363 // TODO
364 m3ApiReturn(__WASI_ESUCCESS);
365 }
366
m3ApiRawFunction(m3_wasi_unstable_random_get)367 m3ApiRawFunction(m3_wasi_unstable_random_get)
368 {
369 m3ApiReturnType (uint32_t)
370 m3ApiGetArgMem (uint8_t * , buf)
371 m3ApiGetArg (__wasi_size_t , buflen)
372
373 while (1) {
374 ssize_t retlen = 0;
375
376 #if defined(__wasi__) || defined(__APPLE__) || defined(__ANDROID_API__) || defined(__OpenBSD__)
377 size_t reqlen = M3_MIN (buflen, 256);
378 # if defined(__APPLE__) && (TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR)
379 retlen = SecRandomCopyBytes(kSecRandomDefault, reqlen, buf) < 0 ? -1 : reqlen;
380 # else
381 retlen = getentropy(buf, reqlen) < 0 ? -1 : reqlen;
382 # endif
383 #elif defined(__FreeBSD__) || defined(__linux__)
384 retlen = getrandom(buf, buflen, 0);
385 #elif defined(_WIN32)
386 if (RtlGenRandom(buf, buflen) == TRUE) {
387 m3ApiReturn(__WASI_ESUCCESS);
388 }
389 #else
390 m3ApiReturn(__WASI_ENOSYS);
391 #endif
392 if (retlen < 0) {
393 if (errno == EINTR || errno == EAGAIN) {
394 continue;
395 }
396 m3ApiReturn(errno_to_wasi(errno));
397 } else if (retlen == buflen) {
398 m3ApiReturn(__WASI_ESUCCESS);
399 } else {
400 buf += retlen;
401 buflen -= retlen;
402 }
403 }
404 }
405
m3ApiRawFunction(m3_wasi_unstable_clock_res_get)406 m3ApiRawFunction(m3_wasi_unstable_clock_res_get)
407 {
408 m3ApiReturnType (uint32_t)
409 m3ApiGetArg (__wasi_clockid_t , wasi_clk_id)
410 m3ApiGetArgMem (__wasi_timestamp_t * , resolution)
411
412 if (runtime == NULL || resolution == NULL) { m3ApiReturn(__WASI_EINVAL); }
413
414 int clk = convert_clockid(wasi_clk_id);
415 if (clk < 0) m3ApiReturn(__WASI_EINVAL);
416
417 struct timespec tp;
418 if (clock_getres(clk, &tp) != 0) {
419 m3ApiWriteMem64(resolution, 1000000);
420 } else {
421 m3ApiWriteMem64(resolution, convert_timespec(&tp));
422 }
423
424 m3ApiReturn(__WASI_ESUCCESS);
425 }
426
m3ApiRawFunction(m3_wasi_unstable_clock_time_get)427 m3ApiRawFunction(m3_wasi_unstable_clock_time_get)
428 {
429 m3ApiReturnType (uint32_t)
430 m3ApiGetArg (__wasi_clockid_t , wasi_clk_id)
431 m3ApiGetArg (__wasi_timestamp_t , precision)
432 m3ApiGetArgMem (__wasi_timestamp_t * , time)
433
434 if (runtime == NULL || time == NULL) { m3ApiReturn(__WASI_EINVAL); }
435
436 int clk = convert_clockid(wasi_clk_id);
437 if (clk < 0) m3ApiReturn(__WASI_EINVAL);
438
439 struct timespec tp;
440 if (clock_gettime(clk, &tp) != 0) {
441 m3ApiReturn(errno_to_wasi(errno));
442 }
443
444 m3ApiWriteMem64(time, convert_timespec(&tp));
445 m3ApiReturn(__WASI_ESUCCESS);
446 }
447
m3ApiRawFunction(m3_wasi_unstable_proc_exit)448 m3ApiRawFunction(m3_wasi_unstable_proc_exit)
449 {
450 m3ApiGetArg (uint32_t, code)
451
452 runtime->exit_code = code;
453
454 m3ApiTrap(m3Err_trapExit);
455 }
456
457
458 static
SuppressLookupFailure(M3Result i_result)459 M3Result SuppressLookupFailure(M3Result i_result)
460 {
461 if (i_result == m3Err_functionLookupFailed)
462 return m3Err_none;
463 else
464 return i_result;
465 }
466
467
m3_LinkEspWASI(IM3Module module)468 M3Result m3_LinkEspWASI (IM3Module module)
469 {
470 M3Result result = m3Err_none;
471
472 // TODO: Preopen dirs
473
474 static const char* namespaces[2] = { "wasi_unstable", "wasi_snapshot_preview1" };
475
476 for (int i=0; i<2; i++)
477 {
478 const char* wasi = namespaces[i];
479
480 _ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "args_get", "i(**)", &m3_wasi_unstable_args_get)));
481 _ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "args_sizes_get", "i(**)", &m3_wasi_unstable_args_sizes_get)));
482 _ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "clock_res_get", "i(i*)", &m3_wasi_unstable_clock_res_get)));
483 _ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "clock_time_get", "i(iI*)", &m3_wasi_unstable_clock_time_get)));
484 _ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "environ_get", "i(**)", &m3_wasi_unstable_environ_get)));
485 _ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "environ_sizes_get", "i(**)", &m3_wasi_unstable_environ_sizes_get)));
486
487 //_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_advise", "i(iIIi)", )));
488 //_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_allocate", "i(iII)", )));
489 _ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_close", "i(i)", &m3_wasi_unstable_fd_close)));
490 _ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_datasync", "i(i)", &m3_wasi_unstable_fd_datasync)));
491 _ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_fdstat_get", "i(i*)", &m3_wasi_unstable_fd_fdstat_get)));
492 _ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_fdstat_set_flags", "i(ii)", &m3_wasi_unstable_fd_fdstat_set_flags)));
493 //_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_fdstat_set_rights", "i(iII)", )));
494 //_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_filestat_get", "i(i*)", )));
495 //_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_filestat_set_size", "i(iI)", )));
496 //_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_filestat_set_times","i(iIIi)", )));
497 //_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_pread", "i(i*iI*)",)));
498 _ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_prestat_get", "i(i*)", &m3_wasi_unstable_fd_prestat_get)));
499 _ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_prestat_dir_name", "i(i*i)", &m3_wasi_unstable_fd_prestat_dir_name)));
500 //_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_pwrite", "i(i*iI*)",)));
501 _ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_read", "i(i*i*)", &m3_wasi_unstable_fd_read)));
502 //_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_readdir", "i(i*iI*)",)));
503 //_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_renumber", "i(ii)", )));
504 _ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_seek", "i(iIi*)", &m3_wasi_unstable_fd_seek)));
505 //_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_sync", "i(i)", )));
506 //_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_tell", "i(i*)", )));
507 _ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_write", "i(i*i*)", &m3_wasi_unstable_fd_write)));
508
509 //_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "path_create_directory", "i(i*i)", )));
510 //_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "path_filestat_get", "i(ii*i*)", &m3_wasi_unstable_path_filestat_get)));
511 //_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "path_filestat_set_times", "i(ii*iIIi)", )));
512 //_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "path_link", "i(ii*ii*i)", )));
513 _ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "path_open", "i(ii*iiIIi*)", &m3_wasi_unstable_path_open)));
514 //_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "path_readlink", "i(i*i*i*)", )));
515 //_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "path_remove_directory", "i(i*i)", )));
516 //_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "path_rename", "i(i*ii*i)", )));
517 //_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "path_symlink", "i(*ii*i)", )));
518 //_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "path_unlink_file", "i(i*i)", )));
519
520 //_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "poll_oneoff", "i(**i*)", &m3_wasi_unstable_poll_oneoff)));
521 _ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "proc_exit", "v(i)", &m3_wasi_unstable_proc_exit)));
522 //_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "proc_raise", "i(i)", )));
523 _ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "random_get", "i(*i)", &m3_wasi_unstable_random_get)));
524 //_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "sched_yield", "i()", )));
525
526 //_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "sock_recv", "i(i*ii**)", )));
527 //_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "sock_send", "i(i*ii*)", )));
528 //_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "sock_shutdown", "i(ii)", )));
529 }
530
531 _catch:
532 return result;
533 }
534
535 #endif // ESP32
536
537