AssemblyScript: making WebAssembly more accessible to JavaScript programmers

Young girl walking over railway track by Johannes Plenio

tl;dr This is an introduction to AssemblyScript: I explain what WebAssembly is, why AssemblyScript maybe an interesting alternative to build WebAssembly for JavaScript developers and, finally, in order to compare JavaScript to AssemblyScript, I comment a small image manipulation project I’ve developed for this purpose.

WebAssembly is one of the biggest revolutions coming to the web, although it is neither Web nor Assembly. WebAssembly, also known as Wasm, is a fast, efficient, safe and low-level bytecode for the Web.

This means that, on one hand, it isn’t an assembly language but bytecode instead. Although both of them are similar in the sense that they are not high-level languages, they are easily understandable, which is something that does not happen with machine code. Thus, they can be classified into an intermediate language category between high-level languages and machine code. The main difference between assembly language and bytecode is that, the first one is created for CPUs while the second is created for virtual machines. That is, one is targeting hardware whereas the other is targeting software.

There is indeed a bytecode textual version, which is named WebAssembly Text Format (or just Wat!).

Additionally, although it’s usually said that Wasm is for the Web, the truth is that it’s not just for the web, because it can be also used for desktop applications, serverless or, even, Crypto and Smart Contracts.

Efficient

Using a Wasm module from JavaScript is as simple as it follows:

The following way to load a Wasm module suggested by Das Surma will allow you to use Streaming Compilation robustly. It will work even if the Content-Type is not correctly set to application/was (Firefox will normally fail, for instance) or even, if you are using Safari (which does not support instantiateStreaming yet).

There has been a lot of work on the Web in order to provide a safe environment that protects us from malicious intentions, and Wasm was designed with the same principles. For instance, as JavaScript does too, Wasm is executed in sandboxed environments that keeps it isolated from production environment. As a consequence, for example, it is necessary to use Web File API to access the file system, which is exactly how it needs to be done with JavaScript.

Bytecode

In order to achieve these goals, the authors of Wasm had to build something new (using asm.js as the starting point) instead of using LLVM, Java or .Net bytecode. There fore, they developed a new binary instruction designed to be a portable target for compilation of high level languages like C, C++ or Rust.

“Wat” should I do if I want to program WebAssembly?

(;
Filename: add.wat
This is a block comment.
;)
(module
(func $add (param $p1 i32) (param $p2 i32) (result i32)
local.get $p1 ;; Push parameter $p1 onto the stack
local.get $p2 ;; Push parameter $p2 onto the stack
i32.add ;; Pop two values off the stack and push their sum
;; The top of the stack is the return value
)
(export "add" (func $add))
)

C, C++, Rust and similar languages are common alternatives to make Wasm modules, but there is a new one for people that feel comfortable programming with JavaScript: AssemblyScript.

AssemblyScript

In order to illustrate how similar JavaScript and AssemblyScript are, I’ve prepared this small project where I manipulate a picture with code in vanilla JavaScript and in AssemblyScript compiled to Wasm. You can find it here: https://github.com/gonzaloruizdevilla/image-manipulation-assemblyscript

In the project, you will see a picture that it’s loaded inside an html canvas and several buttons that will apply different filters to the pictures when clicked. These buttons will execute the filter either with JavaScript or with the Wasm module generated with AssemblyScript.

App screenshot

Applying the different filters we obtain images like these:

Inverted image
Grayscale image
Emboss

In order to use the project, just clone it from Github, and then install AssemblyScript dependency and compile index.ts AssemblyScript file with the following instructions:

It´s interesting to note that, when a Wasm function is called from JavaScript code, the arguments of the call must be of the following types:

  • i32: 32-bit integer
  • i64: 64-bit integer
  • f32: 32-bit float
  • f64: 64-bit float

Obviously, that means that we can’t pass the image as an argument of the call. In order to be able to use a picture’s information from Wasm, first, it should be stored in a shared area of the memory that it will be created using the WebAssembly.Memory class. This shared memory object is used as an argument of the Wasm instantiating function as you can see in the following code:

Reserving memory for Wasm

Before calling a Wasm filter, the picture data in the canvas is retrieved and copied into the shared memory. After that, the Wasm filter is called, then the result is read and stored in imageData. Finally, we send imageData to canvas context, redrawing the images.

There are four different filter functions implemented in both JavaScript and AssemblyScript: invert, grayscale, sepia and convolve (this one is used to apply the blur, edge detection and emboss filters). As you can see below, they are very similar:

JavaScript version
AssemblyScript version

As you can see, the AssemblyScript code is extremely similar, but with types and working at a lower level, and this is what allows developers to leverage all the Wasm potential. So, now, it’s your turn to start playing with AssemblyScript and grow your confidence on Wasm technology, which is meant to become more and more important in web development in the coming years!

gft-engineering

GFT is driving the digital transformation of the world’s…

Gonzalo Ruiz de Villa

Written by

Engineer, Google Developer Expert , co-founder of Adesis Netlife and Kenobi Ventures. CTO @ GFT Group

gft-engineering

GFT is driving the digital transformation of the world’s leading companies. On here, our tech communities from all around the globe share their tips, tricks & insights with other developers.

Gonzalo Ruiz de Villa

Written by

Engineer, Google Developer Expert , co-founder of Adesis Netlife and Kenobi Ventures. CTO @ GFT Group

gft-engineering

GFT is driving the digital transformation of the world’s leading companies. On here, our tech communities from all around the globe share their tips, tricks & insights with other developers.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store