Writing a core library in Rust --- possibilities for SAFE Browser (WASM)

Cool, I’ve read about that. I assumed because I saw some std::net modules being used in the Tokio code it was dependent on the TCP and UDP mechanisms too.

It’s an educated guess from looking at std implementation for WASM. They contain some stubs and stubs don’t always ‘work’. I’ve seen the amount of dependencies needed for safe_app, it’s a lot! I thought the chance is there at least a few of them use something from std:: that is stubbed (or panics) for WASM. Anyway, I can’t back it up with examples, it may be less worse than I thought looking at the stubs. Threading, syscalls and mutexes(?) won’t run on WASM, I assume — but I have no clue whether those components are used by safe_app or its dependencies.

My point is, the low-level libraries require OS-specific code. I assume WASM isn’t quite yet ready to be a full OS-environment yet, so to me it’s vague on how these low-level libraries translate to that context.

A lot of progress is made on wasm-bindgen, so if it doesn’t work now, it might in a few years. It’s exciting really.


Thanks for that explanation on jemalloc, @hunterlester. The more I read the less I understand.

4 Likes

This gives us portability, because each host can have their own implementation of wasi-core that is specifically written for their platform — from WebAssembly runtimes like Mozilla’s wasmtime and Fastly’s Lucet, to Node, or even the browser.

couldn’t we just compile the c code with clang (target = wasm32-unknown-wasi) and then link it to the rust code (also compiled to wasm+wasi)?

3 Likes

Suddenly saw that the tutorial now also includes an example for Rust! https://github.com/CraneStation/wasmtime/blob/master/docs/WASI-tutorial.md#from-rust

The wasi target in the Rust compiler seems quite cool already too! https://github.com/rust-lang/rust/blob/2477e2493e67527fc282c7239e019f7ebd513a1a/src/libstd/sys/wasi/fs.rs#L377

WASI is going to rock, I’m sure! :nerd_face::partying_face:

2 Likes

I was looking at WASM in the Rust standard library again and spotted an implementation of the TcpListener::accept method.

Now, why is this interesting? I’ll try to explain as best I can: Most Rust applications use the standard library which is an abstraction over system libraries that do various things like networking and file system access. Such applications should work on most major operating systems. The Rust standard library takes care of calling the system-specific APIs. The TcpListener::accept method will differ between Windows and Linux. But, WASM is a little different from Windows and Linux.

WASM is a kind of virtual computer processor, like an Intel or AMD processor. In itself, this processor is a primitive component that does very low-level things. Adding up numbers, transfer data in memory and communicating with other components through buses. This is were operating systems like Linux and Windows come in; they implement all kinds of drivers so the processor can communicate with other components. And this is what Rust’s standard library ultimately relies on. So, how does WASM communicate with the network or file system?

WASM is different from your real processor because it is virtual. This means it actually has a ‘host’ that runs it. That means that if WASM were to want to access the network, it always has to go through the host. And this is exactly what WASI defines. It’s the system interface, similar to how Windows and Linux have interfaces for us to talk to the network or file system. So, just like you can use Linux to access the network, you can use WASI to access the network. But, WASI will ultimately rely on the host to provide it. The way this should work is that the host decides what access the program gets.

A very interesting talk I can recommend is this one:

The author explains the current way UNIX works and an improved way of thinking about capabilities (for networking sockets and files). By now, his implementations have been deprecated, and he refers to WebAssembly as a possible alternative. WebAssembly now builds on the ideas of the author.

Back to the TcpListener::accept example. As far as I understand: If you write a Rust application with a TcpListener and compile it to WASM-WASI, this program can be run with wasmtime. The accept call only accepts an already existing socket, so that means that the socket already has to be open. This is what wasmtime can do for you. You can tell it to open a socket, then run your program so that the program can accept incoming connections on that pre-existing socket.

This means the program is capability-based. It can only open sockets you provide it with. Files work similarly, the program will only open files you open for it. So, the program can’t open random files to read from and this is what it is all about: limiting the capabilities of a program to make sure it can’t do anything else than what it needs. This is for security purposes, so that if the program is hijacked by an attacker, it can’t do much harm. It can’t read from random important files etc.

There is a tracking issue that made this all possible here. Due respect for the people working on this!

2 Likes

I should perhaps have posted the following reply here.

WASI Preview 2 is coming in 2023.

So far we have been using Preview 1 although it wasn’t called that! Anyway, Preview 2 includes async Sockets, but threading won’t be until Preview 3 :cry:. These are steps towards a WASI 1.0 W3 Standard.

Good intro to WASI and Preview 2 here: