]> git.proxmox.com Git - wasi-libc.git/commitdiff
Update to the next version of the `witx` crate (#234)
authorAlex Crichton <alex@alexcrichton.com>
Tue, 23 Feb 2021 18:18:56 +0000 (12:18 -0600)
committerGitHub <noreply@github.com>
Tue, 23 Feb 2021 18:18:56 +0000 (12:18 -0600)
* Update to the next version of the `witx` crate

* Generate adapter functions instead of simply a header file to have a
  place where adapter code can go.
* Implement adapters in terms of the instructions that the `witx` crate
  tells us about.
* Update the interface of functions to what `witx` expects, notably
  string arguments are now only taken as `char*` and `strlen` happens in
  the adapter function.
* Update defined/predefined/undefined symbol lists for types that have
  been updated.

Some precise generated code has changed but the actual APIs should all
be the same except for the change to not take the length of the string
in the raw WASI call, since idiomatically C doesn't pass the length of
strings around.

Eventually it's expected that the shim functions, while sometimes not
necessary today, will implement more checks and more conversions as
necessary for new APIs.

* Actually update witx submodule

* Comment how to regenerate files

* Tweak name of actual function imports

Make it a bit clearer that they're the ones that we're importing and
calling.

* Update submodule to point to WebAssembly

22 files changed:
Makefile
expected/wasm32-wasi/defined-symbols.txt
expected/wasm32-wasi/predefined-macros.txt
expected/wasm32-wasi/undefined-symbols.txt
libc-bottom-half/cloudlibc/src/libc/fcntl/openat.c
libc-bottom-half/cloudlibc/src/libc/stdio/renameat.c
libc-bottom-half/cloudlibc/src/libc/sys/stat/fstatat.c
libc-bottom-half/cloudlibc/src/libc/sys/stat/mkdirat.c
libc-bottom-half/cloudlibc/src/libc/sys/stat/utimensat.c
libc-bottom-half/cloudlibc/src/libc/unistd/faccessat.c
libc-bottom-half/cloudlibc/src/libc/unistd/linkat.c
libc-bottom-half/cloudlibc/src/libc/unistd/readlinkat.c
libc-bottom-half/cloudlibc/src/libc/unistd/symlinkat.c
libc-bottom-half/headers/public/wasi/api.h
libc-bottom-half/sources/__wasilibc_real.c [new file with mode: 0644]
libc-bottom-half/sources/__wasilibc_rmdirat.c
libc-bottom-half/sources/__wasilibc_unlinkat.c
tools/wasi-headers/WASI
tools/wasi-headers/src/c_header.rs
tools/wasi-headers/src/lib.rs
tools/wasi-headers/src/main.rs
tools/wasi-headers/tests/verify.rs

index d8e385e54823755059a54689d590389fa559e6ff..df3db5385d29565acd6e467c4c61dd24143643f4 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -460,7 +460,7 @@ finish: startup_files libc
            |grep ' U ' |sed 's/.* U //' |LC_ALL=C sort |uniq); do \
            grep -q '\<'$$undef_sym'\>' "$(SYSROOT_SHARE)/defined-symbols.txt" || echo $$undef_sym; \
        done | grep -v "^__mul" > "$(SYSROOT_SHARE)/undefined-symbols.txt"
-       grep '^_*wasi_' "$(SYSROOT_SHARE)/undefined-symbols.txt" \
+       grep '^_*imported_wasi_' "$(SYSROOT_SHARE)/undefined-symbols.txt" \
            > "$(SYSROOT_LIB)/libc.imports"
 
        #
index 8c0776c63d117eb569c59d7467778eafcebdd7cc..eb33f4b971cb15b42b23c4e0abe046bb5fed95b6 100644 (file)
@@ -249,6 +249,51 @@ __uflow
 __unlist_locked_file
 __uselocale
 __utc
+__wasi_args_get
+__wasi_args_sizes_get
+__wasi_clock_res_get
+__wasi_clock_time_get
+__wasi_environ_get
+__wasi_environ_sizes_get
+__wasi_fd_advise
+__wasi_fd_allocate
+__wasi_fd_close
+__wasi_fd_datasync
+__wasi_fd_fdstat_get
+__wasi_fd_fdstat_set_flags
+__wasi_fd_fdstat_set_rights
+__wasi_fd_filestat_get
+__wasi_fd_filestat_set_size
+__wasi_fd_filestat_set_times
+__wasi_fd_pread
+__wasi_fd_prestat_dir_name
+__wasi_fd_prestat_get
+__wasi_fd_pwrite
+__wasi_fd_read
+__wasi_fd_readdir
+__wasi_fd_renumber
+__wasi_fd_seek
+__wasi_fd_sync
+__wasi_fd_tell
+__wasi_fd_write
+__wasi_path_create_directory
+__wasi_path_filestat_get
+__wasi_path_filestat_set_times
+__wasi_path_link
+__wasi_path_open
+__wasi_path_readlink
+__wasi_path_remove_directory
+__wasi_path_rename
+__wasi_path_symlink
+__wasi_path_unlink_file
+__wasi_poll_oneoff
+__wasi_proc_exit
+__wasi_proc_raise
+__wasi_random_get
+__wasi_sched_yield
+__wasi_sock_recv
+__wasi_sock_send
+__wasi_sock_shutdown
 __wasilibc_access
 __wasilibc_cwd
 __wasilibc_ensure_environ
index 015b4ea50c34dad4917735cf368a4ffb568319ed..63c07cc2561b4e1b0597c6d23ff0a0c23aceda2f 100644 (file)
 #define __WASI_ERRNO_TIMEDOUT (UINT16_C(73))
 #define __WASI_ERRNO_TXTBSY (UINT16_C(74))
 #define __WASI_ERRNO_XDEV (UINT16_C(75))
-#define __WASI_EVENTRWFLAGS_FD_READWRITE_HANGUP (UINT16_C(1))
+#define __WASI_EVENTRWFLAGS_FD_READWRITE_HANGUP ((__wasi_eventrwflags_t)(1 << 0))
 #define __WASI_EVENTTYPE_CLOCK (UINT8_C(0))
 #define __WASI_EVENTTYPE_FD_READ (UINT8_C(1))
 #define __WASI_EVENTTYPE_FD_WRITE (UINT8_C(2))
-#define __WASI_FDFLAGS_APPEND (UINT16_C(1))
-#define __WASI_FDFLAGS_DSYNC (UINT16_C(2))
-#define __WASI_FDFLAGS_NONBLOCK (UINT16_C(4))
-#define __WASI_FDFLAGS_RSYNC (UINT16_C(8))
-#define __WASI_FDFLAGS_SYNC (UINT16_C(16))
+#define __WASI_FDFLAGS_APPEND ((__wasi_fdflags_t)(1 << 0))
+#define __WASI_FDFLAGS_DSYNC ((__wasi_fdflags_t)(1 << 1))
+#define __WASI_FDFLAGS_NONBLOCK ((__wasi_fdflags_t)(1 << 2))
+#define __WASI_FDFLAGS_RSYNC ((__wasi_fdflags_t)(1 << 3))
+#define __WASI_FDFLAGS_SYNC ((__wasi_fdflags_t)(1 << 4))
 #define __WASI_FILETYPE_BLOCK_DEVICE (UINT8_C(1))
 #define __WASI_FILETYPE_CHARACTER_DEVICE (UINT8_C(2))
 #define __WASI_FILETYPE_DIRECTORY (UINT8_C(3))
 #define __WASI_FILETYPE_SOCKET_STREAM (UINT8_C(6))
 #define __WASI_FILETYPE_SYMBOLIC_LINK (UINT8_C(7))
 #define __WASI_FILETYPE_UNKNOWN (UINT8_C(0))
-#define __WASI_FSTFLAGS_ATIM (UINT16_C(1))
-#define __WASI_FSTFLAGS_ATIM_NOW (UINT16_C(2))
-#define __WASI_FSTFLAGS_MTIM (UINT16_C(4))
-#define __WASI_FSTFLAGS_MTIM_NOW (UINT16_C(8))
-#define __WASI_LOOKUPFLAGS_SYMLINK_FOLLOW (UINT32_C(1))
-#define __WASI_OFLAGS_CREAT (UINT16_C(1))
-#define __WASI_OFLAGS_DIRECTORY (UINT16_C(2))
-#define __WASI_OFLAGS_EXCL (UINT16_C(4))
-#define __WASI_OFLAGS_TRUNC (UINT16_C(8))
+#define __WASI_FSTFLAGS_ATIM ((__wasi_fstflags_t)(1 << 0))
+#define __WASI_FSTFLAGS_ATIM_NOW ((__wasi_fstflags_t)(1 << 1))
+#define __WASI_FSTFLAGS_MTIM ((__wasi_fstflags_t)(1 << 2))
+#define __WASI_FSTFLAGS_MTIM_NOW ((__wasi_fstflags_t)(1 << 3))
+#define __WASI_LOOKUPFLAGS_SYMLINK_FOLLOW ((__wasi_lookupflags_t)(1 << 0))
+#define __WASI_OFLAGS_CREAT ((__wasi_oflags_t)(1 << 0))
+#define __WASI_OFLAGS_DIRECTORY ((__wasi_oflags_t)(1 << 1))
+#define __WASI_OFLAGS_EXCL ((__wasi_oflags_t)(1 << 2))
+#define __WASI_OFLAGS_TRUNC ((__wasi_oflags_t)(1 << 3))
 #define __WASI_PREOPENTYPE_DIR (UINT8_C(0))
-#define __WASI_RIFLAGS_RECV_PEEK (UINT16_C(1))
-#define __WASI_RIFLAGS_RECV_WAITALL (UINT16_C(2))
-#define __WASI_RIGHTS_FD_ADVISE (UINT64_C(128))
-#define __WASI_RIGHTS_FD_ALLOCATE (UINT64_C(256))
-#define __WASI_RIGHTS_FD_DATASYNC (UINT64_C(1))
-#define __WASI_RIGHTS_FD_FDSTAT_SET_FLAGS (UINT64_C(8))
-#define __WASI_RIGHTS_FD_FILESTAT_GET (UINT64_C(2097152))
-#define __WASI_RIGHTS_FD_FILESTAT_SET_SIZE (UINT64_C(4194304))
-#define __WASI_RIGHTS_FD_FILESTAT_SET_TIMES (UINT64_C(8388608))
-#define __WASI_RIGHTS_FD_READ (UINT64_C(2))
-#define __WASI_RIGHTS_FD_READDIR (UINT64_C(16384))
-#define __WASI_RIGHTS_FD_SEEK (UINT64_C(4))
-#define __WASI_RIGHTS_FD_SYNC (UINT64_C(16))
-#define __WASI_RIGHTS_FD_TELL (UINT64_C(32))
-#define __WASI_RIGHTS_FD_WRITE (UINT64_C(64))
-#define __WASI_RIGHTS_PATH_CREATE_DIRECTORY (UINT64_C(512))
-#define __WASI_RIGHTS_PATH_CREATE_FILE (UINT64_C(1024))
-#define __WASI_RIGHTS_PATH_FILESTAT_GET (UINT64_C(262144))
-#define __WASI_RIGHTS_PATH_FILESTAT_SET_SIZE (UINT64_C(524288))
-#define __WASI_RIGHTS_PATH_FILESTAT_SET_TIMES (UINT64_C(1048576))
-#define __WASI_RIGHTS_PATH_LINK_SOURCE (UINT64_C(2048))
-#define __WASI_RIGHTS_PATH_LINK_TARGET (UINT64_C(4096))
-#define __WASI_RIGHTS_PATH_OPEN (UINT64_C(8192))
-#define __WASI_RIGHTS_PATH_READLINK (UINT64_C(32768))
-#define __WASI_RIGHTS_PATH_REMOVE_DIRECTORY (UINT64_C(33554432))
-#define __WASI_RIGHTS_PATH_RENAME_SOURCE (UINT64_C(65536))
-#define __WASI_RIGHTS_PATH_RENAME_TARGET (UINT64_C(131072))
-#define __WASI_RIGHTS_PATH_SYMLINK (UINT64_C(16777216))
-#define __WASI_RIGHTS_PATH_UNLINK_FILE (UINT64_C(67108864))
-#define __WASI_RIGHTS_POLL_FD_READWRITE (UINT64_C(134217728))
-#define __WASI_RIGHTS_SOCK_SHUTDOWN (UINT64_C(268435456))
-#define __WASI_ROFLAGS_RECV_DATA_TRUNCATED (UINT16_C(1))
-#define __WASI_SDFLAGS_RD (UINT8_C(1))
-#define __WASI_SDFLAGS_WR (UINT8_C(2))
+#define __WASI_RIFLAGS_RECV_PEEK ((__wasi_riflags_t)(1 << 0))
+#define __WASI_RIFLAGS_RECV_WAITALL ((__wasi_riflags_t)(1 << 1))
+#define __WASI_RIGHTS_FD_ADVISE ((__wasi_rights_t)(1 << 7))
+#define __WASI_RIGHTS_FD_ALLOCATE ((__wasi_rights_t)(1 << 8))
+#define __WASI_RIGHTS_FD_DATASYNC ((__wasi_rights_t)(1 << 0))
+#define __WASI_RIGHTS_FD_FDSTAT_SET_FLAGS ((__wasi_rights_t)(1 << 3))
+#define __WASI_RIGHTS_FD_FILESTAT_GET ((__wasi_rights_t)(1 << 21))
+#define __WASI_RIGHTS_FD_FILESTAT_SET_SIZE ((__wasi_rights_t)(1 << 22))
+#define __WASI_RIGHTS_FD_FILESTAT_SET_TIMES ((__wasi_rights_t)(1 << 23))
+#define __WASI_RIGHTS_FD_READ ((__wasi_rights_t)(1 << 1))
+#define __WASI_RIGHTS_FD_READDIR ((__wasi_rights_t)(1 << 14))
+#define __WASI_RIGHTS_FD_SEEK ((__wasi_rights_t)(1 << 2))
+#define __WASI_RIGHTS_FD_SYNC ((__wasi_rights_t)(1 << 4))
+#define __WASI_RIGHTS_FD_TELL ((__wasi_rights_t)(1 << 5))
+#define __WASI_RIGHTS_FD_WRITE ((__wasi_rights_t)(1 << 6))
+#define __WASI_RIGHTS_PATH_CREATE_DIRECTORY ((__wasi_rights_t)(1 << 9))
+#define __WASI_RIGHTS_PATH_CREATE_FILE ((__wasi_rights_t)(1 << 10))
+#define __WASI_RIGHTS_PATH_FILESTAT_GET ((__wasi_rights_t)(1 << 18))
+#define __WASI_RIGHTS_PATH_FILESTAT_SET_SIZE ((__wasi_rights_t)(1 << 19))
+#define __WASI_RIGHTS_PATH_FILESTAT_SET_TIMES ((__wasi_rights_t)(1 << 20))
+#define __WASI_RIGHTS_PATH_LINK_SOURCE ((__wasi_rights_t)(1 << 11))
+#define __WASI_RIGHTS_PATH_LINK_TARGET ((__wasi_rights_t)(1 << 12))
+#define __WASI_RIGHTS_PATH_OPEN ((__wasi_rights_t)(1 << 13))
+#define __WASI_RIGHTS_PATH_READLINK ((__wasi_rights_t)(1 << 15))
+#define __WASI_RIGHTS_PATH_REMOVE_DIRECTORY ((__wasi_rights_t)(1 << 25))
+#define __WASI_RIGHTS_PATH_RENAME_SOURCE ((__wasi_rights_t)(1 << 16))
+#define __WASI_RIGHTS_PATH_RENAME_TARGET ((__wasi_rights_t)(1 << 17))
+#define __WASI_RIGHTS_PATH_SYMLINK ((__wasi_rights_t)(1 << 24))
+#define __WASI_RIGHTS_PATH_UNLINK_FILE ((__wasi_rights_t)(1 << 26))
+#define __WASI_RIGHTS_POLL_FD_READWRITE ((__wasi_rights_t)(1 << 27))
+#define __WASI_RIGHTS_SOCK_SHUTDOWN ((__wasi_rights_t)(1 << 28))
+#define __WASI_ROFLAGS_RECV_DATA_TRUNCATED ((__wasi_roflags_t)(1 << 0))
+#define __WASI_SDFLAGS_RD ((__wasi_sdflags_t)(1 << 0))
+#define __WASI_SDFLAGS_WR ((__wasi_sdflags_t)(1 << 1))
 #define __WASI_SIGNAL_ABRT (UINT8_C(6))
 #define __WASI_SIGNAL_ALRM (UINT8_C(14))
 #define __WASI_SIGNAL_BUS (UINT8_C(7))
 #define __WASI_SIGNAL_WINCH (UINT8_C(27))
 #define __WASI_SIGNAL_XCPU (UINT8_C(23))
 #define __WASI_SIGNAL_XFSZ (UINT8_C(24))
-#define __WASI_SUBCLOCKFLAGS_SUBSCRIPTION_CLOCK_ABSTIME (UINT16_C(1))
+#define __WASI_SUBCLOCKFLAGS_SUBSCRIPTION_CLOCK_ABSTIME ((__wasi_subclockflags_t)(1 << 0))
 #define __WASI_WHENCE_CUR (UINT8_C(1))
 #define __WASI_WHENCE_END (UINT8_C(2))
 #define __WASI_WHENCE_SET (UINT8_C(0))
index 47e31069034132e16b0c930206c63ce677ed4d9a..dd981ecd10e7adf150525e3b8a644df386d573ff 100644 (file)
@@ -11,6 +11,51 @@ __floatunsitf
 __getf2
 __gttf2
 __heap_base
+__imported_wasi_snapshot_preview1_args_get
+__imported_wasi_snapshot_preview1_args_sizes_get
+__imported_wasi_snapshot_preview1_clock_res_get
+__imported_wasi_snapshot_preview1_clock_time_get
+__imported_wasi_snapshot_preview1_environ_get
+__imported_wasi_snapshot_preview1_environ_sizes_get
+__imported_wasi_snapshot_preview1_fd_advise
+__imported_wasi_snapshot_preview1_fd_allocate
+__imported_wasi_snapshot_preview1_fd_close
+__imported_wasi_snapshot_preview1_fd_datasync
+__imported_wasi_snapshot_preview1_fd_fdstat_get
+__imported_wasi_snapshot_preview1_fd_fdstat_set_flags
+__imported_wasi_snapshot_preview1_fd_fdstat_set_rights
+__imported_wasi_snapshot_preview1_fd_filestat_get
+__imported_wasi_snapshot_preview1_fd_filestat_set_size
+__imported_wasi_snapshot_preview1_fd_filestat_set_times
+__imported_wasi_snapshot_preview1_fd_pread
+__imported_wasi_snapshot_preview1_fd_prestat_dir_name
+__imported_wasi_snapshot_preview1_fd_prestat_get
+__imported_wasi_snapshot_preview1_fd_pwrite
+__imported_wasi_snapshot_preview1_fd_read
+__imported_wasi_snapshot_preview1_fd_readdir
+__imported_wasi_snapshot_preview1_fd_renumber
+__imported_wasi_snapshot_preview1_fd_seek
+__imported_wasi_snapshot_preview1_fd_sync
+__imported_wasi_snapshot_preview1_fd_tell
+__imported_wasi_snapshot_preview1_fd_write
+__imported_wasi_snapshot_preview1_path_create_directory
+__imported_wasi_snapshot_preview1_path_filestat_get
+__imported_wasi_snapshot_preview1_path_filestat_set_times
+__imported_wasi_snapshot_preview1_path_link
+__imported_wasi_snapshot_preview1_path_open
+__imported_wasi_snapshot_preview1_path_readlink
+__imported_wasi_snapshot_preview1_path_remove_directory
+__imported_wasi_snapshot_preview1_path_rename
+__imported_wasi_snapshot_preview1_path_symlink
+__imported_wasi_snapshot_preview1_path_unlink_file
+__imported_wasi_snapshot_preview1_poll_oneoff
+__imported_wasi_snapshot_preview1_proc_exit
+__imported_wasi_snapshot_preview1_proc_raise
+__imported_wasi_snapshot_preview1_random_get
+__imported_wasi_snapshot_preview1_sched_yield
+__imported_wasi_snapshot_preview1_sock_recv
+__imported_wasi_snapshot_preview1_sock_send
+__imported_wasi_snapshot_preview1_sock_shutdown
 __letf2
 __lttf2
 __netf2
@@ -19,48 +64,5 @@ __subtf3
 __trunctfdf2
 __trunctfsf2
 __unordtf2
-__wasi_args_get
-__wasi_args_sizes_get
-__wasi_clock_res_get
-__wasi_clock_time_get
-__wasi_environ_get
-__wasi_environ_sizes_get
-__wasi_fd_advise
-__wasi_fd_allocate
-__wasi_fd_close
-__wasi_fd_datasync
-__wasi_fd_fdstat_get
-__wasi_fd_fdstat_set_flags
-__wasi_fd_filestat_get
-__wasi_fd_filestat_set_size
-__wasi_fd_filestat_set_times
-__wasi_fd_pread
-__wasi_fd_prestat_dir_name
-__wasi_fd_prestat_get
-__wasi_fd_pwrite
-__wasi_fd_read
-__wasi_fd_readdir
-__wasi_fd_renumber
-__wasi_fd_seek
-__wasi_fd_sync
-__wasi_fd_tell
-__wasi_fd_write
-__wasi_path_create_directory
-__wasi_path_filestat_get
-__wasi_path_filestat_set_times
-__wasi_path_link
-__wasi_path_open
-__wasi_path_readlink
-__wasi_path_remove_directory
-__wasi_path_rename
-__wasi_path_symlink
-__wasi_path_unlink_file
-__wasi_poll_oneoff
-__wasi_proc_exit
-__wasi_random_get
-__wasi_sched_yield
-__wasi_sock_recv
-__wasi_sock_send
-__wasi_sock_shutdown
 __wasm_call_ctors
 main
index f5a4cbdebfa6fba16ae85a4644d27d8c675939cb..46919fe8149120077655762be9624ca9a7905928 100644 (file)
@@ -70,7 +70,7 @@ int __wasilibc_nocwd_openat_nomode(int fd, const char *path, int oflag) {
   __wasi_rights_t fs_rights_base = max & fsb_cur.fs_rights_inheriting;
   __wasi_rights_t fs_rights_inheriting = fsb_cur.fs_rights_inheriting;
   __wasi_fd_t newfd;
-  error = __wasi_path_open(fd, lookup_flags, path, strlen(path),
+  error = __wasi_path_open(fd, lookup_flags, path,
                                  (oflag >> 12) & 0xfff,
                                  fs_rights_base, fs_rights_inheriting, fs_flags,
                                  &newfd);
index 031a71fc334b3ff2da9c808ad3264e117eae1d5d..e43cef22c279d518df9858f1d7dd698ef282cdad 100644 (file)
@@ -10,8 +10,7 @@
 #include <string.h>
 
 int __wasilibc_nocwd_renameat(int oldfd, const char *old, int newfd, const char *new) {
-  __wasi_errno_t error = __wasi_path_rename(oldfd, old, strlen(old),
-                                            newfd, new, strlen(new));
+  __wasi_errno_t error = __wasi_path_rename(oldfd, old, newfd, new);
   if (error != 0) {
     errno = errno_fixup_directory(oldfd, errno_fixup_directory(newfd, error));
     return -1;
index db5bf1f808671dfd123101ddd5f51155fb8b143f..f037d99dbe794f49b4f10c2ec5a9570fb97fce4c 100644 (file)
@@ -23,7 +23,7 @@ int __wasilibc_nocwd_fstatat(int fd, const char *restrict path, struct stat *res
   // Perform system call.
   __wasi_filestat_t internal_stat;
   __wasi_errno_t error =
-      __wasi_path_filestat_get(fd, lookup_flags, path, strlen(path), &internal_stat);
+      __wasi_path_filestat_get(fd, lookup_flags, path, &internal_stat);
   if (error != 0) {
     errno = errno_fixup_directory(fd, error);
     return -1;
index f956dd5ffc992debccb6019f3927a54ba7aa806d..c89ce3db52ed96c9d1aa277a8485956da7dbdfea 100644 (file)
@@ -11,8 +11,7 @@
 #include <string.h>
 
 int __wasilibc_nocwd_mkdirat_nomode(int fd, const char *path) {
-  __wasi_errno_t error = __wasi_path_create_directory(
-      fd, path, strlen(path));
+  __wasi_errno_t error = __wasi_path_create_directory(fd, path);
   if (error != 0) {
     errno = errno_fixup_directory(fd, error);
     return -1;
index 67f3adf5548c71f5df6f2026a0ad7b0a14f49992..a5727162011eb7e9a66655cba4d8860489b27a47 100644 (file)
@@ -31,7 +31,7 @@ int __wasilibc_nocwd_utimensat(int fd, const char *path, const struct timespec t
 
   // Perform system call.
   __wasi_errno_t error =
-      __wasi_path_filestat_set_times(fd, lookup_flags, path, strlen(path), st_atim, st_mtim, flags);
+      __wasi_path_filestat_set_times(fd, lookup_flags, path, st_atim, st_mtim, flags);
   if (error != 0) {
     errno = errno_fixup_directory(fd, error);
     return -1;
index a60faf8adb596b9a43b9ed6642f9f7e40bf33f5e..077250c6673d746c8628d29c20a4a44163a11ac4 100644 (file)
@@ -22,7 +22,7 @@ int __wasilibc_nocwd_faccessat(int fd, const char *path, int amode, int flag) {
   __wasi_lookupflags_t lookup_flags = __WASI_LOOKUPFLAGS_SYMLINK_FOLLOW;
   __wasi_filestat_t file;
   __wasi_errno_t error =
-      __wasi_path_filestat_get(fd, lookup_flags, path, strlen(path), &file);
+      __wasi_path_filestat_get(fd, lookup_flags, path, &file);
   if (error != 0) {
     errno = errno_fixup_directory(fd, error);
     return -1;
index d861d7b55f4fd31486be626030e3e08e307dfe24..683dd4cf65ecaee4510d8ff06819f91744e47d5f 100644 (file)
@@ -17,8 +17,7 @@ int __wasilibc_nocwd_linkat(int fd1, const char *path1, int fd2, const char *pat
     lookup1_flags |= __WASI_LOOKUPFLAGS_SYMLINK_FOLLOW;
 
   // Perform system call.
-  __wasi_errno_t error = __wasi_path_link(fd1, lookup1_flags, path1, strlen(path1),
-                                          fd2, path2, strlen(path2));
+  __wasi_errno_t error = __wasi_path_link(fd1, lookup1_flags, path1, fd2, path2);
   if (error != 0) {
     errno = errno_fixup_directory(fd1, errno_fixup_directory(fd2, error));
     return -1;
index 3732620e05a84f0ae764a3821b912953e4ecbcb0..e08afb9b3c35b9872c7e95b92e67dc72b65ef605 100644 (file)
@@ -13,7 +13,7 @@ ssize_t __wasilibc_nocwd_readlinkat(int fd, const char *restrict path, char *res
                                     size_t bufsize) {
   size_t bufused;
   // TODO: Remove the cast on `buf` once the witx is updated with char8 support.
-  __wasi_errno_t error = __wasi_path_readlink(fd, path, strlen(path),
+  __wasi_errno_t error = __wasi_path_readlink(fd, path,
                                                       (uint8_t*)buf, bufsize, &bufused);
   if (error != 0) {
     errno = errno_fixup_directory(fd, error);
index 2ffbcf3bd02c1fdcc371a639f5b76cb1124ee550..1705afc1c548a018781458896b6e543881e827cd 100644 (file)
@@ -10,8 +10,7 @@
 #include <unistd.h>
 
 int __wasilibc_nocwd_symlinkat(const char *path1, int fd, const char *path2) {
-  __wasi_errno_t error =
-      __wasi_path_symlink(path1, strlen(path1), fd, path2, strlen(path2));
+  __wasi_errno_t error = __wasi_path_symlink(path1, fd, path2);
   if (error != 0) {
     errno = errno_fixup_directory(fd, error);
     return -1;
index 734d21203c52849a132bb4e23dde41c4af62ea57..7a208be51e5145ba42527ceb98dec49a6aef3dd8 100644 (file)
@@ -1,6 +1,13 @@
 /**
  * THIS FILE IS AUTO-GENERATED from the following files:
- *   typenames.witx, wasi_snapshot_preview1.witx
+ *   wasi_snapshot_preview1.witx
+ *
+ * To regenerate this file execute:
+ *
+ *     cargo run --manifest-path tools/wasi-headers/Cargo.toml generate-libc
+ *
+ * Modifications to this file will cause CI to fail, the code generator tool
+ * must be modified to change this file.
  *
  * @file
  * This file describes the [WASI] interface, consisting of functions, types,
@@ -502,160 +509,157 @@ typedef uint64_t __wasi_rights_t;
  * If `path_open` is set, includes the right to invoke
  * `path_open` with `fdflags::dsync`.
  */
-#define __WASI_RIGHTS_FD_DATASYNC (UINT64_C(1))
+#define __WASI_RIGHTS_FD_DATASYNC ((__wasi_rights_t)(1 << 0))
 
 /**
  * The right to invoke `fd_read` and `sock_recv`.
  * If `rights::fd_seek` is set, includes the right to invoke `fd_pread`.
  */
-#define __WASI_RIGHTS_FD_READ (UINT64_C(2))
+#define __WASI_RIGHTS_FD_READ ((__wasi_rights_t)(1 << 1))
 
 /**
  * The right to invoke `fd_seek`. This flag implies `rights::fd_tell`.
  */
-#define __WASI_RIGHTS_FD_SEEK (UINT64_C(4))
+#define __WASI_RIGHTS_FD_SEEK ((__wasi_rights_t)(1 << 2))
 
 /**
  * The right to invoke `fd_fdstat_set_flags`.
  */
-#define __WASI_RIGHTS_FD_FDSTAT_SET_FLAGS (UINT64_C(8))
+#define __WASI_RIGHTS_FD_FDSTAT_SET_FLAGS ((__wasi_rights_t)(1 << 3))
 
 /**
  * The right to invoke `fd_sync`.
  * If `path_open` is set, includes the right to invoke
  * `path_open` with `fdflags::rsync` and `fdflags::dsync`.
  */
-#define __WASI_RIGHTS_FD_SYNC (UINT64_C(16))
+#define __WASI_RIGHTS_FD_SYNC ((__wasi_rights_t)(1 << 4))
 
 /**
  * The right to invoke `fd_seek` in such a way that the file offset
  * remains unaltered (i.e., `whence::cur` with offset zero), or to
  * invoke `fd_tell`.
  */
-#define __WASI_RIGHTS_FD_TELL (UINT64_C(32))
+#define __WASI_RIGHTS_FD_TELL ((__wasi_rights_t)(1 << 5))
 
 /**
  * The right to invoke `fd_write` and `sock_send`.
  * If `rights::fd_seek` is set, includes the right to invoke `fd_pwrite`.
  */
-#define __WASI_RIGHTS_FD_WRITE (UINT64_C(64))
+#define __WASI_RIGHTS_FD_WRITE ((__wasi_rights_t)(1 << 6))
 
 /**
  * The right to invoke `fd_advise`.
  */
-#define __WASI_RIGHTS_FD_ADVISE (UINT64_C(128))
+#define __WASI_RIGHTS_FD_ADVISE ((__wasi_rights_t)(1 << 7))
 
 /**
  * The right to invoke `fd_allocate`.
  */
-#define __WASI_RIGHTS_FD_ALLOCATE (UINT64_C(256))
+#define __WASI_RIGHTS_FD_ALLOCATE ((__wasi_rights_t)(1 << 8))
 
 /**
  * The right to invoke `path_create_directory`.
  */
-#define __WASI_RIGHTS_PATH_CREATE_DIRECTORY (UINT64_C(512))
+#define __WASI_RIGHTS_PATH_CREATE_DIRECTORY ((__wasi_rights_t)(1 << 9))
 
 /**
  * If `path_open` is set, the right to invoke `path_open` with `oflags::creat`.
  */
-#define __WASI_RIGHTS_PATH_CREATE_FILE (UINT64_C(1024))
+#define __WASI_RIGHTS_PATH_CREATE_FILE ((__wasi_rights_t)(1 << 10))
 
 /**
  * The right to invoke `path_link` with the file descriptor as the
  * source directory.
  */
-#define __WASI_RIGHTS_PATH_LINK_SOURCE (UINT64_C(2048))
+#define __WASI_RIGHTS_PATH_LINK_SOURCE ((__wasi_rights_t)(1 << 11))
 
 /**
  * The right to invoke `path_link` with the file descriptor as the
  * target directory.
  */
-#define __WASI_RIGHTS_PATH_LINK_TARGET (UINT64_C(4096))
+#define __WASI_RIGHTS_PATH_LINK_TARGET ((__wasi_rights_t)(1 << 12))
 
 /**
  * The right to invoke `path_open`.
  */
-#define __WASI_RIGHTS_PATH_OPEN (UINT64_C(8192))
+#define __WASI_RIGHTS_PATH_OPEN ((__wasi_rights_t)(1 << 13))
 
 /**
  * The right to invoke `fd_readdir`.
  */
-#define __WASI_RIGHTS_FD_READDIR (UINT64_C(16384))
+#define __WASI_RIGHTS_FD_READDIR ((__wasi_rights_t)(1 << 14))
 
 /**
  * The right to invoke `path_readlink`.
  */
-#define __WASI_RIGHTS_PATH_READLINK (UINT64_C(32768))
+#define __WASI_RIGHTS_PATH_READLINK ((__wasi_rights_t)(1 << 15))
 
 /**
  * The right to invoke `path_rename` with the file descriptor as the source directory.
  */
-#define __WASI_RIGHTS_PATH_RENAME_SOURCE (UINT64_C(65536))
+#define __WASI_RIGHTS_PATH_RENAME_SOURCE ((__wasi_rights_t)(1 << 16))
 
 /**
  * The right to invoke `path_rename` with the file descriptor as the target directory.
  */
-#define __WASI_RIGHTS_PATH_RENAME_TARGET (UINT64_C(131072))
+#define __WASI_RIGHTS_PATH_RENAME_TARGET ((__wasi_rights_t)(1 << 17))
 
 /**
  * The right to invoke `path_filestat_get`.
  */
-#define __WASI_RIGHTS_PATH_FILESTAT_GET (UINT64_C(262144))
+#define __WASI_RIGHTS_PATH_FILESTAT_GET ((__wasi_rights_t)(1 << 18))
 
 /**
  * The right to change a file's size (there is no `path_filestat_set_size`).
  * If `path_open` is set, includes the right to invoke `path_open` with `oflags::trunc`.
  */
-#define __WASI_RIGHTS_PATH_FILESTAT_SET_SIZE (UINT64_C(524288))
+#define __WASI_RIGHTS_PATH_FILESTAT_SET_SIZE ((__wasi_rights_t)(1 << 19))
 
 /**
  * The right to invoke `path_filestat_set_times`.
  */
-#define __WASI_RIGHTS_PATH_FILESTAT_SET_TIMES (UINT64_C(1048576))
+#define __WASI_RIGHTS_PATH_FILESTAT_SET_TIMES ((__wasi_rights_t)(1 << 20))
 
 /**
  * The right to invoke `fd_filestat_get`.
  */
-#define __WASI_RIGHTS_FD_FILESTAT_GET (UINT64_C(2097152))
+#define __WASI_RIGHTS_FD_FILESTAT_GET ((__wasi_rights_t)(1 << 21))
 
 /**
  * The right to invoke `fd_filestat_set_size`.
  */
-#define __WASI_RIGHTS_FD_FILESTAT_SET_SIZE (UINT64_C(4194304))
+#define __WASI_RIGHTS_FD_FILESTAT_SET_SIZE ((__wasi_rights_t)(1 << 22))
 
 /**
  * The right to invoke `fd_filestat_set_times`.
  */
-#define __WASI_RIGHTS_FD_FILESTAT_SET_TIMES (UINT64_C(8388608))
+#define __WASI_RIGHTS_FD_FILESTAT_SET_TIMES ((__wasi_rights_t)(1 << 23))
 
 /**
  * The right to invoke `path_symlink`.
  */
-#define __WASI_RIGHTS_PATH_SYMLINK (UINT64_C(16777216))
+#define __WASI_RIGHTS_PATH_SYMLINK ((__wasi_rights_t)(1 << 24))
 
 /**
  * The right to invoke `path_remove_directory`.
  */
-#define __WASI_RIGHTS_PATH_REMOVE_DIRECTORY (UINT64_C(33554432))
+#define __WASI_RIGHTS_PATH_REMOVE_DIRECTORY ((__wasi_rights_t)(1 << 25))
 
 /**
  * The right to invoke `path_unlink_file`.
  */
-#define __WASI_RIGHTS_PATH_UNLINK_FILE (UINT64_C(67108864))
+#define __WASI_RIGHTS_PATH_UNLINK_FILE ((__wasi_rights_t)(1 << 26))
 
 /**
  * If `rights::fd_read` is set, includes the right to invoke `poll_oneoff` to subscribe to `eventtype::fd_read`.
  * If `rights::fd_write` is set, includes the right to invoke `poll_oneoff` to subscribe to `eventtype::fd_write`.
  */
-#define __WASI_RIGHTS_POLL_FD_READWRITE (UINT64_C(134217728))
+#define __WASI_RIGHTS_POLL_FD_READWRITE ((__wasi_rights_t)(1 << 27))
 
 /**
  * The right to invoke `sock_shutdown`.
  */
-#define __WASI_RIGHTS_SOCK_SHUTDOWN (UINT64_C(268435456))
-
-_Static_assert(sizeof(__wasi_rights_t) == 8, "witx calculated size");
-_Static_assert(_Alignof(__wasi_rights_t) == 8, "witx calculated align");
+#define __WASI_RIGHTS_SOCK_SHUTDOWN ((__wasi_rights_t)(1 << 28))
 
 /**
  * A file descriptor handle.
@@ -749,7 +753,7 @@ _Static_assert(sizeof(__wasi_dircookie_t) == 8, "witx calculated size");
 _Static_assert(_Alignof(__wasi_dircookie_t) == 8, "witx calculated align");
 
 /**
- * The type for the $d_namlen field of $dirent.
+ * The type for the `dirent::d_namlen` field of `dirent` struct.
  */
 typedef uint32_t __wasi_dirnamlen_t;
 
@@ -891,32 +895,29 @@ typedef uint16_t __wasi_fdflags_t;
 /**
  * Append mode: Data written to the file is always appended to the file's end.
  */
-#define __WASI_FDFLAGS_APPEND (UINT16_C(1))
+#define __WASI_FDFLAGS_APPEND ((__wasi_fdflags_t)(1 << 0))
 
 /**
  * Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized.
  */
-#define __WASI_FDFLAGS_DSYNC (UINT16_C(2))
+#define __WASI_FDFLAGS_DSYNC ((__wasi_fdflags_t)(1 << 1))
 
 /**
  * Non-blocking mode.
  */
-#define __WASI_FDFLAGS_NONBLOCK (UINT16_C(4))
+#define __WASI_FDFLAGS_NONBLOCK ((__wasi_fdflags_t)(1 << 2))
 
 /**
  * Synchronized read I/O operations.
  */
-#define __WASI_FDFLAGS_RSYNC (UINT16_C(8))
+#define __WASI_FDFLAGS_RSYNC ((__wasi_fdflags_t)(1 << 3))
 
 /**
  * Write according to synchronized I/O file integrity completion. In
  * addition to synchronizing the data stored in the file, the implementation
  * may also synchronously update the file's metadata.
  */
-#define __WASI_FDFLAGS_SYNC (UINT16_C(16))
-
-_Static_assert(sizeof(__wasi_fdflags_t) == 2, "witx calculated size");
-_Static_assert(_Alignof(__wasi_fdflags_t) == 2, "witx calculated align");
+#define __WASI_FDFLAGS_SYNC ((__wasi_fdflags_t)(1 << 4))
 
 /**
  * File descriptor attributes.
@@ -969,25 +970,22 @@ typedef uint16_t __wasi_fstflags_t;
 /**
  * Adjust the last data access timestamp to the value stored in `filestat::atim`.
  */
-#define __WASI_FSTFLAGS_ATIM (UINT16_C(1))
+#define __WASI_FSTFLAGS_ATIM ((__wasi_fstflags_t)(1 << 0))
 
 /**
  * Adjust the last data access timestamp to the time of clock `clockid::realtime`.
  */
-#define __WASI_FSTFLAGS_ATIM_NOW (UINT16_C(2))
+#define __WASI_FSTFLAGS_ATIM_NOW ((__wasi_fstflags_t)(1 << 1))
 
 /**
  * Adjust the last data modification timestamp to the value stored in `filestat::mtim`.
  */
-#define __WASI_FSTFLAGS_MTIM (UINT16_C(4))
+#define __WASI_FSTFLAGS_MTIM ((__wasi_fstflags_t)(1 << 2))
 
 /**
  * Adjust the last data modification timestamp to the time of clock `clockid::realtime`.
  */
-#define __WASI_FSTFLAGS_MTIM_NOW (UINT16_C(8))
-
-_Static_assert(sizeof(__wasi_fstflags_t) == 2, "witx calculated size");
-_Static_assert(_Alignof(__wasi_fstflags_t) == 2, "witx calculated align");
+#define __WASI_FSTFLAGS_MTIM_NOW ((__wasi_fstflags_t)(1 << 3))
 
 /**
  * Flags determining the method of how paths are resolved.
@@ -997,10 +995,7 @@ typedef uint32_t __wasi_lookupflags_t;
 /**
  * As long as the resolved path corresponds to a symbolic link, it is expanded.
  */
-#define __WASI_LOOKUPFLAGS_SYMLINK_FOLLOW (UINT32_C(1))
-
-_Static_assert(sizeof(__wasi_lookupflags_t) == 4, "witx calculated size");
-_Static_assert(_Alignof(__wasi_lookupflags_t) == 4, "witx calculated align");
+#define __WASI_LOOKUPFLAGS_SYMLINK_FOLLOW ((__wasi_lookupflags_t)(1 << 0))
 
 /**
  * Open flags used by `path_open`.
@@ -1010,25 +1005,22 @@ typedef uint16_t __wasi_oflags_t;
 /**
  * Create file if it does not exist.
  */
-#define __WASI_OFLAGS_CREAT (UINT16_C(1))
+#define __WASI_OFLAGS_CREAT ((__wasi_oflags_t)(1 << 0))
 
 /**
  * Fail if not a directory.
  */
-#define __WASI_OFLAGS_DIRECTORY (UINT16_C(2))
+#define __WASI_OFLAGS_DIRECTORY ((__wasi_oflags_t)(1 << 1))
 
 /**
  * Fail if file already exists.
  */
-#define __WASI_OFLAGS_EXCL (UINT16_C(4))
+#define __WASI_OFLAGS_EXCL ((__wasi_oflags_t)(1 << 2))
 
 /**
  * Truncate file to size 0.
  */
-#define __WASI_OFLAGS_TRUNC (UINT16_C(8))
-
-_Static_assert(sizeof(__wasi_oflags_t) == 2, "witx calculated size");
-_Static_assert(_Alignof(__wasi_oflags_t) == 2, "witx calculated align");
+#define __WASI_OFLAGS_TRUNC ((__wasi_oflags_t)(1 << 3))
 
 /**
  * Number of hard links to an inode.
@@ -1139,13 +1131,10 @@ typedef uint16_t __wasi_eventrwflags_t;
 /**
  * The peer of this socket has closed or disconnected.
  */
-#define __WASI_EVENTRWFLAGS_FD_READWRITE_HANGUP (UINT16_C(1))
-
-_Static_assert(sizeof(__wasi_eventrwflags_t) == 2, "witx calculated size");
-_Static_assert(_Alignof(__wasi_eventrwflags_t) == 2, "witx calculated align");
+#define __WASI_EVENTRWFLAGS_FD_READWRITE_HANGUP ((__wasi_eventrwflags_t)(1 << 0))
 
 /**
- * The contents of an $event when type is `eventtype::fd_read` or
+ * The contents of an `event` when type is `eventtype::fd_read` or
  * `eventtype::fd_write`.
  */
 typedef struct __wasi_event_fd_readwrite_t {
@@ -1213,10 +1202,7 @@ typedef uint16_t __wasi_subclockflags_t;
  * provided in `subscription_clock::timeout` relative to the
  * current time value of clock `subscription_clock::id`.
  */
-#define __WASI_SUBCLOCKFLAGS_SUBSCRIPTION_CLOCK_ABSTIME (UINT16_C(1))
-
-_Static_assert(sizeof(__wasi_subclockflags_t) == 2, "witx calculated size");
-_Static_assert(_Alignof(__wasi_subclockflags_t) == 2, "witx calculated align");
+#define __WASI_SUBCLOCKFLAGS_SUBSCRIPTION_CLOCK_ABSTIME ((__wasi_subclockflags_t)(1 << 0))
 
 /**
  * The contents of a `subscription` when type is `eventtype::clock`.
@@ -1277,15 +1263,12 @@ typedef union __wasi_subscription_u_u_t {
     __wasi_subscription_fd_readwrite_t fd_write;
 } __wasi_subscription_u_u_t;
 typedef struct __wasi_subscription_u_t {
-    __wasi_eventtype_t tag;
+    uint8_t tag;
     __wasi_subscription_u_u_t u;
 } __wasi_subscription_u_t;
 
 _Static_assert(sizeof(__wasi_subscription_u_t) == 40, "witx calculated size");
 _Static_assert(_Alignof(__wasi_subscription_u_t) == 8, "witx calculated align");
-_Static_assert(offsetof(__wasi_subscription_u_t, u) == 8, "witx calculated union offset");
-_Static_assert(sizeof(__wasi_subscription_u_u_t) == 32, "witx calculated union size");
-_Static_assert(_Alignof(__wasi_subscription_u_u_t) == 8, "witx calculated union align");
 
 /**
  * Subscription to an event.
@@ -1519,15 +1502,12 @@ typedef uint16_t __wasi_riflags_t;
 /**
  * Returns the message without removing it from the socket's receive queue.
  */
-#define __WASI_RIFLAGS_RECV_PEEK (UINT16_C(1))
+#define __WASI_RIFLAGS_RECV_PEEK ((__wasi_riflags_t)(1 << 0))
 
 /**
  * On byte-stream sockets, block until the full amount of data can be returned.
  */
-#define __WASI_RIFLAGS_RECV_WAITALL (UINT16_C(2))
-
-_Static_assert(sizeof(__wasi_riflags_t) == 2, "witx calculated size");
-_Static_assert(_Alignof(__wasi_riflags_t) == 2, "witx calculated align");
+#define __WASI_RIFLAGS_RECV_WAITALL ((__wasi_riflags_t)(1 << 1))
 
 /**
  * Flags returned by `sock_recv`.
@@ -1537,10 +1517,7 @@ typedef uint16_t __wasi_roflags_t;
 /**
  * Returned by `sock_recv`: Message data has been truncated.
  */
-#define __WASI_ROFLAGS_RECV_DATA_TRUNCATED (UINT16_C(1))
-
-_Static_assert(sizeof(__wasi_roflags_t) == 2, "witx calculated size");
-_Static_assert(_Alignof(__wasi_roflags_t) == 2, "witx calculated align");
+#define __WASI_ROFLAGS_RECV_DATA_TRUNCATED ((__wasi_roflags_t)(1 << 0))
 
 /**
  * Flags provided to `sock_send`. As there are currently no flags
@@ -1559,15 +1536,12 @@ typedef uint8_t __wasi_sdflags_t;
 /**
  * Disables further receive operations.
  */
-#define __WASI_SDFLAGS_RD (UINT8_C(1))
+#define __WASI_SDFLAGS_RD ((__wasi_sdflags_t)(1 << 0))
 
 /**
  * Disables further send operations.
  */
-#define __WASI_SDFLAGS_WR (UINT8_C(2))
-
-_Static_assert(sizeof(__wasi_sdflags_t) == 1, "witx calculated size");
-_Static_assert(_Alignof(__wasi_sdflags_t) == 1, "witx calculated align");
+#define __WASI_SDFLAGS_WR ((__wasi_sdflags_t)(1 << 1))
 
 /**
  * Identifiers for preopened capabilities.
@@ -1604,15 +1578,12 @@ typedef union __wasi_prestat_u_t {
     __wasi_prestat_dir_t dir;
 } __wasi_prestat_u_t;
 typedef struct __wasi_prestat_t {
-    __wasi_preopentype_t tag;
+    uint8_t tag;
     __wasi_prestat_u_t u;
 } __wasi_prestat_t;
 
 _Static_assert(sizeof(__wasi_prestat_t) == 8, "witx calculated size");
 _Static_assert(_Alignof(__wasi_prestat_t) == 4, "witx calculated align");
-_Static_assert(offsetof(__wasi_prestat_t, u) == 4, "witx calculated union offset");
-_Static_assert(sizeof(__wasi_prestat_u_t) == 4, "witx calculated union size");
-_Static_assert(_Alignof(__wasi_prestat_u_t) == 4, "witx calculated union align");
 
 /**
  * @defgroup wasi_snapshot_preview1
@@ -1625,458 +1596,296 @@ _Static_assert(_Alignof(__wasi_prestat_u_t) == 4, "witx calculated union align")
  */
 __wasi_errno_t __wasi_args_get(
     uint8_t * * argv,
-
     uint8_t * argv_buf
-) __attribute__((
-    __import_module__("wasi_snapshot_preview1"),
-    __import_name__("args_get"),
-    __warn_unused_result__
-));
-
+) __attribute__((__warn_unused_result__));
 /**
  * Return command-line argument data sizes.
+ * @return
+ * Returns the number of arguments and the size of the argument string
+ * data, or an error.
  */
 __wasi_errno_t __wasi_args_sizes_get(
-    /**
-     * The number of arguments.
-     */
-    __wasi_size_t *argc,
-    /**
-     * The size of the argument string data.
-     */
-    __wasi_size_t *argv_buf_size
-) __attribute__((
-    __import_module__("wasi_snapshot_preview1"),
-    __import_name__("args_sizes_get"),
-    __warn_unused_result__
-));
-
+    __wasi_size_t *retptr0,
+    __wasi_size_t *retptr1
+) __attribute__((__warn_unused_result__));
 /**
  * Read environment variable data.
  * The sizes of the buffers should match that returned by `environ_sizes_get`.
  */
 __wasi_errno_t __wasi_environ_get(
     uint8_t * * environ,
-
     uint8_t * environ_buf
-) __attribute__((
-    __import_module__("wasi_snapshot_preview1"),
-    __import_name__("environ_get"),
-    __warn_unused_result__
-));
-
+) __attribute__((__warn_unused_result__));
 /**
  * Return environment variable data sizes.
+ * @return
+ * Returns the number of environment variable arguments and the size of the
+ * environment variable data.
  */
 __wasi_errno_t __wasi_environ_sizes_get(
-    /**
-     * The number of environment variable arguments.
-     */
-    __wasi_size_t *environc,
-    /**
-     * The size of the environment variable data.
-     */
-    __wasi_size_t *environ_buf_size
-) __attribute__((
-    __import_module__("wasi_snapshot_preview1"),
-    __import_name__("environ_sizes_get"),
-    __warn_unused_result__
-));
-
+    __wasi_size_t *retptr0,
+    __wasi_size_t *retptr1
+) __attribute__((__warn_unused_result__));
 /**
  * Return the resolution of a clock.
  * Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks,
  * return `errno::inval`.
  * Note: This is similar to `clock_getres` in POSIX.
+ * @return
+ * The resolution of the clock, or an error if one happened.
  */
 __wasi_errno_t __wasi_clock_res_get(
     /**
      * The clock for which to return the resolution.
      */
     __wasi_clockid_t id,
-
-    /**
-     * The resolution of the clock.
-     */
-    __wasi_timestamp_t *resolution
-) __attribute__((
-    __import_module__("wasi_snapshot_preview1"),
-    __import_name__("clock_res_get"),
-    __warn_unused_result__
-));
-
+    __wasi_timestamp_t *retptr0
+) __attribute__((__warn_unused_result__));
 /**
  * Return the time value of a clock.
  * Note: This is similar to `clock_gettime` in POSIX.
+ * @return
+ * The time value of the clock.
  */
 __wasi_errno_t __wasi_clock_time_get(
     /**
      * The clock for which to return the time.
      */
     __wasi_clockid_t id,
-
     /**
      * The maximum lag (exclusive) that the returned time value may have, compared to its actual value.
      */
     __wasi_timestamp_t precision,
-
-    /**
-     * The time value of the clock.
-     */
-    __wasi_timestamp_t *time
-) __attribute__((
-    __import_module__("wasi_snapshot_preview1"),
-    __import_name__("clock_time_get"),
-    __warn_unused_result__
-));
-
+    __wasi_timestamp_t *retptr0
+) __attribute__((__warn_unused_result__));
 /**
  * Provide file advisory information on a file descriptor.
  * Note: This is similar to `posix_fadvise` in POSIX.
  */
 __wasi_errno_t __wasi_fd_advise(
     __wasi_fd_t fd,
-
     /**
      * The offset within the file to which the advisory applies.
      */
     __wasi_filesize_t offset,
-
     /**
      * The length of the region to which the advisory applies.
      */
     __wasi_filesize_t len,
-
     /**
      * The advice.
      */
     __wasi_advice_t advice
-) __attribute__((
-    __import_module__("wasi_snapshot_preview1"),
-    __import_name__("fd_advise"),
-    __warn_unused_result__
-));
-
+) __attribute__((__warn_unused_result__));
 /**
  * Force the allocation of space in a file.
  * Note: This is similar to `posix_fallocate` in POSIX.
  */
 __wasi_errno_t __wasi_fd_allocate(
     __wasi_fd_t fd,
-
     /**
      * The offset at which to start the allocation.
      */
     __wasi_filesize_t offset,
-
     /**
      * The length of the area that is allocated.
      */
     __wasi_filesize_t len
-) __attribute__((
-    __import_module__("wasi_snapshot_preview1"),
-    __import_name__("fd_allocate"),
-    __warn_unused_result__
-));
-
+) __attribute__((__warn_unused_result__));
 /**
  * Close a file descriptor.
  * Note: This is similar to `close` in POSIX.
  */
 __wasi_errno_t __wasi_fd_close(
     __wasi_fd_t fd
-) __attribute__((
-    __import_module__("wasi_snapshot_preview1"),
-    __import_name__("fd_close"),
-    __warn_unused_result__
-));
-
+) __attribute__((__warn_unused_result__));
 /**
  * Synchronize the data of a file to disk.
  * Note: This is similar to `fdatasync` in POSIX.
  */
 __wasi_errno_t __wasi_fd_datasync(
     __wasi_fd_t fd
-) __attribute__((
-    __import_module__("wasi_snapshot_preview1"),
-    __import_name__("fd_datasync"),
-    __warn_unused_result__
-));
-
+) __attribute__((__warn_unused_result__));
 /**
  * Get the attributes of a file descriptor.
  * Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields.
+ * @return
+ * The buffer where the file descriptor's attributes are stored.
  */
 __wasi_errno_t __wasi_fd_fdstat_get(
     __wasi_fd_t fd,
-
-    /**
-     * The buffer where the file descriptor's attributes are stored.
-     */
-    __wasi_fdstat_t *stat
-) __attribute__((
-    __import_module__("wasi_snapshot_preview1"),
-    __import_name__("fd_fdstat_get"),
-    __warn_unused_result__
-));
-
+    __wasi_fdstat_t *retptr0
+) __attribute__((__warn_unused_result__));
 /**
  * Adjust the flags associated with a file descriptor.
  * Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX.
  */
 __wasi_errno_t __wasi_fd_fdstat_set_flags(
     __wasi_fd_t fd,
-
     /**
      * The desired values of the file descriptor flags.
      */
     __wasi_fdflags_t flags
-) __attribute__((
-    __import_module__("wasi_snapshot_preview1"),
-    __import_name__("fd_fdstat_set_flags"),
-    __warn_unused_result__
-));
-
+) __attribute__((__warn_unused_result__));
 /**
  * Adjust the rights associated with a file descriptor.
  * This can only be used to remove rights, and returns `errno::notcapable` if called in a way that would attempt to add rights
  */
 __wasi_errno_t __wasi_fd_fdstat_set_rights(
     __wasi_fd_t fd,
-
     /**
      * The desired rights of the file descriptor.
      */
     __wasi_rights_t fs_rights_base,
-
     __wasi_rights_t fs_rights_inheriting
-) __attribute__((
-    __import_module__("wasi_snapshot_preview1"),
-    __import_name__("fd_fdstat_set_rights"),
-    __warn_unused_result__
-));
-
+) __attribute__((__warn_unused_result__));
 /**
  * Return the attributes of an open file.
+ * @return
+ * The buffer where the file's attributes are stored.
  */
 __wasi_errno_t __wasi_fd_filestat_get(
     __wasi_fd_t fd,
-
-    /**
-     * The buffer where the file's attributes are stored.
-     */
-    __wasi_filestat_t *buf
-) __attribute__((
-    __import_module__("wasi_snapshot_preview1"),
-    __import_name__("fd_filestat_get"),
-    __warn_unused_result__
-));
-
+    __wasi_filestat_t *retptr0
+) __attribute__((__warn_unused_result__));
 /**
  * Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros.
  * Note: This is similar to `ftruncate` in POSIX.
  */
 __wasi_errno_t __wasi_fd_filestat_set_size(
     __wasi_fd_t fd,
-
     /**
      * The desired file size.
      */
     __wasi_filesize_t size
-) __attribute__((
-    __import_module__("wasi_snapshot_preview1"),
-    __import_name__("fd_filestat_set_size"),
-    __warn_unused_result__
-));
-
+) __attribute__((__warn_unused_result__));
 /**
  * Adjust the timestamps of an open file or directory.
  * Note: This is similar to `futimens` in POSIX.
  */
 __wasi_errno_t __wasi_fd_filestat_set_times(
     __wasi_fd_t fd,
-
     /**
      * The desired values of the data access timestamp.
      */
     __wasi_timestamp_t atim,
-
     /**
      * The desired values of the data modification timestamp.
      */
     __wasi_timestamp_t mtim,
-
     /**
      * A bitmask indicating which timestamps to adjust.
      */
     __wasi_fstflags_t fst_flags
-) __attribute__((
-    __import_module__("wasi_snapshot_preview1"),
-    __import_name__("fd_filestat_set_times"),
-    __warn_unused_result__
-));
-
+) __attribute__((__warn_unused_result__));
 /**
  * Read from a file descriptor, without using and updating the file descriptor's offset.
  * Note: This is similar to `preadv` in POSIX.
+ * @return
+ * The number of bytes read.
  */
 __wasi_errno_t __wasi_fd_pread(
     __wasi_fd_t fd,
-
     /**
      * List of scatter/gather vectors in which to store data.
      */
     const __wasi_iovec_t *iovs,
-
     /**
      * The length of the array pointed to by `iovs`.
      */
     size_t iovs_len,
-
     /**
      * The offset within the file at which to read.
      */
     __wasi_filesize_t offset,
-
-    /**
-     * The number of bytes read.
-     */
-    __wasi_size_t *nread
-) __attribute__((
-    __import_module__("wasi_snapshot_preview1"),
-    __import_name__("fd_pread"),
-    __warn_unused_result__
-));
-
+    __wasi_size_t *retptr0
+) __attribute__((__warn_unused_result__));
 /**
  * Return a description of the given preopened file descriptor.
+ * @return
+ * The buffer where the description is stored.
  */
 __wasi_errno_t __wasi_fd_prestat_get(
     __wasi_fd_t fd,
-
-    /**
-     * The buffer where the description is stored.
-     */
-    __wasi_prestat_t *buf
-) __attribute__((
-    __import_module__("wasi_snapshot_preview1"),
-    __import_name__("fd_prestat_get"),
-    __warn_unused_result__
-));
-
+    __wasi_prestat_t *retptr0
+) __attribute__((__warn_unused_result__));
 /**
  * Return a description of the given preopened file descriptor.
  */
 __wasi_errno_t __wasi_fd_prestat_dir_name(
     __wasi_fd_t fd,
-
     /**
      * A buffer into which to write the preopened directory name.
      */
     uint8_t * path,
-
     __wasi_size_t path_len
-) __attribute__((
-    __import_module__("wasi_snapshot_preview1"),
-    __import_name__("fd_prestat_dir_name"),
-    __warn_unused_result__
-));
-
+) __attribute__((__warn_unused_result__));
 /**
  * Write to a file descriptor, without using and updating the file descriptor's offset.
  * Note: This is similar to `pwritev` in POSIX.
+ * @return
+ * The number of bytes written.
  */
 __wasi_errno_t __wasi_fd_pwrite(
     __wasi_fd_t fd,
-
     /**
      * List of scatter/gather vectors from which to retrieve data.
      */
     const __wasi_ciovec_t *iovs,
-
     /**
      * The length of the array pointed to by `iovs`.
      */
     size_t iovs_len,
-
     /**
      * The offset within the file at which to write.
      */
     __wasi_filesize_t offset,
-
-    /**
-     * The number of bytes written.
-     */
-    __wasi_size_t *nwritten
-) __attribute__((
-    __import_module__("wasi_snapshot_preview1"),
-    __import_name__("fd_pwrite"),
-    __warn_unused_result__
-));
-
+    __wasi_size_t *retptr0
+) __attribute__((__warn_unused_result__));
 /**
  * Read from a file descriptor.
  * Note: This is similar to `readv` in POSIX.
+ * @return
+ * The number of bytes read.
  */
 __wasi_errno_t __wasi_fd_read(
     __wasi_fd_t fd,
-
     /**
      * List of scatter/gather vectors to which to store data.
      */
     const __wasi_iovec_t *iovs,
-
     /**
      * The length of the array pointed to by `iovs`.
      */
     size_t iovs_len,
-
-    /**
-     * The number of bytes read.
-     */
-    __wasi_size_t *nread
-) __attribute__((
-    __import_module__("wasi_snapshot_preview1"),
-    __import_name__("fd_read"),
-    __warn_unused_result__
-));
-
+    __wasi_size_t *retptr0
+) __attribute__((__warn_unused_result__));
 /**
  * Read directory entries from a directory.
  * When successful, the contents of the output buffer consist of a sequence of
- * directory entries. Each directory entry consists of a dirent_t object,
- * followed by dirent_t::d_namlen bytes holding the name of the directory
+ * directory entries. Each directory entry consists of a `dirent` object,
+ * followed by `dirent::d_namlen` bytes holding the name of the directory
  * entry.
  * This function fills the output buffer as much as possible, potentially
  * truncating the last directory entry. This allows the caller to grow its
  * read buffer size in case it's too small to fit a single large directory
  * entry, or skip the oversized directory entry.
+ * @return
+ * The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached.
  */
 __wasi_errno_t __wasi_fd_readdir(
     __wasi_fd_t fd,
-
     /**
      * The buffer where directory entries are stored
      */
     uint8_t * buf,
-
     __wasi_size_t buf_len,
-
     /**
      * The location within the directory to start reading
      */
     __wasi_dircookie_t cookie,
-
-    /**
-     * The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached.
-     */
-    __wasi_size_t *bufused
-) __attribute__((
-    __import_module__("wasi_snapshot_preview1"),
-    __import_name__("fd_readdir"),
-    __warn_unused_result__
-));
-
+    __wasi_size_t *retptr0
+) __attribute__((__warn_unused_result__));
 /**
  * Atomically replace a file descriptor by renumbering another file descriptor.
  * Due to the strong focus on thread safety, this environment does not provide
@@ -2089,238 +1898,141 @@ __wasi_errno_t __wasi_fd_readdir(
  */
 __wasi_errno_t __wasi_fd_renumber(
     __wasi_fd_t fd,
-
     /**
      * The file descriptor to overwrite.
      */
     __wasi_fd_t to
-) __attribute__((
-    __import_module__("wasi_snapshot_preview1"),
-    __import_name__("fd_renumber"),
-    __warn_unused_result__
-));
-
+) __attribute__((__warn_unused_result__));
 /**
  * Move the offset of a file descriptor.
  * Note: This is similar to `lseek` in POSIX.
+ * @return
+ * The new offset of the file descriptor, relative to the start of the file.
  */
 __wasi_errno_t __wasi_fd_seek(
     __wasi_fd_t fd,
-
     /**
      * The number of bytes to move.
      */
     __wasi_filedelta_t offset,
-
     /**
      * The base from which the offset is relative.
      */
     __wasi_whence_t whence,
-
-    /**
-     * The new offset of the file descriptor, relative to the start of the file.
-     */
-    __wasi_filesize_t *newoffset
-) __attribute__((
-    __import_module__("wasi_snapshot_preview1"),
-    __import_name__("fd_seek"),
-    __warn_unused_result__
-));
-
+    __wasi_filesize_t *retptr0
+) __attribute__((__warn_unused_result__));
 /**
  * Synchronize the data and metadata of a file to disk.
  * Note: This is similar to `fsync` in POSIX.
  */
 __wasi_errno_t __wasi_fd_sync(
     __wasi_fd_t fd
-) __attribute__((
-    __import_module__("wasi_snapshot_preview1"),
-    __import_name__("fd_sync"),
-    __warn_unused_result__
-));
-
+) __attribute__((__warn_unused_result__));
 /**
  * Return the current offset of a file descriptor.
  * Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX.
+ * @return
+ * The current offset of the file descriptor, relative to the start of the file.
  */
 __wasi_errno_t __wasi_fd_tell(
     __wasi_fd_t fd,
-
-    /**
-     * The current offset of the file descriptor, relative to the start of the file.
-     */
-    __wasi_filesize_t *offset
-) __attribute__((
-    __import_module__("wasi_snapshot_preview1"),
-    __import_name__("fd_tell"),
-    __warn_unused_result__
-));
-
+    __wasi_filesize_t *retptr0
+) __attribute__((__warn_unused_result__));
 /**
  * Write to a file descriptor.
  * Note: This is similar to `writev` in POSIX.
  */
 __wasi_errno_t __wasi_fd_write(
     __wasi_fd_t fd,
-
     /**
      * List of scatter/gather vectors from which to retrieve data.
      */
     const __wasi_ciovec_t *iovs,
-
     /**
      * The length of the array pointed to by `iovs`.
      */
     size_t iovs_len,
-
-    /**
-     * The number of bytes written.
-     */
-    __wasi_size_t *nwritten
-) __attribute__((
-    __import_module__("wasi_snapshot_preview1"),
-    __import_name__("fd_write"),
-    __warn_unused_result__
-));
-
+    __wasi_size_t *retptr0
+) __attribute__((__warn_unused_result__));
 /**
  * Create a directory.
  * Note: This is similar to `mkdirat` in POSIX.
  */
 __wasi_errno_t __wasi_path_create_directory(
     __wasi_fd_t fd,
-
     /**
      * The path at which to create the directory.
      */
-    const char *path,
-
-    /**
-     * The length of the buffer pointed to by `path`.
-     */
-    size_t path_len
-) __attribute__((
-    __import_module__("wasi_snapshot_preview1"),
-    __import_name__("path_create_directory"),
-    __warn_unused_result__
-));
-
+    const char *path
+) __attribute__((__warn_unused_result__));
 /**
  * Return the attributes of a file or directory.
  * Note: This is similar to `stat` in POSIX.
+ * @return
+ * The buffer where the file's attributes are stored.
  */
 __wasi_errno_t __wasi_path_filestat_get(
     __wasi_fd_t fd,
-
     /**
      * Flags determining the method of how the path is resolved.
      */
     __wasi_lookupflags_t flags,
-
     /**
      * The path of the file or directory to inspect.
      */
     const char *path,
-
-    /**
-     * The length of the buffer pointed to by `path`.
-     */
-    size_t path_len,
-
-    /**
-     * The buffer where the file's attributes are stored.
-     */
-    __wasi_filestat_t *buf
-) __attribute__((
-    __import_module__("wasi_snapshot_preview1"),
-    __import_name__("path_filestat_get"),
-    __warn_unused_result__
-));
-
+    __wasi_filestat_t *retptr0
+) __attribute__((__warn_unused_result__));
 /**
  * Adjust the timestamps of a file or directory.
  * Note: This is similar to `utimensat` in POSIX.
  */
 __wasi_errno_t __wasi_path_filestat_set_times(
     __wasi_fd_t fd,
-
     /**
      * Flags determining the method of how the path is resolved.
      */
     __wasi_lookupflags_t flags,
-
     /**
      * The path of the file or directory to operate on.
      */
     const char *path,
-
-    /**
-     * The length of the buffer pointed to by `path`.
-     */
-    size_t path_len,
-
     /**
      * The desired values of the data access timestamp.
      */
     __wasi_timestamp_t atim,
-
     /**
      * The desired values of the data modification timestamp.
      */
     __wasi_timestamp_t mtim,
-
     /**
      * A bitmask indicating which timestamps to adjust.
      */
     __wasi_fstflags_t fst_flags
-) __attribute__((
-    __import_module__("wasi_snapshot_preview1"),
-    __import_name__("path_filestat_set_times"),
-    __warn_unused_result__
-));
-
+) __attribute__((__warn_unused_result__));
 /**
  * Create a hard link.
  * Note: This is similar to `linkat` in POSIX.
  */
 __wasi_errno_t __wasi_path_link(
     __wasi_fd_t old_fd,
-
     /**
      * Flags determining the method of how the path is resolved.
      */
     __wasi_lookupflags_t old_flags,
-
     /**
      * The source path from which to link.
      */
     const char *old_path,
-
-    /**
-     * The length of the buffer pointed to by `old_path`.
-     */
-    size_t old_path_len,
-
     /**
      * The working directory at which the resolution of the new path starts.
      */
     __wasi_fd_t new_fd,
-
     /**
      * The destination path at which to create the hard link.
      */
-    const char *new_path,
-
-    /**
-     * The length of the buffer pointed to by `new_path`.
-     */
-    size_t new_path_len
-) __attribute__((
-    __import_module__("wasi_snapshot_preview1"),
-    __import_name__("path_link"),
-    __warn_unused_result__
-));
-
+    const char *new_path
+) __attribute__((__warn_unused_result__));
 /**
  * Open a file or directory.
  * The returned file descriptor is not guaranteed to be the lowest-numbered
@@ -2329,31 +2041,24 @@ __wasi_errno_t __wasi_path_link(
  * is error-prone in multi-threaded contexts. The returned file descriptor is
  * guaranteed to be less than 2**31.
  * Note: This is similar to `openat` in POSIX.
+ * @return
+ * The file descriptor of the file that has been opened.
  */
 __wasi_errno_t __wasi_path_open(
     __wasi_fd_t fd,
-
     /**
      * Flags determining the method of how the path is resolved.
      */
     __wasi_lookupflags_t dirflags,
-
     /**
      * The relative path of the file or directory to open, relative to the
      * `path_open::fd` directory.
      */
     const char *path,
-
-    /**
-     * The length of the buffer pointed to by `path`.
-     */
-    size_t path_len,
-
     /**
      * The method by which to open the file.
      */
     __wasi_oflags_t oflags,
-
     /**
      * The initial rights of the newly created file descriptor. The
      * implementation is allowed to return a file descriptor with fewer rights
@@ -2364,55 +2069,29 @@ __wasi_errno_t __wasi_path_open(
      * file descriptors derived from it.
      */
     __wasi_rights_t fs_rights_base,
-
-    __wasi_rights_t fs_rights_inherting,
-
+    __wasi_rights_t fs_rights_inheriting,
     __wasi_fdflags_t fdflags,
-
-    /**
-     * The file descriptor of the file that has been opened.
-     */
-    __wasi_fd_t *opened_fd
-) __attribute__((
-    __import_module__("wasi_snapshot_preview1"),
-    __import_name__("path_open"),
-    __warn_unused_result__
-));
-
+    __wasi_fd_t *retptr0
+) __attribute__((__warn_unused_result__));
 /**
  * Read the contents of a symbolic link.
  * Note: This is similar to `readlinkat` in POSIX.
+ * @return
+ * The number of bytes placed in the buffer.
  */
 __wasi_errno_t __wasi_path_readlink(
     __wasi_fd_t fd,
-
     /**
      * The path of the symbolic link from which to read.
      */
     const char *path,
-
-    /**
-     * The length of the buffer pointed to by `path`.
-     */
-    size_t path_len,
-
     /**
      * The buffer to which to write the contents of the symbolic link.
      */
     uint8_t * buf,
-
     __wasi_size_t buf_len,
-
-    /**
-     * The number of bytes placed in the buffer.
-     */
-    __wasi_size_t *bufused
-) __attribute__((
-    __import_module__("wasi_snapshot_preview1"),
-    __import_name__("path_readlink"),
-    __warn_unused_result__
-));
-
+    __wasi_size_t *retptr0
+) __attribute__((__warn_unused_result__));
 /**
  * Remove a directory.
  * Return `errno::notempty` if the directory is not empty.
@@ -2420,59 +2099,30 @@ __wasi_errno_t __wasi_path_readlink(
  */
 __wasi_errno_t __wasi_path_remove_directory(
     __wasi_fd_t fd,
-
     /**
      * The path to a directory to remove.
      */
-    const char *path,
-
-    /**
-     * The length of the buffer pointed to by `path`.
-     */
-    size_t path_len
-) __attribute__((
-    __import_module__("wasi_snapshot_preview1"),
-    __import_name__("path_remove_directory"),
-    __warn_unused_result__
-));
-
+    const char *path
+) __attribute__((__warn_unused_result__));
 /**
  * Rename a file or directory.
  * Note: This is similar to `renameat` in POSIX.
  */
 __wasi_errno_t __wasi_path_rename(
     __wasi_fd_t fd,
-
     /**
      * The source path of the file or directory to rename.
      */
     const char *old_path,
-
-    /**
-     * The length of the buffer pointed to by `old_path`.
-     */
-    size_t old_path_len,
-
     /**
      * The working directory at which the resolution of the new path starts.
      */
     __wasi_fd_t new_fd,
-
     /**
      * The destination path to which to rename the file or directory.
      */
-    const char *new_path,
-
-    /**
-     * The length of the buffer pointed to by `new_path`.
-     */
-    size_t new_path_len
-) __attribute__((
-    __import_module__("wasi_snapshot_preview1"),
-    __import_name__("path_rename"),
-    __warn_unused_result__
-));
-
+    const char *new_path
+) __attribute__((__warn_unused_result__));
 /**
  * Create a symbolic link.
  * Note: This is similar to `symlinkat` in POSIX.
@@ -2482,29 +2132,12 @@ __wasi_errno_t __wasi_path_symlink(
      * The contents of the symbolic link.
      */
     const char *old_path,
-
-    /**
-     * The length of the buffer pointed to by `old_path`.
-     */
-    size_t old_path_len,
-
     __wasi_fd_t fd,
-
     /**
      * The destination path at which to create the symbolic link.
      */
-    const char *new_path,
-
-    /**
-     * The length of the buffer pointed to by `new_path`.
-     */
-    size_t new_path_len
-) __attribute__((
-    __import_module__("wasi_snapshot_preview1"),
-    __import_name__("path_symlink"),
-    __warn_unused_result__
-));
-
+    const char *new_path
+) __attribute__((__warn_unused_result__));
 /**
  * Unlink a file.
  * Return `errno::isdir` if the path refers to a directory.
@@ -2512,51 +2145,31 @@ __wasi_errno_t __wasi_path_symlink(
  */
 __wasi_errno_t __wasi_path_unlink_file(
     __wasi_fd_t fd,
-
     /**
      * The path to a file to unlink.
      */
-    const char *path,
-
-    /**
-     * The length of the buffer pointed to by `path`.
-     */
-    size_t path_len
-) __attribute__((
-    __import_module__("wasi_snapshot_preview1"),
-    __import_name__("path_unlink_file"),
-    __warn_unused_result__
-));
-
+    const char *path
+) __attribute__((__warn_unused_result__));
 /**
  * Concurrently poll for the occurrence of a set of events.
+ * @return
+ * The number of events stored.
  */
 __wasi_errno_t __wasi_poll_oneoff(
     /**
      * The events to which to subscribe.
      */
     const __wasi_subscription_t * in,
-
     /**
      * The events that have occurred.
      */
     __wasi_event_t * out,
-
     /**
      * Both the number of subscriptions and events.
      */
     __wasi_size_t nsubscriptions,
-
-    /**
-     * The number of events stored.
-     */
-    __wasi_size_t *nevents
-) __attribute__((
-    __import_module__("wasi_snapshot_preview1"),
-    __import_name__("poll_oneoff"),
-    __warn_unused_result__
-));
-
+    __wasi_size_t *retptr0
+) __attribute__((__warn_unused_result__));
 /**
  * Terminate the process normally. An exit code of 0 indicates successful
  * termination of the program. The meanings of other values is dependent on
@@ -2567,10 +2180,7 @@ _Noreturn void __wasi_proc_exit(
      * The exit code returned by the process.
      */
     __wasi_exitcode_t rval
-) __attribute__((
-    __import_module__("wasi_snapshot_preview1"),
-    __import_name__("proc_exit")));
-
+);
 /**
  * Send a signal to the process of the calling thread.
  * Note: This is similar to `raise` in POSIX.
@@ -2580,24 +2190,14 @@ __wasi_errno_t __wasi_proc_raise(
      * The signal condition to trigger.
      */
     __wasi_signal_t sig
-) __attribute__((
-    __import_module__("wasi_snapshot_preview1"),
-    __import_name__("proc_raise"),
-    __warn_unused_result__
-));
-
+) __attribute__((__warn_unused_result__));
 /**
  * Temporarily yield execution of the calling thread.
  * Note: This is similar to `sched_yield` in POSIX.
  */
 __wasi_errno_t __wasi_sched_yield(
     void
-) __attribute__((
-    __import_module__("wasi_snapshot_preview1"),
-    __import_name__("sched_yield"),
-    __warn_unused_result__
-));
-
+) __attribute__((__warn_unused_result__));
 /**
  * Write high-quality random data into a buffer.
  * This function blocks when the implementation is unable to immediately
@@ -2611,101 +2211,66 @@ __wasi_errno_t __wasi_random_get(
      * The buffer to fill with random data.
      */
     uint8_t * buf,
-
     __wasi_size_t buf_len
-) __attribute__((
-    __import_module__("wasi_snapshot_preview1"),
-    __import_name__("random_get"),
-    __warn_unused_result__
-));
-
+) __attribute__((__warn_unused_result__));
 /**
  * Receive a message from a socket.
  * Note: This is similar to `recv` in POSIX, though it also supports reading
  * the data into multiple buffers in the manner of `readv`.
+ * @return
+ * Number of bytes stored in ri_data and message flags.
  */
 __wasi_errno_t __wasi_sock_recv(
     __wasi_fd_t fd,
-
     /**
      * List of scatter/gather vectors to which to store data.
      */
     const __wasi_iovec_t *ri_data,
-
     /**
      * The length of the array pointed to by `ri_data`.
      */
     size_t ri_data_len,
-
     /**
      * Message flags.
      */
     __wasi_riflags_t ri_flags,
-
-    /**
-     * Number of bytes stored in ri_data.
-     */
-    __wasi_size_t *ro_datalen,
-    /**
-     * Message flags.
-     */
-    __wasi_roflags_t *ro_flags
-) __attribute__((
-    __import_module__("wasi_snapshot_preview1"),
-    __import_name__("sock_recv"),
-    __warn_unused_result__
-));
-
+    __wasi_size_t *retptr0,
+    __wasi_roflags_t *retptr1
+) __attribute__((__warn_unused_result__));
 /**
  * Send a message on a socket.
  * Note: This is similar to `send` in POSIX, though it also supports writing
  * the data from multiple buffers in the manner of `writev`.
+ * @return
+ * Number of bytes transmitted.
  */
 __wasi_errno_t __wasi_sock_send(
     __wasi_fd_t fd,
-
     /**
      * List of scatter/gather vectors to which to retrieve data
      */
     const __wasi_ciovec_t *si_data,
-
     /**
      * The length of the array pointed to by `si_data`.
      */
     size_t si_data_len,
-
     /**
      * Message flags.
      */
     __wasi_siflags_t si_flags,
-
-    /**
-     * Number of bytes transmitted.
-     */
-    __wasi_size_t *so_datalen
-) __attribute__((
-    __import_module__("wasi_snapshot_preview1"),
-    __import_name__("sock_send"),
-    __warn_unused_result__
-));
-
+    __wasi_size_t *retptr0
+) __attribute__((__warn_unused_result__));
 /**
  * Shut down socket send and receive channels.
  * Note: This is similar to `shutdown` in POSIX.
  */
 __wasi_errno_t __wasi_sock_shutdown(
     __wasi_fd_t fd,
-
     /**
      * Which channels on the socket to shut down.
      */
     __wasi_sdflags_t how
-) __attribute__((
-    __import_module__("wasi_snapshot_preview1"),
-    __import_name__("sock_shutdown"),
-    __warn_unused_result__
-));
-
+) __attribute__((__warn_unused_result__));
 /** @} */
 
 #ifdef __cplusplus
diff --git a/libc-bottom-half/sources/__wasilibc_real.c b/libc-bottom-half/sources/__wasilibc_real.c
new file mode 100644 (file)
index 0000000..e6481f7
--- /dev/null
@@ -0,0 +1,659 @@
+/**
+ * THIS FILE IS AUTO-GENERATED from the following files:
+ *   wasi_snapshot_preview1.witx
+ *
+ * To regenerate this file execute:
+ *
+ *     cargo run --manifest-path tools/wasi-headers/Cargo.toml generate-libc
+ *
+ * Modifications to this file will cause CI to fail, the code generator tool
+ * must be modified to change this file.
+ */
+
+#include <wasi/api.h>
+#include <string.h>
+
+int32_t __imported_wasi_snapshot_preview1_args_get(int32_t arg0, int32_t arg1) __attribute__((
+    __import_module__("wasi_snapshot_preview1"),
+    __import_name__("args_get")
+));
+
+__wasi_errno_t __wasi_args_get(
+    uint8_t * * argv,
+    uint8_t * argv_buf
+){
+    int32_t ret = __imported_wasi_snapshot_preview1_args_get((int32_t) argv, (int32_t) argv_buf);
+    return (uint16_t) ret;
+}
+
+int32_t __imported_wasi_snapshot_preview1_args_sizes_get(int32_t arg0, int32_t arg1) __attribute__((
+    __import_module__("wasi_snapshot_preview1"),
+    __import_name__("args_sizes_get")
+));
+
+__wasi_errno_t __wasi_args_sizes_get(
+    __wasi_size_t *retptr0,
+    __wasi_size_t *retptr1
+){
+    int32_t ret = __imported_wasi_snapshot_preview1_args_sizes_get((int32_t) retptr0, (int32_t) retptr1);
+    return (uint16_t) ret;
+}
+
+int32_t __imported_wasi_snapshot_preview1_environ_get(int32_t arg0, int32_t arg1) __attribute__((
+    __import_module__("wasi_snapshot_preview1"),
+    __import_name__("environ_get")
+));
+
+__wasi_errno_t __wasi_environ_get(
+    uint8_t * * environ,
+    uint8_t * environ_buf
+){
+    int32_t ret = __imported_wasi_snapshot_preview1_environ_get((int32_t) environ, (int32_t) environ_buf);
+    return (uint16_t) ret;
+}
+
+int32_t __imported_wasi_snapshot_preview1_environ_sizes_get(int32_t arg0, int32_t arg1) __attribute__((
+    __import_module__("wasi_snapshot_preview1"),
+    __import_name__("environ_sizes_get")
+));
+
+__wasi_errno_t __wasi_environ_sizes_get(
+    __wasi_size_t *retptr0,
+    __wasi_size_t *retptr1
+){
+    int32_t ret = __imported_wasi_snapshot_preview1_environ_sizes_get((int32_t) retptr0, (int32_t) retptr1);
+    return (uint16_t) ret;
+}
+
+int32_t __imported_wasi_snapshot_preview1_clock_res_get(int32_t arg0, int32_t arg1) __attribute__((
+    __import_module__("wasi_snapshot_preview1"),
+    __import_name__("clock_res_get")
+));
+
+__wasi_errno_t __wasi_clock_res_get(
+    __wasi_clockid_t id,
+    __wasi_timestamp_t *retptr0
+){
+    int32_t ret = __imported_wasi_snapshot_preview1_clock_res_get((int32_t) id, (int32_t) retptr0);
+    return (uint16_t) ret;
+}
+
+int32_t __imported_wasi_snapshot_preview1_clock_time_get(int32_t arg0, int64_t arg1, int32_t arg2) __attribute__((
+    __import_module__("wasi_snapshot_preview1"),
+    __import_name__("clock_time_get")
+));
+
+__wasi_errno_t __wasi_clock_time_get(
+    __wasi_clockid_t id,
+    __wasi_timestamp_t precision,
+    __wasi_timestamp_t *retptr0
+){
+    int32_t ret = __imported_wasi_snapshot_preview1_clock_time_get((int32_t) id, (int64_t) precision, (int32_t) retptr0);
+    return (uint16_t) ret;
+}
+
+int32_t __imported_wasi_snapshot_preview1_fd_advise(int32_t arg0, int64_t arg1, int64_t arg2, int32_t arg3) __attribute__((
+    __import_module__("wasi_snapshot_preview1"),
+    __import_name__("fd_advise")
+));
+
+__wasi_errno_t __wasi_fd_advise(
+    __wasi_fd_t fd,
+    __wasi_filesize_t offset,
+    __wasi_filesize_t len,
+    __wasi_advice_t advice
+){
+    int32_t ret = __imported_wasi_snapshot_preview1_fd_advise((int32_t) fd, (int64_t) offset, (int64_t) len, (int32_t) advice);
+    return (uint16_t) ret;
+}
+
+int32_t __imported_wasi_snapshot_preview1_fd_allocate(int32_t arg0, int64_t arg1, int64_t arg2) __attribute__((
+    __import_module__("wasi_snapshot_preview1"),
+    __import_name__("fd_allocate")
+));
+
+__wasi_errno_t __wasi_fd_allocate(
+    __wasi_fd_t fd,
+    __wasi_filesize_t offset,
+    __wasi_filesize_t len
+){
+    int32_t ret = __imported_wasi_snapshot_preview1_fd_allocate((int32_t) fd, (int64_t) offset, (int64_t) len);
+    return (uint16_t) ret;
+}
+
+int32_t __imported_wasi_snapshot_preview1_fd_close(int32_t arg0) __attribute__((
+    __import_module__("wasi_snapshot_preview1"),
+    __import_name__("fd_close")
+));
+
+__wasi_errno_t __wasi_fd_close(
+    __wasi_fd_t fd
+){
+    int32_t ret = __imported_wasi_snapshot_preview1_fd_close((int32_t) fd);
+    return (uint16_t) ret;
+}
+
+int32_t __imported_wasi_snapshot_preview1_fd_datasync(int32_t arg0) __attribute__((
+    __import_module__("wasi_snapshot_preview1"),
+    __import_name__("fd_datasync")
+));
+
+__wasi_errno_t __wasi_fd_datasync(
+    __wasi_fd_t fd
+){
+    int32_t ret = __imported_wasi_snapshot_preview1_fd_datasync((int32_t) fd);
+    return (uint16_t) ret;
+}
+
+int32_t __imported_wasi_snapshot_preview1_fd_fdstat_get(int32_t arg0, int32_t arg1) __attribute__((
+    __import_module__("wasi_snapshot_preview1"),
+    __import_name__("fd_fdstat_get")
+));
+
+__wasi_errno_t __wasi_fd_fdstat_get(
+    __wasi_fd_t fd,
+    __wasi_fdstat_t *retptr0
+){
+    int32_t ret = __imported_wasi_snapshot_preview1_fd_fdstat_get((int32_t) fd, (int32_t) retptr0);
+    return (uint16_t) ret;
+}
+
+int32_t __imported_wasi_snapshot_preview1_fd_fdstat_set_flags(int32_t arg0, int32_t arg1) __attribute__((
+    __import_module__("wasi_snapshot_preview1"),
+    __import_name__("fd_fdstat_set_flags")
+));
+
+__wasi_errno_t __wasi_fd_fdstat_set_flags(
+    __wasi_fd_t fd,
+    __wasi_fdflags_t flags
+){
+    int32_t ret = __imported_wasi_snapshot_preview1_fd_fdstat_set_flags((int32_t) fd, flags);
+    return (uint16_t) ret;
+}
+
+int32_t __imported_wasi_snapshot_preview1_fd_fdstat_set_rights(int32_t arg0, int64_t arg1, int64_t arg2) __attribute__((
+    __import_module__("wasi_snapshot_preview1"),
+    __import_name__("fd_fdstat_set_rights")
+));
+
+__wasi_errno_t __wasi_fd_fdstat_set_rights(
+    __wasi_fd_t fd,
+    __wasi_rights_t fs_rights_base,
+    __wasi_rights_t fs_rights_inheriting
+){
+    int32_t ret = __imported_wasi_snapshot_preview1_fd_fdstat_set_rights((int32_t) fd, fs_rights_base, fs_rights_inheriting);
+    return (uint16_t) ret;
+}
+
+int32_t __imported_wasi_snapshot_preview1_fd_filestat_get(int32_t arg0, int32_t arg1) __attribute__((
+    __import_module__("wasi_snapshot_preview1"),
+    __import_name__("fd_filestat_get")
+));
+
+__wasi_errno_t __wasi_fd_filestat_get(
+    __wasi_fd_t fd,
+    __wasi_filestat_t *retptr0
+){
+    int32_t ret = __imported_wasi_snapshot_preview1_fd_filestat_get((int32_t) fd, (int32_t) retptr0);
+    return (uint16_t) ret;
+}
+
+int32_t __imported_wasi_snapshot_preview1_fd_filestat_set_size(int32_t arg0, int64_t arg1) __attribute__((
+    __import_module__("wasi_snapshot_preview1"),
+    __import_name__("fd_filestat_set_size")
+));
+
+__wasi_errno_t __wasi_fd_filestat_set_size(
+    __wasi_fd_t fd,
+    __wasi_filesize_t size
+){
+    int32_t ret = __imported_wasi_snapshot_preview1_fd_filestat_set_size((int32_t) fd, (int64_t) size);
+    return (uint16_t) ret;
+}
+
+int32_t __imported_wasi_snapshot_preview1_fd_filestat_set_times(int32_t arg0, int64_t arg1, int64_t arg2, int32_t arg3) __attribute__((
+    __import_module__("wasi_snapshot_preview1"),
+    __import_name__("fd_filestat_set_times")
+));
+
+__wasi_errno_t __wasi_fd_filestat_set_times(
+    __wasi_fd_t fd,
+    __wasi_timestamp_t atim,
+    __wasi_timestamp_t mtim,
+    __wasi_fstflags_t fst_flags
+){
+    int32_t ret = __imported_wasi_snapshot_preview1_fd_filestat_set_times((int32_t) fd, (int64_t) atim, (int64_t) mtim, fst_flags);
+    return (uint16_t) ret;
+}
+
+int32_t __imported_wasi_snapshot_preview1_fd_pread(int32_t arg0, int32_t arg1, int32_t arg2, int64_t arg3, int32_t arg4) __attribute__((
+    __import_module__("wasi_snapshot_preview1"),
+    __import_name__("fd_pread")
+));
+
+__wasi_errno_t __wasi_fd_pread(
+    __wasi_fd_t fd,
+    const __wasi_iovec_t *iovs,
+    size_t iovs_len,
+    __wasi_filesize_t offset,
+    __wasi_size_t *retptr0
+){
+    int32_t ret = __imported_wasi_snapshot_preview1_fd_pread((int32_t) fd, (int32_t) iovs, (int32_t) iovs_len, (int64_t) offset, (int32_t) retptr0);
+    return (uint16_t) ret;
+}
+
+int32_t __imported_wasi_snapshot_preview1_fd_prestat_get(int32_t arg0, int32_t arg1) __attribute__((
+    __import_module__("wasi_snapshot_preview1"),
+    __import_name__("fd_prestat_get")
+));
+
+__wasi_errno_t __wasi_fd_prestat_get(
+    __wasi_fd_t fd,
+    __wasi_prestat_t *retptr0
+){
+    int32_t ret = __imported_wasi_snapshot_preview1_fd_prestat_get((int32_t) fd, (int32_t) retptr0);
+    return (uint16_t) ret;
+}
+
+int32_t __imported_wasi_snapshot_preview1_fd_prestat_dir_name(int32_t arg0, int32_t arg1, int32_t arg2) __attribute__((
+    __import_module__("wasi_snapshot_preview1"),
+    __import_name__("fd_prestat_dir_name")
+));
+
+__wasi_errno_t __wasi_fd_prestat_dir_name(
+    __wasi_fd_t fd,
+    uint8_t * path,
+    __wasi_size_t path_len
+){
+    int32_t ret = __imported_wasi_snapshot_preview1_fd_prestat_dir_name((int32_t) fd, (int32_t) path, (int32_t) path_len);
+    return (uint16_t) ret;
+}
+
+int32_t __imported_wasi_snapshot_preview1_fd_pwrite(int32_t arg0, int32_t arg1, int32_t arg2, int64_t arg3, int32_t arg4) __attribute__((
+    __import_module__("wasi_snapshot_preview1"),
+    __import_name__("fd_pwrite")
+));
+
+__wasi_errno_t __wasi_fd_pwrite(
+    __wasi_fd_t fd,
+    const __wasi_ciovec_t *iovs,
+    size_t iovs_len,
+    __wasi_filesize_t offset,
+    __wasi_size_t *retptr0
+){
+    int32_t ret = __imported_wasi_snapshot_preview1_fd_pwrite((int32_t) fd, (int32_t) iovs, (int32_t) iovs_len, (int64_t) offset, (int32_t) retptr0);
+    return (uint16_t) ret;
+}
+
+int32_t __imported_wasi_snapshot_preview1_fd_read(int32_t arg0, int32_t arg1, int32_t arg2, int32_t arg3) __attribute__((
+    __import_module__("wasi_snapshot_preview1"),
+    __import_name__("fd_read")
+));
+
+__wasi_errno_t __wasi_fd_read(
+    __wasi_fd_t fd,
+    const __wasi_iovec_t *iovs,
+    size_t iovs_len,
+    __wasi_size_t *retptr0
+){
+    int32_t ret = __imported_wasi_snapshot_preview1_fd_read((int32_t) fd, (int32_t) iovs, (int32_t) iovs_len, (int32_t) retptr0);
+    return (uint16_t) ret;
+}
+
+int32_t __imported_wasi_snapshot_preview1_fd_readdir(int32_t arg0, int32_t arg1, int32_t arg2, int64_t arg3, int32_t arg4) __attribute__((
+    __import_module__("wasi_snapshot_preview1"),
+    __import_name__("fd_readdir")
+));
+
+__wasi_errno_t __wasi_fd_readdir(
+    __wasi_fd_t fd,
+    uint8_t * buf,
+    __wasi_size_t buf_len,
+    __wasi_dircookie_t cookie,
+    __wasi_size_t *retptr0
+){
+    int32_t ret = __imported_wasi_snapshot_preview1_fd_readdir((int32_t) fd, (int32_t) buf, (int32_t) buf_len, (int64_t) cookie, (int32_t) retptr0);
+    return (uint16_t) ret;
+}
+
+int32_t __imported_wasi_snapshot_preview1_fd_renumber(int32_t arg0, int32_t arg1) __attribute__((
+    __import_module__("wasi_snapshot_preview1"),
+    __import_name__("fd_renumber")
+));
+
+__wasi_errno_t __wasi_fd_renumber(
+    __wasi_fd_t fd,
+    __wasi_fd_t to
+){
+    int32_t ret = __imported_wasi_snapshot_preview1_fd_renumber((int32_t) fd, (int32_t) to);
+    return (uint16_t) ret;
+}
+
+int32_t __imported_wasi_snapshot_preview1_fd_seek(int32_t arg0, int64_t arg1, int32_t arg2, int32_t arg3) __attribute__((
+    __import_module__("wasi_snapshot_preview1"),
+    __import_name__("fd_seek")
+));
+
+__wasi_errno_t __wasi_fd_seek(
+    __wasi_fd_t fd,
+    __wasi_filedelta_t offset,
+    __wasi_whence_t whence,
+    __wasi_filesize_t *retptr0
+){
+    int32_t ret = __imported_wasi_snapshot_preview1_fd_seek((int32_t) fd, offset, (int32_t) whence, (int32_t) retptr0);
+    return (uint16_t) ret;
+}
+
+int32_t __imported_wasi_snapshot_preview1_fd_sync(int32_t arg0) __attribute__((
+    __import_module__("wasi_snapshot_preview1"),
+    __import_name__("fd_sync")
+));
+
+__wasi_errno_t __wasi_fd_sync(
+    __wasi_fd_t fd
+){
+    int32_t ret = __imported_wasi_snapshot_preview1_fd_sync((int32_t) fd);
+    return (uint16_t) ret;
+}
+
+int32_t __imported_wasi_snapshot_preview1_fd_tell(int32_t arg0, int32_t arg1) __attribute__((
+    __import_module__("wasi_snapshot_preview1"),
+    __import_name__("fd_tell")
+));
+
+__wasi_errno_t __wasi_fd_tell(
+    __wasi_fd_t fd,
+    __wasi_filesize_t *retptr0
+){
+    int32_t ret = __imported_wasi_snapshot_preview1_fd_tell((int32_t) fd, (int32_t) retptr0);
+    return (uint16_t) ret;
+}
+
+int32_t __imported_wasi_snapshot_preview1_fd_write(int32_t arg0, int32_t arg1, int32_t arg2, int32_t arg3) __attribute__((
+    __import_module__("wasi_snapshot_preview1"),
+    __import_name__("fd_write")
+));
+
+__wasi_errno_t __wasi_fd_write(
+    __wasi_fd_t fd,
+    const __wasi_ciovec_t *iovs,
+    size_t iovs_len,
+    __wasi_size_t *retptr0
+){
+    int32_t ret = __imported_wasi_snapshot_preview1_fd_write((int32_t) fd, (int32_t) iovs, (int32_t) iovs_len, (int32_t) retptr0);
+    return (uint16_t) ret;
+}
+
+int32_t __imported_wasi_snapshot_preview1_path_create_directory(int32_t arg0, int32_t arg1, int32_t arg2) __attribute__((
+    __import_module__("wasi_snapshot_preview1"),
+    __import_name__("path_create_directory")
+));
+
+__wasi_errno_t __wasi_path_create_directory(
+    __wasi_fd_t fd,
+    const char *path
+){
+    size_t path_len = strlen(path);
+    int32_t ret = __imported_wasi_snapshot_preview1_path_create_directory((int32_t) fd, (int32_t) path, (int32_t) path_len);
+    return (uint16_t) ret;
+}
+
+int32_t __imported_wasi_snapshot_preview1_path_filestat_get(int32_t arg0, int32_t arg1, int32_t arg2, int32_t arg3, int32_t arg4) __attribute__((
+    __import_module__("wasi_snapshot_preview1"),
+    __import_name__("path_filestat_get")
+));
+
+__wasi_errno_t __wasi_path_filestat_get(
+    __wasi_fd_t fd,
+    __wasi_lookupflags_t flags,
+    const char *path,
+    __wasi_filestat_t *retptr0
+){
+    size_t path_len = strlen(path);
+    int32_t ret = __imported_wasi_snapshot_preview1_path_filestat_get((int32_t) fd, flags, (int32_t) path, (int32_t) path_len, (int32_t) retptr0);
+    return (uint16_t) ret;
+}
+
+int32_t __imported_wasi_snapshot_preview1_path_filestat_set_times(int32_t arg0, int32_t arg1, int32_t arg2, int32_t arg3, int64_t arg4, int64_t arg5, int32_t arg6) __attribute__((
+    __import_module__("wasi_snapshot_preview1"),
+    __import_name__("path_filestat_set_times")
+));
+
+__wasi_errno_t __wasi_path_filestat_set_times(
+    __wasi_fd_t fd,
+    __wasi_lookupflags_t flags,
+    const char *path,
+    __wasi_timestamp_t atim,
+    __wasi_timestamp_t mtim,
+    __wasi_fstflags_t fst_flags
+){
+    size_t path_len = strlen(path);
+    int32_t ret = __imported_wasi_snapshot_preview1_path_filestat_set_times((int32_t) fd, flags, (int32_t) path, (int32_t) path_len, (int64_t) atim, (int64_t) mtim, fst_flags);
+    return (uint16_t) ret;
+}
+
+int32_t __imported_wasi_snapshot_preview1_path_link(int32_t arg0, int32_t arg1, int32_t arg2, int32_t arg3, int32_t arg4, int32_t arg5, int32_t arg6) __attribute__((
+    __import_module__("wasi_snapshot_preview1"),
+    __import_name__("path_link")
+));
+
+__wasi_errno_t __wasi_path_link(
+    __wasi_fd_t old_fd,
+    __wasi_lookupflags_t old_flags,
+    const char *old_path,
+    __wasi_fd_t new_fd,
+    const char *new_path
+){
+    size_t old_path_len = strlen(old_path);
+    size_t new_path_len = strlen(new_path);
+    int32_t ret = __imported_wasi_snapshot_preview1_path_link((int32_t) old_fd, old_flags, (int32_t) old_path, (int32_t) old_path_len, (int32_t) new_fd, (int32_t) new_path, (int32_t) new_path_len);
+    return (uint16_t) ret;
+}
+
+int32_t __imported_wasi_snapshot_preview1_path_open(int32_t arg0, int32_t arg1, int32_t arg2, int32_t arg3, int32_t arg4, int64_t arg5, int64_t arg6, int32_t arg7, int32_t arg8) __attribute__((
+    __import_module__("wasi_snapshot_preview1"),
+    __import_name__("path_open")
+));
+
+__wasi_errno_t __wasi_path_open(
+    __wasi_fd_t fd,
+    __wasi_lookupflags_t dirflags,
+    const char *path,
+    __wasi_oflags_t oflags,
+    __wasi_rights_t fs_rights_base,
+    __wasi_rights_t fs_rights_inheriting,
+    __wasi_fdflags_t fdflags,
+    __wasi_fd_t *retptr0
+){
+    size_t path_len = strlen(path);
+    int32_t ret = __imported_wasi_snapshot_preview1_path_open((int32_t) fd, dirflags, (int32_t) path, (int32_t) path_len, oflags, fs_rights_base, fs_rights_inheriting, fdflags, (int32_t) retptr0);
+    return (uint16_t) ret;
+}
+
+int32_t __imported_wasi_snapshot_preview1_path_readlink(int32_t arg0, int32_t arg1, int32_t arg2, int32_t arg3, int32_t arg4, int32_t arg5) __attribute__((
+    __import_module__("wasi_snapshot_preview1"),
+    __import_name__("path_readlink")
+));
+
+__wasi_errno_t __wasi_path_readlink(
+    __wasi_fd_t fd,
+    const char *path,
+    uint8_t * buf,
+    __wasi_size_t buf_len,
+    __wasi_size_t *retptr0
+){
+    size_t path_len = strlen(path);
+    int32_t ret = __imported_wasi_snapshot_preview1_path_readlink((int32_t) fd, (int32_t) path, (int32_t) path_len, (int32_t) buf, (int32_t) buf_len, (int32_t) retptr0);
+    return (uint16_t) ret;
+}
+
+int32_t __imported_wasi_snapshot_preview1_path_remove_directory(int32_t arg0, int32_t arg1, int32_t arg2) __attribute__((
+    __import_module__("wasi_snapshot_preview1"),
+    __import_name__("path_remove_directory")
+));
+
+__wasi_errno_t __wasi_path_remove_directory(
+    __wasi_fd_t fd,
+    const char *path
+){
+    size_t path_len = strlen(path);
+    int32_t ret = __imported_wasi_snapshot_preview1_path_remove_directory((int32_t) fd, (int32_t) path, (int32_t) path_len);
+    return (uint16_t) ret;
+}
+
+int32_t __imported_wasi_snapshot_preview1_path_rename(int32_t arg0, int32_t arg1, int32_t arg2, int32_t arg3, int32_t arg4, int32_t arg5) __attribute__((
+    __import_module__("wasi_snapshot_preview1"),
+    __import_name__("path_rename")
+));
+
+__wasi_errno_t __wasi_path_rename(
+    __wasi_fd_t fd,
+    const char *old_path,
+    __wasi_fd_t new_fd,
+    const char *new_path
+){
+    size_t old_path_len = strlen(old_path);
+    size_t new_path_len = strlen(new_path);
+    int32_t ret = __imported_wasi_snapshot_preview1_path_rename((int32_t) fd, (int32_t) old_path, (int32_t) old_path_len, (int32_t) new_fd, (int32_t) new_path, (int32_t) new_path_len);
+    return (uint16_t) ret;
+}
+
+int32_t __imported_wasi_snapshot_preview1_path_symlink(int32_t arg0, int32_t arg1, int32_t arg2, int32_t arg3, int32_t arg4) __attribute__((
+    __import_module__("wasi_snapshot_preview1"),
+    __import_name__("path_symlink")
+));
+
+__wasi_errno_t __wasi_path_symlink(
+    const char *old_path,
+    __wasi_fd_t fd,
+    const char *new_path
+){
+    size_t old_path_len = strlen(old_path);
+    size_t new_path_len = strlen(new_path);
+    int32_t ret = __imported_wasi_snapshot_preview1_path_symlink((int32_t) old_path, (int32_t) old_path_len, (int32_t) fd, (int32_t) new_path, (int32_t) new_path_len);
+    return (uint16_t) ret;
+}
+
+int32_t __imported_wasi_snapshot_preview1_path_unlink_file(int32_t arg0, int32_t arg1, int32_t arg2) __attribute__((
+    __import_module__("wasi_snapshot_preview1"),
+    __import_name__("path_unlink_file")
+));
+
+__wasi_errno_t __wasi_path_unlink_file(
+    __wasi_fd_t fd,
+    const char *path
+){
+    size_t path_len = strlen(path);
+    int32_t ret = __imported_wasi_snapshot_preview1_path_unlink_file((int32_t) fd, (int32_t) path, (int32_t) path_len);
+    return (uint16_t) ret;
+}
+
+int32_t __imported_wasi_snapshot_preview1_poll_oneoff(int32_t arg0, int32_t arg1, int32_t arg2, int32_t arg3) __attribute__((
+    __import_module__("wasi_snapshot_preview1"),
+    __import_name__("poll_oneoff")
+));
+
+__wasi_errno_t __wasi_poll_oneoff(
+    const __wasi_subscription_t * in,
+    __wasi_event_t * out,
+    __wasi_size_t nsubscriptions,
+    __wasi_size_t *retptr0
+){
+    int32_t ret = __imported_wasi_snapshot_preview1_poll_oneoff((int32_t) in, (int32_t) out, (int32_t) nsubscriptions, (int32_t) retptr0);
+    return (uint16_t) ret;
+}
+
+_Noreturn void __imported_wasi_snapshot_preview1_proc_exit(int32_t arg0) __attribute__((
+    __import_module__("wasi_snapshot_preview1"),
+    __import_name__("proc_exit")
+));
+
+_Noreturn void __wasi_proc_exit(
+    __wasi_exitcode_t rval
+){
+    __imported_wasi_snapshot_preview1_proc_exit((int32_t) rval);
+}
+
+int32_t __imported_wasi_snapshot_preview1_proc_raise(int32_t arg0) __attribute__((
+    __import_module__("wasi_snapshot_preview1"),
+    __import_name__("proc_raise")
+));
+
+__wasi_errno_t __wasi_proc_raise(
+    __wasi_signal_t sig
+){
+    int32_t ret = __imported_wasi_snapshot_preview1_proc_raise((int32_t) sig);
+    return (uint16_t) ret;
+}
+
+int32_t __imported_wasi_snapshot_preview1_sched_yield() __attribute__((
+    __import_module__("wasi_snapshot_preview1"),
+    __import_name__("sched_yield")
+));
+
+__wasi_errno_t __wasi_sched_yield(
+    void
+){
+    int32_t ret = __imported_wasi_snapshot_preview1_sched_yield();
+    return (uint16_t) ret;
+}
+
+int32_t __imported_wasi_snapshot_preview1_random_get(int32_t arg0, int32_t arg1) __attribute__((
+    __import_module__("wasi_snapshot_preview1"),
+    __import_name__("random_get")
+));
+
+__wasi_errno_t __wasi_random_get(
+    uint8_t * buf,
+    __wasi_size_t buf_len
+){
+    int32_t ret = __imported_wasi_snapshot_preview1_random_get((int32_t) buf, (int32_t) buf_len);
+    return (uint16_t) ret;
+}
+
+int32_t __imported_wasi_snapshot_preview1_sock_recv(int32_t arg0, int32_t arg1, int32_t arg2, int32_t arg3, int32_t arg4, int32_t arg5) __attribute__((
+    __import_module__("wasi_snapshot_preview1"),
+    __import_name__("sock_recv")
+));
+
+__wasi_errno_t __wasi_sock_recv(
+    __wasi_fd_t fd,
+    const __wasi_iovec_t *ri_data,
+    size_t ri_data_len,
+    __wasi_riflags_t ri_flags,
+    __wasi_size_t *retptr0,
+    __wasi_roflags_t *retptr1
+){
+    int32_t ret = __imported_wasi_snapshot_preview1_sock_recv((int32_t) fd, (int32_t) ri_data, (int32_t) ri_data_len, ri_flags, (int32_t) retptr0, (int32_t) retptr1);
+    return (uint16_t) ret;
+}
+
+int32_t __imported_wasi_snapshot_preview1_sock_send(int32_t arg0, int32_t arg1, int32_t arg2, int32_t arg3, int32_t arg4) __attribute__((
+    __import_module__("wasi_snapshot_preview1"),
+    __import_name__("sock_send")
+));
+
+__wasi_errno_t __wasi_sock_send(
+    __wasi_fd_t fd,
+    const __wasi_ciovec_t *si_data,
+    size_t si_data_len,
+    __wasi_siflags_t si_flags,
+    __wasi_size_t *retptr0
+){
+    int32_t ret = __imported_wasi_snapshot_preview1_sock_send((int32_t) fd, (int32_t) si_data, (int32_t) si_data_len, (int32_t) si_flags, (int32_t) retptr0);
+    return (uint16_t) ret;
+}
+
+int32_t __imported_wasi_snapshot_preview1_sock_shutdown(int32_t arg0, int32_t arg1) __attribute__((
+    __import_module__("wasi_snapshot_preview1"),
+    __import_name__("sock_shutdown")
+));
+
+__wasi_errno_t __wasi_sock_shutdown(
+    __wasi_fd_t fd,
+    __wasi_sdflags_t how
+){
+    int32_t ret = __imported_wasi_snapshot_preview1_sock_shutdown((int32_t) fd, how);
+    return (uint16_t) ret;
+}
+
index 3ba3663fc500f3e989d0aca3f332e6fbd1b535d0..2730c23c52cbfc3110b92c3d45c9277a88ef9819 100644 (file)
@@ -2,11 +2,9 @@
 #include <wasi/api.h>
 #include <wasi/libc.h>
 #include <errno.h>
-#include <string.h>
 
 int __wasilibc_nocwd___wasilibc_rmdirat(int fd, const char *path) {
-    size_t path_len = strlen(path);
-    __wasi_errno_t error = __wasi_path_remove_directory(fd, path, path_len);
+    __wasi_errno_t error = __wasi_path_remove_directory(fd, path);
     if (error != 0) {
         errno = errno_fixup_directory(fd, error);
         return -1;
index a29ce2ce8b9e3fd1a5552b0879ab15180a775188..21ae69a52bee91c6eb35d3837d50e96698ddfcc1 100644 (file)
@@ -2,11 +2,9 @@
 #include <wasi/api.h>
 #include <wasi/libc.h>
 #include <errno.h>
-#include <string.h>
 
 int __wasilibc_nocwd___wasilibc_unlinkat(int fd, const char *path) {
-    size_t path_len = strlen(path);
-    __wasi_errno_t error = __wasi_path_unlink_file(fd, path, path_len);
+    __wasi_errno_t error = __wasi_path_unlink_file(fd, path);
     if (error != 0) {
         errno = error;
         return -1;
index 54a8be966698d9499d81f0b3efa08878801f1858..ef8c1a53feb2dfb763d4ea5c7d9e0a0126b45579 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 54a8be966698d9499d81f0b3efa08878801f1858
+Subproject commit ef8c1a53feb2dfb763d4ea5c7d9e0a0126b45579
index 4035f191ee24e92ee2175e78e3eaa7315ca71def..15b64ee6ef2256d7da9f85df1c40f35c81513f49 100644 (file)
@@ -1,14 +1,28 @@
 use heck::ShoutySnakeCase;
+use std::collections::HashMap;
+use std::mem;
 use witx::*;
 
-pub fn to_c_header(doc: &Document, inputs_str: &str) -> String {
-    let mut ret = String::new();
+pub struct Generated {
+    pub header: String,
+    pub source: String,
+}
 
-    ret.push_str(&format!(
+pub fn to_c(doc: &Document, inputs_str: &str) -> Generated {
+    let mut header = String::new();
+
+    header.push_str(&format!(
         r#"/**
  * THIS FILE IS AUTO-GENERATED from the following files:
  *   {}
  *
+ * To regenerate this file execute:
+ *
+ *     cargo run --manifest-path tools/wasi-headers/Cargo.toml generate-libc
+ *
+ * Modifications to this file will cause CI to fail, the code generator tool
+ * must be modified to change this file.
+ *
  * @file
  * This file describes the [WASI] interface, consisting of functions, types,
  * and defined values (macros).
@@ -54,15 +68,47 @@ extern "C" {{
         inputs_str,
     ));
 
+    let mut source = String::new();
+    source.push_str(&format!(
+        r#"/**
+ * THIS FILE IS AUTO-GENERATED from the following files:
+ *   {}
+ *
+ * To regenerate this file execute:
+ *
+ *     cargo run --manifest-path tools/wasi-headers/Cargo.toml generate-libc
+ *
+ * Modifications to this file will cause CI to fail, the code generator tool
+ * must be modified to change this file.
+ */
+
+#include <wasi/api.h>
+#include <string.h>
+
+"#,
+        inputs_str,
+    ));
+
+    let mut type_constants = HashMap::new();
+    for c in doc.constants() {
+        type_constants.entry(&c.ty).or_insert(Vec::new()).push(c);
+    }
+
     for nt in doc.typenames() {
-        print_datatype(&mut ret, &*nt);
+        print_datatype(&mut header, &*nt);
+
+        if let Some(constants) = type_constants.remove(&nt.name) {
+            for constant in constants {
+                print_constant(&mut header, &constant);
+            }
+        }
     }
 
     for m in doc.modules() {
-        print_module(&mut ret, &m);
+        print_module(&mut header, &mut source, &m);
     }
 
-    ret.push_str(
+    header.push_str(
         r#"#ifdef __cplusplus
 }
 #endif
@@ -71,7 +117,7 @@ extern "C" {{
 "#,
     );
 
-    ret
+    Generated { header, source }
 }
 
 fn print_datatype(ret: &mut String, nt: &NamedType) {
@@ -85,14 +131,11 @@ fn print_datatype(ret: &mut String, nt: &NamedType) {
 
     match &nt.tref {
         TypeRef::Value(v) => match &**v {
-            Type::Enum(e) => print_enum(ret, &nt.name, e),
-            Type::Int(i) => print_int(ret, &nt.name, i),
-            Type::Flags(f) => print_flags(ret, &nt.name, f),
-            Type::Struct(s) => print_struct(ret, &nt.name, s),
-            Type::Union(u) => print_union(ret, &nt.name, u),
+            Type::Record(s) => print_record(ret, &nt.name, s),
+            Type::Variant(v) => print_variant(ret, &nt.name, v),
             Type::Handle(h) => print_handle(ret, &nt.name, h),
             Type::Builtin { .. }
-            | Type::Array { .. }
+            | Type::List { .. }
             | Type::Pointer { .. }
             | Type::ConstPointer { .. } => print_alias(ret, &nt.name, &nt.tref),
         },
@@ -101,8 +144,8 @@ fn print_datatype(ret: &mut String, nt: &NamedType) {
 }
 
 fn print_alias(ret: &mut String, name: &Id, dest: &TypeRef) {
-    match &*dest.type_() {
-        Type::Array(_) => {
+    match &**dest.type_() {
+        Type::List(_) => {
             // Don't emit arrays as top-level types; instead we special-case
             // them in places like parameter lists so that we can pass them
             // as pointer and length pairs.
@@ -139,18 +182,18 @@ fn print_alias(ret: &mut String, name: &Id, dest: &TypeRef) {
     }
 }
 
-fn print_enum(ret: &mut String, name: &Id, e: &EnumDatatype) {
+fn print_enum(ret: &mut String, name: &Id, v: &Variant) {
     ret.push_str(&format!(
         "typedef {} __wasi_{}_t;\n",
-        intrepr_name(e.repr),
+        intrepr_name(v.tag_repr),
         ident_name(name)
     ));
     ret.push_str("\n");
 
-    for (index, variant) in e.variants.iter().enumerate() {
-        if !variant.docs.is_empty() {
+    for (index, case) in v.cases.iter().enumerate() {
+        if !case.docs.is_empty() {
             ret.push_str("/**\n");
-            for line in variant.docs.lines() {
+            for line in case.docs.lines() {
                 ret.push_str(&format!(" * {}\n", line));
             }
             ret.push_str(" */\n");
@@ -158,8 +201,8 @@ fn print_enum(ret: &mut String, name: &Id, e: &EnumDatatype) {
         ret.push_str(&format!(
             "#define __WASI_{}_{} ({}({}))\n",
             ident_name(&name).to_shouty_snake_case(),
-            ident_name(&variant.name).to_shouty_snake_case(),
-            intrepr_const(e.repr),
+            ident_name(&case.name).to_shouty_snake_case(),
+            intrepr_const(v.tag_repr),
             index
         ));
         ret.push_str("\n");
@@ -168,98 +211,61 @@ fn print_enum(ret: &mut String, name: &Id, e: &EnumDatatype) {
     ret.push_str(&format!(
         "_Static_assert(sizeof(__wasi_{}_t) == {}, \"witx calculated size\");\n",
         ident_name(name),
-        e.repr.mem_size()
+        v.tag_repr.mem_size()
     ));
     ret.push_str(&format!(
         "_Static_assert(_Alignof(__wasi_{}_t) == {}, \"witx calculated align\");\n",
         ident_name(name),
-        e.repr.mem_align()
+        v.tag_repr.mem_align()
     ));
 
     ret.push_str("\n");
 }
 
-fn print_int(ret: &mut String, name: &Id, i: &IntDatatype) {
-    ret.push_str(&format!(
-        "typedef {} __wasi_{}_t;\n",
-        intrepr_name(i.repr),
-        ident_name(name)
-    ));
-    ret.push_str("\n");
-
-    for (index, const_) in i.consts.iter().enumerate() {
-        if !const_.docs.is_empty() {
-            ret.push_str("/**\n");
-            for line in const_.docs.lines() {
-                ret.push_str(&format!(" * {}\n", line));
-            }
-            ret.push_str(" */\n");
+fn print_constant(ret: &mut String, const_: &Constant) {
+    if !const_.docs.is_empty() {
+        ret.push_str("/**\n");
+        for line in const_.docs.lines() {
+            ret.push_str(&format!(" * {}\n", line));
         }
-        ret.push_str(&format!(
-            "#define __WASI_{}_{} ({}({}))\n",
-            ident_name(&name).to_shouty_snake_case(),
-            ident_name(&const_.name).to_shouty_snake_case(),
-            intrepr_const(i.repr),
-            index
-        ));
-        ret.push_str("\n");
+        ret.push_str(" */\n");
     }
-
-    ret.push_str(&format!(
-        "_Static_assert(sizeof(__wasi_{}_t) == {}, \"witx calculated size\");\n",
-        ident_name(name),
-        i.repr.mem_size()
-    ));
     ret.push_str(&format!(
-        "_Static_assert(_Alignof(__wasi_{}_t) == {}, \"witx calculated align\");\n",
-        ident_name(name),
-        i.repr.mem_align()
+        "#define __WASI_{}_{} ((__wasi_{}_t){})\n",
+        ident_name(&const_.ty).to_shouty_snake_case(),
+        ident_name(&const_.name).to_shouty_snake_case(),
+        ident_name(&const_.ty),
+        const_.value,
     ));
-
     ret.push_str("\n");
 }
 
-fn print_flags(ret: &mut String, name: &Id, f: &FlagsDatatype) {
-    ret.push_str(&format!(
-        "typedef {} __wasi_{}_t;\n",
-        intrepr_name(f.repr),
-        ident_name(name)
-    ));
-    ret.push_str("\n");
-
-    for (index, flag) in f.flags.iter().enumerate() {
-        if !flag.docs.is_empty() {
-            ret.push_str("/**\n");
-            for line in flag.docs.lines() {
-                ret.push_str(&format!(" * {}\n", line));
-            }
-            ret.push_str(" */\n");
-        }
+fn print_record(ret: &mut String, name: &Id, s: &RecordDatatype) {
+    if let Some(repr) = s.bitflags_repr() {
         ret.push_str(&format!(
-            "#define __WASI_{}_{} ({}({}))\n",
-            ident_name(name).to_shouty_snake_case(),
-            ident_name(&flag.name).to_shouty_snake_case(),
-            intrepr_const(f.repr),
-            1u128 << index
+            "typedef {} __wasi_{}_t;\n\n",
+            intrepr_name(repr),
+            ident_name(name)
         ));
-        ret.push_str("\n");
+        for (i, member) in s.members.iter().enumerate() {
+            if !member.docs.is_empty() {
+                ret.push_str("/**\n");
+                for line in member.docs.lines() {
+                    ret.push_str(&format!(" * {}\n", line));
+                }
+                ret.push_str(" */\n");
+            }
+            ret.push_str(&format!(
+                "#define __WASI_{}_{} ((__wasi_{}_t)(1 << {}))\n",
+                ident_name(name).to_shouty_snake_case(),
+                ident_name(&member.name).to_shouty_snake_case(),
+                ident_name(name),
+                i,
+            ));
+            ret.push_str("\n");
+        }
+        return;
     }
-
-    ret.push_str(&format!(
-        "_Static_assert(sizeof(__wasi_{}_t) == {}, \"witx calculated size\");\n",
-        ident_name(name),
-        f.repr.mem_size(),
-    ));
-    ret.push_str(&format!(
-        "_Static_assert(_Alignof(__wasi_{}_t) == {}, \"witx calculated align\");\n",
-        ident_name(name),
-        f.repr.mem_align(),
-    ));
-
-    ret.push_str("\n");
-}
-
-fn print_struct(ret: &mut String, name: &Id, s: &StructDatatype) {
     ret.push_str(&format!(
         "typedef struct __wasi_{}_t {{\n",
         ident_name(name)
@@ -307,17 +313,20 @@ fn print_struct(ret: &mut String, name: &Id, s: &StructDatatype) {
     ret.push_str("\n");
 }
 
-fn print_union(ret: &mut String, name: &Id, u: &UnionDatatype) {
+fn print_variant(ret: &mut String, name: &Id, v: &Variant) {
+    if v.cases.iter().all(|v| v.tref.is_none()) {
+        return print_enum(ret, name, v);
+    }
     ret.push_str(&format!(
         "typedef union __wasi_{}_u_t {{\n",
         ident_name(name)
     ));
 
-    for variant in &u.variants {
-        if let Some(ref tref) = variant.tref {
-            if !variant.docs.is_empty() {
+    for case in &v.cases {
+        if let Some(tref) = &case.tref {
+            if !case.docs.is_empty() {
                 ret.push_str("    /**\n");
-                for line in variant.docs.lines() {
+                for line in case.docs.lines() {
                     ret.push_str(&format!("    * {}\n", line));
                 }
                 ret.push_str("    */\n");
@@ -325,7 +334,7 @@ fn print_union(ret: &mut String, name: &Id, u: &UnionDatatype) {
             ret.push_str(&format!(
                 "    {} {};\n",
                 typeref_name(tref),
-                ident_name(&variant.name)
+                ident_name(&case.name)
             ));
         }
     }
@@ -336,7 +345,7 @@ fn print_union(ret: &mut String, name: &Id, u: &UnionDatatype) {
         ident_name(name)
     ));
 
-    ret.push_str(&format!("    {} tag;\n", namedtype_name(&u.tag)));
+    ret.push_str(&format!("    {} tag;\n", intrepr_name(v.tag_repr)));
     ret.push_str(&format!("    __wasi_{}_u_t u;\n", ident_name(name)));
 
     ret.push_str(&format!("}} __wasi_{}_t;\n", ident_name(name)));
@@ -345,29 +354,12 @@ fn print_union(ret: &mut String, name: &Id, u: &UnionDatatype) {
     ret.push_str(&format!(
         "_Static_assert(sizeof(__wasi_{}_t) == {}, \"witx calculated size\");\n",
         ident_name(name),
-        u.mem_size()
+        v.mem_size()
     ));
     ret.push_str(&format!(
         "_Static_assert(_Alignof(__wasi_{}_t) == {}, \"witx calculated align\");\n",
         ident_name(name),
-        u.mem_align()
-    ));
-
-    let l = u.union_layout();
-    ret.push_str(&format!(
-        "_Static_assert(offsetof(__wasi_{}_t, u) == {}, \"witx calculated union offset\");\n",
-        ident_name(name),
-        l.contents_offset,
-    ));
-    ret.push_str(&format!(
-        "_Static_assert(sizeof(__wasi_{}_u_t) == {}, \"witx calculated union size\");\n",
-        ident_name(name),
-        l.contents_size,
-    ));
-    ret.push_str(&format!(
-        "_Static_assert(_Alignof(__wasi_{}_u_t) == {}, \"witx calculated union align\");\n",
-        ident_name(name),
-        l.contents_align,
+        v.mem_align()
     ));
 
     ret.push_str("\n");
@@ -390,25 +382,26 @@ fn print_handle(ret: &mut String, name: &Id, h: &HandleDatatype) {
     ret.push_str("\n");
 }
 
-fn print_module(ret: &mut String, m: &Module) {
-    ret.push_str("/**\n");
-    ret.push_str(&format!(" * @defgroup {}\n", ident_name(&m.name),));
+fn print_module(header: &mut String, source: &mut String, m: &Module) {
+    header.push_str("/**\n");
+    header.push_str(&format!(" * @defgroup {}\n", ident_name(&m.name),));
     for line in m.docs.lines() {
-        ret.push_str(&format!(" * {}\n", line));
+        header.push_str(&format!(" * {}\n", line));
     }
-    ret.push_str(" * @{\n");
-    ret.push_str(" */\n");
-    ret.push_str("\n");
+    header.push_str(" * @{\n");
+    header.push_str(" */\n");
+    header.push_str("\n");
 
     for func in m.funcs() {
-        print_func(ret, &func, &m.name);
+        print_func_header(header, &func);
+        print_func_source(source, &func, &m.name);
     }
 
-    ret.push_str("/** @} */\n");
-    ret.push_str("\n");
+    header.push_str("/** @} */\n");
+    header.push_str("\n");
 }
 
-fn print_func(ret: &mut String, func: &InterfaceFunc, module_name: &Id) {
+fn print_func_header(ret: &mut String, func: &InterfaceFunc) {
     if !func.docs.is_empty() {
         ret.push_str("/**\n");
         for line in func.docs.lines() {
@@ -419,117 +412,377 @@ fn print_func(ret: &mut String, func: &InterfaceFunc, module_name: &Id) {
             if !first_result.docs.is_empty() {
                 ret.push_str(" * @return\n");
                 for line in first_result.docs.lines() {
-                    ret.push_str(&format!(" * {}", line));
+                    ret.push_str(&format!(" * {}\n", line));
                 }
             }
         }
         ret.push_str(" */\n");
     }
-    if func.results.is_empty() {
-        // Special-case "proc_exit" as _Noreturn -- TODO: Encode this in witx.
-        if func.name.as_str() == "proc_exit" {
-            ret.push_str("_Noreturn ");
-        }
-        ret.push_str("void ");
-    } else {
-        let first_result = &func.results[0];
-        ret.push_str(&format!("{} ", typeref_name(&first_result.tref)));
+
+    print_func_signature(ret, func, true);
+
+    if func.results.len() > 0 {
+        ret.push_str(" __attribute__((__warn_unused_result__))");
     }
 
-    ret.push_str(&format!("__wasi_{}(\n", ident_name(&func.name)));
+    ret.push_str(";\n");
+}
 
-    if func.params.is_empty() && func.results.len() <= 1 {
-        ret.push_str("    void\n");
+fn print_func_signature(ret: &mut String, func: &InterfaceFunc, header: bool) {
+    let mut params = Vec::new();
+    for param in func.params.iter() {
+        add_params(
+            &mut params,
+            &ident_name(&param.name),
+            &param.tref,
+            &param.docs,
+        );
     }
-    for (index, param) in func.params.iter().enumerate() {
-        if !param.docs.is_empty() {
-            ret.push_str("    /**\n");
-            for line in param.docs.lines() {
-                ret.push_str(&format!("     * {}\n", line));
+    match func.results.len() {
+        0 => {
+            if func.noreturn {
+                ret.push_str("_Noreturn ");
             }
-            ret.push_str("     */\n");
+            ret.push_str("void ");
         }
-        add_params(ret, &ident_name(&param.name), &param.tref);
-        ret.push_str(&format!(
-            "{}\n",
-            if index + 1 < func.params.len() || func.results.len() > 1 {
-                ",\n"
-            } else {
-                ""
-            }
-        ));
+        1 => {
+            assert!(!func.noreturn);
+            push_return_type(ret, &mut params, &func.results[0].tref);
+        }
+        _ => panic!("unsupported number of return values"),
     }
 
-    for (index, result) in func.results.iter().enumerate() {
-        if index == 0 {
-            // The first result is returned by value above.
-            continue;
-        }
-        if !result.docs.is_empty() {
-            ret.push_str("    /**\n");
-            for line in result.docs.lines() {
-                ret.push_str(&format!("     * {}\n", line));
+    ret.push_str(&format!("__wasi_{}(\n", ident_name(&func.name)));
+    if params.len() == 0 {
+        ret.push_str("    void\n");
+    } else {
+        for (i, (docs, param)) in params.iter().enumerate() {
+            if header {
+                if let Some(docs) = docs {
+                    ret.push_str("    /**\n");
+                    for line in docs.lines() {
+                        ret.push_str(&format!("     * {}\n", line));
+                    }
+                    ret.push_str("     */\n");
+                }
             }
-            ret.push_str("     */\n");
-        }
-        ret.push_str(&format!(
-            "    {} *{}{}\n",
-            typeref_name(&result.tref),
-            ident_name(&result.name),
-            if index + 1 < func.results.len() {
-                ","
-            } else {
-                ""
+            ret.push_str("    ");
+            ret.push_str(&param);
+            if i != params.len() - 1 {
+                ret.push_str(",");
             }
-        ));
+            ret.push_str("\n");
+        }
     }
+    ret.push_str(")");
+}
+
+fn print_func_source(ret: &mut String, func: &InterfaceFunc, module_name: &Id) {
+    let (params, results) = func.wasm_signature();
 
+    if func.noreturn {
+        ret.push_str("_Noreturn ");
+    }
+    match results.len() {
+        0 => ret.push_str("void "),
+        1 => {
+            ret.push_str(wasm_type(&results[0]));
+            ret.push_str(" ");
+        }
+        _ => unimplemented!(),
+    }
+
+    ret.push_str("__imported_");
+    ret.push_str(&ident_name(module_name));
+    ret.push_str("_");
+    ret.push_str(&ident_name(&func.name));
+    ret.push_str("(");
+    for (i, param) in params.iter().enumerate() {
+        if i > 0 {
+            ret.push_str(", ");
+        }
+        ret.push_str(wasm_type(param));
+        ret.push_str(&format!(" arg{}", i));
+    }
     ret.push_str(") __attribute__((\n");
     ret.push_str(&format!(
         "    __import_module__(\"{}\"),\n",
         ident_name(module_name)
     ));
     ret.push_str(&format!(
-        "    __import_name__(\"{}\")",
+        "    __import_name__(\"{}\")\n",
         ident_name(&func.name)
     ));
-    if !func.results.is_empty() {
-        ret.push_str(",\n    __warn_unused_result__\n");
+    ret.push_str("));\n\n");
+    print_func_signature(ret, func, false);
+    ret.push_str("{\n");
+
+    // Any string arguments will have their length passed to the raw wasi API,
+    // but we only took a `char*` as a parameter. Get the length of all string
+    // arguments here for it to get passed along later.
+    for param in func.params.iter() {
+        if let Type::List(ty) = &**param.tref.type_() {
+            if let Type::Builtin(BuiltinType::Char) = &**ty.type_() {
+                ret.push_str(&format!(
+                    "    size_t {}_len = strlen({0});\n",
+                    ident_name(&param.name)
+                ));
+            }
+        }
     }
-    ret.push_str("));\n");
-    ret.push_str("\n");
-}
 
-fn add_params(ret: &mut String, name: &str, tref: &TypeRef) {
-    match &*tref.type_() {
-        Type::Builtin(BuiltinType::String) => {
-            ret.push_str(&format!("    const char *{},\n", name));
-            ret.push_str("\n");
-            ret.push_str("    /**\n");
-            ret.push_str(&format!(
-                "     * The length of the buffer pointed to by `{}`.\n",
-                name,
-            ));
-            ret.push_str("     */\n");
-            ret.push_str(&format!("    size_t {}_len", name));
+    func.call_wasm(
+        module_name,
+        &mut C {
+            src: ret,
+            params: &func.params,
+            block_storage: Vec::new(),
+            blocks: Vec::new(),
+        },
+    );
+
+    ret.push_str("}\n\n");
+
+    /// This is a structure which implements the glue necessary to translate
+    /// between the C API of a function and the desired WASI ABI we're being
+    /// told it has.
+    ///
+    /// It's worth nothing that this will, in the long run, get much fancier.
+    /// For now this is extremely simple and entirely assumes that the WASI ABI
+    /// matches our C ABI. This means it will only really generate valid code
+    /// as-is *today* and won't work for any updates to the WASI ABI in the
+    /// future.
+    ///
+    /// It's hoped that this situation will improve as interface types and witx
+    /// continue to evolve and there's a more clear path forward for how to
+    /// translate an interface types signature to a C API.
+    struct C<'a> {
+        src: &'a mut String,
+        params: &'a [InterfaceFuncParam],
+        block_storage: Vec<String>,
+        blocks: Vec<String>,
+    }
+
+    impl Bindgen for C<'_> {
+        type Operand = String;
+
+        fn push_block(&mut self) {
+            let prev = mem::replace(self.src, String::new());
+            self.block_storage.push(prev);
         }
-        Type::Array(element) => {
-            ret.push_str(&format!(
-                "    const {} *{},\n",
-                typeref_name(&element),
-                name
-            ));
-            ret.push_str("\n");
-            ret.push_str("    /**\n");
-            ret.push_str(&format!(
-                "     * The length of the array pointed to by `{}`.\n",
-                name,
-            ));
-            ret.push_str("     */\n");
-            ret.push_str(&format!("    size_t {}_len", name));
+
+        fn finish_block(&mut self, operand: Option<String>) {
+            let to_restore = self.block_storage.pop().unwrap();
+            let src = mem::replace(self.src, to_restore);
+            assert!(src.is_empty());
+            match operand {
+                None => self.blocks.push(String::new()),
+                Some(s) => self.blocks.push(s),
+            }
+        }
+
+        fn allocate_space(&mut self, _: usize, _: &NamedType) {
+            // not necessary due to us taking parameters as pointers
+        }
+
+        fn emit(
+            &mut self,
+            inst: &Instruction<'_>,
+            operands: &mut Vec<String>,
+            results: &mut Vec<String>,
+        ) {
+            let mut top_as = |cvt: &str| {
+                let s = operands.pop().unwrap();
+                results.push(format!("({}) {}", cvt, s));
+            };
+
+            match inst {
+                Instruction::GetArg { nth } => {
+                    results.push(ident_name(&self.params[*nth].name));
+                }
+                // For the C bindings right now any parameter which needs its
+                // address taken is already taken as a pointer, so we can just
+                // forward the operand to the result.
+                Instruction::AddrOf => results.push(operands.pop().unwrap()),
+
+                Instruction::I64FromU64 => top_as("int64_t"),
+                Instruction::I32FromPointer
+                | Instruction::I32FromConstPointer
+                | Instruction::I32FromHandle { .. }
+                | Instruction::I32FromUsize
+                | Instruction::I32FromChar
+                | Instruction::I32FromU8
+                | Instruction::I32FromS8
+                | Instruction::I32FromChar8
+                | Instruction::I32FromU16
+                | Instruction::I32FromS16
+                | Instruction::I32FromU32 => top_as("int32_t"),
+
+                Instruction::I32FromBitflags { .. } | Instruction::I64FromBitflags { .. } => {
+                    // Rely on C's casting for this
+                    results.push(operands.pop().unwrap());
+                }
+
+                // No conversion necessary
+                Instruction::F32FromIf32
+                | Instruction::F64FromIf64
+                | Instruction::If32FromF32
+                | Instruction::If64FromF64
+                | Instruction::I64FromS64
+                | Instruction::I32FromS32 => results.push(operands.pop().unwrap()),
+
+                Instruction::ListPointerLength => {
+                    let list = operands.pop().unwrap();
+                    results.push(format!("(int32_t) {}", list));
+                    results.push(format!("(int32_t) {}_len", list));
+                }
+                Instruction::ReturnPointerGet { n } => {
+                    // We currently match the wasi ABI with the actual
+                    // function's API signature in C, this means when a return
+                    // pointer is asked for we can simply forward our parameter
+                    // that's a return pointer.
+                    results.push(format!("(int32_t) retptr{}", n));
+                }
+
+                Instruction::Load { .. } => {
+                    // this is currently skipped because return pointers are
+                    // already evident in parameters and so we don't need to
+                    // load/store from them again
+                    results.push("dummy".to_string());
+                }
+
+                Instruction::ReuseReturn => {
+                    results.push("ret".to_string());
+                }
+
+                Instruction::TupleLift { .. } => {
+                    // this is currently skipped because tuples are only used
+                    // as return values and those are always returned through
+                    // out-ptrs, so the values have already been passed through
+                    // at this point.
+                    results.push("dummy".to_string());
+                }
+
+                Instruction::ResultLift => {
+                    let err = self.blocks.pop().unwrap();
+
+                    // Our ok block should either have done nothing (meaning
+                    // there's no "ok" payload) or it loaded a return pointer
+                    // and/or tuple some values. In all these cases we discard
+                    // the results since out pointers have already been written
+                    // to and we only return the discriminant from the
+                    // function.
+                    let ok = self.blocks.pop().unwrap();
+                    assert!(ok == "dummy" || ok == "");
+
+                    // Note that we just push the result of the error block.
+                    // Our block management asserts that it's an expression,
+                    // which in this case will basically always be casting the
+                    // error code to an error code variant, which we return.
+                    results.push(err);
+                }
+
+                // Enums are represented in C simply as the integral tag type
+                Instruction::EnumLift { ty } => match &**ty.type_() {
+                    Type::Variant(v) => top_as(intrepr_name(v.tag_repr)),
+                    _ => unreachable!(),
+                },
+                Instruction::EnumLower { .. } => top_as("int32_t"),
+
+                Instruction::CallWasm {
+                    module,
+                    name,
+                    params: _,
+                    results: func_results,
+                } => {
+                    assert!(func_results.len() < 2);
+                    self.src.push_str("    ");
+                    if func_results.len() > 0 {
+                        self.src.push_str(wasm_type(&func_results[0]));
+                        self.src.push_str(" ret = ");
+                        results.push("ret".to_string());
+                    }
+                    self.src.push_str("__imported_");
+                    self.src.push_str(module);
+                    self.src.push_str("_");
+                    self.src.push_str(name);
+                    self.src.push_str("(");
+                    self.src.push_str(&operands.join(", "));
+                    self.src.push_str(");\n");
+                }
+
+                Instruction::Return { amt: 0 } => {}
+                Instruction::Return { amt: 1 } => {
+                    self.src.push_str("    return ");
+                    self.src.push_str(&operands[0]);
+                    self.src.push_str(";\n");
+                }
+
+                other => panic!("unimplemented instruction {:?}", other),
+            }
         }
+    }
+}
+
+fn push_return_type(ret: &mut String, params: &mut Vec<(Option<String>, String)>, tref: &TypeRef) {
+    match &**tref.type_() {
+        Type::Variant(v) => {
+            assert_eq!(v.cases.len(), 2, "unsupported type as a return value");
+            assert!(
+                v.cases[0].name == "ok",
+                "unsupported type as a return value"
+            );
+            assert!(
+                v.cases[1].name == "err",
+                "unsupported type as a return value"
+            );
+            let err = match &v.cases[1].tref {
+                Some(ty) => ty,
+                None => panic!("unsupported type as a return value"),
+            };
+            ret.push_str(&typeref_name(&err));
+            ret.push_str(" ");
+
+            let ok = match &v.cases[0].tref {
+                Some(ty) => ty,
+                None => return,
+            };
+            match &**ok.type_() {
+                Type::Record(r) if r.is_tuple() => {
+                    for (i, member) in r.members.iter().enumerate() {
+                        params.push((None, format!("{} *retptr{}", typeref_name(&member.tref), i)));
+                    }
+                }
+                _ => {
+                    params.push((None, format!("{} *retptr0", typeref_name(ok))));
+                }
+            }
+        }
+        _ => panic!("unsupported type as a return value"),
+    }
+}
+
+fn add_params(params: &mut Vec<(Option<String>, String)>, name: &str, tref: &TypeRef, docs: &str) {
+    let docs = if docs.is_empty() {
+        None
+    } else {
+        Some(docs.to_string())
+    };
+    match &**tref.type_() {
+        Type::List(element) => match &**element.type_() {
+            Type::Builtin(BuiltinType::Char) => {
+                params.push((docs, format!("const char *{}", name)));
+            }
+            _ => {
+                params.push((docs, format!("const {} *{}", typeref_name(&element), name)));
+                params.push((
+                    Some(format!("The length of the array pointed to by `{}`.", name,)),
+                    format!("size_t {}_len", name),
+                ));
+            }
+        },
         _ => {
-            ret.push_str(&format!("    {} {}", typeref_name(tref), name));
+            params.push((docs, format!("{} {}", typeref_name(tref), name)));
         }
     }
 }
@@ -540,13 +793,17 @@ fn ident_name(i: &Id) -> String {
 
 fn builtin_type_name(b: BuiltinType) -> &'static str {
     match b {
-        BuiltinType::String | BuiltinType::Char8 => {
+        BuiltinType::U8 { lang_c_char: true } => {
             panic!("no type name for string or char8 builtins")
         }
-        BuiltinType::USize => "size_t",
-        BuiltinType::U8 => "uint8_t",
+        BuiltinType::U8 { lang_c_char: false } => "uint8_t",
         BuiltinType::U16 => "uint16_t",
-        BuiltinType::U32 => "uint32_t",
+        BuiltinType::U32 {
+            lang_ptr_size: true,
+        } => "size_t",
+        BuiltinType::U32 {
+            lang_ptr_size: false,
+        } => "uint32_t",
         BuiltinType::U64 => "uint64_t",
         BuiltinType::S8 => "int8_t",
         BuiltinType::S16 => "int16_t",
@@ -554,12 +811,13 @@ fn builtin_type_name(b: BuiltinType) -> &'static str {
         BuiltinType::S64 => "int64_t",
         BuiltinType::F32 => "float",
         BuiltinType::F64 => "double",
+        BuiltinType::Char => "char32_t",
     }
 }
 
 fn typeref_name(tref: &TypeRef) -> String {
-    match &*tref.type_() {
-        Type::Builtin(BuiltinType::String) | Type::Builtin(BuiltinType::Char8) | Type::Array(_) => {
+    match &**tref.type_() {
+        Type::Builtin(BuiltinType::U8 { lang_c_char: true }) | Type::List(_) => {
             panic!("unsupported grammar: cannot construct name of string or array",)
         }
         _ => {}
@@ -568,16 +826,11 @@ fn typeref_name(tref: &TypeRef) -> String {
     match tref {
         TypeRef::Name(named_type) => namedtype_name(&named_type),
         TypeRef::Value(anon_type) => match &**anon_type {
-            Type::Array(_) => unreachable!("arrays excluded above"),
+            Type::List(_) => unreachable!("arrays excluded above"),
             Type::Builtin(b) => builtin_type_name(*b).to_string(),
             Type::Pointer(p) => format!("{} *", typeref_name(&*p)),
             Type::ConstPointer(p) => format!("const {} *", typeref_name(&*p)),
-            Type::Int(i) => format!("{}", intrepr_name(i.repr)),
-            Type::Struct { .. }
-            | Type::Union { .. }
-            | Type::Enum { .. }
-            | Type::Flags { .. }
-            | Type::Handle { .. } => unreachable!(
+            Type::Record { .. } | Type::Variant { .. } | Type::Handle { .. } => unreachable!(
                 "wasi should not have anonymous structs, unions, enums, flags, handles"
             ),
         },
@@ -585,10 +838,10 @@ fn typeref_name(tref: &TypeRef) -> String {
 }
 
 fn namedtype_name(named_type: &NamedType) -> String {
-    match &*named_type.type_() {
+    match &**named_type.type_() {
         Type::Pointer(p) => format!("{} *", typeref_name(&*p)),
         Type::ConstPointer(p) => format!("const {} *", typeref_name(&*p)),
-        Type::Array(_) => unreachable!("arrays excluded above"),
+        Type::List(_) => unreachable!("arrays excluded above"),
         _ => format!("__wasi_{}_t", named_type.name.as_str()),
     }
 }
@@ -610,3 +863,12 @@ fn intrepr_const(i: IntRepr) -> &'static str {
         IntRepr::U64 => "UINT64_C",
     }
 }
+
+fn wasm_type(wasm: &WasmType) -> &'static str {
+    match wasm {
+        WasmType::I32 => "int32_t",
+        WasmType::I64 => "int64_t",
+        WasmType::F32 => "float",
+        WasmType::F64 => "double",
+    }
+}
index 09450dfa024989e1387be519c104d99271a4b09c..8844c4976df0277626ccbcaa3e7a9023ffd3833a 100644 (file)
@@ -1,15 +1,12 @@
 mod c_header;
 
-use anyhow::{anyhow, Result};
-pub use c_header::to_c_header;
-use std::fs;
-use std::io;
+use anyhow::Result;
+pub use c_header::{to_c, Generated};
 use std::path::{Path, PathBuf};
 use witx::load;
 
-pub fn generate<P: AsRef<Path>>(inputs: &[P]) -> Result<String> {
-    // TODO: drop the anyhow! part once witx switches to anyhow.
-    let doc = load(&inputs).map_err(|e| anyhow!(e.to_string()))?;
+pub fn generate<P: AsRef<Path>>(inputs: &[P]) -> Result<Generated> {
+    let doc = load(&inputs)?;
 
     let inputs_str = &inputs
         .iter()
@@ -24,20 +21,19 @@ pub fn generate<P: AsRef<Path>>(inputs: &[P]) -> Result<String> {
         .collect::<Vec<_>>()
         .join(", ");
 
-    Ok(to_c_header(&doc, &inputs_str))
+    Ok(to_c(&doc, &inputs_str))
 }
 
 pub fn snapshot_witx_files() -> Result<Vec<PathBuf>> {
-    let snapshot_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("WASI/phases/snapshot/witx");
-    let mut inputs = fs::read_dir(snapshot_dir)?
-        .map(|res| res.map(|e| e.path()))
-        .collect::<Result<Vec<_>, io::Error>>()?;
-
-    inputs.sort();
-    Ok(inputs)
+    witx::phases::snapshot()
 }
 
 pub fn libc_wasi_api_header() -> PathBuf {
     PathBuf::from(env!("CARGO_MANIFEST_DIR"))
         .join("../../libc-bottom-half/headers/public/wasi/api.h")
 }
+
+pub fn libc_wasi_api_source() -> PathBuf {
+    PathBuf::from(env!("CARGO_MANIFEST_DIR"))
+        .join("../../libc-bottom-half/sources/__wasilibc_real.c")
+}
index 1ec50877fb07cb9033be6c55ec50a5a802b49187..867c31dbeda765d81e04e6f94030ba1f07e44563 100644 (file)
@@ -3,15 +3,18 @@ extern crate clap;
 
 use anyhow::Result;
 use clap::{Arg, SubCommand};
-use std::fs::File;
-use std::io::Write;
+use std::fs;
 use std::path::Path;
-use wasi_headers::{generate, libc_wasi_api_header, snapshot_witx_files};
+use wasi_headers::{generate, libc_wasi_api_header, libc_wasi_api_source, snapshot_witx_files};
 
-pub fn run<P: AsRef<Path>, Q: AsRef<Path>>(inputs: &[P], output: Q) -> Result<()> {
+pub fn run(
+    inputs: &[impl AsRef<Path>],
+    header_output: impl AsRef<Path>,
+    source_output: impl AsRef<Path>,
+) -> Result<()> {
     let c_header = generate(inputs)?;
-    let mut file = File::create(output)?;
-    file.write_all(c_header.as_bytes())?;
+    fs::write(header_output, c_header.header)?;
+    fs::write(source_output, c_header.source)?;
     Ok(())
 }
 
@@ -37,15 +40,19 @@ fn main() -> Result<()> {
 
     if matches.subcommand_matches("generate-libc").is_some() {
         let inputs = snapshot_witx_files()?;
-        let output = libc_wasi_api_header();
-        run(&inputs, &output)?;
+        run(&inputs, libc_wasi_api_header(), libc_wasi_api_source())?;
     } else if let Some(generate) = matches.subcommand_matches("generate") {
         let inputs = generate
             .values_of("inputs")
             .expect("required inputs arg")
             .collect::<Vec<_>>();
         let output = generate.value_of("output").expect("required output arg");
-        run(&inputs, output)?;
+        let output = Path::new(&output);
+        run(
+            &inputs,
+            output.with_extension("h"),
+            output.with_extension("c"),
+        )?;
     } else {
         unreachable!("a subcommand must be provided")
     };
index 5ff83279a679552fead204714887398cf5ebe455..faae7637ccda3ad57121f67e5dfd96aecacc4674 100644 (file)
@@ -1,17 +1,37 @@
 use std::fs;
+use std::path::Path;
 
 #[test]
 fn assert_same_as_src() {
-    let actual =
+    let actual_header =
         fs::read_to_string(wasi_headers::libc_wasi_api_header()).expect("read libc wasi/api.h");
+    let actual_source =
+        fs::read_to_string(wasi_headers::libc_wasi_api_source()).expect("read libc wasi/api.h");
     let witx_files = wasi_headers::snapshot_witx_files().expect("parse snapshot witx files");
     let expected = wasi_headers::generate(&witx_files).expect("header generation");
-    if actual == expected {
+    if actual_header == expected.header && actual_source == expected.source {
         return;
     }
 
-    eprintln!("The following diff was found between the generated <wasi/api.h> and the");
-    eprintln!("source <wasi/api.h> in the tree:");
+    if actual_header != expected.header {
+        diff(
+            &wasi_headers::libc_wasi_api_header(),
+            &actual_header,
+            &expected.header,
+        );
+    }
+    if actual_header != expected.header {
+        diff(
+            &wasi_headers::libc_wasi_api_source(),
+            &actual_header,
+            &expected.header,
+        );
+    }
+}
+
+fn diff(path: &Path, actual: &str, expected: &str) {
+    eprintln!("The following diff was found between the generated copy and the");
+    eprintln!("source copy of {:?} in the tree:", path);
     eprintln!();
 
     let mut expected_line = 1;