asm.js and WebAssembly are two technologies used to run native code in the browser with great performance. They can be used to run game engines and complex computation on the client.
Take for example a simple expression like
A + B.
In statically typed languages if you know in advance that
B are, let’s say, integers, you simply issue a single CPU instruction for adding 2 numbers.
In dynamically typed languages when you say
A + B,
A can be anything: a number but also an array, object, a function.
And for example according to the spec if you add 2 empty arrays what you get in return is an empty string.
asm.js was an effort to run native statically typed languages in the browser.
asm.js is not meant to be written by hand.
Typically you take an existing source code written in C, C++ or Rust (or other low level languages like that) and do you translate it into asm.js.
However, when compiling to asm.js you add seemingly unimportant statements.
For example our original program was
A + B.
This is how it would look like in C or C++.
In asm.js it becomes
A|0 + B|0.
You might think adding
|0 doesn’t change the actual number.
It’s a no-operation.
A|0 it knows that it has to be a number.
So in other words we are casting arbitrary expression into a number and just-in-time compiler sees
number + number and it can deduce much more.
Just by looking at the source code it knows exactly how to add 2 numbers.
This is a great performance optimization.
Another performance optimization that asm.js adds is the lack of garbage collection. It’s not a coincidence that I mentioned C, C++ and Rust but not Go or Java - because these are the languages that have garbage collector. Programs translated into asm.js are not supposed to produce any garbage, meaning they should allocate and delegate memory on their own.
So once again asm.js is not another languages.
This translation happens using a tool called