
A look at asm.js and the future with WebAssembly - petethomas
https://mayaposch.wordpress.com/2015/12/30/a-look-at-asm-js-and-the-future-with-webassembly/
======
AshleysBrain
The author seems to assume asm.js/WebAssembly are only for games and not
useful for anything else: "It’s so limited and specialistic that beyond
porting games to run inside a browser using WebGL and LibSDL, it’s hard to
think of suitable use-cases."

This is not the case at all - there are loads of use cases outside of games,
and some of them have more straightforward dependencies (e.g. no graphics or
networking). Take a look at Alon Zakai's github [1] where there are some
examples of various libraries compiled to the web which include physics
engines (ammo.js, box2d, cannon.js), database engines (SQLite), programming
language VMs (lua, j2me), parsers (xml.js) and more (LLVM, clang, zlib, GMP,
image/audio/video decoders...)

In some cases these are more-or-less drop-in replacements. For example I've
pretty straightforwardly dropped in asm.js compilations of Box2D and zlib and
gotten massive performance improvements over the handwritten versions with
minor effort. In the Box2D case, it was so good we integrated the result in to
a commercial product (Construct 2). I think it's also a compelling idea to be
able to support new image and audio formats on the web at native-like speeds
without requiring browser support, e.g. compiled WebP or Ogg Vorbis decoders.

I think the author has simply not done enough research around uses of
compiling to the web to recognise its immense value.

[1]
[https://github.com/kripken?tab=repositories](https://github.com/kripken?tab=repositories)

~~~
vanderZwan
> programming language VMs (lua, j2me)

Since these are garbage collected languages, wouldn't it make more sense
compile to plain JavaScript, treating that as VM-bytecode, and avoid doing
things that slows down JavaScript VMs?

~~~
azakai
Not necessarily, since their GC semantics might differ from JavaScript. For
example, if they have finalizers, then compiling into JS isn't an option.

Other semantic differences might also make this hard or impossible. Compare
pyjamas to pypy.js, for example - the former compiles to JS, but has known
differences from proper Python semantics (long bignums), while the latter is a
straight port of a Python VM, so the semantics are identical.

------
bobajeff
This article makes the mistake of buying into the idea that WebAssembly has
anything to do with NaCl. It's not. It just had some NaCl people working on it
(along with emscripten Asm.js people and others).

When it's released it'll map to asm.js and have most of it's limitations. Many
of the limitations he ran into (no raw socket access, system library access)
were related to the API limitations imposed by the browser's security model.

Also WebAssembly is pretty far along as they have drafted a specification and
have prototype implementations in all the major JS engines. They also have a
LLVM/Clang backend.

~~~
pcwalton
That's right. wasm is just like asm.js, plus the possibility of shared-memory
multithreading. It has far more in common with asm.js than it does with NaCl,
contrary to the conclusions of the article.

Threading and being a binary format instead of a text one aren't differences
as fundamental as the difference between the Web APIs and NaCl's Pepper. Many
of the complaints, as you point out, are about the Web APIs, and unlike NaCl
Web Assembly is fully committed to the Web APIs (as it should be).

~~~
azakai
To be fair, asm.js already has significant progress towards shared-memory
threads [1]. That will finish standardization and ship long before wasm has
threads.

I would say that the main difference between asm.js and wasm is, as you
mentioned, that wasm is a binary format. That will allow far smaller
downloads, and far faster startup times.

The second main difference is that wasm is a new formal standard, with all
vendors involved, so we should see consistent performance across browsers.
Unlike asm.js which was a pure JavaScript optimization, so different browsers
optimized in different ways, leading to large variability (which decreased
over time, but remained significant, e.g. on specific things like memory
growth, which was abandoned due to that).

[1] [http://kripken.github.io/emscripten-
site/docs/porting/pthrea...](http://kripken.github.io/emscripten-
site/docs/porting/pthreads.html)

------
azakai
Some notes:

1\. Emscripten/asm.js supports the defined behavior case of setjmp/longjmp.
What is not supported is jumping up an already unwound stack, which is
undefined behavior. This is somewhat commonly-seen undefined behavior, though.

2\. I don't think it's fair to say that function pointers are "hairy at best,
broken at worst." Again, this is a case where we do not support undefined
behavior. But perhaps most importantly, most real-world code is properly
portable and just works. When not, we have tools that help figure things out.

3\. It's not true that everything must be compiled into one massive JS file,
Emscripten/asm.js also supports dynamic linking, [1]. However, the default is
a single file, because then it can be more fully optimized.

4\. There is already threads support, [2]. It works, and progress in the
standards bodies is going well. The main issue is waiting for browsers aside
from Firefox nightly to support it, but that's coming too.

A final note, I don't think the reason most asm.js use cases have been games
is because the technology is only suitable for games. First, there are a bunch
of non-game use cases already (for example, I've seen sites use asm.js for
encryption, education, emulation, codecs, non-game WebGL sites, etc.,
including on major sites like Wikipedia [3]). But perhaps more importantly,
games are already on the web, so they have a clear business model and use
case. And, they are on the web mostly in the form of plugins, and plugins are
going away, so they have to move to JavaScript.

[1]
[https://github.com/kripken/emscripten/wiki/Linking](https://github.com/kripken/emscripten/wiki/Linking)

[2] [http://kripken.github.io/emscripten-
site/docs/porting/pthrea...](http://kripken.github.io/emscripten-
site/docs/porting/pthreads.html)

[3] [https://brionv.com/log/2015/08/09/video-decoding-in-the-
java...](https://brionv.com/log/2015/08/09/video-decoding-in-the-javascript-
platform-ogv-js-how-u-work/)

------
Matthias247
I think the main takeaway is: Writing code for asm.js/webassembly is not easy,
and there might be a serious porting effort from existing C++ code. But I
think that's nothing really new for C++ developers, differences in data types,
OS APIs (e.g. for networking), allowed threading models, allowed exception
handling already exist in a lot C++ target platforms. When you look at the
embedded market it gets even worse. What I mean is that writing cross
plattform C++ code is never easy, and that's not due to webassembly.

Still webassembly will be very helpful for some applications or even only
libraries which have very high performance requirements. And porting some
existing desktop applications might be easier than completly rewriting them to
JS. But I guess for most websites and webapplications [transpiled] JS will be
the more productive choice.

I found the "there is no main loop" comment not that fair, as I think
javascript is one of the few languages which has a mainloop (aka eventloop)
already built in. It's not a spinning loop like what you would build in a C++,
but continously enqueing the main loop iterateration handler in setImmediate
or similar should give the same result.

------
forgettableuser
I expected a fluff article by a high level JavaScript programmer buying into
all the optimistic promises of WebAssembly.

Instead, this is actually one of the best articles I've read about
WebAssembly. The author approaches it from a C/C++ background and investigates
what it means to write applications from that mindset, revealing the huge
limitations of asm.js. Then the author turns to WebAssembly and gives a
sobering look of how immature that project still is.

~~~
anonx
You mixed it up. Actually, it's usually "high level JavaScript programmers"
who are "trying to reveal the huge limitations". Because they are not happy
with the fact something else can be used for client-side web-development other
than JS.

~~~
patates
I'm really disturbed by this clueless Javascript developer stereotype being
repeated over and over. I know there are many more beginners in the js world
than others but any time there's a js alternative being discussed, I read
comments in the tune of "haha now js developers will be useless finally" and
then I wonder who is being threatened by whom.

Please be more welcoming. We don't have enough programmers, no one is taking
anyone's jobs away.

~~~
J_Darnley
Utter lies. There are plenty of programmers around.

~~~
matthewmacleod
I'm not sure that follows. It's increasingly difficult to hire skilled
developers.

------
flohofwoe
Good article. If the limitations of the web platform are taken into account
from the beginning when writing multi-platform C or C++ code, and one doesn't
go crazy with C++ templates, it actually is not too bad. Porting a huge
existing code base with many external dependencies is quite another topic.

I found the performance of asm.js in current JS engines the least limiting
factor, instead it's the higher level APIs like WebGL, WebAudio that become
the limiting factor.

Also, existing (game development) middleware hardly focused on reducing code
bloat so far, which then results in huge Javascript blobs (but also huge
native executables).

I've started a little while ago writing a low-level C++ engine from scratch
with all of this taken into account (here:
[http://floooh.github.io/oryol/](http://floooh.github.io/oryol/)) where the
size of the Javascript blob is (roughly) in the same ballpark as a three.js
demo (minified and compressed three.js is around 100kByte, Oryol 3D samples
start around 90 kByte.

So basically: asm.js and WebAssembly yay, HTML5 APIs nay :)

------
venomsnake
I always though that the idea was to write the performance critical parts in
C++ and trans/com/whateverpile them to asm.js

A lot of the criticisms come from fundamental limitations that are here to
stay. Browser security, JS spec and so on.

The best approach for JS multithreading problem is to create a PureJS spec
that has no side effects. This code will be easier to be multi threaded.

------
huuu
_JavaScript is a single-threaded, prototype-based language with no real
concept of scoped variables and the like._

Is this true?

Webworkers is a multithread concept and as far as I know all variables are
scoped but maybe not like they are in C.

~~~
dbattaglia
I think they meant to say block scoped variables. In js everything is function
scoped or global (until you get to ES 6 "let" and "const" variables).

As far as web workers, they are very restricted/isolated compared to regular
shared memory threads In other languages.

------
frik
Asm.js is okay, but with WebAssembly we will see more and more websites be a
binary blob. (I am not speaking about C++ to WebAssembly, but
Java/C#/Typescript/CoffeeScript/Dart/etc to WebAssembly). Instead of
transpiling their languages to Javascript they will compile it as WebAssembly.
This will be a tipping point. Is going back to MSNv1 or AOL style times is a
good thing? In the end it's a real threat for the open web. Well let's hope
this will never happen. Google will have the power to regulate them, by
lowering their site rank.

~~~
Animats
There will be a very few really good applications of this. But this will be
used mostly to obfuscate code that's doing something hostile to the user.

Look at WebGL. There's a site which lists the best WebGL sites.[1] Most of
them are demos. Some which aren't:

\-
[http://breakthrough.nationalgeographic.com](http://breakthrough.nationalgeographic.com)
\-- a menu system which puts you inside a sphere. Somebody really liked
Lawnmower Man.

\- [http://histography.io](http://histography.io) \-- a timeline of history.
Only works on Chrome or Safari.

\- [https://www.rudys.paris/](https://www.rudys.paris/) \-- a shoe store.
Doesn't seem to have any 3D; they just seem to be using WebGL for zooming.
Takes forever to load, and they broke the Back button.

\- [http://www.thehappyforecast.com/](http://www.thehappyforecast.com/) \-- an
interactive "happiness map" of London. But it's just an overly fancy 3D menu.

\- [http://www.webglgames.com/](http://www.webglgames.com/) \-- Deadtrigger 2
(zombies), They Will Eat You (more zombies), X-Wing (the 80s called, they want
their arcade game back.)

You could do most of this stuff in Flash, and it would load much faster.
Browsers now have more technology than use cases.

[1] [http://cssnectar.com/css-gallery/nominees/site-
features/webg...](http://cssnectar.com/css-gallery/nominees/site-
features/webgl/)

~~~
chc4
PLEASE never use "You could do most of this stuff in Flash" as an argument
against WebAssembly or, uh, any other technology. Flash is a 3rd party, closed
source, proprietary plugin. Aspiring to replace it with something slightly
better at the very least is worth doing.

All else being equal, would you rather have a .swf binary blob that depends on
Adobe, or a WebAssembly binary blob that follows a well defined internet spec
and independent implementation by multiple authors?

~~~
Animats
There are non-Adobe Flash players. The format is well understood. Some
commercial video games use Flash for the non-3D GUI. They don't use Adobe's
player, but they use Adobe's authoring tools, which are graphics-artist
friendly.

[1] [http://lightspark.github.io/](http://lightspark.github.io/) [2]
[https://en.wikipedia.org/wiki/Gnash](https://en.wikipedia.org/wiki/Gnash)

------
IshKebab
Minor correction: you can use UDP, or at least networking with UDP-like
characteristics (unreliable, packet based, low latency).

This is because there is a WebRTC data channel you can use that uses SCTP.
Emscripten emulates UDP on top of SCTP (which should be just a few bytes
overhead per packet). Emscripten also includes the excellent enet networking
library which let's you multiplex multiple reliable and unreliable channels on
the same connection.

It's kind of a crazy multi-level hack (enet->UDP->SCTP->UDP->C++->JavaScript)
but it works well.

~~~
Matthias247
But this would require the remote peer to utilize the same protocol
encapsulation (UDP->SCTP->UDP), wouldn't it? This means due to browser
limitations you can never directly speek an existing UDP/TCP protocol besides
HTTP/WS.

~~~
IshKebab
Yes that's true. I think it is not too much of a limitation though. The major
use of UDP is games and if you're writing a game you control the whole
protocol anyway.

------
muppermeister
Throwaway to vent. Ignoring the current technical positions (there's less than
meets the eye). WASM is a vanity project by consummate politician working the
promo committees. I'm tired of these types ruining the company I've worked for
over a decade. Bourbon at the desk for peer massaging cocktails. Flying around
for face team with people in nice places. Blowing smoke on standards committee
BS. It's not about delivering for the company it's about the next grant.

------
saurik
...first using Visual Basic Script, JavaScript, ActiveX and Java, then
basically just JavaScript. This half-baked language grew from a quick addition
by Netscape to keep up with the competition into the center point of the
modern web, being forced into roles it was never meant or designed for.

I don't see how JavaScript was designed to "keep up with the competition".
Java came first, as part of Sun's HotJava browser, and later as a native
plugin for Netscape using (I think) their proprietary NPAPI (though it might
have simply been welded into the client, to support the next part). Then
JavaScript was built by Netscape, with direct access to Java via LiveConnect.
Finally, Microsoft, to support all the new features being dumped into the web
by Netscape, added VBA to Internet Explorer as "VBScript" with a separate
JavaScript-compatible-ish syntax called JScript. (Later, under pressure from
Microsoft, Netscape worked with them to file an international standard.)
JavaScript was not a way to catch up: it was a game changing move, and one of
the great innovations of Netscape (as opposed to most of the stuff they either
implemented or refused to implement, which led to their delaying CSS and
forcing HTML presentation markup on the world).

------
shadowmint
To be fair, if you have a good read of
[https://github.com/WebAssembly/binaryen](https://github.com/WebAssembly/binaryen),
you'll find the OP is pretty much on the ball; there's no easy way to compile
to web assembly from (language here), and even if you do, there isn't really
any easy way to run the result other than compiling it back to asm.js

...and yes, asm.js certainly has its fair share of limitations, and problems.
but...

    
    
        I’m more interested at this point to see what other approaches to create 
        the new web-based apps of the (near) future have been dreamed up by people 
        so far. Something which does not involve abusing a flawed scripting language’s 
        runtime to do unspeakable things.
    

Like what?

What people?

Who's _actually_ working on _any_ other solution to this problem?

I get that Web Assembly isn't going to solve your need compile a C++
application to run in a browser without modifying it; but... I'm pretty sure
that's not the goal.

The goal is to have some way of making extremely high performance parts of a
web application, without resorting to an unsafe propriety vendor plugin or
breaking backwards compatibility; and (possibly) allowing a new category of
'compile to js' languages to exist that can target web assembly rather than
javascript, which (may, arguably) be easier to implement, technically.

What's the alternative? Web components? That's been a great success. The
polyfill only occasionally destroys firefox and its _technically not possible_
for it to implement some of the features, so lots of people (ie. no one) is
using it.

Dart? I'm not even going to talk about that.

Another browser plugin? Native apps and no more web apps at all?

Come on, it's easy to complain, but unless you've got a tangible alternative,
cut them a bit of slack.

The web assembly stuff is coming along pretty darn fast, and lots of players
are involved. It'll be a big deal before you know it; I think it's pretty fair
to be excited about it.

~~~
Lerc
I have certainly given this a great deal of thought. What is needed? How could
we get from here to there?

People have often called for a ByteCode vm. This has been rejected over and
over again. Bendan Eich in particular has repeatedly argued against bytecode
in ways I found to be quite disingenuous. He has variously used Java to imply
one bytecode being unsuitable means all bytecodes are unsuitable, or suggested
if you want bytecode to make a bytecode VM in JavaScript (even using DCPU16 as
an example), or that it is too late for a new standard, or that. No bytecode
would be accepted by all browser makers (which I took to mean 'not on my
watch'). I have yet to find the arguments against a bytecode VM to be
convincing.

I think it would be well worth making a few different candidate bytecode VMs
to give the platform a chance in the field. Such VMs are not hard. In the case
of the DCPU16 (A imaginary CPU created for a project Notch was working on) it
took less than 48 hours for emulators to appear and just under a week for the
first compiler. A VM that occupies a similar space to Javascript has its own
particular needs.

In a different direction Maxime Chevalier-Boisvert argues for a Control Flow
Graph representation [http://pointersgonewild.com/2015/08/02/javascript-is-
the-c-o...](http://pointersgonewild.com/2015/08/02/javascript-is-the-c-of-the-
web/) Which if the Webassembly approach is to be taken this does seem more
sensible than a AST.

The cooperative multitasking aspect of JavaScript has been a bugbear for all
too long. I have argued for a preemption mechanism of some sort that would fix
the dependency on a main loop event pump. I have half a specification written
as a proposal, but I suspect people will fight the idea tooth-and-nail.

Ideally a solution should encompass concurrency as much as preemption. I kind
of like the idea of A bytecode VM with an arbitrary number of virtual CPUS. A
fork instruction to launch a new CPU. The VM host is free to run them on
however many actual cpus as it sees fit.

