Wasm3 compiles itself (using LLVM/Clang compiled to WASM)
twitter.com
twitter.com
And WASM has been around since 2017, which is only 4 years, not 10 years... Bitcoin has been around much longer (~12 years), for example.
So if wasm is the spiritual successor to Emscripten's "Compile C to JavaScript and run C in a browser" then it's only 8 years.
Overall I think WebAssembly definitely has some usecases, they're just not as visible as people expected. Sites like Figma or Lichess use WASM but not in a super flashy way.
"promising that we'll be able to build web apps in any language" is not how I see WASM, nor is it really used in this way outside of transpiling Unity3D/Unreal games (this may be the one area there is an exception). I use it to transpile C++ to WASM libraries used within React apps, Edge Lambdas, and Node.JS servers. Primarily down to 2 reasons: speed and efficiency. WASM unlocks excellence and resources in other disciplines/languages such as AI and AR tool chains, Engineers, OpenCV, etc. When used like this, it is outstanding.
What WASM will never be good at is being used for the whole experience. You lose the semantic web, and/or accessibility tooling. Web has some outstanding guidelines and frameworks to help the impaired, screen readers and the like. Using WASM to pump a native app into a HTMLCanvasElement will lose all of these advances, therefore, WASM shouldn't be used for this use case (outside of games). Like all tooling, there is a time and a place to use them.
Below are a few links which use WASM in production:
https://holition.com/play/holition-brings-home-twenty-awards...
https://winners.webbyawards.com/2020/apps-mobile-and-voice/a...
https://www.youniqueproducts.com/beautyguide#.YIS9hOhKguU
https://www.charlottetilbury.com/us/products/charlottes-virt...
Unfortunately it kind of got branded this way for people who aren't close to the front-end industry. There's a segment out there who would like to write web apps but aren't willing to touch JavaScript with a ten-foot pole, and their hopes were gotten up that WASM would give them that. It's not exactly a lie, but it has so many asterisks that it may as well be.
In practice, the reality is that JS will continue to be the only first-class language for the web. WASM has many uses, some on the web and some outside of it, but the closer your app is to the DOM and to the browser as a platform, the less likely it is that you'll ever be able to pretend JS doesn't exist.
> What WASM will never be good at is being used for the whole experience.
The Flutter team would disagree.
They are leaning on WASM for browser builds of Flutter apps, with the whole app rendering in a canvas.
They do accessibility via separately created accessibility trees.
The experience far from great at the moment, but give it a few years and I think it will get there. (better wasm optimisations, direct host interop without JS shims, GC, threads, maybe WGPU instead of canvas, ...)
If that's a good thing for the web is another question...
For some use-cases, this is a nonstarter. (Sadly, not to as many as I'd like! But let's simply not regress, to start.)
Considering these are just hello world apps, the performance has a long way to go.
Rust also has the Yew framework, which is surprisingly nice to work with given that Rust is not a frontend language and it only uses the built-in macro system rather than a preprosessor like JSX.
Ideally WASM would expose lower level APIs and then we can start treating the browser as the app sandbox that it is (in the case of buildign apps).
Browsers are already pretty complex machines, considering javascript and the DOM and everything that comes along. Expecting all browser to let WASM have access to the DOM is a big demand.
Is anyone using a language other than C, C++ or Rust to target Wasm? Many other languages seem to have experimental support - but are any of them ready for production, or even making significant progress towards being ready?
Flutter and Blazor are exceptions, but they had to reinvent everything their own way.
Regarding languages, the landscape is pretty much limited to Rust (when using compatible crates), Zig, TinyGo, AssemblyScript and C# (with Blazor).
The specification started with something very simple but keeps getting more and more complicated, not to mention breaking changes, that don’t encourage writing tooling for it. At least not until things settle a little bit.
I convinced one of the engineers to try compiling it in emscripten. It was a total success, running at 45 fps. The middle manager got so excited about this that he decided to make a full push for this version of google earth to be used since it was truly cross platform product running in the browser at near native speed.
The portable Native client / webassembly team caught wind that this was happening and convinced management to kill the project. The middle manager who was overly excited about this technology, was also let go.
All this to make way for web assembly which was “right around the corner” but actually wasn’t (back in 2013). Today web assembly is essentially doing the same thing that asm.js was doing 8 years ago.
If Google had not messed up this decision it would have really been a trailblazer for other companies to follow suit.
For more on the difference, and an explanation of what JIT is, check out this section of the book Crafting Interpreters (https://craftinginterpreters.com/a-map-of-the-territory.html...)
Do none of the notable ones do normal compilation?
If the environment you run on doesn’t support JIT compilation (iOS for example), AOT compiling WASM is useful.
In what way does a platform need to coöperate with that?
To support that, the environment must allow the JIT to write machine code to memory, and then execute that same code.
CPUs have memory protection flags to control which memory areas can be written, and which can be executed. The OS is in charge of setting those flags, on request from the application. Eg. mmap and mprotect system calls.
iOS denies requests for memory that is both writable and executable at the same time. So applications cannot get the type of memory area a JIT needs. There are indirect methods where a file is written then mapped, like generating a small program or shared library on the fly. But iOS restricts these as well.
There are workarounds for a developer's personal applications, used on their own registered iOS devices. But these workarounds cannot be run by everyone else, except people with a jailbroken iOS. They cannot be used in applications on the App Store.
https://hacks.mozilla.org/2020/02/securing-firefox-with-weba...
> The core implementation idea behind wasm sandboxing is that you can compile C/C++ into wasm code, and then you can compile that wasm code into native code for the machine your program actually runs on. These steps are similar to what you’d do to run C/C++ applications in the browser, but we’re performing the wasm to native code translation ahead of time, when Firefox itself is built.
It's a middle ground between sandboxing with subprocesses (which adds all the overhead of IPC) and switching to a fully memory-safe language (Rust, JS, etc.)
But even with the broad definition of JIT, one important difference is that AoT compilers don't have to mark pages executable.
But in general you can't "just compile" Webassembly, because you need a runtime.
There is a C project that can compile an executable that includes the runtime and the compiled WASM, but the name is escaping me right now.
Note that JIT in the WASM world doesn't quite mean the same thing as for eg Java. Almost all runtimes compile a whole module at once, not individual functions.
Full AoT compilation, C programs run within 10% of native
Lost information about e.g. aliasing?
https://kripken.github.io/blog/wasm/2020/07/27/wasmboxc.html
It is heavily based around tail calls. I recently wrote a blog article about how we applied a similar tail-call-oriented strategy to accelerate protobuf parsing to 2+GB/s: https://blog.reverberate.org/2021/04/21/musttail-efficient-i...
I also recently landed a change in Clang trunk that offers guaranteed tail calls, so that this tail call design is safe in non-opt builds: https://reviews.llvm.org/D99517 I think wasm3 could benefit from using this attribute when it is available.
These rules guarantee that the tail call is possible to perform on every platform. They end up being more strict than is necessary on some platforms and calling conventions.
I sometimes wonder what the world would be like if Lua had zero based indices and saw a bit broader adoption. It's such an easy language to embed/extends although QuickJS looks like it's going to give it a run for the money in the long term given the similar goals on ease of embedding.
I wonder if anyone has compiled QuickJS to WASM and run it in the browser.
Fabrice Bellard actually did it himself here: http://numcalc.com/
Iirc J2ME impls could be fairly secure (barring bugs since many were written in an age before security became a focus), and I think the spec even mandated pre-computed stack-frames (the expensive part of verification that is easy to post-validate for correctness).
Another part of J2ME was because like wasm/web, the runtime API was fairly small and all code could be contained within the sandbox with only API-extensions allowed to be native functions. (This restricted API and it's quite sad UI capabilities was probably part of why Apple ignored it entirely for iPhones)
What was much worse however was the mainline JVM and the Applets, Applets had from day 1 relied on all kinds of mainline JVM features and this featureset kept growing.
Features were encouraged to be written as much as possible in Java but many still had more or less large native parts. This is in addition to the core that allows for quite a bit of code loading,etc (that was allowed from applets).
All these features and loading that could allow for insecure behaviour was secured by a security policy system, sadly there was so many features that were exposed that used powerful dynamic features (the because they were whitelisted) allowed for untrusted code to behave or do stuff only trusted code should.
https://docs.oracle.com/javase/7/docs/technotes/guides/secur...
As I understand, the JVM adds a thick layer of abstraction between incoming bytecode and output machine instructions. A wasm "runtime" OTOH adds a much thinner abstraction between incoming wasm and outputted machine code. It's a fairly 1:1 transformation.
However, I think you're correct in that, in order to serve as a host for GC'd and/or web-API-aware scripting languages (DOM, etc), a wasm runtime will need to become more JVM-like. How will wasm remain "web assembly" while doing that? No idea. This is where my mental model breaks down.
It lacks most of java's ‘batteries’—there are projects like WASI that try to resolve this at a low level, but they miss the point somewhat. On the other hand, wasm is saddled with fewer assumptions about the type of code that will run on it. Wasm has generally poorer performance, which is mostly (though not entirely) an artifact of its design, and hence not easily rectifiable[0]. It's not clear to me the extent to which the jvm suffers similarly[1].
Socially, I think wasm is not as interesting as java. Write-once-run-anywhere was solved in practice not by java but by open source; by compatibility libraries like sdl; by standards, like posix and opengl; and by static linking. (Yes, it's not quite as convenient as just plopping in a jar, but it's close enough.)
I don't think we're ever going to see a desktop full of wasm apps. Despite stated goals, the point of wasm was always to be an evolution of the web as a platform for applets. The Birth and Death of Yavascript[2] has many insights thataways (even though it failed to predict wasm as such).
0. https://www.usenix.org/system/files/atc19-jangda.pdf
1. It's also difficult to directly compare the performance of the two systems in their current state. A number of proposals for both (gc for wasm, value types for java, simd for both) are yet pending and are likely to change the runtimes' respective performance profiles.
2. https://www.destroyallsoftware.com/talks/the-birth-and-death...
> In computer programming, self-hosting is the use of a program as part of the toolchain or operating system that produces new versions of that same program—for example, a compiler that can compile its own source code
JS can already write more JS. Are there advantages and risks introduced by this new capability for browser-hosted (?) WASM LLVM to compile WASM?
Would be fun to make it so that native apps for any platform can be run from an interpreter
https://www.destroyallsoftware.com/talks/the-birth-and-death...
Supposedly, there are plans to expand it to where it looks more like a virtual machine and less like ASM. Adding things like garbage collection, direct DOM manipulation, polymorphic inline cache, etc. Things that would make it possible to run a decent scripting language without pulling in some huge runtime.
Or forgetting the scripting languages, just the direct DOM access might make it less tedious to use with compiled languages.
It's sort of a second run at getting "applets" right, but in a cross-language way.
https://www.graalvm.org/reference-manual/native-image/LLVMBa...
You might not want to bundle Rust in with C and C++ in this context. Rust is pretty accessible to developers coming from scripting languages (JavaScript, Python, etc).
Direct DOM manipulation (and the ability to send reference types across the JS-wasm boundary) is a pretty big deal though I think. Currently it doesn't make an awful lot of sense to build code that interacts with the DOM in WASM (although in Rust there are automatically generated bindings that go through a JavaScript shim).
Not in a way that is unique to Rust…
[0]: https://forums.flightsimulator.com/t/getting-started-with-wa... [1]: https://news.ycombinator.com/item?id=24281400
Doesnt this just imply building a 'huge runtime' into the language?
Seems to me the web already has an answer for that: transpile to JavaScript, and leverage the existing high-performance JavaScript engines.
Dart does this, for instance.