WebAssembly is more than the web
words.steveklabnik.com
words.steveklabnik.com
For example, say you want to pass a 16-byte struct as an argument: how do you do it? Do you store the struct in memory and pass an int32 pointer to its start address? Or an int64 pointer? Maybe you encode it as two int64s? Once you've made a choice, good luck calling functions generated by a compiler that made a different one!
Another problem (in the web context) is blocking--Emscripten runs into this one. You can't suspend WebAssembly execution in the middle of calling out to an imported function. If a WebAssembly program wants to read keypresses interactively, it can't use a blocking function like read(). You have to pass the keypresses in at the outer level--or reimplement the call stack yourself like Go did (https://docs.google.com/document/d/131vjr4DH6JFnb-blm_uRdaC0...).
In general, WebAssembly code today is very tied to the JavaScript code that manages its interaction with the outside world. You can't just write a WebAssembly program that uses OpenGL. You also need to write the JavaScript that turns those calls into WebGL calls. I don't think this is a fundamental problem--we just haven't seen standards develop yet. As platforms start to define their API directly in terms of WebAssembly, without a JavaScript layer, we may see more of a "standard ABI" develop. Until then, it's hard to know what kind of APIs to target or support as an application or compiler writer.
Sounds like every architecture ever? There’s an architecture specification and then there’s an ABI. It’s common to only support some small number of sizes, x86 is a bit the odd one out these days.
It will take a decade to figure that out. Till then, wasm is good for single apps but not an ecosystem
This is more or less what SmallTalk has been doing for ages. The keyword for that is "image", in particular "single image".
And yes, it poses interoperability problems: http://www.ianbicking.org/where-smalltalk-went-wrong.html
You can't directly address and manipulate a single byte in WASM?
The blocking thing has some solutions in the browser, like web workers, but that'll be fixed in time too. Emscripten can already do the OpenGL -> WebGL thing, incidentally.
I am in no position to compare the two by any metric other than age. But I am old enough to appreciate how such ideas tend return every couple of decades.
Is this an IT thing, or is this phenomenon known in other areas, too?
[0] I am not even that old, and I do my best to not be grumpy.
[1] Yes, yes, Smalltalk, too. But Java - AFAIK - was the first language that aimed for platform-independent bytecode + network delivery of code (Applets, Webstart).
I don't think that's really fair to say at all.
Bytecode runs directly on the JVM which runs natively.
I'm not seeing how eithers closer to the metal.
Java was not then and still isn't today the fastest of languages. I think WASM's model of being a lower level VM is going to produce fantastic results. Heck I "ported" Lua to WASM[1] and it was pretty snappy compared to what I was expecting.
Other things like the browser being able to prewarm the vm and other first class citizen type support will hopefully lead to more success.
Webasm is basically "write any code once, run anywhere". It models a very low-level CPU-like environment that the code fully controls at the byte level, so even runtime language VMs can run in such a model without harsh slowdowns. While this literally offers fewer features than the JVM, it doesn't restrict which features the final runtime can implement.
This of course is all based on the assumption that you have a CPU-level environment that already bootstraps what you need (like C-based garbage collectors running underneath your dynamic language); or that you're running low-level, assembly-style code for speed reasons.
The current plan for the GC proposal is to allow skipping having memory heaps at all and talk about things in terms of an object graph and types. See comments here: https://github.com/WebAssembly/gc/issues/32
The important part of a runtime to me is the object model, and wasm basically punted on one for now.
It does have a notion of function imports & exports, so in the same way it allows you to do what you want, without specifying what you're going to do. For untrusted code, like in a browser, the environment can choose only to extend limited access. For trusted code, the environment can give access to more OS-level functionality. By webasm not specifying what functions to bind, but giving the ability to bind functions, it remains flexible and appropriate for wildly varying deployments.
Basically, zero cost exceptions let you unwind and capture the stack while not slowing down the common case, and multiple entry points let you build the stack back up without compiling a large amount of duplicate code. This gives you arbitrary stack manipulation without explicit stack manipulation support in the VM. It enables features that usually require special VM features, such as GC, coroutines, lightweight threads, (delimited) continuations, effect handlers, C# style async.
> Webasm is basically "write any code once, run anywhere". It models a very low-level CPU-like environment that the code fully controls at the byte level [...]
The only real difference between the JVM and WASM is that the JVM came from the academic world of "stack-based VMs are better" while WASM comes from the world of "register-based VMs are better".
Both have the same limitations that all the other VMs have. And languages are equally difficult to port to either of them.
What WASM has (and the JVM always lacked) is a compatible zero-friction VM installed on more or less every computer of this planet.
This is the _"everywhere"_ that Java and the JVM wanted but never had.
The main difference is that the JVM has a garbage collected heap and high level instructions for OOP, whereas wasm is lower level than C and only slightly higher level than assembly. Instead of an object model with GC you have raw pointers.
The benefit of WASM is that it's more general purpose because it's lower level. It's agnostic to your memory model, so you can have a not-Java object model if you want.
While this makes integrating WASM code into applications a little awkward—you're basically down to peeking and poking addresses in memory, see [1] for some code I wrote that does exactly that—this has some key advantages.
First, the WASM designers cannot make any opinionated decisions regarding what a library should look like. Providing a library is entirely up to the particular toolchain you're using (e.g., Emscripten, which provides a partial libc). And it's up to you what toolchain you use (if any). Second, this facilitates perfect sandboxing. All you're doing is placing your input on a sliver of memory, running your program on the virtual WASM CPU, and reading back the result from memory (and/or responding to callbacks).
[1] https://github.com/astoeckel/linprog2d/blob/b557f69d00dcadfe...
Bytecode formats for application executables delivery was and still is a common practice in the mainframe world.
Xerox PARC workstation, UCSD Pascal systems, IBM and Unisys mainframes as examples.
It literally is a fancy turning machine bytecode that anyone can write an interpreter/transformer to actual cpu bytecode if needed.
As more languages support WASM, I bet we’ll see more of the front ends written in other languages.
WASM is to the web what JVMBC (java bytecode) is to apps. The open java spec flourished a big ecosystem like Adobe coldfusion/railo, jython for python, Nashhorn/rhino for JS, Jruby for Ruby, Jphp for php, cscjvm for C# and a host of others.
In my university, my compilers course assignment was to write a subset of C compiler that would output java bytecode. It really made me love compilers and programming languages.
I predict a bright future for WASM
The only big difference is that, like many other "modern" ideas, mainstream computers are catching up with mainframes.
Oberon had that too to some extent -- at a time when the Internet was still in its infancy. Oberon wasn't a commercially viable platform though.
Also the canvas, webgl, webrtc, audio and video IO APIs that can hook into it are much better than anything Java had to offer.
This phenomenon is certainly known in fashion and, looking at the boom of populist and nationalist politicians around the world, most probably in politics too. I would even risk saying it's imprinted in human nature.
WASM is great because we can run it in V8 isolates which are much lighter weight than containers or full VMs.
i.e. the Chrome team, post-Spectre, are assuming that any value in a process' memory is readable by any code executing within that process.
[1] https://github.com/v8/v8/wiki/Untrusted-code-mitigations#san...
So, you could try to recompile the entire python ecosystem (interpreter, libraries, extensions, etc.) to wasm. This might be tricky right now because not all stuff readily compiles to wasm yet probably or uses gcc instead of llvm. Als, python has its own vm and compiler that would need to be reengineered on top of wasm.
Of course people have been working on moving python to llvm for some time so this might actually become feasible.
In fact, when I searched for a Python WebAssembly interpreter a few weeks ago I stumbled across this project [1]. So rest assured, people are working on this already.
"Write-once, run everywhere without paying someone for the privilege"
I think the term's overused, but this could actually be a "game changer".
Apple still control what API you can use in their mobile browser, and it's not like they are at the forefront when it comes to implementing Web API today, especially when they also forbid any alternative browser on IOS. Ultimately WebAssembly is limited by the API it has access to in the context of the browser (and the resources that are granted by the browser). All the promises of the "web as an app platform" have not been fulfilled yet.
IMHO WebAssembly will play a bigger role on the server, with nodejs for instance as it will allow portable native code distribution.
I'm not suggesting it's a way to build mobile applications without paying Apple. I'm suggesting it will be possible to deliver a product to (nearly) all platforms using 1) a single codebase and 2) bypassing walled gardens.
Personally I won't build products for an App Store anymore. They're too restrictive, expensive and time consuming to be worth it. But being able to, say, deliver a desktop product (either via the web or packed in something like Electron) and also deliver nearly the same experience to an iPad Pro would be huge.
Meanwhile I will keep my sandboxes.
Glad this is penetrating the wider consciousness.
Thanks for writing this, Steve!
This is basically what is happening with wasm and it's happening much faster Gary Bernhardt was anticipating in that presentation.
IMHO wasm finally displaces javascript as the only practical language to run stuff in a browser. Frontend stuff happens in javascript primarily because browsers cannot run anything else now that plugins have been killed off. Wasm changes that.
At the same time a lot of desktop apps are in fact javascript apps running on top of electron/chrome. Anything like that can also run wasm.
Finally people have been porting vms to javascript for pretty much as long as wasm and its predecessors have been around. So booting a vm that runs windows 95 or linux in a browser is not very practical but was shown to work years ago. This is what probably inspired the presentation above.
I've actually been pondering doing some frontend stuff in kotlin in or rust. I'm a backend guy and I just never had any patience for javascript. I find working in it to be an exercise in frustration. But I actually did some UI work in Java back in the day (swing and applets). Also there's a huge potential for stuff like webgl, webvr, etc. to be driven using languages more suitable to building performance critical software if they can target wasm. I think wasm is going to be a key enabler for that.
Most of the stuff relevant for this has been rolling out in the last few years. E.g. webgl is now supported in most browsers. Webvr is getting there as well. Wasm support has been rolled out as well. Unity has been targeting html5 + wasm for a while now. And one of the first things that Mozilla demoed years ago with wasm was Unreal running in a browser.
I would not be surprised to see some of this stuff showing up in OSes like fuchsia (if and when that ships) or chrome os.
Does that mean one could e.g. create Node.js modules in Wasm, like we also have the C++ modules? That could give a nice boost to certain kinds of code like text processing and math (e.g. a big integer or matrix algebra library).
(Perhaps this is already a thing).
Here's an example (untested, just found it via Google) https://gist.github.com/kanaka/3c9caf38bc4da2ecec38f41ba24b7...
I agree, it's exciting, but this is half (or less than) an article. These hyped-up technologies make me grumpy neck beard.