Skip to content

Commit

Permalink
feat: add wasi-0.3.0 draft
Browse files Browse the repository at this point in the history
Followed the example of `wasi-http` and `wasi-clocks` duplicating the
package in a subdirectory

- In wasip3 return values of functions are pollable by guests,
  therefore remove abstractions for which there is no need anymore:
     - Replace `start-X`/`finish-X` function pairs by `X`
     - Remove `would-block` error code
     - Remove `not-in-progress` error code
- Replace `wasi:io/error.error` usage by `error-context`
- Replace `wasi:io/streams.input-stream` return values by `stream<u8>`
  in return position
- Replace `wasi:io/streams.output-stream` return values by `stream<u8>`
  in parameter position
     - Guests should be able to rely on `stream.new` to construct
       streams

Signed-off-by: Roman Volosatovs <[email protected]>
  • Loading branch information
rvolosatovs committed Jan 14, 2025
1 parent a584c2b commit 605a6b4
Show file tree
Hide file tree
Showing 14 changed files with 990 additions and 0 deletions.
4 changes: 4 additions & 0 deletions wit-0.3.0-draft/deps.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[clocks]
url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz"
sha256 = "26e315db0d371495f8834edfc0e479042f94152ce677d96d54d3623d0e4ffb1e"
sha512 = "e1c76f499435841316f9287b88d8173558e64f277c321ff390556de8707a0b18dd6c1749bbb17bbbba8d523da246ef6eb05c990ceddb762e03efb2ae30cacc76"
1 change: 1 addition & 0 deletions wit-0.3.0-draft/deps.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
clocks = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz"
45 changes: 45 additions & 0 deletions wit-0.3.0-draft/deps/clocks/monotonic-clock.wit
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package wasi:clocks@0.3.0;
/// WASI Monotonic Clock is a clock API intended to let users measure elapsed
/// time.
///
/// It is intended to be portable at least between Unix-family platforms and
/// Windows.
///
/// A monotonic clock is a clock which has an unspecified initial value, and
/// successive reads of the clock will produce non-decreasing values.
@since(version = 0.3.0)
interface monotonic-clock {
/// An instant in time, in nanoseconds. An instant is relative to an
/// unspecified initial value, and can only be compared to instances from
/// the same monotonic-clock.
@since(version = 0.3.0)
type instant = u64;

/// A duration of time, in nanoseconds.
@since(version = 0.3.0)
type duration = u64;

/// Read the current value of the clock.
///
/// The clock is monotonic, therefore calling this function repeatedly will
/// produce a sequence of non-decreasing values.
@since(version = 0.3.0)
now: func() -> instant;

/// Query the resolution of the clock. Returns the duration of time
/// corresponding to a clock tick.
@since(version = 0.3.0)
resolution: func() -> duration;

/// Wait until the specified instant has occurred.
@since(version = 0.3.0)
wait-until: func(
when: instant,
);

/// Wait for the specified duration has elapsed.
@since(version = 0.3.0)
wait-for: func(
how-long: duration,
);
}
55 changes: 55 additions & 0 deletions wit-0.3.0-draft/deps/clocks/timezone.wit
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package wasi:clocks@0.3.0;

@unstable(feature = clocks-timezone)
interface timezone {
@unstable(feature = clocks-timezone)
use wall-clock.{datetime};

/// Return information needed to display the given `datetime`. This includes
/// the UTC offset, the time zone name, and a flag indicating whether
/// daylight saving time is active.
///
/// If the timezone cannot be determined for the given `datetime`, return a
/// `timezone-display` for `UTC` with a `utc-offset` of 0 and no daylight
/// saving time.
@unstable(feature = clocks-timezone)
display: func(when: datetime) -> timezone-display;

/// The same as `display`, but only return the UTC offset.
@unstable(feature = clocks-timezone)
utc-offset: func(when: datetime) -> s32;

/// Information useful for displaying the timezone of a specific `datetime`.
///
/// This information may vary within a single `timezone` to reflect daylight
/// saving time adjustments.
@unstable(feature = clocks-timezone)
record timezone-display {
/// The number of seconds difference between UTC time and the local
/// time of the timezone.
///
/// The returned value will always be less than 86400 which is the
/// number of seconds in a day (24*60*60).
///
/// In implementations that do not expose an actual time zone, this
/// should return 0.
utc-offset: s32,

/// The abbreviated name of the timezone to display to a user. The name
/// `UTC` indicates Coordinated Universal Time. Otherwise, this should
/// reference local standards for the name of the time zone.
///
/// In implementations that do not expose an actual time zone, this
/// should be the string `UTC`.
///
/// In time zones that do not have an applicable name, a formatted
/// representation of the UTC offset may be returned, such as `-04:00`.
name: string,

/// Whether daylight saving time is active.
///
/// In implementations that do not expose an actual time zone, this
/// should return false.
in-daylight-saving-time: bool,
}
}
46 changes: 46 additions & 0 deletions wit-0.3.0-draft/deps/clocks/wall-clock.wit
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package wasi:clocks@0.3.0;
/// WASI Wall Clock is a clock API intended to let users query the current
/// time. The name "wall" makes an analogy to a "clock on the wall", which
/// is not necessarily monotonic as it may be reset.
///
/// It is intended to be portable at least between Unix-family platforms and
/// Windows.
///
/// A wall clock is a clock which measures the date and time according to
/// some external reference.
///
/// External references may be reset, so this clock is not necessarily
/// monotonic, making it unsuitable for measuring elapsed time.
///
/// It is intended for reporting the current date and time for humans.
@since(version = 0.3.0)
interface wall-clock {
/// A time and date in seconds plus nanoseconds.
@since(version = 0.3.0)
record datetime {
seconds: u64,
nanoseconds: u32,
}

/// Read the current value of the clock.
///
/// This clock is not monotonic, therefore calling this function repeatedly
/// will not necessarily produce a sequence of non-decreasing values.
///
/// The returned timestamps represent the number of seconds since
/// 1970-01-01T00:00:00Z, also known as [POSIX's Seconds Since the Epoch],
/// also known as [Unix Time].
///
/// The nanoseconds field of the output is always less than 1000000000.
///
/// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16
/// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time
@since(version = 0.3.0)
now: func() -> datetime;

/// Query the resolution of the clock.
///
/// The nanoseconds field of the output is always less than 1000000000.
@since(version = 0.3.0)
resolution: func() -> datetime;
}
11 changes: 11 additions & 0 deletions wit-0.3.0-draft/deps/clocks/world.wit
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package wasi:clocks@0.3.0;

@since(version = 0.3.0)
world imports {
@since(version = 0.3.0)
import monotonic-clock;
@since(version = 0.3.0)
import wall-clock;
@unstable(feature = clocks-timezone)
import timezone;
}
11 changes: 11 additions & 0 deletions wit-0.3.0-draft/instance-network.wit
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@

/// This interface provides a value-export of the default network handle..
@since(version = 0.2.0)
interface instance-network {
@since(version = 0.2.0)
use network.{network};

/// Get a handle to the default network.
@since(version = 0.2.0)
instance-network: func() -> network;
}
46 changes: 46 additions & 0 deletions wit-0.3.0-draft/ip-name-lookup.wit
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
@since(version = 0.2.0)
interface ip-name-lookup {
@since(version = 0.2.0)
use network.{network, error-code, ip-address};

/// Resolve an internet host name to a list of IP addresses.
///
/// Unicode domain names are automatically converted to ASCII using IDNA encoding.
/// If the input is an IP address string, the address is parsed and returned
/// as-is without making any external requests.
///
/// See the wasi-socket proposal README.md for a comparison with getaddrinfo.
///
/// This function never blocks. It either immediately fails or immediately
/// returns successfully with a `resolve-address-stream` that can be used
/// to (asynchronously) fetch the results.
///
/// # Typical errors
/// - `invalid-argument`: `name` is a syntactically invalid domain name or IP address.
///
/// # References:
/// - <https://pubs.opengroup.org/onlinepubs/9699919799/functions/getaddrinfo.html>
/// - <https://man7.org/linux/man-pages/man3/getaddrinfo.3.html>
/// - <https://learn.microsoft.com/en-us/windows/win32/api/ws2tcpip/nf-ws2tcpip-getaddrinfo>
/// - <https://man.freebsd.org/cgi/man.cgi?query=getaddrinfo&sektion=3>
@since(version = 0.2.0)
resolve-addresses: func(network: borrow<network>, name: string) -> result<resolve-address-stream, error-code>;

@since(version = 0.2.0)
resource resolve-address-stream {
/// Returns the next address from the resolver.
///
/// This function should be called multiple times. On each call, it will
/// return the next address in connection order preference. If all
/// addresses have been exhausted, this function returns `none`.
///
/// This function never returns IPv4-mapped IPv6 addresses.
///
/// # Typical errors
/// - `name-unresolvable`: Name does not exist or has no suitable associated IP addresses. (EAI_NONAME, EAI_NODATA, EAI_ADDRFAMILY)
/// - `temporary-resolver-failure`: A temporary failure in name resolution occurred. (EAI_AGAIN)
/// - `permanent-resolver-failure`: A permanent failure in name resolution occurred. (EAI_FAIL)
@since(version = 0.2.0)
resolve-next-address: func() -> result<option<ip-address>, error-code>;
}
}
153 changes: 153 additions & 0 deletions wit-0.3.0-draft/network.wit
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
@since(version = 0.2.0)
interface network {
/// An opaque resource that represents access to (a subset of) the network.
/// This enables context-based security for networking.
/// There is no need for this to map 1:1 to a physical network interface.
@since(version = 0.2.0)
resource network;

/// Error codes.
///
/// In theory, every API can return any error code.
/// In practice, API's typically only return the errors documented per API
/// combined with a couple of errors that are always possible:
/// - `unknown`
/// - `access-denied`
/// - `not-supported`
/// - `out-of-memory`
/// - `concurrency-conflict`
///
/// See each individual API for what the POSIX equivalents are. They sometimes differ per API.
@since(version = 0.2.0)
enum error-code {
/// Unknown error
unknown,

/// Access denied.
///
/// POSIX equivalent: EACCES, EPERM
access-denied,

/// The operation is not supported.
///
/// POSIX equivalent: EOPNOTSUPP
not-supported,

/// One of the arguments is invalid.
///
/// POSIX equivalent: EINVAL
invalid-argument,

/// Not enough memory to complete the operation.
///
/// POSIX equivalent: ENOMEM, ENOBUFS, EAI_MEMORY
out-of-memory,

/// The operation timed out before it could finish completely.
timeout,

/// This operation is incompatible with another asynchronous operation that is already in progress.
///
/// POSIX equivalent: EALREADY
concurrency-conflict,

/// The operation is not valid in the socket's current state.
invalid-state,

/// A new socket resource could not be created because of a system limit.
new-socket-limit,

/// A bind operation failed because the provided address is not an address that the `network` can bind to.
address-not-bindable,

/// A bind operation failed because the provided address is already in use or because there are no ephemeral ports available.
address-in-use,

/// The remote address is not reachable
remote-unreachable,


/// The TCP connection was forcefully rejected
connection-refused,

/// The TCP connection was reset.
connection-reset,

/// A TCP connection was aborted.
connection-aborted,


/// The size of a datagram sent to a UDP socket exceeded the maximum
/// supported size.
datagram-too-large,


/// Name does not exist or has no suitable associated IP addresses.
name-unresolvable,

/// A temporary failure in name resolution occurred.
temporary-resolver-failure,

/// A permanent failure in name resolution occurred.
permanent-resolver-failure,
}

/// Attempts to extract a network-related `error-code` from the stream
/// `error` provided.
///
/// Stream operations which return `stream-error::last-operation-failed`
/// have a payload with more information about the operation that failed.
/// This payload can be passed through to this function to see if there's
/// network-related information about the error to return.
///
/// Note that this function is fallible because not all stream-related
/// errors are network-related errors.
@unstable(feature = network-error-code)
network-error-code: func(err: borrow<error-context>) -> option<error-code>;

@since(version = 0.2.0)
enum ip-address-family {
/// Similar to `AF_INET` in POSIX.
ipv4,

/// Similar to `AF_INET6` in POSIX.
ipv6,
}

@since(version = 0.2.0)
type ipv4-address = tuple<u8, u8, u8, u8>;
@since(version = 0.2.0)
type ipv6-address = tuple<u16, u16, u16, u16, u16, u16, u16, u16>;

@since(version = 0.2.0)
variant ip-address {
ipv4(ipv4-address),
ipv6(ipv6-address),
}

@since(version = 0.2.0)
record ipv4-socket-address {
/// sin_port
port: u16,
/// sin_addr
address: ipv4-address,
}

@since(version = 0.2.0)
record ipv6-socket-address {
/// sin6_port
port: u16,
/// sin6_flowinfo
flow-info: u32,
/// sin6_addr
address: ipv6-address,
/// sin6_scope_id
scope-id: u32,
}

@since(version = 0.2.0)
variant ip-socket-address {
ipv4(ipv4-socket-address),
ipv6(ipv6-socket-address),
}
}
Loading

0 comments on commit 605a6b4

Please sign in to comment.