Mystery project on European JSConf

At this year’s JSConf in Europe, Lin Clark from Mozilla showed us a mysterious project, an arched rainbow gate (video portal), which is actually a canvas made of 30,000 colored LEDS that display light animations, And controls the lighting animation of the Arch via a WebAssembly module written by Rust. Lin also gave a WebAssembly talk at JSConf in 2017, in which she noted that 2008 was an inflection point in the JavaScript execution efficiency curve, with many browsers adding just-in-time compilers, JavaScript performance has increased tenfold, giving JavaScript wings to fly on the browser side, server side, and client side. Lin points out that the birth of WebAssembly could be the next inflection point in the curve. This shows how serious Mozilla is about WebAssembly.

emm… Let’s go back to 2018. Lin explained how to use the WebAssembly module to control the lighting animation of the Arch. Let’s take a look at how this is done.

To contiguate space or time with bytes

The space we live in is a three-dimensional space, and if we add the dimension of time to it, it becomes a four-dimensional space.

There is no way for a computer to understand this four-dimensional space, and for a computer to “understand” it, we need to reduce the dimensions of the four-dimensional space. The first is the time dimension, which can be done with frames. The display screen is like a page-turning book, with each frame equivalent to a page.

On the web side, 60FPS is the requirement for smooth display of animations through the screen. That means you have 60 different screenshots — animated freeze-frames of 60 points in one second. Imagine a series of snapshots representing three dimensions.

Now to go from three dimensions to two dimensions, what we need to do is flatten the space onto a square paper.

Now that it’s down to two dimensions, we need to reduce it again. Take each line of the square paper and join them in order.

Now that it’s down to a row of pixels, we can put it in memory, because Linear memory is basically a row of small cells. That means we’ve gone down to a one-dimensional structure, but still have all the data that represents two, three, or four dimensions. It’s just that now they’re presented in a continuous, linear way.

Linear Memory

Linear memory is one of the primary means of communication between JavaScript and WebAssembly, and both the WebAssembly and the JavaScript that runs it can access this object. Linear memory is actually a variable-size ArrayBuffer object, which is essentially a contiguous, byte-addressable chunk of memory.

To animate the “arch” mentioned above, the JavaScript tells the WebAssembly module: “Ok, now fill in the animation.” This is done by calling WebAssembly function in JavaScript.

Fill each pixel in linear memory with a color via WebAssembly.

The JavaScript code then takes the color data and converts it into a JSON array and sends it to the Arch.

Let’s take a look at how to use this data in JavaScript.

Fill the linear memory with color

Linear memory is really a big row of zeros and ones. If you want to give meaning to these zeros and ones, you have to figure out how to split them. All you need to do is create a TypedArray for AarryBuffer that tells JavaScript how to segment the bit lines in AarryBuffer. It’s like the grid that’s being drawn around these bits saying to them that those bits belong to those numbers.

For example, if you use a hexadecimal value, your number will be 24 bits wide. So you need a 24-bit grid. Each cell contains one pixel, and the smallest cell that can hold 24 bits is 32 bits (INT32), so we will create an Int32Array view on this buffer. It wraps the bytecode of this buffer into the grid. In this case we need to add some white space to fill the grid from 24 to 32 bits.

If we use RGB values, these cells will be 8 bits wide. To get an RGB value, you will use every three cells to represent your R, G, and B values. That means you need to walk through the cells and pull out the numbers inside them.

To use linear memory directly, you need to walk through it manually (and write some code), pulling the data out of it and storing it in a more reasonable data structure. For this project, that’s not too bad. Color mappings are numbers, which are relatively easy to represent using linear memory. The data structures we use (RGB values) are also not very complex. But if you’re working with more complex data structures, dealing directly with memory can be painful. It would be much easier if you could just pass a JavaScript object to the WebAssembly and let the WebAssembly maintain it. All you need to do is add a very small library (WASM-Bindgen).

Use wasm – bindgen

Wasm-bindgen is a library written in Rust that makes data interaction between JavaScript and WebAssembly modules much easier. It wraps the WebAssembly module with a JavaScript wrapper. This Wrapper knows how to write complex JavaScript objects to linear memory. Then, when the WebAssembly function returns a value, the JavaScript Wrapper takes the data from linear memory and converts it back into a JavaScript object.

To do this, it looks at the function signature in Rust code and calculates the required JavaScript. This applies to built-in types like strings, as well as types you define in your code. Wasm-bindgen converts Rust structures into JavaScript classes. The tool only supports Rust in the current version and will be refined to support other programming languages (such as C/C++).

After the

This project is a great place to start learning about WebAssembly, because we can make an impact in the real world by writing our own WebAssembly modules. Isn’t it cool and fun? Want to experience the fun of writing a WebAssembly module to control light animations? Mozilla has helped us prepare The Arch online environment, so get started!