Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wasi: introduce initial WASI support #30258

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -1503,3 +1503,28 @@ The externally maintained libraries used by Node.js are:
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
"""

- uvwasi, located at deps/uvwasi, is licensed as follows:
"""
MIT License

Copyright (c) 2019 Colin Ihrig and Contributors

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
"""
21 changes: 21 additions & 0 deletions deps/uvwasi/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2019 Colin Ihrig and Contributors

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
13 changes: 13 additions & 0 deletions deps/uvwasi/include/clocks.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#ifndef __UVWASI_CLOCKS_H__
#define __UVWASI_CLOCKS_H__

#include "wasi_types.h"

uvwasi_errno_t uvwasi__clock_gettime_realtime(uvwasi_timestamp_t* time);
uvwasi_errno_t uvwasi__clock_gettime_process_cputime(uvwasi_timestamp_t* time);
uvwasi_errno_t uvwasi__clock_gettime_thread_cputime(uvwasi_timestamp_t* time);

uvwasi_errno_t uvwasi__clock_getres_process_cputime(uvwasi_timestamp_t* time);
uvwasi_errno_t uvwasi__clock_getres_thread_cputime(uvwasi_timestamp_t* time);

#endif /* __UVWASI_CLOCKS_H__ */
60 changes: 60 additions & 0 deletions deps/uvwasi/include/fd_table.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#ifndef __UVWASI_FD_TABLE_H__
#define __UVWASI_FD_TABLE_H__

#include <stdint.h>
#include "uv.h"
#include "wasi_types.h"
#include "uv_mapping.h"

/* TODO(cjihrig): PATH_MAX_BYTES shouldn't be stack allocated. On Windows, paths
can be 32k long, and this PATH_MAX_BYTES is an artificial limitation. */
#ifdef _WIN32
/* MAX_PATH is in characters, not bytes. Make sure we have enough headroom. */
# define PATH_MAX_BYTES (MAX_PATH * 4)
#else
# include <limits.h>
# define PATH_MAX_BYTES (PATH_MAX)
#endif


struct uvwasi_fd_wrap_t {
uvwasi_fd_t id;
uv_file fd;
char path[PATH_MAX_BYTES];
char real_path[PATH_MAX_BYTES];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is uvwasi ABI-stable at this point, or are breaking changes fine? I’d maybe open a PR against it to make these pointers, both to avoid artificial limitations on the max path lengths and to avoid the large memory overhead that this is likely to have?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Breaking changes are totally fine at this point 😄

uvwasi_filetype_t type;
uvwasi_rights_t rights_base;
uvwasi_rights_t rights_inheriting;
int preopen;
int valid;
};

struct uvwasi_fd_table_t {
struct uvwasi_fd_wrap_t* fds;
uint32_t size;
uint32_t used;
};

uvwasi_errno_t uvwasi_fd_table_init(struct uvwasi_fd_table_t* table,
uint32_t init_size);
void uvwasi_fd_table_free(struct uvwasi_fd_table_t* table);
uvwasi_errno_t uvwasi_fd_table_insert_preopen(struct uvwasi_fd_table_t* table,
const uv_file fd,
const char* path,
const char* real_path);
uvwasi_errno_t uvwasi_fd_table_insert_fd(struct uvwasi_fd_table_t* table,
const uv_file fd,
const int flags,
const char* path,
uvwasi_rights_t rights_base,
uvwasi_rights_t rights_inheriting,
struct uvwasi_fd_wrap_t* wrap);
uvwasi_errno_t uvwasi_fd_table_get(const struct uvwasi_fd_table_t* table,
const uvwasi_fd_t id,
struct uvwasi_fd_wrap_t** wrap,
uvwasi_rights_t rights_base,
uvwasi_rights_t rights_inheriting);
uvwasi_errno_t uvwasi_fd_table_remove(struct uvwasi_fd_table_t* table,
const uvwasi_fd_t id);

#endif /* __UVWASI_FD_TABLE_H__ */
15 changes: 15 additions & 0 deletions deps/uvwasi/include/uv_mapping.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#ifndef __UVWASI_UV_MAPPING_H__
#define __UVWASI_UV_MAPPING_H__

#include "uv.h"
#include "wasi_types.h"

#define NANOS_PER_SEC 1000000000

uvwasi_errno_t uvwasi__translate_uv_error(int err);
int uvwasi__translate_to_uv_signal(uvwasi_signal_t sig);
uvwasi_timestamp_t uvwasi__timespec_to_timestamp(const uv_timespec_t* ts);
uvwasi_filetype_t uvwasi__stat_to_filetype(const uv_stat_t* stat);
void uvwasi__stat_to_filestat(const uv_stat_t* stat, uvwasi_filestat_t* fs);

#endif /* __UVWASI_UV_MAPPING_H__ */
252 changes: 252 additions & 0 deletions deps/uvwasi/include/uvwasi.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,252 @@
#ifndef __UVWASI_H__
#define __UVWASI_H__

#ifdef __cplusplus
extern "C" {
#endif

#include "wasi_types.h"
#include "uv_mapping.h"
#include "fd_table.h"

#define UVWASI_VERSION_MAJOR 0
#define UVWASI_VERSION_MINOR 0
#define UVWASI_VERSION_PATCH 1
#define UVWASI_VERSION_HEX ((UVWASI_VERSION_MAJOR << 16) | \
(UVWASI_VERSION_MINOR << 8) | \
(UVWASI_VERSION_PATCH))
#define UVWASI_STRINGIFY(v) UVWASI_STRINGIFY_HELPER(v)
#define UVWASI_STRINGIFY_HELPER(v) #v
#define UVWASI_VERSION_STRING UVWASI_STRINGIFY(UVWASI_VERSION_MAJOR) "." \
UVWASI_STRINGIFY(UVWASI_VERSION_MINOR) "." \
UVWASI_STRINGIFY(UVWASI_VERSION_PATCH)


typedef struct uvwasi_s {
struct uvwasi_fd_table_t fds;
size_t argc;
char** argv;
char* argv_buf;
size_t argv_buf_size;
size_t envc;
char** env;
char* env_buf;
size_t env_buf_size;
} uvwasi_t;

typedef struct uvwasi_preopen_s {
char* mapped_path;
char* real_path;
} uvwasi_preopen_t;

typedef struct uvwasi_options_s {
size_t fd_table_size;
size_t preopenc;
uvwasi_preopen_t* preopens;
size_t argc;
char** argv;
char** envp;
} uvwasi_options_t;


// Embedder API.
uvwasi_errno_t uvwasi_init(uvwasi_t* uvwasi, uvwasi_options_t* options);
void uvwasi_destroy(uvwasi_t* uvwasi);
uvwasi_errno_t uvwasi_embedder_remap_fd(uvwasi_t* uvwasi,
const uvwasi_fd_t fd,
uv_file new_host_fd);


// 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_errno_t uvwasi_clock_res_get(uvwasi_t* uvwasi,
uvwasi_clockid_t clock_id,
uvwasi_timestamp_t* resolution);
uvwasi_errno_t uvwasi_clock_time_get(uvwasi_t* uvwasi,
uvwasi_clockid_t clock_id,
uvwasi_timestamp_t precision,
uvwasi_timestamp_t* time);
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_errno_t uvwasi_fd_advise(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
uvwasi_filesize_t offset,
uvwasi_filesize_t len,
uvwasi_advice_t advice);
uvwasi_errno_t uvwasi_fd_allocate(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
uvwasi_filesize_t offset,
uvwasi_filesize_t len);
uvwasi_errno_t uvwasi_fd_close(uvwasi_t* uvwasi, uvwasi_fd_t fd);
uvwasi_errno_t uvwasi_fd_datasync(uvwasi_t* uvwasi, uvwasi_fd_t fd);
uvwasi_errno_t uvwasi_fd_fdstat_get(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
uvwasi_fdstat_t* buf);
uvwasi_errno_t uvwasi_fd_fdstat_set_flags(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
uvwasi_fdflags_t flags);
uvwasi_errno_t uvwasi_fd_fdstat_set_rights(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
uvwasi_rights_t fs_rights_base,
uvwasi_rights_t fs_rights_inheriting
);
uvwasi_errno_t uvwasi_fd_filestat_get(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
uvwasi_filestat_t* buf);
uvwasi_errno_t uvwasi_fd_filestat_set_size(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
uvwasi_filesize_t st_size);
uvwasi_errno_t uvwasi_fd_filestat_set_times(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
uvwasi_timestamp_t st_atim,
uvwasi_timestamp_t st_mtim,
uvwasi_fstflags_t fst_flags);
uvwasi_errno_t uvwasi_fd_pread(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
const uvwasi_iovec_t* iovs,
size_t iovs_len,
uvwasi_filesize_t offset,
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_errno_t uvwasi_fd_pwrite(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
const uvwasi_ciovec_t* iovs,
size_t iovs_len,
uvwasi_filesize_t offset,
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_errno_t uvwasi_fd_readdir(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
void* buf,
size_t buf_len,
uvwasi_dircookie_t cookie,
size_t* bufused);
uvwasi_errno_t uvwasi_fd_renumber(uvwasi_t* uvwasi,
uvwasi_fd_t from,
uvwasi_fd_t to);
uvwasi_errno_t uvwasi_fd_seek(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
uvwasi_filedelta_t offset,
uvwasi_whence_t whence,
uvwasi_filesize_t* newoffset);
uvwasi_errno_t uvwasi_fd_sync(uvwasi_t* uvwasi, uvwasi_fd_t fd);
uvwasi_errno_t uvwasi_fd_tell(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
uvwasi_filesize_t* offset);
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_errno_t uvwasi_path_create_directory(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
const char* path,
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_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_timestamp_t st_atim,
uvwasi_timestamp_t st_mtim,
uvwasi_fstflags_t fst_flags);
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_fd_t new_fd,
const char* new_path,
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_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);
uvwasi_errno_t uvwasi_path_readlink(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
const char* path,
size_t path_len,
char* buf,
size_t buf_len,
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_errno_t uvwasi_path_rename(uvwasi_t* uvwasi,
uvwasi_fd_t old_fd,
const char* old_path,
size_t old_path_len,
uvwasi_fd_t new_fd,
const char* new_path,
size_t new_path_len);
uvwasi_errno_t uvwasi_path_symlink(uvwasi_t* uvwasi,
const char* old_path,
size_t old_path_len,
uvwasi_fd_t fd,
const char* new_path,
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_errno_t uvwasi_poll_oneoff(uvwasi_t* uvwasi,
const uvwasi_subscription_t* in,
uvwasi_event_t* out,
size_t nsubscriptions,
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_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_riflags_t ri_flags,
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_siflags_t si_flags,
size_t* so_datalen);
uvwasi_errno_t uvwasi_sock_shutdown(uvwasi_t* uvwasi,
uvwasi_fd_t sock,
uvwasi_sdflags_t how);

#ifdef __cplusplus
}
#endif

#endif /* __UVWASI_H__ */
Loading