
The future of WebAssembly – A look at upcoming features and proposals - ColinEberhardt
https://blog.scottlogic.com/2018/07/20/wasm-future.html
======
vardump
I hope WebAssembly will not only be a web technology, but the de-facto format
for cross-platform high-performance embedding. Such as for plugins, scripting
and extensions.

Something you could send over the wire to the remote application and it could
execute it with high performance and reasonable security. Cryptographic
signatures can be used for more security sensitive contexts.

So one thing I'm really hoping no matter what happens to WebAssembly, that
_the external interface and requirements are kept simple_.

Minimal required dependencies, no built-in class library, etc. It'd be ideal
if WASM runtime environment is very lightweight, preferably just 100s of kB.
The smaller, the better. Especially some kind of dependency for Javascript
would be disastrous.

It'd be amazing if it was possible to run small ~10 kB WASM modules remotely
on a microcontroller, like Cortex M4+ or such, with say 64 kB of RAM. You
could add a lot of flexibility in some applications.

It actually looks very interesting for cross-platform "scripting", once
there's a good cross-platform optimizing compiler library for it.

From where I stand, currently the most interesting proposals of the listed
ones:

0) High-performance non-web "embeddability" with low memory requirements. (Not
actually listed, but very much desirable.)

1) Threading. Would greatly help performance and portability in some cases.
I'm a bit sceptical whether there's a way to add this after CPU speculative
attacks (Spectre, etc.) became known.

2) SIMD. Lots of filtering and data processing algorithms can greatly benefit
from this.

3) Tail calls / bulk memory ops.

4) Export / import mutable globals (and good module support in general)

5) Exceptions. (Minor, portability).

~~~
pocketaces
I hope not.

The subset of native (for example, x86) assembly that is equivalent to
webassembly is already perfectly secure. You just limit the native assembly to
pure computations without any system calls. It will also always be
significantly faster than webassembly. When it comes to the security of system
calls, then both webassembly and native assembly needs to make sure that
whatever platform-calls that are available are secure. webassembly have no
benefits over native assembly when it comes to this.

Also, I doubt that it will gain as much popularity as some people predict.
asm.js (the "original" webassembly) has been available for quite a long time
already (and the technology behind it have existed for very very long), and if
it were going to create a flood of developers targeting it instead of using
javascript, then I think it would have happened by now. Inertia when it comes
to development tools should not be underestimated and I doubt that all of the
web developers who have invested in becoming javascript "experts" want to see
the ecosystem change and see all of their "experience" and "expertise" become
worthless.

~~~
pcwalton
> The subset of native (for example, x86) assembly that is equivalent to
> webassembly is already perfectly secure. You just limit the native assembly
> to pure computations without any system calls.

You need portability on the Web. NaCl was abandoned in favor of PNaCl for a
reason.

~~~
pocketaces
No you don't.

The Web as a distribution method has supported the downloading of native
applications since forever. Instead of trying so hard to make it so that users
don't need to install native applications, then I think that it would be much
more optimal if development efforts instead went into making the native
installation-process much more streamlined. For example, browsers could have
some kind of functionality that makes it so that end-users do not need to
choose the correct type of executable themselves (such as choosing between
x86-windows7, x86-windows10, Linux, etc) and instead just click a single
installation button.

~~~
pcwalton
> No you don't.

How would we have made the 32-bit ARM-to-AArch64 transition if the Web were
not portable? Remember that Apple cut 32-bit support very quickly, and no
longer ships with it. For that matter, how could Apple have gotten away with
shipping a usable browser _at all_ on the ARM architecture in 2007, in the
native world?

Remember that the x86 architecture is proprietary to Intel and is covered by a
patent thicket. You'd be handing Intel a monopoly over the Web forever.

> For example, browsers could have some kind of functionality that makes it so
> that end-users do not need to choose the correct type of executable
> themselves (such as choosing between x86-windows7, x86-windows10, Linux,
> etc) and instead just click a single installation button

They've had this for decades [1].

[1]: [https://developer.mozilla.org/en-
US/docs/Web/HTTP/Headers/Us...](https://developer.mozilla.org/en-
US/docs/Web/HTTP/Headers/User-Agent)

~~~
pocketaces
You use 32-bit ARM assembly on 32-bit ARM, AArch64 assembly on AArch64, and
x86 assembly on x86. There is no handing over a monopoly to anyone.

While the mentioned browser functionality have existed for decades, then that
does not change the fact that for the past decade then almost everytime I have
had to download a native application I have had to select the correct type of
executable myself. So the argument still stands. Developers should implement
the mentioned functionality on a download page for their native application,
instead of trying to make everything a web application.

~~~
TomMarius
I think that saying what someone should be doing is very short sighted, it's
almost certain that they will not listen to you, especially since you're
making their jobs harder and it's unsafe for the end user. Instead, let's
focus on things that the developers actually want, like WASM, so we can have
something decent out of it; dismissing it is definitely not going to help and
WASM is already here to stay.

BTW how do you propose to safely run untrusted application with no built in
support of parallelization in parallel, maybe even on multiple machines? How
do you safely directly reference an object that is owned by another (again,
untrusted) module, again, maybe even on a different machine (e.g. using RDMA
through Infiniband)? These are just some of the possibilities that WASM is
offering.

------
a9t9
Just to mention a real life use case: We are using WebAssembly for the image
recognition features in our Visual UI Testing browser extension "Kantu".
Before switching to WA, we tested many other approaches, including WebGL (old
demo here:
[https://a9t9.com/demo/templatematching.js/](https://a9t9.com/demo/templatematching.js/)
).

Whatever we tried before, it was either too slow (pure Javascript), too
unreliable (WebGL) or required 3rd party installations (C++). Finally,
switching to WebAssembly solved all these problems.

~~~
cpeterso
Interesting that WebAssembly could have such a big impact on the viability of
the web version of your product! How much faster was WebAssembly than
JavaScript for your Kantu tests? Were the WebGL issues because not all uses
had WebGL enabled or because of GPU-specific quirks?

~~~
a9t9
Our initial tests were with standard template matching algorithms. With the
Javavscript implementation we were stuck in the 60 seconds+ range per image
search.

With WebGL it was ~0.5s on a "good" machine and ~6s or "did not work at all"
on a "bad" machine. We never figured out why it worked well on one machine,
but not so on others. Of course, I am talking only about machines with WebGL
enabled ;) This would have been a support nightmare.

With WebAssembly we are now in the 0.1-0.5s range per image search and it just
works. So far, we have had exactly 0 WA-related support issues, for both,
Chrome and Firefox.

~~~
cpeterso
60+ seconds to 0.1-0.5 is a pretty nice speedup! :)

------
haberman
Are these proposals "a la carte" or does each accepted proposal make the basic
WebAssembly spec bigger?

Like if the GC proposal is accepted, does every WebAssembly implementation now
need to support GC all the time? Or can a slimmed-down version of WebAssembly
still load modules that don't use GC?

------
markdog12
I gotta say, I'm surprised to see threads being mapped to WebWorkers. Are they
an appropriate target, being that they're heavyweight, with a lot of overhead?
Also, it seems like it'd be a nightmare for compilers to convert threads to
WebWorkers. I also noticed Chrome Canary has had WebAssembly threads via a
flag for a few weeks now, is that based on WebWorkers as well?

------
haberman
Is anyone working on a small, portable, reasonably fast standalone C
implementation?

I am looking for the Lua of WebAssembly implementations.

~~~
kodablah
To confirm, you're looking for an interpreter? Because most "C
implementations" of sorts would instead compile to a standalone binary. If you
are looking for an interpreter, while [0] appears out of date, [1] could
easily be consumed statically in a C lib and is basically as portable as a C
impl. Even better, compile it at runtime and then run it [2]. There's of
course the canonical OCaml one [3]. But it would not be hard to write one,
WASM is fairly trivial.

0 - [https://github.com/kanaka/wac](https://github.com/kanaka/wac) 1 -
[https://github.com/paritytech/wasmi](https://github.com/paritytech/wasmi) 2 -
[https://github.com/sunfishcode/wasmtime](https://github.com/sunfishcode/wasmtime)
3 -
[https://github.com/WebAssembly/spec/tree/master/interpreter](https://github.com/WebAssembly/spec/tree/master/interpreter)

~~~
haberman
> To confirm, you're looking for an interpreter?

I'm interested in an interpreter that is available as a library.

I'm also interested in a small, standalone JIT-compiled implementation, but
that seems less likely to actually exist.

Basically I'm looking for the Lua and LuaJIT of WebAssembly.

~~~
kodablah
I think refs [1] and [2] are those, but they may not quite be mature enough
for you yet.

------
munificent
WebAssembly sits at the crux of directly opposing forces:

If it goes higher-level:

* Compiled applications get smaller because each instruction corresponds to a higher-level semantic behavior and contains more information. Think how a virtual method call is a single instruction in the JVM but several instructions in x64.

* Compiled applications get smaller because runtime facilities can be baked into the browser and shared across all apps. GC is the big one but things like object representation, strings, "standard library" functions, etc.

* More host-level optimization opportunities open up. The JVM JIT can do lots of optimizations because it understands directly what things like interface and virtual calls are and doesn't have to try to reconstitute that information by pattern matching on lower-level instruction sequences.

If it goes lower-level:

* It's a viable target for more diverse languages and paradigms. You can compile other languages to JVM bytecode, but the less like Java your language is, the harder that becomes. The VM has a grain to it. WebAssembly, by virtue of having fewer things baked in, is more open to a varied languages. C/C++ are the big ones because any memory-safe instruction set makes it really hard to support those.

* More application-level optimization opportunities open up. Optimizing compilers can output code that's closer to the metal. They can take advantages of constraints in the source language that the VM may not know about and generate code specific to that.

* Peak execution speed is higher. If your instruction set lets you directly map to something close to what the CPU executes, you can take maximum advantage of it. Despite decades of JIT engineering, C/C++ are still the fastest for that reason.

* The instruction set is simpler. That makes it easier to implement, target, optimize, security audit, and build tooling for.

There is no Goldilocks instruction set that gives you all of these. Adding
instructions for GC is going to make it much more complex and is deadweight
for languages like Rust and C that won't use it. Defining how the GC works is
going to be really difficult given languages like Python (ref-counting), C#
(finalizers), etc. where specific GC policy decisions are user-visible.

Making the instruction set statically typed is what you want for low level
typed languages. But it makes it harder for dynamically-typed languages to be
implemented efficiently. Every dynamically-typed language that compiles to JS
gets to reuse the incredible JITs inside JS implementations because JS is
itself dynamically-typed. But if you compile, say, Python, to WebAssembly, do
you ship a Python bytecode -> WebAssembly JIT inside the application? Does
every language have to do that?

Having strings means you need to pick a string format, which is basically
impossible since every language out there makes different, incompatible
choices for string representation (null-terminated? length-prefixed? null-
clean byte-arrays? UTF-16? UTF-8? multi-encoding?). But _not_ having strings
means every app has to include a string library in its runtime and means you
can't reliably pass strings around in interop.

No amount of hard work is going to magically fix these because they are
directly opposed. I think WebAssembly is really interesting, but one of the
things that has always turned me off about it is that its proponents don't
often acknowledge the hard trade-offs that have to be made.

~~~
repolfx
Thanks. That's a really excellent way to describe things, probably the best
comment on this thread.

There's always a tradeoff between how much intelligence you put into a runtime
vs how much you have to ship with the app. In the limit WASM would turn into
"download and run an entire language runtime with every web page", which is
clearly suboptimal. Most likely compilation to JS will continue for the
forseeable future when possible for that reason.

One idea that could probably work very well is to write a WASM interpreter for
GraalVM. GraalVM has very high level constructs but can also support low level
manually memory managed code. They have one for LLVM bitcode already, but WASM
would probably be simpler to implement and with a more stable bytecode format.
Then C/Rust/exceptionless C++ could ship artifacts as WASM files, scripting
languages can ship source code, static managed languages like Java or Haskell
(eta) can ship JARs, and they can all interoperate and be compiled together.

I don't see a route to getting there with current WASM runtimes or just the
existing featureset of WASM though. As a portable ISA for distribution of
limited, OS neutral C-ish libraries it seems reasonable enough. As a future VM
for everything I can't see them beating GraalVM anytime soon. GraalVM has the
shared high level constructs, but it is able to also (eventually) compile low
level WASM/LLVM style code down to what a typical GCC like compiler would
create.

~~~
nine_k
Re shipping runtimes: caching exists. Right now you likely don't download a
copy of jQuery, or React, or many other common libraries normally used on web
pages. You have a few versions of them cached, and most of the time, there is
a cache hit.

I suppose the same will be true for WASM "runtimes" required by commonly used
languages: you will have 2-3 major versions of them (think Python 2 vs Python
3), and an automatic update when a new version is released.

Much like common JS libraries or fonts, these will be on CDNs, so they'll be
fast more-or-less local downloads.

------
deeg
I'm sure there's a good reason for this and I just don't know it: what's the
advantage of wasm over the JVM; i.e. why not just use the JVM in the browser?

I assume there are complexities in compiling C/C++ to the JVM but wouldn't
wasm have many of the same issues?

~~~
kodablah
Waiting for @steveklabnik to write his post on this as it comes up in all of
these threads. To give you a brief answer, the JVM bytecode is tied to JVM OO
use cases and carries with it a significant runtime library burden. There are
many many other details I can give you about how JVM bytecode is tailored to
Java the language, but suffice to say it is not simple and not generic.

~~~
steveklabnik
I’m hoping to get that out next week. I just gave a talk in Barcelona about
wasm today, so that took up all my time.

------
Feneric
Other languages can be compiled into WebAssembly, too, including Nim:
[https://news.ycombinator.com/item?id=17314581](https://news.ycombinator.com/item?id=17314581)

------
mrfusion
Will web assembly make it possible to do all your JavaScript stuff in python
instead?

~~~
notheguyouthink
Yes.. sort of. For that scenario, we need a lot of things in place that are
down the road for WASM. Technically it would work today, but you'd have to
ship a Python runtime with every "app". That's a lot of overhead, so much so
that it's basically a non-starter for many people.

In the future it _may_ work, because a built in GC is on the roadmap for WASM.
Unfortunately I'm not sure that it will work great for most scenarios. For
example, Go(lang) ships with its own GC which is very tailored to its use
case. Defaulting to a WASM GC could work, in theory, but would it impose
difficulties such as unexpected performance characteristics with longer GC
pauses or whatever?

There's a lot of edge cases that will have to be covered for this stuff to
work instead. Perhaps shared WASM binaries would be the best solution,
allowing runtimes to be offloaded and cached regardless of user land code
running.

~~~
Jach
When many websites are already shipping down megs of crap, I don't think the
few extra megs of a python runtime would matter that much to the end user,
especially if it's cached. Especially if it's marked by the browser as cross-
site 'cached' (perhaps by verifying a signature and installing it as a plugin)
so it's only done once per version. You can go further with more browser
support, for instance browsers could bundle popular runtimes with their own
distribution (Chrome + Flash).

~~~
crooked-v
> Especially if it's marked by the browser as cross-site 'cached'

That runs into the problems that have generally prevented browsers from cross-
site caching common scripts already.

------
7373737373
How probable is it that it will support multiple memories one day?

~~~
ColinEberhardt
I think that will come fairly soon - I forgot to mention that the reference
types proposal also include multiple table support
[https://github.com/WebAssembly/reference-
types/blob/master/p...](https://github.com/WebAssembly/reference-
types/blob/master/proposals/reference-types/Overview.md)

------
s-macke
I am still a little bit disappointed that most transpiled languages have to
provide a litte operating system to run their code including memory management
and garbage collection. With this overhead webassembly can be even much slower
than Javascript (downloading, compilation, simplified but slow memory
management). If I remember correctly Rust adds 200kB of code to the
webassembly binary. For me it was only possible to produce small binaries with
emscripten C without any includes (bare metal).

The proposals look promising and might reduce this overhead somewhat. However
I don't think they will manage to design the virtual machine that is able to
run all major rogramming languages efficiently. What ab0out features such as
longjmp and goto in C?

~~~
steveklabnik
That is incorrect; the smallest rust produced binary is ~100 bytes. Only the
code you use is included; if you want an allocator, choosing a smaller one is
a good idea, for example.

We are usually significantly _smaller_ than emscripten for the same code.

~~~
s-macke
I just programmed a function, which added 2 numbers and compiled it and got a
huge binary. But maybe I did something wrong. I will try again. Thanks.

~~~
the_duke
Which target are you using?

~~~
s-macke
I can tell you in a few hours. But it would be easier if you provide me the
correct compile options to produce such a small binary for trivial functions.
Target was of course the webassembly target.

~~~
steveklabnik
There's two wasm targets; one with emscripten, one without. It sounds like you
were using the one without, which is generally the right one.

