-
Notifications
You must be signed in to change notification settings - Fork 20
WASI MemoryFileSystem #230
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
CI failure seems unrelated to these changes (out of storage space,) but if they are let me know. |
| func getPreopenPaths() -> [String] | ||
|
|
||
| /// Opens a directory and returns a WASIDir implementation. | ||
| func openDirectory(at path: String) throws -> any WASIDir |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if the use of existentials is justified here? Could we use opaque types instead?
| func openDirectory(at path: String) throws -> any WASIDir | |
| func openDirectory(at path: String) throws -> some WASIDir |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
WASIDir seems to be defined as a protocol so I believe an existential is how its used elsewhere (i.e in Directory.swift)
| import SystemPackage | ||
|
|
||
| /// Base protocol for all file system nodes in memory. | ||
| internal protocol MemFSNode: AnyObject { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a strong reason to require AnyObject here? What would exactly classes (as opposed to non-copyable types) bring to the table other than reference counting performance hit?
| internal protocol MemFSNode: AnyObject { | |
| protocol MemFSNode { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Multiple file entries need to share mutable access to the same node (e.g., a file opened twice should see the same content). With classes, this is natural, both entries hold references to the same object. With non-copyable structs, we'd need an indirection layer (handles/indices into a central store), which adds complexity. Open to that refactor if the ref-counting overhead is measurable or if I am mistaken (Swift is arguably very new to me.)
| /// | ||
| /// This implementation provides access to actual files and directories on the host system, | ||
| /// with appropriate sandboxing through pre-opened directories. | ||
| public final class HostFileSystem: FileSystemProvider, FileSystem { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Usual concern WRT classes overhead here. IIUC we're not relying on class hierarchies, so why not make this a non-copyable struct to avoid the ARC overhead?
| public final class HostFileSystem: FileSystemProvider, FileSystem { | |
| public struct HostFileSystem: FileSystemProvider, FileSystemImplementation, ~Copyable { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reason I went with class here is that FileSystemImplementation needs to be stored as a property in WASIBridgeToHost, and Swift's existential types (any Protocol) don't support ~Copyable types. If we make this a non-copyable struct, we'd need to make WASIBridgeToHost generic.
Adds an in-memory file system to the WASI bridge (with the ability to mount actual file descriptors.)