Skip to content
Merged
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
4 changes: 2 additions & 2 deletions expected/wasm32-wasip3/defined-symbols.txt
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ __wasilibc_parse_port
__wasilibc_populate_preopens
__wasilibc_pthread_self
__wasilibc_random
__wasilibc_read_stream3
__wasilibc_read
__wasilibc_rename_newat
__wasilibc_rename_oldat
__wasilibc_reset_preopens
Expand All @@ -345,7 +345,7 @@ __wasilibc_unspecified_addr
__wasilibc_utimens
__wasilibc_wasi_family_to_libc
__wasilibc_wasi_to_sockaddr
__wasilibc_write_stream3
__wasilibc_write
__wasm_call_dtors
__wcscoll_l
__wcsftime_l
Expand Down
3 changes: 1 addition & 2 deletions libc-bottom-half/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ else()
sources/descriptor_table.c
sources/getsockpeername.c
sources/listen.c
sources/file_utils.c
sources/recv.c
sources/send.c
sources/shutdown.c
Expand All @@ -155,7 +156,6 @@ if(WASI STREQUAL "p2")
sources/netdb.c
sources/wasip2.c
sources/wasip2_file.c
sources/wasip2_file_utils.c
sources/wasip2_stdio.c
)
endif()
Expand All @@ -165,7 +165,6 @@ if (WASI STREQUAL "p3")
sources/wasip3.c
sources/wasip3_block_on.c
sources/wasip3_file.c
sources/wasip3_file_utils.c
sources/wasip3_stdio.c
)
endif()
Expand Down
4 changes: 2 additions & 2 deletions libc-bottom-half/cloudlibc/src/libc/poll/poll.c
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ static int poll_impl(struct pollfd *fds, size_t nfds, int timeout) {

if (pollfd->events & POLLRDNORM) {
if (entry->vtable->get_read_stream) {
wasip2_read_t read;
wasi_read_t read;
if (entry->vtable->get_read_stream(entry->data, &read) < 0)
return -1;
if (__wasilibc_poll_add_input_stream(&state, read.input, read.pollable) < 0)
Expand All @@ -229,7 +229,7 @@ static int poll_impl(struct pollfd *fds, size_t nfds, int timeout) {

if (pollfd->events & POLLWRNORM) {
if (entry->vtable->get_write_stream) {
wasip2_write_t write;
wasi_write_t write;
if (entry->vtable->get_write_stream(entry->data, &write) < 0)
return -1;
if (__wasilibc_poll_add_output_stream(&state, write.output, write.pollable) < 0)
Expand Down
29 changes: 2 additions & 27 deletions libc-bottom-half/cloudlibc/src/libc/unistd/read.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,12 @@ ssize_t read(int fildes, void *buf, size_t nbyte) {
return -1;
}
return bytes_read;
#elif defined(__wasip2__)
#else
descriptor_table_entry_t *entry = descriptor_table_get_ref(fildes);
if (!entry)
return -1;
if (entry->vtable->get_read_stream) {
wasip2_read_t read;
wasi_read_t read;
if (entry->vtable->get_read_stream(entry->data, &read) < 0)
return -1;
return __wasilibc_read(&read, buf, nbyte);
Expand All @@ -41,30 +41,5 @@ ssize_t read(int fildes, void *buf, size_t nbyte) {
return entry->vtable->recvfrom(entry->data, buf, nbyte, 0, NULL, NULL);
errno = EOPNOTSUPP;
return -1;
#elif defined(__wasip3__)
filesystem_tuple2_stream_u8_future_result_void_error_code_t *stream;
off_t *off;
if (__wasilibc_read_stream3(fildes, &stream, &off)<0)
return -1;
wasip3_waitable_status_t status =
filesystem_stream_u8_read(stream->f0, buf, nbyte);
size_t amount = wasip3_waitable_block_on(status, stream->f0);
if (amount > 0 || nbyte == 0) {
if (off)
*off += amount;
return amount;
} else {
filesystem_result_void_error_code_t error;
status = filesystem_future_result_void_error_code_read(stream->f1, &error);
amount = wasip3_waitable_block_on(status, stream->f1);
if (amount > 0 && error.is_err) {
translate_error(error.val.err);
return -1;
}
// EOF
return 0;
}
#else
# error "Unsupported WASI version"
#endif
}
32 changes: 2 additions & 30 deletions libc-bottom-half/cloudlibc/src/libc/unistd/write.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@ ssize_t write(int fildes, const void *buf, size_t nbyte) {
return -1;
}
return bytes_written;
#elif defined(__wasip2__)
#else
descriptor_table_entry_t *entry = descriptor_table_get_ref(fildes);
if (!entry)
return -1;
if (entry->vtable->get_write_stream) {
wasip2_write_t write;
wasi_write_t write;
if (entry->vtable->get_write_stream(entry->data, &write) < 0)
return -1;
return __wasilibc_write(&write, buf, nbyte);
Expand All @@ -42,33 +42,5 @@ ssize_t write(int fildes, const void *buf, size_t nbyte) {
return entry->vtable->sendto(entry->data, buf, nbyte, 0, NULL, 0);
errno = EOPNOTSUPP;
return -1;
#elif defined(__wasip3__)
wasip3_write_t *write_end;
off_t *off;
if (__wasilibc_write_stream3(fildes, &write_end, &off) < 0)
return -1;
if (WASIP3_SUBTASK_STATE(write_end->subtask) == WASIP3_SUBTASK_STARTING ||
WASIP3_SUBTASK_STATE(write_end->subtask) == WASIP3_SUBTASK_STARTED) {
// the stream is still active
wasip3_waitable_status_t status =
filesystem_stream_u8_write(write_end->output, buf, nbyte);
size_t amount = wasip3_waitable_block_on(status, write_end->output);
if (amount > 0 || nbyte == 0) {
if (off)
*off += amount;
return amount;
}
// error or eof
wasip3_subtask_block_on(write_end->subtask);
write_end->subtask = WASIP3_SUBTASK_RETURNED;
}
if (write_end->pending_result.is_err) {
translate_error(write_end->pending_result.val.err);
return -1;
}
// EOF
return 0;
#else
# error "Unknown WASI version"
#endif
}
64 changes: 32 additions & 32 deletions libc-bottom-half/headers/private/wasi/descriptor_table.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,48 +8,54 @@
#include <sys/stat.h>
#include <netinet/in.h>

#ifdef __wasip2__
// Metadata for WASI reads which is used to delegate to `__wasilibc_read(...)`
// to perform the actual read of a stream.
typedef struct wasip2_read_t {
// The `wasi:io/streams.input-stream` that this is reading from.
streams_borrow_input_stream_t input;
typedef struct wasi_read_t {
// An optional pointer to the internal offset of this stream, updated on
// successful reads.
off_t *offset;
// A required pointer to an owned pollable for `input`. This is lazily
// initialized as-necessary.
poll_own_pollable_t *pollable;
// Whether or not this read will use blocking I/O.
bool blocking;
// The timeout, in nanoseconds, for this operation.
monotonic_clock_duration_t timeout;
} wasip2_read_t;
#ifdef __wasip2__
// The `wasi:io/streams.input-stream` that this is reading from.
streams_borrow_input_stream_t input;
// A required pointer to an owned pollable for `input`. This is lazily
// initialized as-necessary.
poll_own_pollable_t *pollable;
#else
// The `stream<u8>` that's being read.
filesystem_stream_u8_t stream;

// A callback/ptr pair to invoke when EOF is reached to set errno and return
// an error code.
int (*eof)(void*);
void *eof_data;
#endif
} wasi_read_t;

// Same as `wasip2_read_t`, but for writes.
typedef struct wasip2_write_t {
streams_borrow_output_stream_t output;
// Same as `wasip_read_t`, but for writes.
typedef struct wasi_write_t {
off_t *offset;
poll_own_pollable_t *pollable;
bool blocking;
monotonic_clock_duration_t timeout;
} wasip2_write_t;
#endif

#ifdef __wasip3__
// create an alias to distinguish the handle type in the API
typedef uint32_t waitable_t;

/**
* This data structure represents the write end of a file
*/
typedef struct wasip3_write_t {
#ifdef __wasip2__
streams_borrow_output_stream_t output;
poll_own_pollable_t *pollable;
#else
filesystem_stream_u8_writer_t output;
// contents will be filled by host (once write has an error)
filesystem_result_void_error_code_t pending_result;
// this task gets ready on error or eof
wasip3_subtask_t subtask;
} wasip3_write_t;
wasip3_subtask_t *subtask;
#endif
} wasi_write_t;

#ifdef __wasip3__
// create an alias to distinguish the handle type in the API
typedef uint32_t waitable_t;
#endif

/**
Expand All @@ -71,18 +77,12 @@ typedef struct descriptor_vtable_t {
// =====================================================================
// Generic I/O

#ifdef __wasip2__
/// Looks up metadata to perform a read operation for this stream. This is used
/// to implement the `read` syscall, for example, and is also used with `poll`
/// when waiting for readability.
int (*get_read_stream)(void*, wasip2_read_t*);
int (*get_read_stream)(void*, wasi_read_t*);
/// Same as `get_read_stream`, but for output streams.
int (*get_write_stream)(void*, wasip2_write_t*);
#endif
#ifdef __wasip3__
int (*get_read_stream3)(void*, filesystem_tuple2_stream_u8_future_result_void_error_code_t **out, off_t** off);
int (*get_write_stream3)(void*, wasip3_write_t **write_end, off_t**);
#endif
int (*get_write_stream)(void*, wasi_write_t*);

/// Sets the nonblocking flag for this object to the specified value.
int (*set_blocking)(void*, bool);
Expand Down
21 changes: 5 additions & 16 deletions libc-bottom-half/headers/private/wasi/file_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@
#define __wasi_file_utils_h

#include <wasi/version.h>

#if defined(__wasip2__) || defined(__wasip3__)

#include <assert.h>
#include <wasi/wasip2.h>
#include <wasi/descriptor_table.h>
#include <dirent.h>
#include <fcntl.h>
#include <errno.h>
#endif

#ifdef __wasip2__
/// Handles a `wasi:io/streams.stream-error` for a `read`-style operation.
Expand Down Expand Up @@ -50,7 +49,6 @@ static inline int wasip2_handle_write_error(streams_stream_error_t error) {
int wasip2_string_from_c(const char *s, wasip2_string_t* out);
#endif

#if defined(__wasip2__) || defined(__wasip3__)
// Succeed only if fd is bound to a file handle in the descriptor table
static inline int fd_to_file_handle(int fd, filesystem_borrow_descriptor_t* result) {
descriptor_table_entry_t* entry = descriptor_table_get_ref(fd);
Expand All @@ -62,25 +60,16 @@ static inline int fd_to_file_handle(int fd, filesystem_borrow_descriptor_t* resu
}
return entry->vtable->get_file(entry->data, result);
}
#endif

#ifdef __wasip2__
// Reads from `read` into `buf`/`len`
//
// This perform the read configured by `read`, e.g. whether it's blocking or
// not, and places the result in the specified buffer. Used to implement
// `read` and `recvfrom`, for example.
ssize_t __wasilibc_read(wasip2_read_t *read, void *buf, size_t len);
ssize_t __wasilibc_read(wasi_read_t *read, void *buf, size_t len);
// Same as `__wasilibc_read`, but for writes.
ssize_t __wasilibc_write(wasip2_write_t *write, const void *buf, size_t len);
#endif

#ifdef __wasip3__
int __wasilibc_write_stream3(int fildes, wasip3_write_t **write_end, off_t **off);
int __wasilibc_read_stream3(int fildes, filesystem_tuple2_stream_u8_future_result_void_error_code_t **stream, off_t **off);
#endif
ssize_t __wasilibc_write(wasi_write_t *write, const void *buf, size_t len);

#if defined(__wasip2__) || defined(__wasip3__)
static inline unsigned dir_entry_type_to_d_type(filesystem_descriptor_type_t ty) {
switch(ty) {
case FILESYSTEM_DESCRIPTOR_TYPE_UNKNOWN:
Expand All @@ -104,6 +93,6 @@ static inline unsigned dir_entry_type_to_d_type(filesystem_descriptor_type_t ty)
}
}

#endif
#endif // __wasip2__ || __wasip3__

#endif
#endif // __wasi_file_utils_h
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
#include <stddef.h>
#include <string.h>
#include <wasi/file_utils.h>
#include <wasi/wasip3_block.h>

#ifdef __wasip2__

/**
* Validates that `ptr_signed` is a valid utf-8 string.
*
Expand Down Expand Up @@ -82,9 +82,11 @@ int wasip2_string_from_c(const char *s, wasip2_string_t *out) {
out->len = len;
return 0;
}
#endif

ssize_t __wasilibc_write(wasip2_write_t *write, const void *buffer,
ssize_t __wasilibc_write(wasi_write_t *write, const void *buffer,
size_t length) {
#if defined(__wasip2__)
assert(write->output.__handle != 0);
while (true) {
streams_stream_error_t error;
Expand Down Expand Up @@ -158,9 +160,36 @@ ssize_t __wasilibc_write(wasip2_write_t *write, const void *buffer,
poll_method_pollable_block(pollable_borrow);
}
}
#elif defined(__wasip3__)
if (WASIP3_SUBTASK_STATE(*write->subtask) == WASIP3_SUBTASK_STARTING ||
WASIP3_SUBTASK_STATE(*write->subtask) == WASIP3_SUBTASK_STARTED) {
// the stream is still active
wasip3_waitable_status_t status =
filesystem_stream_u8_write(write->output, buffer, length);
size_t amount = wasip3_waitable_block_on(status, write->output);
if (amount > 0 || length == 0) {
if (write->offset)
*write->offset += amount;
return amount;
}
// error or eof
wasip3_subtask_block_on(*write->subtask);
wasip3_subtask_drop(*write->subtask);
*write->subtask = WASIP3_SUBTASK_RETURNED;
}
if (write->pending_result.is_err) {
translate_error(write->pending_result.val.err);
return -1;
}
// EOF
return 0;
#else
#error "Unknown WASI version"
#endif
}

ssize_t __wasilibc_read(wasip2_read_t *read, void *buffer, size_t length) {
ssize_t __wasilibc_read(wasi_read_t *read, void *buffer, size_t length) {
#if defined(__wasip2__)
while (true) {
wasip2_list_u8_t result;
streams_stream_error_t error;
Expand Down Expand Up @@ -223,6 +252,17 @@ ssize_t __wasilibc_read(wasip2_read_t *read, void *buffer, size_t length) {
poll_method_pollable_block(pollable_borrow);
}
}
#elif defined(__wasip3__)
wasip3_waitable_status_t status =
filesystem_stream_u8_read(read->stream, buffer, length);
size_t amount = wasip3_waitable_block_on(status, read->stream);
if (amount > 0 || length == 0) {
if (read->offset)
*read->offset += amount;
return amount;
}
return read->eof(read->eof_data);
#else
#error "Unknown WASI version"
#endif
}

#endif // __wasip2__
Loading