This is still the current state of WebAssembly. There's several proposals out there that, if implemented, could change the situation. The primary one that I'm aware of is the interface types proposal [1].
[1] https://github.com/WebAssembly/interface-types/blob/master/p...
In practical terms the language of the browser is JavaScript, but what if JavaScript doesn't do what you need, or it isn't fast enough, or you simply don't like JavaScript. Instead you want to write some application in Rust (just using that as an example). The language of the web is still JavaScript and not Rust so your new application will not run directly in a web page. That's unfortunate, because the web is a fantastic distribution platform because things that run in web pages do not require a separate installation step or a separate download step, since web page assets are downloaded automatically as called by the web page. If you compile your Rust application to WASM it can run in a web browser.
To be clear though WASM isn't replacing JavaScript or even in any way competing with JavaScript, because that is certainly what it sounds like. WASM is a separate and isolated execution instance in the browser, even from the page that contains it. JavaScript, on the other hand, executes directly in the context of the page that requests it.
You might hear some discussion of wanting WASM to replace JavaScript, but that is clearly stated by the WASM project as not a design goal. You might also hear that if only the containing page's DOM were available to WASM it would replace JavaScript, but that isn't a design goal either. That part about the DOM is the confluence of a misunderstanding about the DOM and about WASM's security goals of a separate execution context. There is work, however, on providing some Web API capabilities to WASM so that a WASM instance may have some awareness of its execution context or to allow some manner of external interaction of the WASM instance from the surrounding page. I don't know the status of that work though.
* WASM project site - https://webassembly.org/
* Web APIs, a list of de facto standards for interacting with web browsers from JavaScript - https://developer.mozilla.org/en-US/docs/Web/API
* DOM specification, the DOM is a language agnostic dynamic tree model that represents markup and containing content - https://dom.spec.whatwg.org/
Unfortunately, that appears to be a huge miss. There are a lot of programmers in other (non-JS) languages that would very much like to create front end pieces for their web applications.
Hopefully when the interface types proposal (or whatever) happens, direct access to the DOM does become a thing and non-JS programmers really can do their front end work without JS.
Far more likely, and this already exists in various unofficial examples, is that WASM instances ship with a DOM for accessing markup provided by or requested into the WASM instance.
Sounds like it would achieve the same end goal? eg direct access to the page elements, without needing to go through JS
Or is that my not really understanding the problem space? :)
Trying to think of something, but nothing is coming to mind.
eg PgAdmin, which went from a good desktop application (v3) to unusable in non-trivial cases on the desktop when they switched to Qt (web). :(
Blazor / Uno seem to be C#? Not (personally) going to touch that with a long stick. ;)
For me, WebAssembly will be the revenge of browser plugins.
We already have Flash, Java applets and Silverlight being made available on WebAssembly, even if not at same feature level as their former selfs.
Meanwhile real hardware is adopting memory tagging (with exception of x86/x64).
It is really nothing new here, just the politics to have a bytecode execution platform that everyone agrees on.
For example, if I can replicate a Flash security flaw with CheerpX, should I blame Flash, CheerpX for being a good implementation, or WebAssembly for allowing Leaning Technologies to faithfully re-implement Flash?
the security model of the web site based on executing arbitrary code, so you would need to assume that the wasm you receive tagged it's memory in the most malicious way possible anyway.
the way I see it real hardware needs this kind of checks more because they have worse sandboxing
Javascripters aren't going anywhere anytime soon
So if you want to implement cryptography or codec, WebAssembly is a good tool. If you just want to write some browser code, JavaScript is enough.
Another use of WebAssembly probably is to serve a better compilation target. While you can compile anything to JavaScript, it makes more sense to compile to WebAssembly if you don't need GC. So with enough time there will be more languages available for web application development. That said, without GC support in WebAssembly, for most interesting languages it's still not usable.
WebAssembly with a deep GC model will at best be a slightly better environment for writing JavaScript extensions and at worst a way to write really obtuse JavaScript code.
In the Ruby community we discourage anyone from doing crazy stuff like using Objectspace.id2ref
Less obvious (though as you pointed out) are things like finalizers. In Lua finalizers are guaranteed to run in the reverse order of allocation, and that's an important guarantee when writing C modules. Finalizers in Lua can also resurrect dead objects, which isn't always the case in other languages, and indeed some languages don't even support finalizers at all, which simplifies their GC model. Lua also has an optimization/simplification constraint that finalizers must be attached at object construction (specifically, metatable assignment). If WASM copied something like this, it might disadvantage other languages; if it didn't have such a constraint then the GC implementation might be unnecessarily complex relative to Lua's needs.
Another example would be support for ephemerons, which are more powerful than weak references. Only a few languages support this, such as Lua, Smalltalk, and more recently OCaml and JavaScript. AFAIU ephemeron support bleeds into many aspects of the GC. Supporting that in WASM might be tricky and, I'd bet, not something likely to happen--you can't just hoist v8's or SpiderMonkey's GC engine into WASM wholesale, even though I suspect the prospect of doing that motivates some of the interest in adding deep GC support to WASM.
If and how WebAssembly's GC model supports these constructs matters greatly to whether other languages can run as first-class citizens in the WASM VM. As an example for the headaches caused when support is lacking, think about exceptions. the standard C API setjmp/longjmp is ridiculously slow in WASM, yet it's how Perl and Lua (and possibly other languages) implement exceptions. Exceptions are on the roadmap for WASM, but they look to be more tailored to Java/C++ exceptions, which iteratively unwinds the stack; Perl and Lua don't need to unwind the stack because they carefully maintain and preserve internal state consistency and can jump across deeply nested function invocations. That's hardly a blocker, but in practice it's incongruent and I would expect Perl and Lua to either suffer for doing things differently, end up having to rearchitect their VMs to suite WASM, or more likely motivate the emergence of a WASM-specific VM (e.g. Iron Python on .NET), which all but guarantees second-class status, either for the new or old project.
None of these are deal breakers. You can synthesize behaviors and hack your way around all of this. My point is merely that the prospect of a glorious execution model that unifies the diverse world of languages is naive. Languages are designed and implemented around a core set of primitives and concepts; and many of these primitives and concepts either won't exist in WASM, or will behave so differently as to be effectively useless, especially when cross-compiling existing implementations.
That's not going to happen. The primary point of WebAssembly GC support is for integration with the host, with GC for the guest program secondary. And the biggest WebAssembly host is the browser, which as you note uses a copying collector. A design for WebAssembly GC that doesn't allow that is a non-starter.
Because of this prioritization, extensions like finalizers or weak references aren't even under consideration for the initial version: https://github.com/WebAssembly/gc/blob/master/proposals/gc/O...
> My point is merely that the prospect of a glorious execution model that unifies the diverse world of languages is naive.
Hardware already provides this; the whole idea behind WebAssembly and the reason it can support C so well compared to most other VMs is that it exposes a more hardware-like execution model. Implementing your own GC if WebAssembly's isn't suitable should not be considered a hack, just the usual bundling of the runtime that happens on hardware.
Further, as I've pointed out to you before, the CLR does not really support unmodified C and C++ as well as WebAssembly does. It supports C++/CLI instead, which is not a superset of standard C or C++. And worse, the main (only??) compiler for C++/CLI has no plans for keeping newer features of C++ working on the CLR.
In the context of this discussion about integrating GC into a VM that supports C and C++, the CLR is an odd choice of example anyway. The CLR doesn't aim to support existing languages unmodified, every port I've seen has been similar to C++/CLI in diverging from its original definition, specifically because of its memory and object models. And those are precisely what WebAssembly does away with.
What do you call emscripten and the language extensions it makes use of, then?
One of the major features for .NET Core 3.0 was C++/CLI support. It is a major .NET language in Windows desktop applications, as it is more convenient than writing P/Invoke annotations.
Also CLR is just the example more people nowadays can relate to, I can give other C and C++ bytecode examples.
.NET Core 3.0's C++/CLI support, again, is not standard C++ and never will be! It's just the same C++/CLI on a more up-to-date CLR.
(Things may have been better in the past, but the C++/CLI spec has not kept up with the C++ standard at all and so the main implementation, when asked for "C++17 and C++/CLI," just kind of shrugs and makes a mess.)
This is not true of emscripten. It does add some Javascript binding functionality, but that's no different from e.g. Linux or Windows offering their own platform APIs beyond the C++ standard library. You can just take a lot of pre-existing standard C++ programs, often including those that use platform-specific APIs, and drop it in emscripten!
Bytecode for C and C++, is even older than the CLR, and before the browsers, there were a couple of J2ME competing stacks that used C and C++ instead.
The innovative thing with wasm is half political (that is it is socially free to implement and use) and half the lightweight reliable sandboxing.
It is perfectly possible that there is a subset of the CLR that would have been a better Web-Assembly than this WebAssembly, but the CLR chose different trade-offs so it isn't.
One of WebAssembly main distinguishing features is that it can compete with eBPF in term of safe embeddability.
But WebAssembly (wasm32) code density is not the world's best. Comparing to good old x64 it goes at 1.42/1.0 ratio which is still tolerable. I hope someday we'll get a more dense instruction set like ARM's Thumb.
Well, the native machine does that…
For cryptography specifically, the security considerations are the same as for JS: all of your security promises die if your threat model assumes that you cannot trust the security of TLS.
WASM can be MITM’ed just as well as JS.
It's tricky to develop "standard" frontend when support for hot reload isn't "by default","dll's" size is far from being small and having to perform workarounds in order to manipulate DOM.
I think it needs to mature - both wasm and blazor because all of those issues were said to be addressed
Admittedly, The current state of WASM is somewhat limited. For example, it cannot touch DOM directly without JS now. One of the goals of WASM is that making it more browser-native module (just like ES6 modules) to remove such JS dependency. This goal will take years I guess.
Of course, things make people confused as many guys are experimenting with WASM outside of the browser. But this is the initial goal in the web browser context.
[1]: https://www.w3.org/2019/12/pressrelease-wasm-rec.html.en
Or perhaps a general vm will never work as well as a custom one and the trade off won’t be worth it.
I'm building exactly that. A SPA using Go compiled to WASM. Some issues seem to be the startup time and the payload size.
---
Standard Go:
The resulting .wasm sizes aren't practical. 2MB+ for "hello world".
That being said, it was only ~2.5MB for an inital mock 3d on 2d canvas test thing: https://justinclift.github.io/wasmGraph1/ (~550k when gzip compressed, as is commonly done when sending over a network)
---
TinyGo:
Much better sized .wasm files. ~500 bytes for "hello world".
~65k for a mock 3d on 2d canvas test: https://justinclift.github.io/tinygo_canvas2 (~26k compressed)
---
Rust:
~110k for a port of the same mock 3d on 2d canvas test: https://justinclift.github.io/rust_canvas_2d/ (~44k compressed)
Note that this is done with lousy Rust code, as I'm still in the early stages of getting the hang of it.
---
Rust (so far) seems to be the best trade off, at least for now. Although TinyGo's binary sizes are much better than it and standard Go, TinyGo breaks far too often, and reported blocker bugs aren't addressed for months. :(
WebAssembly sucks at DOM. It sucks huge. WebAssembly can't hold a reference to a DOM object and can't even create strings. You have to do that all in JavaScript, and then import that JavaScript code into your WebAssembly module. You'll end up doing something weird like sticking your DOM objects in an array and then passing indexes into the array to your WASM code. Strings have to be encoded/decoded to get them in/out of WASM.
MathJax is written in TypeScript. If you want WASM, that means rewriting large parts of MathJAX, keeping other parts in JS, bridging them, and dealing with all of the resource dependencies (i.e. dealing with WebPack).
And anyway, JavaScript is decent at string processing.
It would be interesting to know what the slowest parts of MathJax are.
I think the project itself lost its track. It started as an admirable goal of being a common low-level-ish compilation target for the browser. They managed to ship an MVP targeting C semantics.
But now it looks that now people are more interested in writing a yet another compiler to WebAssembly (which isn't even in a beta phase) than developing WebAssembly further. And pushing WebAssembly (which, once again, isn't even in beta) into all sorts of weird stuff like server-side apps. And this is occurring even in the orgs responsible for developing WebAssembly, like Mozilla.
WebAssembly was announced in 2015. In 2017 they had a Minimum Viable Product that was supported in all major browsers. We are a third way in 2020, and there's hardly anything beyond MVP.
For a time there seemed to be a lot of hype around writing SPAs in whatever language you like, not just JavaScript, but that seems to have cooled off somewhat - at least that's my impression.
Last time I checked in it seemed to be actually quite the opposite - good for low level stuff, data processing, graphics, things in other threads essentially, but if you want to touch the DOM at all just use JS seemed to still be the standard advice. I haven't looked again since. Have things progressed on that front, and if not was that ever really a goal of WebAssembly anyway?