Stream: git-wasmtime

Topic: wasmtime / PR #2487 rewrite wasi-common in terms of cap-std


view this post on Zulip Wasmtime GitHub notifications bot (Dec 08 2020 at 01:12):

pchickey opened PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Dec 08 2020 at 02:21):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Dec 08 2020 at 05:43):

sunfishcode submitted PR Review.

view this post on Zulip Wasmtime GitHub notifications bot (Dec 08 2020 at 05:43):

sunfishcode submitted PR Review.

view this post on Zulip Wasmtime GitHub notifications bot (Dec 08 2020 at 05:43):

sunfishcode created PR Review Comment:

system-interface 0.1.0 now has FileIoExt::allocate which does this.

view this post on Zulip Wasmtime GitHub notifications bot (Dec 08 2020 at 05:43):

sunfishcode created PR Review Comment:

Ah, sorry I neglected to mention it, that's in a separate crate -- fs-set-times. If you use that crate's SystemTimeSpec in place the FilestatSetTime definition above, then usage is basically

use fs_set_times::SetTimes;
file.set_times(atime, mtime)

Or something like pub trait WasiFile: FileIoExt + SetTimes might work too.

view this post on Zulip Wasmtime GitHub notifications bot (Dec 08 2020 at 05:43):

sunfishcode created PR Review Comment:

cap_std::fs::Metadata implements Unix's MetadataExt on Unix, and Windows' MetadataExt on Windows, with functions that provide all the info here, though I can look into something more portable too.

view this post on Zulip Wasmtime GitHub notifications bot (Dec 08 2020 at 05:43):

sunfishcode created PR Review Comment:

Yeah, cap-std is following std in this respect. On Unix, PermissionsExt does have a from_mode, but I'll think about adding something portable too.

view this post on Zulip Wasmtime GitHub notifications bot (Dec 10 2020 at 20:06):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Dec 10 2020 at 21:57):

pchickey submitted PR Review.

view this post on Zulip Wasmtime GitHub notifications bot (Dec 10 2020 at 21:57):

pchickey created PR Review Comment:

I'll prototype something portable that lets us implement this in the wasi-c2 crate, and we can figure out where to upstream it after.

view this post on Zulip Wasmtime GitHub notifications bot (Dec 10 2020 at 22:00):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Dec 10 2020 at 22:51):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Dec 10 2020 at 23:07):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Dec 10 2020 at 23:37):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Dec 10 2020 at 23:42):

pchickey submitted PR Review.

view this post on Zulip Wasmtime GitHub notifications bot (Dec 10 2020 at 23:42):

pchickey created PR Review Comment:

I came up with something janky here which depends on nightly to work on windows...

view this post on Zulip Wasmtime GitHub notifications bot (Dec 10 2020 at 23:43):

pchickey submitted PR Review.

view this post on Zulip Wasmtime GitHub notifications bot (Dec 10 2020 at 23:43):

pchickey created PR Review Comment:

Implemented this except for making the flags canonical, which is the sort of thing we can sort out later.

On windows, should we reject this with an error or should we silently do nothing?

view this post on Zulip Wasmtime GitHub notifications bot (Dec 11 2020 at 01:31):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Dec 11 2020 at 20:14):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Dec 11 2020 at 23:01):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Dec 11 2020 at 23:34):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Dec 12 2020 at 00:43):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Dec 12 2020 at 01:54):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Dec 12 2020 at 02:22):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Dec 15 2020 at 03:48):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Dec 16 2020 at 02:09):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Dec 16 2020 at 23:17):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Dec 17 2020 at 00:07):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Dec 17 2020 at 01:19):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Dec 17 2020 at 01:54):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Dec 18 2020 at 01:30):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Dec 18 2020 at 01:48):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Dec 18 2020 at 02:12):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Dec 18 2020 at 20:31):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Dec 19 2020 at 00:13):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Dec 19 2020 at 01:04):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 04 2021 at 20:21):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 04 2021 at 20:33):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 04 2021 at 20:37):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 05 2021 at 00:04):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 05 2021 at 00:22):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 05 2021 at 00:28):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 05 2021 at 00:42):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 05 2021 at 01:23):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 05 2021 at 01:28):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 05 2021 at 20:20):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 05 2021 at 21:57):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 05 2021 at 22:28):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 05 2021 at 22:36):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 07 2021 at 22:44):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 07 2021 at 22:56):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 08 2021 at 00:39):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 08 2021 at 00:47):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 08 2021 at 14:36):

ueno submitted PR Review.

view this post on Zulip Wasmtime GitHub notifications bot (Jan 08 2021 at 14:36):

ueno created PR Review Comment:

Probably a dumb question, but I wonder if there is a reason to have separate structs for read and write (ReadPipe and WritePipe) rather than a single bi-directional pipe, something like below?
https://github.com/ueno/wasmtime/blob/wip/dueno/wasi-c2-virt/crates/wasi-c2/src/virt/pipe.rs#L375

view this post on Zulip Wasmtime GitHub notifications bot (Jan 08 2021 at 16:52):

sunfishcode submitted PR Review.

view this post on Zulip Wasmtime GitHub notifications bot (Jan 08 2021 at 16:52):

sunfishcode created PR Review Comment:

From my perspective, the granularity of various traits in this area is something we're still figuring out. Could you say more about why Pipe in your link here uses Seek? Elsewhere you mentioned using TCP, QUIC, etc. sockets, however they don't support Seek. Things that do implement Seek such as files and memory buffers aren't interactive and don't make sense for interactive protocols, which is what one typically does on top of TCP, QUIC, etc. sockets.

view this post on Zulip Wasmtime GitHub notifications bot (Jan 08 2021 at 18:30):

pchickey submitted PR Review.

view this post on Zulip Wasmtime GitHub notifications bot (Jan 08 2021 at 18:30):

pchickey created PR Review Comment:

The use case we wrote ReadPipe and WritePipe for is just to buffering stdin and stdout/err for an instance, rather than communicate between instances. Bi-directional communication is more complex and something I wasn't ready to bite off yet.

view this post on Zulip Wasmtime GitHub notifications bot (Jan 11 2021 at 14:47):

ueno submitted PR Review.

view this post on Zulip Wasmtime GitHub notifications bot (Jan 11 2021 at 14:47):

ueno created PR Review Comment:

Could you say more about why Pipe in your link here uses Seek? Elsewhere you mentioned using TCP, QUIC, etc. sockets, however they don't support Seek.

Yes, that's true; I added it just for my demo of the other branch. On the other hand, I suspect Seek will be desirable in the case with running Wasm programs in TEE, to support transparent encryption of files.

view this post on Zulip Wasmtime GitHub notifications bot (Jan 11 2021 at 23:48):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 11 2021 at 23:57):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 12 2021 at 01:12):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 12 2021 at 01:48):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 12 2021 at 01:59):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 12 2021 at 02:34):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 12 2021 at 20:07):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 13 2021 at 01:43):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 13 2021 at 19:03):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 13 2021 at 19:07):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 13 2021 at 23:11):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 15 2021 at 01:44):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 19 2021 at 17:57):

sunfishcode submitted PR Review.

view this post on Zulip Wasmtime GitHub notifications bot (Jan 19 2021 at 17:57):

sunfishcode created PR Review Comment:

system-interface has this in num_ready_bytes. One difference from how wasi-common does it is that system-interface will sometimes return 0 if the underlying device can't report how many bytes it can read. Here, since we just called poll and it told us that something was ready, we should do let n = sub.num_ready_bytes() and then max(n, 1).

view this post on Zulip Wasmtime GitHub notifications bot (Jan 19 2021 at 22:39):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 19 2021 at 22:43):

pchickey submitted PR Review.

view this post on Zulip Wasmtime GitHub notifications bot (Jan 19 2021 at 22:43):

pchickey created PR Review Comment:

Fixed now- thanks!

view this post on Zulip Wasmtime GitHub notifications bot (Jan 19 2021 at 23:14):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 21 2021 at 03:09):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 21 2021 at 04:54):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 21 2021 at 05:03):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 21 2021 at 21:51):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 21 2021 at 22:14):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 22 2021 at 00:55):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 22 2021 at 01:57):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 22 2021 at 02:08):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 22 2021 at 02:18):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 22 2021 at 21:44):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 22 2021 at 23:33):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 22 2021 at 23:44):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 23 2021 at 02:27):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 25 2021 at 20:20):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 25 2021 at 20:54):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 25 2021 at 23:20):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 25 2021 at 23:28):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 26 2021 at 00:59):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 26 2021 at 01:02):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 26 2021 at 01:08):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 26 2021 at 01:15):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 26 2021 at 20:25):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 26 2021 at 20:27):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 27 2021 at 20:18):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 27 2021 at 20:27):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 27 2021 at 20:43):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 28 2021 at 00:16):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 28 2021 at 02:10):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 28 2021 at 02:18):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 28 2021 at 03:06):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 28 2021 at 17:44):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 28 2021 at 19:44):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 28 2021 at 20:24):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 28 2021 at 21:03):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 28 2021 at 21:23):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 28 2021 at 23:17):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 29 2021 at 01:00):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 29 2021 at 20:07):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 29 2021 at 20:29):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 29 2021 at 20:38):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 29 2021 at 21:25):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 29 2021 at 22:10):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 29 2021 at 22:27):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 29 2021 at 23:40):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 29 2021 at 23:43):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 29 2021 at 23:49):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 30 2021 at 01:24):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 30 2021 at 01:27):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 30 2021 at 02:02):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 30 2021 at 03:52):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 30 2021 at 03:53):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 30 2021 at 03:54):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 30 2021 at 04:58):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 30 2021 at 05:09):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 30 2021 at 05:25):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jan 30 2021 at 21:58):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Feb 01 2021 at 19:01):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Feb 01 2021 at 19:10):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Feb 01 2021 at 20:43):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Feb 01 2021 at 21:16):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Feb 01 2021 at 21:21):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Feb 01 2021 at 21:21):

pchickey has marked PR #2487 as ready for review.

view this post on Zulip Wasmtime GitHub notifications bot (Feb 01 2021 at 22:14):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Feb 01 2021 at 22:26):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Feb 01 2021 at 22:33):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Feb 01 2021 at 22:44):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Feb 01 2021 at 23:26):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

WIP

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Feb 01 2021 at 23:47):

pchickey edited PR #2487 from pch/wasi_common_cap_std to main:

This PR is a complete rewrite of the wasi-common crate. It uses @sunfishcode 's new cap-std family of crates to provide a sandboxed implementation of WASI on the local filesystem.

Re-architecting wasi-common

Over the past year or so, we've run up against many design problems in wasi-common. Many of these problems ended up being so fundamental that a rewrite, as prolonged as it was, ended up being more tractable than incremental changes.

The Table

The WasiFile and WasiDir traits

Traits for the rest of WASI's features

The cap-std-sync implementation of the WASI traits

Improving the WASI test suite

Wasi-common's test suite lives at crates/test-programs.

Changes to wiggle-wasmtime and dependents

Changes to wasmtime-wasi

Regressions

Some behavior around trailing slashes in paths has changed from the test suite. We expect there are some improvements we'll make to these corner cases after this PR lands.

For now, the path_rename_file_trailing_slashes and remove_directory_trailing_slashes tests are #[ignore]'d on all platforms, and additionally the interesting_paths test is ignored on Windows.

Additionally, some behavior around the FdFlags::{SYNC, DSYNC, RSYNC} flags have changed. For now, cap-std does not support opening a file with these flags. Using these flags will result in an Errno::NOTSUP (Not supported).

Outstanding issues required to merge this PR:

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Feb 01 2021 at 23:50):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

This PR is a complete rewrite of the wasi-common crate. It uses @sunfishcode 's new cap-std family of crates to provide a sandboxed implementation of WASI on the local filesystem.

Re-architecting wasi-common

Over the past year or so, we've run up against many design problems in wasi-common. Many of these problems ended up being so fundamental that a rewrite, as prolonged as it was, ended up being more tractable than incremental changes.

The Table

The WasiFile and WasiDir traits

Traits for the rest of WASI's features

The cap-std-sync implementation of the WASI traits

Improving the WASI test suite

Wasi-common's test suite lives at crates/test-programs.

Changes to wiggle-wasmtime and dependents

Changes to wasmtime-wasi

Regressions

Some behavior around trailing slashes in paths has changed from the test suite. We expect there are some improvements we'll make to these corner cases after this PR lands.

For now, the path_rename_file_trailing_slashes and remove_directory_trailing_slashes tests are #[ignore]'d on all platforms, and additionally the interesting_paths test is ignored on Windows.

Additionally, some behavior around the FdFlags::{SYNC, DSYNC, RSYNC} flags have changed. For now, cap-std does not support opening a file with these flags. Using these flags will result in an Errno::NOTSUP (Not supported).

Outstanding issues required to merge this PR:

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Feb 02 2021 at 00:03):

pchickey edited PR #2487 from pch/wasi_common_cap_std to main:

This PR is a complete rewrite of the wasi-common crate. It uses @sunfishcode 's new cap-std family of crates to provide a sandboxed implementation of WASI on the local filesystem.

Re-architecting wasi-common

Over the past year or so, we've run up against many design problems in wasi-common. Many of these problems ended up being so fundamental that a rewrite, as prolonged as it was, ended up being more tractable than incremental changes.

The Table

wasi-common now has a Table type that is designed to map u32 handles to resources. The table is now part of the public interface to a WasiCtx - it is reference counted so that it can be shared beyond a WasiCtx with other WASI proposals (e.g. wasi-crypto and wasi-nn) to manage their resources. Elements in the Table are Any typed.

The Table type is intended to model how the Interface Types concept of Resources is shaping up. Right now it is just an approximation.

The WasiFile and WasiDir traits

The WASI specification only defines one handle type, fd, on which all operations on both files and directories (aka dirfds) are defined. We believe this is a design mistake, and are architecting wasi-common to make this straightforward to correct in future snapshots of WASI. Wasi-common internally treats files and directories as two distinct resource types in the table - Box<dyn WasiFile> and Box<dyn WasiDir>. The snapshot 0 and 1 interfaces via fd will attempt to downcast a table element to one or both of these interfaces depending on what is appropriate - e.g. fd_close operates on both files and directories, fd_read only operates on files, and fd_readdir only operates on directories.

The WasiFile and WasiDir traits are defined by wasi-common in terms of types defined directly in the crate's source code (I decided it should NOT those generated by the wiggle proc macros, see snapshot architecture below), as well as the cap_std::time family of types.

Traits for the rest of WASI's features

Snapshot architecture

The cap-std-sync implementation of the WASI traits

Improving the WASI test suite

Wasi-common's test suite lives at crates/test-programs.

Changes to wiggle-wasmtime and dependents

Changes to wasmtime-wasi

Regressions

Some behavior around trailing slashes in paths has changed from the test suite. We expect there are some improvements we'll make to these corner cases after this PR lands.

For now, the path_rename_file_trailing_slashes and remove_directory_trailing_slashes tests are #[ignore]'d on all platforms, and additionally the interesting_paths test is ignored on Windows.

Additionally, some behavior around the FdFlags::{SYNC, DSYNC, RSYNC} flags have changed. For now, cap-std does not support opening a file with these flags. Using these flags will result in an Errno::NOTSUP (Not supported).

Outstanding issues required to merge this PR:

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Feb 02 2021 at 00:11):

pchickey edited PR #2487 from pch/wasi_common_cap_std to main:

This PR is a complete rewrite of the wasi-common crate. It uses @sunfishcode 's new cap-std family of crates to provide a sandboxed implementation of WASI on the local filesystem.

Re-architecting wasi-common

Over the past year or so, we've run up against many design problems in wasi-common. Many of these problems ended up being so fundamental that a rewrite, as prolonged as it was, ended up being more tractable than incremental changes.

The Table

wasi-common now has a Table type that is designed to map u32 handles to resources. The table is now part of the public interface to a WasiCtx - it is reference counted so that it can be shared beyond a WasiCtx with other WASI proposals (e.g. wasi-crypto and wasi-nn) to manage their resources. Elements in the Table are Any typed.

The Table type is intended to model how the Interface Types concept of Resources is shaping up. Right now it is just an approximation.

The WasiFile and WasiDir traits

The WASI specification only defines one handle type, fd, on which all operations on both files and directories (aka dirfds) are defined. We believe this is a design mistake, and are architecting wasi-common to make this straightforward to correct in future snapshots of WASI. Wasi-common internally treats files and directories as two distinct resource types in the table - Box<dyn WasiFile> and Box<dyn WasiDir>. The snapshot 0 and 1 interfaces via fd will attempt to downcast a table element to one or both of these interfaces depending on what is appropriate - e.g. fd_close operates on both files and directories, fd_read only operates on files, and fd_readdir only operates on directories.

The WasiFile and WasiDir traits are defined by wasi-common in terms of types defined directly in the crate's source code (I decided it should NOT those generated by the wiggle proc macros, see snapshot architecture below), as well as the cap_std::time family of types. And, importantly, wasi-common itself provides no implementation of WasiDir, and only two trivial implementations of WasiFile on the crate::pipe::{ReadPipe, WritePipe} types, which in turn just delegate to std::io::{Read, Write}. In order for wasi-common to access the local filesystem at all, you need to provide WasiFile and WasiDir impls through either the new wasi-cap-std-sync crate found at crates/wasi-common/cap-std-sync - see the section on that crate below - or by providing your own implementation from elsewhere.

This design makes it possible for wasi-common embedders to statically reason about access to the local filesystem by examining what impls are linked into an application. We found that this separation of concerns also makes it pretty enjoyable to write alternative implementations, e.g. a virtual filesystem (which will land in a future PR)

Traits for the rest of WASI's features

Snapshot architecture

The cap-std-sync implementation of the WASI traits

Improving the WASI test suite

Wasi-common's test suite lives at crates/test-programs.

Changes to wiggle-wasmtime and dependents

Changes to wasmtime-wasi

Regressions

Some behavior around trailing slashes in paths has changed from the test suite. We expect there are some improvements we'll make to these corner cases after this PR lands.

For now, the path_rename_file_trailing_slashes and remove_directory_trailing_slashes tests are #[ignore]'d on all platforms, and additionally the interesting_paths test is ignored on Windows.

Additionally, some behavior around the FdFlags::{SYNC, DSYNC, RSYNC} flags have changed. For now, cap-std does not support opening a file with these flags. Using these flags will result in an Errno::NOTSUP (Not supported).

Outstanding issues required to merge this PR:

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Feb 02 2021 at 00:25):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

This PR is a complete rewrite of the wasi-common crate. It uses @sunfishcode 's new cap-std family of crates to provide a sandboxed implementation of WASI on the local filesystem.

Re-architecting wasi-common

Over the past year or so, we've run up against many design problems in wasi-common. Many of these problems ended up being so fundamental that a rewrite, as prolonged as it was, ended up being more tractable than incremental changes.

The Table

wasi-common now has a Table type that is designed to map u32 handles to resources. The table is now part of the public interface to a WasiCtx - it is reference counted so that it can be shared beyond a WasiCtx with other WASI proposals (e.g. wasi-crypto and wasi-nn) to manage their resources. Elements in the Table are Any typed.

The Table type is intended to model how the Interface Types concept of Resources is shaping up. Right now it is just an approximation.

The WasiFile and WasiDir traits

The WASI specification only defines one handle type, fd, on which all operations on both files and directories (aka dirfds) are defined. We believe this is a design mistake, and are architecting wasi-common to make this straightforward to correct in future snapshots of WASI. Wasi-common internally treats files and directories as two distinct resource types in the table - Box<dyn WasiFile> and Box<dyn WasiDir>. The snapshot 0 and 1 interfaces via fd will attempt to downcast a table element to one or both of these interfaces depending on what is appropriate - e.g. fd_close operates on both files and directories, fd_read only operates on files, and fd_readdir only operates on directories.

The WasiFile and WasiDir traits are defined by wasi-common in terms of types defined directly in the crate's source code (I decided it should NOT those generated by the wiggle proc macros, see snapshot architecture below), as well as the cap_std::time family of types. And, importantly, wasi-common itself provides no implementation of WasiDir, and only two trivial implementations of WasiFile on the crate::pipe::{ReadPipe, WritePipe} types, which in turn just delegate to std::io::{Read, Write}. In order for wasi-common to access the local filesystem at all, you need to provide WasiFile and WasiDir impls through either the new wasi-cap-std-sync crate found at crates/wasi-common/cap-std-sync - see the section on that crate below - or by providing your own implementation from elsewhere.

This design makes it possible for wasi-common embedders to statically reason about access to the local filesystem by examining what impls are linked into an application. We found that this separation of concerns also makes it pretty enjoyable to write alternative implementations, e.g. a virtual filesystem (which will land in a future PR)

Traits for the rest of WASI's features

Snapshot architecture

The cap-std-sync implementation of the WASI traits

Improving the WASI test suite

Wasi-common's test suite lives at crates/test-programs.

Changes to wiggle-wasmtime and dependents

Changes to wasmtime-wasi

Regressions

Some behavior around trailing slashes in paths has changed from the test suite. We expect there are some improvements we'll make to these corner cases after this PR lands.

For now, the path_rename_file_trailing_slashes and remove_directory_trailing_slashes tests are #[ignore]'d on all platforms, and additionally the interesting_paths test is ignored on Windows.

Additionally, some behavior around the FdFlags::{SYNC, DSYNC, RSYNC} flags have changed. For now, cap-std does not support opening a file with these flags. Using these flags will result in an Errno::NOTSUP (Not supported).

Outstanding issues required to merge this PR:

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Feb 02 2021 at 00:45):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

This PR is a complete rewrite of the wasi-common crate. It uses @sunfishcode 's new cap-std family of crates to provide a sandboxed implementation of WASI on the local filesystem.

Re-architecting wasi-common

Over the past year or so, we've run up against many design problems in wasi-common. Many of these problems ended up being so fundamental that a rewrite, as prolonged as it was, ended up being more tractable than incremental changes.

The Table

wasi-common now has a Table type that is designed to map u32 handles to resources. The table is now part of the public interface to a WasiCtx - it is reference counted so that it can be shared beyond a WasiCtx with other WASI proposals (e.g. wasi-crypto and wasi-nn) to manage their resources. Elements in the Table are Any typed.

The Table type is intended to model how the Interface Types concept of Resources is shaping up. Right now it is just an approximation.

The WasiFile and WasiDir traits

The WASI specification only defines one handle type, fd, on which all operations on both files and directories (aka dirfds) are defined. We believe this is a design mistake, and are architecting wasi-common to make this straightforward to correct in future snapshots of WASI. Wasi-common internally treats files and directories as two distinct resource types in the table - Box<dyn WasiFile> and Box<dyn WasiDir>. The snapshot 0 and 1 interfaces via fd will attempt to downcast a table element to one or both of these interfaces depending on what is appropriate - e.g. fd_close operates on both files and directories, fd_read only operates on files, and fd_readdir only operates on directories.

The WasiFile and WasiDir traits are defined by wasi-common in terms of types defined directly in the crate's source code (I decided it should NOT those generated by the wiggle proc macros, see snapshot architecture below), as well as the cap_std::time family of types. And, importantly, wasi-common itself provides no implementation of WasiDir, and only two trivial implementations of WasiFile on the crate::pipe::{ReadPipe, WritePipe} types, which in turn just delegate to std::io::{Read, Write}. In order for wasi-common to access the local filesystem at all, you need to provide WasiFile and WasiDir impls through either the new wasi-cap-std-sync crate found at crates/wasi-common/cap-std-sync - see the section on that crate below - or by providing your own implementation from elsewhere.

This design makes it possible for wasi-common embedders to statically reason about access to the local filesystem by examining what impls are linked into an application. We found that this separation of concerns also makes it pretty enjoyable to write alternative implementations, e.g. a virtual filesystem (which will land in a future PR)

Traits for the rest of WASI's features

Snapshot architecture

The cap-std-sync implementation of the WASI traits

Improving the WASI test suite

Wasi-common's test suite lives at crates/test-programs.

Changes to wiggle-wasmtime and dependents

Changes to wasmtime-wasi

Regressions

Some behavior around trailing slashes in paths has changed from the test suite. We expect there are some improvements we'll make to these corner cases after this PR lands.

For now, the path_rename_file_trailing_slashes and remove_directory_trailing_slashes tests are #[ignore]'d on all platforms, and additionally the interesting_paths test is ignored on Windows.

Additionally, some behavior around the FdFlags::{SYNC, DSYNC, RSYNC} flags have changed. For now, cap-std does not support opening a file with these flags. Using these flags will result in an Errno::NOTSUP (Not supported).

Outstanding issues required to merge this PR:

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Feb 02 2021 at 00:57):

pchickey edited PR #2487 from pch/wasi_common_cap_std to main:

This PR is a complete rewrite of the wasi-common crate. It uses @sunfishcode 's new cap-std family of crates to provide a sandboxed implementation of WASI on the local filesystem.

Note that this is a breaking change for all users of WASI with Wasmtime, except for the C API.

Re-architecting wasi-common

Over the past year or so, we've run up against many design problems in wasi-common. Many of these problems ended up being so fundamental that a rewrite, as prolonged as it was, ended up being more tractable than incremental changes.

The Table

wasi-common now has a Table type that is designed to map u32 handles to resources. The table is now part of the public interface to a WasiCtx - it is reference counted so that it can be shared beyond a WasiCtx with other WASI proposals (e.g. wasi-crypto and wasi-nn) to manage their resources. Elements in the Table are Any typed.

The Table type is intended to model how the Interface Types concept of Resources is shaping up. Right now it is just an approximation.

The WasiFile and WasiDir traits

The WASI specification only defines one handle type, fd, on which all operations on both files and directories (aka dirfds) are defined. We believe this is a design mistake, and are architecting wasi-common to make this straightforward to correct in future snapshots of WASI. Wasi-common internally treats files and directories as two distinct resource types in the table - Box<dyn WasiFile> and Box<dyn WasiDir>. The snapshot 0 and 1 interfaces via fd will attempt to downcast a table element to one or both of these interfaces depending on what is appropriate - e.g. fd_close operates on both files and directories, fd_read only operates on files, and fd_readdir only operates on directories.

The WasiFile and WasiDir traits are defined by wasi-common in terms of types defined directly in the crate's source code (I decided it should NOT those generated by the wiggle proc macros, see snapshot architecture below), as well as the cap_std::time family of types. And, importantly, wasi-common itself provides no implementation of WasiDir, and only two trivial implementations of WasiFile on the crate::pipe::{ReadPipe, WritePipe} types, which in turn just delegate to std::io::{Read, Write}. In order for wasi-common to access the local filesystem at all, you need to provide WasiFile and WasiDir impls through either the new wasi-cap-std-sync crate found at crates/wasi-common/cap-std-sync - see the section on that crate below - or by providing your own implementation from elsewhere.

This design makes it possible for wasi-common embedders to statically reason about access to the local filesystem by examining what impls are linked into an application. We found that this separation of concerns also makes it pretty enjoyable to write alternative implementations, e.g. a virtual filesystem (which will land in a future PR).

Traits for the rest of WASI's features

Other aspects of a WASI implementation are not yet considered resources and accessed by handle. We plan to correct this design deficiency in WASI in the future, but for now we have designed the following traits to provide embedders with the same sort of implementation flexibility they get with WasiFile/WasiDir:

Users can provide implementations of each of these interfaces to the WasiCtx::builder(...) function. The wasi_cap_std_sync::WasiCtxBuilder::new() function uses this public interface to plug in its own implementations of each of these resources.

Snapshot architecture

One goal we've had for a while, but not quite met, is for multiple WASI snapshots to provide an interface to the same underlying WasiCtx. This provides us a path to evolve WASI by allowing the same WASI Command to import functions from different snapshots - e.g. the user could use Rust's std which imports snapshot 1, but also depend directly on the wasi crate which imports some future snapshot 2. Right now, this amounts to supporting snapshot 1 and "snapshot 0" aka wasi_unstable at once.

The architectural rules for snapshots are:

The cap-std-sync implementation of the WASI traits

Improving the WASI test suite

Wasi-common's test suite lives at crates/test-programs.

Changes to wiggle-wasmtime and dependents

Changes to wasmtime-wasi

Regressions

Some behavior around trailing slashes in paths has changed from the test suite. We expect there are some improvements we'll make to these corner cases after this PR lands.

For now, the path_rename_file_trailing_slashes and remove_directory_trailing_slashes tests are #[ignore]'d on all platforms, and additionally the interesting_paths test is ignored on Windows.

Additionally, some behavior around the FdFlags::{SYNC, DSYNC, RSYNC} flags have changed. For now, cap-std does not support opening a file with these flags. Using these flags will result in an Errno::NOTSUP (Not supported).

Outstanding issues required to merge this PR:

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Feb 02 2021 at 01:06):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

This PR is a complete rewrite of the wasi-common crate. It uses @sunfishcode 's new cap-std family of crates to provide a sandboxed implementation of WASI on the local filesystem.

Note that this is a breaking change for all users of WASI with Wasmtime, except for the C API.

Re-architecting wasi-common

Over the past year or so, we've run up against many design problems in wasi-common. Many of these problems ended up being so fundamental that a rewrite, as prolonged as it was, ended up being more tractable than incremental changes.

The Table

wasi-common now has a Table type that is designed to map u32 handles to resources. The table is now part of the public interface to a WasiCtx - it is reference counted so that it can be shared beyond a WasiCtx with other WASI proposals (e.g. wasi-crypto and wasi-nn) to manage their resources. Elements in the Table are Any typed.

The Table type is intended to model how the Interface Types concept of Resources is shaping up. Right now it is just an approximation.

The WasiFile and WasiDir traits

The WASI specification only defines one handle type, fd, on which all operations on both files and directories (aka dirfds) are defined. We believe this is a design mistake, and are architecting wasi-common to make this straightforward to correct in future snapshots of WASI. Wasi-common internally treats files and directories as two distinct resource types in the table - Box<dyn WasiFile> and Box<dyn WasiDir>. The snapshot 0 and 1 interfaces via fd will attempt to downcast a table element to one or both of these interfaces depending on what is appropriate - e.g. fd_close operates on both files and directories, fd_read only operates on files, and fd_readdir only operates on directories.

The WasiFile and WasiDir traits are defined by wasi-common in terms of types defined directly in the crate's source code (I decided it should NOT those generated by the wiggle proc macros, see snapshot architecture below), as well as the cap_std::time family of types. And, importantly, wasi-common itself provides no implementation of WasiDir, and only two trivial implementations of WasiFile on the crate::pipe::{ReadPipe, WritePipe} types, which in turn just delegate to std::io::{Read, Write}. In order for wasi-common to access the local filesystem at all, you need to provide WasiFile and WasiDir impls through either the new wasi-cap-std-sync crate found at crates/wasi-common/cap-std-sync - see the section on that crate below - or by providing your own implementation from elsewhere.

This design makes it possible for wasi-common embedders to statically reason about access to the local filesystem by examining what impls are linked into an application. We found that this separation of concerns also makes it pretty enjoyable to write alternative implementations, e.g. a virtual filesystem (which will land in a future PR).

Traits for the rest of WASI's features

Other aspects of a WASI implementation are not yet considered resources and accessed by handle. We plan to correct this design deficiency in WASI in the future, but for now we have designed the following traits to provide embedders with the same sort of implementation flexibility they get with WasiFile/WasiDir:

Users can provide implementations of each of these interfaces to the WasiCtx::builder(...) function. The wasi_cap_std_sync::WasiCtxBuilder::new() function uses this public interface to plug in its own implementations of each of these resources.

Snapshot architecture

One goal we've had for a while, but not quite met, is for multiple WASI snapshots to provide an interface to the same underlying WasiCtx. This provides us a path to evolve WASI by allowing the same WASI Command to import functions from different snapshots - e.g. the user could use Rust's std which imports snapshot 1, but also depend directly on the wasi crate which imports some future snapshot 2. Right now, this amounts to supporting snapshot 1 and "snapshot 0" aka wasi_unstable at once.

The architectural rules for snapshots are:

The cap-std-sync implementation of the WASI traits

Improving the WASI test suite

Wasi-common's test suite lives at crates/test-programs.

Changes to wiggle-wasmtime and dependents

Changes to wasmtime-wasi

Regressions

Some behavior around trailing slashes in paths has changed from the test suite. We expect there are some improvements we'll make to these corner cases after this PR lands.

For now, the path_rename_file_trailing_slashes and remove_directory_trailing_slashes tests are #[ignore]'d on all platforms, and additionally the interesting_paths test is ignored on Windows.

Additionally, some behavior around the FdFlags::{SYNC, DSYNC, RSYNC} flags have changed. For now, cap-std does not support opening a file with these flags. Using these flags will result in an Errno::NOTSUP (Not supported).

Outstanding issues required to merge this PR:

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Feb 02 2021 at 01:07):

pchickey edited PR #2487 from pch/wasi_common_cap_std to main:

This PR is a complete rewrite of the wasi-common crate. It uses @sunfishcode 's new cap-std family of crates to provide a sandboxed implementation of WASI on the local filesystem.

Note that this is a breaking change for all users of WASI with Wasmtime, except for the C API.

Re-architecting wasi-common

Over the past year or so, we've run up against many design problems in wasi-common. Many of these problems ended up being so fundamental that a rewrite, as prolonged as it was, ended up being more tractable than incremental changes.

The Table

wasi-common now has a Table type that is designed to map u32 handles to resources. The table is now part of the public interface to a WasiCtx - it is reference counted so that it can be shared beyond a WasiCtx with other WASI proposals (e.g. wasi-crypto and wasi-nn) to manage their resources. Elements in the Table are Any typed.

The Table type is intended to model how the Interface Types concept of Resources is shaping up. Right now it is just an approximation.

The WasiFile and WasiDir traits

The WASI specification only defines one handle type, fd, on which all operations on both files and directories (aka dirfds) are defined. We believe this is a design mistake, and are architecting wasi-common to make this straightforward to correct in future snapshots of WASI. Wasi-common internally treats files and directories as two distinct resource types in the table - Box<dyn WasiFile> and Box<dyn WasiDir>. The snapshot 0 and 1 interfaces via fd will attempt to downcast a table element to one or both of these interfaces depending on what is appropriate - e.g. fd_close operates on both files and directories, fd_read only operates on files, and fd_readdir only operates on directories.

The WasiFile and WasiDir traits are defined by wasi-common in terms of types defined directly in the crate's source code (I decided it should NOT those generated by the wiggle proc macros, see snapshot architecture below), as well as the cap_std::time family of types. And, importantly, wasi-common itself provides no implementation of WasiDir, and only two trivial implementations of WasiFile on the crate::pipe::{ReadPipe, WritePipe} types, which in turn just delegate to std::io::{Read, Write}. In order for wasi-common to access the local filesystem at all, you need to provide WasiFile and WasiDir impls through either the new wasi-cap-std-sync crate found at crates/wasi-common/cap-std-sync - see the section on that crate below - or by providing your own implementation from elsewhere.

This design makes it possible for wasi-common embedders to statically reason about access to the local filesystem by examining what impls are linked into an application. We found that this separation of concerns also makes it pretty enjoyable to write alternative implementations, e.g. a virtual filesystem (which will land in a future PR).

Traits for the rest of WASI's features

Other aspects of a WASI implementation are not yet considered resources and accessed by handle. We plan to correct this design deficiency in WASI in the future, but for now we have designed the following traits to provide embedders with the same sort of implementation flexibility they get with WasiFile/WasiDir:

Users can provide implementations of each of these interfaces to the WasiCtx::builder(...) function. The wasi_cap_std_sync::WasiCtxBuilder::new() function uses this public interface to plug in its own implementations of each of these resources.

Snapshot architecture

One goal we've had for a while, but not quite met, is for multiple WASI snapshots to provide an interface to the same underlying WasiCtx. This provides us a path to evolve WASI by allowing the same WASI Command to import functions from different snapshots - e.g. the user could use Rust's std which imports snapshot 1, but also depend directly on the wasi crate which imports some future snapshot 2. Right now, this amounts to supporting snapshot 1 and "snapshot 0" aka wasi_unstable at once.

The architectural rules for snapshots are:

The cap-std-sync implementation of the WASI traits

Why is this impl suffixed with -sync? https://github.com/bytecodealliance/wasmtime/pull/2434 async is coming soon!

Improving the WASI test suite

Wasi-common's test suite lives at crates/test-programs.

Changes to wiggle-wasmtime and dependents

Changes to wasmtime-wasi

Regressions

Some behavior around trailing slashes in paths has changed from the test suite. We expect there are some improvements we'll make to these corner cases after this PR lands.

For now, the path_rename_file_trailing_slashes and remove_directory_trailing_slashes tests are #[ignore]'d on all platforms, and additionally the interesting_paths test is ignored on Windows.

Additionally, some behavior around the FdFlags::{SYNC, DSYNC, RSYNC} flags have changed. For now, cap-std does not support opening a file with these flags. Using these flags will result in an Errno::NOTSUP (Not supported).

Outstanding issues required to merge this PR:

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Feb 02 2021 at 01:08):

pchickey edited PR #2487 from pch/wasi_common_cap_std to main:

This PR is a complete rewrite of the wasi-common crate. It uses @sunfishcode 's new cap-std family of crates to provide a sandboxed implementation of WASI on the local filesystem.

Note that this is a breaking change for all users of WASI with Wasmtime, except for the C API.

Re-architecting wasi-common

Over the past year or so, we've run up against many design problems in wasi-common. Many of these problems ended up being so fundamental that a rewrite, as prolonged as it was, ended up being more tractable than incremental changes.

The Table

wasi-common now has a Table type that is designed to map u32 handles to resources. The table is now part of the public interface to a WasiCtx - it is reference counted so that it can be shared beyond a WasiCtx with other WASI proposals (e.g. wasi-crypto and wasi-nn) to manage their resources. Elements in the Table are Any typed.

The Table type is intended to model how the Interface Types concept of Resources is shaping up. Right now it is just an approximation.

The WasiFile and WasiDir traits

The WASI specification only defines one handle type, fd, on which all operations on both files and directories (aka dirfds) are defined. We believe this is a design mistake, and are architecting wasi-common to make this straightforward to correct in future snapshots of WASI. Wasi-common internally treats files and directories as two distinct resource types in the table - Box<dyn WasiFile> and Box<dyn WasiDir>. The snapshot 0 and 1 interfaces via fd will attempt to downcast a table element to one or both of these interfaces depending on what is appropriate - e.g. fd_close operates on both files and directories, fd_read only operates on files, and fd_readdir only operates on directories.

The WasiFile and WasiDir traits are defined by wasi-common in terms of types defined directly in the crate's source code (I decided it should NOT those generated by the wiggle proc macros, see snapshot architecture below), as well as the cap_std::time family of types. And, importantly, wasi-common itself provides no implementation of WasiDir, and only two trivial implementations of WasiFile on the crate::pipe::{ReadPipe, WritePipe} types, which in turn just delegate to std::io::{Read, Write}. In order for wasi-common to access the local filesystem at all, you need to provide WasiFile and WasiDir impls through either the new wasi-cap-std-sync crate found at crates/wasi-common/cap-std-sync - see the section on that crate below - or by providing your own implementation from elsewhere.

This design makes it possible for wasi-common embedders to statically reason about access to the local filesystem by examining what impls are linked into an application. We found that this separation of concerns also makes it pretty enjoyable to write alternative implementations, e.g. a virtual filesystem (which will land in a future PR).

Traits for the rest of WASI's features

Other aspects of a WASI implementation are not yet considered resources and accessed by handle. We plan to correct this design deficiency in WASI in the future, but for now we have designed the following traits to provide embedders with the same sort of implementation flexibility they get with WasiFile/WasiDir:

Users can provide implementations of each of these interfaces to the WasiCtx::builder(...) function. The wasi_cap_std_sync::WasiCtxBuilder::new() function uses this public interface to plug in its own implementations of each of these resources.

Snapshot architecture

One goal we've had for a while, but not quite met, is for multiple WASI snapshots to provide an interface to the same underlying WasiCtx. This provides us a path to evolve WASI by allowing the same WASI Command to import functions from different snapshots - e.g. the user could use Rust's std which imports snapshot 1, but also depend directly on the wasi crate which imports some future snapshot 2. Right now, this amounts to supporting snapshot 1 and "snapshot 0" aka wasi_unstable at once.

The architectural rules for snapshots are:

The cap-std-sync implementation of the WASI traits

Why is this impl suffixed with -sync? https://github.com/bytecodealliance/wasmtime/pull/2434 async is coming soon! The async impl may end up depending on tokio or other relatively heavy deps, so we will retain a sync implementation so that wasi-common users have an option of not pulling in an async runtime.

Improving the WASI test suite

Wasi-common's test suite lives at crates/test-programs.

Changes to wiggle-wasmtime and dependents

Changes to wasmtime-wasi

Regressions

Some behavior around trailing slashes in paths has changed from the test suite. We expect there are some improvements we'll make to these corner cases after this PR lands.

For now, the path_rename_file_trailing_slashes and remove_directory_trailing_slashes tests are #[ignore]'d on all platforms, and additionally the interesting_paths test is ignored on Windows.

Additionally, some behavior around the FdFlags::{SYNC, DSYNC, RSYNC} flags have changed. For now, cap-std does not support opening a file with these flags. Using these flags will result in an Errno::NOTSUP (Not supported).

Outstanding issues required to merge this PR:

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Feb 02 2021 at 01:18):

pchickey edited PR #2487 from pch/wasi_common_cap_std to main:

This PR is a complete rewrite of the wasi-common crate. It uses @sunfishcode 's new cap-std family of crates to provide a sandboxed implementation of WASI on the local filesystem.

Note that this is a breaking change for all users of WASI with Wasmtime, except for the C API.

Re-architecting wasi-common

Over the past year or so, we've run up against many design problems in wasi-common. Many of these problems ended up being so fundamental that a rewrite, as prolonged as it was, ended up being more tractable than incremental changes.

The Table

wasi-common now has a Table type that is designed to map u32 handles to resources. The table is now part of the public interface to a WasiCtx - it is reference counted so that it can be shared beyond a WasiCtx with other WASI proposals (e.g. wasi-crypto and wasi-nn) to manage their resources. Elements in the Table are Any typed.

The Table type is intended to model how the Interface Types concept of Resources is shaping up. Right now it is just an approximation.

The WasiFile and WasiDir traits

The WASI specification only defines one handle type, fd, on which all operations on both files and directories (aka dirfds) are defined. We believe this is a design mistake, and are architecting wasi-common to make this straightforward to correct in future snapshots of WASI. Wasi-common internally treats files and directories as two distinct resource types in the table - Box<dyn WasiFile> and Box<dyn WasiDir>. The snapshot 0 and 1 interfaces via fd will attempt to downcast a table element to one or both of these interfaces depending on what is appropriate - e.g. fd_close operates on both files and directories, fd_read only operates on files, and fd_readdir only operates on directories.

The WasiFile and WasiDir traits are defined by wasi-common in terms of types defined directly in the crate's source code (I decided it should NOT those generated by the wiggle proc macros, see snapshot architecture below), as well as the cap_std::time family of types. And, importantly, wasi-common itself provides no implementation of WasiDir, and only two trivial implementations of WasiFile on the crate::pipe::{ReadPipe, WritePipe} types, which in turn just delegate to std::io::{Read, Write}. In order for wasi-common to access the local filesystem at all, you need to provide WasiFile and WasiDir impls through either the new wasi-cap-std-sync crate found at crates/wasi-common/cap-std-sync - see the section on that crate below - or by providing your own implementation from elsewhere.

This design makes it possible for wasi-common embedders to statically reason about access to the local filesystem by examining what impls are linked into an application. We found that this separation of concerns also makes it pretty enjoyable to write alternative implementations, e.g. a virtual filesystem (which will land in a future PR).

Traits for the rest of WASI's features

Other aspects of a WASI implementation are not yet considered resources and accessed by handle. We plan to correct this design deficiency in WASI in the future, but for now we have designed the following traits to provide embedders with the same sort of implementation flexibility they get with WasiFile/WasiDir:

Users can provide implementations of each of these interfaces to the WasiCtx::builder(...) function. The wasi_cap_std_sync::WasiCtxBuilder::new() function uses this public interface to plug in its own implementations of each of these resources.

Snapshot architecture

One goal we've had for a while, but not quite met, is for multiple WASI snapshots to provide an interface to the same underlying WasiCtx. This provides us a path to evolve WASI by allowing the same WASI Command to import functions from different snapshots - e.g. the user could use Rust's std which imports snapshot 1, but also depend directly on the wasi crate which imports some future snapshot 2. Right now, this amounts to supporting snapshot 1 and "snapshot 0" aka wasi_unstable at once.

The architectural rules for snapshots are:

The wasi-cap-std-sync implementation of the WASI traits

The wasi-cap-std-sync crate provides impl of WasiFile and WasiDir in terms of cap_std::fs::{File, Dir}. These types provide sandboxed access to the local filesystem on both Unix and Windows.

The entire design story of cap-std is much bigger than we can address here, but in short, its functionality replaces all of the wasi_common::sys hierarchy, as well as the yanix / winx crates. All syscalls are hidden behind the cap-std hierarchy, with the lone exception of the sched implementation, which is provided for both unix and windows in separate modules.

Any wasi_common::{WasiCtx, WasiCtxBuilder} is interoperable with the wasi-cap-std-sync crate. However, for convenience, wasi-cap-std-sync provides its own WasiCtxBuilder that hooks up to all of the crate's components, i.e. it fills in all of the arguments to WasiCtx::builder(...), presents preopen_dir in terms of cap_std::fs::Dir, and provides convenience methods for inheriting the parent process's stdio, args, and env.

The only place we expect to run into long-term compatibility issues between wasi-cap-std-sync and the other impl crates that will come later is in the Sched abstraction. Once we can build an async scheduler based on Rust Futures, async impls will be able to interoperate, but the synchronous scheduler depends on downcasting the WasiFile type down to concrete types it knows about (which in turn impl AsRawFd for passing to unix poll, or the analogous traits on windows).

Why is this impl suffixed with -sync? https://github.com/bytecodealliance/wasmtime/pull/2434 async is coming soon! The async impl may end up depending on tokio or other relatively heavy deps, so we will retain a sync implementation so that wasi-common users have an option of not pulling in an async runtime.

Improving the WASI test suite

Wasi-common's test suite lives at crates/test-programs.

Changes to wiggle-wasmtime and dependents

Changes to wasmtime-wasi

Regressions

Some behavior around trailing slashes in paths has changed from the test suite. We expect there are some improvements we'll make to these corner cases after this PR lands.

For now, the path_rename_file_trailing_slashes and remove_directory_trailing_slashes tests are #[ignore]'d on all platforms, and additionally the interesting_paths test is ignored on Windows.

Additionally, some behavior around the FdFlags::{SYNC, DSYNC, RSYNC} flags have changed. For now, cap-std does not support opening a file with these flags. Using these flags will result in an Errno::NOTSUP (Not supported).

Outstanding issues required to merge this PR:

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

Please ensure all communication adheres to the code of conduct.
-->

view this post on Zulip Wasmtime GitHub notifications bot (Feb 02 2021 at 01:29):

pchickey edited PR #2487 from pch/wasi_common_cap_std to main:

This PR is a complete rewrite of the wasi-common crate. It uses @sunfishcode 's new cap-std family of crates to provide a sandboxed implementation of WASI on the local filesystem.

Note that this is a breaking change for all users of WASI with Wasmtime, except for the C API.

Re-architecting wasi-common

Over the past year or so, we've run up against many design problems in wasi-common. Many of these problems ended up being so fundamental that a rewrite, as prolonged as it was, ended up being more tractable than incremental changes.

The Table

wasi-common now has a Table type that is designed to map u32 handles to resources. The table is now part of the public interface to a WasiCtx - it is reference counted so that it can be shared beyond a WasiCtx with other WASI proposals (e.g. wasi-crypto and wasi-nn) to manage their resources. Elements in the Table are Any typed.

The Table type is intended to model how the Interface Types concept of Resources is shaping up. Right now it is just an approximation.

The WasiFile and WasiDir traits

The WASI specification only defines one handle type, fd, on which all operations on both files and directories (aka dirfds) are defined. We believe this is a design mistake, and are architecting wasi-common to make this straightforward to correct in future snapshots of WASI. Wasi-common internally treats files and directories as two distinct resource types in the table - Box<dyn WasiFile> and Box<dyn WasiDir>. The snapshot 0 and 1 interfaces via fd will attempt to downcast a table element to one or both of these interfaces depending on what is appropriate - e.g. fd_close operates on both files and directories, fd_read only operates on files, and fd_readdir only operates on directories.

The WasiFile and WasiDir traits are defined by wasi-common in terms of types defined directly in the crate's source code (I decided it should NOT those generated by the wiggle proc macros, see snapshot architecture below), as well as the cap_std::time family of types. And, importantly, wasi-common itself provides no implementation of WasiDir, and only two trivial implementations of WasiFile on the crate::pipe::{ReadPipe, WritePipe} types, which in turn just delegate to std::io::{Read, Write}. In order for wasi-common to access the local filesystem at all, you need to provide WasiFile and WasiDir impls through either the new wasi-cap-std-sync crate found at crates/wasi-common/cap-std-sync - see the section on that crate below - or by providing your own implementation from elsewhere.

This design makes it possible for wasi-common embedders to statically reason about access to the local filesystem by examining what impls are linked into an application. We found that this separation of concerns also makes it pretty enjoyable to write alternative implementations, e.g. a virtual filesystem (which will land in a future PR).

Traits for the rest of WASI's features

Other aspects of a WASI implementation are not yet considered resources and accessed by handle. We plan to correct this design deficiency in WASI in the future, but for now we have designed the following traits to provide embedders with the same sort of implementation flexibility they get with WasiFile/WasiDir:

Users can provide implementations of each of these interfaces to the WasiCtx::builder(...) function. The wasi_cap_std_sync::WasiCtxBuilder::new() function uses this public interface to plug in its own implementations of each of these resources.

Snapshot architecture

One goal we've had for a while, but not quite met, is for multiple WASI snapshots to provide an interface to the same underlying WasiCtx. This provides us a path to evolve WASI by allowing the same WASI Command to import functions from different snapshots - e.g. the user could use Rust's std which imports snapshot 1, but also depend directly on the wasi crate which imports some future snapshot 2. Right now, this amounts to supporting snapshot 1 and "snapshot 0" aka wasi_unstable at once.

The architectural rules for snapshots are:

The wasi-cap-std-sync implementation of the WASI traits

The wasi-cap-std-sync crate provides impl of WasiFile and WasiDir in terms of cap_std::fs::{File, Dir}. These types provide sandboxed access to the local filesystem on both Unix and Windows.

The entire design story of cap-std is much bigger than we can address here, but in short, its functionality replaces all of the wasi_common::sys hierarchy, as well as the yanix / winx crates. All syscalls are hidden behind the cap-std hierarchy, with the lone exception of the sched implementation, which is provided for both unix and windows in separate modules.

Any wasi_common::{WasiCtx, WasiCtxBuilder} is interoperable with the wasi-cap-std-sync crate. However, for convenience, wasi-cap-std-sync provides its own WasiCtxBuilder that hooks up to all of the crate's components, i.e. it fills in all of the arguments to WasiCtx::builder(...), presents preopen_dir in terms of cap_std::fs::Dir, and provides convenience methods for inheriting the parent process's stdio, args, and env.

The only place we expect to run into long-term compatibility issues between wasi-cap-std-sync and the other impl crates that will come later is in the Sched abstraction. Once we can build an async scheduler based on Rust Futures, async impls will be able to interoperate, but the synchronous scheduler depends on downcasting the WasiFile type down to concrete types it knows about (which in turn impl AsRawFd for passing to unix poll, or the analogous traits on windows).

Why is this impl suffixed with -sync? https://github.com/bytecodealliance/wasmtime/pull/2434 async is coming soon! The async impl may end up depending on tokio or other relatively heavy deps, so we will retain a sync implementation so that wasi-common users have an option of not pulling in an async runtime.

Improving the WASI test suite

The bulk of wasi-common's test suite lives at crates/test-programs. This test suite was extremely useful for guiding this rewrite. We improved the test suite in numerous ways, including

Changes to wiggle-wasmtime and dependents

Changes to wasmtime-wasi

Regressions

Some behavior around trailing slashes in paths has changed from the test suite. We expect there are some improvements we'll make to these corner cases after this PR lands.

For now, the path_rename_file_trailing_slashes and remove_directory_trailing_slashes tests are #[ignore]'d on all platforms, and additionally the interesting_paths test is ignored on Windows.

Additionally, some behavior around the FdFlags::{SYNC, DSYNC, RSYNC} flags have changed. For now, cap-std does not support opening a file with these flags. Using these flags will result in an Errno::NOTSUP (Not supported).

Outstanding issues required to merge this PR:

view this post on Zulip Wasmtime GitHub notifications bot (Feb 02 2021 at 01:39):

pchickey edited PR #2487 from pch/wasi_common_cap_std to main:

This PR is a complete rewrite of the wasi-common crate. It uses @sunfishcode 's new cap-std family of crates to provide a sandboxed implementation of WASI on the local filesystem.

Note that this is a breaking change for all users of WASI with Wasmtime, except for the C API.

Re-architecting wasi-common

Over the past year or so, we've run up against many design problems in wasi-common. Many of these problems ended up being so fundamental that a rewrite, as prolonged as it was, ended up being more tractable than incremental changes.

The Table

wasi-common now has a Table type that is designed to map u32 handles to resources. The table is now part of the public interface to a WasiCtx - it is reference counted so that it can be shared beyond a WasiCtx with other WASI proposals (e.g. wasi-crypto and wasi-nn) to manage their resources. Elements in the Table are Any typed.

The Table type is intended to model how the Interface Types concept of Resources is shaping up. Right now it is just an approximation.

The WasiFile and WasiDir traits

The WASI specification only defines one handle type, fd, on which all operations on both files and directories (aka dirfds) are defined. We believe this is a design mistake, and are architecting wasi-common to make this straightforward to correct in future snapshots of WASI. Wasi-common internally treats files and directories as two distinct resource types in the table - Box<dyn WasiFile> and Box<dyn WasiDir>. The snapshot 0 and 1 interfaces via fd will attempt to downcast a table element to one or both of these interfaces depending on what is appropriate - e.g. fd_close operates on both files and directories, fd_read only operates on files, and fd_readdir only operates on directories.

The WasiFile and WasiDir traits are defined by wasi-common in terms of types defined directly in the crate's source code (I decided it should NOT those generated by the wiggle proc macros, see snapshot architecture below), as well as the cap_std::time family of types. And, importantly, wasi-common itself provides no implementation of WasiDir, and only two trivial implementations of WasiFile on the crate::pipe::{ReadPipe, WritePipe} types, which in turn just delegate to std::io::{Read, Write}. In order for wasi-common to access the local filesystem at all, you need to provide WasiFile and WasiDir impls through either the new wasi-cap-std-sync crate found at crates/wasi-common/cap-std-sync - see the section on that crate below - or by providing your own implementation from elsewhere.

This design makes it possible for wasi-common embedders to statically reason about access to the local filesystem by examining what impls are linked into an application. We found that this separation of concerns also makes it pretty enjoyable to write alternative implementations, e.g. a virtual filesystem (which will land in a future PR).

Traits for the rest of WASI's features

Other aspects of a WASI implementation are not yet considered resources and accessed by handle. We plan to correct this design deficiency in WASI in the future, but for now we have designed the following traits to provide embedders with the same sort of implementation flexibility they get with WasiFile/WasiDir:

Users can provide implementations of each of these interfaces to the WasiCtx::builder(...) function. The wasi_cap_std_sync::WasiCtxBuilder::new() function uses this public interface to plug in its own implementations of each of these resources.

Snapshot architecture

One goal we've had for a while, but not quite met, is for multiple WASI snapshots to provide an interface to the same underlying WasiCtx. This provides us a path to evolve WASI by allowing the same WASI Command to import functions from different snapshots - e.g. the user could use Rust's std which imports snapshot 1, but also depend directly on the wasi crate which imports some future snapshot 2. Right now, this amounts to supporting snapshot 1 and "snapshot 0" aka wasi_unstable at once.

The architectural rules for snapshots are:

The wasi-cap-std-sync implementation of the WASI traits

The wasi-cap-std-sync crate provides impl of WasiFile and WasiDir in terms of cap_std::fs::{File, Dir}. These types provide sandboxed access to the local filesystem on both Unix and Windows.

The entire design story of cap-std is much bigger than we can address here, but in short, its functionality replaces all of the wasi_common::sys hierarchy, as well as the yanix / winx crates. All syscalls are hidden behind the cap-std hierarchy, with the lone exception of the sched implementation, which is provided for both unix and windows in separate modules.

Any wasi_common::{WasiCtx, WasiCtxBuilder} is interoperable with the wasi-cap-std-sync crate. However, for convenience, wasi-cap-std-sync provides its own WasiCtxBuilder that hooks up to all of the crate's components, i.e. it fills in all of the arguments to WasiCtx::builder(...), presents preopen_dir in terms of cap_std::fs::Dir, and provides convenience methods for inheriting the parent process's stdio, args, and env.

The only place we expect to run into long-term compatibility issues between wasi-cap-std-sync and the other impl crates that will come later is in the Sched abstraction. Once we can build an async scheduler based on Rust Futures, async impls will be able to interoperate, but the synchronous scheduler depends on downcasting the WasiFile type down to concrete types it knows about (which in turn impl AsRawFd for passing to unix poll, or the analogous traits on windows).

Why is this impl suffixed with -sync? https://github.com/bytecodealliance/wasmtime/pull/2434 async is coming soon! The async impl may end up depending on tokio or other relatively heavy deps, so we will retain a sync implementation so that wasi-common users have an option of not pulling in an async runtime.

Improving the WASI test suite

The bulk of wasi-common's test suite lives at crates/test-programs. This test suite was extremely useful for guiding this rewrite. We improved the test suite in numerous ways, including

Changes to wiggle-wasmtime and dependents

You used to pass a WasiCtx (or whatever ctx type) directly to the Wasi struct generated by wiggle-wasmtime, and the generated code would wrap the ctx into a Rc<RefCell<ctx>>. This got in the way of supporting multiple snapshots simultaneously, so now callers of the generated code have to pass in an Rc<RefCell<ctx>>.

I made mechanical changes to wasi-nn (cc @abrown) and wasi-crypto (cc @jedisct1) to accommodate these changes. This was of particular help to the wasi-crypto code - I was able to erase an entire Rc<> indirection by getting wiggle out of our way. Sorry that I did not take the time to break this out into a standalone PR.

Changes to wasmtime-wasi

wasmtime-wasi now supports using multiple snapshots to interface to the same WasiCtx!

view this post on Zulip Wasmtime GitHub notifications bot (Feb 02 2021 at 01:44):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

This PR is a complete rewrite of the wasi-common crate. It uses @sunfishcode 's new cap-std family of crates to provide a sandboxed implementation of WASI on the local filesystem.

Note that this is a breaking change for all users of WASI with Wasmtime, except for the C API.

Re-architecting wasi-common

Over the past year or so, we've run up against many design problems in wasi-common. Many of these problems ended up being so fundamental that a rewrite, as prolonged as it was, ended up being more tractable than incremental changes.

The Table

wasi-common now has a Table type that is designed to map u32 handles to resources. The table is now part of the public interface to a WasiCtx - it is reference counted so that it can be shared beyond a WasiCtx with other WASI proposals (e.g. wasi-crypto and wasi-nn) to manage their resources. Elements in the Table are Any typed.

The Table type is intended to model how the Interface Types concept of Resources is shaping up. Right now it is just an approximation.

The WasiFile and WasiDir traits

The WASI specification only defines one handle type, fd, on which all operations on both files and directories (aka dirfds) are defined. We believe this is a design mistake, and are architecting wasi-common to make this straightforward to correct in future snapshots of WASI. Wasi-common internally treats files and directories as two distinct resource types in the table - Box<dyn WasiFile> and Box<dyn WasiDir>. The snapshot 0 and 1 interfaces via fd will attempt to downcast a table element to one or both of these interfaces depending on what is appropriate - e.g. fd_close operates on both files and directories, fd_read only operates on files, and fd_readdir only operates on directories.

The WasiFile and WasiDir traits are defined by wasi-common in terms of types defined directly in the crate's source code (I decided it should NOT those generated by the wiggle proc macros, see snapshot architecture below), as well as the cap_std::time family of types. And, importantly, wasi-common itself provides no implementation of WasiDir, and only two trivial implementations of WasiFile on the crate::pipe::{ReadPipe, WritePipe} types, which in turn just delegate to std::io::{Read, Write}. In order for wasi-common to access the local filesystem at all, you need to provide WasiFile and WasiDir impls through either the new wasi-cap-std-sync crate found at crates/wasi-common/cap-std-sync - see the section on that crate below - or by providing your own implementation from elsewhere.

This design makes it possible for wasi-common embedders to statically reason about access to the local filesystem by examining what impls are linked into an application. We found that this separation of concerns also makes it pretty enjoyable to write alternative implementations, e.g. a virtual filesystem (which will land in a future PR).

Traits for the rest of WASI's features

Other aspects of a WASI implementation are not yet considered resources and accessed by handle. We plan to correct this design deficiency in WASI in the future, but for now we have designed the following traits to provide embedders with the same sort of implementation flexibility they get with WasiFile/WasiDir:

Users can provide implementations of each of these interfaces to the WasiCtx::builder(...) function. The wasi_cap_std_sync::WasiCtxBuilder::new() function uses this public interface to plug in its own implementations of each of these resources.

Snapshot architecture

One goal we've had for a while, but not quite met, is for multiple WASI snapshots to provide an interface to the same underlying WasiCtx. This provides us a path to evolve WASI by allowing the same WASI Command to import functions from different snapshots - e.g. the user could use Rust's std which imports snapshot 1, but also depend directly on the wasi crate which imports some future snapshot 2. Right now, this amounts to supporting snapshot 1 and "snapshot 0" aka wasi_unstable at once.

The architectural rules for snapshots are:

The wasi-cap-std-sync implementation of the WASI traits

The wasi-cap-std-sync crate provides impl of WasiFile and WasiDir in terms of cap_std::fs::{File, Dir}. These types provide sandboxed access to the local filesystem on both Unix and Windows.

The entire design story of cap-std is much bigger than we can address here, but in short, its functionality replaces all of the wasi_common::sys hierarchy, as well as the yanix / winx crates. All syscalls are hidden behind the cap-std hierarchy, with the lone exception of the sched implementation, which is provided for both unix and windows in separate modules.

Any wasi_common::{WasiCtx, WasiCtxBuilder} is interoperable with the wasi-cap-std-sync crate. However, for convenience, wasi-cap-std-sync provides its own WasiCtxBuilder that hooks up to all of the crate's components, i.e. it fills in all of the arguments to WasiCtx::builder(...), presents preopen_dir in terms of cap_std::fs::Dir, and provides convenience methods for inheriting the parent process's stdio, args, and env.

The only place we expect to run into long-term compatibility issues between wasi-cap-std-sync and the other impl crates that will come later is in the Sched abstraction. Once we can build an async scheduler based on Rust Futures, async impls will be able to interoperate, but the synchronous scheduler depends on downcasting the WasiFile type down to concrete types it knows about (which in turn impl AsRawFd for passing to unix poll, or the analogous traits on windows).

Why is this impl suffixed with -sync? https://github.com/bytecodealliance/wasmtime/pull/2434 async is coming soon! The async impl may end up depending on tokio or other relatively heavy deps, so we will retain a sync implementation so that wasi-common users have an option of not pulling in an async runtime.

Improving the WASI test suite

The bulk of wasi-common's test suite lives at crates/test-programs. This test suite was extremely useful for guiding this rewrite. We improved the test suite in numerous ways, including

Changes to wiggle-wasmtime and dependents

You used to pass a WasiCtx (or whatever ctx type) directly to the Wasi struct generated by wiggle-wasmtime, and the generated code would wrap the ctx into a Rc<RefCell<ctx>>. This got in the way of supporting multiple snapshots simultaneously, so now callers of the generated code have to pass in an Rc<RefCell<ctx>>.

I made mechanical changes to wasi-nn (cc @abrown) and wasi-crypto (cc @jedisct1) to accommodate these changes. This was of particular help to the wasi-crypto code - I was able to erase an entire Rc<> indirection by getting wiggle out of our way. Sorry that I did not take the time to break this out into a standalone PR.

Changes to wasmtime-wasi

wasmtime-wasi now supports using multiple snapshots to interface to the same WasiCtx!

view this post on Zulip Wasmtime GitHub notifications bot (Feb 02 2021 at 01:46):

pchickey edited PR #2487 from pch/wasi_common_cap_std to main:

This PR is a complete rewrite of the wasi-common crate. It uses @sunfishcode 's new cap-std family of crates to provide a sandboxed implementation of WASI on the local filesystem.

Note that this is a breaking change for all users of WASI with Wasmtime, except for the C API.

Re-architecting wasi-common

Over the past year or so, we've run up against many design problems in wasi-common. Many of these problems ended up being so fundamental that a rewrite, as prolonged as it was, ended up being more tractable than incremental changes.

The Table

wasi-common now has a Table type that is designed to map u32 handles to resources. The table is now part of the public interface to a WasiCtx - it is reference counted so that it can be shared beyond a WasiCtx with other WASI proposals (e.g. wasi-crypto and wasi-nn) to manage their resources. Elements in the Table are Any typed.

The Table type is intended to model how the Interface Types concept of Resources is shaping up. Right now it is just an approximation.

The WasiFile and WasiDir traits

The WASI specification only defines one handle type, fd, on which all operations on both files and directories (aka dirfds) are defined. We believe this is a design mistake, and are architecting wasi-common to make this straightforward to correct in future snapshots of WASI. Wasi-common internally treats files and directories as two distinct resource types in the table - Box<dyn WasiFile> and Box<dyn WasiDir>. The snapshot 0 and 1 interfaces via fd will attempt to downcast a table element to one or both of these interfaces depending on what is appropriate - e.g. fd_close operates on both files and directories, fd_read only operates on files, and fd_readdir only operates on directories.

The WasiFile and WasiDir traits are defined by wasi-common in terms of types defined directly in the crate's source code (I decided it should NOT those generated by the wiggle proc macros, see snapshot architecture below), as well as the cap_std::time family of types. And, importantly, wasi-common itself provides no implementation of WasiDir, and only two trivial implementations of WasiFile on the crate::pipe::{ReadPipe, WritePipe} types, which in turn just delegate to std::io::{Read, Write}. In order for wasi-common to access the local filesystem at all, you need to provide WasiFile and WasiDir impls through either the new wasi-cap-std-sync crate found at crates/wasi-common/cap-std-sync - see the section on that crate below - or by providing your own implementation from elsewhere.

This design makes it possible for wasi-common embedders to statically reason about access to the local filesystem by examining what impls are linked into an application. We found that this separation of concerns also makes it pretty enjoyable to write alternative implementations, e.g. a virtual filesystem (which will land in a future PR).

Traits for the rest of WASI's features

Other aspects of a WASI implementation are not yet considered resources and accessed by handle. We plan to correct this design deficiency in WASI in the future, but for now we have designed the following traits to provide embedders with the same sort of implementation flexibility they get with WasiFile/WasiDir:

Users can provide implementations of each of these interfaces to the WasiCtx::builder(...) function. The wasi_cap_std_sync::WasiCtxBuilder::new() function uses this public interface to plug in its own implementations of each of these resources.

Snapshot architecture

One goal we've had for a while, but not quite met, is for multiple WASI snapshots to provide an interface to the same underlying WasiCtx. This provides us a path to evolve WASI by allowing the same WASI Command to import functions from different snapshots - e.g. the user could use Rust's std which imports snapshot 1, but also depend directly on the wasi crate which imports some future snapshot 2. Right now, this amounts to supporting snapshot 1 and "snapshot 0" aka wasi_unstable at once.

The architectural rules for snapshots are:

The wasi_common::Error type

wasi_common::Error is now anyhow::Error. wasi_common::snapshots::preview_1 contains all of the logic for transforming an Error into an Errno, by downcasting the error into any of

If you throw an error that does not downcast to one of those, it will turn into a wiggle::Trap and terminate execution.

The wasi-cap-std-sync implementation of the WASI traits

The wasi-cap-std-sync crate provides impl of WasiFile and WasiDir in terms of cap_std::fs::{File, Dir}. These types provide sandboxed access to the local filesystem on both Unix and Windows.

The entire design story of cap-std is much bigger than we can address here, but in short, its functionality replaces all of the wasi_common::sys hierarchy, as well as the yanix / winx crates. All syscalls are hidden behind the cap-std hierarchy, with the lone exception of the sched implementation, which is provided for both unix and windows in separate modules.

Any wasi_common::{WasiCtx, WasiCtxBuilder} is interoperable with the wasi-cap-std-sync crate. However, for convenience, wasi-cap-std-sync provides its own WasiCtxBuilder that hooks up to all of the crate's components, i.e. it fills in all of the arguments to WasiCtx::builder(...), presents preopen_dir in terms of cap_std::fs::Dir, and provides convenience methods for inheriting the parent process's stdio, args, and env.

The only place we expect to run into long-term compatibility issues between wasi-cap-std-sync and the other impl crates that will come later is in the Sched abstraction. Once we can build an async scheduler based on Rust Futures, async impls will be able to interoperate, but the synchronous scheduler depends on downcasting the WasiFile type down to concrete types it knows about (which in turn impl AsRawFd for passing to unix poll, or the analogous traits on windows).

Why is this impl suffixed with -sync? https://github.com/bytecodealliance/wasmtime/pull/2434 async is coming soon! The async impl may end up depending on tokio or other relatively heavy deps, so we will retain a sync implementation so that wasi-common users have an option of not pulling in an async runtime.

Improving the WASI test suite

The bulk of wasi-common's test suite lives at crates/test-programs. This test suite was extremely useful for guiding this rewrite. We improved the test suite in numerous ways, including

Changes to wiggle-wasmtime and dependents

You used to pass a WasiCtx (or whatever ctx type) directly to the Wasi struct generated by wiggle-wasmtime, and the generated code would wrap the ctx into a Rc<RefCell<ctx>>. This got in the way of supporting multiple snapshots simul
[message truncated]

view this post on Zulip Wasmtime GitHub notifications bot (Feb 02 2021 at 01:48):

pchickey edited PR #2487 from pch/wasi_common_cap_std to main:

This PR is a complete rewrite of the wasi-common crate. It uses @sunfishcode 's new cap-std family of crates to provide a sandboxed implementation of WASI on the local filesystem.

Note that this is a breaking change for all users of WASI with Wasmtime, except for the C API.

Re-architecting wasi-common

Over the past year or so, we've run up against many design problems in wasi-common. Many of these problems ended up being so fundamental that a rewrite, as prolonged as it was, ended up being more tractable than incremental changes.

The Table

wasi-common now has a Table type that is designed to map u32 handles to resources. The table is now part of the public interface to a WasiCtx - it is reference counted so that it can be shared beyond a WasiCtx with other WASI proposals (e.g. wasi-crypto and wasi-nn) to manage their resources. Elements in the Table are Any typed.

The Table type is intended to model how the Interface Types concept of Resources is shaping up. Right now it is just an approximation.

The WasiFile and WasiDir traits

The WASI specification only defines one handle type, fd, on which all operations on both files and directories (aka dirfds) are defined. We believe this is a design mistake, and are architecting wasi-common to make this straightforward to correct in future snapshots of WASI. Wasi-common internally treats files and directories as two distinct resource types in the table - Box<dyn WasiFile> and Box<dyn WasiDir>. The snapshot 0 and 1 interfaces via fd will attempt to downcast a table element to one or both of these interfaces depending on what is appropriate - e.g. fd_close operates on both files and directories, fd_read only operates on files, and fd_readdir only operates on directories.

The WasiFile and WasiDir traits are defined by wasi-common in terms of types defined directly in the crate's source code (I decided it should NOT those generated by the wiggle proc macros, see snapshot architecture below), as well as the cap_std::time family of types. And, importantly, wasi-common itself provides no implementation of WasiDir, and only two trivial implementations of WasiFile on the crate::pipe::{ReadPipe, WritePipe} types, which in turn just delegate to std::io::{Read, Write}. In order for wasi-common to access the local filesystem at all, you need to provide WasiFile and WasiDir impls through either the new wasi-cap-std-sync crate found at crates/wasi-common/cap-std-sync - see the section on that crate below - or by providing your own implementation from elsewhere.

This design makes it possible for wasi-common embedders to statically reason about access to the local filesystem by examining what impls are linked into an application. We found that this separation of concerns also makes it pretty enjoyable to write alternative implementations, e.g. a virtual filesystem (which will land in a future PR).

Traits for the rest of WASI's features

Other aspects of a WASI implementation are not yet considered resources and accessed by handle. We plan to correct this design deficiency in WASI in the future, but for now we have designed the following traits to provide embedders with the same sort of implementation flexibility they get with WasiFile/WasiDir:

Users can provide implementations of each of these interfaces to the WasiCtx::builder(...) function. The wasi_cap_std_sync::WasiCtxBuilder::new() function uses this public interface to plug in its own implementations of each of these resources.

Snapshot architecture

One goal we've had for a while, but not quite met, is for multiple WASI snapshots to provide an interface to the same underlying WasiCtx. This provides us a path to evolve WASI by allowing the same WASI Command to import functions from different snapshots - e.g. the user could use Rust's std which imports snapshot 1, but also depend directly on the wasi crate which imports some future snapshot 2. Right now, this amounts to supporting snapshot 1 and "snapshot 0" aka wasi_unstable at once.

The architectural rules for snapshots are:

The wasi_common::Error type

wasi_common::Error is now anyhow::Error. wasi_common::snapshots::preview_1 contains all of the logic for transforming an Error into an Errno, by downcasting the error into any of

The wasi_common::ErrorExt trait provides human-friendly constructors for the wasi_common::ErrorKind variants

If you throw an error that does not downcast to one of those, it will turn into a wiggle::Trap and terminate execution.

The wasi-cap-std-sync implementation of the WASI traits

The wasi-cap-std-sync crate provides impl of WasiFile and WasiDir in terms of cap_std::fs::{File, Dir}. These types provide sandboxed access to the local filesystem on both Unix and Windows.

The entire design story of cap-std is much bigger than we can address here, but in short, its functionality replaces all of the wasi_common::sys hierarchy, as well as the yanix / winx crates. All syscalls are hidden behind the cap-std hierarchy, with the lone exception of the sched implementation, which is provided for both unix and windows in separate modules.

Any wasi_common::{WasiCtx, WasiCtxBuilder} is interoperable with the wasi-cap-std-sync crate. However, for convenience, wasi-cap-std-sync provides its own WasiCtxBuilder that hooks up to all of the crate's components, i.e. it fills in all of the arguments to WasiCtx::builder(...), presents preopen_dir in terms of cap_std::fs::Dir, and provides convenience methods for inheriting the parent process's stdio, args, and env.

The only place we expect to run into long-term compatibility issues between wasi-cap-std-sync and the other impl crates that will come later is in the Sched abstraction. Once we can build an async scheduler based on Rust Futures, async impls will be able to interoperate, but the synchronous scheduler depends on downcasting the WasiFile type down to concrete types it knows about (which in turn impl AsRawFd for passing to unix poll, or the analogous traits on windows).

Why is this impl suffixed with -sync? https://github.com/bytecodealliance/wasmtime/pull/2434 async is coming soon! The async impl may end up depending on tokio or other relatively heavy deps, so we will retain a sync implementation so that wasi-common users have an option of not pulling in an async runtime.

Improving the WASI test suite

The bulk of wasi-common's test suite lives at crates/test-programs. This test suite was extremely useful for guiding this rewrite. We improved the test suite in numerous ways, including

view this post on Zulip Wasmtime GitHub notifications bot (Feb 02 2021 at 01:49):

pchickey edited PR #2487 from pch/wasi_common_cap_std to main:

This PR is a complete rewrite of the wasi-common crate. It uses @sunfishcode 's new cap-std family of crates to provide a sandboxed implementation of WASI on the local filesystem.

Note that this is a breaking change for all users of WASI with Wasmtime, except for the C API.

Re-architecting wasi-common

Over the past year or so, we've run up against many design problems in wasi-common. Many of these problems ended up being so fundamental that a rewrite, as prolonged as it was, ended up being more tractable than incremental changes.

The Table

wasi-common now has a Table type that is designed to map u32 handles to resources. The table is now part of the public interface to a WasiCtx - it is reference counted so that it can be shared beyond a WasiCtx with other WASI proposals (e.g. wasi-crypto and wasi-nn) to manage their resources. Elements in the Table are Any typed.

The Table type is intended to model how the Interface Types concept of Resources is shaping up. Right now it is just an approximation.

The WasiFile and WasiDir traits

The WASI specification only defines one handle type, fd, on which all operations on both files and directories (aka dirfds) are defined. We believe this is a design mistake, and are architecting wasi-common to make this straightforward to correct in future snapshots of WASI. Wasi-common internally treats files and directories as two distinct resource types in the table - Box<dyn WasiFile> and Box<dyn WasiDir>. The snapshot 0 and 1 interfaces via fd will attempt to downcast a table element to one or both of these interfaces depending on what is appropriate - e.g. fd_close operates on both files and directories, fd_read only operates on files, and fd_readdir only operates on directories.

The WasiFile and WasiDir traits are defined by wasi-common in terms of types defined directly in the crate's source code (I decided it should NOT those generated by the wiggle proc macros, see snapshot architecture below), as well as the cap_std::time family of types. And, importantly, wasi-common itself provides no implementation of WasiDir, and only two trivial implementations of WasiFile on the crate::pipe::{ReadPipe, WritePipe} types, which in turn just delegate to std::io::{Read, Write}. In order for wasi-common to access the local filesystem at all, you need to provide WasiFile and WasiDir impls through either the new wasi-cap-std-sync crate found at crates/wasi-common/cap-std-sync - see the section on that crate below - or by providing your own implementation from elsewhere.

This design makes it possible for wasi-common embedders to statically reason about access to the local filesystem by examining what impls are linked into an application. We found that this separation of concerns also makes it pretty enjoyable to write alternative implementations, e.g. a virtual filesystem (which will land in a future PR).

Traits for the rest of WASI's features

Other aspects of a WASI implementation are not yet considered resources and accessed by handle. We plan to correct this design deficiency in WASI in the future, but for now we have designed the following traits to provide embedders with the same sort of implementation flexibility they get with WasiFile/WasiDir:

Users can provide implementations of each of these interfaces to the WasiCtx::builder(...) function. The wasi_cap_std_sync::WasiCtxBuilder::new() function uses this public interface to plug in its own implementations of each of these resources.

Snapshot architecture

One goal we've had for a while, but not quite met, is for multiple WASI snapshots to provide an interface to the same underlying WasiCtx. This provides us a path to evolve WASI by allowing the same WASI Command to import functions from different snapshots - e.g. the user could use Rust's std which imports snapshot 1, but also depend directly on the wasi crate which imports some future snapshot 2. Right now, this amounts to supporting snapshot 1 and "snapshot 0" aka wasi_unstable at once.

The architectural rules for snapshots are:

The wasi_common::Error type

wasi_common::Error is now anyhow::Error. wasi_common::snapshots::preview_1 contains all of the logic for transforming an Error into an Errno, by downcasting the error into any of

The wasi_common::ErrorExt trait provides human-friendly constructors for the wasi_common::ErrorKind variants .

If you throw an error that does not downcast to one of those, it will turn into a wiggle::Trap and terminate execution.

The real value of using anyhow::Error here is being able to use anyhow::Result::context to aid in debugging of errors.

The wasi-cap-std-sync implementation of the WASI traits

The wasi-cap-std-sync crate provides impl of WasiFile and WasiDir in terms of cap_std::fs::{File, Dir}. These types provide sandboxed access to the local filesystem on both Unix and Windows.

The entire design story of cap-std is much bigger than we can address here, but in short, its functionality replaces all of the wasi_common::sys hierarchy, as well as the yanix / winx crates. All syscalls are hidden behind the cap-std hierarchy, with the lone exception of the sched implementation, which is provided for both unix and windows in separate modules.

Any wasi_common::{WasiCtx, WasiCtxBuilder} is interoperable with the wasi-cap-std-sync crate. However, for convenience, wasi-cap-std-sync provides its own WasiCtxBuilder that hooks up to all of the crate's components, i.e. it fills in all of the arguments to WasiCtx::builder(...), presents preopen_dir in terms of cap_std::fs::Dir, and provides convenience methods for inheriting the parent process's stdio, args, and env.

The only place we expect to run into long-term compatibility issues between wasi-cap-std-sync and the other impl crates that will come later is in the Sched abstraction. Once we can build an async scheduler based on Rust Futures, async impls will be able to interoperate, but the synchronous scheduler depends on downcasting the WasiFile type down to concrete types it knows about (which in turn impl AsRawFd for passing to unix poll, or the analogous traits on windows).

Why is this impl suffixed with -sync? https://github.com/bytecodealliance/wasmtime/pull/2434 async is coming soon! The async impl may end up depending on tokio or other relatively heavy deps, so we will retain a sync implementation so that wasi-common users have an option of not pulling in an async runtime.

Improving the WASI test suite

The bulk of wasi-common's test suite lives at crates/test-programs. This test suite was extremely useful for guiding this rewrite. We improved the test suite in numerous ways, including

view this post on Zulip Wasmtime GitHub notifications bot (Feb 02 2021 at 02:22):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

This PR is a complete rewrite of the wasi-common crate. It uses @sunfishcode 's new cap-std family of crates to provide a sandboxed implementation of WASI on the local filesystem.

Note that this is a breaking change for all users of WASI with Wasmtime, except for the C API.

Re-architecting wasi-common

Over the past year or so, we've run up against many design problems in wasi-common. Many of these problems ended up being so fundamental that a rewrite, as prolonged as it was, ended up being more tractable than incremental changes.

The Table

wasi-common now has a Table type that is designed to map u32 handles to resources. The table is now part of the public interface to a WasiCtx - it is reference counted so that it can be shared beyond a WasiCtx with other WASI proposals (e.g. wasi-crypto and wasi-nn) to manage their resources. Elements in the Table are Any typed.

The Table type is intended to model how the Interface Types concept of Resources is shaping up. Right now it is just an approximation.

The WasiFile and WasiDir traits

The WASI specification only defines one handle type, fd, on which all operations on both files and directories (aka dirfds) are defined. We believe this is a design mistake, and are architecting wasi-common to make this straightforward to correct in future snapshots of WASI. Wasi-common internally treats files and directories as two distinct resource types in the table - Box<dyn WasiFile> and Box<dyn WasiDir>. The snapshot 0 and 1 interfaces via fd will attempt to downcast a table element to one or both of these interfaces depending on what is appropriate - e.g. fd_close operates on both files and directories, fd_read only operates on files, and fd_readdir only operates on directories.

The WasiFile and WasiDir traits are defined by wasi-common in terms of types defined directly in the crate's source code (I decided it should NOT those generated by the wiggle proc macros, see snapshot architecture below), as well as the cap_std::time family of types. And, importantly, wasi-common itself provides no implementation of WasiDir, and only two trivial implementations of WasiFile on the crate::pipe::{ReadPipe, WritePipe} types, which in turn just delegate to std::io::{Read, Write}. In order for wasi-common to access the local filesystem at all, you need to provide WasiFile and WasiDir impls through either the new wasi-cap-std-sync crate found at crates/wasi-common/cap-std-sync - see the section on that crate below - or by providing your own implementation from elsewhere.

This design makes it possible for wasi-common embedders to statically reason about access to the local filesystem by examining what impls are linked into an application. We found that this separation of concerns also makes it pretty enjoyable to write alternative implementations, e.g. a virtual filesystem (which will land in a future PR).

Traits for the rest of WASI's features

Other aspects of a WASI implementation are not yet considered resources and accessed by handle. We plan to correct this design deficiency in WASI in the future, but for now we have designed the following traits to provide embedders with the same sort of implementation flexibility they get with WasiFile/WasiDir:

Users can provide implementations of each of these interfaces to the WasiCtx::builder(...) function. The wasi_cap_std_sync::WasiCtxBuilder::new() function uses this public interface to plug in its own implementations of each of these resources.

Snapshot architecture

One goal we've had for a while, but not quite met, is for multiple WASI snapshots to provide an interface to the same underlying WasiCtx. This provides us a path to evolve WASI by allowing the same WASI Command to import functions from different snapshots - e.g. the user could use Rust's std which imports snapshot 1, but also depend directly on the wasi crate which imports some future snapshot 2. Right now, this amounts to supporting snapshot 1 and "snapshot 0" aka wasi_unstable at once.

The architectural rules for snapshots are:

The wasi_common::Error type

wasi_common::Error is now anyhow::Error. wasi_common::snapshots::preview_1 contains all of the logic for transforming an Error into an Errno, by downcasting the error into any of

The wasi_common::ErrorExt trait provides human-friendly constructors for the wasi_common::ErrorKind variants .

If you throw an error that does not downcast to one of those, it will turn into a wiggle::Trap and terminate execution.

The real value of using anyhow::Error here is being able to use anyhow::Result::context to aid in debugging of errors.

The wasi-cap-std-sync implementation of the WASI traits

The wasi-cap-std-sync crate provides impl of WasiFile and WasiDir in terms of cap_std::fs::{File, Dir}. These types provide sandboxed access to the local filesystem on both Unix and Windows.

The entire design story of cap-std is much bigger than we can address here, but in short, its functionality replaces all of the wasi_common::sys hierarchy, as well as the yanix / winx crates. All syscalls are hidden behind the cap-std hierarchy, with the lone exception of the sched implementation, which is provided for both unix and windows in separate modules.

Any wasi_common::{WasiCtx, WasiCtxBuilder} is interoperable with the wasi-cap-std-sync crate. However, for convenience, wasi-cap-std-sync provides its own WasiCtxBuilder that hooks up to all of the crate's components, i.e. it fills in all of the arguments to WasiCtx::builder(...), presents preopen_dir in terms of cap_std::fs::Dir, and provides convenience methods for inheriting the parent process's stdio, args, and env.

The only place we expect to run into long-term compatibility issues between wasi-cap-std-sync and the other impl crates that will come later is in the Sched abstraction. Once we can build an async scheduler based on Rust Futures, async impls will be able to interoperate, but the synchronous scheduler depends on downcasting the WasiFile type down to concrete types it knows about (which in turn impl AsRawFd for passing to unix poll, or the analogous traits on windows).

Why is this impl suffixed with -sync? https://github.com/bytecodealliance/wasmtime/pull/2434 async is coming soon! The async impl may end up depending on tokio or other relatively heavy deps, so we will retain a sync implementation so that wasi-common users have an option of not pulling in an async runtime.

Improving the WASI test suite

The bulk of wasi-common's test suite lives at crates/test-programs. This test suite was extremely useful for guiding this rewrite. We improved the test suite in numerous ways, including

view this post on Zulip Wasmtime GitHub notifications bot (Feb 02 2021 at 02:31):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

This PR is a complete rewrite of the wasi-common crate. It uses @sunfishcode 's new cap-std family of crates to provide a sandboxed implementation of WASI on the local filesystem.

Note that this is a breaking change for all users of WASI with Wasmtime, except for the C API.

Re-architecting wasi-common

Over the past year or so, we've run up against many design problems in wasi-common. Many of these problems ended up being so fundamental that a rewrite, as prolonged as it was, ended up being more tractable than incremental changes.

The Table

wasi-common now has a Table type that is designed to map u32 handles to resources. The table is now part of the public interface to a WasiCtx - it is reference counted so that it can be shared beyond a WasiCtx with other WASI proposals (e.g. wasi-crypto and wasi-nn) to manage their resources. Elements in the Table are Any typed.

The Table type is intended to model how the Interface Types concept of Resources is shaping up. Right now it is just an approximation.

The WasiFile and WasiDir traits

The WASI specification only defines one handle type, fd, on which all operations on both files and directories (aka dirfds) are defined. We believe this is a design mistake, and are architecting wasi-common to make this straightforward to correct in future snapshots of WASI. Wasi-common internally treats files and directories as two distinct resource types in the table - Box<dyn WasiFile> and Box<dyn WasiDir>. The snapshot 0 and 1 interfaces via fd will attempt to downcast a table element to one or both of these interfaces depending on what is appropriate - e.g. fd_close operates on both files and directories, fd_read only operates on files, and fd_readdir only operates on directories.

The WasiFile and WasiDir traits are defined by wasi-common in terms of types defined directly in the crate's source code (I decided it should NOT those generated by the wiggle proc macros, see snapshot architecture below), as well as the cap_std::time family of types. And, importantly, wasi-common itself provides no implementation of WasiDir, and only two trivial implementations of WasiFile on the crate::pipe::{ReadPipe, WritePipe} types, which in turn just delegate to std::io::{Read, Write}. In order for wasi-common to access the local filesystem at all, you need to provide WasiFile and WasiDir impls through either the new wasi-cap-std-sync crate found at crates/wasi-common/cap-std-sync - see the section on that crate below - or by providing your own implementation from elsewhere.

This design makes it possible for wasi-common embedders to statically reason about access to the local filesystem by examining what impls are linked into an application. We found that this separation of concerns also makes it pretty enjoyable to write alternative implementations, e.g. a virtual filesystem (which will land in a future PR).

Traits for the rest of WASI's features

Other aspects of a WASI implementation are not yet considered resources and accessed by handle. We plan to correct this design deficiency in WASI in the future, but for now we have designed the following traits to provide embedders with the same sort of implementation flexibility they get with WasiFile/WasiDir:

Users can provide implementations of each of these interfaces to the WasiCtx::builder(...) function. The wasi_cap_std_sync::WasiCtxBuilder::new() function uses this public interface to plug in its own implementations of each of these resources.

Snapshot architecture

One goal we've had for a while, but not quite met, is for multiple WASI snapshots to provide an interface to the same underlying WasiCtx. This provides us a path to evolve WASI by allowing the same WASI Command to import functions from different snapshots - e.g. the user could use Rust's std which imports snapshot 1, but also depend directly on the wasi crate which imports some future snapshot 2. Right now, this amounts to supporting snapshot 1 and "snapshot 0" aka wasi_unstable at once.

The architectural rules for snapshots are:

The wasi_common::Error type

wasi_common::Error is now anyhow::Error. wasi_common::snapshots::preview_1 contains all of the logic for transforming an Error into an Errno, by downcasting the error into any of

The wasi_common::ErrorExt trait provides human-friendly constructors for the wasi_common::ErrorKind variants .

If you throw an error that does not downcast to one of those, it will turn into a wiggle::Trap and terminate execution.

The real value of using anyhow::Error here is being able to use anyhow::Result::context to aid in debugging of errors.

The wasi-cap-std-sync implementation of the WASI traits

The wasi-cap-std-sync crate provides impl of WasiFile and WasiDir in terms of cap_std::fs::{File, Dir}. These types provide sandboxed access to the local filesystem on both Unix and Windows.

The entire design story of cap-std is much bigger than we can address here, but in short, its functionality replaces all of the wasi_common::sys hierarchy, as well as the yanix / winx crates. All syscalls are hidden behind the cap-std hierarchy, with the lone exception of the sched implementation, which is provided for both unix and windows in separate modules.

Any wasi_common::{WasiCtx, WasiCtxBuilder} is interoperable with the wasi-cap-std-sync crate. However, for convenience, wasi-cap-std-sync provides its own WasiCtxBuilder that hooks up to all of the crate's components, i.e. it fills in all of the arguments to WasiCtx::builder(...), presents preopen_dir in terms of cap_std::fs::Dir, and provides convenience methods for inheriting the parent process's stdio, args, and env.

The only place we expect to run into long-term compatibility issues between wasi-cap-std-sync and the other impl crates that will come later is in the Sched abstraction. Once we can build an async scheduler based on Rust Futures, async impls will be able to interoperate, but the synchronous scheduler depends on downcasting the WasiFile type down to concrete types it knows about (which in turn impl AsRawFd for passing to unix poll, or the analogous traits on windows).

Why is this impl suffixed with -sync? https://github.com/bytecodealliance/wasmtime/pull/2434 async is coming soon! The async impl may end up depending on tokio or other relatively heavy deps, so we will retain a sync implementation so that wasi-common users have an option of not pulling in an async runtime.

Improving the WASI test suite

The bulk of wasi-common's test suite lives at crates/test-programs. This test suite was extremely useful for guiding this rewrite. We improved the test suite in numerous ways, including

view this post on Zulip Wasmtime GitHub notifications bot (Feb 02 2021 at 02:38):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

This PR is a complete rewrite of the wasi-common crate. It uses @sunfishcode 's new cap-std family of crates to provide a sandboxed implementation of WASI on the local filesystem.

Note that this is a breaking change for all users of WASI with Wasmtime, except for the C API.

Re-architecting wasi-common

Over the past year or so, we've run up against many design problems in wasi-common. Many of these problems ended up being so fundamental that a rewrite, as prolonged as it was, ended up being more tractable than incremental changes.

The Table

wasi-common now has a Table type that is designed to map u32 handles to resources. The table is now part of the public interface to a WasiCtx - it is reference counted so that it can be shared beyond a WasiCtx with other WASI proposals (e.g. wasi-crypto and wasi-nn) to manage their resources. Elements in the Table are Any typed.

The Table type is intended to model how the Interface Types concept of Resources is shaping up. Right now it is just an approximation.

The WasiFile and WasiDir traits

The WASI specification only defines one handle type, fd, on which all operations on both files and directories (aka dirfds) are defined. We believe this is a design mistake, and are architecting wasi-common to make this straightforward to correct in future snapshots of WASI. Wasi-common internally treats files and directories as two distinct resource types in the table - Box<dyn WasiFile> and Box<dyn WasiDir>. The snapshot 0 and 1 interfaces via fd will attempt to downcast a table element to one or both of these interfaces depending on what is appropriate - e.g. fd_close operates on both files and directories, fd_read only operates on files, and fd_readdir only operates on directories.

The WasiFile and WasiDir traits are defined by wasi-common in terms of types defined directly in the crate's source code (I decided it should NOT those generated by the wiggle proc macros, see snapshot architecture below), as well as the cap_std::time family of types. And, importantly, wasi-common itself provides no implementation of WasiDir, and only two trivial implementations of WasiFile on the crate::pipe::{ReadPipe, WritePipe} types, which in turn just delegate to std::io::{Read, Write}. In order for wasi-common to access the local filesystem at all, you need to provide WasiFile and WasiDir impls through either the new wasi-cap-std-sync crate found at crates/wasi-common/cap-std-sync - see the section on that crate below - or by providing your own implementation from elsewhere.

This design makes it possible for wasi-common embedders to statically reason about access to the local filesystem by examining what impls are linked into an application. We found that this separation of concerns also makes it pretty enjoyable to write alternative implementations, e.g. a virtual filesystem (which will land in a future PR).

Traits for the rest of WASI's features

Other aspects of a WASI implementation are not yet considered resources and accessed by handle. We plan to correct this design deficiency in WASI in the future, but for now we have designed the following traits to provide embedders with the same sort of implementation flexibility they get with WasiFile/WasiDir:

Users can provide implementations of each of these interfaces to the WasiCtx::builder(...) function. The wasi_cap_std_sync::WasiCtxBuilder::new() function uses this public interface to plug in its own implementations of each of these resources.

Snapshot architecture

One goal we've had for a while, but not quite met, is for multiple WASI snapshots to provide an interface to the same underlying WasiCtx. This provides us a path to evolve WASI by allowing the same WASI Command to import functions from different snapshots - e.g. the user could use Rust's std which imports snapshot 1, but also depend directly on the wasi crate which imports some future snapshot 2. Right now, this amounts to supporting snapshot 1 and "snapshot 0" aka wasi_unstable at once.

The architectural rules for snapshots are:

The wasi_common::Error type

wasi_common::Error is now anyhow::Error. wasi_common::snapshots::preview_1 contains all of the logic for transforming an Error into an Errno, by downcasting the error into any of

The wasi_common::ErrorExt trait provides human-friendly constructors for the wasi_common::ErrorKind variants .

If you throw an error that does not downcast to one of those, it will turn into a wiggle::Trap and terminate execution.

The real value of using anyhow::Error here is being able to use anyhow::Result::context to aid in debugging of errors.

The wasi-cap-std-sync implementation of the WASI traits

The wasi-cap-std-sync crate provides impl of WasiFile and WasiDir in terms of cap_std::fs::{File, Dir}. These types provide sandboxed access to the local filesystem on both Unix and Windows.

The entire design story of cap-std is much bigger than we can address here, but in short, its functionality replaces all of the wasi_common::sys hierarchy, as well as the yanix / winx crates. All syscalls are hidden behind the cap-std hierarchy, with the lone exception of the sched implementation, which is provided for both unix and windows in separate modules.

Any wasi_common::{WasiCtx, WasiCtxBuilder} is interoperable with the wasi-cap-std-sync crate. However, for convenience, wasi-cap-std-sync provides its own WasiCtxBuilder that hooks up to all of the crate's components, i.e. it fills in all of the arguments to WasiCtx::builder(...), presents preopen_dir in terms of cap_std::fs::Dir, and provides convenience methods for inheriting the parent process's stdio, args, and env.

The only place we expect to run into long-term compatibility issues between wasi-cap-std-sync and the other impl crates that will come later is in the Sched abstraction. Once we can build an async scheduler based on Rust Futures, async impls will be able to interoperate, but the synchronous scheduler depends on downcasting the WasiFile type down to concrete types it knows about (which in turn impl AsRawFd for passing to unix poll, or the analogous traits on windows).

Why is this impl suffixed with -sync? https://github.com/bytecodealliance/wasmtime/pull/2434 async is coming soon! The async impl may end up depending on tokio or other relatively heavy deps, so we will retain a sync implementation so that wasi-common users have an option of not pulling in an async runtime.

Improving the WASI test suite

The bulk of wasi-common's test suite lives at crates/test-programs. This test suite was extremely useful for guiding this rewrite. We improved the test suite in numerous ways, including

view this post on Zulip Wasmtime GitHub notifications bot (Feb 02 2021 at 03:12):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

This PR is a complete rewrite of the wasi-common crate. It uses @sunfishcode 's new cap-std family of crates to provide a sandboxed implementation of WASI on the local filesystem.

Note that this is a breaking change for all users of WASI with Wasmtime, except for the C API.

Re-architecting wasi-common

Over the past year or so, we've run up against many design problems in wasi-common. Many of these problems ended up being so fundamental that a rewrite, as prolonged as it was, ended up being more tractable than incremental changes.

The Table

wasi-common now has a Table type that is designed to map u32 handles to resources. The table is now part of the public interface to a WasiCtx - it is reference counted so that it can be shared beyond a WasiCtx with other WASI proposals (e.g. wasi-crypto and wasi-nn) to manage their resources. Elements in the Table are Any typed.

The Table type is intended to model how the Interface Types concept of Resources is shaping up. Right now it is just an approximation.

The WasiFile and WasiDir traits

The WASI specification only defines one handle type, fd, on which all operations on both files and directories (aka dirfds) are defined. We believe this is a design mistake, and are architecting wasi-common to make this straightforward to correct in future snapshots of WASI. Wasi-common internally treats files and directories as two distinct resource types in the table - Box<dyn WasiFile> and Box<dyn WasiDir>. The snapshot 0 and 1 interfaces via fd will attempt to downcast a table element to one or both of these interfaces depending on what is appropriate - e.g. fd_close operates on both files and directories, fd_read only operates on files, and fd_readdir only operates on directories.

The WasiFile and WasiDir traits are defined by wasi-common in terms of types defined directly in the crate's source code (I decided it should NOT those generated by the wiggle proc macros, see snapshot architecture below), as well as the cap_std::time family of types. And, importantly, wasi-common itself provides no implementation of WasiDir, and only two trivial implementations of WasiFile on the crate::pipe::{ReadPipe, WritePipe} types, which in turn just delegate to std::io::{Read, Write}. In order for wasi-common to access the local filesystem at all, you need to provide WasiFile and WasiDir impls through either the new wasi-cap-std-sync crate found at crates/wasi-common/cap-std-sync - see the section on that crate below - or by providing your own implementation from elsewhere.

This design makes it possible for wasi-common embedders to statically reason about access to the local filesystem by examining what impls are linked into an application. We found that this separation of concerns also makes it pretty enjoyable to write alternative implementations, e.g. a virtual filesystem (which will land in a future PR).

Traits for the rest of WASI's features

Other aspects of a WASI implementation are not yet considered resources and accessed by handle. We plan to correct this design deficiency in WASI in the future, but for now we have designed the following traits to provide embedders with the same sort of implementation flexibility they get with WasiFile/WasiDir:

Users can provide implementations of each of these interfaces to the WasiCtx::builder(...) function. The wasi_cap_std_sync::WasiCtxBuilder::new() function uses this public interface to plug in its own implementations of each of these resources.

Snapshot architecture

One goal we've had for a while, but not quite met, is for multiple WASI snapshots to provide an interface to the same underlying WasiCtx. This provides us a path to evolve WASI by allowing the same WASI Command to import functions from different snapshots - e.g. the user could use Rust's std which imports snapshot 1, but also depend directly on the wasi crate which imports some future snapshot 2. Right now, this amounts to supporting snapshot 1 and "snapshot 0" aka wasi_unstable at once.

The architectural rules for snapshots are:

The wasi_common::Error type

wasi_common::Error is now anyhow::Error. wasi_common::snapshots::preview_1 contains all of the logic for transforming an Error into an Errno, by downcasting the error into any of

The wasi_common::ErrorExt trait provides human-friendly constructors for the wasi_common::ErrorKind variants .

If you throw an error that does not downcast to one of those, it will turn into a wiggle::Trap and terminate execution.

The real value of using anyhow::Error here is being able to use anyhow::Result::context to aid in debugging of errors.

The wasi-cap-std-sync implementation of the WASI traits

The wasi-cap-std-sync crate provides impl of WasiFile and WasiDir in terms of cap_std::fs::{File, Dir}. These types provide sandboxed access to the local filesystem on both Unix and Windows.

The entire design story of cap-std is much bigger than we can address here, but in short, its functionality replaces all of the wasi_common::sys hierarchy, as well as the yanix / winx crates. All syscalls are hidden behind the cap-std hierarchy, with the lone exception of the sched implementation, which is provided for both unix and windows in separate modules.

Any wasi_common::{WasiCtx, WasiCtxBuilder} is interoperable with the wasi-cap-std-sync crate. However, for convenience, wasi-cap-std-sync provides its own WasiCtxBuilder that hooks up to all of the crate's components, i.e. it fills in all of the arguments to WasiCtx::builder(...), presents preopen_dir in terms of cap_std::fs::Dir, and provides convenience methods for inheriting the parent process's stdio, args, and env.

The only place we expect to run into long-term compatibility issues between wasi-cap-std-sync and the other impl crates that will come later is in the Sched abstraction. Once we can build an async scheduler based on Rust Futures, async impls will be able to interoperate, but the synchronous scheduler depends on downcasting the WasiFile type down to concrete types it knows about (which in turn impl AsRawFd for passing to unix poll, or the analogous traits on windows).

Why is this impl suffixed with -sync? https://github.com/bytecodealliance/wasmtime/pull/2434 async is coming soon! The async impl may end up depending on tokio or other relatively heavy deps, so we will retain a sync implementation so that wasi-common users have an option of not pulling in an async runtime.

Improving the WASI test suite

The bulk of wasi-common's test suite lives at crates/test-programs. This test suite was extremely useful for guiding this rewrite. We improved the test suite in numerous ways, including

view this post on Zulip Wasmtime GitHub notifications bot (Feb 02 2021 at 03:22):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

This PR is a complete rewrite of the wasi-common crate. It uses @sunfishcode 's new cap-std family of crates to provide a sandboxed implementation of WASI on the local filesystem.

Note that this is a breaking change for all users of WASI with Wasmtime, except for the C API.

Re-architecting wasi-common

Over the past year or so, we've run up against many design problems in wasi-common. Many of these problems ended up being so fundamental that a rewrite, as prolonged as it was, ended up being more tractable than incremental changes.

The Table

wasi-common now has a Table type that is designed to map u32 handles to resources. The table is now part of the public interface to a WasiCtx - it is reference counted so that it can be shared beyond a WasiCtx with other WASI proposals (e.g. wasi-crypto and wasi-nn) to manage their resources. Elements in the Table are Any typed.

The Table type is intended to model how the Interface Types concept of Resources is shaping up. Right now it is just an approximation.

The WasiFile and WasiDir traits

The WASI specification only defines one handle type, fd, on which all operations on both files and directories (aka dirfds) are defined. We believe this is a design mistake, and are architecting wasi-common to make this straightforward to correct in future snapshots of WASI. Wasi-common internally treats files and directories as two distinct resource types in the table - Box<dyn WasiFile> and Box<dyn WasiDir>. The snapshot 0 and 1 interfaces via fd will attempt to downcast a table element to one or both of these interfaces depending on what is appropriate - e.g. fd_close operates on both files and directories, fd_read only operates on files, and fd_readdir only operates on directories.

The WasiFile and WasiDir traits are defined by wasi-common in terms of types defined directly in the crate's source code (I decided it should NOT those generated by the wiggle proc macros, see snapshot architecture below), as well as the cap_std::time family of types. And, importantly, wasi-common itself provides no implementation of WasiDir, and only two trivial implementations of WasiFile on the crate::pipe::{ReadPipe, WritePipe} types, which in turn just delegate to std::io::{Read, Write}. In order for wasi-common to access the local filesystem at all, you need to provide WasiFile and WasiDir impls through either the new wasi-cap-std-sync crate found at crates/wasi-common/cap-std-sync - see the section on that crate below - or by providing your own implementation from elsewhere.

This design makes it possible for wasi-common embedders to statically reason about access to the local filesystem by examining what impls are linked into an application. We found that this separation of concerns also makes it pretty enjoyable to write alternative implementations, e.g. a virtual filesystem (which will land in a future PR).

Traits for the rest of WASI's features

Other aspects of a WASI implementation are not yet considered resources and accessed by handle. We plan to correct this design deficiency in WASI in the future, but for now we have designed the following traits to provide embedders with the same sort of implementation flexibility they get with WasiFile/WasiDir:

Users can provide implementations of each of these interfaces to the WasiCtx::builder(...) function. The wasi_cap_std_sync::WasiCtxBuilder::new() function uses this public interface to plug in its own implementations of each of these resources.

Snapshot architecture

One goal we've had for a while, but not quite met, is for multiple WASI snapshots to provide an interface to the same underlying WasiCtx. This provides us a path to evolve WASI by allowing the same WASI Command to import functions from different snapshots - e.g. the user could use Rust's std which imports snapshot 1, but also depend directly on the wasi crate which imports some future snapshot 2. Right now, this amounts to supporting snapshot 1 and "snapshot 0" aka wasi_unstable at once.

The architectural rules for snapshots are:

The wasi_common::Error type

wasi_common::Error is now anyhow::Error. wasi_common::snapshots::preview_1 contains all of the logic for transforming an Error into an Errno, by downcasting the error into any of

The wasi_common::ErrorExt trait provides human-friendly constructors for the wasi_common::ErrorKind variants .

If you throw an error that does not downcast to one of those, it will turn into a wiggle::Trap and terminate execution.

The real value of using anyhow::Error here is being able to use anyhow::Result::context to aid in debugging of errors.

The wasi-cap-std-sync implementation of the WASI traits

The wasi-cap-std-sync crate provides impl of WasiFile and WasiDir in terms of cap_std::fs::{File, Dir}. These types provide sandboxed access to the local filesystem on both Unix and Windows.

The entire design story of cap-std is much bigger than we can address here, but in short, its functionality replaces all of the wasi_common::sys hierarchy, as well as the yanix / winx crates. All syscalls are hidden behind the cap-std hierarchy, with the lone exception of the sched implementation, which is provided for both unix and windows in separate modules.

Any wasi_common::{WasiCtx, WasiCtxBuilder} is interoperable with the wasi-cap-std-sync crate. However, for convenience, wasi-cap-std-sync provides its own WasiCtxBuilder that hooks up to all of the crate's components, i.e. it fills in all of the arguments to WasiCtx::builder(...), presents preopen_dir in terms of cap_std::fs::Dir, and provides convenience methods for inheriting the parent process's stdio, args, and env.

The only place we expect to run into long-term compatibility issues between wasi-cap-std-sync and the other impl crates that will come later is in the Sched abstraction. Once we can build an async scheduler based on Rust Futures, async impls will be able to interoperate, but the synchronous scheduler depends on downcasting the WasiFile type down to concrete types it knows about (which in turn impl AsRawFd for passing to unix poll, or the analogous traits on windows).

Why is this impl suffixed with -sync? https://github.com/bytecodealliance/wasmtime/pull/2434 async is coming soon! The async impl may end up depending on tokio or other relatively heavy deps, so we will retain a sync implementation so that wasi-common users have an option of not pulling in an async runtime.

Improving the WASI test suite

The bulk of wasi-common's test suite lives at crates/test-programs. This test suite was extremely useful for guiding this rewrite. We improved the test suite in numerous ways, including

view this post on Zulip Wasmtime GitHub notifications bot (Feb 02 2021 at 03:40):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

This PR is a complete rewrite of the wasi-common crate. It uses @sunfishcode 's new cap-std family of crates to provide a sandboxed implementation of WASI on the local filesystem.

Note that this is a breaking change for all users of WASI with Wasmtime, except for the C API.

Re-architecting wasi-common

Over the past year or so, we've run up against many design problems in wasi-common. Many of these problems ended up being so fundamental that a rewrite, as prolonged as it was, ended up being more tractable than incremental changes.

The Table

wasi-common now has a Table type that is designed to map u32 handles to resources. The table is now part of the public interface to a WasiCtx - it is reference counted so that it can be shared beyond a WasiCtx with other WASI proposals (e.g. wasi-crypto and wasi-nn) to manage their resources. Elements in the Table are Any typed.

The Table type is intended to model how the Interface Types concept of Resources is shaping up. Right now it is just an approximation.

The WasiFile and WasiDir traits

The WASI specification only defines one handle type, fd, on which all operations on both files and directories (aka dirfds) are defined. We believe this is a design mistake, and are architecting wasi-common to make this straightforward to correct in future snapshots of WASI. Wasi-common internally treats files and directories as two distinct resource types in the table - Box<dyn WasiFile> and Box<dyn WasiDir>. The snapshot 0 and 1 interfaces via fd will attempt to downcast a table element to one or both of these interfaces depending on what is appropriate - e.g. fd_close operates on both files and directories, fd_read only operates on files, and fd_readdir only operates on directories.

The WasiFile and WasiDir traits are defined by wasi-common in terms of types defined directly in the crate's source code (I decided it should NOT those generated by the wiggle proc macros, see snapshot architecture below), as well as the cap_std::time family of types. And, importantly, wasi-common itself provides no implementation of WasiDir, and only two trivial implementations of WasiFile on the crate::pipe::{ReadPipe, WritePipe} types, which in turn just delegate to std::io::{Read, Write}. In order for wasi-common to access the local filesystem at all, you need to provide WasiFile and WasiDir impls through either the new wasi-cap-std-sync crate found at crates/wasi-common/cap-std-sync - see the section on that crate below - or by providing your own implementation from elsewhere.

This design makes it possible for wasi-common embedders to statically reason about access to the local filesystem by examining what impls are linked into an application. We found that this separation of concerns also makes it pretty enjoyable to write alternative implementations, e.g. a virtual filesystem (which will land in a future PR).

Traits for the rest of WASI's features

Other aspects of a WASI implementation are not yet considered resources and accessed by handle. We plan to correct this design deficiency in WASI in the future, but for now we have designed the following traits to provide embedders with the same sort of implementation flexibility they get with WasiFile/WasiDir:

Users can provide implementations of each of these interfaces to the WasiCtx::builder(...) function. The wasi_cap_std_sync::WasiCtxBuilder::new() function uses this public interface to plug in its own implementations of each of these resources.

Snapshot architecture

One goal we've had for a while, but not quite met, is for multiple WASI snapshots to provide an interface to the same underlying WasiCtx. This provides us a path to evolve WASI by allowing the same WASI Command to import functions from different snapshots - e.g. the user could use Rust's std which imports snapshot 1, but also depend directly on the wasi crate which imports some future snapshot 2. Right now, this amounts to supporting snapshot 1 and "snapshot 0" aka wasi_unstable at once.

The architectural rules for snapshots are:

The wasi_common::Error type

wasi_common::Error is now anyhow::Error. wasi_common::snapshots::preview_1 contains all of the logic for transforming an Error into an Errno, by downcasting the error into any of

The wasi_common::ErrorExt trait provides human-friendly constructors for the wasi_common::ErrorKind variants .

If you throw an error that does not downcast to one of those, it will turn into a wiggle::Trap and terminate execution.

The real value of using anyhow::Error here is being able to use anyhow::Result::context to aid in debugging of errors.

The wasi-cap-std-sync implementation of the WASI traits

The wasi-cap-std-sync crate provides impl of WasiFile and WasiDir in terms of cap_std::fs::{File, Dir}. These types provide sandboxed access to the local filesystem on both Unix and Windows.

The entire design story of cap-std is much bigger than we can address here, but in short, its functionality replaces all of the wasi_common::sys hierarchy, as well as the yanix / winx crates. All syscalls are hidden behind the cap-std hierarchy, with the lone exception of the sched implementation, which is provided for both unix and windows in separate modules.

Any wasi_common::{WasiCtx, WasiCtxBuilder} is interoperable with the wasi-cap-std-sync crate. However, for convenience, wasi-cap-std-sync provides its own WasiCtxBuilder that hooks up to all of the crate's components, i.e. it fills in all of the arguments to WasiCtx::builder(...), presents preopen_dir in terms of cap_std::fs::Dir, and provides convenience methods for inheriting the parent process's stdio, args, and env.

The only place we expect to run into long-term compatibility issues between wasi-cap-std-sync and the other impl crates that will come later is in the Sched abstraction. Once we can build an async scheduler based on Rust Futures, async impls will be able to interoperate, but the synchronous scheduler depends on downcasting the WasiFile type down to concrete types it knows about (which in turn impl AsRawFd for passing to unix poll, or the analogous traits on windows).

Why is this impl suffixed with -sync? https://github.com/bytecodealliance/wasmtime/pull/2434 async is coming soon! The async impl may end up depending on tokio or other relatively heavy deps, so we will retain a sync implementation so that wasi-common users have an option of not pulling in an async runtime.

Improving the WASI test suite

The bulk of wasi-common's test suite lives at crates/test-programs. This test suite was extremely useful for guiding this rewrite. We improved the test suite in numerous ways, including

view this post on Zulip Wasmtime GitHub notifications bot (Feb 02 2021 at 18:44):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

This PR is a complete rewrite of the wasi-common crate. It uses @sunfishcode 's new cap-std family of crates to provide a sandboxed implementation of WASI on the local filesystem.

Note that this is a breaking change for all users of WASI with Wasmtime, except for the C API.

Re-architecting wasi-common

Over the past year or so, we've run up against many design problems in wasi-common. Many of these problems ended up being so fundamental that a rewrite, as prolonged as it was, ended up being more tractable than incremental changes.

The Table

wasi-common now has a Table type that is designed to map u32 handles to resources. The table is now part of the public interface to a WasiCtx - it is reference counted so that it can be shared beyond a WasiCtx with other WASI proposals (e.g. wasi-crypto and wasi-nn) to manage their resources. Elements in the Table are Any typed.

The Table type is intended to model how the Interface Types concept of Resources is shaping up. Right now it is just an approximation.

The WasiFile and WasiDir traits

The WASI specification only defines one handle type, fd, on which all operations on both files and directories (aka dirfds) are defined. We believe this is a design mistake, and are architecting wasi-common to make this straightforward to correct in future snapshots of WASI. Wasi-common internally treats files and directories as two distinct resource types in the table - Box<dyn WasiFile> and Box<dyn WasiDir>. The snapshot 0 and 1 interfaces via fd will attempt to downcast a table element to one or both of these interfaces depending on what is appropriate - e.g. fd_close operates on both files and directories, fd_read only operates on files, and fd_readdir only operates on directories.

The WasiFile and WasiDir traits are defined by wasi-common in terms of types defined directly in the crate's source code (I decided it should NOT those generated by the wiggle proc macros, see snapshot architecture below), as well as the cap_std::time family of types. And, importantly, wasi-common itself provides no implementation of WasiDir, and only two trivial implementations of WasiFile on the crate::pipe::{ReadPipe, WritePipe} types, which in turn just delegate to std::io::{Read, Write}. In order for wasi-common to access the local filesystem at all, you need to provide WasiFile and WasiDir impls through either the new wasi-cap-std-sync crate found at crates/wasi-common/cap-std-sync - see the section on that crate below - or by providing your own implementation from elsewhere.

This design makes it possible for wasi-common embedders to statically reason about access to the local filesystem by examining what impls are linked into an application. We found that this separation of concerns also makes it pretty enjoyable to write alternative implementations, e.g. a virtual filesystem (which will land in a future PR).

Traits for the rest of WASI's features

Other aspects of a WASI implementation are not yet considered resources and accessed by handle. We plan to correct this design deficiency in WASI in the future, but for now we have designed the following traits to provide embedders with the same sort of implementation flexibility they get with WasiFile/WasiDir:

Users can provide implementations of each of these interfaces to the WasiCtx::builder(...) function. The wasi_cap_std_sync::WasiCtxBuilder::new() function uses this public interface to plug in its own implementations of each of these resources.

Snapshot architecture

One goal we've had for a while, but not quite met, is for multiple WASI snapshots to provide an interface to the same underlying WasiCtx. This provides us a path to evolve WASI by allowing the same WASI Command to import functions from different snapshots - e.g. the user could use Rust's std which imports snapshot 1, but also depend directly on the wasi crate which imports some future snapshot 2. Right now, this amounts to supporting snapshot 1 and "snapshot 0" aka wasi_unstable at once.

The architectural rules for snapshots are:

The wasi_common::Error type

wasi_common::Error is now anyhow::Error. wasi_common::snapshots::preview_1 contains all of the logic for transforming an Error into an Errno, by downcasting the error into any of

The wasi_common::ErrorExt trait provides human-friendly constructors for the wasi_common::ErrorKind variants .

If you throw an error that does not downcast to one of those, it will turn into a wiggle::Trap and terminate execution.

The real value of using anyhow::Error here is being able to use anyhow::Result::context to aid in debugging of errors.

The wasi-cap-std-sync implementation of the WASI traits

The wasi-cap-std-sync crate provides impl of WasiFile and WasiDir in terms of cap_std::fs::{File, Dir}. These types provide sandboxed access to the local filesystem on both Unix and Windows.

The entire design story of cap-std is much bigger than we can address here, but in short, its functionality replaces all of the wasi_common::sys hierarchy, as well as the yanix / winx crates. All syscalls are hidden behind the cap-std hierarchy, with the lone exception of the sched implementation, which is provided for both unix and windows in separate modules.

Any wasi_common::{WasiCtx, WasiCtxBuilder} is interoperable with the wasi-cap-std-sync crate. However, for convenience, wasi-cap-std-sync provides its own WasiCtxBuilder that hooks up to all of the crate's components, i.e. it fills in all of the arguments to WasiCtx::builder(...), presents preopen_dir in terms of cap_std::fs::Dir, and provides convenience methods for inheriting the parent process's stdio, args, and env.

The only place we expect to run into long-term compatibility issues between wasi-cap-std-sync and the other impl crates that will come later is in the Sched abstraction. Once we can build an async scheduler based on Rust Futures, async impls will be able to interoperate, but the synchronous scheduler depends on downcasting the WasiFile type down to concrete types it knows about (which in turn impl AsRawFd for passing to unix poll, or the analogous traits on windows).

Why is this impl suffixed with -sync? https://github.com/bytecodealliance/wasmtime/pull/2434 async is coming soon! The async impl may end up depending on tokio or other relatively heavy deps, so we will retain a sync implementation so that wasi-common users have an option of not pulling in an async runtime.

Improving the WASI test suite

The bulk of wasi-common's test suite lives at crates/test-programs. This test suite was extremely useful for guiding this rewrite. We improved the test suite in numerous ways, including

view this post on Zulip Wasmtime GitHub notifications bot (Feb 02 2021 at 21:30):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

This PR is a complete rewrite of the wasi-common crate. It uses @sunfishcode 's new cap-std family of crates to provide a sandboxed implementation of WASI on the local filesystem.

Note that this is a breaking change for all users of WASI with Wasmtime, except for the C API.

Re-architecting wasi-common

Over the past year or so, we've run up against many design problems in wasi-common. Many of these problems ended up being so fundamental that a rewrite, as prolonged as it was, ended up being more tractable than incremental changes.

The Table

wasi-common now has a Table type that is designed to map u32 handles to resources. The table is now part of the public interface to a WasiCtx - it is reference counted so that it can be shared beyond a WasiCtx with other WASI proposals (e.g. wasi-crypto and wasi-nn) to manage their resources. Elements in the Table are Any typed.

The Table type is intended to model how the Interface Types concept of Resources is shaping up. Right now it is just an approximation.

The WasiFile and WasiDir traits

The WASI specification only defines one handle type, fd, on which all operations on both files and directories (aka dirfds) are defined. We believe this is a design mistake, and are architecting wasi-common to make this straightforward to correct in future snapshots of WASI. Wasi-common internally treats files and directories as two distinct resource types in the table - Box<dyn WasiFile> and Box<dyn WasiDir>. The snapshot 0 and 1 interfaces via fd will attempt to downcast a table element to one or both of these interfaces depending on what is appropriate - e.g. fd_close operates on both files and directories, fd_read only operates on files, and fd_readdir only operates on directories.

The WasiFile and WasiDir traits are defined by wasi-common in terms of types defined directly in the crate's source code (I decided it should NOT those generated by the wiggle proc macros, see snapshot architecture below), as well as the cap_std::time family of types. And, importantly, wasi-common itself provides no implementation of WasiDir, and only two trivial implementations of WasiFile on the crate::pipe::{ReadPipe, WritePipe} types, which in turn just delegate to std::io::{Read, Write}. In order for wasi-common to access the local filesystem at all, you need to provide WasiFile and WasiDir impls through either the new wasi-cap-std-sync crate found at crates/wasi-common/cap-std-sync - see the section on that crate below - or by providing your own implementation from elsewhere.

This design makes it possible for wasi-common embedders to statically reason about access to the local filesystem by examining what impls are linked into an application. We found that this separation of concerns also makes it pretty enjoyable to write alternative implementations, e.g. a virtual filesystem (which will land in a future PR).

Traits for the rest of WASI's features

Other aspects of a WASI implementation are not yet considered resources and accessed by handle. We plan to correct this design deficiency in WASI in the future, but for now we have designed the following traits to provide embedders with the same sort of implementation flexibility they get with WasiFile/WasiDir:

Users can provide implementations of each of these interfaces to the WasiCtx::builder(...) function. The wasi_cap_std_sync::WasiCtxBuilder::new() function uses this public interface to plug in its own implementations of each of these resources.

Snapshot architecture

One goal we've had for a while, but not quite met, is for multiple WASI snapshots to provide an interface to the same underlying WasiCtx. This provides us a path to evolve WASI by allowing the same WASI Command to import functions from different snapshots - e.g. the user could use Rust's std which imports snapshot 1, but also depend directly on the wasi crate which imports some future snapshot 2. Right now, this amounts to supporting snapshot 1 and "snapshot 0" aka wasi_unstable at once.

The architectural rules for snapshots are:

The wasi_common::Error type

wasi_common::Error is now anyhow::Error. wasi_common::snapshots::preview_1 contains all of the logic for transforming an Error into an Errno, by downcasting the error into any of

The wasi_common::ErrorExt trait provides human-friendly constructors for the wasi_common::ErrorKind variants .

If you throw an error that does not downcast to one of those, it will turn into a wiggle::Trap and terminate execution.

The real value of using anyhow::Error here is being able to use anyhow::Result::context to aid in debugging of errors.

The wasi-cap-std-sync implementation of the WASI traits

The wasi-cap-std-sync crate provides impl of WasiFile and WasiDir in terms of cap_std::fs::{File, Dir}. These types provide sandboxed access to the local filesystem on both Unix and Windows.

The entire design story of cap-std is much bigger than we can address here, but in short, its functionality replaces all of the wasi_common::sys hierarchy, as well as the yanix / winx crates. All syscalls are hidden behind the cap-std hierarchy, with the lone exception of the sched implementation, which is provided for both unix and windows in separate modules.

Any wasi_common::{WasiCtx, WasiCtxBuilder} is interoperable with the wasi-cap-std-sync crate. However, for convenience, wasi-cap-std-sync provides its own WasiCtxBuilder that hooks up to all of the crate's components, i.e. it fills in all of the arguments to WasiCtx::builder(...), presents preopen_dir in terms of cap_std::fs::Dir, and provides convenience methods for inheriting the parent process's stdio, args, and env.

The only place we expect to run into long-term compatibility issues between wasi-cap-std-sync and the other impl crates that will come later is in the Sched abstraction. Once we can build an async scheduler based on Rust Futures, async impls will be able to interoperate, but the synchronous scheduler depends on downcasting the WasiFile type down to concrete types it knows about (which in turn impl AsRawFd for passing to unix poll, or the analogous traits on windows).

Why is this impl suffixed with -sync? https://github.com/bytecodealliance/wasmtime/pull/2434 async is coming soon! The async impl may end up depending on tokio or other relatively heavy deps, so we will retain a sync implementation so that wasi-common users have an option of not pulling in an async runtime.

Improving the WASI test suite

The bulk of wasi-common's test suite lives at crates/test-programs. This test suite was extremely useful for guiding this rewrite. We improved the test suite in numerous ways, including

view this post on Zulip Wasmtime GitHub notifications bot (Feb 02 2021 at 21:41):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

This PR is a complete rewrite of the wasi-common crate. It uses @sunfishcode 's new cap-std family of crates to provide a sandboxed implementation of WASI on the local filesystem.

Note that this is a breaking change for all users of WASI with Wasmtime, except for the C API.

Re-architecting wasi-common

Over the past year or so, we've run up against many design problems in wasi-common. Many of these problems ended up being so fundamental that a rewrite, as prolonged as it was, ended up being more tractable than incremental changes.

The Table

wasi-common now has a Table type that is designed to map u32 handles to resources. The table is now part of the public interface to a WasiCtx - it is reference counted so that it can be shared beyond a WasiCtx with other WASI proposals (e.g. wasi-crypto and wasi-nn) to manage their resources. Elements in the Table are Any typed.

The Table type is intended to model how the Interface Types concept of Resources is shaping up. Right now it is just an approximation.

The WasiFile and WasiDir traits

The WASI specification only defines one handle type, fd, on which all operations on both files and directories (aka dirfds) are defined. We believe this is a design mistake, and are architecting wasi-common to make this straightforward to correct in future snapshots of WASI. Wasi-common internally treats files and directories as two distinct resource types in the table - Box<dyn WasiFile> and Box<dyn WasiDir>. The snapshot 0 and 1 interfaces via fd will attempt to downcast a table element to one or both of these interfaces depending on what is appropriate - e.g. fd_close operates on both files and directories, fd_read only operates on files, and fd_readdir only operates on directories.

The WasiFile and WasiDir traits are defined by wasi-common in terms of types defined directly in the crate's source code (I decided it should NOT those generated by the wiggle proc macros, see snapshot architecture below), as well as the cap_std::time family of types. And, importantly, wasi-common itself provides no implementation of WasiDir, and only two trivial implementations of WasiFile on the crate::pipe::{ReadPipe, WritePipe} types, which in turn just delegate to std::io::{Read, Write}. In order for wasi-common to access the local filesystem at all, you need to provide WasiFile and WasiDir impls through either the new wasi-cap-std-sync crate found at crates/wasi-common/cap-std-sync - see the section on that crate below - or by providing your own implementation from elsewhere.

This design makes it possible for wasi-common embedders to statically reason about access to the local filesystem by examining what impls are linked into an application. We found that this separation of concerns also makes it pretty enjoyable to write alternative implementations, e.g. a virtual filesystem (which will land in a future PR).

Traits for the rest of WASI's features

Other aspects of a WASI implementation are not yet considered resources and accessed by handle. We plan to correct this design deficiency in WASI in the future, but for now we have designed the following traits to provide embedders with the same sort of implementation flexibility they get with WasiFile/WasiDir:

Users can provide implementations of each of these interfaces to the WasiCtx::builder(...) function. The wasi_cap_std_sync::WasiCtxBuilder::new() function uses this public interface to plug in its own implementations of each of these resources.

Snapshot architecture

One goal we've had for a while, but not quite met, is for multiple WASI snapshots to provide an interface to the same underlying WasiCtx. This provides us a path to evolve WASI by allowing the same WASI Command to import functions from different snapshots - e.g. the user could use Rust's std which imports snapshot 1, but also depend directly on the wasi crate which imports some future snapshot 2. Right now, this amounts to supporting snapshot 1 and "snapshot 0" aka wasi_unstable at once.

The architectural rules for snapshots are:

The wasi_common::Error type

wasi_common::Error is now anyhow::Error. wasi_common::snapshots::preview_1 contains all of the logic for transforming an Error into an Errno, by downcasting the error into any of

The wasi_common::ErrorExt trait provides human-friendly constructors for the wasi_common::ErrorKind variants .

If you throw an error that does not downcast to one of those, it will turn into a wiggle::Trap and terminate execution.

The real value of using anyhow::Error here is being able to use anyhow::Result::context to aid in debugging of errors.

The wasi-cap-std-sync implementation of the WASI traits

The wasi-cap-std-sync crate provides impl of WasiFile and WasiDir in terms of cap_std::fs::{File, Dir}. These types provide sandboxed access to the local filesystem on both Unix and Windows.

The entire design story of cap-std is much bigger than we can address here, but in short, its functionality replaces all of the wasi_common::sys hierarchy, as well as the yanix / winx crates. All syscalls are hidden behind the cap-std hierarchy, with the lone exception of the sched implementation, which is provided for both unix and windows in separate modules.

Any wasi_common::{WasiCtx, WasiCtxBuilder} is interoperable with the wasi-cap-std-sync crate. However, for convenience, wasi-cap-std-sync provides its own WasiCtxBuilder that hooks up to all of the crate's components, i.e. it fills in all of the arguments to WasiCtx::builder(...), presents preopen_dir in terms of cap_std::fs::Dir, and provides convenience methods for inheriting the parent process's stdio, args, and env.

The only place we expect to run into long-term compatibility issues between wasi-cap-std-sync and the other impl crates that will come later is in the Sched abstraction. Once we can build an async scheduler based on Rust Futures, async impls will be able to interoperate, but the synchronous scheduler depends on downcasting the WasiFile type down to concrete types it knows about (which in turn impl AsRawFd for passing to unix poll, or the analogous traits on windows).

Why is this impl suffixed with -sync? https://github.com/bytecodealliance/wasmtime/pull/2434 async is coming soon! The async impl may end up depending on tokio or other relatively heavy deps, so we will retain a sync implementation so that wasi-common users have an option of not pulling in an async runtime.

Improving the WASI test suite

The bulk of wasi-common's test suite lives at crates/test-programs. This test suite was extremely useful for guiding this rewrite. We improved the test suite in numerous ways, including

view this post on Zulip Wasmtime GitHub notifications bot (Feb 02 2021 at 23:30):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

This PR is a complete rewrite of the wasi-common crate. It uses @sunfishcode 's new cap-std family of crates to provide a sandboxed implementation of WASI on the local filesystem.

Note that this is a breaking change for all users of WASI with Wasmtime, except for the C API.

Re-architecting wasi-common

Over the past year or so, we've run up against many design problems in wasi-common. Many of these problems ended up being so fundamental that a rewrite, as prolonged as it was, ended up being more tractable than incremental changes.

The Table

wasi-common now has a Table type that is designed to map u32 handles to resources. The table is now part of the public interface to a WasiCtx - it is reference counted so that it can be shared beyond a WasiCtx with other WASI proposals (e.g. wasi-crypto and wasi-nn) to manage their resources. Elements in the Table are Any typed.

The Table type is intended to model how the Interface Types concept of Resources is shaping up. Right now it is just an approximation.

The WasiFile and WasiDir traits

The WASI specification only defines one handle type, fd, on which all operations on both files and directories (aka dirfds) are defined. We believe this is a design mistake, and are architecting wasi-common to make this straightforward to correct in future snapshots of WASI. Wasi-common internally treats files and directories as two distinct resource types in the table - Box<dyn WasiFile> and Box<dyn WasiDir>. The snapshot 0 and 1 interfaces via fd will attempt to downcast a table element to one or both of these interfaces depending on what is appropriate - e.g. fd_close operates on both files and directories, fd_read only operates on files, and fd_readdir only operates on directories.

The WasiFile and WasiDir traits are defined by wasi-common in terms of types defined directly in the crate's source code (I decided it should NOT those generated by the wiggle proc macros, see snapshot architecture below), as well as the cap_std::time family of types. And, importantly, wasi-common itself provides no implementation of WasiDir, and only two trivial implementations of WasiFile on the crate::pipe::{ReadPipe, WritePipe} types, which in turn just delegate to std::io::{Read, Write}. In order for wasi-common to access the local filesystem at all, you need to provide WasiFile and WasiDir impls through either the new wasi-cap-std-sync crate found at crates/wasi-common/cap-std-sync - see the section on that crate below - or by providing your own implementation from elsewhere.

This design makes it possible for wasi-common embedders to statically reason about access to the local filesystem by examining what impls are linked into an application. We found that this separation of concerns also makes it pretty enjoyable to write alternative implementations, e.g. a virtual filesystem (which will land in a future PR).

Traits for the rest of WASI's features

Other aspects of a WASI implementation are not yet considered resources and accessed by handle. We plan to correct this design deficiency in WASI in the future, but for now we have designed the following traits to provide embedders with the same sort of implementation flexibility they get with WasiFile/WasiDir:

Users can provide implementations of each of these interfaces to the WasiCtx::builder(...) function. The wasi_cap_std_sync::WasiCtxBuilder::new() function uses this public interface to plug in its own implementations of each of these resources.

Snapshot architecture

One goal we've had for a while, but not quite met, is for multiple WASI snapshots to provide an interface to the same underlying WasiCtx. This provides us a path to evolve WASI by allowing the same WASI Command to import functions from different snapshots - e.g. the user could use Rust's std which imports snapshot 1, but also depend directly on the wasi crate which imports some future snapshot 2. Right now, this amounts to supporting snapshot 1 and "snapshot 0" aka wasi_unstable at once.

The architectural rules for snapshots are:

The wasi_common::Error type

wasi_common::Error is now anyhow::Error. wasi_common::snapshots::preview_1 contains all of the logic for transforming an Error into an Errno, by downcasting the error into any of

The wasi_common::ErrorExt trait provides human-friendly constructors for the wasi_common::ErrorKind variants .

If you throw an error that does not downcast to one of those, it will turn into a wiggle::Trap and terminate execution.

The real value of using anyhow::Error here is being able to use anyhow::Result::context to aid in debugging of errors.

The wasi-cap-std-sync implementation of the WASI traits

The wasi-cap-std-sync crate provides impl of WasiFile and WasiDir in terms of cap_std::fs::{File, Dir}. These types provide sandboxed access to the local filesystem on both Unix and Windows.

The entire design story of cap-std is much bigger than we can address here, but in short, its functionality replaces all of the wasi_common::sys hierarchy, as well as the yanix / winx crates. All syscalls are hidden behind the cap-std hierarchy, with the lone exception of the sched implementation, which is provided for both unix and windows in separate modules.

Any wasi_common::{WasiCtx, WasiCtxBuilder} is interoperable with the wasi-cap-std-sync crate. However, for convenience, wasi-cap-std-sync provides its own WasiCtxBuilder that hooks up to all of the crate's components, i.e. it fills in all of the arguments to WasiCtx::builder(...), presents preopen_dir in terms of cap_std::fs::Dir, and provides convenience methods for inheriting the parent process's stdio, args, and env.

The only place we expect to run into long-term compatibility issues between wasi-cap-std-sync and the other impl crates that will come later is in the Sched abstraction. Once we can build an async scheduler based on Rust Futures, async impls will be able to interoperate, but the synchronous scheduler depends on downcasting the WasiFile type down to concrete types it knows about (which in turn impl AsRawFd for passing to unix poll, or the analogous traits on windows).

Why is this impl suffixed with -sync? https://github.com/bytecodealliance/wasmtime/pull/2434 async is coming soon! The async impl may end up depending on tokio or other relatively heavy deps, so we will retain a sync implementation so that wasi-common users have an option of not pulling in an async runtime.

Improving the WASI test suite

The bulk of wasi-common's test suite lives at crates/test-programs. This test suite was extremely useful for guiding this rewrite. We improved the test suite in numerous ways, including

view this post on Zulip Wasmtime GitHub notifications bot (Feb 03 2021 at 00:16):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

This PR is a complete rewrite of the wasi-common crate. It uses @sunfishcode 's new cap-std family of crates to provide a sandboxed implementation of WASI on the local filesystem.

Note that this is a breaking change for all users of WASI with Wasmtime, except for the C API.

Re-architecting wasi-common

Over the past year or so, we've run up against many design problems in wasi-common. Many of these problems ended up being so fundamental that a rewrite, as prolonged as it was, ended up being more tractable than incremental changes.

The Table

wasi-common now has a Table type that is designed to map u32 handles to resources. The table is now part of the public interface to a WasiCtx - it is reference counted so that it can be shared beyond a WasiCtx with other WASI proposals (e.g. wasi-crypto and wasi-nn) to manage their resources. Elements in the Table are Any typed.

The Table type is intended to model how the Interface Types concept of Resources is shaping up. Right now it is just an approximation.

The WasiFile and WasiDir traits

The WASI specification only defines one handle type, fd, on which all operations on both files and directories (aka dirfds) are defined. We believe this is a design mistake, and are architecting wasi-common to make this straightforward to correct in future snapshots of WASI. Wasi-common internally treats files and directories as two distinct resource types in the table - Box<dyn WasiFile> and Box<dyn WasiDir>. The snapshot 0 and 1 interfaces via fd will attempt to downcast a table element to one or both of these interfaces depending on what is appropriate - e.g. fd_close operates on both files and directories, fd_read only operates on files, and fd_readdir only operates on directories.

The WasiFile and WasiDir traits are defined by wasi-common in terms of types defined directly in the crate's source code (I decided it should NOT those generated by the wiggle proc macros, see snapshot architecture below), as well as the cap_std::time family of types. And, importantly, wasi-common itself provides no implementation of WasiDir, and only two trivial implementations of WasiFile on the crate::pipe::{ReadPipe, WritePipe} types, which in turn just delegate to std::io::{Read, Write}. In order for wasi-common to access the local filesystem at all, you need to provide WasiFile and WasiDir impls through either the new wasi-cap-std-sync crate found at crates/wasi-common/cap-std-sync - see the section on that crate below - or by providing your own implementation from elsewhere.

This design makes it possible for wasi-common embedders to statically reason about access to the local filesystem by examining what impls are linked into an application. We found that this separation of concerns also makes it pretty enjoyable to write alternative implementations, e.g. a virtual filesystem (which will land in a future PR).

Traits for the rest of WASI's features

Other aspects of a WASI implementation are not yet considered resources and accessed by handle. We plan to correct this design deficiency in WASI in the future, but for now we have designed the following traits to provide embedders with the same sort of implementation flexibility they get with WasiFile/WasiDir:

Users can provide implementations of each of these interfaces to the WasiCtx::builder(...) function. The wasi_cap_std_sync::WasiCtxBuilder::new() function uses this public interface to plug in its own implementations of each of these resources.

Snapshot architecture

One goal we've had for a while, but not quite met, is for multiple WASI snapshots to provide an interface to the same underlying WasiCtx. This provides us a path to evolve WASI by allowing the same WASI Command to import functions from different snapshots - e.g. the user could use Rust's std which imports snapshot 1, but also depend directly on the wasi crate which imports some future snapshot 2. Right now, this amounts to supporting snapshot 1 and "snapshot 0" aka wasi_unstable at once.

The architectural rules for snapshots are:

The wasi_common::Error type

wasi_common::Error is now anyhow::Error. wasi_common::snapshots::preview_1 contains all of the logic for transforming an Error into an Errno, by downcasting the error into any of

The wasi_common::ErrorExt trait provides human-friendly constructors for the wasi_common::ErrorKind variants .

If you throw an error that does not downcast to one of those, it will turn into a wiggle::Trap and terminate execution.

The real value of using anyhow::Error here is being able to use anyhow::Result::context to aid in debugging of errors.

The wasi-cap-std-sync implementation of the WASI traits

The wasi-cap-std-sync crate provides impl of WasiFile and WasiDir in terms of cap_std::fs::{File, Dir}. These types provide sandboxed access to the local filesystem on both Unix and Windows.

The entire design story of cap-std is much bigger than we can address here, but in short, its functionality replaces all of the wasi_common::sys hierarchy, as well as the yanix / winx crates. All syscalls are hidden behind the cap-std hierarchy, with the lone exception of the sched implementation, which is provided for both unix and windows in separate modules.

Any wasi_common::{WasiCtx, WasiCtxBuilder} is interoperable with the wasi-cap-std-sync crate. However, for convenience, wasi-cap-std-sync provides its own WasiCtxBuilder that hooks up to all of the crate's components, i.e. it fills in all of the arguments to WasiCtx::builder(...), presents preopen_dir in terms of cap_std::fs::Dir, and provides convenience methods for inheriting the parent process's stdio, args, and env.

The only place we expect to run into long-term compatibility issues between wasi-cap-std-sync and the other impl crates that will come later is in the Sched abstraction. Once we can build an async scheduler based on Rust Futures, async impls will be able to interoperate, but the synchronous scheduler depends on downcasting the WasiFile type down to concrete types it knows about (which in turn impl AsRawFd for passing to unix poll, or the analogous traits on windows).

Why is this impl suffixed with -sync? https://github.com/bytecodealliance/wasmtime/pull/2434 async is coming soon! The async impl may end up depending on tokio or other relatively heavy deps, so we will retain a sync implementation so that wasi-common users have an option of not pulling in an async runtime.

Improving the WASI test suite

The bulk of wasi-common's test suite lives at crates/test-programs. This test suite was extremely useful for guiding this rewrite. We improved the test suite in numerous ways, including

view this post on Zulip Wasmtime GitHub notifications bot (Feb 03 2021 at 00:24):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

This PR is a complete rewrite of the wasi-common crate. It uses @sunfishcode 's new cap-std family of crates to provide a sandboxed implementation of WASI on the local filesystem.

Note that this is a breaking change for all users of WASI with Wasmtime, except for the C API.

Re-architecting wasi-common

Over the past year or so, we've run up against many design problems in wasi-common. Many of these problems ended up being so fundamental that a rewrite, as prolonged as it was, ended up being more tractable than incremental changes.

The Table

wasi-common now has a Table type that is designed to map u32 handles to resources. The table is now part of the public interface to a WasiCtx - it is reference counted so that it can be shared beyond a WasiCtx with other WASI proposals (e.g. wasi-crypto and wasi-nn) to manage their resources. Elements in the Table are Any typed.

The Table type is intended to model how the Interface Types concept of Resources is shaping up. Right now it is just an approximation.

The WasiFile and WasiDir traits

The WASI specification only defines one handle type, fd, on which all operations on both files and directories (aka dirfds) are defined. We believe this is a design mistake, and are architecting wasi-common to make this straightforward to correct in future snapshots of WASI. Wasi-common internally treats files and directories as two distinct resource types in the table - Box<dyn WasiFile> and Box<dyn WasiDir>. The snapshot 0 and 1 interfaces via fd will attempt to downcast a table element to one or both of these interfaces depending on what is appropriate - e.g. fd_close operates on both files and directories, fd_read only operates on files, and fd_readdir only operates on directories.

The WasiFile and WasiDir traits are defined by wasi-common in terms of types defined directly in the crate's source code (I decided it should NOT those generated by the wiggle proc macros, see snapshot architecture below), as well as the cap_std::time family of types. And, importantly, wasi-common itself provides no implementation of WasiDir, and only two trivial implementations of WasiFile on the crate::pipe::{ReadPipe, WritePipe} types, which in turn just delegate to std::io::{Read, Write}. In order for wasi-common to access the local filesystem at all, you need to provide WasiFile and WasiDir impls through either the new wasi-cap-std-sync crate found at crates/wasi-common/cap-std-sync - see the section on that crate below - or by providing your own implementation from elsewhere.

This design makes it possible for wasi-common embedders to statically reason about access to the local filesystem by examining what impls are linked into an application. We found that this separation of concerns also makes it pretty enjoyable to write alternative implementations, e.g. a virtual filesystem (which will land in a future PR).

Traits for the rest of WASI's features

Other aspects of a WASI implementation are not yet considered resources and accessed by handle. We plan to correct this design deficiency in WASI in the future, but for now we have designed the following traits to provide embedders with the same sort of implementation flexibility they get with WasiFile/WasiDir:

Users can provide implementations of each of these interfaces to the WasiCtx::builder(...) function. The wasi_cap_std_sync::WasiCtxBuilder::new() function uses this public interface to plug in its own implementations of each of these resources.

Snapshot architecture

One goal we've had for a while, but not quite met, is for multiple WASI snapshots to provide an interface to the same underlying WasiCtx. This provides us a path to evolve WASI by allowing the same WASI Command to import functions from different snapshots - e.g. the user could use Rust's std which imports snapshot 1, but also depend directly on the wasi crate which imports some future snapshot 2. Right now, this amounts to supporting snapshot 1 and "snapshot 0" aka wasi_unstable at once.

The architectural rules for snapshots are:

The wasi_common::Error type

wasi_common::Error is now anyhow::Error. wasi_common::snapshots::preview_1 contains all of the logic for transforming an Error into an Errno, by downcasting the error into any of

The wasi_common::ErrorExt trait provides human-friendly constructors for the wasi_common::ErrorKind variants .

If you throw an error that does not downcast to one of those, it will turn into a wiggle::Trap and terminate execution.

The real value of using anyhow::Error here is being able to use anyhow::Result::context to aid in debugging of errors.

The wasi-cap-std-sync implementation of the WASI traits

The wasi-cap-std-sync crate provides impl of WasiFile and WasiDir in terms of cap_std::fs::{File, Dir}. These types provide sandboxed access to the local filesystem on both Unix and Windows.

The entire design story of cap-std is much bigger than we can address here, but in short, its functionality replaces all of the wasi_common::sys hierarchy, as well as the yanix / winx crates. All syscalls are hidden behind the cap-std hierarchy, with the lone exception of the sched implementation, which is provided for both unix and windows in separate modules.

Any wasi_common::{WasiCtx, WasiCtxBuilder} is interoperable with the wasi-cap-std-sync crate. However, for convenience, wasi-cap-std-sync provides its own WasiCtxBuilder that hooks up to all of the crate's components, i.e. it fills in all of the arguments to WasiCtx::builder(...), presents preopen_dir in terms of cap_std::fs::Dir, and provides convenience methods for inheriting the parent process's stdio, args, and env.

The only place we expect to run into long-term compatibility issues between wasi-cap-std-sync and the other impl crates that will come later is in the Sched abstraction. Once we can build an async scheduler based on Rust Futures, async impls will be able to interoperate, but the synchronous scheduler depends on downcasting the WasiFile type down to concrete types it knows about (which in turn impl AsRawFd for passing to unix poll, or the analogous traits on windows).

Why is this impl suffixed with -sync? https://github.com/bytecodealliance/wasmtime/pull/2434 async is coming soon! The async impl may end up depending on tokio or other relatively heavy deps, so we will retain a sync implementation so that wasi-common users have an option of not pulling in an async runtime.

Improving the WASI test suite

The bulk of wasi-common's test suite lives at crates/test-programs. This test suite was extremely useful for guiding this rewrite. We improved the test suite in numerous ways, including

view this post on Zulip Wasmtime GitHub notifications bot (Feb 03 2021 at 01:09):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

This PR is a complete rewrite of the wasi-common crate. It uses @sunfishcode 's new cap-std family of crates to provide a sandboxed implementation of WASI on the local filesystem.

Note that this is a breaking change for all users of WASI with Wasmtime, except for the C API.

Re-architecting wasi-common

Over the past year or so, we've run up against many design problems in wasi-common. Many of these problems ended up being so fundamental that a rewrite, as prolonged as it was, ended up being more tractable than incremental changes.

The Table

wasi-common now has a Table type that is designed to map u32 handles to resources. The table is now part of the public interface to a WasiCtx - it is reference counted so that it can be shared beyond a WasiCtx with other WASI proposals (e.g. wasi-crypto and wasi-nn) to manage their resources. Elements in the Table are Any typed.

The Table type is intended to model how the Interface Types concept of Resources is shaping up. Right now it is just an approximation.

The WasiFile and WasiDir traits

The WASI specification only defines one handle type, fd, on which all operations on both files and directories (aka dirfds) are defined. We believe this is a design mistake, and are architecting wasi-common to make this straightforward to correct in future snapshots of WASI. Wasi-common internally treats files and directories as two distinct resource types in the table - Box<dyn WasiFile> and Box<dyn WasiDir>. The snapshot 0 and 1 interfaces via fd will attempt to downcast a table element to one or both of these interfaces depending on what is appropriate - e.g. fd_close operates on both files and directories, fd_read only operates on files, and fd_readdir only operates on directories.

The WasiFile and WasiDir traits are defined by wasi-common in terms of types defined directly in the crate's source code (I decided it should NOT those generated by the wiggle proc macros, see snapshot architecture below), as well as the cap_std::time family of types. And, importantly, wasi-common itself provides no implementation of WasiDir, and only two trivial implementations of WasiFile on the crate::pipe::{ReadPipe, WritePipe} types, which in turn just delegate to std::io::{Read, Write}. In order for wasi-common to access the local filesystem at all, you need to provide WasiFile and WasiDir impls through either the new wasi-cap-std-sync crate found at crates/wasi-common/cap-std-sync - see the section on that crate below - or by providing your own implementation from elsewhere.

This design makes it possible for wasi-common embedders to statically reason about access to the local filesystem by examining what impls are linked into an application. We found that this separation of concerns also makes it pretty enjoyable to write alternative implementations, e.g. a virtual filesystem (which will land in a future PR).

Traits for the rest of WASI's features

Other aspects of a WASI implementation are not yet considered resources and accessed by handle. We plan to correct this design deficiency in WASI in the future, but for now we have designed the following traits to provide embedders with the same sort of implementation flexibility they get with WasiFile/WasiDir:

Users can provide implementations of each of these interfaces to the WasiCtx::builder(...) function. The wasi_cap_std_sync::WasiCtxBuilder::new() function uses this public interface to plug in its own implementations of each of these resources.

Snapshot architecture

One goal we've had for a while, but not quite met, is for multiple WASI snapshots to provide an interface to the same underlying WasiCtx. This provides us a path to evolve WASI by allowing the same WASI Command to import functions from different snapshots - e.g. the user could use Rust's std which imports snapshot 1, but also depend directly on the wasi crate which imports some future snapshot 2. Right now, this amounts to supporting snapshot 1 and "snapshot 0" aka wasi_unstable at once.

The architectural rules for snapshots are:

The wasi_common::Error type

wasi_common::Error is now anyhow::Error. wasi_common::snapshots::preview_1 contains all of the logic for transforming an Error into an Errno, by downcasting the error into any of

The wasi_common::ErrorExt trait provides human-friendly constructors for the wasi_common::ErrorKind variants .

If you throw an error that does not downcast to one of those, it will turn into a wiggle::Trap and terminate execution.

The real value of using anyhow::Error here is being able to use anyhow::Result::context to aid in debugging of errors.

The wasi-cap-std-sync implementation of the WASI traits

The wasi-cap-std-sync crate provides impl of WasiFile and WasiDir in terms of cap_std::fs::{File, Dir}. These types provide sandboxed access to the local filesystem on both Unix and Windows.

The entire design story of cap-std is much bigger than we can address here, but in short, its functionality replaces all of the wasi_common::sys hierarchy, as well as the yanix / winx crates. All syscalls are hidden behind the cap-std hierarchy, with the lone exception of the sched implementation, which is provided for both unix and windows in separate modules.

Any wasi_common::{WasiCtx, WasiCtxBuilder} is interoperable with the wasi-cap-std-sync crate. However, for convenience, wasi-cap-std-sync provides its own WasiCtxBuilder that hooks up to all of the crate's components, i.e. it fills in all of the arguments to WasiCtx::builder(...), presents preopen_dir in terms of cap_std::fs::Dir, and provides convenience methods for inheriting the parent process's stdio, args, and env.

The only place we expect to run into long-term compatibility issues between wasi-cap-std-sync and the other impl crates that will come later is in the Sched abstraction. Once we can build an async scheduler based on Rust Futures, async impls will be able to interoperate, but the synchronous scheduler depends on downcasting the WasiFile type down to concrete types it knows about (which in turn impl AsRawFd for passing to unix poll, or the analogous traits on windows).

Why is this impl suffixed with -sync? https://github.com/bytecodealliance/wasmtime/pull/2434 async is coming soon! The async impl may end up depending on tokio or other relatively heavy deps, so we will retain a sync implementation so that wasi-common users have an option of not pulling in an async runtime.

Improving the WASI test suite

The bulk of wasi-common's test suite lives at crates/test-programs. This test suite was extremely useful for guiding this rewrite. We improved the test suite in numerous ways, including

view this post on Zulip Wasmtime GitHub notifications bot (Feb 03 2021 at 15:57):

jedisct1 submitted PR Review.

view this post on Zulip Wasmtime GitHub notifications bot (Feb 03 2021 at 15:57):

jedisct1 created PR Review Comment:

Incrementing the key is a very good thing; it helps avoid reuse and catch bugs (and we don't have to deal with select(2)).

But why not wrap on overflow? If entries are properly closed after use, there wouldn't be anything wrong with that, especially since the map is checked right after (even though it is not necessary before a wrap).

view this post on Zulip Wasmtime GitHub notifications bot (Feb 03 2021 at 16:00):

jedisct1 submitted PR Review.

view this post on Zulip Wasmtime GitHub notifications bot (Feb 03 2021 at 16:00):

jedisct1 created PR Review Comment:

What are the thread-safety guaranty requirements?

Couldn't multiple threads access the same key concurrently?

Instead of Any, wouldn't it be safer to enforce Any + Send + Sync?

view this post on Zulip Wasmtime GitHub notifications bot (Feb 03 2021 at 19:07):

pchickey submitted PR Review.

view this post on Zulip Wasmtime GitHub notifications bot (Feb 03 2021 at 19:07):

pchickey created PR Review Comment:

A Table should only be associated with a single wasmtime::Store, which is not Send or Sync. So, I made no attempt to provide any thread-safety guarantees.

view this post on Zulip Wasmtime GitHub notifications bot (Feb 03 2021 at 19:09):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

This PR is a complete rewrite of the wasi-common crate. It uses @sunfishcode 's new cap-std family of crates to provide a sandboxed implementation of WASI on the local filesystem.

Note that this is a breaking change for all users of WASI with Wasmtime, except for the C API.

Re-architecting wasi-common

Over the past year or so, we've run up against many design problems in wasi-common. Many of these problems ended up being so fundamental that a rewrite, as prolonged as it was, ended up being more tractable than incremental changes.

The Table

wasi-common now has a Table type that is designed to map u32 handles to resources. The table is now part of the public interface to a WasiCtx - it is reference counted so that it can be shared beyond a WasiCtx with other WASI proposals (e.g. wasi-crypto and wasi-nn) to manage their resources. Elements in the Table are Any typed.

The Table type is intended to model how the Interface Types concept of Resources is shaping up. Right now it is just an approximation.

The WasiFile and WasiDir traits

The WASI specification only defines one handle type, fd, on which all operations on both files and directories (aka dirfds) are defined. We believe this is a design mistake, and are architecting wasi-common to make this straightforward to correct in future snapshots of WASI. Wasi-common internally treats files and directories as two distinct resource types in the table - Box<dyn WasiFile> and Box<dyn WasiDir>. The snapshot 0 and 1 interfaces via fd will attempt to downcast a table element to one or both of these interfaces depending on what is appropriate - e.g. fd_close operates on both files and directories, fd_read only operates on files, and fd_readdir only operates on directories.

The WasiFile and WasiDir traits are defined by wasi-common in terms of types defined directly in the crate's source code (I decided it should NOT those generated by the wiggle proc macros, see snapshot architecture below), as well as the cap_std::time family of types. And, importantly, wasi-common itself provides no implementation of WasiDir, and only two trivial implementations of WasiFile on the crate::pipe::{ReadPipe, WritePipe} types, which in turn just delegate to std::io::{Read, Write}. In order for wasi-common to access the local filesystem at all, you need to provide WasiFile and WasiDir impls through either the new wasi-cap-std-sync crate found at crates/wasi-common/cap-std-sync - see the section on that crate below - or by providing your own implementation from elsewhere.

This design makes it possible for wasi-common embedders to statically reason about access to the local filesystem by examining what impls are linked into an application. We found that this separation of concerns also makes it pretty enjoyable to write alternative implementations, e.g. a virtual filesystem (which will land in a future PR).

Traits for the rest of WASI's features

Other aspects of a WASI implementation are not yet considered resources and accessed by handle. We plan to correct this design deficiency in WASI in the future, but for now we have designed the following traits to provide embedders with the same sort of implementation flexibility they get with WasiFile/WasiDir:

Users can provide implementations of each of these interfaces to the WasiCtx::builder(...) function. The wasi_cap_std_sync::WasiCtxBuilder::new() function uses this public interface to plug in its own implementations of each of these resources.

Snapshot architecture

One goal we've had for a while, but not quite met, is for multiple WASI snapshots to provide an interface to the same underlying WasiCtx. This provides us a path to evolve WASI by allowing the same WASI Command to import functions from different snapshots - e.g. the user could use Rust's std which imports snapshot 1, but also depend directly on the wasi crate which imports some future snapshot 2. Right now, this amounts to supporting snapshot 1 and "snapshot 0" aka wasi_unstable at once.

The architectural rules for snapshots are:

The wasi_common::Error type

wasi_common::Error is now anyhow::Error. wasi_common::snapshots::preview_1 contains all of the logic for transforming an Error into an Errno, by downcasting the error into any of

The wasi_common::ErrorExt trait provides human-friendly constructors for the wasi_common::ErrorKind variants .

If you throw an error that does not downcast to one of those, it will turn into a wiggle::Trap and terminate execution.

The real value of using anyhow::Error here is being able to use anyhow::Result::context to aid in debugging of errors.

The wasi-cap-std-sync implementation of the WASI traits

The wasi-cap-std-sync crate provides impl of WasiFile and WasiDir in terms of cap_std::fs::{File, Dir}. These types provide sandboxed access to the local filesystem on both Unix and Windows.

The entire design story of cap-std is much bigger than we can address here, but in short, its functionality replaces all of the wasi_common::sys hierarchy, as well as the yanix / winx crates. All syscalls are hidden behind the cap-std hierarchy, with the lone exception of the sched implementation, which is provided for both unix and windows in separate modules.

Any wasi_common::{WasiCtx, WasiCtxBuilder} is interoperable with the wasi-cap-std-sync crate. However, for convenience, wasi-cap-std-sync provides its own WasiCtxBuilder that hooks up to all of the crate's components, i.e. it fills in all of the arguments to WasiCtx::builder(...), presents preopen_dir in terms of cap_std::fs::Dir, and provides convenience methods for inheriting the parent process's stdio, args, and env.

The only place we expect to run into long-term compatibility issues between wasi-cap-std-sync and the other impl crates that will come later is in the Sched abstraction. Once we can build an async scheduler based on Rust Futures, async impls will be able to interoperate, but the synchronous scheduler depends on downcasting the WasiFile type down to concrete types it knows about (which in turn impl AsRawFd for passing to unix poll, or the analogous traits on windows).

Why is this impl suffixed with -sync? https://github.com/bytecodealliance/wasmtime/pull/2434 async is coming soon! The async impl may end up depending on tokio or other relatively heavy deps, so we will retain a sync implementation so that wasi-common users have an option of not pulling in an async runtime.

Improving the WASI test suite

The bulk of wasi-common's test suite lives at crates/test-programs. This test suite was extremely useful for guiding this rewrite. We improved the test suite in numerous ways, including

view this post on Zulip Wasmtime GitHub notifications bot (Feb 03 2021 at 19:09):

pchickey submitted PR Review.

view this post on Zulip Wasmtime GitHub notifications bot (Feb 03 2021 at 19:09):

pchickey created PR Review Comment:

Thanks, I fixed this to wrap on overflow, and only trap when the table is full.

view this post on Zulip Wasmtime GitHub notifications bot (Feb 03 2021 at 19:28):

jedisct1 submitted PR Review.

view this post on Zulip Wasmtime GitHub notifications bot (Feb 03 2021 at 19:28):

jedisct1 created PR Review Comment:

Are descriptors 0/1/2 counted here?

view this post on Zulip Wasmtime GitHub notifications bot (Feb 03 2021 at 19:33):

jedisct1 submitted PR Review.

view this post on Zulip Wasmtime GitHub notifications bot (Feb 03 2021 at 19:33):

jedisct1 created PR Review Comment:

As a side note, it may be useful to:

view this post on Zulip Wasmtime GitHub notifications bot (Feb 03 2021 at 19:35):

pchickey submitted PR Review.

view this post on Zulip Wasmtime GitHub notifications bot (Feb 03 2021 at 19:35):

pchickey created PR Review Comment:

The ctx constructor asserts that descriptors 0/1/2 are populated, so I believe they are counted, though in a different spot.

I agree those features sound useful, but I think they're out of scope for landing the initial version of this.

view this post on Zulip Wasmtime GitHub notifications bot (Feb 03 2021 at 19:39):

jedisct1 submitted PR Review.

view this post on Zulip Wasmtime GitHub notifications bot (Feb 03 2021 at 19:39):

jedisct1 created PR Review Comment:

So a handle will never be shared by multiple threads?

Is this a requirement of the WebAssembly threading proposal, or a temporary limitation in Wasmtime?

More generally, should hostcalls assume that a resource will never be shared?

view this post on Zulip Wasmtime GitHub notifications bot (Feb 03 2021 at 20:00):

pchickey submitted PR Review.

view this post on Zulip Wasmtime GitHub notifications bot (Feb 03 2021 at 20:00):

pchickey created PR Review Comment:

Right, a handle will never be shared between threads. It is a limitation of Wasmtime until we choose to implement a threading proposal.

If a hostcall needs to assume a resource is shared between multiple Stores running in separate threads, it can do its own internal arc/mutex wrapping inside the resource.

view this post on Zulip Wasmtime GitHub notifications bot (Feb 03 2021 at 22:27):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

This PR is a complete rewrite of the wasi-common crate. It uses @sunfishcode 's new cap-std family of crates to provide a sandboxed implementation of WASI on the local filesystem.

Note that this is a breaking change for all users of WASI with Wasmtime, except for the C API.

Re-architecting wasi-common

Over the past year or so, we've run up against many design problems in wasi-common. Many of these problems ended up being so fundamental that a rewrite, as prolonged as it was, ended up being more tractable than incremental changes.

The Table

wasi-common now has a Table type that is designed to map u32 handles to resources. The table is now part of the public interface to a WasiCtx - it is reference counted so that it can be shared beyond a WasiCtx with other WASI proposals (e.g. wasi-crypto and wasi-nn) to manage their resources. Elements in the Table are Any typed.

The Table type is intended to model how the Interface Types concept of Resources is shaping up. Right now it is just an approximation.

The WasiFile and WasiDir traits

The WASI specification only defines one handle type, fd, on which all operations on both files and directories (aka dirfds) are defined. We believe this is a design mistake, and are architecting wasi-common to make this straightforward to correct in future snapshots of WASI. Wasi-common internally treats files and directories as two distinct resource types in the table - Box<dyn WasiFile> and Box<dyn WasiDir>. The snapshot 0 and 1 interfaces via fd will attempt to downcast a table element to one or both of these interfaces depending on what is appropriate - e.g. fd_close operates on both files and directories, fd_read only operates on files, and fd_readdir only operates on directories.

The WasiFile and WasiDir traits are defined by wasi-common in terms of types defined directly in the crate's source code (I decided it should NOT those generated by the wiggle proc macros, see snapshot architecture below), as well as the cap_std::time family of types. And, importantly, wasi-common itself provides no implementation of WasiDir, and only two trivial implementations of WasiFile on the crate::pipe::{ReadPipe, WritePipe} types, which in turn just delegate to std::io::{Read, Write}. In order for wasi-common to access the local filesystem at all, you need to provide WasiFile and WasiDir impls through either the new wasi-cap-std-sync crate found at crates/wasi-common/cap-std-sync - see the section on that crate below - or by providing your own implementation from elsewhere.

This design makes it possible for wasi-common embedders to statically reason about access to the local filesystem by examining what impls are linked into an application. We found that this separation of concerns also makes it pretty enjoyable to write alternative implementations, e.g. a virtual filesystem (which will land in a future PR).

Traits for the rest of WASI's features

Other aspects of a WASI implementation are not yet considered resources and accessed by handle. We plan to correct this design deficiency in WASI in the future, but for now we have designed the following traits to provide embedders with the same sort of implementation flexibility they get with WasiFile/WasiDir:

Users can provide implementations of each of these interfaces to the WasiCtx::builder(...) function. The wasi_cap_std_sync::WasiCtxBuilder::new() function uses this public interface to plug in its own implementations of each of these resources.

Snapshot architecture

One goal we've had for a while, but not quite met, is for multiple WASI snapshots to provide an interface to the same underlying WasiCtx. This provides us a path to evolve WASI by allowing the same WASI Command to import functions from different snapshots - e.g. the user could use Rust's std which imports snapshot 1, but also depend directly on the wasi crate which imports some future snapshot 2. Right now, this amounts to supporting snapshot 1 and "snapshot 0" aka wasi_unstable at once.

The architectural rules for snapshots are:

The wasi_common::Error type

wasi_common::Error is now anyhow::Error. wasi_common::snapshots::preview_1 contains all of the logic for transforming an Error into an Errno, by downcasting the error into any of

The wasi_common::ErrorExt trait provides human-friendly constructors for the wasi_common::ErrorKind variants .

If you throw an error that does not downcast to one of those, it will turn into a wiggle::Trap and terminate execution.

The real value of using anyhow::Error here is being able to use anyhow::Result::context to aid in debugging of errors.

The wasi-cap-std-sync implementation of the WASI traits

The wasi-cap-std-sync crate provides impl of WasiFile and WasiDir in terms of cap_std::fs::{File, Dir}. These types provide sandboxed access to the local filesystem on both Unix and Windows.

The entire design story of cap-std is much bigger than we can address here, but in short, its functionality replaces all of the wasi_common::sys hierarchy, as well as the yanix / winx crates. All syscalls are hidden behind the cap-std hierarchy, with the lone exception of the sched implementation, which is provided for both unix and windows in separate modules.

Any wasi_common::{WasiCtx, WasiCtxBuilder} is interoperable with the wasi-cap-std-sync crate. However, for convenience, wasi-cap-std-sync provides its own WasiCtxBuilder that hooks up to all of the crate's components, i.e. it fills in all of the arguments to WasiCtx::builder(...), presents preopen_dir in terms of cap_std::fs::Dir, and provides convenience methods for inheriting the parent process's stdio, args, and env.

The only place we expect to run into long-term compatibility issues between wasi-cap-std-sync and the other impl crates that will come later is in the Sched abstraction. Once we can build an async scheduler based on Rust Futures, async impls will be able to interoperate, but the synchronous scheduler depends on downcasting the WasiFile type down to concrete types it knows about (which in turn impl AsRawFd for passing to unix poll, or the analogous traits on windows).

Why is this impl suffixed with -sync? https://github.com/bytecodealliance/wasmtime/pull/2434 async is coming soon! The async impl may end up depending on tokio or other relatively heavy deps, so we will retain a sync implementation so that wasi-common users have an option of not pulling in an async runtime.

Improving the WASI test suite

The bulk of wasi-common's test suite lives at crates/test-programs. This test suite was extremely useful for guiding this rewrite. We improved the test suite in numerous ways, including

view this post on Zulip Wasmtime GitHub notifications bot (Feb 03 2021 at 22:55):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

This PR is a complete rewrite of the wasi-common crate. It uses @sunfishcode 's new cap-std family of crates to provide a sandboxed implementation of WASI on the local filesystem.

Note that this is a breaking change for all users of WASI with Wasmtime, except for the C API.

Re-architecting wasi-common

Over the past year or so, we've run up against many design problems in wasi-common. Many of these problems ended up being so fundamental that a rewrite, as prolonged as it was, ended up being more tractable than incremental changes.

The Table

wasi-common now has a Table type that is designed to map u32 handles to resources. The table is now part of the public interface to a WasiCtx - it is reference counted so that it can be shared beyond a WasiCtx with other WASI proposals (e.g. wasi-crypto and wasi-nn) to manage their resources. Elements in the Table are Any typed.

The Table type is intended to model how the Interface Types concept of Resources is shaping up. Right now it is just an approximation.

The WasiFile and WasiDir traits

The WASI specification only defines one handle type, fd, on which all operations on both files and directories (aka dirfds) are defined. We believe this is a design mistake, and are architecting wasi-common to make this straightforward to correct in future snapshots of WASI. Wasi-common internally treats files and directories as two distinct resource types in the table - Box<dyn WasiFile> and Box<dyn WasiDir>. The snapshot 0 and 1 interfaces via fd will attempt to downcast a table element to one or both of these interfaces depending on what is appropriate - e.g. fd_close operates on both files and directories, fd_read only operates on files, and fd_readdir only operates on directories.

The WasiFile and WasiDir traits are defined by wasi-common in terms of types defined directly in the crate's source code (I decided it should NOT those generated by the wiggle proc macros, see snapshot architecture below), as well as the cap_std::time family of types. And, importantly, wasi-common itself provides no implementation of WasiDir, and only two trivial implementations of WasiFile on the crate::pipe::{ReadPipe, WritePipe} types, which in turn just delegate to std::io::{Read, Write}. In order for wasi-common to access the local filesystem at all, you need to provide WasiFile and WasiDir impls through either the new wasi-cap-std-sync crate found at crates/wasi-common/cap-std-sync - see the section on that crate below - or by providing your own implementation from elsewhere.

This design makes it possible for wasi-common embedders to statically reason about access to the local filesystem by examining what impls are linked into an application. We found that this separation of concerns also makes it pretty enjoyable to write alternative implementations, e.g. a virtual filesystem (which will land in a future PR).

Traits for the rest of WASI's features

Other aspects of a WASI implementation are not yet considered resources and accessed by handle. We plan to correct this design deficiency in WASI in the future, but for now we have designed the following traits to provide embedders with the same sort of implementation flexibility they get with WasiFile/WasiDir:

Users can provide implementations of each of these interfaces to the WasiCtx::builder(...) function. The wasi_cap_std_sync::WasiCtxBuilder::new() function uses this public interface to plug in its own implementations of each of these resources.

Snapshot architecture

One goal we've had for a while, but not quite met, is for multiple WASI snapshots to provide an interface to the same underlying WasiCtx. This provides us a path to evolve WASI by allowing the same WASI Command to import functions from different snapshots - e.g. the user could use Rust's std which imports snapshot 1, but also depend directly on the wasi crate which imports some future snapshot 2. Right now, this amounts to supporting snapshot 1 and "snapshot 0" aka wasi_unstable at once.

The architectural rules for snapshots are:

The wasi_common::Error type

wasi_common::Error is now anyhow::Error. wasi_common::snapshots::preview_1 contains all of the logic for transforming an Error into an Errno, by downcasting the error into any of

The wasi_common::ErrorExt trait provides human-friendly constructors for the wasi_common::ErrorKind variants .

If you throw an error that does not downcast to one of those, it will turn into a wiggle::Trap and terminate execution.

The real value of using anyhow::Error here is being able to use anyhow::Result::context to aid in debugging of errors.

The wasi-cap-std-sync implementation of the WASI traits

The wasi-cap-std-sync crate provides impl of WasiFile and WasiDir in terms of cap_std::fs::{File, Dir}. These types provide sandboxed access to the local filesystem on both Unix and Windows.

The entire design story of cap-std is much bigger than we can address here, but in short, its functionality replaces all of the wasi_common::sys hierarchy, as well as the yanix / winx crates. All syscalls are hidden behind the cap-std hierarchy, with the lone exception of the sched implementation, which is provided for both unix and windows in separate modules.

Any wasi_common::{WasiCtx, WasiCtxBuilder} is interoperable with the wasi-cap-std-sync crate. However, for convenience, wasi-cap-std-sync provides its own WasiCtxBuilder that hooks up to all of the crate's components, i.e. it fills in all of the arguments to WasiCtx::builder(...), presents preopen_dir in terms of cap_std::fs::Dir, and provides convenience methods for inheriting the parent process's stdio, args, and env.

The only place we expect to run into long-term compatibility issues between wasi-cap-std-sync and the other impl crates that will come later is in the Sched abstraction. Once we can build an async scheduler based on Rust Futures, async impls will be able to interoperate, but the synchronous scheduler depends on downcasting the WasiFile type down to concrete types it knows about (which in turn impl AsRawFd for passing to unix poll, or the analogous traits on windows).

Why is this impl suffixed with -sync? https://github.com/bytecodealliance/wasmtime/pull/2434 async is coming soon! The async impl may end up depending on tokio or other relatively heavy deps, so we will retain a sync implementation so that wasi-common users have an option of not pulling in an async runtime.

Improving the WASI test suite

The bulk of wasi-common's test suite lives at crates/test-programs. This test suite was extremely useful for guiding this rewrite. We improved the test suite in numerous ways, including

view this post on Zulip Wasmtime GitHub notifications bot (Feb 03 2021 at 23:11):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

This PR is a complete rewrite of the wasi-common crate. It uses @sunfishcode 's new cap-std family of crates to provide a sandboxed implementation of WASI on the local filesystem.

Note that this is a breaking change for all users of WASI with Wasmtime, except for the C API.

Re-architecting wasi-common

Over the past year or so, we've run up against many design problems in wasi-common. Many of these problems ended up being so fundamental that a rewrite, as prolonged as it was, ended up being more tractable than incremental changes.

The Table

wasi-common now has a Table type that is designed to map u32 handles to resources. The table is now part of the public interface to a WasiCtx - it is reference counted so that it can be shared beyond a WasiCtx with other WASI proposals (e.g. wasi-crypto and wasi-nn) to manage their resources. Elements in the Table are Any typed.

The Table type is intended to model how the Interface Types concept of Resources is shaping up. Right now it is just an approximation.

The WasiFile and WasiDir traits

The WASI specification only defines one handle type, fd, on which all operations on both files and directories (aka dirfds) are defined. We believe this is a design mistake, and are architecting wasi-common to make this straightforward to correct in future snapshots of WASI. Wasi-common internally treats files and directories as two distinct resource types in the table - Box<dyn WasiFile> and Box<dyn WasiDir>. The snapshot 0 and 1 interfaces via fd will attempt to downcast a table element to one or both of these interfaces depending on what is appropriate - e.g. fd_close operates on both files and directories, fd_read only operates on files, and fd_readdir only operates on directories.

The WasiFile and WasiDir traits are defined by wasi-common in terms of types defined directly in the crate's source code (I decided it should NOT those generated by the wiggle proc macros, see snapshot architecture below), as well as the cap_std::time family of types. And, importantly, wasi-common itself provides no implementation of WasiDir, and only two trivial implementations of WasiFile on the crate::pipe::{ReadPipe, WritePipe} types, which in turn just delegate to std::io::{Read, Write}. In order for wasi-common to access the local filesystem at all, you need to provide WasiFile and WasiDir impls through either the new wasi-cap-std-sync crate found at crates/wasi-common/cap-std-sync - see the section on that crate below - or by providing your own implementation from elsewhere.

This design makes it possible for wasi-common embedders to statically reason about access to the local filesystem by examining what impls are linked into an application. We found that this separation of concerns also makes it pretty enjoyable to write alternative implementations, e.g. a virtual filesystem (which will land in a future PR).

Traits for the rest of WASI's features

Other aspects of a WASI implementation are not yet considered resources and accessed by handle. We plan to correct this design deficiency in WASI in the future, but for now we have designed the following traits to provide embedders with the same sort of implementation flexibility they get with WasiFile/WasiDir:

Users can provide implementations of each of these interfaces to the WasiCtx::builder(...) function. The wasi_cap_std_sync::WasiCtxBuilder::new() function uses this public interface to plug in its own implementations of each of these resources.

Snapshot architecture

One goal we've had for a while, but not quite met, is for multiple WASI snapshots to provide an interface to the same underlying WasiCtx. This provides us a path to evolve WASI by allowing the same WASI Command to import functions from different snapshots - e.g. the user could use Rust's std which imports snapshot 1, but also depend directly on the wasi crate which imports some future snapshot 2. Right now, this amounts to supporting snapshot 1 and "snapshot 0" aka wasi_unstable at once.

The architectural rules for snapshots are:

The wasi_common::Error type

wasi_common::Error is now anyhow::Error. wasi_common::snapshots::preview_1 contains all of the logic for transforming an Error into an Errno, by downcasting the error into any of

The wasi_common::ErrorExt trait provides human-friendly constructors for the wasi_common::ErrorKind variants .

If you throw an error that does not downcast to one of those, it will turn into a wiggle::Trap and terminate execution.

The real value of using anyhow::Error here is being able to use anyhow::Result::context to aid in debugging of errors.

The wasi-cap-std-sync implementation of the WASI traits

The wasi-cap-std-sync crate provides impl of WasiFile and WasiDir in terms of cap_std::fs::{File, Dir}. These types provide sandboxed access to the local filesystem on both Unix and Windows.

The entire design story of cap-std is much bigger than we can address here, but in short, its functionality replaces all of the wasi_common::sys hierarchy, as well as the yanix / winx crates. All syscalls are hidden behind the cap-std hierarchy, with the lone exception of the sched implementation, which is provided for both unix and windows in separate modules.

Any wasi_common::{WasiCtx, WasiCtxBuilder} is interoperable with the wasi-cap-std-sync crate. However, for convenience, wasi-cap-std-sync provides its own WasiCtxBuilder that hooks up to all of the crate's components, i.e. it fills in all of the arguments to WasiCtx::builder(...), presents preopen_dir in terms of cap_std::fs::Dir, and provides convenience methods for inheriting the parent process's stdio, args, and env.

The only place we expect to run into long-term compatibility issues between wasi-cap-std-sync and the other impl crates that will come later is in the Sched abstraction. Once we can build an async scheduler based on Rust Futures, async impls will be able to interoperate, but the synchronous scheduler depends on downcasting the WasiFile type down to concrete types it knows about (which in turn impl AsRawFd for passing to unix poll, or the analogous traits on windows).

Why is this impl suffixed with -sync? https://github.com/bytecodealliance/wasmtime/pull/2434 async is coming soon! The async impl may end up depending on tokio or other relatively heavy deps, so we will retain a sync implementation so that wasi-common users have an option of not pulling in an async runtime.

Improving the WASI test suite

The bulk of wasi-common's test suite lives at crates/test-programs. This test suite was extremely useful for guiding this rewrite. We improved the test suite in numerous ways, including

view this post on Zulip Wasmtime GitHub notifications bot (Feb 03 2021 at 23:12):

pchickey edited PR #2487 from pch/wasi_common_cap_std to main:

This PR is a complete rewrite of the wasi-common crate. It uses @sunfishcode 's new cap-std family of crates to provide a sandboxed implementation of WASI on the local filesystem.

Note that this is a breaking change for all users of WASI with Wasmtime, except for the C API.

Re-architecting wasi-common

Over the past year or so, we've run up against many design problems in wasi-common. Many of these problems ended up being so fundamental that a rewrite, as prolonged as it was, ended up being more tractable than incremental changes.

The Table

wasi-common now has a Table type that is designed to map u32 handles to resources. The table is now part of the public interface to a WasiCtx - it is reference counted so that it can be shared beyond a WasiCtx with other WASI proposals (e.g. wasi-crypto and wasi-nn) to manage their resources. Elements in the Table are Any typed.

The Table type is intended to model how the Interface Types concept of Resources is shaping up. Right now it is just an approximation.

The WasiFile and WasiDir traits

The WASI specification only defines one handle type, fd, on which all operations on both files and directories (aka dirfds) are defined. We believe this is a design mistake, and are architecting wasi-common to make this straightforward to correct in future snapshots of WASI. Wasi-common internally treats files and directories as two distinct resource types in the table - Box<dyn WasiFile> and Box<dyn WasiDir>. The snapshot 0 and 1 interfaces via fd will attempt to downcast a table element to one or both of these interfaces depending on what is appropriate - e.g. fd_close operates on both files and directories, fd_read only operates on files, and fd_readdir only operates on directories.

The WasiFile and WasiDir traits are defined by wasi-common in terms of types defined directly in the crate's source code (I decided it should NOT those generated by the wiggle proc macros, see snapshot architecture below), as well as the cap_std::time family of types. And, importantly, wasi-common itself provides no implementation of WasiDir, and only two trivial implementations of WasiFile on the crate::pipe::{ReadPipe, WritePipe} types, which in turn just delegate to std::io::{Read, Write}. In order for wasi-common to access the local filesystem at all, you need to provide WasiFile and WasiDir impls through either the new wasi-cap-std-sync crate found at crates/wasi-common/cap-std-sync - see the section on that crate below - or by providing your own implementation from elsewhere.

This design makes it possible for wasi-common embedders to statically reason about access to the local filesystem by examining what impls are linked into an application. We found that this separation of concerns also makes it pretty enjoyable to write alternative implementations, e.g. a virtual filesystem (which will land in a future PR).

Traits for the rest of WASI's features

Other aspects of a WASI implementation are not yet considered resources and accessed by handle. We plan to correct this design deficiency in WASI in the future, but for now we have designed the following traits to provide embedders with the same sort of implementation flexibility they get with WasiFile/WasiDir:

Users can provide implementations of each of these interfaces to the WasiCtx::builder(...) function. The wasi_cap_std_sync::WasiCtxBuilder::new() function uses this public interface to plug in its own implementations of each of these resources.

Snapshot architecture

One goal we've had for a while, but not quite met, is for multiple WASI snapshots to provide an interface to the same underlying WasiCtx. This provides us a path to evolve WASI by allowing the same WASI Command to import functions from different snapshots - e.g. the user could use Rust's std which imports snapshot 1, but also depend directly on the wasi crate which imports some future snapshot 2. Right now, this amounts to supporting snapshot 1 and "snapshot 0" aka wasi_unstable at once.

The architectural rules for snapshots are:

The wasi_common::Error type

wasi_common::Error is now anyhow::Error. wasi_common::snapshots::preview_1 contains all of the logic for transforming an Error into an Errno, by downcasting the error into any of

The wasi_common::ErrorExt trait provides human-friendly constructors for the wasi_common::ErrorKind variants .

If you throw an error that does not downcast to one of those, it will turn into a wiggle::Trap and terminate execution.

The real value of using anyhow::Error here is being able to use anyhow::Result::context to aid in debugging of errors.

The wasi-cap-std-sync implementation of the WASI traits

The wasi-cap-std-sync crate provides impl of WasiFile and WasiDir in terms of cap_std::fs::{File, Dir}. These types provide sandboxed access to the local filesystem on both Unix and Windows.

The entire design story of cap-std is much bigger than we can address here, but in short, its functionality replaces all of the wasi_common::sys hierarchy, as well as the yanix / winx crates. All syscalls are hidden behind the cap-std hierarchy, with the lone exception of the sched implementation, which is provided for both unix and windows in separate modules.

Any wasi_common::{WasiCtx, WasiCtxBuilder} is interoperable with the wasi-cap-std-sync crate. However, for convenience, wasi-cap-std-sync provides its own WasiCtxBuilder that hooks up to all of the crate's components, i.e. it fills in all of the arguments to WasiCtx::builder(...), presents preopen_dir in terms of cap_std::fs::Dir, and provides convenience methods for inheriting the parent process's stdio, args, and env.

The only place we expect to run into long-term compatibility issues between wasi-cap-std-sync and the other impl crates that will come later is in the Sched abstraction. Once we can build an async scheduler based on Rust Futures, async impls will be able to interoperate, but the synchronous scheduler depends on downcasting the WasiFile type down to concrete types it knows about (which in turn impl AsRawFd for passing to unix poll, or the analogous traits on windows).

Why is this impl suffixed with -sync? https://github.com/bytecodealliance/wasmtime/pull/2434 async is coming soon! The async impl may end up depending on tokio or other relatively heavy deps, so we will retain a sync implementation so that wasi-common users have an option of not pulling in an async runtime.

Improving the WASI test suite

The bulk of wasi-common's test suite lives at crates/test-programs. This test suite was extremely useful for guiding this rewrite. We improved the test suite in numerous ways, including

view this post on Zulip Wasmtime GitHub notifications bot (Feb 03 2021 at 23:52):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

This PR is a complete rewrite of the wasi-common crate. It uses @sunfishcode 's new cap-std family of crates to provide a sandboxed implementation of WASI on the local filesystem.

Note that this is a breaking change for all users of WASI with Wasmtime, except for the C API.

Re-architecting wasi-common

Over the past year or so, we've run up against many design problems in wasi-common. Many of these problems ended up being so fundamental that a rewrite, as prolonged as it was, ended up being more tractable than incremental changes.

The Table

wasi-common now has a Table type that is designed to map u32 handles to resources. The table is now part of the public interface to a WasiCtx - it is reference counted so that it can be shared beyond a WasiCtx with other WASI proposals (e.g. wasi-crypto and wasi-nn) to manage their resources. Elements in the Table are Any typed.

The Table type is intended to model how the Interface Types concept of Resources is shaping up. Right now it is just an approximation.

The WasiFile and WasiDir traits

The WASI specification only defines one handle type, fd, on which all operations on both files and directories (aka dirfds) are defined. We believe this is a design mistake, and are architecting wasi-common to make this straightforward to correct in future snapshots of WASI. Wasi-common internally treats files and directories as two distinct resource types in the table - Box<dyn WasiFile> and Box<dyn WasiDir>. The snapshot 0 and 1 interfaces via fd will attempt to downcast a table element to one or both of these interfaces depending on what is appropriate - e.g. fd_close operates on both files and directories, fd_read only operates on files, and fd_readdir only operates on directories.

The WasiFile and WasiDir traits are defined by wasi-common in terms of types defined directly in the crate's source code (I decided it should NOT those generated by the wiggle proc macros, see snapshot architecture below), as well as the cap_std::time family of types. And, importantly, wasi-common itself provides no implementation of WasiDir, and only two trivial implementations of WasiFile on the crate::pipe::{ReadPipe, WritePipe} types, which in turn just delegate to std::io::{Read, Write}. In order for wasi-common to access the local filesystem at all, you need to provide WasiFile and WasiDir impls through either the new wasi-cap-std-sync crate found at crates/wasi-common/cap-std-sync - see the section on that crate below - or by providing your own implementation from elsewhere.

This design makes it possible for wasi-common embedders to statically reason about access to the local filesystem by examining what impls are linked into an application. We found that this separation of concerns also makes it pretty enjoyable to write alternative implementations, e.g. a virtual filesystem (which will land in a future PR).

Traits for the rest of WASI's features

Other aspects of a WASI implementation are not yet considered resources and accessed by handle. We plan to correct this design deficiency in WASI in the future, but for now we have designed the following traits to provide embedders with the same sort of implementation flexibility they get with WasiFile/WasiDir:

Users can provide implementations of each of these interfaces to the WasiCtx::builder(...) function. The wasi_cap_std_sync::WasiCtxBuilder::new() function uses this public interface to plug in its own implementations of each of these resources.

Snapshot architecture

One goal we've had for a while, but not quite met, is for multiple WASI snapshots to provide an interface to the same underlying WasiCtx. This provides us a path to evolve WASI by allowing the same WASI Command to import functions from different snapshots - e.g. the user could use Rust's std which imports snapshot 1, but also depend directly on the wasi crate which imports some future snapshot 2. Right now, this amounts to supporting snapshot 1 and "snapshot 0" aka wasi_unstable at once.

The architectural rules for snapshots are:

The wasi_common::Error type

wasi_common::Error is now anyhow::Error. wasi_common::snapshots::preview_1 contains all of the logic for transforming an Error into an Errno, by downcasting the error into any of

The wasi_common::ErrorExt trait provides human-friendly constructors for the wasi_common::ErrorKind variants .

If you throw an error that does not downcast to one of those, it will turn into a wiggle::Trap and terminate execution.

The real value of using anyhow::Error here is being able to use anyhow::Result::context to aid in debugging of errors.

The wasi-cap-std-sync implementation of the WASI traits

The wasi-cap-std-sync crate provides impl of WasiFile and WasiDir in terms of cap_std::fs::{File, Dir}. These types provide sandboxed access to the local filesystem on both Unix and Windows.

The entire design story of cap-std is much bigger than we can address here, but in short, its functionality replaces all of the wasi_common::sys hierarchy, as well as the yanix / winx crates. All syscalls are hidden behind the cap-std hierarchy, with the lone exception of the sched implementation, which is provided for both unix and windows in separate modules.

Any wasi_common::{WasiCtx, WasiCtxBuilder} is interoperable with the wasi-cap-std-sync crate. However, for convenience, wasi-cap-std-sync provides its own WasiCtxBuilder that hooks up to all of the crate's components, i.e. it fills in all of the arguments to WasiCtx::builder(...), presents preopen_dir in terms of cap_std::fs::Dir, and provides convenience methods for inheriting the parent process's stdio, args, and env.

The only place we expect to run into long-term compatibility issues between wasi-cap-std-sync and the other impl crates that will come later is in the Sched abstraction. Once we can build an async scheduler based on Rust Futures, async impls will be able to interoperate, but the synchronous scheduler depends on downcasting the WasiFile type down to concrete types it knows about (which in turn impl AsRawFd for passing to unix poll, or the analogous traits on windows).

Why is this impl suffixed with -sync? https://github.com/bytecodealliance/wasmtime/pull/2434 async is coming soon! The async impl may end up depending on tokio or other relatively heavy deps, so we will retain a sync implementation so that wasi-common users have an option of not pulling in an async runtime.

Improving the WASI test suite

The bulk of wasi-common's test suite lives at crates/test-programs. This test suite was extremely useful for guiding this rewrite. We improved the test suite in numerous ways, including

view this post on Zulip Wasmtime GitHub notifications bot (Feb 04 2021 at 00:17):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

This PR is a complete rewrite of the wasi-common crate. It uses @sunfishcode 's new cap-std family of crates to provide a sandboxed implementation of WASI on the local filesystem.

Note that this is a breaking change for all users of WASI with Wasmtime, except for the C API.

Re-architecting wasi-common

Over the past year or so, we've run up against many design problems in wasi-common. Many of these problems ended up being so fundamental that a rewrite, as prolonged as it was, ended up being more tractable than incremental changes.

The Table

wasi-common now has a Table type that is designed to map u32 handles to resources. The table is now part of the public interface to a WasiCtx - it is reference counted so that it can be shared beyond a WasiCtx with other WASI proposals (e.g. wasi-crypto and wasi-nn) to manage their resources. Elements in the Table are Any typed.

The Table type is intended to model how the Interface Types concept of Resources is shaping up. Right now it is just an approximation.

The WasiFile and WasiDir traits

The WASI specification only defines one handle type, fd, on which all operations on both files and directories (aka dirfds) are defined. We believe this is a design mistake, and are architecting wasi-common to make this straightforward to correct in future snapshots of WASI. Wasi-common internally treats files and directories as two distinct resource types in the table - Box<dyn WasiFile> and Box<dyn WasiDir>. The snapshot 0 and 1 interfaces via fd will attempt to downcast a table element to one or both of these interfaces depending on what is appropriate - e.g. fd_close operates on both files and directories, fd_read only operates on files, and fd_readdir only operates on directories.

The WasiFile and WasiDir traits are defined by wasi-common in terms of types defined directly in the crate's source code (I decided it should NOT those generated by the wiggle proc macros, see snapshot architecture below), as well as the cap_std::time family of types. And, importantly, wasi-common itself provides no implementation of WasiDir, and only two trivial implementations of WasiFile on the crate::pipe::{ReadPipe, WritePipe} types, which in turn just delegate to std::io::{Read, Write}. In order for wasi-common to access the local filesystem at all, you need to provide WasiFile and WasiDir impls through either the new wasi-cap-std-sync crate found at crates/wasi-common/cap-std-sync - see the section on that crate below - or by providing your own implementation from elsewhere.

This design makes it possible for wasi-common embedders to statically reason about access to the local filesystem by examining what impls are linked into an application. We found that this separation of concerns also makes it pretty enjoyable to write alternative implementations, e.g. a virtual filesystem (which will land in a future PR).

Traits for the rest of WASI's features

Other aspects of a WASI implementation are not yet considered resources and accessed by handle. We plan to correct this design deficiency in WASI in the future, but for now we have designed the following traits to provide embedders with the same sort of implementation flexibility they get with WasiFile/WasiDir:

Users can provide implementations of each of these interfaces to the WasiCtx::builder(...) function. The wasi_cap_std_sync::WasiCtxBuilder::new() function uses this public interface to plug in its own implementations of each of these resources.

Snapshot architecture

One goal we've had for a while, but not quite met, is for multiple WASI snapshots to provide an interface to the same underlying WasiCtx. This provides us a path to evolve WASI by allowing the same WASI Command to import functions from different snapshots - e.g. the user could use Rust's std which imports snapshot 1, but also depend directly on the wasi crate which imports some future snapshot 2. Right now, this amounts to supporting snapshot 1 and "snapshot 0" aka wasi_unstable at once.

The architectural rules for snapshots are:

The wasi_common::Error type

wasi_common::Error is now anyhow::Error. wasi_common::snapshots::preview_1 contains all of the logic for transforming an Error into an Errno, by downcasting the error into any of

The wasi_common::ErrorExt trait provides human-friendly constructors for the wasi_common::ErrorKind variants .

If you throw an error that does not downcast to one of those, it will turn into a wiggle::Trap and terminate execution.

The real value of using anyhow::Error here is being able to use anyhow::Result::context to aid in debugging of errors.

The wasi-cap-std-sync implementation of the WASI traits

The wasi-cap-std-sync crate provides impl of WasiFile and WasiDir in terms of cap_std::fs::{File, Dir}. These types provide sandboxed access to the local filesystem on both Unix and Windows.

The entire design story of cap-std is much bigger than we can address here, but in short, its functionality replaces all of the wasi_common::sys hierarchy, as well as the yanix / winx crates. All syscalls are hidden behind the cap-std hierarchy, with the lone exception of the sched implementation, which is provided for both unix and windows in separate modules.

Any wasi_common::{WasiCtx, WasiCtxBuilder} is interoperable with the wasi-cap-std-sync crate. However, for convenience, wasi-cap-std-sync provides its own WasiCtxBuilder that hooks up to all of the crate's components, i.e. it fills in all of the arguments to WasiCtx::builder(...), presents preopen_dir in terms of cap_std::fs::Dir, and provides convenience methods for inheriting the parent process's stdio, args, and env.

The only place we expect to run into long-term compatibility issues between wasi-cap-std-sync and the other impl crates that will come later is in the Sched abstraction. Once we can build an async scheduler based on Rust Futures, async impls will be able to interoperate, but the synchronous scheduler depends on downcasting the WasiFile type down to concrete types it knows about (which in turn impl AsRawFd for passing to unix poll, or the analogous traits on windows).

Why is this impl suffixed with -sync? https://github.com/bytecodealliance/wasmtime/pull/2434 async is coming soon! The async impl may end up depending on tokio or other relatively heavy deps, so we will retain a sync implementation so that wasi-common users have an option of not pulling in an async runtime.

Improving the WASI test suite

The bulk of wasi-common's test suite lives at crates/test-programs. This test suite was extremely useful for guiding this rewrite. We improved the test suite in numerous ways, including

view this post on Zulip Wasmtime GitHub notifications bot (Feb 04 2021 at 01:35):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

This PR is a complete rewrite of the wasi-common crate. It uses @sunfishcode 's new cap-std family of crates to provide a sandboxed implementation of WASI on the local filesystem.

Note that this is a breaking change for all users of WASI with Wasmtime, except for the C API.

Re-architecting wasi-common

Over the past year or so, we've run up against many design problems in wasi-common. Many of these problems ended up being so fundamental that a rewrite, as prolonged as it was, ended up being more tractable than incremental changes.

The Table

wasi-common now has a Table type that is designed to map u32 handles to resources. The table is now part of the public interface to a WasiCtx - it is reference counted so that it can be shared beyond a WasiCtx with other WASI proposals (e.g. wasi-crypto and wasi-nn) to manage their resources. Elements in the Table are Any typed.

The Table type is intended to model how the Interface Types concept of Resources is shaping up. Right now it is just an approximation.

The WasiFile and WasiDir traits

The WASI specification only defines one handle type, fd, on which all operations on both files and directories (aka dirfds) are defined. We believe this is a design mistake, and are architecting wasi-common to make this straightforward to correct in future snapshots of WASI. Wasi-common internally treats files and directories as two distinct resource types in the table - Box<dyn WasiFile> and Box<dyn WasiDir>. The snapshot 0 and 1 interfaces via fd will attempt to downcast a table element to one or both of these interfaces depending on what is appropriate - e.g. fd_close operates on both files and directories, fd_read only operates on files, and fd_readdir only operates on directories.

The WasiFile and WasiDir traits are defined by wasi-common in terms of types defined directly in the crate's source code (I decided it should NOT those generated by the wiggle proc macros, see snapshot architecture below), as well as the cap_std::time family of types. And, importantly, wasi-common itself provides no implementation of WasiDir, and only two trivial implementations of WasiFile on the crate::pipe::{ReadPipe, WritePipe} types, which in turn just delegate to std::io::{Read, Write}. In order for wasi-common to access the local filesystem at all, you need to provide WasiFile and WasiDir impls through either the new wasi-cap-std-sync crate found at crates/wasi-common/cap-std-sync - see the section on that crate below - or by providing your own implementation from elsewhere.

This design makes it possible for wasi-common embedders to statically reason about access to the local filesystem by examining what impls are linked into an application. We found that this separation of concerns also makes it pretty enjoyable to write alternative implementations, e.g. a virtual filesystem (which will land in a future PR).

Traits for the rest of WASI's features

Other aspects of a WASI implementation are not yet considered resources and accessed by handle. We plan to correct this design deficiency in WASI in the future, but for now we have designed the following traits to provide embedders with the same sort of implementation flexibility they get with WasiFile/WasiDir:

Users can provide implementations of each of these interfaces to the WasiCtx::builder(...) function. The wasi_cap_std_sync::WasiCtxBuilder::new() function uses this public interface to plug in its own implementations of each of these resources.

Snapshot architecture

One goal we've had for a while, but not quite met, is for multiple WASI snapshots to provide an interface to the same underlying WasiCtx. This provides us a path to evolve WASI by allowing the same WASI Command to import functions from different snapshots - e.g. the user could use Rust's std which imports snapshot 1, but also depend directly on the wasi crate which imports some future snapshot 2. Right now, this amounts to supporting snapshot 1 and "snapshot 0" aka wasi_unstable at once.

The architectural rules for snapshots are:

The wasi_common::Error type

wasi_common::Error is now anyhow::Error. wasi_common::snapshots::preview_1 contains all of the logic for transforming an Error into an Errno, by downcasting the error into any of

The wasi_common::ErrorExt trait provides human-friendly constructors for the wasi_common::ErrorKind variants .

If you throw an error that does not downcast to one of those, it will turn into a wiggle::Trap and terminate execution.

The real value of using anyhow::Error here is being able to use anyhow::Result::context to aid in debugging of errors.

The wasi-cap-std-sync implementation of the WASI traits

The wasi-cap-std-sync crate provides impl of WasiFile and WasiDir in terms of cap_std::fs::{File, Dir}. These types provide sandboxed access to the local filesystem on both Unix and Windows.

The entire design story of cap-std is much bigger than we can address here, but in short, its functionality replaces all of the wasi_common::sys hierarchy, as well as the yanix / winx crates. All syscalls are hidden behind the cap-std hierarchy, with the lone exception of the sched implementation, which is provided for both unix and windows in separate modules.

Any wasi_common::{WasiCtx, WasiCtxBuilder} is interoperable with the wasi-cap-std-sync crate. However, for convenience, wasi-cap-std-sync provides its own WasiCtxBuilder that hooks up to all of the crate's components, i.e. it fills in all of the arguments to WasiCtx::builder(...), presents preopen_dir in terms of cap_std::fs::Dir, and provides convenience methods for inheriting the parent process's stdio, args, and env.

The only place we expect to run into long-term compatibility issues between wasi-cap-std-sync and the other impl crates that will come later is in the Sched abstraction. Once we can build an async scheduler based on Rust Futures, async impls will be able to interoperate, but the synchronous scheduler depends on downcasting the WasiFile type down to concrete types it knows about (which in turn impl AsRawFd for passing to unix poll, or the analogous traits on windows).

Why is this impl suffixed with -sync? https://github.com/bytecodealliance/wasmtime/pull/2434 async is coming soon! The async impl may end up depending on tokio or other relatively heavy deps, so we will retain a sync implementation so that wasi-common users have an option of not pulling in an async runtime.

Improving the WASI test suite

The bulk of wasi-common's test suite lives at crates/test-programs. This test suite was extremely useful for guiding this rewrite. We improved the test suite in numerous ways, including

view this post on Zulip Wasmtime GitHub notifications bot (Feb 04 2021 at 01:53):

pchickey edited PR #2487 from pch/wasi_common_cap_std to main:

This PR is a complete rewrite of the wasi-common crate. It uses @sunfishcode 's new cap-std family of crates to provide a sandboxed implementation of WASI on the local filesystem.

Note that this is a breaking change for all users of WASI with Wasmtime, except for the C API.

Re-architecting wasi-common

Over the past year or so, we've run up against many design problems in wasi-common. Many of these problems ended up being so fundamental that a rewrite, as prolonged as it was, ended up being more tractable than incremental changes.

The Table

wasi-common now has a Table type that is designed to map u32 handles to resources. The table is now part of the public interface to a WasiCtx - it is reference counted so that it can be shared beyond a WasiCtx with other WASI proposals (e.g. wasi-crypto and wasi-nn) to manage their resources. Elements in the Table are Any typed.

The Table type is intended to model how the Interface Types concept of Resources is shaping up. Right now it is just an approximation.

The WasiFile and WasiDir traits

The WASI specification only defines one handle type, fd, on which all operations on both files and directories (aka dirfds) are defined. We believe this is a design mistake, and are architecting wasi-common to make this straightforward to correct in future snapshots of WASI. Wasi-common internally treats files and directories as two distinct resource types in the table - Box<dyn WasiFile> and Box<dyn WasiDir>. The snapshot 0 and 1 interfaces via fd will attempt to downcast a table element to one or both of these interfaces depending on what is appropriate - e.g. fd_close operates on both files and directories, fd_read only operates on files, and fd_readdir only operates on directories.

The WasiFile and WasiDir traits are defined by wasi-common in terms of types defined directly in the crate's source code (I decided it should NOT those generated by the wiggle proc macros, see snapshot architecture below), as well as the cap_std::time family of types. And, importantly, wasi-common itself provides no implementation of WasiDir, and only two trivial implementations of WasiFile on the crate::pipe::{ReadPipe, WritePipe} types, which in turn just delegate to std::io::{Read, Write}. In order for wasi-common to access the local filesystem at all, you need to provide WasiFile and WasiDir impls through either the new wasi-cap-std-sync crate found at crates/wasi-common/cap-std-sync - see the section on that crate below - or by providing your own implementation from elsewhere.

This design makes it possible for wasi-common embedders to statically reason about access to the local filesystem by examining what impls are linked into an application. We found that this separation of concerns also makes it pretty enjoyable to write alternative implementations, e.g. a virtual filesystem (which will land in a future PR).

Traits for the rest of WASI's features

Other aspects of a WASI implementation are not yet considered resources and accessed by handle. We plan to correct this design deficiency in WASI in the future, but for now we have designed the following traits to provide embedders with the same sort of implementation flexibility they get with WasiFile/WasiDir:

Users can provide implementations of each of these interfaces to the WasiCtx::builder(...) function. The wasi_cap_std_sync::WasiCtxBuilder::new() function uses this public interface to plug in its own implementations of each of these resources.

Snapshot architecture

One goal we've had for a while, but not quite met, is for multiple WASI snapshots to provide an interface to the same underlying WasiCtx. This provides us a path to evolve WASI by allowing the same WASI Command to import functions from different snapshots - e.g. the user could use Rust's std which imports snapshot 1, but also depend directly on the wasi crate which imports some future snapshot 2. Right now, this amounts to supporting snapshot 1 and "snapshot 0" aka wasi_unstable at once.

The architectural rules for snapshots are:

The wasi_common::Error type

wasi_common::Error is now anyhow::Error. wasi_common::snapshots::preview_1 contains all of the logic for transforming an Error into an Errno, by downcasting the error into any of

The wasi_common::ErrorExt trait provides human-friendly constructors for the wasi_common::ErrorKind variants .

If you throw an error that does not downcast to one of those, it will turn into a wiggle::Trap and terminate execution.

The real value of using anyhow::Error here is being able to use anyhow::Result::context to aid in debugging of errors.

The wasi-cap-std-sync implementation of the WASI traits

The wasi-cap-std-sync crate provides impl of WasiFile and WasiDir in terms of cap_std::fs::{File, Dir}. These types provide sandboxed access to the local filesystem on both Unix and Windows.

The entire design story of cap-std is much bigger than we can address here, but in short, its functionality replaces all of the wasi_common::sys hierarchy, as well as the yanix / winx crates. All syscalls are hidden behind the cap-std hierarchy, with the lone exception of the sched implementation, which is provided for both unix and windows in separate modules.

Any wasi_common::{WasiCtx, WasiCtxBuilder} is interoperable with the wasi-cap-std-sync crate. However, for convenience, wasi-cap-std-sync provides its own WasiCtxBuilder that hooks up to all of the crate's components, i.e. it fills in all of the arguments to WasiCtx::builder(...), presents preopen_dir in terms of cap_std::fs::Dir, and provides convenience methods for inheriting the parent process's stdio, args, and env.

The only place we expect to run into long-term compatibility issues between wasi-cap-std-sync and the other impl crates that will come later is in the Sched abstraction. Once we can build an async scheduler based on Rust Futures, async impls will be able to interoperate, but the synchronous scheduler depends on downcasting the WasiFile type down to concrete types it knows about (which in turn impl AsRawFd for passing to unix poll, or the analogous traits on windows).

Why is this impl suffixed with -sync? https://github.com/bytecodealliance/wasmtime/pull/2434 async is coming soon! The async impl may end up depending on tokio or other relatively heavy deps, so we will retain a sync implementation so that wasi-common users have an option of not pulling in an async runtime.

Improving the WASI test suite

The bulk of wasi-common's test suite lives at crates/test-programs. This test suite was extremely useful for guiding this rewrite. We improved the test suite in numerous ways, including

view this post on Zulip Wasmtime GitHub notifications bot (Feb 04 2021 at 01:53):

pchickey edited PR #2487 from pch/wasi_common_cap_std to main:

This PR is a complete rewrite of the wasi-common crate. It uses @sunfishcode 's new cap-std family of crates to provide a sandboxed implementation of WASI on the local filesystem.

Note that this is a breaking change for all users of WASI with Wasmtime, except for the C API.

Re-architecting wasi-common

Over the past year or so, we've run up against many design problems in wasi-common. Many of these problems ended up being so fundamental that a rewrite, as prolonged as it was, ended up being more tractable than incremental changes.

The Table

wasi-common now has a Table type that is designed to map u32 handles to resources. The table is now part of the public interface to a WasiCtx - it is reference counted so that it can be shared beyond a WasiCtx with other WASI proposals (e.g. wasi-crypto and wasi-nn) to manage their resources. Elements in the Table are Any typed.

The Table type is intended to model how the Interface Types concept of Resources is shaping up. Right now it is just an approximation.

The WasiFile and WasiDir traits

The WASI specification only defines one handle type, fd, on which all operations on both files and directories (aka dirfds) are defined. We believe this is a design mistake, and are architecting wasi-common to make this straightforward to correct in future snapshots of WASI. Wasi-common internally treats files and directories as two distinct resource types in the table - Box<dyn WasiFile> and Box<dyn WasiDir>. The snapshot 0 and 1 interfaces via fd will attempt to downcast a table element to one or both of these interfaces depending on what is appropriate - e.g. fd_close operates on both files and directories, fd_read only operates on files, and fd_readdir only operates on directories.

The WasiFile and WasiDir traits are defined by wasi-common in terms of types defined directly in the crate's source code (I decided it should NOT those generated by the wiggle proc macros, see snapshot architecture below), as well as the cap_std::time family of types. And, importantly, wasi-common itself provides no implementation of WasiDir, and only two trivial implementations of WasiFile on the crate::pipe::{ReadPipe, WritePipe} types, which in turn just delegate to std::io::{Read, Write}. In order for wasi-common to access the local filesystem at all, you need to provide WasiFile and WasiDir impls through either the new wasi-cap-std-sync crate found at crates/wasi-common/cap-std-sync - see the section on that crate below - or by providing your own implementation from elsewhere.

This design makes it possible for wasi-common embedders to statically reason about access to the local filesystem by examining what impls are linked into an application. We found that this separation of concerns also makes it pretty enjoyable to write alternative implementations, e.g. a virtual filesystem (which will land in a future PR).

Traits for the rest of WASI's features

Other aspects of a WASI implementation are not yet considered resources and accessed by handle. We plan to correct this design deficiency in WASI in the future, but for now we have designed the following traits to provide embedders with the same sort of implementation flexibility they get with WasiFile/WasiDir:

Users can provide implementations of each of these interfaces to the WasiCtx::builder(...) function. The wasi_cap_std_sync::WasiCtxBuilder::new() function uses this public interface to plug in its own implementations of each of these resources.

Snapshot architecture

One goal we've had for a while, but not quite met, is for multiple WASI snapshots to provide an interface to the same underlying WasiCtx. This provides us a path to evolve WASI by allowing the same WASI Command to import functions from different snapshots - e.g. the user could use Rust's std which imports snapshot 1, but also depend directly on the wasi crate which imports some future snapshot 2. Right now, this amounts to supporting snapshot 1 and "snapshot 0" aka wasi_unstable at once.

The architectural rules for snapshots are:

The wasi_common::Error type

wasi_common::Error is now anyhow::Error. wasi_common::snapshots::preview_1 contains all of the logic for transforming an Error into an Errno, by downcasting the error into any of

The wasi_common::ErrorExt trait provides human-friendly constructors for the wasi_common::ErrorKind variants .

If you throw an error that does not downcast to one of those, it will turn into a wiggle::Trap and terminate execution.

The real value of using anyhow::Error here is being able to use anyhow::Result::context to aid in debugging of errors.

The wasi-cap-std-sync implementation of the WASI traits

The wasi-cap-std-sync crate provides impl of WasiFile and WasiDir in terms of cap_std::fs::{File, Dir}. These types provide sandboxed access to the local filesystem on both Unix and Windows.

The entire design story of cap-std is much bigger than we can address here, but in short, its functionality replaces all of the wasi_common::sys hierarchy, as well as the yanix / winx crates. All syscalls are hidden behind the cap-std hierarchy, with the lone exception of the sched implementation, which is provided for both unix and windows in separate modules.

Any wasi_common::{WasiCtx, WasiCtxBuilder} is interoperable with the wasi-cap-std-sync crate. However, for convenience, wasi-cap-std-sync provides its own WasiCtxBuilder that hooks up to all of the crate's components, i.e. it fills in all of the arguments to WasiCtx::builder(...), presents preopen_dir in terms of cap_std::fs::Dir, and provides convenience methods for inheriting the parent process's stdio, args, and env.

The only place we expect to run into long-term compatibility issues between wasi-cap-std-sync and the other impl crates that will come later is in the Sched abstraction. Once we can build an async scheduler based on Rust Futures, async impls will be able to interoperate, but the synchronous scheduler depends on downcasting the WasiFile type down to concrete types it knows about (which in turn impl AsRawFd for passing to unix poll, or the analogous traits on windows).

Why is this impl suffixed with -sync? https://github.com/bytecodealliance/wasmtime/pull/2434 async is coming soon! The async impl may end up depending on tokio or other relatively heavy deps, so we will retain a sync implementation so that wasi-common users have an option of not pulling in an async runtime.

Improving the WASI test suite

The bulk of wasi-common's test suite lives at crates/test-programs. This test suite was extremely useful for guiding this rewrite. We improved the test suite in numerous ways, including

view this post on Zulip Wasmtime GitHub notifications bot (Feb 04 2021 at 02:04):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

This PR is a complete rewrite of the wasi-common crate. It uses @sunfishcode 's new cap-std family of crates to provide a sandboxed implementation of WASI on the local filesystem.

Note that this is a breaking change for all users of WASI with Wasmtime, except for the C API.

Re-architecting wasi-common

Over the past year or so, we've run up against many design problems in wasi-common. Many of these problems ended up being so fundamental that a rewrite, as prolonged as it was, ended up being more tractable than incremental changes.

The Table

wasi-common now has a Table type that is designed to map u32 handles to resources. The table is now part of the public interface to a WasiCtx - it is reference counted so that it can be shared beyond a WasiCtx with other WASI proposals (e.g. wasi-crypto and wasi-nn) to manage their resources. Elements in the Table are Any typed.

The Table type is intended to model how the Interface Types concept of Resources is shaping up. Right now it is just an approximation.

The WasiFile and WasiDir traits

The WASI specification only defines one handle type, fd, on which all operations on both files and directories (aka dirfds) are defined. We believe this is a design mistake, and are architecting wasi-common to make this straightforward to correct in future snapshots of WASI. Wasi-common internally treats files and directories as two distinct resource types in the table - Box<dyn WasiFile> and Box<dyn WasiDir>. The snapshot 0 and 1 interfaces via fd will attempt to downcast a table element to one or both of these interfaces depending on what is appropriate - e.g. fd_close operates on both files and directories, fd_read only operates on files, and fd_readdir only operates on directories.

The WasiFile and WasiDir traits are defined by wasi-common in terms of types defined directly in the crate's source code (I decided it should NOT those generated by the wiggle proc macros, see snapshot architecture below), as well as the cap_std::time family of types. And, importantly, wasi-common itself provides no implementation of WasiDir, and only two trivial implementations of WasiFile on the crate::pipe::{ReadPipe, WritePipe} types, which in turn just delegate to std::io::{Read, Write}. In order for wasi-common to access the local filesystem at all, you need to provide WasiFile and WasiDir impls through either the new wasi-cap-std-sync crate found at crates/wasi-common/cap-std-sync - see the section on that crate below - or by providing your own implementation from elsewhere.

This design makes it possible for wasi-common embedders to statically reason about access to the local filesystem by examining what impls are linked into an application. We found that this separation of concerns also makes it pretty enjoyable to write alternative implementations, e.g. a virtual filesystem (which will land in a future PR).

Traits for the rest of WASI's features

Other aspects of a WASI implementation are not yet considered resources and accessed by handle. We plan to correct this design deficiency in WASI in the future, but for now we have designed the following traits to provide embedders with the same sort of implementation flexibility they get with WasiFile/WasiDir:

Users can provide implementations of each of these interfaces to the WasiCtx::builder(...) function. The wasi_cap_std_sync::WasiCtxBuilder::new() function uses this public interface to plug in its own implementations of each of these resources.

Snapshot architecture

One goal we've had for a while, but not quite met, is for multiple WASI snapshots to provide an interface to the same underlying WasiCtx. This provides us a path to evolve WASI by allowing the same WASI Command to import functions from different snapshots - e.g. the user could use Rust's std which imports snapshot 1, but also depend directly on the wasi crate which imports some future snapshot 2. Right now, this amounts to supporting snapshot 1 and "snapshot 0" aka wasi_unstable at once.

The architectural rules for snapshots are:

The wasi_common::Error type

wasi_common::Error is now anyhow::Error. wasi_common::snapshots::preview_1 contains all of the logic for transforming an Error into an Errno, by downcasting the error into any of

The wasi_common::ErrorExt trait provides human-friendly constructors for the wasi_common::ErrorKind variants .

If you throw an error that does not downcast to one of those, it will turn into a wiggle::Trap and terminate execution.

The real value of using anyhow::Error here is being able to use anyhow::Result::context to aid in debugging of errors.

The wasi-cap-std-sync implementation of the WASI traits

The wasi-cap-std-sync crate provides impl of WasiFile and WasiDir in terms of cap_std::fs::{File, Dir}. These types provide sandboxed access to the local filesystem on both Unix and Windows.

The entire design story of cap-std is much bigger than we can address here, but in short, its functionality replaces all of the wasi_common::sys hierarchy, as well as the yanix / winx crates. All syscalls are hidden behind the cap-std hierarchy, with the lone exception of the sched implementation, which is provided for both unix and windows in separate modules.

Any wasi_common::{WasiCtx, WasiCtxBuilder} is interoperable with the wasi-cap-std-sync crate. However, for convenience, wasi-cap-std-sync provides its own WasiCtxBuilder that hooks up to all of the crate's components, i.e. it fills in all of the arguments to WasiCtx::builder(...), presents preopen_dir in terms of cap_std::fs::Dir, and provides convenience methods for inheriting the parent process's stdio, args, and env.

The only place we expect to run into long-term compatibility issues between wasi-cap-std-sync and the other impl crates that will come later is in the Sched abstraction. Once we can build an async scheduler based on Rust Futures, async impls will be able to interoperate, but the synchronous scheduler depends on downcasting the WasiFile type down to concrete types it knows about (which in turn impl AsRawFd for passing to unix poll, or the analogous traits on windows).

Why is this impl suffixed with -sync? https://github.com/bytecodealliance/wasmtime/pull/2434 async is coming soon! The async impl may end up depending on tokio or other relatively heavy deps, so we will retain a sync implementation so that wasi-common users have an option of not pulling in an async runtime.

Improving the WASI test suite

The bulk of wasi-common's test suite lives at crates/test-programs. This test suite was extremely useful for guiding this rewrite. We improved the test suite in numerous ways, including

view this post on Zulip Wasmtime GitHub notifications bot (Feb 04 2021 at 18:03):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

This PR is a complete rewrite of the wasi-common crate. It uses @sunfishcode 's new cap-std family of crates to provide a sandboxed implementation of WASI on the local filesystem.

Note that this is a breaking change for all users of WASI with Wasmtime, except for the C API.

Re-architecting wasi-common

Over the past year or so, we've run up against many design problems in wasi-common. Many of these problems ended up being so fundamental that a rewrite, as prolonged as it was, ended up being more tractable than incremental changes.

The Table

wasi-common now has a Table type that is designed to map u32 handles to resources. The table is now part of the public interface to a WasiCtx - it is reference counted so that it can be shared beyond a WasiCtx with other WASI proposals (e.g. wasi-crypto and wasi-nn) to manage their resources. Elements in the Table are Any typed.

The Table type is intended to model how the Interface Types concept of Resources is shaping up. Right now it is just an approximation.

The WasiFile and WasiDir traits

The WASI specification only defines one handle type, fd, on which all operations on both files and directories (aka dirfds) are defined. We believe this is a design mistake, and are architecting wasi-common to make this straightforward to correct in future snapshots of WASI. Wasi-common internally treats files and directories as two distinct resource types in the table - Box<dyn WasiFile> and Box<dyn WasiDir>. The snapshot 0 and 1 interfaces via fd will attempt to downcast a table element to one or both of these interfaces depending on what is appropriate - e.g. fd_close operates on both files and directories, fd_read only operates on files, and fd_readdir only operates on directories.

The WasiFile and WasiDir traits are defined by wasi-common in terms of types defined directly in the crate's source code (I decided it should NOT those generated by the wiggle proc macros, see snapshot architecture below), as well as the cap_std::time family of types. And, importantly, wasi-common itself provides no implementation of WasiDir, and only two trivial implementations of WasiFile on the crate::pipe::{ReadPipe, WritePipe} types, which in turn just delegate to std::io::{Read, Write}. In order for wasi-common to access the local filesystem at all, you need to provide WasiFile and WasiDir impls through either the new wasi-cap-std-sync crate found at crates/wasi-common/cap-std-sync - see the section on that crate below - or by providing your own implementation from elsewhere.

This design makes it possible for wasi-common embedders to statically reason about access to the local filesystem by examining what impls are linked into an application. We found that this separation of concerns also makes it pretty enjoyable to write alternative implementations, e.g. a virtual filesystem (which will land in a future PR).

Traits for the rest of WASI's features

Other aspects of a WASI implementation are not yet considered resources and accessed by handle. We plan to correct this design deficiency in WASI in the future, but for now we have designed the following traits to provide embedders with the same sort of implementation flexibility they get with WasiFile/WasiDir:

Users can provide implementations of each of these interfaces to the WasiCtx::builder(...) function. The wasi_cap_std_sync::WasiCtxBuilder::new() function uses this public interface to plug in its own implementations of each of these resources.

Snapshot architecture

One goal we've had for a while, but not quite met, is for multiple WASI snapshots to provide an interface to the same underlying WasiCtx. This provides us a path to evolve WASI by allowing the same WASI Command to import functions from different snapshots - e.g. the user could use Rust's std which imports snapshot 1, but also depend directly on the wasi crate which imports some future snapshot 2. Right now, this amounts to supporting snapshot 1 and "snapshot 0" aka wasi_unstable at once.

The architectural rules for snapshots are:

The wasi_common::Error type

wasi_common::Error is now anyhow::Error. wasi_common::snapshots::preview_1 contains all of the logic for transforming an Error into an Errno, by downcasting the error into any of

The wasi_common::ErrorExt trait provides human-friendly constructors for the wasi_common::ErrorKind variants .

If you throw an error that does not downcast to one of those, it will turn into a wiggle::Trap and terminate execution.

The real value of using anyhow::Error here is being able to use anyhow::Result::context to aid in debugging of errors.

The wasi-cap-std-sync implementation of the WASI traits

The wasi-cap-std-sync crate provides impl of WasiFile and WasiDir in terms of cap_std::fs::{File, Dir}. These types provide sandboxed access to the local filesystem on both Unix and Windows.

The entire design story of cap-std is much bigger than we can address here, but in short, its functionality replaces all of the wasi_common::sys hierarchy, as well as the yanix / winx crates. All syscalls are hidden behind the cap-std hierarchy, with the lone exception of the sched implementation, which is provided for both unix and windows in separate modules.

Any wasi_common::{WasiCtx, WasiCtxBuilder} is interoperable with the wasi-cap-std-sync crate. However, for convenience, wasi-cap-std-sync provides its own WasiCtxBuilder that hooks up to all of the crate's components, i.e. it fills in all of the arguments to WasiCtx::builder(...), presents preopen_dir in terms of cap_std::fs::Dir, and provides convenience methods for inheriting the parent process's stdio, args, and env.

The only place we expect to run into long-term compatibility issues between wasi-cap-std-sync and the other impl crates that will come later is in the Sched abstraction. Once we can build an async scheduler based on Rust Futures, async impls will be able to interoperate, but the synchronous scheduler depends on downcasting the WasiFile type down to concrete types it knows about (which in turn impl AsRawFd for passing to unix poll, or the analogous traits on windows).

Why is this impl suffixed with -sync? https://github.com/bytecodealliance/wasmtime/pull/2434 async is coming soon! The async impl may end up depending on tokio or other relatively heavy deps, so we will retain a sync implementation so that wasi-common users have an option of not pulling in an async runtime.

Improving the WASI test suite

The bulk of wasi-common's test suite lives at crates/test-programs. This test suite was extremely useful for guiding this rewrite. We improved the test suite in numerous ways, including

view this post on Zulip Wasmtime GitHub notifications bot (Feb 04 2021 at 18:38):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

This PR is a complete rewrite of the wasi-common crate. It uses @sunfishcode 's new cap-std family of crates to provide a sandboxed implementation of WASI on the local filesystem.

Note that this is a breaking change for all users of WASI with Wasmtime, except for the C API.

Re-architecting wasi-common

Over the past year or so, we've run up against many design problems in wasi-common. Many of these problems ended up being so fundamental that a rewrite, as prolonged as it was, ended up being more tractable than incremental changes.

The Table

wasi-common now has a Table type that is designed to map u32 handles to resources. The table is now part of the public interface to a WasiCtx - it is reference counted so that it can be shared beyond a WasiCtx with other WASI proposals (e.g. wasi-crypto and wasi-nn) to manage their resources. Elements in the Table are Any typed.

The Table type is intended to model how the Interface Types concept of Resources is shaping up. Right now it is just an approximation.

The WasiFile and WasiDir traits

The WASI specification only defines one handle type, fd, on which all operations on both files and directories (aka dirfds) are defined. We believe this is a design mistake, and are architecting wasi-common to make this straightforward to correct in future snapshots of WASI. Wasi-common internally treats files and directories as two distinct resource types in the table - Box<dyn WasiFile> and Box<dyn WasiDir>. The snapshot 0 and 1 interfaces via fd will attempt to downcast a table element to one or both of these interfaces depending on what is appropriate - e.g. fd_close operates on both files and directories, fd_read only operates on files, and fd_readdir only operates on directories.

The WasiFile and WasiDir traits are defined by wasi-common in terms of types defined directly in the crate's source code (I decided it should NOT those generated by the wiggle proc macros, see snapshot architecture below), as well as the cap_std::time family of types. And, importantly, wasi-common itself provides no implementation of WasiDir, and only two trivial implementations of WasiFile on the crate::pipe::{ReadPipe, WritePipe} types, which in turn just delegate to std::io::{Read, Write}. In order for wasi-common to access the local filesystem at all, you need to provide WasiFile and WasiDir impls through either the new wasi-cap-std-sync crate found at crates/wasi-common/cap-std-sync - see the section on that crate below - or by providing your own implementation from elsewhere.

This design makes it possible for wasi-common embedders to statically reason about access to the local filesystem by examining what impls are linked into an application. We found that this separation of concerns also makes it pretty enjoyable to write alternative implementations, e.g. a virtual filesystem (which will land in a future PR).

Traits for the rest of WASI's features

Other aspects of a WASI implementation are not yet considered resources and accessed by handle. We plan to correct this design deficiency in WASI in the future, but for now we have designed the following traits to provide embedders with the same sort of implementation flexibility they get with WasiFile/WasiDir:

Users can provide implementations of each of these interfaces to the WasiCtx::builder(...) function. The wasi_cap_std_sync::WasiCtxBuilder::new() function uses this public interface to plug in its own implementations of each of these resources.

Snapshot architecture

One goal we've had for a while, but not quite met, is for multiple WASI snapshots to provide an interface to the same underlying WasiCtx. This provides us a path to evolve WASI by allowing the same WASI Command to import functions from different snapshots - e.g. the user could use Rust's std which imports snapshot 1, but also depend directly on the wasi crate which imports some future snapshot 2. Right now, this amounts to supporting snapshot 1 and "snapshot 0" aka wasi_unstable at once.

The architectural rules for snapshots are:

The wasi_common::Error type

wasi_common::Error is now anyhow::Error. wasi_common::snapshots::preview_1 contains all of the logic for transforming an Error into an Errno, by downcasting the error into any of

The wasi_common::ErrorExt trait provides human-friendly constructors for the wasi_common::ErrorKind variants .

If you throw an error that does not downcast to one of those, it will turn into a wiggle::Trap and terminate execution.

The real value of using anyhow::Error here is being able to use anyhow::Result::context to aid in debugging of errors.

The wasi-cap-std-sync implementation of the WASI traits

The wasi-cap-std-sync crate provides impl of WasiFile and WasiDir in terms of cap_std::fs::{File, Dir}. These types provide sandboxed access to the local filesystem on both Unix and Windows.

The entire design story of cap-std is much bigger than we can address here, but in short, its functionality replaces all of the wasi_common::sys hierarchy, as well as the yanix / winx crates. All syscalls are hidden behind the cap-std hierarchy, with the lone exception of the sched implementation, which is provided for both unix and windows in separate modules.

Any wasi_common::{WasiCtx, WasiCtxBuilder} is interoperable with the wasi-cap-std-sync crate. However, for convenience, wasi-cap-std-sync provides its own WasiCtxBuilder that hooks up to all of the crate's components, i.e. it fills in all of the arguments to WasiCtx::builder(...), presents preopen_dir in terms of cap_std::fs::Dir, and provides convenience methods for inheriting the parent process's stdio, args, and env.

The only place we expect to run into long-term compatibility issues between wasi-cap-std-sync and the other impl crates that will come later is in the Sched abstraction. Once we can build an async scheduler based on Rust Futures, async impls will be able to interoperate, but the synchronous scheduler depends on downcasting the WasiFile type down to concrete types it knows about (which in turn impl AsRawFd for passing to unix poll, or the analogous traits on windows).

Why is this impl suffixed with -sync? https://github.com/bytecodealliance/wasmtime/pull/2434 async is coming soon! The async impl may end up depending on tokio or other relatively heavy deps, so we will retain a sync implementation so that wasi-common users have an option of not pulling in an async runtime.

Improving the WASI test suite

The bulk of wasi-common's test suite lives at crates/test-programs. This test suite was extremely useful for guiding this rewrite. We improved the test suite in numerous ways, including

view this post on Zulip Wasmtime GitHub notifications bot (Feb 04 2021 at 22:59):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

This PR is a complete rewrite of the wasi-common crate. It uses @sunfishcode 's new cap-std family of crates to provide a sandboxed implementation of WASI on the local filesystem.

Note that this is a breaking change for all users of WASI with Wasmtime, except for the C API.

Re-architecting wasi-common

Over the past year or so, we've run up against many design problems in wasi-common. Many of these problems ended up being so fundamental that a rewrite, as prolonged as it was, ended up being more tractable than incremental changes.

The Table

wasi-common now has a Table type that is designed to map u32 handles to resources. The table is now part of the public interface to a WasiCtx - it is reference counted so that it can be shared beyond a WasiCtx with other WASI proposals (e.g. wasi-crypto and wasi-nn) to manage their resources. Elements in the Table are Any typed.

The Table type is intended to model how the Interface Types concept of Resources is shaping up. Right now it is just an approximation.

The WasiFile and WasiDir traits

The WASI specification only defines one handle type, fd, on which all operations on both files and directories (aka dirfds) are defined. We believe this is a design mistake, and are architecting wasi-common to make this straightforward to correct in future snapshots of WASI. Wasi-common internally treats files and directories as two distinct resource types in the table - Box<dyn WasiFile> and Box<dyn WasiDir>. The snapshot 0 and 1 interfaces via fd will attempt to downcast a table element to one or both of these interfaces depending on what is appropriate - e.g. fd_close operates on both files and directories, fd_read only operates on files, and fd_readdir only operates on directories.

The WasiFile and WasiDir traits are defined by wasi-common in terms of types defined directly in the crate's source code (I decided it should NOT those generated by the wiggle proc macros, see snapshot architecture below), as well as the cap_std::time family of types. And, importantly, wasi-common itself provides no implementation of WasiDir, and only two trivial implementations of WasiFile on the crate::pipe::{ReadPipe, WritePipe} types, which in turn just delegate to std::io::{Read, Write}. In order for wasi-common to access the local filesystem at all, you need to provide WasiFile and WasiDir impls through either the new wasi-cap-std-sync crate found at crates/wasi-common/cap-std-sync - see the section on that crate below - or by providing your own implementation from elsewhere.

This design makes it possible for wasi-common embedders to statically reason about access to the local filesystem by examining what impls are linked into an application. We found that this separation of concerns also makes it pretty enjoyable to write alternative implementations, e.g. a virtual filesystem (which will land in a future PR).

Traits for the rest of WASI's features

Other aspects of a WASI implementation are not yet considered resources and accessed by handle. We plan to correct this design deficiency in WASI in the future, but for now we have designed the following traits to provide embedders with the same sort of implementation flexibility they get with WasiFile/WasiDir:

Users can provide implementations of each of these interfaces to the WasiCtx::builder(...) function. The wasi_cap_std_sync::WasiCtxBuilder::new() function uses this public interface to plug in its own implementations of each of these resources.

Snapshot architecture

One goal we've had for a while, but not quite met, is for multiple WASI snapshots to provide an interface to the same underlying WasiCtx. This provides us a path to evolve WASI by allowing the same WASI Command to import functions from different snapshots - e.g. the user could use Rust's std which imports snapshot 1, but also depend directly on the wasi crate which imports some future snapshot 2. Right now, this amounts to supporting snapshot 1 and "snapshot 0" aka wasi_unstable at once.

The architectural rules for snapshots are:

The wasi_common::Error type

wasi_common::Error is now anyhow::Error. wasi_common::snapshots::preview_1 contains all of the logic for transforming an Error into an Errno, by downcasting the error into any of

The wasi_common::ErrorExt trait provides human-friendly constructors for the wasi_common::ErrorKind variants .

If you throw an error that does not downcast to one of those, it will turn into a wiggle::Trap and terminate execution.

The real value of using anyhow::Error here is being able to use anyhow::Result::context to aid in debugging of errors.

The wasi-cap-std-sync implementation of the WASI traits

The wasi-cap-std-sync crate provides impl of WasiFile and WasiDir in terms of cap_std::fs::{File, Dir}. These types provide sandboxed access to the local filesystem on both Unix and Windows.

The entire design story of cap-std is much bigger than we can address here, but in short, its functionality replaces all of the wasi_common::sys hierarchy, as well as the yanix / winx crates. All syscalls are hidden behind the cap-std hierarchy, with the lone exception of the sched implementation, which is provided for both unix and windows in separate modules.

Any wasi_common::{WasiCtx, WasiCtxBuilder} is interoperable with the wasi-cap-std-sync crate. However, for convenience, wasi-cap-std-sync provides its own WasiCtxBuilder that hooks up to all of the crate's components, i.e. it fills in all of the arguments to WasiCtx::builder(...), presents preopen_dir in terms of cap_std::fs::Dir, and provides convenience methods for inheriting the parent process's stdio, args, and env.

The only place we expect to run into long-term compatibility issues between wasi-cap-std-sync and the other impl crates that will come later is in the Sched abstraction. Once we can build an async scheduler based on Rust Futures, async impls will be able to interoperate, but the synchronous scheduler depends on downcasting the WasiFile type down to concrete types it knows about (which in turn impl AsRawFd for passing to unix poll, or the analogous traits on windows).

Why is this impl suffixed with -sync? https://github.com/bytecodealliance/wasmtime/pull/2434 async is coming soon! The async impl may end up depending on tokio or other relatively heavy deps, so we will retain a sync implementation so that wasi-common users have an option of not pulling in an async runtime.

Improving the WASI test suite

The bulk of wasi-common's test suite lives at crates/test-programs. This test suite was extremely useful for guiding this rewrite. We improved the test suite in numerous ways, including

view this post on Zulip Wasmtime GitHub notifications bot (Feb 04 2021 at 23:38):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

This PR is a complete rewrite of the wasi-common crate. It uses @sunfishcode 's new cap-std family of crates to provide a sandboxed implementation of WASI on the local filesystem.

Note that this is a breaking change for all users of WASI with Wasmtime, except for the C API.

Re-architecting wasi-common

Over the past year or so, we've run up against many design problems in wasi-common. Many of these problems ended up being so fundamental that a rewrite, as prolonged as it was, ended up being more tractable than incremental changes.

The Table

wasi-common now has a Table type that is designed to map u32 handles to resources. The table is now part of the public interface to a WasiCtx - it is reference counted so that it can be shared beyond a WasiCtx with other WASI proposals (e.g. wasi-crypto and wasi-nn) to manage their resources. Elements in the Table are Any typed.

The Table type is intended to model how the Interface Types concept of Resources is shaping up. Right now it is just an approximation.

The WasiFile and WasiDir traits

The WASI specification only defines one handle type, fd, on which all operations on both files and directories (aka dirfds) are defined. We believe this is a design mistake, and are architecting wasi-common to make this straightforward to correct in future snapshots of WASI. Wasi-common internally treats files and directories as two distinct resource types in the table - Box<dyn WasiFile> and Box<dyn WasiDir>. The snapshot 0 and 1 interfaces via fd will attempt to downcast a table element to one or both of these interfaces depending on what is appropriate - e.g. fd_close operates on both files and directories, fd_read only operates on files, and fd_readdir only operates on directories.

The WasiFile and WasiDir traits are defined by wasi-common in terms of types defined directly in the crate's source code (I decided it should NOT those generated by the wiggle proc macros, see snapshot architecture below), as well as the cap_std::time family of types. And, importantly, wasi-common itself provides no implementation of WasiDir, and only two trivial implementations of WasiFile on the crate::pipe::{ReadPipe, WritePipe} types, which in turn just delegate to std::io::{Read, Write}. In order for wasi-common to access the local filesystem at all, you need to provide WasiFile and WasiDir impls through either the new wasi-cap-std-sync crate found at crates/wasi-common/cap-std-sync - see the section on that crate below - or by providing your own implementation from elsewhere.

This design makes it possible for wasi-common embedders to statically reason about access to the local filesystem by examining what impls are linked into an application. We found that this separation of concerns also makes it pretty enjoyable to write alternative implementations, e.g. a virtual filesystem (which will land in a future PR).

Traits for the rest of WASI's features

Other aspects of a WASI implementation are not yet considered resources and accessed by handle. We plan to correct this design deficiency in WASI in the future, but for now we have designed the following traits to provide embedders with the same sort of implementation flexibility they get with WasiFile/WasiDir:

Users can provide implementations of each of these interfaces to the WasiCtx::builder(...) function. The wasi_cap_std_sync::WasiCtxBuilder::new() function uses this public interface to plug in its own implementations of each of these resources.

Snapshot architecture

One goal we've had for a while, but not quite met, is for multiple WASI snapshots to provide an interface to the same underlying WasiCtx. This provides us a path to evolve WASI by allowing the same WASI Command to import functions from different snapshots - e.g. the user could use Rust's std which imports snapshot 1, but also depend directly on the wasi crate which imports some future snapshot 2. Right now, this amounts to supporting snapshot 1 and "snapshot 0" aka wasi_unstable at once.

The architectural rules for snapshots are:

The wasi_common::Error type

wasi_common::Error is now anyhow::Error. wasi_common::snapshots::preview_1 contains all of the logic for transforming an Error into an Errno, by downcasting the error into any of

The wasi_common::ErrorExt trait provides human-friendly constructors for the wasi_common::ErrorKind variants .

If you throw an error that does not downcast to one of those, it will turn into a wiggle::Trap and terminate execution.

The real value of using anyhow::Error here is being able to use anyhow::Result::context to aid in debugging of errors.

The wasi-cap-std-sync implementation of the WASI traits

The wasi-cap-std-sync crate provides impl of WasiFile and WasiDir in terms of cap_std::fs::{File, Dir}. These types provide sandboxed access to the local filesystem on both Unix and Windows.

The entire design story of cap-std is much bigger than we can address here, but in short, its functionality replaces all of the wasi_common::sys hierarchy, as well as the yanix / winx crates. All syscalls are hidden behind the cap-std hierarchy, with the lone exception of the sched implementation, which is provided for both unix and windows in separate modules.

Any wasi_common::{WasiCtx, WasiCtxBuilder} is interoperable with the wasi-cap-std-sync crate. However, for convenience, wasi-cap-std-sync provides its own WasiCtxBuilder that hooks up to all of the crate's components, i.e. it fills in all of the arguments to WasiCtx::builder(...), presents preopen_dir in terms of cap_std::fs::Dir, and provides convenience methods for inheriting the parent process's stdio, args, and env.

The only place we expect to run into long-term compatibility issues between wasi-cap-std-sync and the other impl crates that will come later is in the Sched abstraction. Once we can build an async scheduler based on Rust Futures, async impls will be able to interoperate, but the synchronous scheduler depends on downcasting the WasiFile type down to concrete types it knows about (which in turn impl AsRawFd for passing to unix poll, or the analogous traits on windows).

Why is this impl suffixed with -sync? https://github.com/bytecodealliance/wasmtime/pull/2434 async is coming soon! The async impl may end up depending on tokio or other relatively heavy deps, so we will retain a sync implementation so that wasi-common users have an option of not pulling in an async runtime.

Improving the WASI test suite

The bulk of wasi-common's test suite lives at crates/test-programs. This test suite was extremely useful for guiding this rewrite. We improved the test suite in numerous ways, including

view this post on Zulip Wasmtime GitHub notifications bot (Feb 05 2021 at 01:01):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

This PR is a complete rewrite of the wasi-common crate. It uses @sunfishcode 's new cap-std family of crates to provide a sandboxed implementation of WASI on the local filesystem.

Note that this is a breaking change for all users of WASI with Wasmtime, except for the C API.

Re-architecting wasi-common

Over the past year or so, we've run up against many design problems in wasi-common. Many of these problems ended up being so fundamental that a rewrite, as prolonged as it was, ended up being more tractable than incremental changes.

The Table

wasi-common now has a Table type that is designed to map u32 handles to resources. The table is now part of the public interface to a WasiCtx - it is reference counted so that it can be shared beyond a WasiCtx with other WASI proposals (e.g. wasi-crypto and wasi-nn) to manage their resources. Elements in the Table are Any typed.

The Table type is intended to model how the Interface Types concept of Resources is shaping up. Right now it is just an approximation.

The WasiFile and WasiDir traits

The WASI specification only defines one handle type, fd, on which all operations on both files and directories (aka dirfds) are defined. We believe this is a design mistake, and are architecting wasi-common to make this straightforward to correct in future snapshots of WASI. Wasi-common internally treats files and directories as two distinct resource types in the table - Box<dyn WasiFile> and Box<dyn WasiDir>. The snapshot 0 and 1 interfaces via fd will attempt to downcast a table element to one or both of these interfaces depending on what is appropriate - e.g. fd_close operates on both files and directories, fd_read only operates on files, and fd_readdir only operates on directories.

The WasiFile and WasiDir traits are defined by wasi-common in terms of types defined directly in the crate's source code (I decided it should NOT those generated by the wiggle proc macros, see snapshot architecture below), as well as the cap_std::time family of types. And, importantly, wasi-common itself provides no implementation of WasiDir, and only two trivial implementations of WasiFile on the crate::pipe::{ReadPipe, WritePipe} types, which in turn just delegate to std::io::{Read, Write}. In order for wasi-common to access the local filesystem at all, you need to provide WasiFile and WasiDir impls through either the new wasi-cap-std-sync crate found at crates/wasi-common/cap-std-sync - see the section on that crate below - or by providing your own implementation from elsewhere.

This design makes it possible for wasi-common embedders to statically reason about access to the local filesystem by examining what impls are linked into an application. We found that this separation of concerns also makes it pretty enjoyable to write alternative implementations, e.g. a virtual filesystem (which will land in a future PR).

Traits for the rest of WASI's features

Other aspects of a WASI implementation are not yet considered resources and accessed by handle. We plan to correct this design deficiency in WASI in the future, but for now we have designed the following traits to provide embedders with the same sort of implementation flexibility they get with WasiFile/WasiDir:

Users can provide implementations of each of these interfaces to the WasiCtx::builder(...) function. The wasi_cap_std_sync::WasiCtxBuilder::new() function uses this public interface to plug in its own implementations of each of these resources.

Snapshot architecture

One goal we've had for a while, but not quite met, is for multiple WASI snapshots to provide an interface to the same underlying WasiCtx. This provides us a path to evolve WASI by allowing the same WASI Command to import functions from different snapshots - e.g. the user could use Rust's std which imports snapshot 1, but also depend directly on the wasi crate which imports some future snapshot 2. Right now, this amounts to supporting snapshot 1 and "snapshot 0" aka wasi_unstable at once.

The architectural rules for snapshots are:

The wasi_common::Error type

wasi_common::Error is now anyhow::Error. wasi_common::snapshots::preview_1 contains all of the logic for transforming an Error into an Errno, by downcasting the error into any of

The wasi_common::ErrorExt trait provides human-friendly constructors for the wasi_common::ErrorKind variants .

If you throw an error that does not downcast to one of those, it will turn into a wiggle::Trap and terminate execution.

The real value of using anyhow::Error here is being able to use anyhow::Result::context to aid in debugging of errors.

The wasi-cap-std-sync implementation of the WASI traits

The wasi-cap-std-sync crate provides impl of WasiFile and WasiDir in terms of cap_std::fs::{File, Dir}. These types provide sandboxed access to the local filesystem on both Unix and Windows.

The entire design story of cap-std is much bigger than we can address here, but in short, its functionality replaces all of the wasi_common::sys hierarchy, as well as the yanix / winx crates. All syscalls are hidden behind the cap-std hierarchy, with the lone exception of the sched implementation, which is provided for both unix and windows in separate modules.

Any wasi_common::{WasiCtx, WasiCtxBuilder} is interoperable with the wasi-cap-std-sync crate. However, for convenience, wasi-cap-std-sync provides its own WasiCtxBuilder that hooks up to all of the crate's components, i.e. it fills in all of the arguments to WasiCtx::builder(...), presents preopen_dir in terms of cap_std::fs::Dir, and provides convenience methods for inheriting the parent process's stdio, args, and env.

The only place we expect to run into long-term compatibility issues between wasi-cap-std-sync and the other impl crates that will come later is in the Sched abstraction. Once we can build an async scheduler based on Rust Futures, async impls will be able to interoperate, but the synchronous scheduler depends on downcasting the WasiFile type down to concrete types it knows about (which in turn impl AsRawFd for passing to unix poll, or the analogous traits on windows).

Why is this impl suffixed with -sync? https://github.com/bytecodealliance/wasmtime/pull/2434 async is coming soon! The async impl may end up depending on tokio or other relatively heavy deps, so we will retain a sync implementation so that wasi-common users have an option of not pulling in an async runtime.

Improving the WASI test suite

The bulk of wasi-common's test suite lives at crates/test-programs. This test suite was extremely useful for guiding this rewrite. We improved the test suite in numerous ways, including

view this post on Zulip Wasmtime GitHub notifications bot (Feb 05 2021 at 01:01):

pchickey requested sunfishcode for a review on PR #2487.

view this post on Zulip Wasmtime GitHub notifications bot (Feb 05 2021 at 01:09):

pchickey updated PR #2487 from pch/wasi_common_cap_std to main:

This PR is a complete rewrite of the wasi-common crate. It uses @sunfishcode 's new cap-std family of crates to provide a sandboxed implementation of WASI on the local filesystem.

Note that this is a breaking change for all users of WASI with Wasmtime, except for the C API.

Re-architecting wasi-common

Over the past year or so, we've run up against many design problems in wasi-common. Many of these problems ended up being so fundamental that a rewrite, as prolonged as it was, ended up being more tractable than incremental changes.

The Table

wasi-common now has a Table type that is designed to map u32 handles to resources. The table is now part of the public interface to a WasiCtx - it is reference counted so that it can be shared beyond a WasiCtx with other WASI proposals (e.g. wasi-crypto and wasi-nn) to manage their resources. Elements in the Table are Any typed.

The Table type is intended to model how the Interface Types concept of Resources is shaping up. Right now it is just an approximation.

The WasiFile and WasiDir traits

The WASI specification only defines one handle type, fd, on which all operations on both files and directories (aka dirfds) are defined. We believe this is a design mistake, and are architecting wasi-common to make this straightforward to correct in future snapshots of WASI. Wasi-common internally treats files and directories as two distinct resource types in the table - Box<dyn WasiFile> and Box<dyn WasiDir>. The snapshot 0 and 1 interfaces via fd will attempt to downcast a table element to one or both of these interfaces depending on what is appropriate - e.g. fd_close operates on both files and directories, fd_read only operates on files, and fd_readdir only operates on directories.

The WasiFile and WasiDir traits are defined by wasi-common in terms of types defined directly in the crate's source code (I decided it should NOT those generated by the wiggle proc macros, see snapshot architecture below), as well as the cap_std::time family of types. And, importantly, wasi-common itself provides no implementation of WasiDir, and only two trivial implementations of WasiFile on the crate::pipe::{ReadPipe, WritePipe} types, which in turn just delegate to std::io::{Read, Write}. In order for wasi-common to access the local filesystem at all, you need to provide WasiFile and WasiDir impls through either the new wasi-cap-std-sync crate found at crates/wasi-common/cap-std-sync - see the section on that crate below - or by providing your own implementation from elsewhere.

This design makes it possible for wasi-common embedders to statically reason about access to the local filesystem by examining what impls are linked into an application. We found that this separation of concerns also makes it pretty enjoyable to write alternative implementations, e.g. a virtual filesystem (which will land in a future PR).

Traits for the rest of WASI's features

Other aspects of a WASI implementation are not yet considered resources and accessed by handle. We plan to correct this design deficiency in WASI in the future, but for now we have designed the following traits to provide embedders with the same sort of implementation flexibility they get with WasiFile/WasiDir:

Users can provide implementations of each of these interfaces to the WasiCtx::builder(...) function. The wasi_cap_std_sync::WasiCtxBuilder::new() function uses this public interface to plug in its own implementations of each of these resources.

Snapshot architecture

One goal we've had for a while, but not quite met, is for multiple WASI snapshots to provide an interface to the same underlying WasiCtx. This provides us a path to evolve WASI by allowing the same WASI Command to import functions from different snapshots - e.g. the user could use Rust's std which imports snapshot 1, but also depend directly on the wasi crate which imports some future snapshot 2. Right now, this amounts to supporting snapshot 1 and "snapshot 0" aka wasi_unstable at once.

The architectural rules for snapshots are:

The wasi_common::Error type

wasi_common::Error is now anyhow::Error. wasi_common::snapshots::preview_1 contains all of the logic for transforming an Error into an Errno, by downcasting the error into any of

The wasi_common::ErrorExt trait provides human-friendly constructors for the wasi_common::ErrorKind variants .

If you throw an error that does not downcast to one of those, it will turn into a wiggle::Trap and terminate execution.

The real value of using anyhow::Error here is being able to use anyhow::Result::context to aid in debugging of errors.

The wasi-cap-std-sync implementation of the WASI traits

The wasi-cap-std-sync crate provides impl of WasiFile and WasiDir in terms of cap_std::fs::{File, Dir}. These types provide sandboxed access to the local filesystem on both Unix and Windows.

The entire design story of cap-std is much bigger than we can address here, but in short, its functionality replaces all of the wasi_common::sys hierarchy, as well as the yanix / winx crates. All syscalls are hidden behind the cap-std hierarchy, with the lone exception of the sched implementation, which is provided for both unix and windows in separate modules.

Any wasi_common::{WasiCtx, WasiCtxBuilder} is interoperable with the wasi-cap-std-sync crate. However, for convenience, wasi-cap-std-sync provides its own WasiCtxBuilder that hooks up to all of the crate's components, i.e. it fills in all of the arguments to WasiCtx::builder(...), presents preopen_dir in terms of cap_std::fs::Dir, and provides convenience methods for inheriting the parent process's stdio, args, and env.

The only place we expect to run into long-term compatibility issues between wasi-cap-std-sync and the other impl crates that will come later is in the Sched abstraction. Once we can build an async scheduler based on Rust Futures, async impls will be able to interoperate, but the synchronous scheduler depends on downcasting the WasiFile type down to concrete types it knows about (which in turn impl AsRawFd for passing to unix poll, or the analogous traits on windows).

Why is this impl suffixed with -sync? https://github.com/bytecodealliance/wasmtime/pull/2434 async is coming soon! The async impl may end up depending on tokio or other relatively heavy deps, so we will retain a sync implementation so that wasi-common users have an option of not pulling in an async runtime.

Improving the WASI test suite

The bulk of wasi-common's test suite lives at crates/test-programs. This test suite was extremely useful for guiding this rewrite. We improved the test suite in numerous ways, including

view this post on Zulip Wasmtime GitHub notifications bot (Feb 05 2021 at 01:15):

sunfishcode submitted PR Review.

view this post on Zulip Wasmtime GitHub notifications bot (Feb 05 2021 at 01:15):

sunfishcode submitted PR Review.

view this post on Zulip Wasmtime GitHub notifications bot (Feb 05 2021 at 01:15):

sunfishcode created PR Review Comment:

Is this line still needed?

view this post on Zulip Wasmtime GitHub notifications bot (Feb 05 2021 at 01:15):

sunfishcode created PR Review Comment:

Are these fail-fast: false lines still needed?

view this post on Zulip Wasmtime GitHub notifications bot (Feb 05 2021 at 01:15):

sunfishcode deleted PR Review Comment.

view this post on Zulip Wasmtime GitHub notifications bot (Feb 05 2021 at 01:15):

sunfishcode deleted PR Review Comment.

view this post on Zulip Wasmtime GitHub notifications bot (Feb 05 2021 at 02:02):

pchickey merged PR #2487.


Last updated: Nov 22 2024 at 16:03 UTC