1 //
2 // m3_api_meta_wasi.c
3 //
4 // Created by Volodymyr Shymanskyy on 01/08/20.
5 // Copyright © 2020 Volodymyr Shymanskyy. All rights reserved.
6 //
7
8 #include "m3_api_wasi.h"
9
10 #include "m3_env.h"
11 #include "m3_exception.h"
12
13 #if defined(d_m3HasMetaWASI)
14
15 // NOTE: MetaWASI mostly redirects WASI calls to the host WASI environment
16
17 #if !defined(__wasi__)
18 # error "MetaWASI is only supported on WASI target"
19 #endif
20
21 #if __has_include("wasi/api.h")
22 # include <wasi/api.h>
23
24 #elif __has_include("wasi/core.h")
25 # warning "Using legacy WASI headers"
26 # include <wasi/core.h>
27 # define __WASI_ERRNO_SUCCESS __WASI_ESUCCESS
28 # define __WASI_ERRNO_INVAL __WASI_EINVAL
29
30 #else
31 # error "Missing WASI headers"
32 #endif
33
34 static m3_wasi_context_t* wasi_context;
35
36 typedef size_t __wasi_size_t;
37
38 static inline
copy_iov_to_host(void * _mem,__wasi_iovec_t * host_iov,__wasi_iovec_t * wasi_iov,int32_t iovs_len)39 void copy_iov_to_host(void* _mem, __wasi_iovec_t* host_iov, __wasi_iovec_t* wasi_iov, int32_t iovs_len)
40 {
41 // Convert wasi memory offsets to host addresses
42 for (int i = 0; i < iovs_len; i++) {
43 host_iov[i].buf = m3ApiOffsetToPtr(wasi_iov[i].buf);
44 host_iov[i].buf_len = wasi_iov[i].buf_len;
45 }
46 }
47
48 /*
49 * WASI API implementation
50 */
51
m3ApiRawFunction(m3_wasi_generic_args_get)52 m3ApiRawFunction(m3_wasi_generic_args_get)
53 {
54 m3ApiReturnType (uint32_t)
55 m3ApiGetArgMem (uint32_t * , argv)
56 m3ApiGetArgMem (char * , argv_buf)
57
58 m3_wasi_context_t* context = (m3_wasi_context_t*)(_ctx->userdata);
59
60 if (context == NULL) { m3ApiReturn(__WASI_ERRNO_INVAL); }
61
62 m3ApiCheckMem(argv, context->argc * sizeof(uint32_t));
63
64 for (u32 i = 0; i < context->argc; ++i)
65 {
66 m3ApiWriteMem32(&argv[i], m3ApiPtrToOffset(argv_buf));
67
68 size_t len = strlen (context->argv[i]);
69
70 m3ApiCheckMem(argv_buf, len);
71 memcpy (argv_buf, context->argv[i], len);
72 argv_buf += len;
73 * argv_buf++ = 0;
74 }
75
76 m3ApiReturn(__WASI_ERRNO_SUCCESS);
77 }
78
m3ApiRawFunction(m3_wasi_generic_args_sizes_get)79 m3ApiRawFunction(m3_wasi_generic_args_sizes_get)
80 {
81 m3ApiReturnType (uint32_t)
82 m3ApiGetArgMem (__wasi_size_t * , argc)
83 m3ApiGetArgMem (__wasi_size_t * , argv_buf_size)
84
85 m3ApiCheckMem(argc, sizeof(__wasi_size_t));
86 m3ApiCheckMem(argv_buf_size, sizeof(__wasi_size_t));
87
88 m3_wasi_context_t* context = (m3_wasi_context_t*)(_ctx->userdata);
89
90 if (context == NULL) { m3ApiReturn(__WASI_ERRNO_INVAL); }
91
92 __wasi_size_t buf_len = 0;
93 for (u32 i = 0; i < context->argc; ++i)
94 {
95 buf_len += strlen (context->argv[i]) + 1;
96 }
97
98 m3ApiWriteMem32(argc, context->argc);
99 m3ApiWriteMem32(argv_buf_size, buf_len);
100
101 m3ApiReturn(__WASI_ERRNO_SUCCESS);
102 }
103
m3ApiRawFunction(m3_wasi_generic_environ_get)104 m3ApiRawFunction(m3_wasi_generic_environ_get)
105 {
106 m3ApiReturnType (uint32_t)
107 m3ApiGetArgMem (uint32_t * , env)
108 m3ApiGetArgMem (char * , env_buf)
109
110 __wasi_errno_t ret;
111 __wasi_size_t env_count, env_buf_size;
112
113 ret = __wasi_environ_sizes_get(&env_count, &env_buf_size);
114 if (ret != __WASI_ERRNO_SUCCESS) m3ApiReturn(ret);
115
116 m3ApiCheckMem(env, env_count * sizeof(uint32_t));
117 m3ApiCheckMem(env_buf, env_buf_size);
118
119 ret = __wasi_environ_get(env, env_buf);
120 if (ret != __WASI_ERRNO_SUCCESS) m3ApiReturn(ret);
121
122 for (u32 i = 0; i < env_count; ++i) {
123 env[i] = m3ApiPtrToOffset (env[i]);
124 }
125
126 m3ApiReturn(ret);
127 }
128
m3ApiRawFunction(m3_wasi_generic_environ_sizes_get)129 m3ApiRawFunction(m3_wasi_generic_environ_sizes_get)
130 {
131 m3ApiReturnType (uint32_t)
132 m3ApiGetArgMem (__wasi_size_t * , env_count)
133 m3ApiGetArgMem (__wasi_size_t * , env_buf_size)
134
135 m3ApiCheckMem(env_count, sizeof(__wasi_size_t));
136 m3ApiCheckMem(env_buf_size, sizeof(__wasi_size_t));
137
138 __wasi_errno_t ret = __wasi_environ_sizes_get(env_count, env_buf_size);
139
140 m3ApiReturn(ret);
141 }
142
m3ApiRawFunction(m3_wasi_generic_fd_prestat_dir_name)143 m3ApiRawFunction(m3_wasi_generic_fd_prestat_dir_name)
144 {
145 m3ApiReturnType (uint32_t)
146 m3ApiGetArg (__wasi_fd_t , fd)
147 m3ApiGetArgMem (char * , path)
148 m3ApiGetArg (__wasi_size_t , path_len)
149
150 m3ApiCheckMem(path, path_len);
151
152 __wasi_errno_t ret = __wasi_fd_prestat_dir_name(fd, path, path_len);
153
154 m3ApiReturn(ret);
155 }
156
m3ApiRawFunction(m3_wasi_generic_fd_prestat_get)157 m3ApiRawFunction(m3_wasi_generic_fd_prestat_get)
158 {
159 m3ApiReturnType (uint32_t)
160 m3ApiGetArg (__wasi_fd_t , fd)
161 m3ApiGetArgMem (__wasi_prestat_t * , buf)
162
163 m3ApiCheckMem(buf, sizeof(__wasi_prestat_t));
164
165 __wasi_errno_t ret = __wasi_fd_prestat_get(fd, buf);
166
167 m3ApiReturn(ret);
168 }
169
m3ApiRawFunction(m3_wasi_generic_fd_fdstat_get)170 m3ApiRawFunction(m3_wasi_generic_fd_fdstat_get)
171 {
172 m3ApiReturnType (uint32_t)
173 m3ApiGetArg (__wasi_fd_t , fd)
174 m3ApiGetArgMem (__wasi_fdstat_t * , fdstat)
175
176 m3ApiCheckMem(fdstat, sizeof(__wasi_fdstat_t));
177
178 __wasi_errno_t ret = __wasi_fd_fdstat_get(fd, fdstat);
179
180 m3ApiReturn(ret);
181 }
182
m3ApiRawFunction(m3_wasi_generic_fd_fdstat_set_flags)183 m3ApiRawFunction(m3_wasi_generic_fd_fdstat_set_flags)
184 {
185 m3ApiReturnType (uint32_t)
186 m3ApiGetArg (__wasi_fd_t , fd)
187 m3ApiGetArg (__wasi_fdflags_t , flags)
188
189 __wasi_errno_t ret = __wasi_fd_fdstat_set_flags(fd, flags);
190
191 m3ApiReturn(ret);
192 }
193
m3ApiRawFunction(m3_wasi_unstable_fd_filestat_get)194 m3ApiRawFunction(m3_wasi_unstable_fd_filestat_get)
195 {
196 m3ApiReturnType (uint32_t)
197 m3ApiGetArg (__wasi_fd_t , fd)
198 m3ApiGetArgMem (uint8_t * , buf)
199
200 m3ApiCheckMem(buf, 56); // wasi_filestat_t
201
202 __wasi_filestat_t stat;
203
204 __wasi_errno_t ret = __wasi_fd_filestat_get(fd, &stat);
205
206 if (ret != __WASI_ERRNO_SUCCESS) {
207 m3ApiReturn(ret);
208 }
209
210 memset(buf, 0, 56);
211 m3ApiWriteMem64(buf+0, stat.st_dev);
212 m3ApiWriteMem64(buf+8, stat.st_ino);
213 m3ApiWriteMem8 (buf+16, stat.st_filetype);
214 m3ApiWriteMem32(buf+20, stat.st_nlink);
215 m3ApiWriteMem64(buf+24, stat.st_size);
216 m3ApiWriteMem64(buf+32, stat.st_atim);
217 m3ApiWriteMem64(buf+40, stat.st_mtim);
218 m3ApiWriteMem64(buf+48, stat.st_ctim);
219
220 m3ApiReturn(ret);
221 }
222
m3ApiRawFunction(m3_wasi_snapshot_preview1_fd_filestat_get)223 m3ApiRawFunction(m3_wasi_snapshot_preview1_fd_filestat_get)
224 {
225 m3ApiReturnType (uint32_t)
226 m3ApiGetArg (__wasi_fd_t , fd)
227 m3ApiGetArgMem (uint8_t * , buf)
228
229 m3ApiCheckMem(buf, 64); // wasi_filestat_t
230
231 __wasi_filestat_t stat;
232
233 __wasi_errno_t ret = __wasi_fd_filestat_get(fd, &stat);
234
235 if (ret != __WASI_ERRNO_SUCCESS) {
236 m3ApiReturn(ret);
237 }
238
239 memset(buf, 0, 64);
240 m3ApiWriteMem64(buf+0, stat.st_dev);
241 m3ApiWriteMem64(buf+8, stat.st_ino);
242 m3ApiWriteMem8 (buf+16, stat.st_filetype);
243 m3ApiWriteMem64(buf+24, stat.st_nlink);
244 m3ApiWriteMem64(buf+32, stat.st_size);
245 m3ApiWriteMem64(buf+40, stat.st_atim);
246 m3ApiWriteMem64(buf+48, stat.st_mtim);
247 m3ApiWriteMem64(buf+56, stat.st_ctim);
248
249 m3ApiReturn(ret);
250 }
251
m3ApiRawFunction(m3_wasi_unstable_fd_seek)252 m3ApiRawFunction(m3_wasi_unstable_fd_seek)
253 {
254 m3ApiReturnType (uint32_t)
255 m3ApiGetArg (__wasi_fd_t , fd)
256 m3ApiGetArg (__wasi_filedelta_t , offset)
257 m3ApiGetArg (uint32_t , wasi_whence)
258 m3ApiGetArgMem (__wasi_filesize_t * , result)
259
260 m3ApiCheckMem(result, sizeof(__wasi_filesize_t));
261
262 __wasi_whence_t whence;
263
264 switch (wasi_whence) {
265 case 0: whence = __WASI_WHENCE_CUR; break;
266 case 1: whence = __WASI_WHENCE_END; break;
267 case 2: whence = __WASI_WHENCE_SET; break;
268 default: m3ApiReturn(__WASI_ERRNO_INVAL);
269 }
270
271 __wasi_errno_t ret = __wasi_fd_seek(fd, offset, whence, result);
272
273 m3ApiReturn(ret);
274 }
275
m3ApiRawFunction(m3_wasi_snapshot_preview1_fd_seek)276 m3ApiRawFunction(m3_wasi_snapshot_preview1_fd_seek)
277 {
278 m3ApiReturnType (uint32_t)
279 m3ApiGetArg (__wasi_fd_t , fd)
280 m3ApiGetArg (__wasi_filedelta_t , offset)
281 m3ApiGetArg (uint32_t , wasi_whence)
282 m3ApiGetArgMem (__wasi_filesize_t * , result)
283
284 m3ApiCheckMem(result, sizeof(__wasi_filesize_t));
285
286 __wasi_whence_t whence;
287
288 switch (wasi_whence) {
289 case 0: whence = __WASI_WHENCE_SET; break;
290 case 1: whence = __WASI_WHENCE_CUR; break;
291 case 2: whence = __WASI_WHENCE_END; break;
292 default: m3ApiReturn(__WASI_ERRNO_INVAL);
293 }
294
295 __wasi_errno_t ret = __wasi_fd_seek(fd, offset, whence, result);
296
297 m3ApiReturn(ret);
298 }
299
m3ApiRawFunction(m3_wasi_generic_path_create_directory)300 m3ApiRawFunction(m3_wasi_generic_path_create_directory)
301 {
302 m3ApiReturnType (uint32_t)
303 m3ApiGetArg (__wasi_fd_t , fd)
304 m3ApiGetArgMem (const char * , path)
305 m3ApiGetArg (__wasi_size_t , path_len)
306
307 m3ApiCheckMem(path, path_len);
308
309 __wasi_errno_t ret = __wasi_path_create_directory(fd, path, path_len);
310
311 m3ApiReturn(ret);
312 }
313
m3ApiRawFunction(m3_wasi_generic_path_readlink)314 m3ApiRawFunction(m3_wasi_generic_path_readlink)
315 {
316 m3ApiReturnType (uint32_t)
317 m3ApiGetArg (__wasi_fd_t , fd)
318 m3ApiGetArgMem (const char * , path)
319 m3ApiGetArg (__wasi_size_t , path_len)
320 m3ApiGetArgMem (char * , buf)
321 m3ApiGetArg (__wasi_size_t , buf_len)
322 m3ApiGetArgMem (__wasi_size_t * , bufused)
323
324 m3ApiCheckMem(path, path_len);
325 m3ApiCheckMem(buf, buf_len);
326 m3ApiCheckMem(bufused, sizeof(__wasi_size_t));
327
328 __wasi_errno_t ret = __wasi_path_readlink(fd, path, path_len, buf, buf_len, bufused);
329
330 m3ApiReturn(ret);
331 }
332
m3ApiRawFunction(m3_wasi_generic_path_remove_directory)333 m3ApiRawFunction(m3_wasi_generic_path_remove_directory)
334 {
335 m3ApiReturnType (uint32_t)
336 m3ApiGetArg (__wasi_fd_t , fd)
337 m3ApiGetArgMem (const char * , path)
338 m3ApiGetArg (__wasi_size_t , path_len)
339
340 m3ApiCheckMem(path, path_len);
341
342 __wasi_errno_t ret = __wasi_path_remove_directory(fd, path, path_len);
343
344 m3ApiReturn(ret);
345 }
346
m3ApiRawFunction(m3_wasi_generic_path_rename)347 m3ApiRawFunction(m3_wasi_generic_path_rename)
348 {
349 m3ApiReturnType (uint32_t)
350 m3ApiGetArg (__wasi_fd_t , old_fd)
351 m3ApiGetArgMem (const char * , old_path)
352 m3ApiGetArg (__wasi_size_t , old_path_len)
353 m3ApiGetArg (__wasi_fd_t , new_fd)
354 m3ApiGetArgMem (const char * , new_path)
355 m3ApiGetArg (__wasi_size_t , new_path_len)
356
357 m3ApiCheckMem(old_path, old_path_len);
358 m3ApiCheckMem(new_path, new_path_len);
359
360 __wasi_errno_t ret = __wasi_path_rename(old_fd, old_path, old_path_len,
361 new_fd, new_path, new_path_len);
362
363 m3ApiReturn(ret);
364 }
365
m3ApiRawFunction(m3_wasi_generic_path_unlink_file)366 m3ApiRawFunction(m3_wasi_generic_path_unlink_file)
367 {
368 m3ApiReturnType (uint32_t)
369 m3ApiGetArg (__wasi_fd_t , fd)
370 m3ApiGetArgMem (const char * , path)
371 m3ApiGetArg (__wasi_size_t , path_len)
372
373 m3ApiCheckMem(path, path_len);
374
375 __wasi_errno_t ret = __wasi_path_unlink_file(fd, path, path_len);
376
377 m3ApiReturn(ret);
378 }
379
m3ApiRawFunction(m3_wasi_generic_path_open)380 m3ApiRawFunction(m3_wasi_generic_path_open)
381 {
382 m3ApiReturnType (uint32_t)
383 m3ApiGetArg (__wasi_fd_t , dirfd)
384 m3ApiGetArg (__wasi_lookupflags_t , dirflags)
385 m3ApiGetArgMem (const char * , path)
386 m3ApiGetArg (__wasi_size_t , path_len)
387 m3ApiGetArg (__wasi_oflags_t , oflags)
388 m3ApiGetArg (__wasi_rights_t , fs_rights_base)
389 m3ApiGetArg (__wasi_rights_t , fs_rights_inheriting)
390 m3ApiGetArg (__wasi_fdflags_t , fs_flags)
391 m3ApiGetArgMem (__wasi_fd_t * , fd)
392
393 m3ApiCheckMem(path, path_len);
394 m3ApiCheckMem(fd, sizeof(__wasi_fd_t));
395
396 __wasi_errno_t ret = __wasi_path_open(dirfd,
397 dirflags,
398 path,
399 path_len,
400 oflags,
401 fs_rights_base,
402 fs_rights_inheriting,
403 fs_flags,
404 fd);
405
406 m3ApiReturn(ret);
407 }
408
m3ApiRawFunction(m3_wasi_unstable_path_filestat_get)409 m3ApiRawFunction(m3_wasi_unstable_path_filestat_get)
410 {
411 m3ApiReturnType (uint32_t)
412 m3ApiGetArg (__wasi_fd_t , fd)
413 m3ApiGetArg (__wasi_lookupflags_t , flags)
414 m3ApiGetArgMem (const char * , path)
415 m3ApiGetArg (uint32_t , path_len)
416 m3ApiGetArgMem (uint8_t * , buf)
417
418 m3ApiCheckMem(path, path_len);
419 m3ApiCheckMem(buf, 56); // wasi_filestat_t
420
421 __wasi_filestat_t stat;
422
423 __wasi_errno_t ret = __wasi_path_filestat_get(fd, flags, path, path_len, &stat);
424
425 if (ret != __WASI_ERRNO_SUCCESS) {
426 m3ApiReturn(ret);
427 }
428
429 memset(buf, 0, 56);
430 m3ApiWriteMem64(buf+0, stat.st_dev);
431 m3ApiWriteMem64(buf+8, stat.st_ino);
432 m3ApiWriteMem8 (buf+16, stat.st_filetype);
433 m3ApiWriteMem32(buf+20, stat.st_nlink);
434 m3ApiWriteMem64(buf+24, stat.st_size);
435 m3ApiWriteMem64(buf+32, stat.st_atim);
436 m3ApiWriteMem64(buf+40, stat.st_mtim);
437 m3ApiWriteMem64(buf+48, stat.st_ctim);
438
439 m3ApiReturn(ret);
440 }
441
m3ApiRawFunction(m3_wasi_snapshot_preview1_path_filestat_get)442 m3ApiRawFunction(m3_wasi_snapshot_preview1_path_filestat_get)
443 {
444 m3ApiReturnType (uint32_t)
445 m3ApiGetArg (__wasi_fd_t , fd)
446 m3ApiGetArg (__wasi_lookupflags_t , flags)
447 m3ApiGetArgMem (const char * , path)
448 m3ApiGetArg (uint32_t , path_len)
449 m3ApiGetArgMem (uint8_t * , buf)
450
451 m3ApiCheckMem(path, path_len);
452 m3ApiCheckMem(buf, 64); // wasi_filestat_t
453
454 __wasi_filestat_t stat;
455
456 __wasi_errno_t ret = __wasi_path_filestat_get(fd, flags, path, path_len, &stat);
457
458 if (ret != __WASI_ERRNO_SUCCESS) {
459 m3ApiReturn(ret);
460 }
461
462 memset(buf, 0, 64);
463 m3ApiWriteMem64(buf+0, stat.st_dev);
464 m3ApiWriteMem64(buf+8, stat.st_ino);
465 m3ApiWriteMem8 (buf+16, stat.st_filetype);
466 m3ApiWriteMem64(buf+24, stat.st_nlink);
467 m3ApiWriteMem64(buf+32, stat.st_size);
468 m3ApiWriteMem64(buf+40, stat.st_atim);
469 m3ApiWriteMem64(buf+48, stat.st_mtim);
470 m3ApiWriteMem64(buf+56, stat.st_ctim);
471
472 m3ApiReturn(ret);
473 }
474
m3ApiRawFunction(m3_wasi_generic_fd_pread)475 m3ApiRawFunction(m3_wasi_generic_fd_pread)
476 {
477 m3ApiReturnType (uint32_t)
478 m3ApiGetArg (__wasi_fd_t , fd)
479 m3ApiGetArgMem (__wasi_iovec_t * , wasi_iovs)
480 m3ApiGetArg (__wasi_size_t , iovs_len)
481 m3ApiGetArg (__wasi_filesize_t , offset)
482 m3ApiGetArgMem (__wasi_size_t * , nread)
483
484 m3ApiCheckMem(wasi_iovs, iovs_len * sizeof(__wasi_iovec_t));
485 m3ApiCheckMem(nread, sizeof(__wasi_size_t));
486
487 __wasi_iovec_t iovs[iovs_len];
488 copy_iov_to_host(_mem, iovs, wasi_iovs, iovs_len);
489
490 __wasi_errno_t ret = __wasi_fd_pread(fd, iovs, iovs_len, offset, nread);
491
492 m3ApiReturn(ret);
493 }
494
m3ApiRawFunction(m3_wasi_generic_fd_read)495 m3ApiRawFunction(m3_wasi_generic_fd_read)
496 {
497 m3ApiReturnType (uint32_t)
498 m3ApiGetArg (__wasi_fd_t , fd)
499 m3ApiGetArgMem (__wasi_iovec_t * , wasi_iovs)
500 m3ApiGetArg (__wasi_size_t , iovs_len)
501 m3ApiGetArgMem (__wasi_size_t * , nread)
502
503 m3ApiCheckMem(wasi_iovs, iovs_len * sizeof(__wasi_iovec_t));
504 m3ApiCheckMem(nread, sizeof(__wasi_size_t));
505
506 __wasi_iovec_t iovs[iovs_len];
507 copy_iov_to_host(_mem, iovs, wasi_iovs, iovs_len);
508
509 __wasi_errno_t ret = __wasi_fd_read(fd, iovs, iovs_len, nread);
510
511 m3ApiReturn(ret);
512 }
513
m3ApiRawFunction(m3_wasi_generic_fd_write)514 m3ApiRawFunction(m3_wasi_generic_fd_write)
515 {
516 m3ApiReturnType (uint32_t)
517 m3ApiGetArg (__wasi_fd_t , fd)
518 m3ApiGetArgMem (__wasi_iovec_t * , wasi_iovs)
519 m3ApiGetArg (__wasi_size_t , iovs_len)
520 m3ApiGetArgMem (__wasi_size_t * , nwritten)
521
522 m3ApiCheckMem(wasi_iovs, iovs_len * sizeof(__wasi_iovec_t));
523 m3ApiCheckMem(nwritten, sizeof(__wasi_size_t));
524
525 __wasi_iovec_t iovs[iovs_len];
526 copy_iov_to_host(_mem, iovs, wasi_iovs, iovs_len);
527
528 __wasi_errno_t ret = __wasi_fd_write(fd, (__wasi_ciovec_t*)iovs, iovs_len, nwritten);
529
530 m3ApiReturn(ret);
531 }
532
m3ApiRawFunction(m3_wasi_generic_fd_readdir)533 m3ApiRawFunction(m3_wasi_generic_fd_readdir)
534 {
535 m3ApiReturnType (uint32_t)
536 m3ApiGetArg (__wasi_fd_t , fd)
537 m3ApiGetArgMem (void * , buf)
538 m3ApiGetArg (__wasi_size_t , buf_len)
539 m3ApiGetArg (__wasi_dircookie_t , cookie)
540 m3ApiGetArgMem (__wasi_size_t * , bufused)
541
542 m3ApiCheckMem(buf, buf_len);
543 m3ApiCheckMem(bufused, sizeof(__wasi_size_t));
544
545 __wasi_errno_t ret = __wasi_fd_readdir(fd, buf, buf_len, cookie, bufused);
546
547 m3ApiReturn(ret);
548 }
549
m3ApiRawFunction(m3_wasi_generic_fd_close)550 m3ApiRawFunction(m3_wasi_generic_fd_close)
551 {
552 m3ApiReturnType (uint32_t)
553 m3ApiGetArg (__wasi_fd_t, fd)
554
555 __wasi_errno_t ret = __wasi_fd_close(fd);
556
557 m3ApiReturn(ret);
558 }
559
m3ApiRawFunction(m3_wasi_generic_fd_datasync)560 m3ApiRawFunction(m3_wasi_generic_fd_datasync)
561 {
562 m3ApiReturnType (uint32_t)
563 m3ApiGetArg (__wasi_fd_t, fd)
564
565 __wasi_errno_t ret = __wasi_fd_datasync(fd);
566
567 m3ApiReturn(ret);
568 }
569
m3ApiRawFunction(m3_wasi_generic_random_get)570 m3ApiRawFunction(m3_wasi_generic_random_get)
571 {
572 m3ApiReturnType (uint32_t)
573 m3ApiGetArgMem (uint8_t * , buf)
574 m3ApiGetArg (__wasi_size_t , buf_len)
575
576 m3ApiCheckMem(buf, buf_len);
577
578 __wasi_errno_t ret = __wasi_random_get(buf, buf_len);
579
580 m3ApiReturn(ret);
581 }
582
m3ApiRawFunction(m3_wasi_generic_clock_res_get)583 m3ApiRawFunction(m3_wasi_generic_clock_res_get)
584 {
585 m3ApiReturnType (uint32_t)
586 m3ApiGetArg (__wasi_clockid_t , wasi_clk_id)
587 m3ApiGetArgMem (__wasi_timestamp_t * , resolution)
588
589 m3ApiCheckMem(resolution, sizeof(__wasi_timestamp_t));
590
591 __wasi_errno_t ret = __wasi_clock_res_get(wasi_clk_id, resolution);
592
593 m3ApiReturn(ret);
594 }
595
m3ApiRawFunction(m3_wasi_generic_clock_time_get)596 m3ApiRawFunction(m3_wasi_generic_clock_time_get)
597 {
598 m3ApiReturnType (uint32_t)
599 m3ApiGetArg (__wasi_clockid_t , wasi_clk_id)
600 m3ApiGetArg (__wasi_timestamp_t , precision)
601 m3ApiGetArgMem (__wasi_timestamp_t * , time)
602
603 m3ApiCheckMem(time, sizeof(__wasi_timestamp_t));
604
605 __wasi_errno_t ret = __wasi_clock_time_get(wasi_clk_id, precision, time);
606
607 m3ApiReturn(ret);
608 }
609
m3ApiRawFunction(m3_wasi_generic_poll_oneoff)610 m3ApiRawFunction(m3_wasi_generic_poll_oneoff)
611 {
612 m3ApiReturnType (uint32_t)
613 m3ApiGetArgMem (const __wasi_subscription_t * , in)
614 m3ApiGetArgMem (__wasi_event_t * , out)
615 m3ApiGetArg (__wasi_size_t , nsubscriptions)
616 m3ApiGetArgMem (__wasi_size_t * , nevents)
617
618 m3ApiCheckMem(in, nsubscriptions * sizeof(__wasi_subscription_t));
619 m3ApiCheckMem(out, nsubscriptions * sizeof(__wasi_event_t));
620 m3ApiCheckMem(nevents, sizeof(__wasi_size_t));
621
622 __wasi_errno_t ret = __wasi_poll_oneoff(in, out, nsubscriptions, nevents);
623
624 m3ApiReturn(ret);
625 }
626
m3ApiRawFunction(m3_wasi_generic_proc_exit)627 m3ApiRawFunction(m3_wasi_generic_proc_exit)
628 {
629 m3ApiGetArg (uint32_t, code)
630
631 m3_wasi_context_t* context = (m3_wasi_context_t*)(_ctx->userdata);
632
633 if (context) {
634 context->exit_code = code;
635 }
636
637 m3ApiTrap(m3Err_trapExit);
638 }
639
640
641 static
SuppressLookupFailure(M3Result i_result)642 M3Result SuppressLookupFailure(M3Result i_result)
643 {
644 if (i_result == m3Err_functionLookupFailed)
645 return m3Err_none;
646 else
647 return i_result;
648 }
649
m3_GetWasiContext()650 m3_wasi_context_t* m3_GetWasiContext()
651 {
652 return wasi_context;
653 }
654
655
m3_LinkWASI(IM3Module module)656 M3Result m3_LinkWASI (IM3Module module)
657 {
658 M3Result result = m3Err_none;
659
660 if (!wasi_context) {
661 wasi_context = (m3_wasi_context_t*)malloc(sizeof(m3_wasi_context_t));
662 wasi_context->exit_code = 0;
663 wasi_context->argc = 0;
664 wasi_context->argv = 0;
665 }
666
667 static const char* namespaces[2] = { "wasi_unstable", "wasi_snapshot_preview1" };
668
669 // fd_seek is incompatible
670 _ (SuppressLookupFailure (m3_LinkRawFunction (module, "wasi_unstable", "fd_seek", "i(iIi*)", &m3_wasi_unstable_fd_seek)));
671 _ (SuppressLookupFailure (m3_LinkRawFunction (module, "wasi_snapshot_preview1", "fd_seek", "i(iIi*)", &m3_wasi_snapshot_preview1_fd_seek)));
672 _ (SuppressLookupFailure (m3_LinkRawFunction (module, "wasi_unstable", "fd_filestat_get", "i(i*)", &m3_wasi_unstable_fd_filestat_get)));
673 _ (SuppressLookupFailure (m3_LinkRawFunction (module, "wasi_snapshot_preview1", "fd_filestat_get", "i(i*)", &m3_wasi_snapshot_preview1_fd_filestat_get)));
674 _ (SuppressLookupFailure (m3_LinkRawFunction (module, "wasi_unstable", "path_filestat_get", "i(ii*i*)", &m3_wasi_unstable_path_filestat_get)));
675 _ (SuppressLookupFailure (m3_LinkRawFunction (module, "wasi_snapshot_preview1", "path_filestat_get", "i(ii*i*)", &m3_wasi_snapshot_preview1_path_filestat_get)));
676
677 for (int i=0; i<2; i++)
678 {
679 const char* wasi = namespaces[i];
680
681 _ (SuppressLookupFailure (m3_LinkRawFunctionEx (module, wasi, "args_get", "i(**)", &m3_wasi_generic_args_get, wasi_context)));
682 _ (SuppressLookupFailure (m3_LinkRawFunctionEx (module, wasi, "args_sizes_get", "i(**)", &m3_wasi_generic_args_sizes_get, wasi_context)));
683 _ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "clock_res_get", "i(i*)", &m3_wasi_generic_clock_res_get)));
684 _ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "clock_time_get", "i(iI*)", &m3_wasi_generic_clock_time_get)));
685 _ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "environ_get", "i(**)", &m3_wasi_generic_environ_get)));
686 _ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "environ_sizes_get", "i(**)", &m3_wasi_generic_environ_sizes_get)));
687
688 //_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_advise", "i(iIIi)", )));
689 //_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_allocate", "i(iII)", )));
690 _ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_close", "i(i)", &m3_wasi_generic_fd_close)));
691 _ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_datasync", "i(i)", &m3_wasi_generic_fd_datasync)));
692 _ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_fdstat_get", "i(i*)", &m3_wasi_generic_fd_fdstat_get)));
693 _ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_fdstat_set_flags", "i(ii)", &m3_wasi_generic_fd_fdstat_set_flags)));
694 //_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_fdstat_set_rights", "i(iII)", )));
695 //_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_filestat_set_size", "i(iI)", )));
696 //_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_filestat_set_times","i(iIIi)", )));
697 _ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_pread", "i(i*iI*)",&m3_wasi_generic_fd_pread)));
698 _ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_prestat_get", "i(i*)", &m3_wasi_generic_fd_prestat_get)));
699 _ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_prestat_dir_name", "i(i*i)", &m3_wasi_generic_fd_prestat_dir_name)));
700 //_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_pwrite", "i(i*iI*)",)));
701 _ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_read", "i(i*i*)", &m3_wasi_generic_fd_read)));
702 _ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_readdir", "i(i*iI*)",&m3_wasi_generic_fd_readdir)));
703 //_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_renumber", "i(ii)", )));
704 //_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_sync", "i(i)", )));
705 //_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_tell", "i(i*)", )));
706 _ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_write", "i(i*i*)", &m3_wasi_generic_fd_write)));
707
708 _ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "path_create_directory", "i(i*i)", &m3_wasi_generic_path_create_directory)));
709 //_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "path_filestat_set_times", "i(ii*iIIi)", )));
710 //_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "path_link", "i(ii*ii*i)", )));
711 _ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "path_open", "i(ii*iiIIi*)", &m3_wasi_generic_path_open)));
712 _ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "path_readlink", "i(i*i*i*)", &m3_wasi_generic_path_readlink)));
713 _ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "path_remove_directory", "i(i*i)", &m3_wasi_generic_path_remove_directory)));
714 _ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "path_rename", "i(i*ii*i)", &m3_wasi_generic_path_rename)));
715 //_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "path_symlink", "i(*ii*i)", )));
716 _ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "path_unlink_file", "i(i*i)", &m3_wasi_generic_path_unlink_file)));
717
718 _ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "poll_oneoff", "i(**i*)", &m3_wasi_generic_poll_oneoff)));
719 _ (SuppressLookupFailure (m3_LinkRawFunctionEx (module, wasi, "proc_exit", "v(i)", &m3_wasi_generic_proc_exit, wasi_context)));
720 //_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "proc_raise", "i(i)", )));
721 _ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "random_get", "i(*i)", &m3_wasi_generic_random_get)));
722 //_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "sched_yield", "i()", )));
723
724 //_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "sock_recv", "i(i*ii**)", )));
725 //_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "sock_send", "i(i*ii*)", )));
726 //_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "sock_shutdown", "i(ii)", )));
727 }
728
729 _catch:
730 return result;
731 }
732
733 #endif // d_m3HasMetaWASI
734
735