Skip to content

Commit

Permalink
Change witx unions to be tagged (#220)
Browse files Browse the repository at this point in the history
* unions are now tagged by an enum

* union fields may be empty. TODO: write tests

* unions: add more tests. compute layout.

* snapshot 0: translate untagged union syntax to tagged union syntax

* snapshot: update from untagged union to tagged union syntax

* snapshot: update docs

* snapshot 0: update docs

* ephemeral: translate untagged unions to tagged unions

* render: fix union output

* bump witx to 0.8.0 - this is definitely semver breaking

* snapshot: I forgot to delete the tag field `subscription.type`

* regen docs

* unionlayout: derive the usual suspects

* snapshot 1 and 0: put tag back in event struct, flatten event_u

prior to this PR, event_u was a union with only one variant
fd_readwrite. the change into tagged union ended up changing the
memory layout of the event struct. so, rather than use tagged
unions in the event struct, we just use a struct that you ignore
in the case of the clock event, which has the same ABI as previously.

in ephemeral, we use a tagged union for events, because we dont have
any ABI stability guarantees to maintain there.

* layout: refactor so we have impls for NamedType and Type too

* ast: change tag of UnionDatatype to be a NamedType

this is much more convenient for consumers, and it reflects the
requirement of the syntax to provide an Id

* fixup docs
  • Loading branch information
Pat Hickey committed Feb 18, 2020
1 parent 3f054c6 commit 85df508
Show file tree
Hide file tree
Showing 16 changed files with 526 additions and 232 deletions.
41 changes: 14 additions & 27 deletions phases/ephemeral/docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -688,8 +688,11 @@ The state of the file descriptor.
The contents of an $event.

### Union variants
- <a href="#event_u.fd_readwrite" name="event_u.fd_readwrite"></a> `fd_readwrite`: [`event_fd_readwrite`](#event_fd_readwrite)
When type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write):
- <a href="#event_u.fd_read" name="event_u.fd_read"></a> `fd_read`: [`event_fd_readwrite`](#event_fd_readwrite)

- <a href="#event_u.fd_write" name="event_u.fd_write"></a> `fd_write`: [`event_fd_readwrite`](#event_fd_readwrite)

- <a href="#event_u.clock" name="event_u.clock"></a> `clock`

## <a href="#event" name="event"></a> `event`: Struct
An event that occurred.
Expand All @@ -701,11 +704,8 @@ User-provided value that got attached to [`subscription::userdata`](#subscriptio
- <a href="#event.error" name="event.error"></a> `error`: [`errno`](#errno)
If non-zero, an error that occurred while processing the subscription request.

- <a href="#event.type" name="event.type"></a> `type`: [`eventtype`](#eventtype)
The type of the event that occurred.

- <a href="#event.u" name="event.u"></a> `u`: [`event_u`](#event_u)
The contents of the event.
The type of the event that occurred, and the contents of the event

## <a href="#subclockflags" name="subclockflags"></a> `subclockflags`: Flags(`u16`)
Flags determining how to interpret the timestamp provided in
Expand Down Expand Up @@ -749,10 +749,10 @@ The contents of a $subscription.

### Union variants
- <a href="#subscription_u.clock" name="subscription_u.clock"></a> `clock`: [`subscription_clock`](#subscription_clock)
When type is [`eventtype::clock`](#eventtype.clock):

- <a href="#subscription_u.fd_readwrite" name="subscription_u.fd_readwrite"></a> `fd_readwrite`: [`subscription_fd_readwrite`](#subscription_fd_readwrite)
When type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write):
- <a href="#subscription_u.fd_read" name="subscription_u.fd_read"></a> `fd_read`: [`subscription_fd_readwrite`](#subscription_fd_readwrite)

- <a href="#subscription_u.fd_write" name="subscription_u.fd_write"></a> `fd_write`: [`subscription_fd_readwrite`](#subscription_fd_readwrite)

## <a href="#subscription" name="subscription"></a> `subscription`: Struct
Subscription to an event.
Expand All @@ -762,11 +762,8 @@ Subscription to an event.
User-provided value that is attached to the subscription in the
implementation and returned through [`event::userdata`](#event.userdata).

- <a href="#subscription.type" name="subscription.type"></a> `type`: [`eventtype`](#eventtype)
The type of the event to which to subscribe.

- <a href="#subscription.u" name="subscription.u"></a> `u`: [`subscription_u`](#subscription_u)
The contents of the subscription.
The type of the event to which to subscribe, and the contents of the subscription.

## <a href="#exitcode" name="exitcode"></a> `exitcode`: `u32`
Exit code generated by a process when exiting.
Expand Down Expand Up @@ -816,22 +813,12 @@ The contents of a $prestat when its $pr_type is [`preopentype::dir`](#preopentyp
- <a href="#prestat_dir.pr_name_len" name="prestat_dir.pr_name_len"></a> `pr_name_len`: [`size`](#size)
The length of the directory name for use with `fd_prestat_dir_name`.

## <a href="#prestat_u" name="prestat_u"></a> `prestat_u`: Union
The contents of an $prestat.

### Union variants
- <a href="#prestat_u.dir" name="prestat_u.dir"></a> `dir`: [`prestat_dir`](#prestat_dir)
When $pr_type of the $prestat is [`preopentype::dir`](#preopentype.dir):

## <a href="#prestat" name="prestat"></a> `prestat`: Struct
## <a href="#prestat" name="prestat"></a> `prestat`: Union
Information about a pre-opened capability.

### Struct members
- <a href="#prestat.pr_type" name="prestat.pr_type"></a> `pr_type`: [`preopentype`](#preopentype)
The type of the pre-opened capability.

- <a href="#prestat.u" name="prestat.u"></a> `u`: [`prestat_u`](#prestat_u)
The contents of the information.
### Union variants
- <a href="#prestat.dir" name="prestat.dir"></a> `dir`: [`prestat_dir`](#prestat_dir)
When type is [`preopentype::dir`](#preopentype.dir):

# Modules
## <a href="#wasi_ephemeral_args" name="wasi_ephemeral_args"></a> wasi_ephemeral_args
Expand Down
38 changes: 12 additions & 26 deletions phases/ephemeral/witx/typenames.witx
Original file line number Diff line number Diff line change
Expand Up @@ -560,9 +560,10 @@

;;; The contents of an $event.
(typename $event_u
(union
;;; When type is `eventtype::fd_read` or `eventtype::fd_write`:
(field $fd_readwrite $event_fd_readwrite)
(union $eventtype
(field $fd_read $event_fd_readwrite)
(field $fd_write $event_fd_readwrite)
(empty $clock)
)
)

Expand All @@ -573,9 +574,7 @@
(field $userdata $userdata)
;;; If non-zero, an error that occurred while processing the subscription request.
(field $error $errno)
;;; The type of the event that occurred.
(field $type $eventtype)
;;; The contents of the event.
;;; The type of the event that occurred, and the contents of the event
(field $u $event_u)
)
)
Expand Down Expand Up @@ -619,11 +618,10 @@

;;; The contents of a $subscription.
(typename $subscription_u
(union
;;; When type is `eventtype::clock`:
(union $eventtype
(field $clock $subscription_clock)
;;; When type is `eventtype::fd_read` or `eventtype::fd_write`:
(field $fd_readwrite $subscription_fd_readwrite)
(field $fd_read $subscription_fd_readwrite)
(field $fd_write $subscription_fd_readwrite)
)
)

Expand All @@ -633,9 +631,7 @@
;;; User-provided value that is attached to the subscription in the
;;; implementation and returned through `event::userdata`.
(field $userdata $userdata)
;;; The type of the event to which to subscribe.
(field $type $eventtype)
;;; The contents of the subscription.
;;; The type of the event to which to subscribe, and the contents of the subscription.
(field $u $subscription_u)
)
)
Expand Down Expand Up @@ -691,20 +687,10 @@
)
)

;;; The contents of an $prestat.
(typename $prestat_u
(union
;;; When $pr_type of the $prestat is `preopentype::dir`:
(field $dir $prestat_dir)
)
)

;;; Information about a pre-opened capability.
(typename $prestat
(struct
;;; The type of the pre-opened capability.
(field $pr_type $preopentype)
;;; The contents of the information.
(field $u $prestat_u)
(union $preopentype
;;; When type is `preopentype::dir`:
(field $dir $prestat_dir)
)
)
48 changes: 14 additions & 34 deletions phases/old/snapshot_0/docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -627,8 +627,8 @@ The state of the file descriptor subscribed to with
The peer of this socket has closed or disconnected.

## <a href="#event_fd_readwrite" name="event_fd_readwrite"></a> `event_fd_readwrite`: Struct
The contents of an $event when type is [`eventtype::fd_read`](#eventtype.fd_read) or
[`eventtype::fd_write`](#eventtype.fd_write).
The contents of an $event for the [`eventtype::fd_read`](#eventtype.fd_read) and
[`eventtype::fd_write`](#eventtype.fd_write) variants

### Struct members
- <a href="#event_fd_readwrite.nbytes" name="event_fd_readwrite.nbytes"></a> `nbytes`: [`filesize`](#filesize)
Expand All @@ -637,13 +637,6 @@ The number of bytes available for reading or writing.
- <a href="#event_fd_readwrite.flags" name="event_fd_readwrite.flags"></a> `flags`: [`eventrwflags`](#eventrwflags)
The state of the file descriptor.

## <a href="#event_u" name="event_u"></a> `event_u`: Union
The contents of an $event.

### Union variants
- <a href="#event_u.fd_readwrite" name="event_u.fd_readwrite"></a> `fd_readwrite`: [`event_fd_readwrite`](#event_fd_readwrite)
When type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write):

## <a href="#event" name="event"></a> `event`: Struct
An event that occurred.

Expand All @@ -655,10 +648,11 @@ User-provided value that got attached to [`subscription::userdata`](#subscriptio
If non-zero, an error that occurred while processing the subscription request.

- <a href="#event.type" name="event.type"></a> `type`: [`eventtype`](#eventtype)
The type of the event that occurred.
The type of event that occured

- <a href="#event.u" name="event.u"></a> `u`: [`event_u`](#event_u)
The contents of the event.
- <a href="#event.fd_readwrite" name="event.fd_readwrite"></a> `fd_readwrite`: [`event_fd_readwrite`](#event_fd_readwrite)
The contents of the event, if it is an [`eventtype::fd_read`](#eventtype.fd_read) or
[`eventtype::fd_write`](#eventtype.fd_write). [`eventtype::clock`](#eventtype.clock) events ignore this field.

## <a href="#subclockflags" name="subclockflags"></a> `subclockflags`: Flags(`u16`)
Flags determining how to interpret the timestamp provided in
Expand Down Expand Up @@ -693,7 +687,7 @@ to coalesce with other events.
Flags specifying whether the timeout is absolute or relative

## <a href="#subscription_fd_readwrite" name="subscription_fd_readwrite"></a> `subscription_fd_readwrite`: Struct
The contents of a $subscription when type is type is
The contents of a $subscription when the variant is
[`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write).

### Struct members
Expand All @@ -705,10 +699,10 @@ The contents of a $subscription.

### Union variants
- <a href="#subscription_u.clock" name="subscription_u.clock"></a> `clock`: [`subscription_clock`](#subscription_clock)
When type is [`eventtype::clock`](#eventtype.clock):

- <a href="#subscription_u.fd_readwrite" name="subscription_u.fd_readwrite"></a> `fd_readwrite`: [`subscription_fd_readwrite`](#subscription_fd_readwrite)
When type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write):
- <a href="#subscription_u.fd_read" name="subscription_u.fd_read"></a> `fd_read`: [`subscription_fd_readwrite`](#subscription_fd_readwrite)

- <a href="#subscription_u.fd_write" name="subscription_u.fd_write"></a> `fd_write`: [`subscription_fd_readwrite`](#subscription_fd_readwrite)

## <a href="#subscription" name="subscription"></a> `subscription`: Struct
Subscription to an event.
Expand All @@ -718,11 +712,8 @@ Subscription to an event.
User-provided value that is attached to the subscription in the
implementation and returned through [`event::userdata`](#event.userdata).

- <a href="#subscription.type" name="subscription.type"></a> `type`: [`eventtype`](#eventtype)
The type of the event to which to subscribe.

- <a href="#subscription.u" name="subscription.u"></a> `u`: [`subscription_u`](#subscription_u)
The contents of the subscription.
The type of the event to which to subscribe.

## <a href="#exitcode" name="exitcode"></a> `exitcode`: `u32`
Exit code generated by a process when exiting.
Expand Down Expand Up @@ -900,22 +891,11 @@ The contents of a $prestat when type is `PREOPENTYPE_DIR`.
- <a href="#prestat_dir.pr_name_len" name="prestat_dir.pr_name_len"></a> `pr_name_len`: [`size`](#size)
The length of the directory name for use with [`fd_prestat_dir_name`](#fd_prestat_dir_name).

## <a href="#prestat_u" name="prestat_u"></a> `prestat_u`: Union
The contents of an $prestat.

### Union variants
- <a href="#prestat_u.dir" name="prestat_u.dir"></a> `dir`: [`prestat_dir`](#prestat_dir)
When type is `PREOPENTYPE_DIR`:

## <a href="#prestat" name="prestat"></a> `prestat`: Struct
## <a href="#prestat" name="prestat"></a> `prestat`: Union
Information about a pre-opened capability.

### Struct members
- <a href="#prestat.pr_type" name="prestat.pr_type"></a> `pr_type`: [`preopentype`](#preopentype)
The type of the pre-opened capability.

- <a href="#prestat.u" name="prestat.u"></a> `u`: [`prestat_u`](#prestat_u)
The contents of the information.
### Union variants
- <a href="#prestat.dir" name="prestat.dir"></a> `dir`: [`prestat_dir`](#prestat_dir)

# Modules
## <a href="#wasi_unstable" name="wasi_unstable"></a> wasi_unstable
Expand Down
45 changes: 12 additions & 33 deletions phases/old/snapshot_0/witx/typenames.witx
Original file line number Diff line number Diff line change
Expand Up @@ -503,8 +503,8 @@
)
)

;;; The contents of an $event when type is `eventtype::fd_read` or
;;; `eventtype::fd_write`.
;;; The contents of an $event for the `eventtype::fd_read` and
;;; `eventtype::fd_write` variants
(typename $event_fd_readwrite
(struct
;;; The number of bytes available for reading or writing.
Expand All @@ -514,25 +514,18 @@
)
)

;;; The contents of an $event.
(typename $event_u
(union
;;; When type is `eventtype::fd_read` or `eventtype::fd_write`:
(field $fd_readwrite $event_fd_readwrite)
)
)

;;; An event that occurred.
(typename $event
(struct
;;; User-provided value that got attached to `subscription::userdata`.
(field $userdata $userdata)
;;; If non-zero, an error that occurred while processing the subscription request.
(field $error $errno)
;;; The type of the event that occurred.
;;; The type of event that occured
(field $type $eventtype)
;;; The contents of the event.
(field $u $event_u)
;;; The contents of the event, if it is an `eventtype::fd_read` or
;;; `eventtype::fd_write`. `eventtype::clock` events ignore this field.
(field $fd_readwrite $event_fd_readwrite)
)
)

Expand Down Expand Up @@ -566,7 +559,7 @@
)
)

;;; The contents of a $subscription when type is type is
;;; The contents of a $subscription when the variant is
;;; `eventtype::fd_read` or `eventtype::fd_write`.
(typename $subscription_fd_readwrite
(struct
Expand All @@ -577,11 +570,10 @@

;;; The contents of a $subscription.
(typename $subscription_u
(union
;;; When type is `eventtype::clock`:
(union $eventtype
(field $clock $subscription_clock)
;;; When type is `eventtype::fd_read` or `eventtype::fd_write`:
(field $fd_readwrite $subscription_fd_readwrite)
(field $fd_read $subscription_fd_readwrite)
(field $fd_write $subscription_fd_readwrite)
)
)

Expand All @@ -592,8 +584,6 @@
;;; implementation and returned through `event::userdata`.
(field $userdata $userdata)
;;; The type of the event to which to subscribe.
(field $type $eventtype)
;;; The contents of the subscription.
(field $u $subscription_u)
)
)
Expand Down Expand Up @@ -748,20 +738,9 @@
)
)

;;; The contents of an $prestat.
(typename $prestat_u
(union
;;; When type is `PREOPENTYPE_DIR`:
(field $dir $prestat_dir)
)
)

;;; Information about a pre-opened capability.
(typename $prestat
(struct
;;; The type of the pre-opened capability.
(field $pr_type $preopentype)
;;; The contents of the information.
(field $u $prestat_u)
(union $preopentype
(field $dir $prestat_dir)
)
)
Loading

0 comments on commit 85df508

Please sign in to comment.