-
Notifications
You must be signed in to change notification settings - Fork 125
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
Added WASI Examples for Rust #86
Conversation
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.
This is a really great write-up. I have suggested a handful of copy edits, and one or two clarifications
// Entry point to our WASI applications | ||
fn main() { | ||
// Print out hello world! | ||
// This will handle writing to /dev/stdout for us using the WASI APIs (e.g fd_write) |
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.
just stdout
, its not in /dev/
// This will map the `/helloworld` directory on the guest, to the current directory (`.`) on the host | ||
// For example: `--mapdir /helloworld::.`, | ||
// This will error if you don't use the `--mapdir` flag correctly. | ||
let mut file = fs::File::create("/helloworld/helloworld.txt").unwrap(); |
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 would rephrase this comment as something like:
This code requires the Wasi host to provide a /helloworld
directory on the guest. If the /helloworld
directory is not available, the unwrap()
will cause this program to panic.
For example, in Wasmtime, if you want to map the current directory to /helloworld
, invoke the runtime with --mapdir /helloworld::.
.
|
||
## Overview | ||
|
||
In this example, We will be writing "Hello world!" to both the console (`/dev/stdout`), and a newly created file `./hello-world.txt`. We highly reccomended that you have read the [WASI Introduction](/example-redirect?exampleName=wasi-introduction) before procedding with this example. You should install [wasmtime](https://wasmtime.dev/) as that is the WebAssembly runtime we will be using as our host. You should also ensure that [rustup and rust](https://www.rust-lang.org/tools/install) is installed. |
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.
stdout
is just the name of a POSIX io stream (see man 3 stdout
), the /dev/stdout file is a special Linux thing.
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.
"you should install Rust using the [rustup
](url here) tool"
|
||
## Implementation | ||
|
||
First, we will generate a new binary program with cargo: |
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.
rather than binary program
id call it an executable
|
||
// Write the text to the file we created | ||
write!(file, "Hello world!\n").unwrap(); | ||
} |
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.
same comments as above on the source file.
|
||
As mentioned in the code comments, even though the [WASI APIs](https://github.com/WebAssembly/WASI/blob/master/phases/snapshot/docs.md) are not being used directly, when we compile our program to WASI, the rust APIs will be using these WASI APIs under the hood for us. | ||
|
||
Next, we will want to add WASI as a target that we can compile to. And then compile our program to WASI. To do this we will run: |
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.
Next, we will ask the rustup
tool to install support for WASI
.
- Most WebAssembly runtimes / interpreters can be used as a command line interface, or embedded/linked in a larger application by using it's library API. | ||
- Each of these projects has their own strengths, and it really depends on what your use case is to choose the best host for you. And there are many more projects out there that you can choose from! For example, here is a [WASI awesome list](https://github.com/wasmerio/awesome-wasi). | ||
- **"Guests"** | ||
- Guests are the WebAssembly modules that are executed in the host. If you plan to write WebAssembly modules, than you would be writing the guest application that is run inside the host application. |
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.
executed by the host
- **"Guests"** | ||
- Guests are the WebAssembly modules that are executed in the host. If you plan to write WebAssembly modules, than you would be writing the guest application that is run inside the host application. | ||
- The host is able to provide additional functionality to guest, by doing tasks on the guests' behalf. This functionality is offered by passing functions to the importObject ([Similar to how we do this for the browser in the "Importing Javascript Functions Into Webassembly"](/example-redirect?exampleName=importing-javascript-functions-into-webassembly)). | ||
- This brings us back to WASI, as WASI is a standardized set of APIs for hosts to do system level actions (such as filystem operations) for the guest WebAssembly module. Therefore, this gives guest WebAssembly modules that a developer could write, access to system resources! |
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.
Therefore, this allows every developer to write WebAssembly modules that can access system resources.
- The host is able to provide additional functionality to guest, by doing tasks on the guests' behalf. This functionality is offered by passing functions to the importObject ([Similar to how we do this for the browser in the "Importing Javascript Functions Into Webassembly"](/example-redirect?exampleName=importing-javascript-functions-into-webassembly)). | ||
- This brings us back to WASI, as WASI is a standardized set of APIs for hosts to do system level actions (such as filystem operations) for the guest WebAssembly module. Therefore, this gives guest WebAssembly modules that a developer could write, access to system resources! | ||
|
||
The last thing worth mentioning is that WASI uses a [capability based security model](https://github.com/bytecodealliance/wasmtime/blob/master/docs/WASI-capabilities.md). Meaning, hosts must be explicitly given a capability, before it will allow a guest module to perform an action. For example in [Wasmtime](https://wasmtime.dev/), a guest module cannot modify the filesystem, without using the `--mapdir` or `--dir` flag which explictly says which directory on the host (your runtime / computer filesystem) maps to the guest (the webassembly module's virtual filesystem provided by the host). |
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.
Meaning, host must explicitly grant a capability to a guest module in order for the guest module to perform an action. For example in Wasmtime, by default, the guest module cannot access any part of the host's filesystem. The user that invokes Wasmtime must pass in the --mapdir
or --dir
flag to grant modules the capability to access directories in the host filesystem.
|
||
The last thing worth mentioning is that WASI uses a [capability based security model](https://github.com/bytecodealliance/wasmtime/blob/master/docs/WASI-capabilities.md). Meaning, hosts must be explicitly given a capability, before it will allow a guest module to perform an action. For example in [Wasmtime](https://wasmtime.dev/), a guest module cannot modify the filesystem, without using the `--mapdir` or `--dir` flag which explictly says which directory on the host (your runtime / computer filesystem) maps to the guest (the webassembly module's virtual filesystem provided by the host). | ||
|
||
At the time of this writing, a lot of WASI is still in proposals and things. Only a few features of what WASI is hoping to acheive is fully implemented and standardized. One of those features is filesystem access! Therefore, let's take a look at modifying the file system in the [WASI hello world example](/example-redirect?exampleName=wasi-hello-world), if there is a hello world currently for your language. If not, feel free to look at your language documentation, to see if they support WASI currently, and submit the [WASI hello world example for your language](https://github.com/torch2424/wasm-by-example). |
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.
It may be worth mentioning "Other system resources, like networking, are not yet part of the WASI standard, though they will be one day. So, if you're hoping to bind()
to a socket in your WebAssembly module, WASI hosts don't yet expose those capabilities."
Would be great to add a link to: http://www.jakubkonka.com/2020/04/28/rust-wasi-from-scratch.html And also, remove the link to: https://github.com/wasmerio/awesome-wasi as it seems a little outdated. For people interested in how all the wasi calls are made and things |
First, we should answer the question, "What is WASI"? WASI is the [WebAssembly System Interface](https://wasi.dev/), "a modular system interface for WebAssembly". To help explain this, let's break it down to: | ||
|
||
- **What can WASI do for my WebAssembly Applications?** | ||
- WASI offers a [standardized set of APIs](https://github.com/WebAssembly/WASI/blob/master/phases/snapshot/docs.md) for WebAssembly modules to access system resource such as a FileSystem, Networking, Time, Random, etc... . |
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.
My suggestion here would be to mention running wasm "outside the browser" somewhere earlier here, to help new users understand the context here.
- **What can WASI do for my WebAssembly Applications?** | ||
- WASI offers a [standardized set of APIs](https://github.com/WebAssembly/WASI/blob/master/phases/snapshot/docs.md) for WebAssembly modules to access system resource such as a FileSystem, Networking, Time, Random, etc... . | ||
- **How do WebAssembly modules use WASI?** | ||
- A WebAssembly module will use their importObject ([Similar to how we do this for the browser in the "Importing Javascript Functions Into Webassembly"](/example-redirect?exampleName=importing-javascript-functions-into-webassembly)), to be able to access the standardized WASI API bindings (meaning the names of these importObject functions map directly to the agreed-upon WASI implementation). |
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.
importObject
is a term specific to the JS API, which help users coming from JS, but may also be confusing because in many WASI use cases, there is no JS API. The comparison to the JS tutorial is good, but you may want to clarify that importObject
is the JS way of doing this. Core wasm itself just has import
s.
IN general, for the WASI introduction my be worth mentioning: Without if a user goes straight to the WASI example, without the context of the other examples, they could be a bit lost. Therefore:
|
Made requested chages by @pchickey and @sunfishcode ! Hopefully it looks good, if not, we can always edit it later 😄 👍 Thanks again for the look over, I super appreciate it :) |
closes #2
This adds a WASI introduction, as well as a Hello World for Rust, that is similar to the wasmtime tutorial, but shortened to fit the "by example" theme.
This in general lays the groundwork for WASI on wasm by example 😄 👍
AssemblyScript will come in another PR, as some quality of life improvements will be coming in the next AS release for WASI: AssemblyScript/assemblyscript#1159
cc @sunfish code, if you got the time, would be excited to hear your thoughts!