In the beginning, God created the Bit and the Byte. And from those he created the Word.
And there were two Bytes in the Word, and nothing else existed. And God separated the One from the Zero, and he saw it was good.
A long, long time ago, developers were using machine codes to program computers. It was hard to keep all of them in mind, easy to make a mistake, and almost impossible to read. After struggling with machine codes, they created mnemonic codes to refer to machine code instructions aka Assembly language. The assembler was responsible for translating assembly language to machine codes.
The complexity of the systems kept growing and so higher-level programming languages were created to hide this complexity behind abstractions. The first widely used high-level general-purpose programming language was FORTRAN, invented in IBM in 1954. Then we got BASIC, C, C++, and many more. We are still using compilers to translate high-level languages into machine codes. The problem is, that compiler produces architecture-specific code, so if you have compiled your C program to x86 architecture, you cannot run it on AMR processor (due to a different set of available CPU instructions).
To solve this problem, developers have created another set of abstractions – bytecode (aka intermediate language) and virtual machines. Bytecode is the instruction set of the virtual machine, that is architecture-independent. Translating bytecode to a CPU specific instructions is a responsibility of a virtual machine. In this way, we can write once, run anywhere! C# and Java are good examples of this concept.
The Internet Era
We need to go deeper – Web Assembly
How does it work?
Here we import function
i and export function
;; simple.wasm (module (func $i (import "imports" "i") (param i32)) (func (export "e") i32.const 42 call $i))
After the page is loaded in the browser, you can load the .wasm file as a regular resource and do the following to call the wasm function:
- Get the
.wasmbytes into a typed array or
- Compile the bytes into a
- Instantiate the
WebAssembly.Modulewith imports to get the callable exports
- Call function from the module
Another important concept is Linear memory – a low-overhead “shared memory” between JS and WebAssembly. You can pass the data to do some calculation on a WebAssebmly side and pass the result back to display it on the web page.
As you can see, WebAssembly is showing better score in all browsers, the biggest difference between JS and WASM is in Firefox, Edge is the slowest of all.
Browser support, limitations, and future plans
At the moment, the MVP version of WebAssembly is supported in all major browsers (including iOS and Android). You can compile C, C++ and Rust code to Web Assembly.
As well, right now you cannot interact with DOM from WebAssembly code, so all DOM interactions should be done via proxy JS function.
There are future plans to allow WebAssembly modules to be loaded just like ES6 modules (using
<script type='module'>) as well as adding multithreading support, garbage collection, and DOM interaction.
Since most of the modern applications are running in the browsers, I think it’s a great step forward to bring other languages in the game. I can’t wait to see the next versions of WebAssembly standard and the variety of features it will bring us.