Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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);
ssize_t amount = wasip3_waitable_block_on(status, stream->f0);
if (amount > 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);
ssize_t amount = wasip3_waitable_block_on(status, write_end->output);
if (amount > 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
17 changes: 16 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,9 @@ int __wasilibc_read_stream(int fd,
streams_borrow_input_stream_t *out,
off_t **off,
poll_borrow_pollable_t *pollable);
#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 All @@ -96,4 +104,11 @@ static unsigned dir_entry_type_to_d_type(filesystem_descriptor_type_t ty) {

#endif

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

ssize_t __wasilibc_write_stream3(int fildes, wasip3_write_t **write_end, off_t **off);
ssize_t __wasilibc_read_stream3(int fildes, filesystem_tuple2_stream_u8_future_result_void_error_code_t **stream, off_t **off);
#endif

#endif
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 <__typedef_ssize_t.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
ssize_t wasip3_waitable_block_on(wasip3_waitable_status_t status, waitable_t stream);
#endif

#endif // WASI_WASIP3_BLOCK_H
52 changes: 52 additions & 0 deletions libc-bottom-half/sources/wasip3_block_on.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#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);
}
}

ssize_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);
ssize_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) {
ssize_t amount = WASIP3_WAITABLE_COUNT(status);
return amount;
} else {
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>

ssize_t __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);
}

ssize_t __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