feat(preview1): implement core I/O functionality#6440
feat(preview1): implement core I/O functionality#6440pchickey merged 3 commits intobytecodealliance:mainfrom
Conversation
Signed-off-by: Roman Volosatovs <rvolosatovs@riseup.net>
Signed-off-by: Roman Volosatovs <rvolosatovs@riseup.net>
c6585fd to
fad7fa5
Compare
Subscribe to Label Actioncc @kubkon DetailsThis issue or pull request has been labeled: "wasi"Thus the following users have been cc'd because of the following labels:
To subscribe or unsubscribe from this label, edit the |
|
cc @pchickey |
|
this looks good to me, but I'll defer to @pchickey as the shepherd of the preview2 -> wasmtime move. |
pchickey
left a comment
There was a problem hiding this comment.
This is great work! Just a few small issues. Thank you for finding all of these bad behaviors in the legacy implementation!
| let descriptors = self.descriptors.take(); | ||
| self.view.adapter_mut().descriptors = Some(descriptors); | ||
| } | ||
| } |
There was a problem hiding this comment.
I wasn't expecting this sort of machinery to be required - we can't get away with implementing the DescriptorsRef methods on WasiPreview1Ctx? I can't intuit where the problem is in a more straightforward implementation, so if this is required, lets leave a comment on the struct definition explaining why.
There was a problem hiding this comment.
I'll add a comment, but the biggest reasons why this is required are:
- By far the biggest issue is
bindgengenerating host methods with&mut selfreceivers, preventing e.g. simultaneous lazy initialization of the descriptor table and calling a preview2 method using any data borrowed from that table, even looking up something liketable().is_fileis problematic WasiPreview1Adapter(assuming that's what you meant by WasiPreview1Ctx) does not have access to preview2 functionality and/or the underlying table, so it cannot initialize itself using something like https://docs.rs/once_cell/latest/once_cell/sync/struct.Lazy.html . Lazily initializing the descriptor map requires access to both theWasiPreview1Adapterandwasi::preopens::Host, so the only place where this functionality could exist is in an extension trait (WasiPreview1ViewExt). Note that from within this trait, we can never return anything borrowed directly, because we'd first need to calladapter_mut()to get access to the state (which we may need to lazily initialize). And even if we had a way to return a borrowed descriptor table directly, it would not be possible to call any other method onselfdue to 1., since that would cause a double mutable borrow, which is not allowed.
In short, an alternative solution would be storing Option<Arc<Mutex<Descriptors>>> in the adapter and returning Arc<Mutex<Descriptors>> in the WasiPreview1AdapterExt::descriptors(&mut self) method, which IMO is way more awkward to work with and simply redundant complexity.
Overall, the DescriptorsRef is just a workaround for bindgen design drawbacks. I believe this could be simplified dramatically if host methods would just take &self
There was a problem hiding this comment.
That makes sense. Thank you.
We should look into adding a bindgen option to enable &self receivers in the future, and then we may be able to unwind a bit of this complexity. For now, this is a fine implementation once it has a comment.
There was a problem hiding this comment.
I've added a few comments and renamed the struct to Transaction so it's a bit more obvious what it actually is
| _fs_rights_inheriting: types::Rights, | ||
| ) -> Result<(), types::Error> { | ||
| todo!() | ||
| unreachable!() |
There was a problem hiding this comment.
this is still a todo!() - we can leave it to a follow up PR, but unreachable!() communicates to me that it is a bug in this code if it is reachable, while this is reachable from any guest program.
There was a problem hiding this comment.
I took this directly from
wasmtime/crates/wasi-preview1-component-adapter/src/lib.rs
Lines 560 to 569 in 5b93cdb
It seems to me that the adapter has to implement rights handling, which the existing one does not do. I'll mark this as
todo! and file an issue for rights handling follow-up
There was a problem hiding this comment.
Oh, that is indeed a bug in the component adapter as well. unreachabable!() is just how we spell todo!() and panic!() and etc over there since we cant use std's macros.
In the legacy implementation, set_rights is a no-op, it only validates the fd. That is the correct behavior for both of these spots. Would you mind making this fix to the component adapter as well?
prtest:full Signed-off-by: Roman Volosatovs <rvolosatovs@riseup.net>
fad7fa5 to
ee72313
Compare
Moved from bytecodealliance/preview2-prototyping#175
Refs #6370
The implementation tries to follow existing preview1 behavior as much as possible - as a result, there are a few differences in behavior from existing adapter. Please see the original PR for more details.
A follow-up issues/PRs fill be filed for:
fd_readdirwindowssupport for a few tests (still not sure what's causing the failures)