Skip to content

Commit ef8c1a5

Browse files
authored
Take another step towards interface types (#395)
* Take another step towards interface types This commit is another large refactoring on the tail of #391 which is intended to help march one step closer to using pure interface types for specifying WASI and using `*.witx` files. Contained here is a large amount of refactoring of the `*.witx` files, the internals of the `witx` crate, and how code generators are supposed to work. At the `*.witx` level, some notable changes have been made: * All functions returning results now return `(expected ok? (error $errno))`. This helps signify that the intention of all functions is that they return a packaged value which is either a successful result or the erroneous error code on failure. ABI-wise nothing has changed, but this is intended to model more closely what the interface-types API of this would be. * The `flags` type in `*.witx` now desugars as a struct-of-bools rather than simply an `int`. This doesn't have any effect on the ABI today, but it does change the AST and type-level representation of these types. All existing `*.witx` files in this repository have been updated for all phases with these new forms. To reiterate, though, no details of the ABI have changed (or at least not intentionally). Everything should still be ABI-compatible with before. Under the hood for code generators this is a very large breaking change. The intention of this commit is to start moving code generators relying on `witx` into the direction that we'll end up with interface types. Namely the `coretypes` module is entirely replaced with a new `abi` module with the intention of handling lots more high-level details of translation than the previous module did. The `InterfaceFunc` type now sports two new methods: `call_wasm` and `call_interface`. These two methods represent the two halves of lifting/lowering operations performed by code generators. The `call_wasm` function takes interface types values (or whatever they are represented as in the source language) and converts them to wasm types to call a wasm import. The wasm import's return values are then "deserialized" back into the language's interface types values too. The `call_interface` function is the opposite, it assumes that you're coming from wasm values and calling, e.g., a host function with interface values. The `abi` module is refactored with an `Instruction` `enum` which lists out what are the current set of "adapter instructions". These adapter instructions are intended to somewhat model the eventual idea of adapter functions and their instructions, but for now they're pretty specific to WASI as-is today. All instructions currently model what WASI currently does, sometimes in very specific manners. It's expected that the `Instruction` type will be in flux as we tweak the ABI of WASI over time, but the current set of instructions will likely only be expanded because of maintaining compatibility with the current snapshot. The expected usage of `Instruction` is that code generators will implement how to generate code for each `Instruction`. This should be a very low-level operation (generating code per instruction) and should be in theory quite easy to implement. Not all code generators need to implement all instructions depending on their use case. Additionally WASI as-is today doesn't always exercise all types of instructions. The next steps after a PR like this include starting to define a new ABI for WASI which supports all types in all positions rather than the current ABI which supports only a limited subset of types in some positions. The intention is that this new ABI may add a new instruction or two but will generally not be a large breaking change for all existing code generators. Some new additions are expected but other than that existing code generators updated to use this PR will require little effort to support new ABIs. * Add more documentation and some more tests for shorthand syntax * Bump to 0.9.0 and bump wast dependency * Support variants as arguments Same as records, they use pointers * Fix a typo
1 parent 3ca67fc commit ef8c1a5

33 files changed

+4528
-1309
lines changed

phases/ephemeral/docs.md

Lines changed: 733 additions & 236 deletions
Large diffs are not rendered by default.

phases/ephemeral/witx/typenames.witx

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@
195195

196196
;;; File descriptor rights, determining which actions may be performed.
197197
(typename $rights
198-
(flags (@witx bitflags u64)
198+
(flags (@witx repr u64)
199199
;;; The right to invoke `fd_datasync`.
200200
;;
201201
;;; If `path_open` is set, includes the right to invoke
@@ -392,7 +392,7 @@
392392

393393
;;; File descriptor flags.
394394
(typename $fdflags
395-
(flags (@witx bitflags u16)
395+
(flags (@witx repr u16)
396396
;;; Append mode: Data written to the file is always appended to the file's end.
397397
$append
398398
;;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized.
@@ -429,7 +429,7 @@
429429

430430
;;; Which file time attributes to adjust.
431431
(typename $fstflags
432-
(flags (@witx bitflags u16)
432+
(flags (@witx repr u16)
433433
;;; Adjust the last data access timestamp to the value stored in `filestat::atim`.
434434
$atim
435435
;;; Adjust the last data access timestamp to the time of clock `clockid::realtime`.
@@ -443,15 +443,15 @@
443443

444444
;;; Flags determining the method of how paths are resolved.
445445
(typename $lookupflags
446-
(flags (@witx bitflags u32)
446+
(flags (@witx repr u32)
447447
;;; As long as the resolved path corresponds to a symbolic link, it is expanded.
448448
$symlink_follow
449449
)
450450
)
451451

452452
;;; Open flags used by `path_open`.
453453
(typename $oflags
454-
(flags (@witx bitflags u16)
454+
(flags (@witx repr u16)
455455
;;; Create file if it does not exist.
456456
$create
457457
;;; Fail if not a directory.
@@ -470,7 +470,7 @@
470470
;;; file in a filesystem, and don't fully reflect all the conditions
471471
;;; which determine whether a given WASI program can access the file.
472472
(typename $permissions
473-
(flags (@witx bitflags u8)
473+
(flags (@witx repr u8)
474474
;;; For files, permission to read the file.
475475
;;; For directories, permission to do `readdir` and access files
476476
;;; within the directory.
@@ -543,7 +543,7 @@
543543
;;; The state of the file descriptor subscribed to with
544544
;;; `eventtype::fd_read` or `eventtype::fd_write`.
545545
(typename $eventrwflags
546-
(flags (@witx bitflags u16)
546+
(flags (@witx repr u16)
547547
;;; The peer of this socket has closed or disconnected.
548548
$fd_readwrite_hangup
549549
)
@@ -584,7 +584,7 @@
584584
;;; Flags determining how to interpret the timestamp provided in
585585
;;; `subscription_clock::timeout`.
586586
(typename $subclockflags
587-
(flags (@witx bitflags u16)
587+
(flags (@witx repr u16)
588588
;;; If set, treat the timestamp provided in
589589
;;; `subscription_clock::timeout` as an absolute timestamp of clock
590590
;;; `subscription_clock::id`. If clear, treat the timestamp
@@ -643,7 +643,7 @@
643643

644644
;;; Flags provided to `sock_recv`.
645645
(typename $riflags
646-
(flags (@witx bitflags u16)
646+
(flags (@witx repr u16)
647647
;;; Returns the message without removing it from the socket's receive queue.
648648
$recv_peek
649649
;;; On byte-stream sockets, block until the full amount of data can be returned.
@@ -653,7 +653,7 @@
653653

654654
;;; Flags returned by `sock_recv`.
655655
(typename $roflags
656-
(flags (@witx bitflags u16)
656+
(flags (@witx repr u16)
657657
;;; Returned by `sock_recv`: Message data has been truncated.
658658
$recv_data_truncated
659659
)
@@ -665,7 +665,7 @@
665665

666666
;;; Which channels on a socket to shut down.
667667
(typename $sdflags
668-
(flags (@witx bitflags u8)
668+
(flags (@witx repr u8)
669669
;;; Disables further receive operations.
670670
$rd
671671
;;; Disables further send operations.

phases/ephemeral/witx/wasi_ephemeral_args.witx

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,13 @@
1414
(@interface func (export "get")
1515
(param $argv (@witx pointer (@witx pointer (@witx char8))))
1616
(param $argv_buf (@witx pointer (@witx char8)))
17-
(result $error $errno)
17+
(result $error (expected (error $errno)))
1818
)
1919

2020
;;; Return command-line argument data sizes.
2121
(@interface func (export "sizes_get")
22-
(result $error $errno)
23-
;;; The number of arguments.
24-
(result $argc $size)
25-
;;; The size of the argument string data.
26-
(result $argv_buf_size $size)
22+
;;; Returns the number of arguments and the size of the argument string
23+
;;; data, or an error.
24+
(result $error (expected (tuple $size $size) (error $errno)))
2725
)
2826
)

phases/ephemeral/witx/wasi_ephemeral_clock.witx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,8 @@
1818
(@interface func (export "res_get")
1919
;;; The clock for which to return the resolution.
2020
(param $id $clockid)
21-
(result $error $errno)
2221
;;; The resolution of the clock.
23-
(result $resolution $timestamp)
22+
(result $error (expected $timestamp (error $errno)))
2423
)
2524

2625
;;; Return the time value of a clock.
@@ -30,8 +29,7 @@
3029
(param $id $clockid)
3130
;;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value.
3231
(param $precision $timestamp)
33-
(result $error $errno)
3432
;;; The time value of the clock.
35-
(result $time $timestamp)
33+
(result $error (expected $timestamp (error $errno)))
3634
)
3735
)

phases/ephemeral/witx/wasi_ephemeral_environ.witx

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,13 @@
1414
(@interface func (export "get")
1515
(param $environ (@witx pointer (@witx pointer (@witx char8))))
1616
(param $environ_buf (@witx pointer (@witx char8)))
17-
(result $error $errno)
17+
(result $error (expected (error $errno)))
1818
)
1919

2020
;;; Return environment variable data sizes.
2121
(@interface func (export "sizes_get")
22-
(result $error $errno)
23-
;;; The number of environment variable arguments.
24-
(result $environc $size)
25-
;;; The size of the environment variable data.
26-
(result $environ_buf_size $size)
22+
;;; Returns the number of environment variable arguments and the size of the
23+
;;; environment variable data.
24+
(result $error (expected (tuple $size $size) (error $errno)))
2725
)
2826
)

phases/ephemeral/witx/wasi_ephemeral_fd.witx

Lines changed: 22 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
(param $len $filesize)
2222
;;; The advice.
2323
(param $advice $advice)
24-
(result $error $errno)
24+
(result $error (expected (error $errno)))
2525
)
2626

2727
;;; Force the allocation of space in a file.
@@ -32,30 +32,29 @@
3232
(param $offset $filesize)
3333
;;; The length of the area that is allocated.
3434
(param $len $filesize)
35-
(result $error $errno)
35+
(result $error (expected (error $errno)))
3636
)
3737

3838
;;; Close a file descriptor.
3939
;;; Note: This is similar to `close` in POSIX.
4040
(@interface func (export "close")
4141
(param $fd $fd)
42-
(result $error $errno)
42+
(result $error (expected (error $errno)))
4343
)
4444

4545
;;; Synchronize the data of a file to disk.
4646
;;; Note: This is similar to `fdatasync` in POSIX.
4747
(@interface func (export "datasync")
4848
(param $fd $fd)
49-
(result $error $errno)
49+
(result $error (expected (error $errno)))
5050
)
5151

5252
;;; Get the attributes of a file descriptor.
5353
;;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields.
5454
(@interface func (export "fdstat_get")
5555
(param $fd $fd)
56-
(result $error $errno)
5756
;;; The buffer where the file descriptor's attributes are stored.
58-
(result $stat $fdstat)
57+
(result $error (expected $fdstat (error $errno)))
5958
)
6059

6160
;;; Adjust the flags associated with a file descriptor.
@@ -64,7 +63,7 @@
6463
(param $fd $fd)
6564
;;; The desired values of the file descriptor flags.
6665
(param $flags $fdflags)
67-
(result $error $errno)
66+
(result $error (expected (error $errno)))
6867
)
6968

7069
;;; Adjust the rights associated with a file descriptor.
@@ -74,15 +73,14 @@
7473
;;; The desired rights of the file descriptor.
7574
(param $fs_rights_base $rights)
7675
(param $fs_rights_inheriting $rights)
77-
(result $error $errno)
76+
(result $error (expected (error $errno)))
7877
)
7978

8079
;;; Return the attributes of an open file.
8180
(@interface func (export "filestat_get")
8281
(param $fd $fd)
83-
(result $error $errno)
8482
;;; The buffer where the file's attributes are stored.
85-
(result $buf $filestat)
83+
(result $error (expected $filestat (error $errno)))
8684
)
8785

8886
;;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros.
@@ -91,7 +89,7 @@
9189
(param $fd $fd)
9290
;;; The desired file size.
9391
(param $size $filesize)
94-
(result $error $errno)
92+
(result $error (expected (error $errno)))
9593
)
9694

9795
;;; Adjust the timestamps of an open file or directory.
@@ -104,7 +102,7 @@
104102
(param $mtim $timestamp)
105103
;;; A bitmask indicating which timestamps to adjust.
106104
(param $fst_flags $fstflags)
107-
(result $error $errno)
105+
(result $error (expected (error $errno)))
108106
)
109107

110108
;;; Set the permissions of a file or directory.
@@ -123,7 +121,7 @@
123121
(param $fd $fd)
124122
;;; The permissions associated with the file.
125123
(param $permissions $permissions)
126-
(result $error $errno)
124+
(result $error (expected (error $errno)))
127125
)
128126

129127
;;; Read from a file descriptor, without using and updating the file descriptor's offset.
@@ -134,17 +132,15 @@
134132
(param $iovs $iovec_array)
135133
;;; The offset within the file at which to read.
136134
(param $offset $filesize)
137-
(result $error $errno)
138135
;;; The number of bytes read.
139-
(result $nread $size)
136+
(result $error (expected $size (error $errno)))
140137
)
141138

142139
;;; Return a description of the given preopened file descriptor.
143140
(@interface func (export "prestat_get")
144141
(param $fd $fd)
145-
(result $error $errno)
146142
;;; The buffer where the description is stored.
147-
(result $buf $prestat)
143+
(result $error (expected $prestat (error $errno)))
148144
)
149145

150146
;;; Return a description of the given preopened file descriptor.
@@ -153,7 +149,7 @@
153149
;;; A buffer into which to write the preopened directory name.
154150
(param $path (@witx pointer (@witx char8)))
155151
(param $path_len $size)
156-
(result $error $errno)
152+
(result $error (expected (error $errno)))
157153
)
158154

159155
;;; Write to a file descriptor, without using and updating the file descriptor's offset.
@@ -168,9 +164,8 @@
168164
(param $iovs $ciovec_array)
169165
;;; The offset within the file at which to write.
170166
(param $offset $filesize)
171-
(result $error $errno)
172167
;;; The number of bytes written.
173-
(result $nwritten $size)
168+
(result $error (expected $size (error $errno)))
174169
)
175170

176171
;;; Read from a file descriptor.
@@ -179,9 +174,8 @@
179174
(param $fd $fd)
180175
;;; List of scatter/gather vectors to which to store data.
181176
(param $iovs $iovec_array)
182-
(result $error $errno)
183177
;;; The number of bytes read.
184-
(result $nread $size)
178+
(result $error (expected $size (error $errno)))
185179
)
186180

187181
;;; Read directory entries from a directory.
@@ -201,9 +195,8 @@
201195
(param $buf_len $size)
202196
;;; The location within the directory to start reading
203197
(param $cookie $dircookie)
204-
(result $error $errno)
205198
;;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached.
206-
(result $bufused $size)
199+
(result $error (expected $size (error $errno)))
207200
)
208201

209202
;;; Atomically replace a file descriptor by renumbering another file descriptor.
@@ -220,7 +213,7 @@
220213
(param $fd $fd)
221214
;;; The file descriptor to overwrite.
222215
(param $to $fd)
223-
(result $error $errno)
216+
(result $error (expected (error $errno)))
224217
)
225218

226219
;;; Move the offset of a file descriptor.
@@ -231,25 +224,23 @@
231224
(param $offset $filedelta)
232225
;;; The base from which the offset is relative.
233226
(param $whence $whence)
234-
(result $error $errno)
235227
;;; The new offset of the file descriptor, relative to the start of the file.
236-
(result $newoffset $filesize)
228+
(result $error (expected $filesize (error $errno)))
237229
)
238230

239231
;;; Synchronize the data and metadata of a file to disk.
240232
;;; Note: This is similar to `fsync` in POSIX.
241233
(@interface func (export "sync")
242234
(param $fd $fd)
243-
(result $error $errno)
235+
(result $error (expected (error $errno)))
244236
)
245237

246238
;;; Return the current offset of a file descriptor.
247239
;;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX.
248240
(@interface func (export "tell")
249241
(param $fd $fd)
250-
(result $error $errno)
251242
;;; The current offset of the file descriptor, relative to the start of the file.
252-
(result $offset $filesize)
243+
(result $error (expected $filesize (error $errno)))
253244
)
254245

255246
;;; Write to a file descriptor.
@@ -262,8 +253,7 @@
262253
(param $fd $fd)
263254
;;; List of scatter/gather vectors from which to retrieve data.
264255
(param $iovs $ciovec_array)
265-
(result $error $errno)
266256
;;; The number of bytes written.
267-
(result $nwritten $size)
257+
(result $error (expected $size (error $errno)))
268258
)
269259
)

0 commit comments

Comments
 (0)