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
3 changes: 3 additions & 0 deletions expected/wasm32-wasip3/defined-symbols.txt
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,7 @@ __wasilibc_open_nomode
__wasilibc_populate_preopens
__wasilibc_pthread_self
__wasilibc_random
__wasilibc_read_stream3
__wasilibc_rename_newat
__wasilibc_rename_oldat
__wasilibc_reset_preopens
Expand All @@ -344,6 +345,7 @@ __wasilibc_stat
__wasilibc_tell
__wasilibc_unlinkat
__wasilibc_utimens
__wasilibc_write_stream3
__wasm_call_dtors
__wcscoll_l
__wcsftime_l
Expand Down Expand Up @@ -1479,6 +1481,7 @@ wasip3_subtask_drop
wasip3_task_cancel
wasip3_thread_yield
wasip3_tuple2_string_string_free
wasip3_waitable_block_on
wasip3_waitable_join
wasip3_waitable_set_drop
wasip3_waitable_set_new
Expand Down
3 changes: 2 additions & 1 deletion libc-bottom-half/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -163,9 +163,10 @@ endif()
if (WASI STREQUAL "p3")
list(APPEND bottom_half_sources
sources/wasip3.c
sources/wasip3_block_on.c
sources/wasip3_file.c
sources/wasip3_file_utils.c
sources/wasip3_stdio.c
sources/wasip3_subtask.c
sources/wasip3_tcp.c
sources/wasip3_udp.c
)
Expand Down
4 changes: 3 additions & 1 deletion libc-bottom-half/cloudlibc/src/common/errors.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include <wasi/api.h>

#ifdef __wasip2__
#if defined(__wasip2__) || defined(__wasip3__)
#include <errno.h>
#include <stdlib.h>

Expand All @@ -9,9 +9,11 @@ static void translate_error(filesystem_error_code_t error) {
case FILESYSTEM_ERROR_CODE_ACCESS:
errno = EACCES;
break;
#ifdef __wasip2__
case FILESYSTEM_ERROR_CODE_WOULD_BLOCK:
errno = EAGAIN;
break;
#endif
case FILESYSTEM_ERROR_CODE_ALREADY:
errno = EALREADY;
break;
Expand Down
29 changes: 26 additions & 3 deletions libc-bottom-half/cloudlibc/src/libc/unistd/read.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
#include <string.h>
#endif

#ifdef __wasip3__
#include <wasi/wasip3_block.h>
#endif

ssize_t read(int fildes, void *buf, size_t nbyte) {
#if defined(__wasip1__)
__wasi_iovec_t iov = {.buf = buf, .buf_len = nbyte};
Expand Down Expand Up @@ -53,9 +57,28 @@ ssize_t read(int fildes, void *buf, size_t nbyte) {
*off += contents.len;
return contents.len;
#elif defined(__wasip3__)
// TODO(wasip3)
errno = ENOTSUP;
return -1;
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
Expand Down
32 changes: 29 additions & 3 deletions libc-bottom-half/cloudlibc/src/libc/unistd/write.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
#include <time.h>
#endif

#ifdef __wasip3__
#include <wasi/wasip3_block.h>
#endif

ssize_t write(int fildes, const void *buf, size_t nbyte) {
#if defined(__wasip1__)
__wasi_ciovec_t iov = {.buf = buf, .buf_len = nbyte};
Expand Down Expand Up @@ -72,9 +76,31 @@ ssize_t write(int fildes, const void *buf, size_t nbyte) {
*off += contents.len;
return contents.len;
#elif defined(__wasip3__)
// TODO(wasip3)
errno = ENOTSUP;
return -1;
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
Expand Down
20 changes: 20 additions & 0 deletions libc-bottom-half/headers/private/wasi/descriptor_table.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,22 @@
#include <sys/stat.h>
#include <netinet/in.h>

#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 {
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;
#endif

/**
* Operations that are required of all descriptors registered as file
* descriptors.
Expand Down Expand Up @@ -37,6 +53,10 @@ typedef struct descriptor_vtable_t {
/// Same as `get_read_stream`, but for output streams.
int (*get_write_stream)(void*, streams_borrow_output_stream_t*, off_t**, poll_own_pollable_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

/// Sets the nonblocking flag for this object to the specified value.
int (*set_blocking)(void*, bool);
Expand Down
14 changes: 13 additions & 1 deletion libc-bottom-half/headers/private/wasi/file_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@

#include <wasi/version.h>

#ifdef __wasip2__
#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.
///
/// If the error indicates "closed" then 0 is returned to mean EOF. Otherwise
Expand Down Expand Up @@ -46,7 +48,9 @@ static int wasip2_handle_write_error(streams_stream_error_t error) {
// Returns 0 if `s` is valid utf-8.
// Returns -1 and sets errno to `ENOENT` if `s` is not valid utf-8.
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 int fd_to_file_handle(int fd, filesystem_borrow_descriptor_t* result) {
descriptor_table_entry_t* entry = descriptor_table_get_ref(fd);
Expand All @@ -58,7 +62,9 @@ static int fd_to_file_handle(int fd, filesystem_borrow_descriptor_t* result) {
}
return entry->vtable->get_file(entry->data, result);
}
#endif

#ifdef __wasip2__
// Gets an `output-stream` borrow from the `fd` provided.
int __wasilibc_write_stream(int fd,
streams_borrow_output_stream_t *out,
Expand All @@ -70,7 +76,13 @@ int __wasilibc_read_stream(int fd,
streams_borrow_input_stream_t *out,
off_t **off,
poll_borrow_pollable_t *pollable);
#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

#if defined(__wasip2__) || defined(__wasip3__)
static unsigned dir_entry_type_to_d_type(filesystem_descriptor_type_t ty) {
switch(ty) {
case FILESYSTEM_DESCRIPTOR_TYPE_UNKNOWN:
Expand Down
5 changes: 5 additions & 0 deletions libc-bottom-half/headers/private/wasi/wasip3_block.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,13 @@
#include <wasi/api.h>

#ifdef __wasip3__
#include <stdint.h>
#include <wasi/descriptor_table.h> // for waitable_t

// Waits for a subtask to return
void wasip3_subtask_block_on(wasip3_subtask_status_t status);
// Waits for a (stream) transfer to complete
size_t wasip3_waitable_block_on(wasip3_waitable_status_t status, waitable_t stream);
#endif

#endif // WASI_WASIP3_BLOCK_H
53 changes: 53 additions & 0 deletions libc-bottom-half/sources/wasip3_block_on.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#include <wasi/version.h>

#ifdef __wasip3__
#include <assert.h>
#include <stdlib.h>
#include <wasi/wasip3_block.h>

void wasip3_subtask_block_on(wasip3_subtask_status_t status) {
// we don't encounter cancelled state because this function won't cancel
if (WASIP3_SUBTASK_STATE(status) == WASIP3_SUBTASK_STARTING ||
WASIP3_SUBTASK_STATE(status) == WASIP3_SUBTASK_STARTED) {
wasip3_subtask_t handle = WASIP3_SUBTASK_HANDLE(status);
wasip3_waitable_set_t set = wasip3_waitable_set_new();
wasip3_waitable_join(handle, set);
wasip3_event_t event;
event.code = WASIP3_SUBTASK_STATE(status);
while (event.code != WASIP3_SUBTASK_RETURNED) {
wasip3_waitable_set_wait(set, &event);
assert(event.event == WASIP3_EVENT_SUBTASK);
assert(event.waitable == handle);
}
wasip3_subtask_drop(event.waitable);
wasip3_waitable_set_drop(set);
}
}

size_t wasip3_waitable_block_on(wasip3_waitable_status_t status,
waitable_t stream) {
if (status == WASIP3_WAITABLE_STATUS_BLOCKED) {
wasip3_waitable_set_t set = wasip3_waitable_set_new();
wasip3_waitable_join(stream, set);
wasip3_event_t event;
wasip3_waitable_set_wait(set, &event);
assert(event.event == WASIP3_EVENT_STREAM_WRITE ||
event.event == WASIP3_EVENT_STREAM_READ ||
event.event == WASIP3_EVENT_FUTURE_READ);
assert(event.waitable == stream);
// remove from set
wasip3_waitable_join(stream, 0);
wasip3_waitable_set_drop(set);
size_t amount = event.event == WASIP3_EVENT_FUTURE_READ ? 1 : event.code;
return amount;
} else if (WASIP3_WAITABLE_STATE(status) == WASIP3_WAITABLE_COMPLETED ||
WASIP3_WAITABLE_STATE(status) == WASIP3_WAITABLE_DROPPED) {
size_t amount = WASIP3_WAITABLE_COUNT(status);
return amount;
} else {
// other status (e.g. cancelled) shouldn't occur
abort();
}
}

#endif
31 changes: 31 additions & 0 deletions libc-bottom-half/sources/wasip3_file_utils.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#include <wasi/version.h>

#ifdef __wasip3__
#include <wasi/file_utils.h>

int __wasilibc_write_stream3(int fildes, wasip3_write_t **write_end,
off_t **off) {
descriptor_table_entry_t *entry = descriptor_table_get_ref(fildes);
if (!entry)
return -1;
if (!entry->vtable->get_write_stream3) {
errno = EOPNOTSUPP;
return -1;
}
return (*entry->vtable->get_write_stream3)(entry->data, write_end, off);
}

int __wasilibc_read_stream3(
int fildes,
filesystem_tuple2_stream_u8_future_result_void_error_code_t **stream,
off_t **off) {
descriptor_table_entry_t *entry = descriptor_table_get_ref(fildes);
if (!entry)
return -1;
if (!entry->vtable->get_read_stream3) {
errno = EOPNOTSUPP;
return -1;
}
return (*entry->vtable->get_read_stream3)(entry->data, stream, off);
}
#endif // __wasip3__
Loading