diff --git a/deps/uvwasi/include/uvwasi.h b/deps/uvwasi/include/uvwasi.h
index f2d2d1a9fd8945..0090313c8af2eb 100644
--- a/deps/uvwasi/include/uvwasi.h
+++ b/deps/uvwasi/include/uvwasi.h
@@ -5,13 +5,12 @@
 extern "C" {
 #endif
 
-#include "uv.h"
+#include "wasi_serdes.h"
 #include "wasi_types.h"
-#include "fd_table.h"
 
 #define UVWASI_VERSION_MAJOR 0
 #define UVWASI_VERSION_MINOR 0
-#define UVWASI_VERSION_PATCH 8
+#define UVWASI_VERSION_PATCH 9
 #define UVWASI_VERSION_HEX ((UVWASI_VERSION_MAJOR << 16) | \
                             (UVWASI_VERSION_MINOR <<  8) | \
                             (UVWASI_VERSION_PATCH))
@@ -35,16 +34,18 @@ typedef struct uvwasi_mem_s {
   uvwasi_realloc realloc;
 } uvwasi_mem_t;
 
+struct uvwasi_fd_table_t;
+
 typedef struct uvwasi_s {
-  struct uvwasi_fd_table_t fds;
-  size_t argc;
+  struct uvwasi_fd_table_t* fds;
+  uvwasi_size_t argc;
   char** argv;
   char* argv_buf;
-  size_t argv_buf_size;
-  size_t envc;
+  uvwasi_size_t argv_buf_size;
+  uvwasi_size_t envc;
   char** env;
   char* env_buf;
-  size_t env_buf_size;
+  uvwasi_size_t env_buf_size;
   const uvwasi_mem_t* allocator;
 } uvwasi_t;
 
@@ -54,12 +55,12 @@ typedef struct uvwasi_preopen_s {
 } uvwasi_preopen_t;
 
 typedef struct uvwasi_options_s {
-  size_t fd_table_size;
-  size_t preopenc;
+  uvwasi_size_t fd_table_size;
+  uvwasi_size_t preopenc;
   uvwasi_preopen_t* preopens;
-  size_t argc;
-  char** argv;
-  char** envp;
+  uvwasi_size_t argc;
+  const char** argv;
+  const char** envp;
   uvwasi_fd_t in;
   uvwasi_fd_t out;
   uvwasi_fd_t err;
@@ -69,17 +70,18 @@ typedef struct uvwasi_options_s {
 /* Embedder API. */
 uvwasi_errno_t uvwasi_init(uvwasi_t* uvwasi, uvwasi_options_t* options);
 void uvwasi_destroy(uvwasi_t* uvwasi);
+/* Use int instead of uv_file to avoid needing uv.h */
 uvwasi_errno_t uvwasi_embedder_remap_fd(uvwasi_t* uvwasi,
                                         const uvwasi_fd_t fd,
-                                        uv_file new_host_fd);
+                                        int new_host_fd);
 const char* uvwasi_embedder_err_code_to_string(uvwasi_errno_t code);
 
 
 /* WASI system call API. */
 uvwasi_errno_t uvwasi_args_get(uvwasi_t* uvwasi, char** argv, char* argv_buf);
 uvwasi_errno_t uvwasi_args_sizes_get(uvwasi_t* uvwasi,
-                                     size_t* argc,
-                                     size_t* argv_buf_size);
+                                     uvwasi_size_t* argc,
+                                     uvwasi_size_t* argv_buf_size);
 uvwasi_errno_t uvwasi_clock_res_get(uvwasi_t* uvwasi,
                                     uvwasi_clockid_t clock_id,
                                     uvwasi_timestamp_t* resolution);
@@ -91,8 +93,8 @@ uvwasi_errno_t uvwasi_environ_get(uvwasi_t* uvwasi,
                                   char** environment,
                                   char* environ_buf);
 uvwasi_errno_t uvwasi_environ_sizes_get(uvwasi_t* uvwasi,
-                                        size_t* environ_count,
-                                        size_t* environ_buf_size);
+                                        uvwasi_size_t* environ_count,
+                                        uvwasi_size_t* environ_buf_size);
 uvwasi_errno_t uvwasi_fd_advise(uvwasi_t* uvwasi,
                                 uvwasi_fd_t fd,
                                 uvwasi_filesize_t offset,
@@ -129,33 +131,33 @@ uvwasi_errno_t uvwasi_fd_filestat_set_times(uvwasi_t* uvwasi,
 uvwasi_errno_t uvwasi_fd_pread(uvwasi_t* uvwasi,
                                uvwasi_fd_t fd,
                                const uvwasi_iovec_t* iovs,
-                               size_t iovs_len,
+                               uvwasi_size_t iovs_len,
                                uvwasi_filesize_t offset,
-                               size_t* nread);
+                               uvwasi_size_t* nread);
 uvwasi_errno_t uvwasi_fd_prestat_get(uvwasi_t* uvwasi,
                                      uvwasi_fd_t fd,
                                      uvwasi_prestat_t* buf);
 uvwasi_errno_t uvwasi_fd_prestat_dir_name(uvwasi_t* uvwasi,
                                           uvwasi_fd_t fd,
                                           char* path,
-                                          size_t path_len);
+                                          uvwasi_size_t path_len);
 uvwasi_errno_t uvwasi_fd_pwrite(uvwasi_t* uvwasi,
                                 uvwasi_fd_t fd,
                                 const uvwasi_ciovec_t* iovs,
-                                size_t iovs_len,
+                                uvwasi_size_t iovs_len,
                                 uvwasi_filesize_t offset,
-                                size_t* nwritten);
+                                uvwasi_size_t* nwritten);
 uvwasi_errno_t uvwasi_fd_read(uvwasi_t* uvwasi,
                               uvwasi_fd_t fd,
                               const uvwasi_iovec_t* iovs,
-                              size_t iovs_len,
-                              size_t* nread);
+                              uvwasi_size_t iovs_len,
+                              uvwasi_size_t* nread);
 uvwasi_errno_t uvwasi_fd_readdir(uvwasi_t* uvwasi,
                                  uvwasi_fd_t fd,
                                  void* buf,
-                                 size_t buf_len,
+                                 uvwasi_size_t buf_len,
                                  uvwasi_dircookie_t cookie,
-                                 size_t* bufused);
+                                 uvwasi_size_t* bufused);
 uvwasi_errno_t uvwasi_fd_renumber(uvwasi_t* uvwasi,
                                   uvwasi_fd_t from,
                                   uvwasi_fd_t to);
@@ -171,23 +173,23 @@ uvwasi_errno_t uvwasi_fd_tell(uvwasi_t* uvwasi,
 uvwasi_errno_t uvwasi_fd_write(uvwasi_t* uvwasi,
                                uvwasi_fd_t fd,
                                const uvwasi_ciovec_t* iovs,
-                               size_t iovs_len,
-                               size_t* nwritten);
+                               uvwasi_size_t iovs_len,
+                               uvwasi_size_t* nwritten);
 uvwasi_errno_t uvwasi_path_create_directory(uvwasi_t* uvwasi,
                                             uvwasi_fd_t fd,
                                             const char* path,
-                                            size_t path_len);
+                                            uvwasi_size_t path_len);
 uvwasi_errno_t uvwasi_path_filestat_get(uvwasi_t* uvwasi,
                                         uvwasi_fd_t fd,
                                         uvwasi_lookupflags_t flags,
                                         const char* path,
-                                        size_t path_len,
+                                        uvwasi_size_t path_len,
                                         uvwasi_filestat_t* buf);
 uvwasi_errno_t uvwasi_path_filestat_set_times(uvwasi_t* uvwasi,
                                               uvwasi_fd_t fd,
                                               uvwasi_lookupflags_t flags,
                                               const char* path,
-                                              size_t path_len,
+                                              uvwasi_size_t path_len,
                                               uvwasi_timestamp_t st_atim,
                                               uvwasi_timestamp_t st_mtim,
                                               uvwasi_fstflags_t fst_flags);
@@ -195,15 +197,15 @@ uvwasi_errno_t uvwasi_path_link(uvwasi_t* uvwasi,
                                 uvwasi_fd_t old_fd,
                                 uvwasi_lookupflags_t old_flags,
                                 const char* old_path,
-                                size_t old_path_len,
+                                uvwasi_size_t old_path_len,
                                 uvwasi_fd_t new_fd,
                                 const char* new_path,
-                                size_t new_path_len);
+                                uvwasi_size_t new_path_len);
 uvwasi_errno_t uvwasi_path_open(uvwasi_t* uvwasi,
                                 uvwasi_fd_t dirfd,
                                 uvwasi_lookupflags_t dirflags,
                                 const char* path,
-                                size_t path_len,
+                                uvwasi_size_t path_len,
                                 uvwasi_oflags_t o_flags,
                                 uvwasi_rights_t fs_rights_base,
                                 uvwasi_rights_t fs_rights_inheriting,
@@ -212,53 +214,55 @@ uvwasi_errno_t uvwasi_path_open(uvwasi_t* uvwasi,
 uvwasi_errno_t uvwasi_path_readlink(uvwasi_t* uvwasi,
                                     uvwasi_fd_t fd,
                                     const char* path,
-                                    size_t path_len,
+                                    uvwasi_size_t path_len,
                                     char* buf,
-                                    size_t buf_len,
-                                    size_t* bufused);
+                                    uvwasi_size_t buf_len,
+                                    uvwasi_size_t* bufused);
 uvwasi_errno_t uvwasi_path_remove_directory(uvwasi_t* uvwasi,
                                             uvwasi_fd_t fd,
                                             const char* path,
-                                            size_t path_len);
+                                            uvwasi_size_t path_len);
 uvwasi_errno_t uvwasi_path_rename(uvwasi_t* uvwasi,
                                   uvwasi_fd_t old_fd,
                                   const char* old_path,
-                                  size_t old_path_len,
+                                  uvwasi_size_t old_path_len,
                                   uvwasi_fd_t new_fd,
                                   const char* new_path,
-                                  size_t new_path_len);
+                                  uvwasi_size_t new_path_len);
 uvwasi_errno_t uvwasi_path_symlink(uvwasi_t* uvwasi,
                                    const char* old_path,
-                                   size_t old_path_len,
+                                   uvwasi_size_t old_path_len,
                                    uvwasi_fd_t fd,
                                    const char* new_path,
-                                   size_t new_path_len);
+                                   uvwasi_size_t new_path_len);
 uvwasi_errno_t uvwasi_path_unlink_file(uvwasi_t* uvwasi,
                                        uvwasi_fd_t fd,
                                        const char* path,
-                                       size_t path_len);
+                                       uvwasi_size_t path_len);
 uvwasi_errno_t uvwasi_poll_oneoff(uvwasi_t* uvwasi,
                                   const uvwasi_subscription_t* in,
                                   uvwasi_event_t* out,
-                                  size_t nsubscriptions,
-                                  size_t* nevents);
+                                  uvwasi_size_t nsubscriptions,
+                                  uvwasi_size_t* nevents);
 uvwasi_errno_t uvwasi_proc_exit(uvwasi_t* uvwasi, uvwasi_exitcode_t rval);
 uvwasi_errno_t uvwasi_proc_raise(uvwasi_t* uvwasi, uvwasi_signal_t sig);
-uvwasi_errno_t uvwasi_random_get(uvwasi_t* uvwasi, void* buf, size_t buf_len);
+uvwasi_errno_t uvwasi_random_get(uvwasi_t* uvwasi,
+                                 void* buf,
+                                 uvwasi_size_t buf_len);
 uvwasi_errno_t uvwasi_sched_yield(uvwasi_t* uvwasi);
 uvwasi_errno_t uvwasi_sock_recv(uvwasi_t* uvwasi,
                                 uvwasi_fd_t sock,
                                 const uvwasi_iovec_t* ri_data,
-                                size_t ri_data_len,
+                                uvwasi_size_t ri_data_len,
                                 uvwasi_riflags_t ri_flags,
-                                size_t* ro_datalen,
+                                uvwasi_size_t* ro_datalen,
                                 uvwasi_roflags_t* ro_flags);
 uvwasi_errno_t uvwasi_sock_send(uvwasi_t* uvwasi,
                                 uvwasi_fd_t sock,
                                 const uvwasi_ciovec_t* si_data,
-                                size_t si_data_len,
+                                uvwasi_size_t si_data_len,
                                 uvwasi_siflags_t si_flags,
-                                size_t* so_datalen);
+                                uvwasi_size_t* so_datalen);
 uvwasi_errno_t uvwasi_sock_shutdown(uvwasi_t* uvwasi,
                                     uvwasi_fd_t sock,
                                     uvwasi_sdflags_t how);
diff --git a/deps/uvwasi/include/wasi_serdes.h b/deps/uvwasi/include/wasi_serdes.h
new file mode 100644
index 00000000000000..f927b82bac9cbc
--- /dev/null
+++ b/deps/uvwasi/include/wasi_serdes.h
@@ -0,0 +1,145 @@
+#ifndef __UVWASI_SERDES_H__
+#define __UVWASI_SERDES_H__
+
+#include "wasi_types.h"
+
+/* Basic uint{8,16,32,64}_t read/write functions. */
+
+#define BASIC_TYPE_(name, type)                                               \
+  void uvwasi_serdes_write_##name(void* ptr, size_t offset, type value);      \
+  type uvwasi_serdes_read_##name(const void* ptr, size_t offset);             \
+
+#define BASIC_TYPE(type) BASIC_TYPE_(type, type)
+#define BASIC_TYPE_UVWASI(type) BASIC_TYPE_(type, uvwasi_##type)
+
+#define UVWASI_SERDES_SIZE_uint8_t sizeof(uint8_t)
+BASIC_TYPE(uint8_t)
+#define UVWASI_SERDES_SIZE_uint16_t sizeof(uint16_t)
+BASIC_TYPE(uint16_t)
+#define UVWASI_SERDES_SIZE_uint32_t sizeof(uint32_t)
+BASIC_TYPE(uint32_t)
+#define UVWASI_SERDES_SIZE_uint64_t sizeof(uint64_t)
+BASIC_TYPE(uint64_t)
+
+#define UVWASI_SERDES_SIZE_advice_t sizeof(uvwasi_advice_t)
+BASIC_TYPE_UVWASI(advice_t)
+#define UVWASI_SERDES_SIZE_clockid_t sizeof(uvwasi_clockid_t)
+BASIC_TYPE_UVWASI(clockid_t)
+#define UVWASI_SERDES_SIZE_device_t sizeof(uvwasi_device_t)
+BASIC_TYPE_UVWASI(device_t)
+#define UVWASI_SERDES_SIZE_dircookie_t sizeof(uvwasi_dircookie_t)
+BASIC_TYPE_UVWASI(dircookie_t)
+#define UVWASI_SERDES_SIZE_eventrwflags_t sizeof(uvwasi_eventrwflags_t)
+BASIC_TYPE_UVWASI(eventrwflags_t)
+#define UVWASI_SERDES_SIZE_eventtype_t sizeof(uvwasi_eventtype_t)
+BASIC_TYPE_UVWASI(eventtype_t)
+#define UVWASI_SERDES_SIZE_exitcode_t sizeof(uvwasi_exitcode_t)
+BASIC_TYPE_UVWASI(exitcode_t)
+#define UVWASI_SERDES_SIZE_fd_t sizeof(uvwasi_fd_t)
+BASIC_TYPE_UVWASI(fd_t)
+#define UVWASI_SERDES_SIZE_fdflags_t sizeof(uvwasi_fdflags_t)
+BASIC_TYPE_UVWASI(fdflags_t)
+#define UVWASI_SERDES_SIZE_filesize_t sizeof(uvwasi_filesize_t)
+BASIC_TYPE_UVWASI(filesize_t)
+#define UVWASI_SERDES_SIZE_fstflags_t sizeof(uvwasi_fstflags_t)
+BASIC_TYPE_UVWASI(fstflags_t)
+#define UVWASI_SERDES_SIZE_inode_t sizeof(uvwasi_inode_t)
+BASIC_TYPE_UVWASI(inode_t)
+#define UVWASI_SERDES_SIZE_linkcount_t sizeof(uvwasi_linkcount_t)
+BASIC_TYPE_UVWASI(linkcount_t)
+#define UVWASI_SERDES_SIZE_lookupflags_t sizeof(uvwasi_lookupflags_t)
+BASIC_TYPE_UVWASI(lookupflags_t)
+#define UVWASI_SERDES_SIZE_oflags_t sizeof(uvwasi_oflags_t)
+BASIC_TYPE_UVWASI(oflags_t)
+#define UVWASI_SERDES_SIZE_preopentype_t sizeof(uvwasi_preopentype_t)
+BASIC_TYPE_UVWASI(preopentype_t)
+#define UVWASI_SERDES_SIZE_riflags_t sizeof(uvwasi_riflags_t)
+BASIC_TYPE_UVWASI(riflags_t)
+#define UVWASI_SERDES_SIZE_rights_t sizeof(uvwasi_rights_t)
+BASIC_TYPE_UVWASI(rights_t)
+#define UVWASI_SERDES_SIZE_roflags_t sizeof(uvwasi_roflags_t)
+BASIC_TYPE_UVWASI(roflags_t)
+#define UVWASI_SERDES_SIZE_sdflags_t sizeof(uvwasi_sdflags_t)
+BASIC_TYPE_UVWASI(sdflags_t)
+#define UVWASI_SERDES_SIZE_siflags_t sizeof(uvwasi_siflags_t)
+BASIC_TYPE_UVWASI(siflags_t)
+#define UVWASI_SERDES_SIZE_size_t sizeof(uvwasi_size_t)
+BASIC_TYPE_UVWASI(size_t)
+#define UVWASI_SERDES_SIZE_inode_t sizeof(uvwasi_inode_t)
+BASIC_TYPE_UVWASI(inode_t)
+#define UVWASI_SERDES_SIZE_signal_t sizeof(uvwasi_signal_t)
+BASIC_TYPE_UVWASI(signal_t)
+#define UVWASI_SERDES_SIZE_subclockflags_t sizeof(uvwasi_subclockflags_t)
+BASIC_TYPE_UVWASI(subclockflags_t)
+#define UVWASI_SERDES_SIZE_timestamp_t sizeof(uvwasi_timestamp_t)
+BASIC_TYPE_UVWASI(timestamp_t)
+#define UVWASI_SERDES_SIZE_userdata_t sizeof(uvwasi_userdata_t)
+BASIC_TYPE_UVWASI(userdata_t)
+#define UVWASI_SERDES_SIZE_whence_t sizeof(uvwasi_whence_t)
+BASIC_TYPE_UVWASI(whence_t)
+
+#undef BASIC_TYPE_UVWASI
+#undef BASIC_TYPE
+#undef BASIC_TYPE_
+
+/* WASI structure read/write functions. */
+
+#define STRUCT(name)                                                          \
+  void uvwasi_serdes_write_##name(void* ptr,                                  \
+                                  size_t offset,                              \
+                                  const uvwasi_##name* value);                \
+  void uvwasi_serdes_read_##name(const void* ptr,                             \
+                                 size_t offset,                               \
+                                 uvwasi_##name* value);
+
+/* iovs currently only need to be read from WASM memory. */
+#define IOVS_STRUCT(name)                                                     \
+  uvwasi_errno_t uvwasi_serdes_read_##name(const void* ptr,                   \
+                                           size_t end,                        \
+                                           size_t offset,                     \
+                                           uvwasi_##name* value);
+
+#define UVWASI_SERDES_SIZE_ciovec_t 8
+IOVS_STRUCT(ciovec_t)
+
+#define UVWASI_SERDES_SIZE_iovec_t 8
+IOVS_STRUCT(iovec_t)
+
+#define UVWASI_SERDES_SIZE_fdstat_t 24
+STRUCT(fdstat_t)
+
+#define UVWASI_SERDES_SIZE_filestat_t 64
+STRUCT(filestat_t)
+
+#define UVWASI_SERDES_SIZE_prestat_t 8
+STRUCT(prestat_t)
+
+#define UVWASI_SERDES_SIZE_event_t 32
+STRUCT(event_t)
+
+#define UVWASI_SERDES_SIZE_subscription_t 48
+STRUCT(subscription_t)
+
+#undef STRUCT
+#undef IOVS_STRUCT
+
+uvwasi_errno_t uvwasi_serdes_readv_ciovec_t(const void* ptr,
+                                            size_t end,
+                                            size_t offset,
+                                            uvwasi_ciovec_t* iovs,
+                                            uvwasi_size_t iovs_len);
+
+uvwasi_errno_t uvwasi_serdes_readv_iovec_t(const void* ptr,
+                                           size_t end,
+                                           size_t offset,
+                                           uvwasi_iovec_t* iovs,
+                                           uvwasi_size_t iovs_len);
+
+/* Helper functions for memory bounds checking. */
+int uvwasi_serdes_check_bounds(size_t offset, size_t end, size_t size);
+int uvwasi_serdes_check_array_bounds(size_t offset,
+                                     size_t end,
+                                     size_t size,
+                                     size_t count);
+
+#endif /* __UVWASI_SERDES_H__ */
diff --git a/deps/uvwasi/include/wasi_types.h b/deps/uvwasi/include/wasi_types.h
index 2f93b412624c06..57c2dd2f3ce589 100644
--- a/deps/uvwasi/include/wasi_types.h
+++ b/deps/uvwasi/include/wasi_types.h
@@ -6,6 +6,8 @@
 
 /* API: https://github.com/WebAssembly/WASI/blob/master/phases/snapshot/docs.md */
 
+typedef uint32_t uvwasi_size_t;
+
 typedef uint8_t uvwasi_advice_t;
 #define UVWASI_ADVICE_NORMAL     0
 #define UVWASI_ADVICE_SEQUENTIAL 1
@@ -16,7 +18,7 @@ typedef uint8_t uvwasi_advice_t;
 
 typedef struct uvwasi_ciovec_s {
   const void* buf;
-  size_t buf_len;
+  uvwasi_size_t buf_len;
 } uvwasi_ciovec_t;
 
 typedef uint32_t uvwasi_clockid_t;
@@ -152,7 +154,7 @@ typedef uint64_t uvwasi_inode_t;
 
 typedef struct uvwasi_iovec_s {
   void* buf;
-  size_t buf_len;
+  uvwasi_size_t buf_len;
 } uvwasi_iovec_t;
 
 typedef uint64_t uvwasi_linkcount_t;
@@ -173,7 +175,7 @@ typedef struct uvwasi_prestat_s {
   uvwasi_preopentype_t pr_type;
   union uvwasi_prestat_u {
     struct uvwasi_prestat_dir_t {
-      size_t pr_name_len;
+      uvwasi_size_t pr_name_len;
     } dir;
   } u;
 } uvwasi_prestat_t;
diff --git a/deps/uvwasi/src/debug.h b/deps/uvwasi/src/debug.h
new file mode 100644
index 00000000000000..16bc2732ec90cd
--- /dev/null
+++ b/deps/uvwasi/src/debug.h
@@ -0,0 +1,13 @@
+#ifndef __UVWASI_DEBUG_H__
+#define __UVWASI_DEBUG_H__
+
+#ifdef UVWASI_DEBUG_LOG
+# define __STDC_FORMAT_MACROS
+# include <inttypes.h>
+# define DEBUG(fmt, ...)                                                      \
+    do { fprintf(stderr, fmt, __VA_ARGS__); } while (0)
+#else
+# define DEBUG(fmt, ...)
+#endif
+
+#endif /* __UVWASI_DEBUG_H__ */
diff --git a/deps/uvwasi/src/fd_table.c b/deps/uvwasi/src/fd_table.c
index 3d134e3b7e5e2e..877faf4ca19cd0 100644
--- a/deps/uvwasi/src/fd_table.c
+++ b/deps/uvwasi/src/fd_table.c
@@ -181,26 +181,25 @@ uvwasi_errno_t uvwasi_fd_table_init(uvwasi_t* uvwasi,
   if (uvwasi == NULL || options == NULL || options->fd_table_size < 3)
     return UVWASI_EINVAL;
 
-  table = &uvwasi->fds;
-  table->fds = NULL;
+  table = uvwasi__malloc(uvwasi, sizeof(*table));
+  if (table == NULL)
+    return UVWASI_ENOMEM;
+
   table->used = 0;
   table->size = options->fd_table_size;
   table->fds = uvwasi__calloc(uvwasi,
                               options->fd_table_size,
                               sizeof(struct uvwasi_fd_wrap_t*));
-
-  if (table->fds == NULL)
+  if (table->fds == NULL) {
+    uvwasi__free(uvwasi, table);
     return UVWASI_ENOMEM;
+  }
 
   r = uv_rwlock_init(&table->rwlock);
   if (r != 0) {
     err = uvwasi__translate_uv_error(r);
-    /* Free table->fds and set it to NULL here. This is done explicitly instead
-       of jumping to error_exit because uvwasi_fd_table_free() relies on fds
-       being NULL to know whether or not to destroy the rwlock.
-    */
     uvwasi__free(uvwasi, table->fds);
-    table->fds = NULL;
+    uvwasi__free(uvwasi, table);
     return err;
   }
 
@@ -217,6 +216,7 @@ uvwasi_errno_t uvwasi_fd_table_init(uvwasi_t* uvwasi,
   if (err != UVWASI_ESUCCESS)
     goto error_exit;
 
+  uvwasi->fds = table;
   return UVWASI_ESUCCESS;
 error_exit:
   uvwasi_fd_table_free(uvwasi, table);
@@ -228,12 +228,14 @@ 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)
+  if (uvwasi == NULL || table == NULL)
     return;
 
   for (i = 0; i < table->size; i++) {
     entry = table->fds[i];
-    if (entry == NULL) continue;
+
+    if (entry == NULL)
+      continue;
 
     uv_mutex_destroy(&entry->mutex);
     uvwasi__free(uvwasi, entry);
@@ -246,6 +248,8 @@ void uvwasi_fd_table_free(uvwasi_t* uvwasi, struct uvwasi_fd_table_t* table) {
     table->used = 0;
     uv_rwlock_destroy(&table->rwlock);
   }
+
+  uvwasi__free(uvwasi, table);
 }
 
 
diff --git a/deps/uvwasi/include/fd_table.h b/deps/uvwasi/src/fd_table.h
similarity index 100%
rename from deps/uvwasi/include/fd_table.h
rename to deps/uvwasi/src/fd_table.h
diff --git a/deps/uvwasi/src/path_resolver.c b/deps/uvwasi/src/path_resolver.c
index ee0e60f7e8f4ea..af13c1553ca874 100644
--- a/deps/uvwasi/src/path_resolver.c
+++ b/deps/uvwasi/src/path_resolver.c
@@ -15,7 +15,7 @@
 #endif /* _WIN32 */
 
 
-static int uvwasi__is_absolute_path(const char* path, size_t path_len) {
+static int uvwasi__is_absolute_path(const char* path, uvwasi_size_t path_len) {
   /* It's expected that only Unix style paths will be generated by WASI. */
   return path != NULL && path_len > 0 && path[0] == '/';
 }
@@ -33,9 +33,9 @@ static char* uvwasi__strchr_slash(const char* s) {
 
 
 uvwasi_errno_t uvwasi__normalize_path(const char* path,
-                                      size_t path_len,
+                                      uvwasi_size_t path_len,
                                       char* normalized_path,
-                                      size_t normalized_len) {
+                                      uvwasi_size_t normalized_len) {
   const char* cur;
   char* ptr;
   char* next;
@@ -125,9 +125,9 @@ uvwasi_errno_t uvwasi__normalize_path(const char* path,
 
 
 static int uvwasi__is_path_sandboxed(const char* path,
-                                     size_t path_len,
+                                     uvwasi_size_t path_len,
                                      const char* fd_path,
-                                     size_t fd_path_len) {
+                                     uvwasi_size_t fd_path_len) {
   char* ptr;
   int remaining_len;
 
@@ -173,9 +173,9 @@ static uvwasi_errno_t uvwasi__normalize_absolute_path(
                                               const uvwasi_t* uvwasi,
                                               const struct uvwasi_fd_wrap_t* fd,
                                               const char* path,
-                                              size_t path_len,
+                                              uvwasi_size_t path_len,
                                               char** normalized_path,
-                                              size_t* normalized_len
+                                              uvwasi_size_t* normalized_len
                                             ) {
   /* This function resolves an absolute path to the provided file descriptor.
      If the file descriptor's path is relative, then this operation will fail
@@ -224,9 +224,9 @@ static uvwasi_errno_t uvwasi__normalize_relative_path(
                                               const uvwasi_t* uvwasi,
                                               const struct uvwasi_fd_wrap_t* fd,
                                               const char* path,
-                                              size_t path_len,
+                                              uvwasi_size_t path_len,
                                               char** normalized_path,
-                                              size_t* normalized_len
+                                              uvwasi_size_t* normalized_len
                                             ) {
   /* This function resolves a relative path to the provided file descriptor.
      The relative path is concatenated to the file descriptor's path, and then
@@ -298,9 +298,9 @@ static uvwasi_errno_t uvwasi__resolve_path_to_host(
                                               const uvwasi_t* uvwasi,
                                               const struct uvwasi_fd_wrap_t* fd,
                                               const char* path,
-                                              size_t path_len,
+                                              uvwasi_size_t path_len,
                                               char** resolved_path,
-                                              size_t* resolved_len
+                                              uvwasi_size_t* resolved_len
                                             ) {
   /* Return the normalized path, but resolved to the host's real path. */
   char* res_path;
@@ -309,7 +309,7 @@ static uvwasi_errno_t uvwasi__resolve_path_to_host(
   int fake_path_len;
   int stripped_len;
 #ifdef _WIN32
-  size_t i;
+  uvwasi_size_t i;
 #endif /* _WIN32 */
 
   real_path_len = strlen(fd->real_path);
@@ -351,6 +351,7 @@ static uvwasi_errno_t uvwasi__resolve_path_to_host(
 
 #ifdef _WIN32
   /* Replace / with \ on Windows. */
+  res_path = *resolved_path;
   for (i = real_path_len; i < *resolved_len; i++) {
     if (res_path[i] == '/')
       res_path[i] = '\\';
@@ -364,8 +365,8 @@ static uvwasi_errno_t uvwasi__resolve_path_to_host(
 uvwasi_errno_t uvwasi__resolve_path(const uvwasi_t* uvwasi,
                                     const struct uvwasi_fd_wrap_t* fd,
                                     const char* path,
-                                    size_t path_len,
-                                    char* resolved_path,
+                                    uvwasi_size_t path_len,
+                                    char** resolved_path,
                                     uvwasi_lookupflags_t flags) {
   uv_fs_t req;
   uvwasi_errno_t err;
@@ -373,9 +374,9 @@ uvwasi_errno_t uvwasi__resolve_path(const uvwasi_t* uvwasi,
   char* host_path;
   char* normalized_path;
   char* link_target;
-  size_t input_len;
-  size_t host_path_len;
-  size_t normalized_len;
+  uvwasi_size_t input_len;
+  uvwasi_size_t host_path_len;
+  uvwasi_size_t normalized_len;
   int follow_count;
   int r;
 
@@ -418,14 +419,6 @@ uvwasi_errno_t uvwasi__resolve_path(const uvwasi_t* uvwasi,
   if (err != UVWASI_ESUCCESS)
     goto exit;
 
-  /* TODO(cjihrig): Currently performing a bounds check here. The TODO is to
-     stop allocating resolved_path in every caller and instead return the
-     path allocated in this function. */
-  if (host_path_len > PATH_MAX_BYTES) {
-    err = UVWASI_ENOBUFS;
-    goto exit;
-  }
-
   if ((flags & UVWASI_LOOKUP_SYMLINK_FOLLOW) == UVWASI_LOOKUP_SYMLINK_FOLLOW) {
     r = uv_fs_readlink(NULL, &req, host_path, NULL);
 
@@ -482,11 +475,14 @@ uvwasi_errno_t uvwasi__resolve_path(const uvwasi_t* uvwasi,
   }
 
 exit:
-  if (err == UVWASI_ESUCCESS)
-    memcpy(resolved_path, host_path, host_path_len + 1);
+  if (err == UVWASI_ESUCCESS) {
+    *resolved_path = host_path;
+  } else {
+    *resolved_path = NULL;
+    uvwasi__free(uvwasi, host_path);
+  }
 
   uvwasi__free(uvwasi, link_target);
   uvwasi__free(uvwasi, normalized_path);
-  uvwasi__free(uvwasi, host_path);
   return err;
 }
diff --git a/deps/uvwasi/src/path_resolver.h b/deps/uvwasi/src/path_resolver.h
index d5f95eafbfbf83..5040c69ac40cb7 100644
--- a/deps/uvwasi/src/path_resolver.h
+++ b/deps/uvwasi/src/path_resolver.h
@@ -1,28 +1,19 @@
 #ifndef __UVWASI_PATH_RESOLVER_H__
 #define __UVWASI_PATH_RESOLVER_H__
 
+#include "fd_table.h"
 #include "uvwasi.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 <limits.h>
-# define PATH_MAX_BYTES (PATH_MAX)
-#endif
-
 uvwasi_errno_t uvwasi__normalize_path(const char* path,
-                                      size_t path_len,
+                                      uvwasi_size_t path_len,
                                       char* normalized_path,
-                                      size_t normalized_len);
+                                      uvwasi_size_t normalized_len);
 
 uvwasi_errno_t uvwasi__resolve_path(const uvwasi_t* uvwasi,
                                     const struct uvwasi_fd_wrap_t* fd,
                                     const char* path,
-                                    size_t path_len,
-                                    char* resolved_path,
+                                    uvwasi_size_t path_len,
+                                    char** resolved_path,
                                     uvwasi_lookupflags_t flags);
 
 #endif /* __UVWASI_PATH_RESOLVER_H__ */
diff --git a/deps/uvwasi/src/poll_oneoff.c b/deps/uvwasi/src/poll_oneoff.c
new file mode 100644
index 00000000000000..97b8ef332da71f
--- /dev/null
+++ b/deps/uvwasi/src/poll_oneoff.c
@@ -0,0 +1,267 @@
+#include "uv.h"
+#include "poll_oneoff.h"
+#include "uv_mapping.h"
+#include "uvwasi_alloc.h"
+
+
+static void poll_cb(uv_poll_t* handle, int status, int events) {
+  struct uvwasi_poll_oneoff_state_t* state;
+  struct uvwasi__poll_fdevent_t* event;
+
+  uv_poll_stop(handle);
+  event = uv_handle_get_data((uv_handle_t*) handle);
+  event->revents = events;
+
+  if (status != 0)
+    event->error = UVWASI_EIO;
+
+  state = uv_loop_get_data(handle->loop);
+  state->result++;
+}
+
+
+static void timeout_cb(uv_timer_t* handle) {
+  struct uvwasi_poll_oneoff_state_t* state;
+  uvwasi_size_t i;
+
+  state = uv_loop_get_data(handle->loop);
+
+  for (i = 0; i < state->handle_cnt; i++)
+    uv_poll_stop(&state->poll_handles[i]);
+}
+
+
+uvwasi_errno_t uvwasi__poll_oneoff_state_init(
+                                      uvwasi_t* uvwasi,
+                                      struct uvwasi_poll_oneoff_state_t* state,
+                                      uvwasi_size_t max_fds
+                                    ) {
+  uvwasi_errno_t err;
+  int r;
+
+  if (uvwasi == NULL || state == NULL)
+    return UVWASI_EINVAL;
+
+  state->uvwasi = NULL;
+  state->timeout = 0;
+  state->has_timer = 0;
+  state->fdevents = NULL;
+  state->poll_handles = NULL;
+  state->max_fds = 0;
+  state->fdevent_cnt = 0;
+  state->handle_cnt = 0;
+  state->result = 0;
+
+  r = uv_loop_init(&state->loop);
+  if (r != 0)
+    return uvwasi__translate_uv_error(r);
+
+  if (max_fds > 0) {
+    state->fdevents = uvwasi__calloc(uvwasi,
+                                     max_fds,
+                                     sizeof(*state->fdevents));
+    if (state->fdevents == NULL) {
+      err = UVWASI_ENOMEM;
+      goto error_exit;
+    }
+
+    state->poll_handles = uvwasi__calloc(uvwasi,
+                                         max_fds,
+                                         sizeof(*state->poll_handles));
+    if (state->poll_handles == NULL) {
+      err = UVWASI_ENOMEM;
+      goto error_exit;
+    }
+  }
+
+  uv_loop_set_data(&state->loop, (void*) state);
+  state->uvwasi = uvwasi;
+  state->max_fds = max_fds;
+
+  return UVWASI_ESUCCESS;
+
+error_exit:
+  uv_loop_close(&state->loop);
+  uvwasi__free(state->uvwasi, state->fdevents);
+  uvwasi__free(state->uvwasi, state->poll_handles);
+  return err;
+}
+
+
+uvwasi_errno_t uvwasi__poll_oneoff_state_cleanup(
+                                        struct uvwasi_poll_oneoff_state_t* state
+                                      ) {
+  struct uvwasi__poll_fdevent_t* event;
+  uvwasi_size_t i;
+  int r;
+
+  if (state == NULL)
+    return UVWASI_EINVAL;
+
+  if (state->has_timer != 0) {
+    state->timeout = 0;
+    state->has_timer = 0;
+    uv_close((uv_handle_t*) &state->timer, NULL);
+  }
+
+  for (i = 0; i < state->fdevent_cnt; i++) {
+    event = &state->fdevents[i];
+
+    if (event->is_duplicate_fd == 0 && event->wrap != NULL)
+      uv_mutex_unlock(&event->wrap->mutex);
+  }
+
+  for (i = 0; i < state->handle_cnt; i++)
+    uv_close((uv_handle_t*) &state->poll_handles[i], NULL);
+
+  state->max_fds = 0;
+  state->fdevent_cnt = 0;
+  state->handle_cnt = 0;
+
+  uvwasi__free(state->uvwasi, state->fdevents);
+  uvwasi__free(state->uvwasi, state->poll_handles);
+  state->fdevents = NULL;
+  state->poll_handles = NULL;
+  state->uvwasi = NULL;
+
+  r = uv_loop_close(&state->loop);
+  if (r != 0)
+    return uvwasi__translate_uv_error(r);
+
+  return UVWASI_ESUCCESS;
+}
+
+
+uvwasi_errno_t uvwasi__poll_oneoff_state_set_timer(
+                                      struct uvwasi_poll_oneoff_state_t* state,
+                                      uvwasi_timestamp_t timeout
+                                    ) {
+  int r;
+
+  if (state == NULL)
+    return UVWASI_EINVAL;
+
+  r = uv_timer_init(&state->loop, &state->timer);
+  if (r != 0)
+    return uvwasi__translate_uv_error(r);
+
+  /* Convert WASI timeout from nanoseconds to milliseconds for libuv. */
+  state->timeout = timeout / 1000000;
+  state->has_timer = 1;
+  return UVWASI_ESUCCESS;
+}
+
+
+uvwasi_errno_t uvwasi__poll_oneoff_state_add_fdevent(
+                                      struct uvwasi_poll_oneoff_state_t* state,
+                                      uvwasi_subscription_t* subscription
+                                    ) {
+  struct uvwasi__poll_fdevent_t* event;
+  struct uvwasi__poll_fdevent_t* dup;
+  uv_poll_t* poll_handle;
+  uvwasi_eventtype_t type;
+  uvwasi_rights_t rights;
+  uvwasi_fd_t fd;
+  uvwasi_errno_t err;
+  uvwasi_size_t i;
+  int r;
+
+  if (state == NULL)
+    return UVWASI_EINVAL;
+
+  event = &state->fdevents[state->fdevent_cnt];
+  fd = subscription->u.fd_readwrite.fd;
+  type = subscription->type;
+
+  if (type == UVWASI_EVENTTYPE_FD_READ) {
+    event->events = UV_DISCONNECT | UV_READABLE;
+    rights = UVWASI_RIGHT_POLL_FD_READWRITE | UVWASI_RIGHT_FD_READ;
+  } else if (type == UVWASI_EVENTTYPE_FD_WRITE) {
+    event->events = UV_DISCONNECT | UV_WRITABLE;
+    rights = UVWASI_RIGHT_POLL_FD_READWRITE | UVWASI_RIGHT_FD_WRITE;
+  } else {
+    return UVWASI_EINVAL;
+  }
+
+  /* Check if the same file descriptor is already being polled. If so, use the
+     wrap and poll handle from the first descriptor. The reasons are that libuv
+     does not support polling the same fd more than once at the same time, and
+     uvwasi has the fd's mutex locked. */
+  event->is_duplicate_fd = 0;
+  for (i = 0; i < state->fdevent_cnt; i++) {
+    dup = &state->fdevents[i];
+    if (dup->wrap->id == fd) {
+      event->is_duplicate_fd = 1;
+      event->wrap = dup->wrap;
+      event->poll_handle = dup->poll_handle;
+      err = event->error;
+      goto poll_config_done;
+    }
+  }
+
+  /* Get the file descriptor. If UVWASI_EBADF is returned, continue on, but
+     don't do any polling with the handle. */
+  err = uvwasi_fd_table_get(state->uvwasi->fds, fd, &event->wrap, rights, 0);
+  if (err == UVWASI_EBADF)
+    event->wrap = NULL;
+  else if (err != UVWASI_ESUCCESS)
+    return err;
+
+  if (err == UVWASI_ESUCCESS) {
+    /* The fd is valid, so setup the poll handle. */
+    poll_handle = &state->poll_handles[state->handle_cnt];
+    r = uv_poll_init(&state->loop, poll_handle, event->wrap->fd);
+
+    if (r != 0) {
+      /* If uv_poll_init() fails (for example on Windows because only sockets
+         are supported), set the error for this event to UVWASI_EBADF, but don't
+         do any polling with the handle. */
+      uv_mutex_unlock(&event->wrap->mutex);
+      return uvwasi__translate_uv_error(r);
+    } else {
+      r = uv_poll_start(poll_handle,
+                        event->events,
+                        poll_cb);
+      if (r != 0) {
+        uv_mutex_unlock(&event->wrap->mutex);
+        uv_close((uv_handle_t*) poll_handle, NULL);
+        return uvwasi__translate_uv_error(r);
+      }
+
+      uv_handle_set_data((uv_handle_t*) poll_handle,
+                         (void*) &state->fdevents[state->fdevent_cnt]);
+      event->poll_handle = poll_handle;
+      state->handle_cnt++;
+    }
+  }
+
+poll_config_done:
+  event->type = type;
+  event->userdata = subscription->userdata;
+  event->error = err;
+  event->revents = 0;
+  state->fdevent_cnt++;
+  return UVWASI_ESUCCESS;
+}
+
+
+uvwasi_errno_t uvwasi__poll_oneoff_run(
+                                      struct uvwasi_poll_oneoff_state_t* state
+                                    ) {
+  int r;
+
+  if (state->has_timer == 1) {
+    r = uv_timer_start(&state->timer, timeout_cb, state->timeout, 0);
+    if (r != 0)
+      return uvwasi__translate_uv_error(r);
+
+    if (state->fdevent_cnt > 0)
+      uv_unref((uv_handle_t*) &state->timer);
+  }
+
+  r = uv_run(&state->loop, UV_RUN_DEFAULT);
+  if (r != 0)
+    return uvwasi__translate_uv_error(r);
+
+  return UVWASI_ESUCCESS;
+}
diff --git a/deps/uvwasi/src/poll_oneoff.h b/deps/uvwasi/src/poll_oneoff.h
new file mode 100644
index 00000000000000..64a315af1b334b
--- /dev/null
+++ b/deps/uvwasi/src/poll_oneoff.h
@@ -0,0 +1,60 @@
+#ifndef __UVWASI_POLL_ONEOFF_H__
+#define __UVWASI_POLL_ONEOFF_H__
+
+#include "fd_table.h"
+#include "wasi_types.h"
+
+struct uvwasi_s;
+
+struct uvwasi__poll_fdevent_t {
+  struct uvwasi_fd_wrap_t* wrap;
+  uvwasi_userdata_t userdata;
+  uvwasi_eventtype_t type;
+  uvwasi_errno_t error;
+  uv_poll_t* poll_handle;
+  int is_duplicate_fd;
+  int events;
+  int revents;
+};
+
+struct uvwasi_poll_oneoff_state_t {
+  struct uvwasi_s* uvwasi;
+  struct uvwasi__poll_fdevent_t* fdevents;
+  uv_poll_t* poll_handles;
+  uv_timer_t timer;
+  uint64_t timeout;
+  uv_loop_t loop;
+  uvwasi_size_t max_fds;
+  int has_timer;
+  uvwasi_size_t fdevent_cnt;
+  uvwasi_size_t handle_cnt;
+  int result;
+};
+
+
+uvwasi_errno_t uvwasi__poll_oneoff_state_init(
+                                      struct uvwasi_s* uvwasi,
+                                      struct uvwasi_poll_oneoff_state_t* state,
+                                      uvwasi_size_t max_fds
+                                    );
+
+uvwasi_errno_t uvwasi__poll_oneoff_state_cleanup(
+                                        struct uvwasi_poll_oneoff_state_t* state
+                                      );
+
+uvwasi_errno_t uvwasi__poll_oneoff_state_set_timer(
+                                      struct uvwasi_poll_oneoff_state_t* state,
+                                      uvwasi_timestamp_t timeout
+                                    );
+
+uvwasi_errno_t uvwasi__poll_oneoff_state_add_fdevent(
+                                      struct uvwasi_poll_oneoff_state_t* state,
+                                      uvwasi_subscription_t* subscription
+                                    );
+
+uvwasi_errno_t uvwasi__poll_oneoff_run(
+                                      struct uvwasi_poll_oneoff_state_t* state
+                                    );
+
+
+#endif /* __UVWASI_POLL_ONEOFF_H__ */
diff --git a/deps/uvwasi/src/uvwasi.c b/deps/uvwasi/src/uvwasi.c
index 0ee66be36a3951..fc8f0ee4844b9e 100644
--- a/deps/uvwasi/src/uvwasi.c
+++ b/deps/uvwasi/src/uvwasi.c
@@ -20,7 +20,9 @@
 #include "fd_table.h"
 #include "clocks.h"
 #include "path_resolver.h"
+#include "poll_oneoff.h"
 #include "wasi_rights.h"
+#include "debug.h"
 
 /* IBMi PASE does not support posix_fadvise() */
 #ifdef __PASE__
@@ -109,9 +111,9 @@ static uvwasi_errno_t uvwasi__lseek(uv_file fd,
 static uvwasi_errno_t uvwasi__setup_iovs(const uvwasi_t* uvwasi,
                                          uv_buf_t** buffers,
                                          const uvwasi_iovec_t* iovs,
-                                         size_t iovs_len) {
+                                         uvwasi_size_t iovs_len) {
   uv_buf_t* bufs;
-  size_t i;
+  uvwasi_size_t i;
 
   if ((iovs_len * sizeof(*bufs)) / (sizeof(*bufs)) != iovs_len)
     return UVWASI_ENOMEM;
@@ -131,9 +133,9 @@ static uvwasi_errno_t uvwasi__setup_iovs(const uvwasi_t* uvwasi,
 static uvwasi_errno_t uvwasi__setup_ciovs(const uvwasi_t* uvwasi,
                                           uv_buf_t** buffers,
                                           const uvwasi_ciovec_t* iovs,
-                                          size_t iovs_len) {
+                                          uvwasi_size_t iovs_len) {
   uv_buf_t* bufs;
-  size_t i;
+  uvwasi_size_t i;
 
   if ((iovs_len * sizeof(*bufs)) / (sizeof(*bufs)) != iovs_len)
     return UVWASI_ENOMEM;
@@ -154,12 +156,12 @@ uvwasi_errno_t uvwasi_init(uvwasi_t* uvwasi, uvwasi_options_t* options) {
   uv_fs_t realpath_req;
   uv_fs_t open_req;
   uvwasi_errno_t err;
-  size_t args_size;
-  size_t size;
-  size_t offset;
-  size_t env_count;
-  size_t env_buf_size;
-  size_t i;
+  uvwasi_size_t args_size;
+  uvwasi_size_t size;
+  uvwasi_size_t offset;
+  uvwasi_size_t env_count;
+  uvwasi_size_t env_buf_size;
+  uvwasi_size_t i;
   int r;
 
   if (uvwasi == NULL || options == NULL || options->fd_table_size == 0)
@@ -173,7 +175,7 @@ uvwasi_errno_t uvwasi_init(uvwasi_t* uvwasi, uvwasi_options_t* options) {
   uvwasi->argv = NULL;
   uvwasi->env_buf = NULL;
   uvwasi->env = NULL;
-  uvwasi->fds.fds = NULL;
+  uvwasi->fds = NULL;
 
   args_size = 0;
   for (i = 0; i < options->argc; ++i)
@@ -270,7 +272,7 @@ uvwasi_errno_t uvwasi_init(uvwasi_t* uvwasi, uvwasi_options_t* options) {
     }
 
     err = uvwasi_fd_table_insert_preopen(uvwasi,
-                                         &uvwasi->fds,
+                                         uvwasi->fds,
                                          open_req.result,
                                          options->preopens[i].mapped_path,
                                          realpath_req.ptr);
@@ -293,11 +295,12 @@ void uvwasi_destroy(uvwasi_t* uvwasi) {
   if (uvwasi == NULL)
     return;
 
-  uvwasi_fd_table_free(uvwasi, &uvwasi->fds);
+  uvwasi_fd_table_free(uvwasi, uvwasi->fds);
   uvwasi__free(uvwasi, uvwasi->argv_buf);
   uvwasi__free(uvwasi, uvwasi->argv);
   uvwasi__free(uvwasi, uvwasi->env_buf);
   uvwasi__free(uvwasi, uvwasi->env);
+  uvwasi->fds = NULL;
   uvwasi->argv_buf = NULL;
   uvwasi->argv = NULL;
   uvwasi->env_buf = NULL;
@@ -314,7 +317,7 @@ uvwasi_errno_t uvwasi_embedder_remap_fd(uvwasi_t* uvwasi,
   if (uvwasi == NULL)
     return UVWASI_EINVAL;
 
-  err = uvwasi_fd_table_get(&uvwasi->fds, fd, &wrap, 0, 0);
+  err = uvwasi_fd_table_get(uvwasi->fds, fd, &wrap, 0, 0);
   if (err != UVWASI_ESUCCESS)
     return err;
 
@@ -325,7 +328,12 @@ uvwasi_errno_t uvwasi_embedder_remap_fd(uvwasi_t* uvwasi,
 
 
 uvwasi_errno_t uvwasi_args_get(uvwasi_t* uvwasi, char** argv, char* argv_buf) {
-  size_t i;
+  uvwasi_size_t i;
+
+  DEBUG("uvwasi_args_get(uvwasi=%p, argv=%p, argv_buf=%p)\n",
+        uvwasi,
+        argv,
+        argv_buf);
 
   if (uvwasi == NULL || argv == NULL || argv_buf == NULL)
     return UVWASI_EINVAL;
@@ -340,8 +348,13 @@ uvwasi_errno_t uvwasi_args_get(uvwasi_t* uvwasi, char** argv, char* argv_buf) {
 
 
 uvwasi_errno_t uvwasi_args_sizes_get(uvwasi_t* uvwasi,
-                                     size_t* argc,
-                                     size_t* argv_buf_size) {
+                                     uvwasi_size_t* argc,
+                                     uvwasi_size_t* argv_buf_size) {
+  DEBUG("uvwasi_args_sizes_get(uvwasi=%p, argc=%p, argv_buf_size=%p)\n",
+        uvwasi,
+        argc,
+        argv_buf_size);
+
   if (uvwasi == NULL || argc == NULL || argv_buf_size == NULL)
     return UVWASI_EINVAL;
 
@@ -354,6 +367,11 @@ uvwasi_errno_t uvwasi_args_sizes_get(uvwasi_t* uvwasi,
 uvwasi_errno_t uvwasi_clock_res_get(uvwasi_t* uvwasi,
                                     uvwasi_clockid_t clock_id,
                                     uvwasi_timestamp_t* resolution) {
+  DEBUG("uvwasi_clock_res_get(uvwasi=%p, clock_id=%d, resolution=%p)\n",
+        uvwasi,
+        clock_id,
+        resolution);
+
   if (uvwasi == NULL || resolution == NULL)
     return UVWASI_EINVAL;
 
@@ -376,6 +394,13 @@ uvwasi_errno_t uvwasi_clock_time_get(uvwasi_t* uvwasi,
                                      uvwasi_clockid_t clock_id,
                                      uvwasi_timestamp_t precision,
                                      uvwasi_timestamp_t* time) {
+  DEBUG("uvwasi_clock_time_get(uvwasi=%p, clock_id=%d, "
+        "precision=%"PRIu64", time=%p)\n",
+        uvwasi,
+        clock_id,
+        precision,
+        time);
+
   if (uvwasi == NULL || time == NULL)
     return UVWASI_EINVAL;
 
@@ -398,7 +423,12 @@ uvwasi_errno_t uvwasi_clock_time_get(uvwasi_t* uvwasi,
 uvwasi_errno_t uvwasi_environ_get(uvwasi_t* uvwasi,
                                   char** environment,
                                   char* environ_buf) {
-  size_t i;
+  uvwasi_size_t i;
+
+  DEBUG("uvwasi_environ_get(uvwasi=%p, environment=%p, environ_buf=%p)\n",
+        uvwasi,
+        environment,
+        environ_buf);
 
   if (uvwasi == NULL || environment == NULL || environ_buf == NULL)
     return UVWASI_EINVAL;
@@ -413,8 +443,14 @@ uvwasi_errno_t uvwasi_environ_get(uvwasi_t* uvwasi,
 
 
 uvwasi_errno_t uvwasi_environ_sizes_get(uvwasi_t* uvwasi,
-                                        size_t* environ_count,
-                                        size_t* environ_buf_size) {
+                                        uvwasi_size_t* environ_count,
+                                        uvwasi_size_t* environ_buf_size) {
+  DEBUG("uvwasi_environ_sizes_get(uvwasi=%p, environ_count=%p, "
+        "environ_buf_size=%p)\n",
+        uvwasi,
+        environ_count,
+        environ_buf_size);
+
   if (uvwasi == NULL || environ_count == NULL || environ_buf_size == NULL)
     return UVWASI_EINVAL;
 
@@ -436,6 +472,14 @@ uvwasi_errno_t uvwasi_fd_advise(uvwasi_t* uvwasi,
   int r;
 #endif /* POSIX_FADV_NORMAL */
 
+  DEBUG("uvwasi_fd_advise(uvwasi=%p, fd=%d, offset=%"PRIu64", len=%"PRIu64", "
+        "advice=%d)\n",
+        uvwasi,
+        fd,
+        offset,
+        len,
+        advice);
+
   if (uvwasi == NULL)
     return UVWASI_EINVAL;
 
@@ -474,7 +518,7 @@ uvwasi_errno_t uvwasi_fd_advise(uvwasi_t* uvwasi,
       return UVWASI_EINVAL;
   }
 
-  err = uvwasi_fd_table_get(&uvwasi->fds, fd, &wrap, UVWASI_RIGHT_FD_ADVISE, 0);
+  err = uvwasi_fd_table_get(uvwasi->fds, fd, &wrap, UVWASI_RIGHT_FD_ADVISE, 0);
   if (err != UVWASI_ESUCCESS)
     return err;
 
@@ -502,10 +546,17 @@ uvwasi_errno_t uvwasi_fd_allocate(uvwasi_t* uvwasi,
   uvwasi_errno_t err;
   int r;
 
+  DEBUG("uvwasi_fd_allocate(uvwasi=%p, fd=%d, offset=%"PRIu64", "
+        "len=%"PRIu64")\n",
+        uvwasi,
+        fd,
+        offset,
+        len);
+
   if (uvwasi == NULL)
     return UVWASI_EINVAL;
 
-  err = uvwasi_fd_table_get(&uvwasi->fds,
+  err = uvwasi_fd_table_get(uvwasi->fds,
                             fd,
                             &wrap,
                             UVWASI_RIGHT_FD_ALLOCATE,
@@ -552,12 +603,14 @@ uvwasi_errno_t uvwasi_fd_close(uvwasi_t* uvwasi, uvwasi_fd_t fd) {
   uv_fs_t req;
   int r;
 
+  DEBUG("uvwasi_fd_close(uvwasi=%p, fd=%d)\n", uvwasi, fd);
+
   if (uvwasi == NULL)
     return UVWASI_EINVAL;
 
-  uvwasi_fd_table_lock(&uvwasi->fds);
+  uvwasi_fd_table_lock(uvwasi->fds);
 
-  err = uvwasi_fd_table_get_nolock(&uvwasi->fds, fd, &wrap, 0, 0);
+  err = uvwasi_fd_table_get_nolock(uvwasi->fds, fd, &wrap, 0, 0);
   if (err != UVWASI_ESUCCESS)
     goto exit;
 
@@ -570,10 +623,10 @@ uvwasi_errno_t uvwasi_fd_close(uvwasi_t* uvwasi, uvwasi_fd_t fd) {
     goto exit;
   }
 
-  err = uvwasi_fd_table_remove_nolock(uvwasi, &uvwasi->fds, fd);
+  err = uvwasi_fd_table_remove_nolock(uvwasi, uvwasi->fds, fd);
 
 exit:
-  uvwasi_fd_table_unlock(&uvwasi->fds);
+  uvwasi_fd_table_unlock(uvwasi->fds);
   return err;
 }
 
@@ -584,10 +637,12 @@ uvwasi_errno_t uvwasi_fd_datasync(uvwasi_t* uvwasi, uvwasi_fd_t fd) {
   uv_fs_t req;
   int r;
 
+  DEBUG("uvwasi_fd_datasync(uvwasi=%p, fd=%d)\n", uvwasi, fd);
+
   if (uvwasi == NULL)
     return UVWASI_EINVAL;
 
-  err = uvwasi_fd_table_get(&uvwasi->fds,
+  err = uvwasi_fd_table_get(uvwasi->fds,
                             fd,
                             &wrap,
                             UVWASI_RIGHT_FD_DATASYNC,
@@ -615,10 +670,12 @@ uvwasi_errno_t uvwasi_fd_fdstat_get(uvwasi_t* uvwasi,
   int r;
 #endif
 
+  DEBUG("uvwasi_fd_fdstat_get(uvwasi=%p, fd=%d, buf=%p)\n", uvwasi, fd, buf);
+
   if (uvwasi == NULL || buf == NULL)
     return UVWASI_EINVAL;
 
-  err = uvwasi_fd_table_get(&uvwasi->fds, fd, &wrap, 0, 0);
+  err = uvwasi_fd_table_get(uvwasi->fds, fd, &wrap, 0, 0);
   if (err != UVWASI_ESUCCESS)
     return err;
 
@@ -646,7 +703,12 @@ uvwasi_errno_t uvwasi_fd_fdstat_set_flags(uvwasi_t* uvwasi,
                                           uvwasi_fd_t fd,
                                           uvwasi_fdflags_t flags) {
 #ifdef _WIN32
-  /* TODO(cjihrig): Missing Windows support. */
+  DEBUG("uvwasi_fd_fdstat_set_flags(uvwasi=%p, fd=%d, flags=%d)\n",
+        uvwasi,
+        fd,
+        flags);
+
+  /* TODO(cjihrig): Windows is not supported. */
   return UVWASI_ENOSYS;
 #else
   struct uvwasi_fd_wrap_t* wrap;
@@ -654,10 +716,15 @@ uvwasi_errno_t uvwasi_fd_fdstat_set_flags(uvwasi_t* uvwasi,
   int mapped_flags;
   int r;
 
+  DEBUG("uvwasi_fd_fdstat_set_flags(uvwasi=%p, fd=%d, flags=%d)\n",
+        uvwasi,
+        fd,
+        flags);
+
   if (uvwasi == NULL)
     return UVWASI_EINVAL;
 
-  err = uvwasi_fd_table_get(&uvwasi->fds,
+  err = uvwasi_fd_table_get(uvwasi->fds,
                             fd,
                             &wrap,
                             UVWASI_RIGHT_FD_FDSTAT_SET_FLAGS,
@@ -710,10 +777,17 @@ uvwasi_errno_t uvwasi_fd_fdstat_set_rights(uvwasi_t* uvwasi,
   struct uvwasi_fd_wrap_t* wrap;
   uvwasi_errno_t err;
 
+  DEBUG("uvwasi_fd_fdstat_set_rights(uvwasi=%p, fd=%d, "
+        "fs_rights_base=%"PRIu64", fs_rights_inheriting=%"PRIu64")\n",
+        uvwasi,
+        fd,
+        fs_rights_base,
+        fs_rights_inheriting);
+
   if (uvwasi == NULL)
     return UVWASI_EINVAL;
 
-  err = uvwasi_fd_table_get(&uvwasi->fds, fd, &wrap, 0, 0);
+  err = uvwasi_fd_table_get(uvwasi->fds, fd, &wrap, 0, 0);
   if (err != UVWASI_ESUCCESS)
     return err;
 
@@ -746,10 +820,12 @@ uvwasi_errno_t uvwasi_fd_filestat_get(uvwasi_t* uvwasi,
   uvwasi_errno_t err;
   int r;
 
+  DEBUG("uvwasi_fd_filestat_get(uvwasi=%p, fd=%d, buf=%p)\n", uvwasi, fd, buf);
+
   if (uvwasi == NULL || buf == NULL)
     return UVWASI_EINVAL;
 
-  err = uvwasi_fd_table_get(&uvwasi->fds,
+  err = uvwasi_fd_table_get(uvwasi->fds,
                             fd,
                             &wrap,
                             UVWASI_RIGHT_FD_FILESTAT_GET,
@@ -781,10 +857,15 @@ uvwasi_errno_t uvwasi_fd_filestat_set_size(uvwasi_t* uvwasi,
   uvwasi_errno_t err;
   int r;
 
+  DEBUG("uvwasi_fd_filestat_set_size(uvwasi=%p, fd=%d, st_size=%"PRIu64")\n",
+        uvwasi,
+        fd,
+        st_size);
+
   if (uvwasi == NULL)
     return UVWASI_EINVAL;
 
-  err = uvwasi_fd_table_get(&uvwasi->fds,
+  err = uvwasi_fd_table_get(uvwasi->fds,
                             fd,
                             &wrap,
                             UVWASI_RIGHT_FD_FILESTAT_SET_SIZE,
@@ -814,6 +895,14 @@ uvwasi_errno_t uvwasi_fd_filestat_set_times(uvwasi_t* uvwasi,
   uvwasi_errno_t err;
   int r;
 
+  DEBUG("uvwasi_fd_filestat_set_times(uvwasi=%p, fd=%d, st_atim=%"PRIu64", "
+        "st_mtim=%"PRIu64", fst_flags=%d)\n",
+        uvwasi,
+        fd,
+        st_atim,
+        st_mtim,
+        fst_flags);
+
   if (uvwasi == NULL)
     return UVWASI_EINVAL;
 
@@ -822,7 +911,7 @@ uvwasi_errno_t uvwasi_fd_filestat_set_times(uvwasi_t* uvwasi,
     return UVWASI_EINVAL;
   }
 
-  err = uvwasi_fd_table_get(&uvwasi->fds,
+  err = uvwasi_fd_table_get(uvwasi->fds,
                             fd,
                             &wrap,
                             UVWASI_RIGHT_FD_FILESTAT_SET_TIMES,
@@ -845,9 +934,9 @@ uvwasi_errno_t uvwasi_fd_filestat_set_times(uvwasi_t* uvwasi,
 uvwasi_errno_t uvwasi_fd_pread(uvwasi_t* uvwasi,
                                uvwasi_fd_t fd,
                                const uvwasi_iovec_t* iovs,
-                               size_t iovs_len,
+                               uvwasi_size_t iovs_len,
                                uvwasi_filesize_t offset,
-                               size_t* nread) {
+                               uvwasi_size_t* nread) {
   struct uvwasi_fd_wrap_t* wrap;
   uv_buf_t* bufs;
   uv_fs_t req;
@@ -855,10 +944,19 @@ uvwasi_errno_t uvwasi_fd_pread(uvwasi_t* uvwasi,
   size_t uvread;
   int r;
 
+  DEBUG("uvwasi_fd_pread(uvwasi=%p, fd=%d, iovs=%p, iovs_len=%zu, "
+        "offset=%"PRIu64", nread=%p)\n",
+        uvwasi,
+        fd,
+        iovs,
+        iovs_len,
+        offset,
+        nread);
+
   if (uvwasi == NULL || iovs == NULL || nread == NULL)
     return UVWASI_EINVAL;
 
-  err = uvwasi_fd_table_get(&uvwasi->fds,
+  err = uvwasi_fd_table_get(uvwasi->fds,
                             fd,
                             &wrap,
                             UVWASI_RIGHT_FD_READ | UVWASI_RIGHT_FD_SEEK,
@@ -881,7 +979,7 @@ uvwasi_errno_t uvwasi_fd_pread(uvwasi_t* uvwasi,
   if (r < 0)
     return uvwasi__translate_uv_error(r);
 
-  *nread = uvread;
+  *nread = (uvwasi_size_t) uvread;
   return UVWASI_ESUCCESS;
 }
 
@@ -892,10 +990,15 @@ uvwasi_errno_t uvwasi_fd_prestat_get(uvwasi_t* uvwasi,
   struct uvwasi_fd_wrap_t* wrap;
   uvwasi_errno_t err;
 
+  DEBUG("uvwasi_fd_prestat_get(uvwasi=%p, fd=%d, buf=%p)\n",
+        uvwasi,
+        fd,
+        buf);
+
   if (uvwasi == NULL || buf == NULL)
     return UVWASI_EINVAL;
 
-  err = uvwasi_fd_table_get(&uvwasi->fds, fd, &wrap, 0, 0);
+  err = uvwasi_fd_table_get(uvwasi->fds, fd, &wrap, 0, 0);
   if (err != UVWASI_ESUCCESS)
     return err;
   if (wrap->preopen != 1) {
@@ -915,15 +1018,21 @@ uvwasi_errno_t uvwasi_fd_prestat_get(uvwasi_t* uvwasi,
 uvwasi_errno_t uvwasi_fd_prestat_dir_name(uvwasi_t* uvwasi,
                                           uvwasi_fd_t fd,
                                           char* path,
-                                          size_t path_len) {
+                                          uvwasi_size_t path_len) {
   struct uvwasi_fd_wrap_t* wrap;
   uvwasi_errno_t err;
   size_t size;
 
+  DEBUG("uvwasi_fd_prestat_dir_name(uvwasi=%p, fd=%d, path=%p, path_len=%zu)\n",
+        uvwasi,
+        fd,
+        path,
+        path_len);
+
   if (uvwasi == NULL || path == NULL)
     return UVWASI_EINVAL;
 
-  err = uvwasi_fd_table_get(&uvwasi->fds, fd, &wrap, 0, 0);
+  err = uvwasi_fd_table_get(uvwasi->fds, fd, &wrap, 0, 0);
   if (err != UVWASI_ESUCCESS)
     return err;
   if (wrap->preopen != 1) {
@@ -932,7 +1041,7 @@ uvwasi_errno_t uvwasi_fd_prestat_dir_name(uvwasi_t* uvwasi,
   }
 
   size = strlen(wrap->path) + 1;
-  if (size > path_len) {
+  if (size > (size_t) path_len) {
     err = UVWASI_ENOBUFS;
     goto exit;
   }
@@ -948,9 +1057,9 @@ uvwasi_errno_t uvwasi_fd_prestat_dir_name(uvwasi_t* uvwasi,
 uvwasi_errno_t uvwasi_fd_pwrite(uvwasi_t* uvwasi,
                                 uvwasi_fd_t fd,
                                 const uvwasi_ciovec_t* iovs,
-                                size_t iovs_len,
+                                uvwasi_size_t iovs_len,
                                 uvwasi_filesize_t offset,
-                                size_t* nwritten) {
+                                uvwasi_size_t* nwritten) {
   struct uvwasi_fd_wrap_t* wrap;
   uv_buf_t* bufs;
   uv_fs_t req;
@@ -958,10 +1067,19 @@ uvwasi_errno_t uvwasi_fd_pwrite(uvwasi_t* uvwasi,
   size_t uvwritten;
   int r;
 
+  DEBUG("uvwasi_fd_pwrite(uvwasi=%p, fd=%d, iovs=%p, iovs_len=%zu, "
+        "offset=%"PRIu64", nwritten=%p)\n",
+        uvwasi,
+        fd,
+        iovs,
+        iovs_len,
+        offset,
+        nwritten);
+
   if (uvwasi == NULL || iovs == NULL || nwritten == NULL)
     return UVWASI_EINVAL;
 
-  err = uvwasi_fd_table_get(&uvwasi->fds,
+  err = uvwasi_fd_table_get(uvwasi->fds,
                             fd,
                             &wrap,
                             UVWASI_RIGHT_FD_WRITE | UVWASI_RIGHT_FD_SEEK,
@@ -984,7 +1102,7 @@ uvwasi_errno_t uvwasi_fd_pwrite(uvwasi_t* uvwasi,
   if (r < 0)
     return uvwasi__translate_uv_error(r);
 
-  *nwritten = uvwritten;
+  *nwritten = (uvwasi_size_t) uvwritten;
   return UVWASI_ESUCCESS;
 }
 
@@ -992,8 +1110,8 @@ uvwasi_errno_t uvwasi_fd_pwrite(uvwasi_t* uvwasi,
 uvwasi_errno_t uvwasi_fd_read(uvwasi_t* uvwasi,
                               uvwasi_fd_t fd,
                               const uvwasi_iovec_t* iovs,
-                              size_t iovs_len,
-                              size_t* nread) {
+                              uvwasi_size_t iovs_len,
+                              uvwasi_size_t* nread) {
   struct uvwasi_fd_wrap_t* wrap;
   uv_buf_t* bufs;
   uv_fs_t req;
@@ -1001,10 +1119,17 @@ uvwasi_errno_t uvwasi_fd_read(uvwasi_t* uvwasi,
   size_t uvread;
   int r;
 
+  DEBUG("uvwasi_fd_read(uvwasi=%p, fd=%d, iovs=%p, iovs_len=%zu, nread=%p)\n",
+        uvwasi,
+        fd,
+        iovs,
+        iovs_len,
+        nread);
+
   if (uvwasi == NULL || iovs == NULL || nread == NULL)
     return UVWASI_EINVAL;
 
-  err = uvwasi_fd_table_get(&uvwasi->fds, fd, &wrap, UVWASI_RIGHT_FD_READ, 0);
+  err = uvwasi_fd_table_get(uvwasi->fds, fd, &wrap, UVWASI_RIGHT_FD_READ, 0);
   if (err != UVWASI_ESUCCESS)
     return err;
 
@@ -1023,7 +1148,7 @@ uvwasi_errno_t uvwasi_fd_read(uvwasi_t* uvwasi,
   if (r < 0)
     return uvwasi__translate_uv_error(r);
 
-  *nread = uvread;
+  *nread = (uvwasi_size_t) uvread;
   return UVWASI_ESUCCESS;
 }
 
@@ -1031,9 +1156,9 @@ uvwasi_errno_t uvwasi_fd_read(uvwasi_t* uvwasi,
 uvwasi_errno_t uvwasi_fd_readdir(uvwasi_t* uvwasi,
                                  uvwasi_fd_t fd,
                                  void* buf,
-                                 size_t buf_len,
+                                 uvwasi_size_t buf_len,
                                  uvwasi_dircookie_t cookie,
-                                 size_t* bufused) {
+                                 uvwasi_size_t* bufused) {
   /* TODO(cjihrig): Support Windows where seekdir() and telldir() are used. */
   /* TODO(cjihrig): Avoid opening and closing the directory on each call. */
   struct uvwasi_fd_wrap_t* wrap;
@@ -1049,10 +1174,19 @@ uvwasi_errno_t uvwasi_fd_readdir(uvwasi_t* uvwasi,
   int i;
   int r;
 
+  DEBUG("uvwasi_fd_readdir(uvwasi=%p, fd=%d, buf=%p, buf_len=%zu, "
+        "cookie=%"PRIu64", bufused=%p)\n",
+        uvwasi,
+        fd,
+        buf,
+        buf_len,
+        cookie,
+        bufused);
+
   if (uvwasi == NULL || buf == NULL || bufused == NULL)
     return UVWASI_EINVAL;
 
-  err = uvwasi_fd_table_get(&uvwasi->fds,
+  err = uvwasi_fd_table_get(uvwasi->fds,
                             fd,
                             &wrap,
                             UVWASI_RIGHT_FD_READDIR,
@@ -1171,10 +1305,12 @@ uvwasi_errno_t uvwasi_fd_readdir(uvwasi_t* uvwasi,
 uvwasi_errno_t uvwasi_fd_renumber(uvwasi_t* uvwasi,
                                   uvwasi_fd_t from,
                                   uvwasi_fd_t to) {
+  DEBUG("uvwasi_fd_renumber(uvwasi=%p, from=%d, to=%d)\n", uvwasi, from, to);
+
   if (uvwasi == NULL)
     return UVWASI_EINVAL;
 
-  return uvwasi_fd_table_renumber(uvwasi, &uvwasi->fds, to, from);
+  return uvwasi_fd_table_renumber(uvwasi, uvwasi->fds, to, from);
 }
 
 
@@ -1186,10 +1322,18 @@ uvwasi_errno_t uvwasi_fd_seek(uvwasi_t* uvwasi,
   struct uvwasi_fd_wrap_t* wrap;
   uvwasi_errno_t err;
 
+  DEBUG("uvwasi_fd_seek(uvwasi=%p, fd=%d, offset=%"PRId64", "
+        "whence=%d, newoffset=%p)\n",
+        uvwasi,
+        fd,
+        offset,
+        whence,
+        newoffset);
+
   if (uvwasi == NULL || newoffset == NULL)
     return UVWASI_EINVAL;
 
-  err = uvwasi_fd_table_get(&uvwasi->fds, fd, &wrap, UVWASI_RIGHT_FD_SEEK, 0);
+  err = uvwasi_fd_table_get(uvwasi->fds, fd, &wrap, UVWASI_RIGHT_FD_SEEK, 0);
   if (err != UVWASI_ESUCCESS)
     return err;
 
@@ -1205,10 +1349,12 @@ uvwasi_errno_t uvwasi_fd_sync(uvwasi_t* uvwasi, uvwasi_fd_t fd) {
   uvwasi_errno_t err;
   int r;
 
+  DEBUG("uvwasi_fd_sync(uvwasi=%p, fd=%d)\n", uvwasi, fd);
+
   if (uvwasi == NULL)
     return UVWASI_EINVAL;
 
-  err = uvwasi_fd_table_get(&uvwasi->fds,
+  err = uvwasi_fd_table_get(uvwasi->fds,
                             fd,
                             &wrap,
                             UVWASI_RIGHT_FD_SYNC,
@@ -1233,10 +1379,12 @@ uvwasi_errno_t uvwasi_fd_tell(uvwasi_t* uvwasi,
   struct uvwasi_fd_wrap_t* wrap;
   uvwasi_errno_t err;
 
+  DEBUG("uvwasi_fd_tell(uvwasi=%p, fd=%d, offset=%p)\n", uvwasi, fd, offset);
+
   if (uvwasi == NULL || offset == NULL)
     return UVWASI_EINVAL;
 
-  err = uvwasi_fd_table_get(&uvwasi->fds, fd, &wrap, UVWASI_RIGHT_FD_TELL, 0);
+  err = uvwasi_fd_table_get(uvwasi->fds, fd, &wrap, UVWASI_RIGHT_FD_TELL, 0);
   if (err != UVWASI_ESUCCESS)
     return err;
 
@@ -1249,8 +1397,8 @@ uvwasi_errno_t uvwasi_fd_tell(uvwasi_t* uvwasi,
 uvwasi_errno_t uvwasi_fd_write(uvwasi_t* uvwasi,
                                uvwasi_fd_t fd,
                                const uvwasi_ciovec_t* iovs,
-                               size_t iovs_len,
-                               size_t* nwritten) {
+                               uvwasi_size_t iovs_len,
+                               uvwasi_size_t* nwritten) {
   struct uvwasi_fd_wrap_t* wrap;
   uv_buf_t* bufs;
   uv_fs_t req;
@@ -1258,10 +1406,18 @@ uvwasi_errno_t uvwasi_fd_write(uvwasi_t* uvwasi,
   size_t uvwritten;
   int r;
 
+  DEBUG("uvwasi_fd_write(uvwasi=%p, fd=%d, iovs=%p, iovs_len=%zu, "
+        "nwritten=%p)\n",
+        uvwasi,
+        fd,
+        iovs,
+        iovs_len,
+        nwritten);
+
   if (uvwasi == NULL || iovs == NULL || nwritten == NULL)
     return UVWASI_EINVAL;
 
-  err = uvwasi_fd_table_get(&uvwasi->fds, fd, &wrap, UVWASI_RIGHT_FD_WRITE, 0);
+  err = uvwasi_fd_table_get(uvwasi->fds, fd, &wrap, UVWASI_RIGHT_FD_WRITE, 0);
   if (err != UVWASI_ESUCCESS)
     return err;
 
@@ -1280,7 +1436,7 @@ uvwasi_errno_t uvwasi_fd_write(uvwasi_t* uvwasi,
   if (r < 0)
     return uvwasi__translate_uv_error(r);
 
-  *nwritten = uvwritten;
+  *nwritten = (uvwasi_size_t) uvwritten;
   return UVWASI_ESUCCESS;
 }
 
@@ -1288,17 +1444,24 @@ uvwasi_errno_t uvwasi_fd_write(uvwasi_t* uvwasi,
 uvwasi_errno_t uvwasi_path_create_directory(uvwasi_t* uvwasi,
                                             uvwasi_fd_t fd,
                                             const char* path,
-                                            size_t path_len) {
-  char resolved_path[PATH_MAX_BYTES];
+                                            uvwasi_size_t path_len) {
+  char* resolved_path;
   struct uvwasi_fd_wrap_t* wrap;
   uv_fs_t req;
   uvwasi_errno_t err;
   int r;
 
+  DEBUG("uvwasi_path_create_directory(uvwasi=%p, fd=%d, path='%s', "
+        "path_len=%zu)\n",
+        uvwasi,
+        fd,
+        path,
+        path_len);
+
   if (uvwasi == NULL || path == NULL)
     return UVWASI_EINVAL;
 
-  err = uvwasi_fd_table_get(&uvwasi->fds,
+  err = uvwasi_fd_table_get(uvwasi->fds,
                             fd,
                             &wrap,
                             UVWASI_RIGHT_PATH_CREATE_DIRECTORY,
@@ -1306,12 +1469,13 @@ uvwasi_errno_t uvwasi_path_create_directory(uvwasi_t* uvwasi,
   if (err != UVWASI_ESUCCESS)
     return err;
 
-  err = uvwasi__resolve_path(uvwasi, wrap, path, path_len, resolved_path, 0);
+  err = uvwasi__resolve_path(uvwasi, wrap, path, path_len, &resolved_path, 0);
   if (err != UVWASI_ESUCCESS)
     goto exit;
 
   r = uv_fs_mkdir(NULL, &req, resolved_path, 0777, NULL);
   uv_fs_req_cleanup(&req);
+  uvwasi__free(uvwasi, resolved_path);
 
   if (r != 0) {
     err = uvwasi__translate_uv_error(r);
@@ -1329,18 +1493,27 @@ uvwasi_errno_t uvwasi_path_filestat_get(uvwasi_t* uvwasi,
                                         uvwasi_fd_t fd,
                                         uvwasi_lookupflags_t flags,
                                         const char* path,
-                                        size_t path_len,
+                                        uvwasi_size_t path_len,
                                         uvwasi_filestat_t* buf) {
-  char resolved_path[PATH_MAX_BYTES];
+  char* resolved_path;
   struct uvwasi_fd_wrap_t* wrap;
   uv_fs_t req;
   uvwasi_errno_t err;
   int r;
 
+  DEBUG("uvwasi_path_filestat_get(uvwasi=%p, fd=%d, flags=%d, path='%s', "
+        "path_len=%zu, buf=%p)\n",
+        uvwasi,
+        fd,
+        flags,
+        path,
+        path_len,
+        buf);
+
   if (uvwasi == NULL || path == NULL || buf == NULL)
     return UVWASI_EINVAL;
 
-  err = uvwasi_fd_table_get(&uvwasi->fds,
+  err = uvwasi_fd_table_get(uvwasi->fds,
                             fd,
                             &wrap,
                             UVWASI_RIGHT_PATH_FILESTAT_GET,
@@ -1352,12 +1525,13 @@ uvwasi_errno_t uvwasi_path_filestat_get(uvwasi_t* uvwasi,
                              wrap,
                              path,
                              path_len,
-                             resolved_path,
+                             &resolved_path,
                              flags);
   if (err != UVWASI_ESUCCESS)
     goto exit;
 
   r = uv_fs_stat(NULL, &req, resolved_path, NULL);
+  uvwasi__free(uvwasi, resolved_path);
   if (r != 0) {
     uv_fs_req_cleanup(&req);
     err = uvwasi__translate_uv_error(r);
@@ -1377,17 +1551,28 @@ uvwasi_errno_t uvwasi_path_filestat_set_times(uvwasi_t* uvwasi,
                                               uvwasi_fd_t fd,
                                               uvwasi_lookupflags_t flags,
                                               const char* path,
-                                              size_t path_len,
+                                              uvwasi_size_t path_len,
                                               uvwasi_timestamp_t st_atim,
                                               uvwasi_timestamp_t st_mtim,
                                               uvwasi_fstflags_t fst_flags) {
   /* TODO(cjihrig): libuv does not currently support nanosecond precision. */
-  char resolved_path[PATH_MAX_BYTES];
+  char* resolved_path;
   struct uvwasi_fd_wrap_t* wrap;
   uv_fs_t req;
   uvwasi_errno_t err;
   int r;
 
+  DEBUG("uvwasi_path_filestat_set_times(uvwasi=%p, fd=%d, flags=%d, path='%s', "
+        "path_len=%zu, st_atim=%"PRIu64", st_mtim=%"PRIu64", fst_flags=%d)\n",
+        uvwasi,
+        fd,
+        flags,
+        path,
+        path_len,
+        st_atim,
+        st_mtim,
+        fst_flags);
+
   if (uvwasi == NULL || path == NULL)
     return UVWASI_EINVAL;
 
@@ -1396,7 +1581,7 @@ uvwasi_errno_t uvwasi_path_filestat_set_times(uvwasi_t* uvwasi,
     return UVWASI_EINVAL;
   }
 
-  err = uvwasi_fd_table_get(&uvwasi->fds,
+  err = uvwasi_fd_table_get(uvwasi->fds,
                             fd,
                             &wrap,
                             UVWASI_RIGHT_PATH_FILESTAT_SET_TIMES,
@@ -1408,13 +1593,14 @@ uvwasi_errno_t uvwasi_path_filestat_set_times(uvwasi_t* uvwasi,
                              wrap,
                              path,
                              path_len,
-                             resolved_path,
+                             &resolved_path,
                              flags);
   if (err != UVWASI_ESUCCESS)
     goto exit;
 
   /* TODO(cjihrig): st_atim and st_mtim should not be unconditionally passed. */
   r = uv_fs_utime(NULL, &req, resolved_path, st_atim, st_mtim, NULL);
+  uvwasi__free(uvwasi, resolved_path);
   uv_fs_req_cleanup(&req);
 
   if (r != 0) {
@@ -1433,25 +1619,36 @@ uvwasi_errno_t uvwasi_path_link(uvwasi_t* uvwasi,
                                 uvwasi_fd_t old_fd,
                                 uvwasi_lookupflags_t old_flags,
                                 const char* old_path,
-                                size_t old_path_len,
+                                uvwasi_size_t old_path_len,
                                 uvwasi_fd_t new_fd,
                                 const char* new_path,
-                                size_t new_path_len) {
-  char resolved_old_path[PATH_MAX_BYTES];
-  char resolved_new_path[PATH_MAX_BYTES];
+                                uvwasi_size_t new_path_len) {
+  char* resolved_old_path;
+  char* resolved_new_path;
   struct uvwasi_fd_wrap_t* old_wrap;
   struct uvwasi_fd_wrap_t* new_wrap;
   uvwasi_errno_t err;
   uv_fs_t req;
   int r;
 
+  DEBUG("uvwasi_path_link(uvwasi=%p, old_fd=%d, old_flags=%d, old_path='%s', "
+        "old_path_len=%zu, new_fd=%d, new_path='%s', new_path_len=%zu)\n",
+        uvwasi,
+        old_fd,
+        old_flags,
+        old_path,
+        old_path_len,
+        new_fd,
+        new_path,
+        new_path_len);
+
   if (uvwasi == NULL || old_path == NULL || new_path == NULL)
     return UVWASI_EINVAL;
 
-  uvwasi_fd_table_lock(&uvwasi->fds);
+  uvwasi_fd_table_lock(uvwasi->fds);
 
   if (old_fd == new_fd) {
-    err = uvwasi_fd_table_get_nolock(&uvwasi->fds,
+    err = uvwasi_fd_table_get_nolock(uvwasi->fds,
                                      old_fd,
                                      &old_wrap,
                                      UVWASI_RIGHT_PATH_LINK_SOURCE |
@@ -1459,17 +1656,17 @@ uvwasi_errno_t uvwasi_path_link(uvwasi_t* uvwasi,
                                      0);
     new_wrap = old_wrap;
   } else {
-    err = uvwasi_fd_table_get_nolock(&uvwasi->fds,
+    err = uvwasi_fd_table_get_nolock(uvwasi->fds,
                                      old_fd,
                                      &old_wrap,
                                      UVWASI_RIGHT_PATH_LINK_SOURCE,
                                      0);
     if (err != UVWASI_ESUCCESS) {
-      uvwasi_fd_table_unlock(&uvwasi->fds);
+      uvwasi_fd_table_unlock(uvwasi->fds);
       return err;
     }
 
-    err = uvwasi_fd_table_get_nolock(&uvwasi->fds,
+    err = uvwasi_fd_table_get_nolock(uvwasi->fds,
                                      new_fd,
                                      &new_wrap,
                                      UVWASI_RIGHT_PATH_LINK_TARGET,
@@ -1478,16 +1675,19 @@ uvwasi_errno_t uvwasi_path_link(uvwasi_t* uvwasi,
       uv_mutex_unlock(&old_wrap->mutex);
   }
 
-  uvwasi_fd_table_unlock(&uvwasi->fds);
+  uvwasi_fd_table_unlock(uvwasi->fds);
 
   if (err != UVWASI_ESUCCESS)
     return err;
 
+  resolved_old_path = NULL;
+  resolved_new_path = NULL;
+
   err = uvwasi__resolve_path(uvwasi,
                              old_wrap,
                              old_path,
                              old_path_len,
-                             resolved_old_path,
+                             &resolved_old_path,
                              old_flags);
   if (err != UVWASI_ESUCCESS)
     goto exit;
@@ -1496,7 +1696,7 @@ uvwasi_errno_t uvwasi_path_link(uvwasi_t* uvwasi,
                              new_wrap,
                              new_path,
                              new_path_len,
-                             resolved_new_path,
+                             &resolved_new_path,
                              0);
   if (err != UVWASI_ESUCCESS)
     goto exit;
@@ -1513,6 +1713,9 @@ uvwasi_errno_t uvwasi_path_link(uvwasi_t* uvwasi,
   uv_mutex_unlock(&new_wrap->mutex);
   if (old_fd != new_fd)
     uv_mutex_unlock(&old_wrap->mutex);
+
+  uvwasi__free(uvwasi, resolved_old_path);
+  uvwasi__free(uvwasi, resolved_new_path);
   return err;
 }
 
@@ -1521,13 +1724,13 @@ uvwasi_errno_t uvwasi_path_open(uvwasi_t* uvwasi,
                                 uvwasi_fd_t dirfd,
                                 uvwasi_lookupflags_t dirflags,
                                 const char* path,
-                                size_t path_len,
+                                uvwasi_size_t path_len,
                                 uvwasi_oflags_t o_flags,
                                 uvwasi_rights_t fs_rights_base,
                                 uvwasi_rights_t fs_rights_inheriting,
                                 uvwasi_fdflags_t fs_flags,
                                 uvwasi_fd_t* fd) {
-  char resolved_path[PATH_MAX_BYTES];
+  char* resolved_path;
   uvwasi_rights_t needed_inheriting;
   uvwasi_rights_t needed_base;
   uvwasi_rights_t max_base;
@@ -1542,6 +1745,20 @@ uvwasi_errno_t uvwasi_path_open(uvwasi_t* uvwasi,
   int write;
   int r;
 
+  DEBUG("uvwasi_path_open(uvwasi=%p, dirfd=%d, dirflags=%d, path='%s', "
+        "path_len=%zu, o_flags=%d, fs_rights_base=%"PRIu64", "
+        "fs_rights_inheriting=%"PRIu64", fs_flags=%d, fd=%p)\n",
+        uvwasi,
+        dirfd,
+        dirflags,
+        path,
+        path_len,
+        o_flags,
+        fs_rights_base,
+        fs_rights_inheriting,
+        fs_flags,
+        fd);
+
   if (uvwasi == NULL || path == NULL || fd == NULL)
     return UVWASI_EINVAL;
 
@@ -1591,7 +1808,7 @@ uvwasi_errno_t uvwasi_path_open(uvwasi_t* uvwasi,
   if (write && (flags & (UV_FS_O_APPEND | UV_FS_O_TRUNC)) == 0)
     needed_inheriting |= UVWASI_RIGHT_FD_SEEK;
 
-  err = uvwasi_fd_table_get(&uvwasi->fds,
+  err = uvwasi_fd_table_get(uvwasi->fds,
                             dirfd,
                             &dirfd_wrap,
                             needed_base,
@@ -1603,7 +1820,7 @@ uvwasi_errno_t uvwasi_path_open(uvwasi_t* uvwasi,
                              dirfd_wrap,
                              path,
                              path_len,
-                             resolved_path,
+                             &resolved_path,
                              dirflags);
   if (err != UVWASI_ESUCCESS) {
     uv_mutex_unlock(&dirfd_wrap->mutex);
@@ -1614,8 +1831,10 @@ uvwasi_errno_t uvwasi_path_open(uvwasi_t* uvwasi,
   uv_mutex_unlock(&dirfd_wrap->mutex);
   uv_fs_req_cleanup(&req);
 
-  if (r < 0)
+  if (r < 0) {
+    uvwasi__free(uvwasi, resolved_path);
     return uvwasi__translate_uv_error(r);
+  }
 
   /* Not all platforms support UV_FS_O_DIRECTORY, so get the file type and check
      it here. */
@@ -1634,7 +1853,7 @@ uvwasi_errno_t uvwasi_path_open(uvwasi_t* uvwasi,
     goto close_file_and_error_exit;
 
   err = uvwasi_fd_table_insert(uvwasi,
-                               &uvwasi->fds,
+                               uvwasi->fds,
                                r,
                                resolved_path,
                                resolved_path,
@@ -1648,11 +1867,13 @@ uvwasi_errno_t uvwasi_path_open(uvwasi_t* uvwasi,
 
   *fd = wrap->id;
   uv_mutex_unlock(&wrap->mutex);
+  uvwasi__free(uvwasi, resolved_path);
   return UVWASI_ESUCCESS;
 
 close_file_and_error_exit:
   uv_fs_close(NULL, &req, r, NULL);
   uv_fs_req_cleanup(&req);
+  uvwasi__free(uvwasi, resolved_path);
   return err;
 }
 
@@ -1660,21 +1881,31 @@ uvwasi_errno_t uvwasi_path_open(uvwasi_t* uvwasi,
 uvwasi_errno_t uvwasi_path_readlink(uvwasi_t* uvwasi,
                                     uvwasi_fd_t fd,
                                     const char* path,
-                                    size_t path_len,
+                                    uvwasi_size_t path_len,
                                     char* buf,
-                                    size_t buf_len,
-                                    size_t* bufused) {
-  char resolved_path[PATH_MAX_BYTES];
+                                    uvwasi_size_t buf_len,
+                                    uvwasi_size_t* bufused) {
+  char* resolved_path;
   struct uvwasi_fd_wrap_t* wrap;
   uvwasi_errno_t err;
   uv_fs_t req;
   size_t len;
   int r;
 
+  DEBUG("uvwasi_path_readlink(uvwasi=%p, fd=%d, path='%s', path_len=%zu, "
+        "buf=%p, buf_len=%zu, bufused=%p)\n",
+        uvwasi,
+        fd,
+        path,
+        path_len,
+        buf,
+        buf_len,
+        bufused);
+
   if (uvwasi == NULL || path == NULL || buf == NULL || bufused == NULL)
     return UVWASI_EINVAL;
 
-  err = uvwasi_fd_table_get(&uvwasi->fds,
+  err = uvwasi_fd_table_get(uvwasi->fds,
                             fd,
                             &wrap,
                             UVWASI_RIGHT_PATH_READLINK,
@@ -1682,7 +1913,7 @@ uvwasi_errno_t uvwasi_path_readlink(uvwasi_t* uvwasi,
   if (err != UVWASI_ESUCCESS)
     return err;
 
-  err = uvwasi__resolve_path(uvwasi, wrap, path, path_len, resolved_path, 0);
+  err = uvwasi__resolve_path(uvwasi, wrap, path, path_len, &resolved_path, 0);
   if (err != UVWASI_ESUCCESS) {
     uv_mutex_unlock(&wrap->mutex);
     return err;
@@ -1690,6 +1921,7 @@ uvwasi_errno_t uvwasi_path_readlink(uvwasi_t* uvwasi,
 
   r = uv_fs_readlink(NULL, &req, resolved_path, NULL);
   uv_mutex_unlock(&wrap->mutex);
+  uvwasi__free(uvwasi, resolved_path);
   if (r != 0) {
     uv_fs_req_cleanup(&req);
     return uvwasi__translate_uv_error(r);
@@ -1712,17 +1944,24 @@ uvwasi_errno_t uvwasi_path_readlink(uvwasi_t* uvwasi,
 uvwasi_errno_t uvwasi_path_remove_directory(uvwasi_t* uvwasi,
                                             uvwasi_fd_t fd,
                                             const char* path,
-                                            size_t path_len) {
-  char resolved_path[PATH_MAX_BYTES];
+                                            uvwasi_size_t path_len) {
+  char* resolved_path;
   struct uvwasi_fd_wrap_t* wrap;
   uv_fs_t req;
   uvwasi_errno_t err;
   int r;
 
+  DEBUG("uvwasi_path_remove_directory(uvwasi=%p, fd=%d, path='%s', "
+        "path_len=%zu)\n",
+        uvwasi,
+        fd,
+        path,
+        path_len);
+
   if (uvwasi == NULL || path == NULL)
     return UVWASI_EINVAL;
 
-  err = uvwasi_fd_table_get(&uvwasi->fds,
+  err = uvwasi_fd_table_get(uvwasi->fds,
                             fd,
                             &wrap,
                             UVWASI_RIGHT_PATH_REMOVE_DIRECTORY,
@@ -1730,7 +1969,7 @@ uvwasi_errno_t uvwasi_path_remove_directory(uvwasi_t* uvwasi,
   if (err != UVWASI_ESUCCESS)
     return err;
 
-  err = uvwasi__resolve_path(uvwasi, wrap, path, path_len, resolved_path, 0);
+  err = uvwasi__resolve_path(uvwasi, wrap, path, path_len, &resolved_path, 0);
   if (err != UVWASI_ESUCCESS) {
     uv_mutex_unlock(&wrap->mutex);
     return err;
@@ -1738,6 +1977,7 @@ uvwasi_errno_t uvwasi_path_remove_directory(uvwasi_t* uvwasi,
 
   r = uv_fs_rmdir(NULL, &req, resolved_path, NULL);
   uv_mutex_unlock(&wrap->mutex);
+  uvwasi__free(uvwasi, resolved_path);
   uv_fs_req_cleanup(&req);
 
   if (r != 0)
@@ -1750,25 +1990,35 @@ uvwasi_errno_t uvwasi_path_remove_directory(uvwasi_t* uvwasi,
 uvwasi_errno_t uvwasi_path_rename(uvwasi_t* uvwasi,
                                   uvwasi_fd_t old_fd,
                                   const char* old_path,
-                                  size_t old_path_len,
+                                  uvwasi_size_t old_path_len,
                                   uvwasi_fd_t new_fd,
                                   const char* new_path,
-                                  size_t new_path_len) {
-  char resolved_old_path[PATH_MAX_BYTES];
-  char resolved_new_path[PATH_MAX_BYTES];
+                                  uvwasi_size_t new_path_len) {
+  char* resolved_old_path;
+  char* resolved_new_path;
   struct uvwasi_fd_wrap_t* old_wrap;
   struct uvwasi_fd_wrap_t* new_wrap;
   uvwasi_errno_t err;
   uv_fs_t req;
   int r;
 
+  DEBUG("uvwasi_path_rename(uvwasi=%p, old_fd=%d, old_path='%s', "
+        "old_path_len=%zu, new_fd=%d, new_path='%s', new_path_len=%zu)\n",
+        uvwasi,
+        old_fd,
+        old_path,
+        old_path_len,
+        new_fd,
+        new_path,
+        new_path_len);
+
   if (uvwasi == NULL || old_path == NULL || new_path == NULL)
     return UVWASI_EINVAL;
 
-  uvwasi_fd_table_lock(&uvwasi->fds);
+  uvwasi_fd_table_lock(uvwasi->fds);
 
   if (old_fd == new_fd) {
-    err = uvwasi_fd_table_get_nolock(&uvwasi->fds,
+    err = uvwasi_fd_table_get_nolock(uvwasi->fds,
                                      old_fd,
                                      &old_wrap,
                                      UVWASI_RIGHT_PATH_RENAME_SOURCE |
@@ -1776,17 +2026,17 @@ uvwasi_errno_t uvwasi_path_rename(uvwasi_t* uvwasi,
                                      0);
     new_wrap = old_wrap;
   } else {
-    err = uvwasi_fd_table_get_nolock(&uvwasi->fds,
+    err = uvwasi_fd_table_get_nolock(uvwasi->fds,
                                      old_fd,
                                      &old_wrap,
                                      UVWASI_RIGHT_PATH_RENAME_SOURCE,
                                      0);
     if (err != UVWASI_ESUCCESS) {
-      uvwasi_fd_table_unlock(&uvwasi->fds);
+      uvwasi_fd_table_unlock(uvwasi->fds);
       return err;
     }
 
-    err = uvwasi_fd_table_get_nolock(&uvwasi->fds,
+    err = uvwasi_fd_table_get_nolock(uvwasi->fds,
                                      new_fd,
                                      &new_wrap,
                                      UVWASI_RIGHT_PATH_RENAME_TARGET,
@@ -1795,16 +2045,19 @@ uvwasi_errno_t uvwasi_path_rename(uvwasi_t* uvwasi,
       uv_mutex_unlock(&old_wrap->mutex);
   }
 
-  uvwasi_fd_table_unlock(&uvwasi->fds);
+  uvwasi_fd_table_unlock(uvwasi->fds);
 
   if (err != UVWASI_ESUCCESS)
     return err;
 
+  resolved_old_path = NULL;
+  resolved_new_path = NULL;
+
   err = uvwasi__resolve_path(uvwasi,
                              old_wrap,
                              old_path,
                              old_path_len,
-                             resolved_old_path,
+                             &resolved_old_path,
                              0);
   if (err != UVWASI_ESUCCESS)
     goto exit;
@@ -1813,7 +2066,7 @@ uvwasi_errno_t uvwasi_path_rename(uvwasi_t* uvwasi,
                              new_wrap,
                              new_path,
                              new_path_len,
-                             resolved_new_path,
+                             &resolved_new_path,
                              0);
   if (err != UVWASI_ESUCCESS)
     goto exit;
@@ -1831,26 +2084,37 @@ uvwasi_errno_t uvwasi_path_rename(uvwasi_t* uvwasi,
   if (old_fd != new_fd)
     uv_mutex_unlock(&old_wrap->mutex);
 
+  uvwasi__free(uvwasi, resolved_old_path);
+  uvwasi__free(uvwasi, resolved_new_path);
   return err;
 }
 
 
 uvwasi_errno_t uvwasi_path_symlink(uvwasi_t* uvwasi,
                                    const char* old_path,
-                                   size_t old_path_len,
+                                   uvwasi_size_t old_path_len,
                                    uvwasi_fd_t fd,
                                    const char* new_path,
-                                   size_t new_path_len) {
-  char resolved_new_path[PATH_MAX_BYTES];
+                                   uvwasi_size_t new_path_len) {
+  char* resolved_new_path;
   struct uvwasi_fd_wrap_t* wrap;
   uvwasi_errno_t err;
   uv_fs_t req;
   int r;
 
+  DEBUG("uvwasi_path_symlink(uvwasi=%p, old_path='%s', old_path_len=%zu, "
+        "fd=%d, new_path='%s', new_path_len=%zu)\n",
+        uvwasi,
+        old_path,
+        old_path_len,
+        fd,
+        new_path,
+        new_path_len);
+
   if (uvwasi == NULL || old_path == NULL || new_path == NULL)
     return UVWASI_EINVAL;
 
-  err = uvwasi_fd_table_get(&uvwasi->fds,
+  err = uvwasi_fd_table_get(uvwasi->fds,
                             fd,
                             &wrap,
                             UVWASI_RIGHT_PATH_SYMLINK,
@@ -1862,7 +2126,7 @@ uvwasi_errno_t uvwasi_path_symlink(uvwasi_t* uvwasi,
                              wrap,
                              new_path,
                              new_path_len,
-                             resolved_new_path,
+                             &resolved_new_path,
                              0);
   if (err != UVWASI_ESUCCESS) {
     uv_mutex_unlock(&wrap->mutex);
@@ -1872,6 +2136,7 @@ uvwasi_errno_t uvwasi_path_symlink(uvwasi_t* uvwasi,
   /* Windows support may require setting the flags option. */
   r = uv_fs_symlink(NULL, &req, old_path, resolved_new_path, 0, NULL);
   uv_mutex_unlock(&wrap->mutex);
+  uvwasi__free(uvwasi, resolved_new_path);
   uv_fs_req_cleanup(&req);
   if (r != 0)
     return uvwasi__translate_uv_error(r);
@@ -1883,17 +2148,23 @@ uvwasi_errno_t uvwasi_path_symlink(uvwasi_t* uvwasi,
 uvwasi_errno_t uvwasi_path_unlink_file(uvwasi_t* uvwasi,
                                        uvwasi_fd_t fd,
                                        const char* path,
-                                       size_t path_len) {
-  char resolved_path[PATH_MAX_BYTES];
+                                       uvwasi_size_t path_len) {
+  char* resolved_path;
   struct uvwasi_fd_wrap_t* wrap;
   uv_fs_t req;
   uvwasi_errno_t err;
   int r;
 
+  DEBUG("uvwasi_path_unlink_file(uvwasi=%p, fd=%d, path='%s', path_len=%zu)\n",
+        uvwasi,
+        fd,
+        path,
+        path_len);
+
   if (uvwasi == NULL || path == NULL)
     return UVWASI_EINVAL;
 
-  err = uvwasi_fd_table_get(&uvwasi->fds,
+  err = uvwasi_fd_table_get(uvwasi->fds,
                             fd,
                             &wrap,
                             UVWASI_RIGHT_PATH_UNLINK_FILE,
@@ -1901,7 +2172,7 @@ uvwasi_errno_t uvwasi_path_unlink_file(uvwasi_t* uvwasi,
   if (err != UVWASI_ESUCCESS)
     return err;
 
-  err = uvwasi__resolve_path(uvwasi, wrap, path, path_len, resolved_path, 0);
+  err = uvwasi__resolve_path(uvwasi, wrap, path, path_len, &resolved_path, 0);
   if (err != UVWASI_ESUCCESS) {
     uv_mutex_unlock(&wrap->mutex);
     return err;
@@ -1909,6 +2180,7 @@ uvwasi_errno_t uvwasi_path_unlink_file(uvwasi_t* uvwasi,
 
   r = uv_fs_unlink(NULL, &req, resolved_path, NULL);
   uv_mutex_unlock(&wrap->mutex);
+  uvwasi__free(uvwasi, resolved_path);
   uv_fs_req_cleanup(&req);
 
   if (r != 0)
@@ -1921,14 +2193,127 @@ uvwasi_errno_t uvwasi_path_unlink_file(uvwasi_t* uvwasi,
 uvwasi_errno_t uvwasi_poll_oneoff(uvwasi_t* uvwasi,
                                   const uvwasi_subscription_t* in,
                                   uvwasi_event_t* out,
-                                  size_t nsubscriptions,
-                                  size_t* nevents) {
-  /* TODO(cjihrig): Implement this. */
-  return UVWASI_ENOTSUP;
+                                  uvwasi_size_t nsubscriptions,
+                                  uvwasi_size_t* nevents) {
+  struct uvwasi_poll_oneoff_state_t state;
+  struct uvwasi__poll_fdevent_t* fdevent;
+  uvwasi_userdata_t timer_userdata;
+  uvwasi_timestamp_t min_timeout;
+  uvwasi_timestamp_t cur_timeout;
+  uvwasi_timestamp_t now;
+  uvwasi_subscription_t sub;
+  uvwasi_event_t* event;
+  uvwasi_errno_t err;
+  int has_timeout;
+  uvwasi_size_t i;
+
+  DEBUG("uvwasi_poll_oneoff(uvwasi=%p, in=%p, out=%p, nsubscriptions=%zu, "
+        "nevents=%p)\n",
+        uvwasi,
+        in,
+        out,
+        nsubscriptions,
+        nevents);
+
+  if (uvwasi == NULL || in == NULL || out == NULL ||
+      nsubscriptions == 0 || nevents == NULL) {
+    return UVWASI_EINVAL;
+  }
+
+  *nevents = 0;
+  err = uvwasi__poll_oneoff_state_init(uvwasi, &state, nsubscriptions);
+  if (err != UVWASI_ESUCCESS)
+    return err;
+
+  has_timeout = 0;
+  min_timeout = 0;
+
+  for (i = 0; i < nsubscriptions; i++) {
+    sub = in[i];
+
+    switch (sub.type) {
+      case UVWASI_EVENTTYPE_CLOCK:
+        if (sub.u.clock.flags == UVWASI_SUBSCRIPTION_CLOCK_ABSTIME) {
+          /* Convert absolute time to relative delay. */
+          err = uvwasi__clock_gettime_realtime(&now);
+          if (err != UVWASI_ESUCCESS)
+            goto exit;
+
+          cur_timeout = sub.u.clock.timeout - now;
+        } else {
+          cur_timeout = sub.u.clock.timeout;
+        }
+
+        if (has_timeout == 0 || cur_timeout < min_timeout) {
+          min_timeout = cur_timeout;
+          timer_userdata = sub.userdata;
+          has_timeout = 1;
+        }
+
+        break;
+      case UVWASI_EVENTTYPE_FD_READ:
+      case UVWASI_EVENTTYPE_FD_WRITE:
+        err = uvwasi__poll_oneoff_state_add_fdevent(&state, &sub);
+        if (err != UVWASI_ESUCCESS)
+          goto exit;
+
+        break;
+      default:
+        err = UVWASI_EINVAL;
+        goto exit;
+    }
+  }
+
+  if (has_timeout == 1) {
+    err = uvwasi__poll_oneoff_state_set_timer(&state, min_timeout);
+    if (err != UVWASI_ESUCCESS)
+      goto exit;
+  }
+
+  /* Handle poll() errors, then timeouts, then happy path. */
+  err = uvwasi__poll_oneoff_run(&state);
+  if (err != UVWASI_ESUCCESS) {
+    goto exit;
+  } else if (state.result == 0) {
+    event = &out[0];
+    event->userdata = timer_userdata;
+    event->error = UVWASI_ESUCCESS;
+    event->type = UVWASI_EVENTTYPE_CLOCK;
+    *nevents = 1;
+  } else {
+    for (i = 0; i < state.fdevent_cnt; i++) {
+      fdevent = &state.fdevents[i];
+      event = &out[*nevents];
+
+      event->userdata = fdevent->userdata;
+      event->error = fdevent->error;
+      event->type = fdevent->type;
+      event->u.fd_readwrite.nbytes = 0;
+      event->u.fd_readwrite.flags = 0;
+
+      if (fdevent->error != UVWASI_ESUCCESS)
+        ;
+      else if ((fdevent->revents & UV_DISCONNECT) != 0)
+        event->u.fd_readwrite.flags = UVWASI_EVENT_FD_READWRITE_HANGUP;
+      else if ((fdevent->revents & (UV_READABLE | UV_WRITABLE)) != 0)
+        ; /* TODO(cjihrig): Set nbytes if type is UVWASI_EVENTTYPE_FD_READ. */
+      else
+        continue;
+
+      *nevents = *nevents + 1;
+    }
+  }
+
+  err = UVWASI_ESUCCESS;
+
+exit:
+  uvwasi__poll_oneoff_state_cleanup(&state);
+  return err;
 }
 
 
 uvwasi_errno_t uvwasi_proc_exit(uvwasi_t* uvwasi, uvwasi_exitcode_t rval) {
+  DEBUG("uvwasi_proc_exit(uvwasi=%p, rval=%d)\n", uvwasi, rval);
   exit(rval);
   return UVWASI_ESUCCESS; /* This doesn't happen. */
 }
@@ -1937,6 +2322,8 @@ uvwasi_errno_t uvwasi_proc_exit(uvwasi_t* uvwasi, uvwasi_exitcode_t rval) {
 uvwasi_errno_t uvwasi_proc_raise(uvwasi_t* uvwasi, uvwasi_signal_t sig) {
   int r;
 
+  DEBUG("uvwasi_proc_raise(uvwasi=%p, sig=%d)\n", uvwasi, sig);
+
   if (uvwasi == NULL)
     return UVWASI_EINVAL;
 
@@ -1952,9 +2339,16 @@ uvwasi_errno_t uvwasi_proc_raise(uvwasi_t* uvwasi, uvwasi_signal_t sig) {
 }
 
 
-uvwasi_errno_t uvwasi_random_get(uvwasi_t* uvwasi, void* buf, size_t buf_len) {
+uvwasi_errno_t uvwasi_random_get(uvwasi_t* uvwasi,
+                                 void* buf,
+                                 uvwasi_size_t buf_len) {
   int r;
 
+  DEBUG("uvwasi_random_get(uvwasi=%p, buf=%p, buf_len=%zu)\n",
+        uvwasi,
+        buf,
+        buf_len);
+
   if (uvwasi == NULL || buf == NULL)
     return UVWASI_EINVAL;
 
@@ -1967,6 +2361,8 @@ uvwasi_errno_t uvwasi_random_get(uvwasi_t* uvwasi, void* buf, size_t buf_len) {
 
 
 uvwasi_errno_t uvwasi_sched_yield(uvwasi_t* uvwasi) {
+  DEBUG("uvwasi_sched_yield(uvwasi=%p)\n", uvwasi);
+
   if (uvwasi == NULL)
     return UVWASI_EINVAL;
 
@@ -1984,12 +2380,13 @@ uvwasi_errno_t uvwasi_sched_yield(uvwasi_t* uvwasi) {
 uvwasi_errno_t uvwasi_sock_recv(uvwasi_t* uvwasi,
                                 uvwasi_fd_t sock,
                                 const uvwasi_iovec_t* ri_data,
-                                size_t ri_data_len,
+                                uvwasi_size_t ri_data_len,
                                 uvwasi_riflags_t ri_flags,
-                                size_t* ro_datalen,
+                                uvwasi_size_t* ro_datalen,
                                 uvwasi_roflags_t* ro_flags) {
   /* TODO(cjihrig): Waiting to implement, pending
                     https://github.com/WebAssembly/WASI/issues/4 */
+  DEBUG("uvwasi_sock_recv(uvwasi=%p, unimplemented)\n", uvwasi);
   return UVWASI_ENOTSUP;
 }
 
@@ -1997,11 +2394,12 @@ uvwasi_errno_t uvwasi_sock_recv(uvwasi_t* uvwasi,
 uvwasi_errno_t uvwasi_sock_send(uvwasi_t* uvwasi,
                                 uvwasi_fd_t sock,
                                 const uvwasi_ciovec_t* si_data,
-                                size_t si_data_len,
+                                uvwasi_size_t si_data_len,
                                 uvwasi_siflags_t si_flags,
-                                size_t* so_datalen) {
+                                uvwasi_size_t* so_datalen) {
   /* TODO(cjihrig): Waiting to implement, pending
                     https://github.com/WebAssembly/WASI/issues/4 */
+  DEBUG("uvwasi_sock_send(uvwasi=%p, unimplemented)\n", uvwasi);
   return UVWASI_ENOTSUP;
 }
 
@@ -2011,6 +2409,7 @@ uvwasi_errno_t uvwasi_sock_shutdown(uvwasi_t* uvwasi,
                                     uvwasi_sdflags_t how) {
   /* TODO(cjihrig): Waiting to implement, pending
                     https://github.com/WebAssembly/WASI/issues/4 */
+  DEBUG("uvwasi_sock_shutdown(uvwasi=%p, unimplemented)\n", uvwasi);
   return UVWASI_ENOTSUP;
 }
 
diff --git a/deps/uvwasi/src/wasi_serdes.c b/deps/uvwasi/src/wasi_serdes.c
new file mode 100644
index 00000000000000..96253fc5af0623
--- /dev/null
+++ b/deps/uvwasi/src/wasi_serdes.c
@@ -0,0 +1,259 @@
+#include "wasi_serdes.h"
+#include "wasi_types.h"
+
+void uvwasi_serdes_write_uint64_t(void* ptr,
+                                  size_t offset,
+                                  uint64_t value) {
+  uvwasi_serdes_write_uint32_t(ptr, offset, (uint32_t) value);
+  uvwasi_serdes_write_uint32_t(ptr, offset + 4, value >> 32);
+}
+
+void uvwasi_serdes_write_uint32_t(void* ptr,
+                                  size_t offset,
+                                  uint32_t value) {
+  uvwasi_serdes_write_uint16_t(ptr, offset, (uint16_t) value);
+  uvwasi_serdes_write_uint16_t(ptr, offset + 2, value >> 16);
+}
+
+void uvwasi_serdes_write_uint16_t(void* ptr,
+                                  size_t offset,
+                                  uint16_t value) {
+  uvwasi_serdes_write_uint8_t(ptr, offset, (uint8_t) value);
+  uvwasi_serdes_write_uint8_t(ptr, offset + 1, value >> 8);
+}
+
+void uvwasi_serdes_write_uint8_t(void* ptr,
+                                 size_t offset,
+                                 uint8_t value) {
+  ((uint8_t*) ptr)[offset] = value;
+}
+
+uint64_t uvwasi_serdes_read_uint64_t(const void* ptr, size_t offset) {
+  uint64_t low = uvwasi_serdes_read_uint32_t(ptr, offset);
+  uint64_t high = uvwasi_serdes_read_uint32_t(ptr, offset + 4);
+  return low | (high << 32);
+}
+
+uint32_t uvwasi_serdes_read_uint32_t(const void* ptr, size_t offset) {
+  uint32_t low = uvwasi_serdes_read_uint16_t(ptr, offset);
+  uint32_t high = uvwasi_serdes_read_uint16_t(ptr, offset + 2);
+  return low | (high << 16);
+}
+
+uint16_t uvwasi_serdes_read_uint16_t(const void* ptr, size_t offset) {
+  uint16_t low = uvwasi_serdes_read_uint8_t(ptr, offset);
+  uint16_t high = uvwasi_serdes_read_uint8_t(ptr, offset + 1);
+  return low | (high << 8);
+}
+
+uint8_t uvwasi_serdes_read_uint8_t(const void* ptr,  size_t offset) {
+  return ((const uint8_t*) ptr)[offset];
+}
+
+#define TYPE_SWITCH switch (value->type)
+
+#define ALL_TYPES(STRUCT, FIELD, ALIAS)                                       \
+                                                                              \
+  ALIAS(advice_t,        uint8_t)                                             \
+  ALIAS(clockid_t,       uint32_t)                                            \
+  ALIAS(device_t,        uint64_t)                                            \
+  ALIAS(dircookie_t,     uint64_t)                                            \
+  ALIAS(errno_t,         uint16_t)                                            \
+  ALIAS(eventrwflags_t,  uint16_t)                                            \
+  ALIAS(eventtype_t,     uint8_t)                                             \
+  ALIAS(exitcode_t,      uint32_t)                                            \
+  ALIAS(fd_t,            uint32_t)                                            \
+  ALIAS(fdflags_t,       uint16_t)                                            \
+  ALIAS(filesize_t,      uint64_t)                                            \
+  ALIAS(filetype_t,      uint8_t)                                             \
+  ALIAS(fstflags_t,      uint16_t)                                            \
+  ALIAS(inode_t,         uint64_t)                                            \
+  ALIAS(linkcount_t,     uint64_t)                                            \
+  ALIAS(lookupflags_t,   uint32_t)                                            \
+  ALIAS(oflags_t,        uint16_t)                                            \
+  ALIAS(preopentype_t,   uint8_t)                                             \
+  ALIAS(riflags_t,       uint16_t)                                            \
+  ALIAS(rights_t,        uint64_t)                                            \
+  ALIAS(roflags_t,       uint16_t)                                            \
+  ALIAS(sdflags_t,       uint8_t)                                             \
+  ALIAS(siflags_t,       uint16_t)                                            \
+  ALIAS(signal_t,        uint8_t)                                             \
+  ALIAS(size_t,          uint32_t)                                            \
+  ALIAS(subclockflags_t, uint16_t)                                            \
+  ALIAS(timestamp_t,     uint64_t)                                            \
+  ALIAS(userdata_t,      uint64_t)                                            \
+  ALIAS(whence_t,        uint8_t)                                             \
+                                                                              \
+  STRUCT(fdstat_t) {                                                          \
+    FIELD( 0, filetype_t, fs_filetype);                                       \
+    FIELD( 2, fdflags_t,  fs_flags);                                          \
+    FIELD( 8, rights_t,   fs_rights_base);                                    \
+    FIELD(16, rights_t,   fs_rights_inheriting);                              \
+  }                                                                           \
+                                                                              \
+  STRUCT(filestat_t) {                                                        \
+    FIELD( 0, device_t,    st_dev);                                           \
+    FIELD( 8, inode_t,     st_ino);                                           \
+    FIELD(16, filetype_t,  st_filetype);                                      \
+    FIELD(24, linkcount_t, st_nlink);                                         \
+    FIELD(32, filesize_t,  st_size);                                          \
+    FIELD(40, timestamp_t, st_atim);                                          \
+    FIELD(48, timestamp_t, st_mtim);                                          \
+    FIELD(56, timestamp_t, st_ctim);                                          \
+  }                                                                           \
+                                                                              \
+  STRUCT(prestat_t) {                                                         \
+    FIELD(0, preopentype_t, pr_type);                                         \
+    FIELD(4, uint32_t,      u.dir.pr_name_len);                               \
+  }                                                                           \
+                                                                              \
+  STRUCT(event_t) {                                                           \
+    FIELD( 0, userdata_t,  userdata);                                         \
+    FIELD( 8, errno_t,     error);                                            \
+    FIELD(10, eventtype_t, type);                                             \
+    TYPE_SWITCH {                                                             \
+      case UVWASI_EVENTTYPE_FD_READ:                                          \
+      case UVWASI_EVENTTYPE_FD_WRITE:                                         \
+        FIELD(16, filesize_t,     u.fd_readwrite.nbytes);                     \
+        FIELD(24, eventrwflags_t, u.fd_readwrite.flags);                      \
+    }                                                                         \
+  }                                                                           \
+                                                                              \
+  STRUCT(subscription_t) {                                                    \
+    FIELD(0, userdata_t,  userdata);                                          \
+    FIELD(8, eventtype_t, type);                                              \
+    TYPE_SWITCH {                                                             \
+      case UVWASI_EVENTTYPE_CLOCK:                                            \
+        FIELD(16, clockid_t,       u.clock.clock_id);                         \
+        FIELD(24, timestamp_t,     u.clock.timeout);                          \
+        FIELD(32, timestamp_t,     u.clock.precision);                        \
+        FIELD(40, subclockflags_t, u.clock.flags);                            \
+        break;                                                                \
+      case UVWASI_EVENTTYPE_FD_READ:                                          \
+      case UVWASI_EVENTTYPE_FD_WRITE:                                         \
+        FIELD(16, fd_t, u.fd_readwrite.fd);                                   \
+    }                                                                         \
+  }                                                                           \
+
+#define WRITE_STRUCT(name)                                                    \
+  void uvwasi_serdes_write_##name(void* ptr,                                  \
+                                  size_t offset,                              \
+                                  const uvwasi_##name* value)                 \
+
+#define READ_STRUCT(name)                                                     \
+  void uvwasi_serdes_read_##name(const void* ptr,                             \
+                                 size_t offset,                               \
+                                 uvwasi_##name* value)                        \
+
+#define WRITE_FIELD(field_offset, type, field)                                \
+  do {                                                                        \
+    uvwasi_serdes_write_##type(ptr, offset + field_offset, value->field);     \
+  } while (0)                                                                 \
+
+#define READ_FIELD(field_offset, type, field)                                 \
+  do {                                                                        \
+    value->field = uvwasi_serdes_read_##type(ptr, offset + field_offset);     \
+  } while (0)                                                                 \
+
+#define WRITE_ALIAS(new_name, old_name)                                       \
+  void uvwasi_serdes_write_##new_name(void* ptr,                              \
+                                      size_t offset,                          \
+                                      uvwasi_##new_name value) {              \
+    uvwasi_serdes_write_##old_name(ptr, offset, value);                       \
+  }                                                                           \
+
+#define READ_ALIAS(new_name, old_name)                                        \
+  uvwasi_##new_name uvwasi_serdes_read_##new_name(const void* ptr,            \
+                                                  size_t offset) {            \
+    return uvwasi_serdes_read_##old_name(ptr, offset);                        \
+  }                                                                           \
+
+ALL_TYPES(WRITE_STRUCT, WRITE_FIELD, WRITE_ALIAS)
+ALL_TYPES(READ_STRUCT, READ_FIELD, READ_ALIAS)
+
+
+uvwasi_errno_t uvwasi_serdes_read_ciovec_t(const void* ptr,
+                                           size_t end,
+                                           size_t offset,
+                                           uvwasi_ciovec_t* value) {
+  uint32_t buf_ptr;
+
+  buf_ptr = uvwasi_serdes_read_uint32_t(ptr, offset);
+  value->buf_len = uvwasi_serdes_read_size_t(ptr, offset + 4);
+
+  if (!uvwasi_serdes_check_bounds(buf_ptr, end, value->buf_len))
+    return UVWASI_EOVERFLOW;
+
+  value->buf = ((uint8_t*) ptr + buf_ptr);
+  return UVWASI_ESUCCESS;
+}
+
+
+uvwasi_errno_t uvwasi_serdes_read_iovec_t(const void* ptr,
+                                          size_t end,
+                                          size_t offset,
+                                          uvwasi_iovec_t* value) {
+  uint32_t buf_ptr;
+
+  buf_ptr = uvwasi_serdes_read_uint32_t(ptr, offset);
+  value->buf_len = uvwasi_serdes_read_size_t(ptr, offset + 4);
+
+  if (!uvwasi_serdes_check_bounds(buf_ptr, end, value->buf_len))
+    return UVWASI_EOVERFLOW;
+
+  value->buf = ((uint8_t*) ptr + buf_ptr);
+  return UVWASI_ESUCCESS;
+}
+
+
+uvwasi_errno_t uvwasi_serdes_readv_ciovec_t(const void* ptr,
+                                            size_t end,
+                                            size_t offset,
+                                            uvwasi_ciovec_t* iovs,
+                                            uvwasi_size_t iovs_len) {
+  uvwasi_errno_t err;
+  uvwasi_size_t i;
+
+  for (i = 0; i < iovs_len; i++) {
+    err = uvwasi_serdes_read_ciovec_t(ptr, end, offset, &iovs[i]);
+    if (err != UVWASI_ESUCCESS)
+      return err;
+    offset += UVWASI_SERDES_SIZE_ciovec_t;
+  }
+
+  return UVWASI_ESUCCESS;
+}
+
+
+uvwasi_errno_t uvwasi_serdes_readv_iovec_t(const void* ptr,
+                                           size_t end,
+                                           size_t offset,
+                                           uvwasi_iovec_t* iovs,
+                                           uvwasi_size_t iovs_len) {
+  uvwasi_errno_t err;
+  uvwasi_size_t i;
+
+  for (i = 0; i < iovs_len; i++) {
+    err = uvwasi_serdes_read_iovec_t(ptr, end, offset, &iovs[i]);
+    if (err != UVWASI_ESUCCESS)
+      return err;
+    offset += UVWASI_SERDES_SIZE_iovec_t;
+  }
+
+  return UVWASI_ESUCCESS;
+}
+
+
+int uvwasi_serdes_check_bounds(size_t offset, size_t end, size_t size) {
+  return end > offset && size <= (end - offset);
+}
+
+
+int uvwasi_serdes_check_array_bounds(size_t offset,
+                                     size_t end,
+                                     size_t size,
+                                     size_t count) {
+  return end > offset &&
+         ((count * size) / size == count) &&
+         (count * size <= end - offset);
+}
diff --git a/deps/uvwasi/uvwasi.gyp b/deps/uvwasi/uvwasi.gyp
index 42769095ecbafd..d4189eeee2fc94 100644
--- a/deps/uvwasi/uvwasi.gyp
+++ b/deps/uvwasi/uvwasi.gyp
@@ -12,9 +12,11 @@
         'src/clocks.c',
         'src/fd_table.c',
         'src/path_resolver.c',
+        'src/poll_oneoff.c',
         'src/uv_mapping.c',
         'src/uvwasi.c',
         'src/wasi_rights.c',
+        'src/wasi_serdes.c',
       ],
       'dependencies': [
         '../uv/uv.gyp:libuv',
diff --git a/src/node_wasi.cc b/src/node_wasi.cc
index 909023d84e0235..dad8bfc07674de 100644
--- a/src/node_wasi.cc
+++ b/src/node_wasi.cc
@@ -13,12 +13,6 @@
 namespace node {
 namespace wasi {
 
-static inline bool is_access_oob(size_t mem_size,
-                                 uint32_t offset,
-                                 uint32_t buf_size) {
-  return offset + buf_size > mem_size;
-}
-
 template <typename... Args>
 inline void Debug(WASI* wasi, Args&&... args) {
   Debug(wasi->env(), DebugCategory::WASI, std::forward<Args>(args)...);
@@ -72,7 +66,7 @@ inline void Debug(WASI* wasi, Args&&... args) {
 
 #define CHECK_BOUNDS_OR_RETURN(args, mem_size, offset, buf_size)              \
   do {                                                                        \
-    if (is_access_oob((mem_size), (offset), (buf_size))) {                    \
+    if (!uvwasi_serdes_check_bounds((offset), (mem_size), (buf_size))) {      \
       (args).GetReturnValue().Set(UVWASI_EOVERFLOW);                          \
       return;                                                                 \
     }                                                                         \
@@ -185,7 +179,8 @@ void WASI::New(const FunctionCallbackInfo<Value>& args) {
   options.err = 2;
   options.fd_table_size = 3;
   options.argc = argc;
-  options.argv = argc == 0 ? nullptr : new char*[argc];
+  options.argv =
+    const_cast<const char**>(argc == 0 ? nullptr : new char*[argc]);
 
   for (uint32_t i = 0; i < argc; i++) {
     auto arg = argv->Get(context, i).ToLocalChecked();
@@ -197,7 +192,7 @@ void WASI::New(const FunctionCallbackInfo<Value>& args) {
 
   Local<Array> env_pairs = args[1].As<Array>();
   const uint32_t envc = env_pairs->Length();
-  options.envp = new char*[envc + 1];
+  options.envp = const_cast<const char**>(new char*[envc + 1]);
   for (uint32_t i = 0; i < envc; i++) {
     auto pair = env_pairs->Get(context, i).ToLocalChecked();
     CHECK(pair->IsString());
@@ -230,13 +225,13 @@ void WASI::New(const FunctionCallbackInfo<Value>& args) {
 
   if (options.argv != nullptr) {
     for (uint32_t i = 0; i < argc; i++)
-      free(options.argv[i]);
+      free(const_cast<char*>(options.argv[i]));
     delete[] options.argv;
   }
 
   if (options.envp != nullptr) {
     for (uint32_t i = 0; options.envp[i]; i++)
-      free(options.envp[i]);
+      free(const_cast<char*>(options.envp[i]));
     delete[] options.envp;
   }
 
@@ -267,7 +262,10 @@ void WASI::ArgsGet(const FunctionCallbackInfo<Value>& args) {
                          mem_size,
                          argv_buf_offset,
                          wasi->uvw_.argv_buf_size);
-  CHECK_BOUNDS_OR_RETURN(args, mem_size, argv_offset, wasi->uvw_.argc * 4);
+  CHECK_BOUNDS_OR_RETURN(args,
+                         mem_size,
+                         argv_offset,
+                         wasi->uvw_.argc * UVWASI_SERDES_SIZE_uint32_t);
   std::vector<char*> argv(wasi->uvw_.argc);
   char* argv_buf = &memory[argv_buf_offset];
   uvwasi_errno_t err = uvwasi_args_get(&wasi->uvw_, argv.data(), argv_buf);
@@ -275,7 +273,10 @@ void WASI::ArgsGet(const FunctionCallbackInfo<Value>& args) {
   if (err == UVWASI_ESUCCESS) {
     for (size_t i = 0; i < wasi->uvw_.argc; i++) {
       uint32_t offset = argv_buf_offset + (argv[i] - argv[0]);
-      wasi->writeUInt32(memory, offset, argv_offset + (i * 4));
+      uvwasi_serdes_write_uint32_t(memory,
+                                   argv_offset +
+                                   (i * UVWASI_SERDES_SIZE_uint32_t),
+                                   offset);
     }
   }
 
@@ -295,16 +296,22 @@ void WASI::ArgsSizesGet(const FunctionCallbackInfo<Value>& args) {
   ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
   Debug(wasi, "args_sizes_get(%d, %d)\n", argc_offset, argv_buf_offset);
   GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
-  CHECK_BOUNDS_OR_RETURN(args, mem_size, argc_offset, 4);
-  CHECK_BOUNDS_OR_RETURN(args, mem_size, argv_buf_offset, 4);
-  size_t argc;
-  size_t argv_buf_size;
+  CHECK_BOUNDS_OR_RETURN(args,
+                         mem_size,
+                         argc_offset,
+                         UVWASI_SERDES_SIZE_size_t);
+  CHECK_BOUNDS_OR_RETURN(args,
+                         mem_size,
+                         argv_buf_offset,
+                         UVWASI_SERDES_SIZE_size_t);
+  uvwasi_size_t argc;
+  uvwasi_size_t argv_buf_size;
   uvwasi_errno_t err = uvwasi_args_sizes_get(&wasi->uvw_,
                                              &argc,
                                              &argv_buf_size);
   if (err == UVWASI_ESUCCESS) {
-    wasi->writeUInt32(memory, argc, argc_offset);
-    wasi->writeUInt32(memory, argv_buf_size, argv_buf_offset);
+    uvwasi_serdes_write_size_t(memory, argc_offset, argc);
+    uvwasi_serdes_write_size_t(memory, argv_buf_offset, argv_buf_size);
   }
 
   args.GetReturnValue().Set(err);
@@ -323,13 +330,16 @@ void WASI::ClockResGet(const FunctionCallbackInfo<Value>& args) {
   ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
   Debug(wasi, "clock_res_get(%d, %d)\n", clock_id, resolution_ptr);
   GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
-  CHECK_BOUNDS_OR_RETURN(args, mem_size, resolution_ptr, 8);
+  CHECK_BOUNDS_OR_RETURN(args,
+                         mem_size,
+                         resolution_ptr,
+                         UVWASI_SERDES_SIZE_timestamp_t);
   uvwasi_timestamp_t resolution;
   uvwasi_errno_t err = uvwasi_clock_res_get(&wasi->uvw_,
                                             clock_id,
                                             &resolution);
   if (err == UVWASI_ESUCCESS)
-    wasi->writeUInt64(memory, resolution, resolution_ptr);
+    uvwasi_serdes_write_timestamp_t(memory, resolution_ptr, resolution);
 
   args.GetReturnValue().Set(err);
 }
@@ -349,14 +359,17 @@ void WASI::ClockTimeGet(const FunctionCallbackInfo<Value>& args) {
   ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
   Debug(wasi, "clock_time_get(%d, %d, %d)\n", clock_id, precision, time_ptr);
   GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
-  CHECK_BOUNDS_OR_RETURN(args, mem_size, time_ptr, 8);
+  CHECK_BOUNDS_OR_RETURN(args,
+                         mem_size,
+                         time_ptr,
+                         UVWASI_SERDES_SIZE_timestamp_t);
   uvwasi_timestamp_t time;
   uvwasi_errno_t err = uvwasi_clock_time_get(&wasi->uvw_,
                                              clock_id,
                                              precision,
                                              &time);
   if (err == UVWASI_ESUCCESS)
-    wasi->writeUInt64(memory, time, time_ptr);
+    uvwasi_serdes_write_timestamp_t(memory, time_ptr, time);
 
   args.GetReturnValue().Set(err);
 }
@@ -378,7 +391,10 @@ void WASI::EnvironGet(const FunctionCallbackInfo<Value>& args) {
                          mem_size,
                          environ_buf_offset,
                          wasi->uvw_.env_buf_size);
-  CHECK_BOUNDS_OR_RETURN(args, mem_size, environ_offset, wasi->uvw_.envc * 4);
+  CHECK_BOUNDS_OR_RETURN(args,
+                         mem_size,
+                         environ_offset,
+                         wasi->uvw_.envc * UVWASI_SERDES_SIZE_uint32_t);
   std::vector<char*> environment(wasi->uvw_.envc);
   char* environ_buf = &memory[environ_buf_offset];
   uvwasi_errno_t err = uvwasi_environ_get(&wasi->uvw_,
@@ -388,7 +404,11 @@ void WASI::EnvironGet(const FunctionCallbackInfo<Value>& args) {
   if (err == UVWASI_ESUCCESS) {
     for (size_t i = 0; i < wasi->uvw_.envc; i++) {
       uint32_t offset = environ_buf_offset + (environment[i] - environment[0]);
-      wasi->writeUInt32(memory, offset, environ_offset + (i * 4));
+
+      uvwasi_serdes_write_uint32_t(memory,
+                                   environ_offset +
+                                   (i * UVWASI_SERDES_SIZE_uint32_t),
+                                   offset);
     }
   }
 
@@ -408,16 +428,22 @@ void WASI::EnvironSizesGet(const FunctionCallbackInfo<Value>& args) {
   ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
   Debug(wasi, "environ_sizes_get(%d, %d)\n", envc_offset, env_buf_offset);
   GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
-  CHECK_BOUNDS_OR_RETURN(args, mem_size, envc_offset, 4);
-  CHECK_BOUNDS_OR_RETURN(args, mem_size, env_buf_offset, 4);
-  size_t envc;
-  size_t env_buf_size;
+  CHECK_BOUNDS_OR_RETURN(args,
+                         mem_size,
+                         envc_offset,
+                         UVWASI_SERDES_SIZE_size_t);
+  CHECK_BOUNDS_OR_RETURN(args,
+                         mem_size,
+                         env_buf_offset,
+                         UVWASI_SERDES_SIZE_size_t);
+  uvwasi_size_t envc;
+  uvwasi_size_t env_buf_size;
   uvwasi_errno_t err = uvwasi_environ_sizes_get(&wasi->uvw_,
                                                 &envc,
                                                 &env_buf_size);
   if (err == UVWASI_ESUCCESS) {
-    wasi->writeUInt32(memory, envc, envc_offset);
-    wasi->writeUInt32(memory, env_buf_size, env_buf_offset);
+    uvwasi_serdes_write_size_t(memory, envc_offset, envc);
+    uvwasi_serdes_write_size_t(memory, env_buf_offset, env_buf_size);
   }
 
   args.GetReturnValue().Set(err);
@@ -494,16 +520,12 @@ void WASI::FdFdstatGet(const FunctionCallbackInfo<Value>& args) {
   ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
   Debug(wasi, "fd_fdstat_get(%d, %d)\n", fd, buf);
   GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
-  CHECK_BOUNDS_OR_RETURN(args, mem_size, buf, 24);
+  CHECK_BOUNDS_OR_RETURN(args, mem_size, buf, UVWASI_SERDES_SIZE_fdstat_t);
   uvwasi_fdstat_t stats;
   uvwasi_errno_t err = uvwasi_fd_fdstat_get(&wasi->uvw_, fd, &stats);
 
-  if (err == UVWASI_ESUCCESS) {
-    wasi->writeUInt8(memory, stats.fs_filetype, buf);
-    wasi->writeUInt16(memory, stats.fs_flags, buf + 2);
-    wasi->writeUInt64(memory, stats.fs_rights_base, buf + 8);
-    wasi->writeUInt64(memory, stats.fs_rights_inheriting, buf + 16);
-  }
+  if (err == UVWASI_ESUCCESS)
+    uvwasi_serdes_write_fdstat_t(memory, buf, &stats);
 
   args.GetReturnValue().Set(err);
 }
@@ -558,20 +580,12 @@ void WASI::FdFilestatGet(const FunctionCallbackInfo<Value>& args) {
   ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
   Debug(wasi, "fd_filestat_get(%d, %d)\n", fd, buf);
   GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
-  CHECK_BOUNDS_OR_RETURN(args, mem_size, buf, 64);
+  CHECK_BOUNDS_OR_RETURN(args, mem_size, buf, UVWASI_SERDES_SIZE_filestat_t);
   uvwasi_filestat_t stats;
   uvwasi_errno_t err = uvwasi_fd_filestat_get(&wasi->uvw_, fd, &stats);
 
-  if (err == UVWASI_ESUCCESS) {
-    wasi->writeUInt64(memory, stats.st_dev, buf);
-    wasi->writeUInt64(memory, stats.st_ino, buf + 8);
-    wasi->writeUInt8(memory, stats.st_filetype, buf + 16);
-    wasi->writeUInt64(memory, stats.st_nlink, buf + 24);
-    wasi->writeUInt64(memory, stats.st_size, buf + 32);
-    wasi->writeUInt64(memory, stats.st_atim, buf + 40);
-    wasi->writeUInt64(memory, stats.st_mtim, buf + 48);
-    wasi->writeUInt64(memory, stats.st_ctim, buf + 56);
-  }
+  if (err == UVWASI_ESUCCESS)
+    uvwasi_serdes_write_filestat_t(memory, buf, &stats);
 
   args.GetReturnValue().Set(err);
 }
@@ -642,42 +656,30 @@ void WASI::FdPread(const FunctionCallbackInfo<Value>& args) {
         offset,
         nread_ptr);
   GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
-  CHECK_BOUNDS_OR_RETURN(args, mem_size, iovs_ptr, iovs_len * 8);
-  CHECK_BOUNDS_OR_RETURN(args, mem_size, nread_ptr, 4);
+  CHECK_BOUNDS_OR_RETURN(args,
+                         mem_size,
+                         iovs_ptr,
+                         iovs_len * UVWASI_SERDES_SIZE_iovec_t);
+  CHECK_BOUNDS_OR_RETURN(args, mem_size, nread_ptr, UVWASI_SERDES_SIZE_size_t);
   uvwasi_iovec_t* iovs = UncheckedCalloc<uvwasi_iovec_t>(iovs_len);
+  uvwasi_errno_t err;
 
   if (iovs == nullptr) {
     args.GetReturnValue().Set(UVWASI_ENOMEM);
     return;
   }
 
-  for (uint32_t i = 0; i < iovs_len; ++i) {
-    uint32_t buf_ptr;
-    uint32_t buf_len;
-
-    wasi->readUInt32(memory, &buf_ptr, iovs_ptr);
-    wasi->readUInt32(memory, &buf_len, iovs_ptr + 4);
-
-    if (is_access_oob(mem_size, buf_ptr, buf_len)) {
-      free(iovs);
-      args.GetReturnValue().Set(UVWASI_EOVERFLOW);
-      return;
-    }
-
-    iovs_ptr += 8;
-    iovs[i].buf = static_cast<void*>(&memory[buf_ptr]);
-    iovs[i].buf_len = buf_len;
+  err = uvwasi_serdes_readv_iovec_t(memory, mem_size, iovs_ptr, iovs, iovs_len);
+  if (err != UVWASI_ESUCCESS) {
+    free(iovs);
+    args.GetReturnValue().Set(err);
+    return;
   }
 
-  size_t nread;
-  uvwasi_errno_t err = uvwasi_fd_pread(&wasi->uvw_,
-                                       fd,
-                                       iovs,
-                                       iovs_len,
-                                       offset,
-                                       &nread);
+  uvwasi_size_t nread;
+  err = uvwasi_fd_pread(&wasi->uvw_, fd, iovs, iovs_len, offset, &nread);
   if (err == UVWASI_ESUCCESS)
-    wasi->writeUInt32(memory, nread, nread_ptr);
+    uvwasi_serdes_write_size_t(memory, nread_ptr, nread);
 
   free(iovs);
   args.GetReturnValue().Set(err);
@@ -696,14 +698,12 @@ void WASI::FdPrestatGet(const FunctionCallbackInfo<Value>& args) {
   ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
   Debug(wasi, "fd_prestat_get(%d, %d)\n", fd, buf);
   GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
-  CHECK_BOUNDS_OR_RETURN(args, mem_size, buf, 8);
+  CHECK_BOUNDS_OR_RETURN(args, mem_size, buf, UVWASI_SERDES_SIZE_prestat_t);
   uvwasi_prestat_t prestat;
   uvwasi_errno_t err = uvwasi_fd_prestat_get(&wasi->uvw_, fd, &prestat);
 
-  if (err == UVWASI_ESUCCESS) {
-    wasi->writeUInt32(memory, prestat.pr_type, buf);
-    wasi->writeUInt32(memory, prestat.u.dir.pr_name_len, buf + 4);
-  }
+  if (err == UVWASI_ESUCCESS)
+    uvwasi_serdes_write_prestat_t(memory, buf, &prestat);
 
   args.GetReturnValue().Set(err);
 }
@@ -756,42 +756,37 @@ void WASI::FdPwrite(const FunctionCallbackInfo<Value>& args) {
         offset,
         nwritten_ptr);
   GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
-  CHECK_BOUNDS_OR_RETURN(args, mem_size, iovs_ptr, iovs_len * 8);
-  CHECK_BOUNDS_OR_RETURN(args, mem_size, nwritten_ptr, 4);
+  CHECK_BOUNDS_OR_RETURN(args,
+                         mem_size,
+                         iovs_ptr,
+                         iovs_len * UVWASI_SERDES_SIZE_ciovec_t);
+  CHECK_BOUNDS_OR_RETURN(args,
+                         mem_size,
+                         nwritten_ptr,
+                         UVWASI_SERDES_SIZE_size_t);
   uvwasi_ciovec_t* iovs = UncheckedCalloc<uvwasi_ciovec_t>(iovs_len);
+  uvwasi_errno_t err;
 
   if (iovs == nullptr) {
     args.GetReturnValue().Set(UVWASI_ENOMEM);
     return;
   }
 
-  for (uint32_t i = 0; i < iovs_len; ++i) {
-    uint32_t buf_ptr;
-    uint32_t buf_len;
-
-    wasi->readUInt32(memory, &buf_ptr, iovs_ptr);
-    wasi->readUInt32(memory, &buf_len, iovs_ptr + 4);
-
-    if (is_access_oob(mem_size, buf_ptr, buf_len)) {
-      free(iovs);
-      args.GetReturnValue().Set(UVWASI_EOVERFLOW);
-      return;
-    }
-
-    iovs_ptr += 8;
-    iovs[i].buf = static_cast<void*>(&memory[buf_ptr]);
-    iovs[i].buf_len = buf_len;
+  err = uvwasi_serdes_readv_ciovec_t(memory,
+                                     mem_size,
+                                     iovs_ptr,
+                                     iovs,
+                                     iovs_len);
+  if (err != UVWASI_ESUCCESS) {
+    free(iovs);
+    args.GetReturnValue().Set(err);
+    return;
   }
 
-  size_t nwritten;
-  uvwasi_errno_t err = uvwasi_fd_pwrite(&wasi->uvw_,
-                                        fd,
-                                        iovs,
-                                        iovs_len,
-                                        offset,
-                                        &nwritten);
+  uvwasi_size_t nwritten;
+  err = uvwasi_fd_pwrite(&wasi->uvw_, fd, iovs, iovs_len, offset, &nwritten);
   if (err == UVWASI_ESUCCESS)
-    wasi->writeUInt32(memory, nwritten, nwritten_ptr);
+    uvwasi_serdes_write_size_t(memory, nwritten_ptr, nwritten);
 
   free(iovs);
   args.GetReturnValue().Set(err);
@@ -814,41 +809,30 @@ void WASI::FdRead(const FunctionCallbackInfo<Value>& args) {
   ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
   Debug(wasi, "fd_read(%d, %d, %d, %d)\n", fd, iovs_ptr, iovs_len, nread_ptr);
   GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
-  CHECK_BOUNDS_OR_RETURN(args, mem_size, iovs_ptr, iovs_len * 8);
-  CHECK_BOUNDS_OR_RETURN(args, mem_size, nread_ptr, 4);
+  CHECK_BOUNDS_OR_RETURN(args,
+                         mem_size,
+                         iovs_ptr,
+                         iovs_len * UVWASI_SERDES_SIZE_iovec_t);
+  CHECK_BOUNDS_OR_RETURN(args, mem_size, nread_ptr, UVWASI_SERDES_SIZE_size_t);
   uvwasi_iovec_t* iovs = UncheckedCalloc<uvwasi_iovec_t>(iovs_len);
+  uvwasi_errno_t err;
 
   if (iovs == nullptr) {
     args.GetReturnValue().Set(UVWASI_ENOMEM);
     return;
   }
 
-  for (uint32_t i = 0; i < iovs_len; ++i) {
-    uint32_t buf_ptr;
-    uint32_t buf_len;
-
-    wasi->readUInt32(memory, &buf_ptr, iovs_ptr);
-    wasi->readUInt32(memory, &buf_len, iovs_ptr + 4);
-
-    if (is_access_oob(mem_size, buf_ptr, buf_len)) {
-      free(iovs);
-      args.GetReturnValue().Set(UVWASI_EOVERFLOW);
-      return;
-    }
-
-    iovs_ptr += 8;
-    iovs[i].buf = static_cast<void*>(&memory[buf_ptr]);
-    iovs[i].buf_len = buf_len;
+  err = uvwasi_serdes_readv_iovec_t(memory, mem_size, iovs_ptr, iovs, iovs_len);
+  if (err != UVWASI_ESUCCESS) {
+    free(iovs);
+    args.GetReturnValue().Set(err);
+    return;
   }
 
-  size_t nread;
-  uvwasi_errno_t err = uvwasi_fd_read(&wasi->uvw_,
-                                      fd,
-                                      iovs,
-                                      iovs_len,
-                                      &nread);
+  uvwasi_size_t nread;
+  err = uvwasi_fd_read(&wasi->uvw_, fd, iovs, iovs_len, &nread);
   if (err == UVWASI_ESUCCESS)
-    wasi->writeUInt32(memory, nread, nread_ptr);
+    uvwasi_serdes_write_size_t(memory, nread_ptr, nread);
 
   free(iovs);
   args.GetReturnValue().Set(err);
@@ -880,8 +864,11 @@ void WASI::FdReaddir(const FunctionCallbackInfo<Value>& args) {
         bufused_ptr);
   GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
   CHECK_BOUNDS_OR_RETURN(args, mem_size, buf_ptr, buf_len);
-  CHECK_BOUNDS_OR_RETURN(args, mem_size, bufused_ptr, 4);
-  size_t bufused;
+  CHECK_BOUNDS_OR_RETURN(args,
+                         mem_size,
+                         bufused_ptr,
+                         UVWASI_SERDES_SIZE_size_t);
+  uvwasi_size_t bufused;
   uvwasi_errno_t err = uvwasi_fd_readdir(&wasi->uvw_,
                                          fd,
                                          &memory[buf_ptr],
@@ -889,7 +876,7 @@ void WASI::FdReaddir(const FunctionCallbackInfo<Value>& args) {
                                          cookie,
                                          &bufused);
   if (err == UVWASI_ESUCCESS)
-    wasi->writeUInt32(memory, bufused, bufused_ptr);
+    uvwasi_serdes_write_size_t(memory, bufused_ptr, bufused);
 
   args.GetReturnValue().Set(err);
 }
@@ -925,7 +912,10 @@ void WASI::FdSeek(const FunctionCallbackInfo<Value>& args) {
   ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
   Debug(wasi, "fd_seek(%d, %d, %d, %d)\n", fd, offset, whence, newoffset_ptr);
   GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
-  CHECK_BOUNDS_OR_RETURN(args, mem_size, newoffset_ptr, 8);
+  CHECK_BOUNDS_OR_RETURN(args,
+                         mem_size,
+                         newoffset_ptr,
+                         UVWASI_SERDES_SIZE_filesize_t);
   uvwasi_filesize_t newoffset;
   uvwasi_errno_t err = uvwasi_fd_seek(&wasi->uvw_,
                                       fd,
@@ -933,7 +923,7 @@ void WASI::FdSeek(const FunctionCallbackInfo<Value>& args) {
                                       whence,
                                       &newoffset);
   if (err == UVWASI_ESUCCESS)
-    wasi->writeUInt64(memory, newoffset, newoffset_ptr);
+    uvwasi_serdes_write_filesize_t(memory, newoffset_ptr, newoffset);
 
   args.GetReturnValue().Set(err);
 }
@@ -963,12 +953,15 @@ void WASI::FdTell(const FunctionCallbackInfo<Value>& args) {
   ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
   Debug(wasi, "fd_tell(%d, %d)\n", fd, offset_ptr);
   GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
-  CHECK_BOUNDS_OR_RETURN(args, mem_size, offset_ptr, 8);
+  CHECK_BOUNDS_OR_RETURN(args,
+                         mem_size,
+                         offset_ptr,
+                         UVWASI_SERDES_SIZE_filesize_t);
   uvwasi_filesize_t offset;
   uvwasi_errno_t err = uvwasi_fd_tell(&wasi->uvw_, fd, &offset);
 
   if (err == UVWASI_ESUCCESS)
-    wasi->writeUInt64(memory, offset, offset_ptr);
+    uvwasi_serdes_write_filesize_t(memory, offset_ptr, offset);
 
   args.GetReturnValue().Set(err);
 }
@@ -995,41 +988,37 @@ void WASI::FdWrite(const FunctionCallbackInfo<Value>& args) {
         iovs_len,
         nwritten_ptr);
   GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
-  CHECK_BOUNDS_OR_RETURN(args, mem_size, iovs_ptr, iovs_len * 8);
-  CHECK_BOUNDS_OR_RETURN(args, mem_size, nwritten_ptr, 4);
+  CHECK_BOUNDS_OR_RETURN(args,
+                         mem_size,
+                         iovs_ptr,
+                         iovs_len * UVWASI_SERDES_SIZE_ciovec_t);
+  CHECK_BOUNDS_OR_RETURN(args,
+                         mem_size,
+                         nwritten_ptr,
+                         UVWASI_SERDES_SIZE_size_t);
   uvwasi_ciovec_t* iovs = UncheckedCalloc<uvwasi_ciovec_t>(iovs_len);
+  uvwasi_errno_t err;
 
   if (iovs == nullptr) {
     args.GetReturnValue().Set(UVWASI_ENOMEM);
     return;
   }
 
-  for (uint32_t i = 0; i < iovs_len; ++i) {
-    uint32_t buf_ptr;
-    uint32_t buf_len;
-
-    wasi->readUInt32(memory, &buf_ptr, iovs_ptr);
-    wasi->readUInt32(memory, &buf_len, iovs_ptr + 4);
-
-    if (is_access_oob(mem_size, buf_ptr, buf_len)) {
-      free(iovs);
-      args.GetReturnValue().Set(UVWASI_EOVERFLOW);
-      return;
-    }
-
-    iovs_ptr += 8;
-    iovs[i].buf = static_cast<void*>(&memory[buf_ptr]);
-    iovs[i].buf_len = buf_len;
+  err = uvwasi_serdes_readv_ciovec_t(memory,
+                                     mem_size,
+                                     iovs_ptr,
+                                     iovs,
+                                     iovs_len);
+  if (err != UVWASI_ESUCCESS) {
+    free(iovs);
+    args.GetReturnValue().Set(err);
+    return;
   }
 
-  size_t nwritten;
-  uvwasi_errno_t err = uvwasi_fd_write(&wasi->uvw_,
-                                       fd,
-                                       iovs,
-                                       iovs_len,
-                                       &nwritten);
+  uvwasi_size_t nwritten;
+  err = uvwasi_fd_write(&wasi->uvw_, fd, iovs, iovs_len, &nwritten);
   if (err == UVWASI_ESUCCESS)
-    wasi->writeUInt32(memory, nwritten, nwritten_ptr);
+    uvwasi_serdes_write_size_t(memory, nwritten_ptr, nwritten);
 
   free(iovs);
   args.GetReturnValue().Set(err);
@@ -1082,7 +1071,10 @@ void WASI::PathFilestatGet(const FunctionCallbackInfo<Value>& args) {
         path_len);
   GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
   CHECK_BOUNDS_OR_RETURN(args, mem_size, path_ptr, path_len);
-  CHECK_BOUNDS_OR_RETURN(args, mem_size, buf_ptr, 64);
+  CHECK_BOUNDS_OR_RETURN(args,
+                         mem_size,
+                         buf_ptr,
+                         UVWASI_SERDES_SIZE_filestat_t);
   uvwasi_filestat_t stats;
   uvwasi_errno_t err = uvwasi_path_filestat_get(&wasi->uvw_,
                                                 fd,
@@ -1090,16 +1082,8 @@ void WASI::PathFilestatGet(const FunctionCallbackInfo<Value>& args) {
                                                 &memory[path_ptr],
                                                 path_len,
                                                 &stats);
-  if (err == UVWASI_ESUCCESS) {
-    wasi->writeUInt64(memory, stats.st_dev, buf_ptr);
-    wasi->writeUInt64(memory, stats.st_ino, buf_ptr + 8);
-    wasi->writeUInt8(memory, stats.st_filetype, buf_ptr + 16);
-    wasi->writeUInt64(memory, stats.st_nlink, buf_ptr + 24);
-    wasi->writeUInt64(memory, stats.st_size, buf_ptr + 32);
-    wasi->writeUInt64(memory, stats.st_atim, buf_ptr + 40);
-    wasi->writeUInt64(memory, stats.st_mtim, buf_ptr + 48);
-    wasi->writeUInt64(memory, stats.st_ctim, buf_ptr + 56);
-  }
+  if (err == UVWASI_ESUCCESS)
+    uvwasi_serdes_write_filestat_t(memory, buf_ptr, &stats);
 
   args.GetReturnValue().Set(err);
 }
@@ -1229,7 +1213,7 @@ void WASI::PathOpen(const FunctionCallbackInfo<Value>& args) {
         fd_ptr);
   GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
   CHECK_BOUNDS_OR_RETURN(args, mem_size, path_ptr, path_len);
-  CHECK_BOUNDS_OR_RETURN(args, mem_size, fd_ptr, 4);
+  CHECK_BOUNDS_OR_RETURN(args, mem_size, fd_ptr, UVWASI_SERDES_SIZE_fd_t);
   uvwasi_fd_t fd;
   uvwasi_errno_t err = uvwasi_path_open(&wasi->uvw_,
                                         dirfd,
@@ -1242,7 +1226,7 @@ void WASI::PathOpen(const FunctionCallbackInfo<Value>& args) {
                                         static_cast<uvwasi_fdflags_t>(fs_flags),
                                         &fd);
   if (err == UVWASI_ESUCCESS)
-    wasi->writeUInt32(memory, fd, fd_ptr);
+    uvwasi_serdes_write_size_t(memory, fd_ptr, fd);
 
   args.GetReturnValue().Set(err);
 }
@@ -1277,17 +1261,20 @@ void WASI::PathReadlink(const FunctionCallbackInfo<Value>& args) {
   GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
   CHECK_BOUNDS_OR_RETURN(args, mem_size, path_ptr, path_len);
   CHECK_BOUNDS_OR_RETURN(args, mem_size, buf_ptr, buf_len);
-  CHECK_BOUNDS_OR_RETURN(args, mem_size, bufused_ptr, 4);
-  size_t bufused;
+  CHECK_BOUNDS_OR_RETURN(args,
+                         mem_size,
+                         bufused_ptr,
+                         UVWASI_SERDES_SIZE_size_t);
+  uvwasi_size_t bufused;
   uvwasi_errno_t err = uvwasi_path_readlink(&wasi->uvw_,
-                                        fd,
-                                        &memory[path_ptr],
-                                        path_len,
-                                        &memory[buf_ptr],
-                                        buf_len,
-                                        &bufused);
+                                            fd,
+                                            &memory[path_ptr],
+                                            path_len,
+                                            &memory[buf_ptr],
+                                            buf_len,
+                                            &bufused);
   if (err == UVWASI_ESUCCESS)
-    wasi->writeUInt32(memory, bufused, bufused_ptr);
+    uvwasi_serdes_write_size_t(memory, bufused_ptr, bufused);
 
   args.GetReturnValue().Set(err);
 }
@@ -1436,9 +1423,18 @@ void WASI::PollOneoff(const FunctionCallbackInfo<Value>& args) {
         nsubscriptions,
         nevents_ptr);
   GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
-  CHECK_BOUNDS_OR_RETURN(args, mem_size, in_ptr, nsubscriptions * 48);
-  CHECK_BOUNDS_OR_RETURN(args, mem_size, out_ptr, nsubscriptions * 32);
-  CHECK_BOUNDS_OR_RETURN(args, mem_size, nevents_ptr, 4);
+  CHECK_BOUNDS_OR_RETURN(args,
+                         mem_size,
+                         in_ptr,
+                         nsubscriptions * UVWASI_SERDES_SIZE_subscription_t);
+  CHECK_BOUNDS_OR_RETURN(args,
+                         mem_size,
+                         out_ptr,
+                         nsubscriptions * UVWASI_SERDES_SIZE_event_t);
+  CHECK_BOUNDS_OR_RETURN(args,
+                         mem_size,
+                         nevents_ptr,
+                         UVWASI_SERDES_SIZE_size_t);
   uvwasi_subscription_t* in =
       UncheckedCalloc<uvwasi_subscription_t>(nsubscriptions);
 
@@ -1456,46 +1452,22 @@ void WASI::PollOneoff(const FunctionCallbackInfo<Value>& args) {
   }
 
   for (uint32_t i = 0; i < nsubscriptions; ++i) {
-    uvwasi_subscription_t* sub = &in[i];
-    wasi->readUInt64(memory, &sub->userdata, in_ptr);
-    wasi->readUInt8(memory, &sub->type, in_ptr + 8);
-
-    if (sub->type == UVWASI_EVENTTYPE_CLOCK) {
-      wasi->readUInt32(memory, &sub->u.clock.clock_id, in_ptr + 16);
-      wasi->readUInt64(memory, &sub->u.clock.timeout, in_ptr + 24);
-      wasi->readUInt64(memory, &sub->u.clock.precision, in_ptr + 32);
-      wasi->readUInt16(memory, &sub->u.clock.flags, in_ptr + 40);
-    } else if (sub->type == UVWASI_EVENTTYPE_FD_READ ||
-               sub->type == UVWASI_EVENTTYPE_FD_WRITE) {
-      wasi->readUInt32(memory, &sub->u.fd_readwrite.fd, in_ptr + 16);
-    }
-
-    in_ptr += 48;
+    uvwasi_serdes_read_subscription_t(memory, in_ptr, &in[i]);
+    in_ptr += UVWASI_SERDES_SIZE_subscription_t;
   }
 
-  size_t nevents;
+  uvwasi_size_t nevents;
   uvwasi_errno_t err = uvwasi_poll_oneoff(&wasi->uvw_,
                                           in,
                                           out,
                                           nsubscriptions,
                                           &nevents);
   if (err == UVWASI_ESUCCESS) {
-    wasi->writeUInt32(memory, nevents, nevents_ptr);
+    uvwasi_serdes_write_size_t(memory, nevents_ptr, nevents);
 
     for (uint32_t i = 0; i < nsubscriptions; ++i) {
-      uvwasi_event_t event = out[i];
-
-      wasi->writeUInt64(memory, event.userdata, out_ptr);
-      wasi->writeUInt16(memory, event.error, out_ptr + 8);
-      wasi->writeUInt8(memory, event.type, out_ptr + 10);
-
-      if (event.type == UVWASI_EVENTTYPE_FD_READ ||
-          event.type == UVWASI_EVENTTYPE_FD_WRITE) {
-        wasi->writeUInt64(memory, event.u.fd_readwrite.nbytes, out_ptr + 16);
-        wasi->writeUInt16(memory, event.u.fd_readwrite.flags, out_ptr + 24);
-      }
-
-      out_ptr += 32;
+      uvwasi_serdes_write_event_t(memory, out_ptr, &out[i]);
+      out_ptr += UVWASI_SERDES_SIZE_event_t;
     }
   }
 
@@ -1585,7 +1557,10 @@ void WASI::SockRecv(const FunctionCallbackInfo<Value>& args) {
         ro_datalen_ptr,
         ro_flags_ptr);
   GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
-  CHECK_BOUNDS_OR_RETURN(args, mem_size, ri_data_ptr, ri_data_len * 8);
+  CHECK_BOUNDS_OR_RETURN(args,
+                         mem_size,
+                         ri_data_ptr,
+                         ri_data_len * UVWASI_SERDES_SIZE_iovec_t);
   CHECK_BOUNDS_OR_RETURN(args, mem_size, ro_datalen_ptr, 4);
   CHECK_BOUNDS_OR_RETURN(args, mem_size, ro_flags_ptr, 4);
   uvwasi_iovec_t* ri_data = UncheckedCalloc<uvwasi_iovec_t>(ri_data_len);
@@ -1595,36 +1570,29 @@ void WASI::SockRecv(const FunctionCallbackInfo<Value>& args) {
     return;
   }
 
-  for (uint32_t i = 0; i < ri_data_len; ++i) {
-    uint32_t buf_ptr;
-    uint32_t buf_len;
-
-    wasi->readUInt32(memory, &buf_ptr, ri_data_ptr);
-    wasi->readUInt32(memory, &buf_len, ri_data_ptr + 4);
-
-    if (is_access_oob(mem_size, buf_ptr, buf_len)) {
-      free(ri_data);
-      args.GetReturnValue().Set(UVWASI_EOVERFLOW);
-      return;
-    }
-
-    ri_data_ptr += 8;
-    ri_data[i].buf = static_cast<void*>(&memory[buf_ptr]);
-    ri_data[i].buf_len = buf_len;
+  uvwasi_errno_t err = uvwasi_serdes_readv_iovec_t(memory,
+                                                   mem_size,
+                                                   ri_data_ptr,
+                                                   ri_data,
+                                                   ri_data_len);
+  if (err != UVWASI_ESUCCESS) {
+    free(ri_data);
+    args.GetReturnValue().Set(err);
+    return;
   }
 
-  size_t ro_datalen;
+  uvwasi_size_t ro_datalen;
   uvwasi_roflags_t ro_flags;
-  uvwasi_errno_t err = uvwasi_sock_recv(&wasi->uvw_,
-                                        sock,
-                                        ri_data,
-                                        ri_data_len,
-                                        ri_flags,
-                                        &ro_datalen,
-                                        &ro_flags);
+  err = uvwasi_sock_recv(&wasi->uvw_,
+                         sock,
+                         ri_data,
+                         ri_data_len,
+                         ri_flags,
+                         &ro_datalen,
+                         &ro_flags);
   if (err == UVWASI_ESUCCESS) {
-    wasi->writeUInt32(memory, ro_datalen, ro_datalen_ptr);
-    wasi->writeUInt32(memory, ro_flags, ro_flags_ptr);
+    uvwasi_serdes_write_size_t(memory, ro_datalen_ptr, ro_datalen);
+    uvwasi_serdes_write_roflags_t(memory, ro_flags_ptr, ro_flags);
   }
 
   free(ri_data);
@@ -1656,8 +1624,14 @@ void WASI::SockSend(const FunctionCallbackInfo<Value>& args) {
         si_flags,
         so_datalen_ptr);
   GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
-  CHECK_BOUNDS_OR_RETURN(args, mem_size, si_data_ptr, si_data_len * 8);
-  CHECK_BOUNDS_OR_RETURN(args, mem_size, so_datalen_ptr, 4);
+  CHECK_BOUNDS_OR_RETURN(args,
+                         mem_size,
+                         si_data_ptr,
+                         si_data_len * UVWASI_SERDES_SIZE_ciovec_t);
+  CHECK_BOUNDS_OR_RETURN(args,
+                         mem_size,
+                         so_datalen_ptr,
+                         UVWASI_SERDES_SIZE_size_t);
   uvwasi_ciovec_t* si_data = UncheckedCalloc<uvwasi_ciovec_t>(si_data_len);
 
   if (si_data == nullptr) {
@@ -1665,33 +1639,26 @@ void WASI::SockSend(const FunctionCallbackInfo<Value>& args) {
     return;
   }
 
-  for (uint32_t i = 0; i < si_data_len; ++i) {
-    uint32_t buf_ptr;
-    uint32_t buf_len;
-
-    wasi->readUInt32(memory, &buf_ptr, si_data_ptr);
-    wasi->readUInt32(memory, &buf_len, si_data_ptr + 4);
-
-    if (is_access_oob(mem_size, buf_ptr, buf_len)) {
-      free(si_data);
-      args.GetReturnValue().Set(UVWASI_EOVERFLOW);
-      return;
-    }
-
-    si_data_ptr += 8;
-    si_data[i].buf = static_cast<void*>(&memory[buf_ptr]);
-    si_data[i].buf_len = buf_len;
+  uvwasi_errno_t err = uvwasi_serdes_readv_ciovec_t(memory,
+                                                    mem_size,
+                                                    si_data_ptr,
+                                                    si_data,
+                                                    si_data_len);
+  if (err != UVWASI_ESUCCESS) {
+    free(si_data);
+    args.GetReturnValue().Set(err);
+    return;
   }
 
-  size_t so_datalen;
-  uvwasi_errno_t err = uvwasi_sock_send(&wasi->uvw_,
-                                        sock,
-                                        si_data,
-                                        si_data_len,
-                                        si_flags,
-                                        &so_datalen);
+  uvwasi_size_t so_datalen;
+  err = uvwasi_sock_send(&wasi->uvw_,
+                         sock,
+                         si_data,
+                         si_data_len,
+                         si_flags,
+                         &so_datalen);
   if (err == UVWASI_ESUCCESS)
-    wasi->writeUInt32(memory, so_datalen, so_datalen_ptr);
+    uvwasi_serdes_write_size_t(memory, so_datalen_ptr, so_datalen);
 
   free(si_data);
   args.GetReturnValue().Set(err);
@@ -1721,81 +1688,6 @@ void WASI::_SetMemory(const FunctionCallbackInfo<Value>& args) {
 }
 
 
-void WASI::readUInt8(char* memory, uint8_t* value, uint32_t offset) {
-  CHECK_NOT_NULL(memory);
-  CHECK_NOT_NULL(value);
-  *value = memory[offset] & 0xFF;
-}
-
-
-void WASI::readUInt16(char* memory, uint16_t* value, uint32_t offset) {
-  CHECK_NOT_NULL(memory);
-  CHECK_NOT_NULL(value);
-  *value = (memory[offset] & 0xFF) |
-           ((memory[offset + 1] & 0xFF) << 8);
-}
-
-
-void WASI::readUInt32(char* memory, uint32_t* value, uint32_t offset) {
-  CHECK_NOT_NULL(memory);
-  CHECK_NOT_NULL(value);
-  *value = (memory[offset] & 0xFF) |
-           ((memory[offset + 1] & 0xFF) << 8) |
-           ((memory[offset + 2] & 0xFF) << 16) |
-           ((memory[offset + 3] & 0xFF) << 24);
-}
-
-
-void WASI::readUInt64(char* memory, uint64_t* value, uint32_t offset) {
-  CHECK_NOT_NULL(memory);
-  CHECK_NOT_NULL(value);
-  uint64_t low = (memory[offset] & 0xFF) |
-                 ((memory[offset + 1] & 0xFF) << 8) |
-                 ((memory[offset + 2] & 0xFF) << 16) |
-                 ((memory[offset + 3] & 0xFF) << 24);
-  uint64_t high = (memory[offset + 4] & 0xFF) |
-                  ((memory[offset + 5] & 0xFF) << 8) |
-                  ((memory[offset + 6] & 0xFF) << 16) |
-                  ((memory[offset + 7] & 0xFF) << 24);
-  *value = (high << 32) + low;
-}
-
-
-void WASI::writeUInt8(char* memory, uint8_t value, uint32_t offset) {
-  CHECK_NOT_NULL(memory);
-  memory[offset] = value & 0xFF;
-}
-
-
-void WASI::writeUInt16(char* memory, uint16_t value, uint32_t offset) {
-  CHECK_NOT_NULL(memory);
-  memory[offset++] = value & 0xFF;
-  memory[offset] = (value >> 8) & 0xFF;
-}
-
-
-void WASI::writeUInt32(char* memory, uint32_t value, uint32_t offset) {
-  CHECK_NOT_NULL(memory);
-  memory[offset++] = value & 0xFF;
-  memory[offset++] = (value >> 8) & 0xFF;
-  memory[offset++] = (value >> 16) & 0xFF;
-  memory[offset] = (value >> 24) & 0xFF;
-}
-
-
-void WASI::writeUInt64(char* memory, uint64_t value, uint32_t offset) {
-  CHECK_NOT_NULL(memory);
-  memory[offset++] = value & 0xFF;
-  memory[offset++] = (value >> 8) & 0xFF;
-  memory[offset++] = (value >> 16) & 0xFF;
-  memory[offset++] = (value >> 24) & 0xFF;
-  memory[offset++] = (value >> 32) & 0xFF;
-  memory[offset++] = (value >> 40) & 0xFF;
-  memory[offset++] = (value >> 48) & 0xFF;
-  memory[offset] = (value >> 56) & 0xFF;
-}
-
-
 uvwasi_errno_t WASI::backingStore(char** store, size_t* byte_length) {
   Environment* env = this->env();
   Local<Object> memory = PersistentToLocal::Strong(this->memory_);
@@ -1811,6 +1703,7 @@ uvwasi_errno_t WASI::backingStore(char** store, size_t* byte_length) {
   std::shared_ptr<BackingStore> backing_store = ab->GetBackingStore();
   *byte_length = backing_store->ByteLength();
   *store = static_cast<char*>(backing_store->Data());
+  CHECK_NOT_NULL(*store);
   return UVWASI_ESUCCESS;
 }