Get the top HN stories in your inbox every day.
jjcm
prewett
I guess I’m just a crusty ol’ greybeard C++ developer, but it seems like a video editor is out of place in a document browser. There’s a perfectly good native operating system that nobody uses any more.
If we think we need a more thoroughly virtualized machine than traditional operating system processes give us (which I think is obvious), then we should be honest and build a virtualization abstraction that is actually what we want, rather than converting a document reader into a video editor…
wyldfire
> ... document browser ... document reader ...
I'm going to assume you're being sincere. But even the crustiest among us can recognize that the modern purpose for web browsers is not (merely) documents. Chances are, many folks on HN in the last month have booked tickets for a flight or bought a home or a car or watched a cat video using the "document browser".
> If we think we need a more thoroughly virtualized machine than traditional operating system processes give us (which I think is obvious)...
Like ... the WASM virtual machine? What if the WASM virtual machine were the culmination of learning from previous not-quite-good-enough VMs?
WASM -- despite its name -- is not truly bound to the "document" browser.
DonHopkins
Alan Kay on “Should web browsers have stuck to being document viewers?” and a discussion of Smalltalk, HyperCard, NeWS, and HyperLook
https://donhopkins.medium.com/alan-kay-on-should-web-browser...
>Alan Kay answered: “Actually quite the opposite, if “document” means an imitation of old static text media (and later including pictures, and audio and video recordings).”
jpc0
So you are telling me I can now directly render from WASM into the viewport of the browser with a11y? Nope, then it’s still restricted to interacting with the DOM through JS or or renderings to a cavas with no a11y support or significantly worse dx for a11y because you would need to render a screen reader only document layout ontop of your actual UI, instead of just handing the browser an interaction tree and allowing it to do what is needed for screen readers.
pjmlp
We have, but not by choice, I miss my native apps, even though ChromeOS Platform pays the bills.
Dylan16807
While web apps make sense, those are pretty weak examples. Booking and buying are pretty document-based and need to run little to zero external code. The cat video isn't technically a document but upgrading a photo to a video is not a very big change and doesn't require any external code at all.
Terretta
document browser, document reader, printed paper, paper form, return to sender... those are all in the same concept space*
"virtual machine" is clearly not
that said, i love WASM in the browser, high time wrapping media with code to become "new media" wasn't stuck solely with a choice between JS and "plugins" like Java, Flash, or Silverlight
it's interesting to look back at a few "what might have been" alternate timelines, when the iPhone was intended to launch as an HTML app platform, or Palm Pre (under a former Apple exec, the "pod-father") intended the same with WebOS. if a VM running a web OS shows a PDF or HTML viewer in a frame, versus if a HTML viewer shows a VM running a web OS in a frame...
we're still working on figuring out whether new media and software distribution are the same.
today, writing Swift, or Nim, or whatever LLVM, and getting WASM -- I agree with you, feels like a collective convergence on the next step of common denominator
* note: those are all documents and document workflows with skeuomorphic analogs in the same headspace, and newspaper with "live pictures" has been a sci-fi trope for long enough TV news still can't bring themselves to say "video" (reminding us "movie" is to "moving" as "talkie" was to "talking") so extending document to include "media" is reasonable. but extending that further to be "arbitrary software" is no longer strictly document nor media
prewett
Well, that's my point. The modern purpose of the browser is for applications, and for very good reasons, namely to abstract away the OS. The problem is that the design of the browser is for documents, and is really unsuitable for applications. Applications need a UI toolkit that takes a rectangle and renders the button, whatever into it. But you can't even get a proper rectangle with DOM: a div is 100% width, which is usually not what you want, but a span is this strange thing that makes sense for text, but not for a button or slider. So everything has "display: inline-block;", which then overrides the div or span part, so that it doesn't even matter which you pick. You can't even center something vertically without doing a web search, although I guess these days you use flexbox. Flexbox at least is the equivalent of Qt or Swing's layouts.
Mind you, I think WASM is the best thing that has happened to the browser, but that's because I think the HTML/DOM is completely unsuitable for apps, and I hate developing with it so much that I won't do it, even if I have to switch careers.
I think WASM is a reasonable start to a proper virtual machine. But I think what we need is a "browser" that presents a virtual machine with a virtual monitor(s), virtual chunk of contiguous memory, virtual CPU(s), virtual networking, virtual filesystem, and basic drawing primitives, that executes WASM. The "browser" part would be that you can use a URL to point to a WASM program. The program would see itself as being the only thing on the machine (see, basically generalization of the OS process concept into a machine). The user would be able to put limits on what the virtual network can access, what parts of the OS filesystem the virtual filesystem could access, how many real CPUs (and a cpulimit) the virtual CPUs get, etc. So, sort of like a containerized Plan9. I would be happy to do this myself, but I just don't have the spare time to do it, so unless someone is willing to fund me, I'll hope someone sees this and catches the vision.
Using WASM in the web browser is a workaround.
undefined
xmichael909
Personally not a fan of Windows 95 in the browser, however the browser stoped being a “document reader” a decade ago it’s the only universel, sandbox runtime, and everything is moving in that direction ... safe code. WASM isnt a worst VM; it’s a diffrent trade off: portable, fast start, capability scoped compute without shiping a OS. Raw device still have their place (servers). If you need safe distribution + performance thats “good enough” WASM in the browser is going to be the future of client.
oblio
A decade ago? Gmail was launched in 2004, 21 years ago.
flohofwoe
The problem is: even us old timers can't deny nor change the fact that operating systems have been putting up barriers to disallow running untrusted code downloaded from the internet.
Try to distribute an installer on Windows that isn't signed with an extensive EV-certificate for instance. It's scare popup galore.
Not to mention the closed gardens of the Apple and Google Stores which even when you get in, you can be kicked out again for absolutely no objective reason (they don't even need to tell you why).
> then we should be honest and build a virtualization abstraction that is actually what we want,
This is not in the interest of Microsoft, Google or Apple. They can't put the open web back into the box (yet, anyway), but they will not support any new attempts to create an open software ecosystem on "their" platforms.
pjmlp
Just wait until the Web finally becomes ChromeOS Platform, after the Safari barrier is out of the way.
chrsig
Think of it like emacs. Browsers are perfectly good operating systems just needing a better way to view the web.
mwcz
That's too true to be funny!
RussianCow
The browser removes the friction of needing to install specialized software locally, which is HUGE when you want people to actually use your software. Figma would have been dead in the water if it wasn't stupidly simple to share a design via a URL to anyone with a computer and an internet connection.
zeroq
I can't shake the feeling that this ship has sailed and only a few got to get on it while it happened.
And this comes from someone who started with Flash, built actual video editing apps with it, and for the last 25 years build application with "it's not a web app, it's a desktop app that lives in a browser" attitude [1].
Even with Flash we often used hybrid approach where you had two builds from same codebase - a lite version running in the browser and an optional desktop app (AIR) with full functionality. ShareObjects and LocalConnection made this approach extremely feasible as both instances were aware of each other and you could move data and objects between them in real time.
The premise is great, but it was never fully realized - sure you have few outliers like Figma, but building a real "desktop app" in a browser comes with a lot of quirks, and the resulting UX is just terrible in most cases.
[1] just to be clear, there's a huge difference between web page and web app ;D
ivell
I would argue that as soon as it was decided to include JavaScript runtime in the browser, it stopped being a plain document browser. From then on, we were just on the evolutionary path of converting it from a low capability app sandbox to a highly capable one.
imoverclocked
There are projects to run WASM on bare metal.
I do agree that we tend to run a lot in a web-browser or browser environment though. It seems like a pattern that started as a hack but grew into its own thing through convenience.
It would be interesting to sit down with a small group and figure out exactly what is good/bad about it and design a new thing around the desired pattern that doesn't involve a browser-in-the-loop.
syndeo
> run WASM on bare metal
Heh, reminds me of those boxes Sun used to make that only ran Java. (I don’t know how far down Java actually went; perhaps it was Solaris for the lower layers now that I think about it…)
Taikonerd
That's the idea of the Orca app/standard: https://orca-app.dev/
"What if we made a new WASM-based platform for apps, separate from the browser?"
GeneralMaximus
There is no difference between a "document" and an "app". There has never been a difference between the two, it's a purely artificial distinction.
Word and LibreOffice "documents" can run embedded macros. Emacs has `org-mode`, which can call out to any programming language on your $PATH. A PDF document is produced by running code in a stack-based virtual machine. Even fonts have bytecode instructions embedded inside them that are used for hinting.
If by "document" you mean "static text with no executable bits", then only plain text files can truly be called documents. Everything else is a computer program, and has been since the dawn of computing.
muyuu
the loose implication is that documents don't have access to resources outside of itself and they're somewhat static
imo when you start talking about dynamic documents the distinction starts to blur but it should be fine if it's just a few parameters that are meant to be manually updated... beyond that "document" seems like the wrong term (and tech)
those artificial distinctions are essential and perfectly practical as they can convey expectations just fine
GP is correct in that the browser has generalised to a point it has clear drawbacks for its original intended purpose, but that is just a fact of life at this point
IMO, html should have scaled back from 5.0 to the feature-set of 4, if not 3, with mass deprecations and beyond that it shouldn't be called html even if the main browsers carried on adding features and interoperable OS-like characteristics, so people could see beforehand if they were visiting hypertext documents or application sites, because certainly most of the web right now could not be reasonably called "hypertext"
but that isn't the way it was handled and tbh it was to be expected
wolvesechoes
> There is no difference between a "document" and an "app". There has never been a difference between the two, it's a purely artificial distinction.
Every distinction is artificial if you are willing to hair-split. No useful conclusion follows from this realization.
incrudible
I don’t think the total dissolution of a blurry boundary is a useful act. Yes, many document formats become Turing complete and run Doom eventually, but there is still a notable practical distinction between the intent to create a document interpreter versus an application framework.
undefined
renehsz
Unfortunately, Memory64 comes with a significant performance penalty because the wasm runtime has to check bounds (which wasn't necessary on 32-bit as the runtime would simply allocate the full 4GB of address space every time).
But if you really need more than 4GB of memory, then sure, go ahead and use it.
Findecanor
Actually, runtimes often allocate 8GB of address space because WASM has a [base32 + index32] address mode where the effective address could overflow into the 33rd bit.
On x86-64, the start of the linear memory is typically put into one of the two remaining segment registers: GS or FS. Then the code can simply use an address mode such as "GS:[RAX + RCX]" without any additional instructions for addition or bounds-checking.
jsheard
The comedy option would be to use the new multi-memory feature to juggle a bunch of 32bit memories instead of a 64bit one, at the cost of your sanity.
baq
didn't we call it 'segmented memory' back in DOS days...?
andrewl-hn
Somewhat related. At some point around 15 years ago I needed to work with large images in Java, and at least at the time the language used 32-bit integers for array sizes and indices. My image data was about 30 gigs in size, and despite having enough RAM and running a 64-bit OS and JVM I couldn't fit image data into s ingle array.
This multi-memory setup reminds me of my array juggling I had to do back then. While intellectually challenging it was not fun at all.
the_duke
The problem with multi-memory (and why it hasn't seen much usage, despite having been supported in many runtimes for years) is that basically no language supports distinct memory spaces. You have to rewrite everything to use WASM intrinsics to work on a specific memory.
evmar
It looks like memories have to be declared up front, and the memcpy instruction takes the memories to copy between as numeric literals. So I guess you can't use it to allocate dynamic buffers. But maybe you could decide memory 0 = heap and memory 1 = pixel data or something like that?
afiori
Honestly you could allocate a new memory for every page :-)
TrueDuality
The irony for me is that it's already slow because of the lack of native 64-bit math. I don't care about the memory space available nearly as much.
sehugg
Eh? I'm pretty sure it's had 64-bit math for awhile -- i64.add, etc.
fulafel
Bounds checking in other PLT is often reproted to result in pretty low overheads. Will be interesting to see some details about how this turns out.
zarzavat
I still don't understand why it's slower to mask to 33 or 34 bit rather than 32. It's all running on 64-bit in the end isn't it? What's so special about 32?
nagisa
That's because with 32-bit addresses the runtime did not need to do any masking at all. It could allocate a 4GiB area of virtual memory, set up page permissions as appropriate and all memory accesses would be hardware checked without any additional work. Well that, and a special SIGSEGV/SIGBUS handler to generate a trap to the embedder.
With 64-bit addresses, and the requirements for how invalid memory accesses should work, this is no longer possible. AND-masking does not really allow for producing the necessary traps for invalid accesses. So every one now needs some conditional before to validate that this access is in-bounds. The addresses cannot be trivially offset either as they can wrap-around (and/or accidentally hit some other mapping.)
azakai
The special part is the "signal handler trick" that is easy to use for 32-bit pointers. You reserve 4GB of memory - all that 32 bits can address - and mark everything above used memory as trapping. Then you can just do normal reads and writes, and the CPU hardware checks out of bounds.
With 64-bit pointers, you can't really reserve all the possible space a pointer might refer to. So you end up doing manual bounds checks.
phire
Because CPUs still have instructions that automatically truncate the result of all math operations to 32 bits (and sometimes 8-bit and 16-bit too, though not universally).
To operate on any other size, you need to insert extra instructions to mask addresses to the desired size before they are used.
dist1ll
WASM traps on out-of-bounds accesses (including overflow). Masking addresses would hide that.
tjoff
Webapps limited by 4GiB memory?
Sounds about right. Guess 512 GiB menory is the minimum to read email nowadays.
jjcm
I know you're in this for the satire, but it's less about the webapps needing the memory and more about the content - that's why I mentioned video editing webapps.
For video editing, 4GiB of completely uncompressed 1080p video in memory is only 86 frames, or about 3-4 seconds of video. You can certainly optimize this, and it's rare to handle fully uncompressed video, but there are situations where you do need to buffer this into memory. It's why most modern video editing machines are sold with 64-128GB of memory.
In the case of Figma, we have files with over a million layers. If each layer takes 4kb of memory, we're suddenly at the limit even if the webapp is infinitely optimal.
gertop
> 4GiB of completely uncompressed 1080p video in memory is only 86 frames
How is that data stored?
Because (2^32)÷(1920×1080×4) = 518 which is still low but not 86 so I'm curious what I'm missing?
undefined
flykespice
I'm strange to webdev, but can't you swap the remaining uncompressed frames that don't fit into memory to disk?
poly2it
It doesn't actually allocate 4 GiB. Memory can be mapped without being physically occupied.
IshKebab
No, web apps can actually use 4GB of memory (now 16GB apparently).
miniBill
In fairness, this is talking about Figma, not an email client
hsbauauvhabzb
Finally a web browser capable of loading slack
wslh
I assume that looking into the present we need to think about running local LLMs in the browser. Just a few days ago I submitted an article about that [1].
mikestaas
I'm excited by the GC, ref types and JS string API! Been a while J, how are you going?
undefined
j0e1
> Garbage collection. In addition to expanding the capabilities of raw linear memories, Wasm also adds support for a new (and separate) form of storage that is automatically managed by the Wasm runtime via a garbage collector. Staying true to the spirit of Wasm as a low-level language, Wasm GC is low-level as well: a compiler targeting Wasm can declare the memory layout of its runtime data structures in terms of struct and array types, plus unboxed tagged integers, whose allocation and lifetime is then handled by Wasm. But that’s it.
Wow!
teleforce
It's very refreshing and good to see WASM is embracing GC in addition to non-GC support. This approach is similar to D language where both non-GC and GC are supported with fast compilation and execution.
By the way now you can generate WASM via Dlang compiler LDC [1].
[1] Generating WebAssembly with LDC:
baxuz
Does this allow for shrinking the WebAssembly.Memory object?
- https://github.com/WebAssembly/design/issues/1397
- https://github.com/WebAssembly/memory-control/issues/6
This is a crucial issue, as the released memory is still allocated by the browser.
kannanvijayan
No, I don't think it will. Pointers to managed objects are opaque, and aren't actually backed by the wasm memory buffer. The managed heap is offloaded.
Shrinking the memory object shouldn't require any special support from GC, just an appropriate API hook. It would, as always, be up to the application code running inside the module to ensure that if a shrink is done, that the program doesn't refer to memory addresses past the new endpoint.
If this hasn't been implemented yet, it's not because it's been waiting on GC, but more that it's not been prioritized.
azakai
Wasm GC is entirely separate from Wasm Memory objects, so no, this does not help linear memory applications.
Zariff
I'm not familiar with WASM. Can someone explain why this is a good thing? How does this work with languages that do not have a garbage collector, like Rust?
goku12
The answer was kind of known before hand. It was to enable the use of GCed languages like Python on Ruby to create WASM applications. Meanwhile, non-GCed languages like Rust, C and C++ were supposed to continue to work as before on WASM without breaking compatibility. This is what they seem to have finally achieved. But I needed to make sure of it. So, here are the relevant points from the WASM GC proposal [1]:
* Motivation
- Efficient support for high-level languages
- faster execution
- smaller modules
- the vast majority of modern languages need it
* Approach
- Pay as you go; in particular, no effect on code not using GC, no runtime type information unless requested
- Don't introduce dependencies on GC for other features (e.g., using resources through tables)
[1] https://github.com/WebAssembly/spec/blob/wasm-3.0/proposals/...wffurr
Note that the high level language needs a sufficient abstraction in its own runtime to allow substituting the Wasm GC for the runtime’s own GC. Work has been done for Java and Kotlin, but Python, C#, Ruby, Go can’t yet use the Wasm GC.
larodi
to also consider this one https://github.com/6over3/zeroperl
robmccoll
Non-GCed languages will continue to manage memory themselves. Previously, GCed languages that wanted to run on WASM had to have an implementation of their runtime including GC compiled to WASM. The idea or hope here is that those languages can use the built-in GC instead and slim down the amount of WASM that needs to be delivered to run the application to only include a minimal runtime. The current scenario is closer to if a web app or node app built with JavaScript had to ship a significant portion of V8 with it to function.
flykespice
This will probably benefit Java applets targeting Wasm the most considering the huge size of their JVM.
apitman
Here's a fun example of a language that takes advantage of this: https://spritely.institute/hoot/
simon_void
I works very well, thank you for asking: https://rustwasm.github.io/book/
wyager
This seems less than ideal to me.
1. Different languages have totally different allocation requirements, and only the compiler knows what type of allocator works best (e.g. generational bump allocator for functional languages, classic malloc style allocator for C-style languages).
2. This perhaps makes wasm less suitable for usage on embedded targets.
The best argument I can make for this is that they're trying to emulate the way that libc is usually available and provides a default malloc() impl, but honestly that feels quite weak.
Zardoz84
I don't see this as a problem in the JVM, where independently of what programming language you are using, you will use the GC configured on the JVM at launch.
satellite2
That sounds like WASM is going into the Java direction. Is that really a good thing?
robmccoll
What do you mean by the Java direction? It's a virtual machine with GC support, so I guess in that regard it's similar to the JVM, CLR, BEAM, et al. If anything, those VMs show performance improvement and better GC over time and a strong track record of giving legacy software longevity. The place where things seem to fall apart over the long term is when you get to the GUI, which is arguably a problem with all software.
danielearwicker
Java approach: create the JVM to support one language, so it has rich high-level concepts that are unfortunately skewed toward certain assumptions about language design, and it can be reused only for other languages that are similar enough.
WASM approach: start very low-level so C is definitely supported. Thus everything is supported, although every language has to roll its own high-level constructs. But over time more patterns can be standardised so languages can be interoperable within a polyglot WASM app.
cedws
When is WASM finally going to be able to touch the DOM? It feels like that was the whole point of WASM and instead its become a monster of its own that barely has anything to do with web anymore. When can we finally kill JavaScript?
apatheticonion
Agreed. This and (sane) access to multi-threading. I want to be able to write a Rust application, compile to wasm and load it with
<html>
<body>
<div id="root"></div>
<script type="application/wasm" src="./main.wasm"></script>
</body>
</html>
Would be great for high performance web applications and for contexts like browser extensions where the memory usage and performance drain is real when multiplied over n open tabs. I'm not sure how code splitting would work in the wasm world, however.v8 could be optimized to reduce its memory footprint if it detects that no JavaScript is running - or wasm-only applications could use an engine like wasmer and bypass v8 entirely.
Another factor is that web technologies are used to write desktop applications via Electron/similar. This is probably because desktop APIs are terrible and not portable. First class wasm support in the web would translate to more efficient desktop applications (Slack, VSCode, Discord, etc) and perhaps less hate towards memory heavy electron applications.
cesarb
> <script type="application/wasm" src="./main.wasm"></script>
<applet code="./Main.class"></applet>
Plus ça change...
pjmlp
The difference is that now it is cool.
biztos
<!doctype html>
<wasm src="my-app.wasm">
Why not just do the whole DOM out of your WASM?Aransentin
If you're at that point, the logical step would be to just support replying to the HTTP request with a "content-type: application/wasm" and skip the initial html step entirely.
jesse__
Not sure what the Rust situation is like, but last I checked (and compiled a non-trivial personal application) WASM supported the pthreads API and it seemed to work reasonably well. Have you encountered stumbling points porting a heavily MT Rust program to WASM?
stevefan1999
That's supposedly WASI, an interface specifically designated for system programming use, and that's where it implements part of the POSIX support including pthread.
OTOH you still need to start a wasm runtime first, then import the WASI module into the wasm host.
P.S.: used to tinker with wasmtime and wasmi to add wasm support to my half abandoned deno clone ;) I learned this the hard way
kketch
WASM itself does not support pthreads. However things like Emscripten have very good support for pthreads. WASM is one of the compilation targets of Emscripten (we had asm.js before that) and on top of that emscripten provides excellent shims for many POSIX APIs. Regarding Rust which has supported WASM as a compilation target for a long time now, the idiomatic way of doing this is not shiming, but using higher level APIs: if you need parallel execution threads and need to compile to WASM you would use a crate (such as rayon) that is able to compile to WASM (and will use web workers under the hood just like Emscripten does). You would not use pthreads directly (std::thread)
sapiogram
WASM does not support pthreads in the browser, only web workers, which are much more limited.
kketch
You can do all of this using Rust today. Very sane access to multi-threading => writing rust code that runs in parallel and is compiled without you worrying about it to run under several web workers
apatheticonion
That still requires a bunch of glue code right? Like, I can't simply compile my application to a wasm target and threads just work
cargo build --release --target wasm64
I think wasi has access to threading, but I don't think browsers support wasi?hankman86
I completely agree. The WebAssembly multi-threading programming model with its reliance on the web worker API is a pain to deal with. Google’s Native Client had native threading support, why can this not be replicated in WebAssembly?
dfabulich
Basically never, because it would require re-standardizing the DOM with a lower-level API. That would take years, and no major browser implementor is interested in starting down that road. https://danfabulich.medium.com/webassembly-wont-get-direct-d...
Killing JavaScript was never the point of WASM. WASM is for CPU-intensive pure functions, like video decoding.
Some people wrongly thought that WASM was trying to kill JS, but nobody working on standardizing WASM in browsers believed in that goal.
pjmlp
People have to look at it, from the same point of view Google sees the NDK on Android.
"However, the NDK can be useful for cases in which you need to do one or more of the following:
- Squeeze extra performance out of a device to achieve low latency or run computationally intensive applications, such as games or physics simulations.
- Reuse your own or other developers' C or C++ libraries."
And I would argue WebGL/WebGPU are preferably better suited, given how clunky WebAssembly tooling still is for most languages.
apatheticonion
It's really not that hard. Node.js has a very mature C FFI for interacting with JavaScript.
Just agree on some basic bindings
wasb_create_u32(env: *const env, value: u32, result *mut value) -> status
wasb_create_string_utf8(env: *const env, str: *const c_char, length: i32, result: *mut value) -> status
There is even a shim that ports the Node.js C FFI to wasm: https://github.com/devongovett/napi-wasm/blob/main/index.mjs...Heck, just include that in the browser so it doesn't need to be loaded at runtime
Stack that with support in the browser for wasi and you have everything you need to work with the DOM from wasm as well as things like threading
yoden
That's the issue with WASM. Very, very few people want a limited VM that's only good for CPU-intensive pure functions. The WASM group has redirected a huge amount of resources to create something almost nobody wants.
mallets
A bit unrelated, but are there any recent benchmarks comparing it with native perf?
Hard to believe it can compete with V8 JIT anytime soon. Might be easier to integrate fast vector libraries within javascript engines.
torginus
Contrary to naysayers, I'm pretty sure this is very doable. Most browser JS objects map 1-1 to C++ native objects implemeneted in the browser.
As others have pointed out, the Js compoment interface is define in a language called WebIDL:
https://firefox-source-docs.mozilla.org/dom/webIdlBindings/i...
How it works in Chrome(Blink) is that a compiler generates a wrapper between V8, which is a V8 object that holds onto the native object reference using this IDL.
Once V8 cleans up the Js object, the native code, holding a weak reference to the native objects, detects that it has become unreachable and cleans that up.
In any ways, the object lifetime is encapsulated by the v8 Isolate (which is depending on how you look at it, the lifetime of the HTML document or the heap), so it'd be perfectly fine to expose native references as they'd be cleaned up when you navigate away/close the page.
Once you support all the relevant types, define a calling convention, and add an appropriate verifier to Wasm, it'd be possible to expose all native objects to Wasm, probably by generating a different (and lighter weight) glue to the native classes, or delegating this task to the Wasm compiler.
Of course, if you wanted to have both JS and Wasm to be able to access the same object, you'd have to do some sort of shared ownership, which'd be quite a bit more complicated.
So I'd argue it'd make sense to allow objects that are wholly-owned by the Wasm side or the JS side, which still makes a ton of sense for stuff like WebGL, as you could basically do rendering without calling into JS.
I'm going out on a limb here, but I'd guess since this multi-memory support has landed, that means a single webassembly instance can map multiple SABs, so it might be the beginnings of that.
vinkelhake
You can write a WASM program today that touches the DOM, it just needs to go through the regular JS APIs. While there were some discussions early on about making custom APIs for WASM to access, that has long since been dropped - there are just too many downsides.
cedws
But then you need two things instead of one. It should be made possible to build WASM-only SPAs. The north star of browser developers should be to deprecate JS runtimes the same way they did Flash.
austin-cheney
That is never going to happen until you create your own browser with a fork of the WASM spec. People have been asking for this for about a decade. The WASM team knows this but WASM wants to focus on its mission of being a universal compile target without distraction of the completely unrelated mission of being a JavaScript replacement.
bonestamp2
I agree with the first part, but getting rid of JS entirely means that if you want to augment some HTML with one line of javascript you have to build a WASM binary to do it?
I see good use cases for building entirely in html/JS and also building entirely in WASM.
brokencode
You can use a framework that abstracts all the WASM to JS communication for DOM access. There are many such framework already.
The only issue is that there’s a performance cost. Not sure how significant it is for typical applications, but it definitely exists.
It’d be nice to have direct DOM access, but if the performance is not a significant problem, then I can see the rationale for not putting in the major amount of work work it’d take to do this.
lyu07282
I was under the impression that this very much still on the table, with active work like the component model laying the foundation for the ABI to come.
benrutter
I have slightly different question than OP - what's left until it feels like javascript is gone for people who don't want to touch it?
Say I really want to write front end code in Rust* does there just need to be a library that handles the js DOM calls for me? After that, I don't ever have to think about javascript again?
tcfhgj
> Say I really want to write front end code in Rust* does there just need to be a library that handles the js DOM calls for me? After that, I don't ever have to think about javascript again?
yes, e.g. with Leptos you don't have to touch JS at all
colordrops
Isn't going through the JS APIs slow?
nasso_dev
used to be, in the early days, but nowadays runtimes optimized the function call overhead between WASM and JS to near zero
https://hacks.mozilla.org/2018/10/calls-between-javascript-a...
zekrioca
Could you list some of these downsides and what are the reason of their existence?
cogman10
For starters, the DOM API is huge and expansive. Simply giving WASM the DOM means you are greatly expanding what the sandbox can do. That means lower friction when writing WASM with much much higher security risks.
But further, WASM is more than just a browser thing at this point. You might be running in an environment that has no DOM to speak of (think nodejs). Having this bolted on extension simply for ease of use means you now need to decide how and when you communicate its availability.
And the benefits just aren't there. You can create a DOM exposing library for WASM if you really want to (I believe a few already exist) but you end up with a "what's the point". If you are trying to make some sort of UX framework based on wasm then you probably don't want to actually expose the DOM, you want to expose the framework functions.
DarkNova6
I am watching patiently from a distance to my hands on a well-designed frontend language but can't help to wonder... is it really _that_ inefficient to call a JS wrapper to touch the DOM?
Most code already is so horribly inefficient that I can't imagine this making a noticeable difference in most scenarios.
p_l
GC was required part, because it was needed to allow interaction between DOM-side lifetimes and WASM-side lifetimes. You might still need a puny shim to essentially "declare" whatever form you want the DOM API to look like on WASM side (probably utilizing components and WIT in the future) but that shim won't have to do anything other than register the APIs because WASM will be able to take a reference to DOM object and vice versa instead of throwing a copy of data over the wall as it is now.
undefined
namuol
> When can we finally kill JavaScript?
If you think JavaScript has problems I have bad news about the DOM…
Tade0
Wanted to say the same thing. People often conflate JS with the DOM API, but that couldn't be further from the case.
You can get rid of JS, but that won't help much because it's just a small language interfacing with a huge, old, backwards compatible to 20+ years ago system that is the DOM.
fullstackchris
yep, ive still never understood the fetish of HN folks wanting to eliminate JS completely. you tell them to use TS, they say its overcomplicated... i've never heard a definitive or decent answer to "ok what language WOULD you use for manipulating the DOM?" its infuriating, though i suppose those complaining have probably built like one website once. yes, JS is not your strongly typed Rust / Go / .NET, get over it - go learn TypeScript and be happy
DanielHB
I don't think WASM by itself will finally kill Javascript, other languages and their tooling are not well equipped to create DOM-based applications with the constraints expected for the web (fast loading times, lazy-loading, asset bundling, etc).
I don't think most languages it is even feasible to compile to wasm in a way that doesn't include a splashscreen for any non-trivial application. Which is simply unacceptable for most web content. And that is even before all the work required in user-land to support browser primitives (like URL routing, asset loading, DOM integration, etc).
So I can foresee this unlocking "heavy duty productivity apps" to run in the browser things like video editors or photoshop using web-first GUI (meaning DOM elements) without significant amounts of JS. But for general web content consumed by the masses I find it unlikely.
I expect the real "javascript death" will mean a completely new language designed from the ground-up to compile to WASM and work with browser APIs.
re
I haven't really been following WASM development in the last year and didn't realize that WASM had moved to a versioned release model. I've been aware of the various features in development[1] and had thought many of the newer features were going to remain optional but I guess now that implementations are expected to support all the features to be able to claim compatibility with e.g. "WASM 3.0"?
It'll be interesting to see what the second non-browser-based WASM runtime to fully support 3.0 will be (I'm guessing wasmtime will be first; I'm not counting Deno since it builds on v8). Garbage collection seems like a pretty tricky feature in particular.
Does anyone know how this 3.0 release fits into the previously announced "evergreen" release model?[2]
> With the advent of 2.0, the Working Group is switching to a so-called “evergreen” model for future releases. That means that the Candidate Recommendation will be updated in place when we create new versions of the language, without ever technically moving it to the final Recommendation state. For all intents and purposes, the latest Candidate Recommendation Draft[3] is considered to be the current standard, representing the consensus of the Community Group and Working Group.
[1] https://webassembly.org/features/
cfallin
> It'll be interesting to see what the second non-browser-based WASM runtime to fully support 3.0 will be (I'm guessing wasmtime will be first; ...)
Wasmtime already supports every major feature in the Wasm 3.0 release, I believe. Of the big ones: garbage collection was implemented by my colleague Nick Fitzgerald a few years ago; tail calls by Jamey Sharp and Trevor Elliott last year (with full generality, any signature to any signature, no trampolines required!); and I built our exceptions support which merged last month and is about to go out in Wasmtime 37 in 3 days.
The "3.0" release of the Wasm spec is meant to show progress and provide a shorthand for a level of features, I think, but the individual proposals have been in progress for a long time so all the engine maintainers have known about them, given their feedback, and built their implementations for the most part already.
(Obligatory: I'm a core maintainer of Wasmtime and its compiler Cranelift)
azakai
> garbage collection was implemented by my colleague Nick Fitzgerald a few years ago
The wasm features page says it is still behind a flag on wasmtime (--wasm=gc). Is that page out of date?
cfallin
No, it's still behind a flag (and so transitively, exceptions are too, because we built exception objects on top of GC).
Our docs (https://docs.wasmtime.dev/stability-tiers.html) put GC at tier 2 with reason "production quality" and I believe the remaining concerns there are that we want to do a semi-space copying implementation rather than current DRC eventually. Nick could say more. But we're spec-compliant as-is and the question was whether we've implemented these features -- which we have :-)
titzer
Wizard supports all of Wasm 3.0, but as a research tool, it only has an interpreter and baseline compiler tier (no opt compiler), so it doesn't run as fast as, say, V8 or wasmtime.
afiori
I suspect the versioning is going to replicate the JavaScript version system where versions are just sets of features that a runtime can support or not, I am not sure how feature discovery works in wasm though
alabhyajindal
The WebAssembly community should really focus more the developer experience of using it. I recently completed a project where I wrote a compiler¹ targeting it and found the experience to be rather frustrating.
Given that Wasm is designed with formal semantics in mind, why is the DX of using it as a target so bad? I used binaryen.js to emit Wasm in my compiler and didn't get a feeling that I am targeting a well designed instruction set. Maybe this is a criticism of Binaryen and its poor documentation because I liked writing short snippets of Wasm text very much.
sjrd
Binaryen has a lot of baggage from Wasm early days, when it was still a strict AST. Many newer features are difficult to manipulate in its model.
In our compiler (featured in TFA), we chose to define our own data structure for an abstract representation of Wasm. We then wrote two emitters: one to .wasm (the default, for speed), and one to .wat (to debug our compiler when we get it wrong). It was pretty straightforward, so I think the instruction set is quite nice. [1]
[1] https://github.com/scala-js/scala-js/tree/main/linker/shared...
sestep
For what it's worth, I also tried Binaryen from TypeScript and similarly found it frustrating. I switched to using wasm-tools from Rust instead, and have found that to be a vastly better experience.
alabhyajindal
Isn't wasm-tools for working with Wasm modules? Maybe I'm missing something. I was using Binaryen to compile an AST to WebAssembly text. Also worth mentioning that Binaryen is the official compiler/toolchain for this purpose which is why I expected more from it.
sestep
Currently you use Binaryen to build up a representation of a Wasm module, then call emitText to generate a .wat file from that. With wasm-tools you'd do the same thing via the wasm-encoder crate to generate the bytes corresponding to a .wasm file, and then use the wasmprinter crate to convert from the .wasm format to the .wat format. Alternatively, I believe the walrus crate gives you a somewhat higher-level API to do the same thing, but I haven't used it because it's much heavier-weight.
titzer
What were your specific pain points? One thing that can be annoying is validation errors. That's one of the reasons that Wizard has a --trace-validation flag that prints a nicely-formatted depiction of the validation algorithm as it works.
alabhyajindal
Validation errors were bit of an issue. Especially because Binaryen constructs an internal IR that remains opaque until we emit the Wasm text. I did consider Wizard for my project but settled on Wasmtime because I needed WASI support.
My major pain point was the documentation. The binaryen.js API reference¹ is a list of function signatures. Maybe this makes sense to someone more experienced but I found it hard to understand initially. There are no explanation of what the parameters mean. For example, the following is the only information the reference provides for compiling an `if` statement:
Module#if(condition: Expression, ifTrue: Expression, ifFalse?: Expression): Expression
In contrast, the Wasm instruction reference on MDN² is amazing. WASI again suffers from the same documentation issues. I didn't find any official resource on how to use `fd_write` for example. Thankfully I found this blog post³.Wasm feels more inaccessible that other projects. The everyday programmer shouldn't be expected to understand PL research topics when they are trying to do something with it. I understand that's not the intention but this is what it feels like.
1. https://github.com/WebAssembly/binaryen/wiki/binaryen.js-API
2. https://developer.mozilla.org/en-US/docs/WebAssembly/Referen...
kg
Thanks for bringing Wizard to my attention, the next time I need to validate wasm it's going to save me a ton of time.
azakai
Sorry about binaryen.js - those JS/TS bindings could be a lot better, and better documented, but priorities are generally focused on improving optimizations in core Binaryen.
That is, most work in Binaryen is on improving wasm-opt which inputs wasm and outputs wasm, so any toolchain can use it (as opposed to just JS/TS).
But if someone had the time to improve the JS/TS bindings that would be great!
Existenceblinks
i found assembly is easier to assemble from scratch (it's apple and orange but.). Most materials should exclude these tooling, mostly rust based tools. We should be able to write them by hands just like when assembly was taught. Compiler and assembly are separate classes. I think it's bad assumption that only compiler devs only care about wasm. It's compiling target, sure, but framing it this way will not broaden its knowledge.
jamii
I've tried using binaryen, and I've also tried emitting raw wasm by hand, and the latter was far easier. It only took ~200 lines of wasm-specific code.
pveierland
The SpecTec mentioned in the announcement is really cool. They're using a single source of truth to derive LaTeX, Sphinx docs, Coq definitions for proofs, and an AST schema. Building the language spec in a way that its soundness can be proven and everything derived from one truth in this way seems super useful.
flohofwoe
Since it hasn't been mentioned here yet: I wonder if the multiple-memories feature will somehow allow to avoid the extra copy that's currently needed when mapping a WebGPU resource. This mapping is available in a separate ArrayBuffer object which isn't accessible from WASM without calling into JS and then copying from the ArrayBuffer into the WASM heap and back.
Multiple WASM memories and Clang's/LLVM's address space feature sound like they should be able to solve that problem, but I'm not sure if it is as trivial as it sounds...
titzer
There has been a discussion (https://github.com/WebAssembly/multi-memory/issues/45) on the toolchain support, but I'm not sure if there have been steps to use multiple address spaces to support Wasm multi-memory in LLVM yet.
whizzter
I'm just getting horrible segmenting and far-pointer vibes of the whole thing, been coding a classic Gameboy game for fun so fiddling with memory mappings is part of the "fun" but for anything non-constrained I'd hate that.
We buried far pointers with DOS and Win16 for a good reason..
flohofwoe
I'd take segment-pointers over copying megabytes of memory around anyday though ;)
It's not much different than dealing with all the alignment rules that are needed when arranging data for the GPU.
dontlaugh
"Far" memory is already a central concept in modern GPU APIs. Not all GPUs naturally share memory with the CPU they're running against and handles for resources are a requirement.
bborud
I'm a simple man who has simple needs. I want a better and faster way to pass Go structs in and out of the runtime that doesn't mean I have to do a sword dance on a parquet floor wearing thick knit wool socks and use some fragile grafted on solution.
If there can be a solution that works for more languages: great. I mostly want this for Go. If it means there will be some _reasonable_ limitations, that's also fine.
mixedCase
You're doing native code, this the solution is the same as in native code: your languages agree on a representation, normally C's, or you serialize and deserialize. Mixing language runtimes is just not a nice situation to deal with without the languages having first class support for it, and it should be obvious why.
afiori
I am not sure what you actually want but it sounds like something where the component model (the backbone of WASI) might help.
It defines a framework to allow modules to communicate with structured data types by allowing each module to decide how to map it to and from its linear memory (and in future the runtime GC heap)
In your case you could be able to define WIT interfaces for your go types and have your compiler of choice use it to generate all the relevant glue code
fidotron
This is the truth, and it's not really much better in non-GCed languages either. (In reality my impression is the GCed wasm side runtimes are even worse).
Some of the least fun JavaScript I have ever written involved manually cleaning up pointers that in C++ would be caught by destructors triggering when the variable falls out of scope. It was enough that my recollections of JNI were more tolerable. (Including for go, on Android, curiously).
Then once you get through it you discover there is some serious per-call overhead, so those structs start growing and growing to avoid as many calls as possible.
I too want wasm to be decent, but to date it is just annoying.
tracker1
Was this dealing with DOM nodes and older IE versions by chance? That was probably the single biggest reason to wrap all DOM manipulation with JQuery in that it did a decent job of tracking and cleanup for you. IIRC, a lot of the issues came from the DOM and JS being in separate COM areas and the bridge not really tracking connections for both sides.
fidotron
I need to pass all the user input events to a game engine, and get back the results into the webgl JS runtime side renderer. (The games at https://www.luduxia.com/ )
zdandoh
That would be more of a library than a WASM spec thing, no? I wrote a code generator that does this well for some internal use-cases.
pjmlp
This is exactly why I say WebGL/WebGPU are much better for perfomance code on the browser than dealing with WebAssembly tooling.
phkahler
Still looking forward to when they support OpenMP. We have an experimental Solvespace web build which could benefit quite a bit from that.
Open source CAD in the browser.
atroche
This is one of the best WASM-based web UIs I've seen! What was the hardest part of getting your desktop build working via Emscripten?
phkahler
I didn't do the WASM port. It was started by our previous lead whitequark, and some more work done by a few others. It's not quite complete, but you can do some 3d modeling. Just might not be able to save...
threeducks
> Just might not be able to save...
Oops, I did not read that before going ham in the editor. It seems that the files are stored inside the emscripten file system, so they are not lost. I could download my exported 'test.stl' with the following JavaScript code:
var data = FS.readFile('test.stl');
var blob = new Blob([data], { type: 'application/octet-stream' });
var a = document.createElement('a');
a.href = URL.createObjectURL(blob);
a.download = 'test.stl';
a.click();phkahler
One thing worth noting, everything but the menus and popups is drawn with openGL. The text window uses GNU unifont which is a bitmap font. All the interactions are handled the same way as the desktop versions.
fulafel
Sounds like that would be something on a different abstraction level than WebAssembly itself, or are there some blockers in the platform that preclude a OpenMP implementation targeting WebAssembly?
aquariusDue
I just want to say that Solvespace is amazing, I was able to follow a tutorial on YouTube and then design a split keyboard case for CNCing, all pretty quickly a few years ago.
Thank you for maintaining it!
spankalee
I really hope this spurs AssemblyScript to just port to WASM GC: https://github.com/AssemblyScript/assemblyscript/issues/2808
There's comments in there about waiting for a polyfill, but GC support is widespread enough that they should probably just drop support for non-GC runtimes in a major version.
mistahchris
I'm still hype about WASM. This looks like a cool release. I'm running some pretty high traffic WASM plugins on envoy, running some plugins for terminal apps (zellij), and for one of my toy side projects, I'm running a wasm web app (rust leptos).
For 2 of those 3 use cases, i think it's not technically the optimal choice, but i think that future may actually come. Congratulations and nice work to everyone involved!
jasonthorsness
I don't think the GC in this version has the features required to enable a C# runtime on top of it yet: https://github.com/WebAssembly/gc/issues/77
I wonder what language this GC can actually be used for at this stage?
davexunit
The article answers your question, there are at least 6 languages: Java, OCaml, Scala, Kotlin, Scheme, and Dart.
programLyrique
OCaml with wasocaml: https://github.com/OCamlPro/wasocaml
markdog12
Dart for a long time now.
outadoc
Kotlin/WASM is a thing
whizzter
I'm not familiar with all the implementation details of objects in C#, but the list of issues mixes runtime implementation details (object layouts) that should be fairly low effort to work around with actual language/runtime features (references, finalization).
In general though most regular C# code written today _doesn't directly_ use many of the features mentioned apart from references. Libraries and bindings however do so a lot since f.ex. p/invoke isn't half as braindead as JNI was, but targeting the web should really not bring along all these libraries anyhow.
So, making a MSIL runtime that handles most common C# code would map pretty much 1-1 with Wasm-GC, some features like ref's might need some extra shims to emulate behaviour (or compiler specializations to avoid too bad performance penalties by extra object creation).
Regardless of what penalties,etc goes in, the generated code should be able to be far smaller and far less costly compared to the situation today since they won't have to ship both their own GC and implement everything around that.
kg
Part of the problem is you would need to fork the base class libraries and many popular nuget packages to remove any uses of ref/in/out, along with any interior references, spans, etc. The .NET type system has allowed 'interior references' (references into the inside of a GC object) for a long time and it's difficult to emulate those on top of WasmGC, especially if your goal is to do it at low cost.
It's definitely true that you could compile some subset of C# applications to WasmGC but the mismatch with the language as it's existed for a long time is painful.
whizzter
Like I wrote, references could be managed with shims (basically a getter-setter interface per-referenced-value-type that's then implemented per-target type) and yes it'd be a painfully "expensive" variation, but for 90% of the cases those can probably be rewritten by a compiler to an inlined variation without those performance penalties.
My argument is that, code that goes on the web-side mostly would adhere to the subset, many of the ref-cases can be statically compiled away and what remains is infrequent enough that for most users it'll be a major win compared to avoid lugging along the GC,etc.
Get the top HN stories in your inbox every day.
I'm definitely excited to see 64 bit as a default part of the spec. A lot of web apps have been heavily restricted by this, in particular any online video editors. We see a bunch of restrictions due to the 32 bit cap today here at Figma. One thing I'm curious though is whether mobile devices will keep their addressable per-tab memory cap the same. It's often OS defined rather than tied to the 32 bit space.