Skip to content
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
78 changes: 78 additions & 0 deletions schema/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
## WASI Interface Definitions

The interface definition are written in [Capn Proto schema](https://capnproto.org/language.html).

### Files
- [wasi-common.capnp](./wasi-common.capnproto)
- [wasi-fd.capnp](./wasi-fd.capnp) The interfaces for file descriptors, directors, files and sockets.
- [wasi-env.capnp](./wasi-env.capnp) The interface for enviromental variables.
- [wasi-args.capnp](./wasi-args.capnp) The interface for command line arguments
- [wasi-clock.capnp](./wasi-clock.capnp) The interface for clocks.
- [wasi-events.capnp](./wasi-events.capnp) The interface events.
- [wasi-proc.capnp](./wasi-proc.capnp) The for proc related items.


## Cap'n Proto Wasm Generation

## Multiple Returns
Multiple returns in Cap'n Proto schema should be translated into pointer arguments that is appended to the end of a function arguments. For example

```
returnTwoInts @0 (
someInput :Uint64
) -> (
first :UInt64,
second :Uint64
);

```

Would get compiled to the following signature

```
(func $returnTwoInts
(param $someInput i64)
(param $ptr_first i32)
(param $ptr_second i32)
)
```

## Returned Text
Text as an return value is turned into two arguments a pointer to write the text and an i32 representing the length of memory allocated for storing the text.

```
returnString @0 (
someInput :Uint64
) -> (
path :Text
);

```

Would get compiled to the following signature

```
(func $returnString
(param $someInput i64)
(param $ptr_path i32)
(param $path_len i32)
)
```

## Lists
Lists are turned into a pointer to a buffer of pointers

```
get @0 (
args :List(Text) # the environment variables string data.
) -> ()
```

Would get compiled to the following signature

```
(func $returnString
(param $argv i32)
(param $argv_buf i32)
)
```
22 changes: 22 additions & 0 deletions schema/wasi-args.capnp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
@0xb47a0b67171659f7;
Copy link
Member

Choose a reason for hiding this comment

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

what are these?

Copy link
Contributor

Choose a reason for hiding this comment

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

that is the unique file id: https://capnproto.org/language.html#unique-ids
the @0, @1, @2, etc. are used to define the canonical field/method order for seriaization.

Copy link
Author

Choose a reason for hiding this comment

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

we could possible use these in the future for versioning the interfaces but I wanted to start on discussion at time.


using import "wasi-common.capnp".Errno;
using import "wasi-common.capnp".Size;

interface Args {
# Read command-line argument data.
# The sizes of the buffers should match that returned by argsSizesGet().
get @0 (
argvBuf :List(Text) # A pointer to a buffer to write the argument string data.
) -> (
error :Errno
);

# Return command-line argument data sizes.
sizesGet @1 () -> (
Copy link
Member

@devsnek devsnek Jun 16, 2019

Choose a reason for hiding this comment

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

assuming i can use these files as some sort of data to generate information i can use in my library or language or whatever, shouldn't these functions be snake_case? (and contain some data about being in the wasi_unstable module?)

Copy link
Author

Choose a reason for hiding this comment

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

so there are a couple of routes to go here. Capn proto schema style should be camelcase, but then the doc and interface generators can could spit out snake_case. Also we can add annotations to generate the current naming if there are other discrepancies.

error :Errno,
argc :Size, # The number of arguments.
argv_buf_size :Size # The size of the argument string data.
);
}

40 changes: 40 additions & 0 deletions schema/wasi-clock.capnp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
@0xdb04d36135e780f4;

using import "wasi-common.capnp".Errno;
using import "wasi-common.capnp".Timestamp;


enum ClockId {
# The store-wide monotonic clock, which is defined as a clock measuring real time, whose value cannot be adjusted and which cannot have negative clock jumps.
# The epoch of this clock is undefined. The absolute time value of this clock therefore has no meaning.
monotonic @0;
# The CPU-time clock associated with the current process.
processcputimeid @1;
# The clock measuring real time. Time value zero corresponds with 1970-01-01T00:00:00Z.
realtime @2;
# The CPU-time clock associated with the current thread.
threadcputimeid @3;
}

interface Clock {
# Return the resolution of a clock.
# Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `einval`.
# Note: This is similar to clock_getres in POSIX.
resGet @0 (
clock_id :ClockId, # The clock for which to return the resolution.
) -> (
error :Errno,
resolution :Timestamp # The resolution of the clock.
);

# Return the time value of a clock.
# Note: This is similar to clock_gettime in POSIX.
timeGet @1 (
clockId :ClockId, # The clock for which to return the time.
precision :Timestamp, # The maximum lag (exclusive) that the returned time value may have, compared to its actual value.
) -> (
error :Errno,
time :Timestamp # The time value of the clock.
);
}

88 changes: 88 additions & 0 deletions schema/wasi-common.capnp
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
@0xf8a5c786b8463cf1;

using Timestamp = UInt64; # Timestamp in nanoseconds.
using Size = UInt64;


# Error codes returned by functions.
# Not all of these error codes are returned by the functions provided by this API; some are used in higher-level library layers, and others are provided merely for alignment with POSIX.
enum Errno {
esuccess @0; # No error occurred. System call completed successfully.ErrnoT
e2big @1; # Argument list too long.
eacces @2; # Permission denied.
eaddrinuse @3; # Address in use.
eaddrnotavail @4; # Address not available.
eafnosupport @5; # Address family not supported.
eagain @6; # Resource unavailable, or operation would block.
ealready @7; # Connection already in progress.
ebadf @8; # Bad file descriptor.
ebadmsg @9; # Bad message.
ebusy @10; # Device or resource busy.
ecanceled @11; # Operation canceled.
eechild @12; # No child processes.
econnaborted @13; # Connection aborted.
econnrefused @14; # Connection refused.
econnreset @15; # Connection reset.
edeadlk @16; # Resource deadlock would occur.
edestaddrreq @17; # Destination address required.
edom @18; # Mathematics argument out of domain of function.
edquot @19; # Reserved.
eexist @20; # File exists.
efault @21; # Bad address.
efbig @22; # File too large.
ehostunreach @23; # Host is unreachable.
eidrm @24; # Identifier removed.
eilseq @25; # Illegal byte sequence.
einprogress @26; # Operation in progress.
eintr @27; # Interrupted function.
einval @28; # Invalid argument.
eio @29; # I/O error.
eisconn @30; # Socket is connected.
eisdir @31; # Is a directory.
eloop @32; # Too many levels of symbolic links.
emfile @33; # File descriptor value too large.
emlink @34; # Too many links.
emsgsize @35; # Message too large.
emultihop @36; # Reserved.
enametoolong @37; # Filename too long.
enetdown @38; # Network is down.
enetreset @39; # Connection aborted by network.
enetunreach @40; # Network unreachable.
enfile @41; # Too many files open in system.
enobufs @42; # No buffer space available.
enodev @43; # No such device.
enoent @44; # No such file or directory.
enoexec @45; # Executable file format error.
enolck @46; # No locks available.
enolink @47; # Reserved.
enomem @48; # Not enough space.
enomsg @49; # No message of the desired type.
enoprotoopt @50; # Protocol not available.
enospc @51; # No space left on device.
enosys @52; # Function not supported.
enotconn @53; # The socket is not connected.
enotdir @54; # Not a directory or a symbolic link to a directory.
enotempty @55; # Directory not empty.
enotrecoverable @56; # State not recoverable.
enotsock @57; # Not a socket.
enotsup @58; # Not supported, or operation not supported on socket.
enotty @59; # Inappropriate I/O control operation.
enxio @60; # No such device or address.
eoverflow @61; # Value too large to be stored in data type.
eownerdead @62; # Previous owner died.
eperm @63; # Operation not permitted.
epipe @64; # Broken pipe.
eproto @65; # Protocol error.
eprotonosupport @66; # Protocol not supported.
eprototype @67; # Protocol wrong type for socket.
erange @68; # Result too large.
erofs @69; # Read-only file system.
espipe @70; # Invalid seek.
esrch @71; # No such process.
estale @72; # Reserved
etimedout @73; # Connection timed out.
etxtbsy @74; # Text file busy.
exdev @75; # Cross-device link.
enotcapable @76; # Extension: Capabilities insufficient.
}

22 changes: 22 additions & 0 deletions schema/wasi-env.capnp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
@0xb076a1080f602f71;

using import "wasi-common.capnp".Errno;
using import "wasi-common.capnp".Size;

interface Environ {
# Read environment variable data.
# The sizes of the buffers should match that returned by environ_sizes_get().
get @0 (
argvBuf :List(Text) # the environment variable string data.
) -> (
error :Errno
);

# Return environment variable data sizes.
sizesGet @1 () -> (
error :Errno,
argc :Size, # The number of environment variables.
argv_buf_size :Size # The size of the environment variable string data.
);
}

68 changes: 68 additions & 0 deletions schema/wasi-events.capnp
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
@0x9bc3b97f0db7d1a2;
using import "wasi-common.capnp".Errno;
using import "wasi-common.capnp".Timestamp;
using import "wasi-common.capnp".Size;
using import "wasi-fs.capnp".FileDescriptor;
using import "wasi-fs.capnp".Filesize;
using import "wasi-clock.capnp".ClockId;


interface Events {
using Userdata = UInt64; # User-provided value that may be attached to objects that is retained when extracted from the implementation.

enum EventType {
clock @0; # The time value of clock __wasi_subscription_t::u.clock.clock_id has reached timestamp __wasi_subscription_t::u.clock.timeout.
fdRead @1; # File descriptor __wasi_subscription_t::u.fd_readwrite.fd has data available for reading. This event always triggers for regular files.
fdWrite @2; # File descriptor __wasi_subscription_t::u.fd_readwrite.fd has capacity available for writing. This event always triggers for regular files.
}

# The state of the file descriptor subscribed to with __WASI_EVENTTYPE_FD_READ or __WASI_EVENTTYPE_FD_WRITE.
enum Eventrwflags {
eventFdReadwriteHangup @0; # The peer of this socket has closed or disconnected.
}

# Subscription to an event.
struct Subscription {
userdata @0 :Userdata; # User-provided value that is attached to the subscription in the implementation and returned through __wasi_event_t::userdata.
type @1 :EventType; # The type of the event to which to subscribe.
union {
# When type is __WASI_EVENTTYPE_CLOCK
clock :group {
identifier @2 :Userdata; # The user-defined unique identifier of the clock.
clockId @3 :ClockId; # The clock against which to compare the timestamp.
timeout @4 :Timestamp; # The absolute or relative timestamp.
precision @5 :Timestamp; # The amount of time that the implementation may wait additionally to coalesce with other events.
}
# When type is __WASI_EVENTTYPE_FD_READ or __WASI_EVENTTYPE_FD_WRITE
fdReadwrite :group {
fd @6 :FileDescriptor; # The file descriptor on which to wait for it to become ready for reading or writing.
}
}
}

# An event that occurred.
struct Event {
userdata @0 :Userdata; # User-provided value that got attached to __wasi_subscription_t::userdata.
error @1 :Errno; # If non-zero, an error that occurred while processing the subscription request.
type @2 :EventType; # The type of the event that occurred.
union {
# When type is __WASI_EVENTTYPE_FD_READ or __WASI_EVENTTYPE_FD_WRITE
fdReadwrite :group {
nbytes @3 :Filesize; # The number of bytes available for reading or writing.
flags @4 :Eventrwflags; # The state of the file descriptor.
}
else @5 :Void;
}
}

# Concurrently poll for the occurrence of a set of events.
pollOneoff @0 (
in :Subscription, # The events to which to subscribe.
nsubscriptions :Size # Both the number of subscriptions and events.
) -> (
error :Errno,
nevents :Size, # The number of events stored.
out :Event # The events that have occurred.
);
}

Loading