Rust and WebAssembly /

Introduction to Rust and WebAssembly


This article is part of a serie:  Rust and WebAssembly

  1. Hello World with Rust and WebAssembly
  2. Introduction to Rust and WebAssembly

In this article, I would like to talk about two technologies I’ve been playing with recently: the Rust programming language and the WebAssembly standard.

I’ll start by presenting each of these two technologies and which problems they are trying to solve. Then, I’ll explain what are the advantages of a Rust-powered Wasm module, and why it can be useful. Finally, I’ll provide links to interesting documentation.

WebAssembly

Since many years, client side web applications, implemented in JavaScript, have been becoming larger and larger. Even with the ever improving performances of web browsers (especially thanks to the work of Google on its V8 JavaScript engine), JavaScript has been hold back by performances. Optimizations are not endless, and JavaScript can not be made much faster: it is an interpreted language after all.

From asm.js to WebAssembly

A first experiment, named asm.js, has tried to take a radical approach, and remove as much abstraction as possible, to enable new optimizations. This worked by defining a subset of JavaScript which could be heavily optimized. Other languages (such as C) were then compiled/transpiled into this JavaScript subset, and executed by the browser’s JavaScript engine. Performances were greatly improved (and reached 2x native performances), but it was still JavaScript.

WebAssembly has taken one step further, by defining an instruction set from scratch. A VM which can execute this instruction set is implemented in the browser. This system has been designed with modern knowledge, and performance and security in mind. Thanks to LLVM, many compiled language can be compiled for this platform, including Rust.

WebAssembly logo: a blue square with "WA" inside.
WebAssembly Logo - CC0

WebAssembly without web-browsers: WASI

The execution engine can be extracted and run non-web applications (remember, any language can be compiled to Wasm, instead of x86_64-linux-gnu). In this case, Wasm uses an interface, WASI (WebAssembly System Interface), to talk to the kernel and execute system calls, in order to read files, use the network, or anything else.

As a comparison, WASI offers similar features as a standard VM or Docker. And this is a big deal, as Docker’s creator puts it:

If Wasm+WASI existed in 2008, we wouldn’t have needed to created Docker. That’s how important it is. WebAssembly on the server is the future of computing. A standardized system interface was the missing link. Let’s hope WASI is up to the task!

Solomon Hykes

A great future

I think Wasm is a very powerful technology and is here to stay. I’ve no particular interest in writing JavaScript, and Wasm enables one to execute (almost) any language in the browser. This has many advantages which I’ll detail in the Rust on Wasm section. It also defines a common interface for desktop and server applications. This improves security and greatly simplifies the work of system administrators.

You’ll probably hear about it again in the future.

Rust

Rust is a (not so) new language initially designed by Mozilla, which has been gaining a lot of momentum recently. It shares many similarities with C/C++, but with a focus on safety.

In particular, it offers strong guarantees regarding memory safety: NULL pointers simply does not exist, and non existing data are checked and protected at compile time. Rust has the concepts of ownership and lifetime, and its borrow-checker ensures that a piece of data either has only one owner, either is read only. It is also responsible for allocating and deallocating memory. This is all done at compile time, which allows Rust to behave in a predictable way, without a garbage collector (which means no performance hit).

Additionally, Rust has many high level features such as arrays or operator overloading.

Rust features fully prevent many kinds of issues which exist in C: dereferencing NULL pointers, data races, double free and read after free, buffer overflows, etc.

A language empowering everyone to build reliable and efficient software.

Rust

Embedded systems

This language is promising for applications which need performance and safety (games, image/video/sound processing, etc). It could also be a good alternative to C for embedded systems and critical software.

In the aerospace industry (and others in which software critical is used), most of the code is written in C (for its predictable performances and large history) and Ada is used for the most critical parts.

If Rust’s performance proves to be comparable to C’s, and its safety to Ada’s, it could become a good alternative to these two languages.

Language maturity

Although some features are not fully stable (notably async), most of the language is quite mature. There are already many projects using Rust, for example Mozilla’s Servo.

To ensure that Rust is safe, it needs to be validated, like C and Ada are. This is the goal of the Sealed Rust project by Ferrous Systems. Their plan is to first specify the Rust Language, and then validate a Rust Compiler. Although I would love it, I don’t expect to see Rust in critical embedded systems anytime soon.

Rust on Wasm

I wanted to learn Rust for some time, because I think it could make me a better C developer, and because I think this languages has interesting features to overcome C’s shortcomings.

Wasm looks very attractive, and the prospect of being able to execute any language in the browser is very exciting.

Executing Rust in the browser has many advantages.

First, sharing code between the front end and the back end would save many people a lot of time. This is true for applications which share heavy client and server, but it is also the case for games and complex business applications.

JavaScript has some shortcomings, in particular concerning the type system. Rust could improve productivity by bringing more safety features.

Recruitment could be made easier as well. Instead of needing to recruit both a front end and a back end developers, only on Rust developer would be needed. This could streamline development.

Finally, performances are improved, which is great for games. Being able to run more ambitious games in the browser could save time when trying to make those games cross-platform.

Conclusion

Starting from the final choice (using Wasm and Rust) to get to the requirements (finding a project to work on), is in most cases stupid. Actually, stupid only if the goal is to answer a business need. In such case, one should start from the requirements and find the best technical solution to answer those needs. But in my case, my requirement is actually to learn, have fun, and use Wasm and Rust.

So, to play with Wasm and learn Rust, I have started a project: implementing the game of (French) tarot1. It might probably never be finished, but I will at least gain some experience with Rust. When I finish, or get fed up with this project, I’ll try to work on something more ambitious or low level (maybe a rocket guidance software).

While reading documentation and tutorials, I found a game made with Rust and Wasm: Pont. The code is actually quite short and more readable than it seems at first sight.

If you want to get started too, you should start here. Note: the setup is a bit complex, I’ll try to write a article with a hello world. Also, the docs are not obvious, but npm is not needed, you can skip it.


  1. French tarot has nothing to do with bullshit card reading. ↩︎