Hacker News new | past | comments | ask | show | jobs | submit login
Assembling WebAssembly (webkit.org)
202 points by jfbastien on June 6, 2017 | hide | past | favorite | 86 comments



Summarizing the "JSC <3 ES6" discussion and translating to WebAssembly: no ServiceWorker, polyfills from C++ / asm.js to WebAssembly won't be fast enough, "ES6" is a bad name and so is "WebAssembly", "we" is the WebKit team (as individuals), no tail call in WebAssembly but it's on the roadmap. https://news.ycombinator.com/item?id=14489577

Now that these points are out of the way, let's discuss implementation details, WebAssembly, and things!


Give me qt in the browser, the rest are details.


boom, qt, gtk, even xlib (or a win32 clone) would be better than html/css/js bullshit


HTML/CSS/JS has some huge advantages from the user perspective. When a designer has made some questionable choices, all it takes is a user stylesheet or a quick tour to the devtools to fix the font size and contrast ratio.

The whole world of extensions that improve existing websites with additional buttons etc. is only possible because the page structure is exposed in the DOM. If Reddit were only WASM rendering on a <canvas>, there were no "Better Reddit" extensions.


there's reddit and then there are all the in house enterprise-ish apps that basically amount to moving buckets of bits between cross-linked tables for which html+css is not cost effective.


Also, nobody wants to pay a C++ dev for doing a JS devs work, haha


you can still code in js or any other language.


I know.

I just thought, with JavaScript front-end development has been commoditized and C++ is harder than JavaScript. So I don't think many people would pay a more expensive C++ dev to use Qt for a WASM based app, if they could get it all going with a cheap JS dev.


It is more like "you can code in any language as long as it JS".


reddit would probably have an opensource rendering layer or third party uis that use it's api.

wasm will be the new android without the need to install apps.


That's what they said about HTML 5, too.


How do you easily skin xlib or win32? (I think that Qt and Gtk support stylesheets)


I think you could still use stylesheets, just not for the good defaults.


Please no. We only just finished killing Flash (mostly); the last thing we need is another UI framework which doesn't respect standard features of the web platform taking its place.


That's why you don't want Qt in the browser? It isn't having to download 25MB for a hello world program?


tcl/ttk is all i want


I really look forward to the day when WebAssembly stops being seen as "JavaScript's fast sidekick" and starts being seen as "the language of the web". It won't take that much to expose APIs directly to WebAssembly rather than just to JavaScript.


We're a long way away from that. Here's what you'd need:

- GC types in WebAssembly. That's still an open problem, but that would give you API access.

- Ability to load WebAssembly via something like <script>.

- WebAssembly would have to load and start as quickly as JS.

The last one is probably the hardest in the long run, since wasm is being optimized for the kinds of apps where you want to pay some cost up front so that you get great throughput later.

Note also that GC types would make it harder to compile existing languages to wasm, since those GC types will probably have to have JS semantics built into them from the start to allow API interoperability. So, even if wasm succeeds in the way you'd like, it would probably mean that the language of the web is still something JavaScriptey.


> - GC types in WebAssembly. That's still an open problem, but that would give you API access.

I've seen numerous discussions about integrating WebAssembly with the JavaScript heap. That might not require full GC; ownership semantics might suffice (such that either wasm or JS can own the object at any given time, and within the wasm world it can use wasm memory management).

> - Ability to load WebAssembly via something like <script>.

What we have today seems very close to that in practice.

> - WebAssembly would have to load and start as quickly as JS.

A combination of a fast bytecode interpreter and compiled code caching could probably manage that. Or a fast, targeted JIT.

> Note also that GC types would make it harder to compile existing languages to wasm, since those GC types will probably have to have JS semantics built into them from the start to allow API interoperability. So, even if wasm succeeds in the way you'd like, it would probably mean that the language of the web is still something JavaScriptey.

Still an improvement, but also see above about ownership semantics.


> I've seen numerous discussions about integrating WebAssembly with the JavaScript heap. That might not require full GC; ownership semantics might suffice (such that either wasm or JS can own the object at any given time, and within the wasm world it can use wasm memory management).

Those discussions have not resulted in a proposal.

Ownership semantics are most likely not going to work. The options being considered are:

- WebAssembly has strong or weak handles to JS objects. That's not ownership.

- WebAssembly can allocate GC'd objects. That's not ownership.

- WebAssembly exposes enough stuff so that you can write your own GC. That's ownership, sorta, but doesn't allow wasm to access JS objects. Wasm would simply own objects it allocated in its own heap and would never be able to claim ownership of JS objects or relinquish ownership of its objects to JS. By itself, this means zero GC interop with JS.

Most likely, we'll end up with all three options.

It sounds like you're proposing that WebAssembly can somehow come to own a JS object. That's not practical, since it would imply either eagerly ref-counting all JS objects (that's a 2x slow-down), or it would imply full synchronous GC every time you share any object (totally impractical), or it would imply pretending that WebAssembly can own an object without first proving it (then wasm code could create use-after-free bugs to escape the web sandbox).

> What we have today seems very close to that in practice.

You have to use JS API to load wasm, so we're not close to this at all.

> A combination of a fast bytecode interpreter and compiled code caching could probably manage that. Or a fast, targeted JIT.

So long as WebAssembly is a low-level compiler target, that implies that developers shipping WebAssembly will also be shipping a userland for whatever their source language is. See emscripten for example, which has a large userland (the "emsdk", which includes libc and other things). So long as this is the pattern, WebAssembly will necessarily take longer to load than JS because the same program written in wasm will be bigger than its JS variant.

> Still an improvement, but also see above about ownership semantics.

I don't think your ownership idea will work, see above.


> So long as this is the pattern, WebAssembly will necessarily take longer to load than JS because the same program written in wasm will be bigger than its JS variant.

Binary bytecode, which is what webassembly apps are, is often, generally, almost always smaller than source code. Except for really small programs.

Also, js code needs to be parsed previously. Webassembly code does not. Webassembly should load faster and execute faster.

Happy times ahead on the browser side...


I believe the thought was that, for many languages, there is an additional, standard runtime, which is not always remove-able from the language itself, which may not always be of a trivial size, and which is not guaranteed to be already available on a client machine.


I think you're misunderstanding Fil's point: JS is more expressive, and can often encode more things in a smaller package.

For same-code wasm / asm.js / x86 comparison (not what Fil was talking about) see section 7.3: https://github.com/WebAssembly/spec/blob/master/papers/pldi2...

Additionally, WebAssembly definitely needs to be parsed. See: https://github.com/WebKit/webkit/blob/master/Source/JavaScri... and https://github.com/WebKit/webkit/blob/master/Source/JavaScri...

Granted, that's simpler than parsing JavaScript.


For reference, the current GC proposal is here: https://github.com/WebAssembly/gc/blob/master/proposals/gc/O...

I expect it'll be discussed at an upcoming CG meeting. Either the next one or the one after.


> GC types in WebAssembly. That's still an open problem, but that would give you API access.

Nothing prevents one to implement a GC on top of existing WebAssembly as it is, no different than when implementing bare metal runtimes.

Of course having a GC as part of WebAssembly does simplify implementations, but only as an easy solution, because the best GC implementations need to be language aware for optimal performance.


I hadn't thought about this before, but your comment made me aware that if you wanted to compile any kind of high-level language with GC into WebAssembly, you have to download it with an entire runtime. I wonder how much overhead that adds to downloads. Like, if you compile a C# or Java thing for wasm, do you have to download a 30mb runtime every page you load?


Yes, but one can probably trim it down to what is actually used.

Java runtime is only 8MB (JVM) + whatever classes are actually required, other ones can be removed by something like ProGuard or the new linker.

.NET Native is quite similar.

Same applies to OCaml, Haskell, Scala, Go, ....


Wouldn't modules allow you to load the language runtime separately from a CDN, so that it remains cached? Kind of like people do right now with jQuery? It still would be nice if that runtime was slim of course; IIRC mobile browsers especially have small caches.


I think it'll be more like 1..3 MB for something like the .NET mscorlib, but yes, the runtime overhead cost is definitely there. The more "managed" the language is the worse this will be. That's why it makes a lot of sense to use 'bare metal' languages which have a very small, or even completely optional runtime for WebAssembly, and use an 'embedded platform' programming style, that way you can get useful WebAssembly modules down to a few dozen kilobytes.


Just look at Go binaries. They include all the standard library modules that they use. A typical "Hello World" in Golang compiles to around 1-1.5 MB (and that's after you strip debug info).


> Nothing prevents one to implement a GC on top of existing WebAssembly as it is

Except that efficient GC implementations use concurrency with a shared memory space and locking and memory-barrier instructions that are not yet available in WASM. (AFAIK, please prove me wrong)


Correct, shared memory and atomics are likely the first big post-MVP feature: https://github.com/WebAssembly/threads/blob/master/proposals...


Those operations are not available in all hardware architectures anyway, and they surely weren't even common before processors went multi-core.

So GC were implemented within those constraints, which means it is possible to do within the current state, even if it isn't the most optimal one versus the availabilities of such CPU features.


Large JS applications take so long to parse that they could already be slower on startup. https://hacks.mozilla.org/2017/02/what-makes-webassembly-fas...


WebKit has a fast JS parser. I don't think this would be true for us.


I'm not sure if that is true. our application takes at least 100ms or more to parse. only parsing. on Safari 10.1.1 on a macbook pro 2013 late. well chrome and firefox is as slow as that. I don't think the same stuff in WebAssembly would take that long (i.e. angular 1 application, if we add angular 4 which we are planning it will prolly take even longer since we need more vendor stuff.)


Link to repro?


not open source. but start with angular 4 hello world. that takes a little while to parse, too.


> WebAssembly would have to load and start as quickly as JS.

Wouldn't it already load faster than JS, because it's much less work to compile and doesn't require guessing types?


It's implementation dependent. Most implementations JIT Wasm up front (I think Chakra is the only engine that interprets). So, JS loads faster because almost all engines interpret first (all?).


I think the primarily-AOT compilation strategy we see today is a consequence of many of the initial workloads being frame-based animation where AOT avoids animation stutters. But this is likely to evolve over time as wasm workloads evolve. If and when we see wasm showing up in frameworks in contexts where page-load is the primary concern I can see a more lazy JIT strategy being the right thing and then we'd want to specify some sort of developer knob to control this. But given a pure-JIT approach like Chakra is using, wasm should be able to load code byte-for-byte faster than JS.


WebKit already has a more lazy JIT strategy. From the article being discussed:

"WebKit’s WebAssembly implementation, like our JavaScript implementation, uses a tiering system to balance startup costs with throughput. Currently, there are two tiers to the engine: the Build Bytecode Quickly (BBQ) tier and the Optimized Machine-code Generator (OMG) tier. Both rely on the B3 JIT as their low-level optimizer."


I agree.

Chakra uses a pure JIT approach? I thought they interpret both in JS and Wasm?


Maybe some terminology difference here but what I meant by 'pure JIT' was that, iiuc, Chakra waits until the function is called to even validate it, then warms up in an interpreter and only if the function is hot compiles it in a background thread. I think that's one end of the eager/lazy spectrum that may well be what a category of wasm uses will want.


Is “interpreting” necessarily faster?

Consider also this is perhaps a false distinction. V8 always produces machine code when running JS IIRC. And that code is JITed doesn't mean the entire module is.


V8 used to do this. Now they have a JS interpreter called Ignition.


> V8 always produces machine code when running JS IIRC.

They used to. They stopped doing that because it made initial load too slow...


What would it take to give WebAssembly access to the DOM?



Ahh my bad. I'm just a lowly CSS developer, so I didn't realise that GC (garbage collection?) came with interoperability to the DOM


No worries! It's all non-obvious :-) Yes GC == Garbage Collection.


I hope soon we'll have a shot at rethinking the browser's rendering stack. Not necessarily ala WebRender [0] since it needs to be backwards-compatible, but something with a clean slate.

I imagine programmable layout, GPU contour rasterization, motion-blur, programmable shaders, layer blending, LOD and infinite zooming, and render-to-texture (for putting 2D surfaces in a 3D scene).

None of this is unnecessary if you bring AR/VR to the mix. Soon people will want to put on their AR/VR glasses and read books, select pieces of text, open links, etc. There are no APIs that allows them to do that in a web browser. Ergo => flock to native.

Quite a bit of work remains for that to happen. A whole bunch of APIs need to be exposed in the browser, such as native text rendering APIs, a better-than-WebGL2 API for graphics [1][2], a way to make the webpage accessible to non-humans (eg. How do you make the page reader-friendly? how do you do "Find in page"? How do you index the content?), etc.

[0] https://wiki.mozilla.org/Platform/GFX/Quantum_Render [1] https://github.com/KhronosGroup/WebGLNext-Proposals [2] https://github.com/gpuweb/nxt-standalone


> Currently, there are two tiers to the engine: the Build Bytecode Quickly (BBQ) tier and the Optimized Machine-code Generator (OMG) tier.

I assume the next tier they're going to do will be "WTF"?


WTF stands for Web Template Framework. BBQ and OMG both use it.


Ok now make LOL: LLVM Optimized Language



We had a chance to have LOL: Low-level Object Library. But now it is named as PAL.


Man, we are bringing a giant load of complexity into the browser with this. As I understand it, what we get in return is a 2x speed increase. I wonder if its worth it.


What complexity? It's just a new frontend for the complex tiered interpreter-and-JIT-compiler monstrosities that JS engines have.

A massively simpler frontend than JS itself — it's closer to, well, assembly :) while JS is a dynamic language.

What we get in return is very very close to native execution speed for all the performance-sensitive things you might want to run on a computer — game engines, crypto, compression, codecs, etc. — in a sandboxed and portable way. One executable for everything from the typical Windows/amd64 desktop to your NetBSD/mips toaster, potentially.


It's quite a bit more than a frontend, but I agree it isn't as complex as the JS engine itself. For comparison, this is the JSC wasm implementation: https://github.com/WebKit/webkit/tree/master/Source/JavaScri...


We are potentially removing the complexity at all ends.

Right now the chain is: Developer writes code in something like Typescript that then is translated to Javascript and then is downloaded by the browser (huge downloads compared to binary code). The browser then needs to parse that huge amount of javascript code to compile it into a bytecode that can then be JIT executed or interpreted.

With webassembly it would be as follows:

Developer writes code in the language of his/her choice, that then is compiled to a small bytecode. This bytecode is downloaded by the browser and then it is JIT executed or interpreted.

It is simpler, more flexible, and potentially faster.


That's assuming the old ways are deprecated and removed.

There's countries in the world that still use IE6, and that's comparatively an easier transition :)


As I understand it, potential performance gains are higher than 2x, and we're still in a pretty early stage. It depends on your application.

Also, as has been mentioned by others, WebAssembly could perhaps evolve to take a greater role, leading to a greater potential impact of performance gains.

Finally, if the complexity does in fact outweigh the benefit, the idea would eventually fade away. So far it looks promising. Time will tell.


Where does even the 2x come from? Currently it looks very much like 1x vs integer hinted JS code like generated by asm.js.


That is incorrect. See: https://github.com/WebAssembly/spec/blob/master/papers/pldi2...

These are already old numbers, and section 7.3 says 33.7% more efficient. Were one to run updated numbers, and use more than Chrome and Firefox, I'm pretty sure the numbers would be better still.


Very interesting looking paper, thanks.

I note that the comment in 7.3 says the biggest speedup vs asm.js is in validation, so I assume this means the measurement includes startup. This advantage is easy to concede to WebAssembly due to its design.


FWIW I trust that the numbers were good when the Google and Mozilla folks gathered them, but I had nothing to do with numbers!

In particular, I haven't looked into validation. JSC doesn't treat asm.js any differently than JavaScript, so the comparison would be different as well.


I hope wasm becomes the first class citizen and JavaScript becomes just one out of many languages that compiles to it.

JavaScript is not bad at the high level, but at the low level it has been hell for engineers to implement a fast VM. A wasm VM is way easier to implement than a JavaScript VM.


I do like the upside, but coupled with DRM support, it's going to be used to obfuscate, hide and control things. I'm expecting a much less open web coming.


WebAssembly is as Turing-complete as JavaScript is, and has fewer APIs. The only API it has JS doesn't really is grow_memory, and even that can kinda be done with ArrayBuffer.

I'm not sure what you think makes it the harbinger of closed web. As the WebAssembly CG chair, I'd be interested in understanding that.


I don't see it as THE harbinger, but one of many. Some people will use it for the same reasons that they obfuscate things today. See, for example, the dropbox client. It's python, but they go to great lengths to keep you from peeking behind the kimono.

I understand WASM isn't reverse engineering proof, but it certainly raises the bar. Especially sans source maps.


Source map is totally optional! It provides zero help in understanding asm.js or minified JS. I see what you're saying about binaries being opaque blobs, but I just don't see how that's different from asm.js or minified JS.

Kinda sounds like you're trolling pcwalton TBH: https://twitter.com/pcwalton/status/872151997473972224

I approve ;-)


I understand source maps are optional...not getting the exclamation point. That's exactly my point, it's optional and therefore not much help.

Minified js isn't (so far) a barrier for me. Prettify and a short bit of debug clears things up. Chrome even helps[1]. I have not yet run into asm.js used for anything in my field.

[1] https://developers.google.com/web/tools/chrome-devtools/java...


I don't think it raises the bar at all. You could already do everything you can do in wasm today with Emscripten, and any harebrained attempts at DRM schemes shipped over the wire would almost certainly be using Emscripten. Wasm is easier to read than Emscripten'd code because of types.


Well, while true, today many things are being hidden from browsers by doing them server-side.


Has it?

The fastest VMs on the planet are JS VMs right now.


Well, there's a smart fellow called Mike Pall who would like to race Lua against JavaScript for you. Plus, the very best VMs are Java.


I thought he stopped because he couldn't keep up ;)


I wonder how easy it would be to use JSC's WebAssembly backend separately from the rest of Webkit, and maybe even have it output to a static binary. And maybe connect its FFI with a different language than Javascript (maybe Go?).

Given the work that has gone into B3 it might make a good target IR for compilers that want fast compilation to native executables, and you'd get to target the web for free as a bonus.


Not too bad. Some things are connected to GC and JIT-code generation, but if you wanted just BBQ or OMG (no tiering) something could be done. Tiering too, but then you have more of JSC in there, really depends what you want.

Depending on what you want to do, there are a few experimental .wasm -> LLVM IR -> machine code things around.

Problem is really what your embedder would be. Import / export is what you'd have to define! In JavaScript we have a standardized API for that.


This sounds quite disappointing to me: "WebAssembly cannot access the DOM except by calling into JavaScript. WebAssembly is meant to be used in conjunction with JavaScript."


That text is a bit misleading. WebAssembly currently can't access the DOM directly, but it's definitely a goal to let it do so in the future:

https://github.com/WebAssembly/design/blob/master/GC.md


WebAssembly means closed source binaries all over again, and threatens our ability in all the metrics Stallman advocates.

Also, it probably means the end of the Web as we know it.

Browsers very likely should treat closed source like they treat our microphone or camera: don't give access unless the user consents.

But do allow it to run without consent if, and only if, the source code is public.


This is pure nonsense. WebAssembly is no more obscure than asm.js or minified JavaScript. "Binary" versus Unicode-enabled minified and transformed "source" is the same thing.

You can get text out of WebAssembly as well as you can get text out of minified JS.

Further, users don't care about this. It's literally just developers. Open Source / Free Software is a super valid discussion to have, but I highly doubt any non-technical user cares.

Amusingly, pcwalton brought up this discussion recently: https://twitter.com/pcwalton/status/872151997473972224


I guess you may be right! I presumed WebAssembly to be some sort of opaque "goto-soup" (unlike minification), as the term "assembly" suggests.

But I looked it up and it seems WebAssembly preserves the structure of the original document, just like minification, at least that's what I understand from the following quote:

"In practice, outer blocks can be used to place labels for any given branching pattern, except that the nesting restriction makes it impossible to branch into the middle of a loop from outside the loop. This limitation ensures by construction that all control flow graphs are well-structured as in high-level languages like Java, JavaScript and Go." See: https://github.com/WebAssembly/design/blob/master/TextFormat...

I am delighted :)


When is this coming to iOS though?

I think chrome for mobile already has it?




Consider applying for YC's W25 batch! Applications are open till Nov 12.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: