From b6c589fde50b5b69a77fa6f316bccbc9ff259f48 Mon Sep 17 00:00:00 2001 From: cjihrig Date: Sun, 15 Dec 2019 10:38:58 -0500 Subject: deps,src,test: update to uvwasi 0.0.3 This commit updates to uvwasi 0.0.3, which implements a newer version of the WASI spec, snapshot_1. Since the WASI API has changed, this also requires updating the WebAssembly memory interfacing logic and recompiling the WASI tests with a version of wasi-libc that supports snapshot_1. PR-URL: https://github.com/nodejs/node/pull/30980 Reviewed-By: David Carlier Reviewed-By: Anna Henningsen Reviewed-By: Rich Trott --- deps/uvwasi/include/fd_table.h | 20 ++------ deps/uvwasi/include/uvwasi.h | 5 +- deps/uvwasi/include/wasi_types.h | 9 ++-- deps/uvwasi/src/fd_table.c | 59 ++++++++++++++++------ deps/uvwasi/src/uvwasi.c | 103 +++++++++++++++++++++++++++++++++++++-- 5 files changed, 157 insertions(+), 39 deletions(-) (limited to 'deps') diff --git a/deps/uvwasi/include/fd_table.h b/deps/uvwasi/include/fd_table.h index 42a5f0d920..639ff9abc8 100644 --- a/deps/uvwasi/include/fd_table.h +++ b/deps/uvwasi/include/fd_table.h @@ -6,33 +6,22 @@ #include "wasi_types.h" #include "uv_mapping.h" -/* TODO(cjihrig): PATH_MAX_BYTES shouldn't be stack allocated. On Windows, paths - can be 32k long, and this PATH_MAX_BYTES is an artificial limitation. */ -#ifdef _WIN32 -/* MAX_PATH is in characters, not bytes. Make sure we have enough headroom. */ -# define PATH_MAX_BYTES (MAX_PATH * 4) -#else -# include -# define PATH_MAX_BYTES (PATH_MAX) -#endif - struct uvwasi_s; struct uvwasi_fd_wrap_t { uvwasi_fd_t id; uv_file fd; - char path[PATH_MAX_BYTES]; - char real_path[PATH_MAX_BYTES]; + char* path; + char* real_path; uvwasi_filetype_t type; uvwasi_rights_t rights_base; uvwasi_rights_t rights_inheriting; int preopen; - int valid; uv_mutex_t mutex; }; struct uvwasi_fd_table_t { - struct uvwasi_fd_wrap_t* fds; + struct uvwasi_fd_wrap_t** fds; uint32_t size; uint32_t used; uv_rwlock_t rwlock; @@ -61,7 +50,8 @@ uvwasi_errno_t uvwasi_fd_table_get(const struct uvwasi_fd_table_t* table, struct uvwasi_fd_wrap_t** wrap, uvwasi_rights_t rights_base, uvwasi_rights_t rights_inheriting); -uvwasi_errno_t uvwasi_fd_table_remove(struct uvwasi_fd_table_t* table, +uvwasi_errno_t uvwasi_fd_table_remove(struct uvwasi_s* uvwasi, + struct uvwasi_fd_table_t* table, const uvwasi_fd_t id); #endif /* __UVWASI_FD_TABLE_H__ */ diff --git a/deps/uvwasi/include/uvwasi.h b/deps/uvwasi/include/uvwasi.h index 2a4e389164..2fbcbc583d 100644 --- a/deps/uvwasi/include/uvwasi.h +++ b/deps/uvwasi/include/uvwasi.h @@ -11,7 +11,7 @@ extern "C" { #define UVWASI_VERSION_MAJOR 0 #define UVWASI_VERSION_MINOR 0 -#define UVWASI_VERSION_PATCH 1 +#define UVWASI_VERSION_PATCH 3 #define UVWASI_VERSION_HEX ((UVWASI_VERSION_MAJOR << 16) | \ (UVWASI_VERSION_MINOR << 8) | \ (UVWASI_VERSION_PATCH)) @@ -20,7 +20,7 @@ extern "C" { #define UVWASI_VERSION_STRING UVWASI_STRINGIFY(UVWASI_VERSION_MAJOR) "." \ UVWASI_STRINGIFY(UVWASI_VERSION_MINOR) "." \ UVWASI_STRINGIFY(UVWASI_VERSION_PATCH) -#define UVWASI_VERSION_WASI "snapshot_0" +#define UVWASI_VERSION_WASI "snapshot_1" typedef void* (*uvwasi_malloc)(size_t size, void* mem_user_data); typedef void (*uvwasi_free)(void* ptr, void* mem_user_data); @@ -69,6 +69,7 @@ void uvwasi_destroy(uvwasi_t* uvwasi); uvwasi_errno_t uvwasi_embedder_remap_fd(uvwasi_t* uvwasi, const uvwasi_fd_t fd, uv_file new_host_fd); +const char* uvwasi_embedder_err_code_to_string(uvwasi_errno_t code); // WASI system call API. diff --git a/deps/uvwasi/include/wasi_types.h b/deps/uvwasi/include/wasi_types.h index 34b5291c57..ec1013663f 100644 --- a/deps/uvwasi/include/wasi_types.h +++ b/deps/uvwasi/include/wasi_types.h @@ -155,7 +155,7 @@ typedef struct uvwasi_iovec_s { size_t buf_len; } uvwasi_iovec_t; -typedef uint32_t uvwasi_linkcount_t; +typedef uint64_t uvwasi_linkcount_t; typedef uint32_t uvwasi_lookupflags_t; /* Bitfield */ #define UVWASI_LOOKUP_SYMLINK_FOLLOW (1 << 0) @@ -266,7 +266,6 @@ typedef struct uvwasi_subscription_s { uvwasi_eventtype_t type; union { struct { - uvwasi_userdata_t identifier; uvwasi_clockid_t clock_id; uvwasi_timestamp_t timeout; uvwasi_timestamp_t precision; @@ -316,8 +315,8 @@ typedef struct uvwasi_event_s { } uvwasi_event_t; typedef uint8_t uvwasi_whence_t; -#define UVWASI_WHENCE_CUR 0 -#define UVWASI_WHENCE_END 1 -#define UVWASI_WHENCE_SET 2 +#define UVWASI_WHENCE_SET 0 +#define UVWASI_WHENCE_CUR 1 +#define UVWASI_WHENCE_END 2 #endif /* __UVWASI_WASI_TYPES_H__ */ diff --git a/deps/uvwasi/src/fd_table.c b/deps/uvwasi/src/fd_table.c index f716495e9a..0abddb5a21 100644 --- a/deps/uvwasi/src/fd_table.c +++ b/deps/uvwasi/src/fd_table.c @@ -187,12 +187,29 @@ static uvwasi_errno_t uvwasi__fd_table_insert(uvwasi_t* uvwasi, int preopen, struct uvwasi_fd_wrap_t** wrap) { struct uvwasi_fd_wrap_t* entry; - struct uvwasi_fd_wrap_t* new_fds; + struct uvwasi_fd_wrap_t** new_fds; uvwasi_errno_t err; uint32_t new_size; int index; uint32_t i; int r; + size_t mp_len; + char* mp_copy; + size_t rp_len; + char* rp_copy; + + mp_len = strlen(mapped_path); + rp_len = strlen(real_path); + entry = (struct uvwasi_fd_wrap_t*) + uvwasi__malloc(uvwasi, sizeof(*entry) + mp_len + rp_len + 2); + if (entry == NULL) return UVWASI_ENOMEM; + + mp_copy = (char*)(entry + 1); + rp_copy = mp_copy + mp_len + 1; + memcpy(mp_copy, mapped_path, mp_len); + mp_copy[mp_len] = '\0'; + memcpy(rp_copy, real_path, rp_len); + rp_copy[rp_len] = '\0'; uv_rwlock_wrlock(&table->rwlock); @@ -201,12 +218,13 @@ static uvwasi_errno_t uvwasi__fd_table_insert(uvwasi_t* uvwasi, new_size = table->size * 2; new_fds = uvwasi__realloc(uvwasi, table->fds, new_size * sizeof(*new_fds)); if (new_fds == NULL) { + uvwasi__free(uvwasi, entry); err = UVWASI_ENOMEM; goto exit; } for (i = table->size; i < new_size; ++i) - new_fds[i].valid = 0; + new_fds[i] = NULL; index = table->size; table->fds = new_fds; @@ -215,7 +233,7 @@ static uvwasi_errno_t uvwasi__fd_table_insert(uvwasi_t* uvwasi, /* The table is big enough, so find an empty slot for the new data. */ index = -1; for (i = 0; i < table->size; ++i) { - if (table->fds[i].valid != 1) { + if (table->fds[i] == NULL) { index = i; break; } @@ -223,12 +241,13 @@ static uvwasi_errno_t uvwasi__fd_table_insert(uvwasi_t* uvwasi, /* index should never be -1. */ if (index == -1) { + uvwasi__free(uvwasi, entry); err = UVWASI_ENOSPC; goto exit; } } - entry = &table->fds[index]; + table->fds[index] = entry; r = uv_mutex_init(&entry->mutex); if (r != 0) { @@ -238,13 +257,12 @@ static uvwasi_errno_t uvwasi__fd_table_insert(uvwasi_t* uvwasi, entry->id = index; entry->fd = fd; - strcpy(entry->path, mapped_path); - strcpy(entry->real_path, real_path); + entry->path = mp_copy; + entry->real_path = rp_copy; entry->type = type; entry->rights_base = rights_base; entry->rights_inheriting = rights_inheriting; entry->preopen = preopen; - entry->valid = 1; table->used++; if (wrap != NULL) @@ -281,7 +299,7 @@ uvwasi_errno_t uvwasi_fd_table_init(uvwasi_t* uvwasi, table->size = init_size; table->fds = uvwasi__calloc(uvwasi, init_size, - sizeof(struct uvwasi_fd_wrap_t)); + sizeof(struct uvwasi_fd_wrap_t*)); if (table->fds == NULL) { err = UVWASI_ENOMEM; @@ -325,9 +343,20 @@ error_exit: void uvwasi_fd_table_free(uvwasi_t* uvwasi, struct uvwasi_fd_table_t* table) { + struct uvwasi_fd_wrap_t* entry; + uint32_t i; + if (table == NULL) return; + for (i = 0; i < table->size; i++) { + entry = table->fds[i]; + if (entry == NULL) continue; + + uv_mutex_destroy(&entry->mutex); + uvwasi__free(uvwasi, entry); + } + uvwasi__free(uvwasi, table->fds); table->fds = NULL; table->size = 0; @@ -430,9 +459,9 @@ uvwasi_errno_t uvwasi_fd_table_get(const struct uvwasi_fd_table_t* table, goto exit; } - entry = &table->fds[id]; + entry = table->fds[id]; - if (entry->valid != 1 || entry->id != id) { + if (entry == NULL || entry->id != id) { err = UVWASI_EBADF; goto exit; } @@ -453,7 +482,8 @@ exit: } -uvwasi_errno_t uvwasi_fd_table_remove(struct uvwasi_fd_table_t* table, +uvwasi_errno_t uvwasi_fd_table_remove(uvwasi_t* uvwasi, + struct uvwasi_fd_table_t* table, const uvwasi_fd_t id) { struct uvwasi_fd_wrap_t* entry; uvwasi_errno_t err; @@ -468,15 +498,16 @@ uvwasi_errno_t uvwasi_fd_table_remove(struct uvwasi_fd_table_t* table, goto exit; } - entry = &table->fds[id]; + entry = table->fds[id]; - if (entry->valid != 1 || entry->id != id) { + if (entry == NULL || entry->id != id) { err = UVWASI_EBADF; goto exit; } uv_mutex_destroy(&entry->mutex); - entry->valid = 0; + uvwasi__free(uvwasi, entry); + table->fds[id] = NULL; table->used--; err = UVWASI_ESUCCESS; exit: diff --git a/deps/uvwasi/src/uvwasi.c b/deps/uvwasi/src/uvwasi.c index 0f7c4c5d3a..28c6dcc261 100644 --- a/deps/uvwasi/src/uvwasi.c +++ b/deps/uvwasi/src/uvwasi.c @@ -25,6 +25,16 @@ #include "fd_table.h" #include "clocks.h" +/* TODO(cjihrig): PATH_MAX_BYTES shouldn't be stack allocated. On Windows, paths + can be 32k long, and this PATH_MAX_BYTES is an artificial limitation. */ +#ifdef _WIN32 +/* MAX_PATH is in characters, not bytes. Make sure we have enough headroom. */ +# define PATH_MAX_BYTES (MAX_PATH * 4) +#else +# include +# define PATH_MAX_BYTES (PATH_MAX) +#endif + static void* default_malloc(size_t size, void* mem_user_data) { return malloc(size); } @@ -688,7 +698,7 @@ uvwasi_errno_t uvwasi_fd_close(uvwasi_t* uvwasi, uvwasi_fd_t fd) { if (r != 0) return uvwasi__translate_uv_error(r); - return uvwasi_fd_table_remove(&uvwasi->fds, fd); + return uvwasi_fd_table_remove(uvwasi, &uvwasi->fds, fd); } @@ -1319,7 +1329,7 @@ uvwasi_errno_t uvwasi_fd_renumber(uvwasi_t* uvwasi, to_wrap->id = to; uv_mutex_unlock(&from_wrap->mutex); uv_mutex_unlock(&to_wrap->mutex); - return uvwasi_fd_table_remove(&uvwasi->fds, from); + return uvwasi_fd_table_remove(uvwasi, &uvwasi->fds, from); } @@ -1773,7 +1783,7 @@ uvwasi_errno_t uvwasi_path_open(uvwasi_t* uvwasi, if ((o_flags & UVWASI_O_DIRECTORY) != 0 && wrap.type != UVWASI_FILETYPE_DIRECTORY) { uv_mutex_unlock(&dirfd_wrap->mutex); - uvwasi_fd_table_remove(&uvwasi->fds, wrap.id); + uvwasi_fd_table_remove(uvwasi, &uvwasi->fds, wrap.id); err = UVWASI_ENOTDIR; goto close_file_and_error_exit; } @@ -2140,3 +2150,90 @@ uvwasi_errno_t uvwasi_sock_shutdown(uvwasi_t* uvwasi, https://github.com/WebAssembly/WASI/issues/4 */ return UVWASI_ENOTSUP; } + + +const char* uvwasi_embedder_err_code_to_string(uvwasi_errno_t code) { + switch (code) { +#define V(errcode) case errcode: return #errcode; + V(UVWASI_E2BIG) + V(UVWASI_EACCES) + V(UVWASI_EADDRINUSE) + V(UVWASI_EADDRNOTAVAIL) + V(UVWASI_EAFNOSUPPORT) + V(UVWASI_EAGAIN) + V(UVWASI_EALREADY) + V(UVWASI_EBADF) + V(UVWASI_EBADMSG) + V(UVWASI_EBUSY) + V(UVWASI_ECANCELED) + V(UVWASI_ECHILD) + V(UVWASI_ECONNABORTED) + V(UVWASI_ECONNREFUSED) + V(UVWASI_ECONNRESET) + V(UVWASI_EDEADLK) + V(UVWASI_EDESTADDRREQ) + V(UVWASI_EDOM) + V(UVWASI_EDQUOT) + V(UVWASI_EEXIST) + V(UVWASI_EFAULT) + V(UVWASI_EFBIG) + V(UVWASI_EHOSTUNREACH) + V(UVWASI_EIDRM) + V(UVWASI_EILSEQ) + V(UVWASI_EINPROGRESS) + V(UVWASI_EINTR) + V(UVWASI_EINVAL) + V(UVWASI_EIO) + V(UVWASI_EISCONN) + V(UVWASI_EISDIR) + V(UVWASI_ELOOP) + V(UVWASI_EMFILE) + V(UVWASI_EMLINK) + V(UVWASI_EMSGSIZE) + V(UVWASI_EMULTIHOP) + V(UVWASI_ENAMETOOLONG) + V(UVWASI_ENETDOWN) + V(UVWASI_ENETRESET) + V(UVWASI_ENETUNREACH) + V(UVWASI_ENFILE) + V(UVWASI_ENOBUFS) + V(UVWASI_ENODEV) + V(UVWASI_ENOENT) + V(UVWASI_ENOEXEC) + V(UVWASI_ENOLCK) + V(UVWASI_ENOLINK) + V(UVWASI_ENOMEM) + V(UVWASI_ENOMSG) + V(UVWASI_ENOPROTOOPT) + V(UVWASI_ENOSPC) + V(UVWASI_ENOSYS) + V(UVWASI_ENOTCONN) + V(UVWASI_ENOTDIR) + V(UVWASI_ENOTEMPTY) + V(UVWASI_ENOTRECOVERABLE) + V(UVWASI_ENOTSOCK) + V(UVWASI_ENOTSUP) + V(UVWASI_ENOTTY) + V(UVWASI_ENXIO) + V(UVWASI_EOVERFLOW) + V(UVWASI_EOWNERDEAD) + V(UVWASI_EPERM) + V(UVWASI_EPIPE) + V(UVWASI_EPROTO) + V(UVWASI_EPROTONOSUPPORT) + V(UVWASI_EPROTOTYPE) + V(UVWASI_ERANGE) + V(UVWASI_EROFS) + V(UVWASI_ESPIPE) + V(UVWASI_ESRCH) + V(UVWASI_ESTALE) + V(UVWASI_ETIMEDOUT) + V(UVWASI_ETXTBSY) + V(UVWASI_EXDEV) + V(UVWASI_ENOTCAPABLE) + V(UVWASI_ESUCCESS) +#undef V + default: + return "UVWASI_UNKNOWN_ERROR"; + } +} -- cgit v1.2.1