Asm.js, universal application compatibility

This subset of JavaScript defined by Mozilla gives applications and games near native code speed.

The value of a virtual machine in a browser, which allows you to compile and run different languages ​ ​ on all operating systems, has long been considered. This idea took shape thanks to the Mozilla developers, and Asm.js was implemented in SpiderMonkey in 2013.

Capture of Unreal Engine 3 video with Asm.js

Unreal Engine 3 with Asm.js video

This is not actual bytecode, but a subset of JavaScript that is compiled and optimized for speed. Asm.js code is compiled by AOT (once and for all - before changing sources), while JavaScript code is compiled by JIT, on the fly.

Various statically typed languages ​ ​ can be compiled into LLVM bitcode, then using Emscriptem to convert it to Asm.js. Since the source code is already optimized, this produces faster JavaScript, and Asm.js also provides a speed that is twice as slow as binary, but ten times faster than JavaScript.
The whole application can be converted to Asm.js, or just a library from another language can be used by a JavaScript program.

Together with game manufacturer Epic, Mozilla has implemented the Unreal Engine 3 3D engine in Asm.js. This prompted V8 developers to optimize Chrome's JavaScript compilers and Node.js for Asm.js. Opera is also optimized for Asm.js code. Microsoft, for its part, announced the introduction of Asm.js in Windows 10 and is partnering with Mozilla to achieve this goal.

Since the last optimization in December 2013, Asm.js code takes 1.5 times longer to execute the same program than native code.

Asm.js is implemented in Microsoft's new Edge browser using Mozilla. This was discussed in several company posts, including one titled: Bringing Asm.js to Chackra in Microsoft Edge.

Features

Diagram of compilation to Asm.js
From C to LLVM bitcode to Asm.js

Asm.js is JavaScript compatible and does not provide additional functionality. However, for validation and compilation, it must contain only a subset defined by the specification.

Asm.js can only be used if the compiled language has static types, because this is where Asm.js finds its speed. Instead, the dynamic language must be compiled into simple JavaScript to run in the browser.

Asm.js vs. Native Client vs. WebAssembly

Which solution to prefer: Asm.js or NaCl, in other words, programs compiled into bitcode for LLVM, which also run in the browser?

A program for NaCl, even if it runs in a browser, must be compiled for each operating system. Therefore, the creator must provide multiple versions, which is not the case in Asm.js, which works the same on all systems. Knowing that Mozilla does not want to implement NaCl, this excludes it from Firefox, and apparently from Internet Explorer as well.

Asm.js works automatically because a JS compiler already exists in every browser. We know how to optimize it, and only a few minor modifications are required to run it on V8 or other JIT (Just-In-Time) or AOT (Ahead-Of-Time) frameworks.

The announcement of WebAssembly in June 2015 makes NaCl obsolete, especially since it will be supported by all browsers, while NaCl will not. Chrome only. But that's not the case for Asm.js, with whom it will coexist. In fact, the WebAssembly code will be similar to the Asm.js code initially, before the discrepancy. Wasm can be converted to Asm.js to work on older browsers. It can also be used in JavaScript or Asm.js modules.

Sample code

Define the strlen function and output the letters of the string.

JavaScript:

function strlen(ptr)
{
var curr = ptr;
while(MEM8[curr] != 0)
curr++;
return (curr - ptr);
}

var ptr = "demo";
var len = strlen(ptr);
for(var i = 0; i < len; i++)
{ 
document.write(ptr[i]);
}

Asm.js:

function strlen(ptr)
{ 
ptr = ptr | 0; 
var curr = 0; 
curr = ptr; 
while (MEM8[curr]|0 != 0) 
{ 
curr = (curr + 1) | 0; 
} 
return (curr - ptr) | 0;
}

var ptr = "demo";
var len = strlen(ptr) | 0;
for(var i = 0; i < len; i++)
{ 
document.write(ptr[i]);
}

I do not guarantee that document.write is validated, it is there for demonstration.

Emscriptem with the ASM_JS=1 option produces Asm.js code instead of JavaScript.

Documentation