The issue comes down to the fact that even if your WASM code can return a utf16 buffer, to use it as a string in JS code the engine needs to make a copy at some point. The TextDecoder api does a first good job of making this efficient, ensuring there is just a single copy, but it's still overhead.
Ideally there should be a way to wrap an array buffer with a "String View", offloading the responsibility of ensuring its utf16 to the WASM code, and there being no copy made. But that brings a ton of complexities as strings need to be immutable in js, but the underlying buffer could still be changed.
https://github.com/WebAssembly/js-string-builtins/blob/main/...
It keeps WASM simple and provides a thin layer as an optimisation.
At the cost of complicating JS string implementations, probably to the point of undoing the benefits.
Currently JS strings are immutable objects, allowing for all kinds of optimization tricks (interning, ropes, etc.). Having one string represented by a mutable arraybuffer messes with that.
There's probably also security concerns with allowing mutable access to string internals inside the JS engine side.
So the simple-appearing solution you suggested would be rejected all major browser vendors who back the various WASM and JS engines.
Access to constant JS strings without any form of mutability is the only realistic option for accessing JS strings. And creating constant strings is the only one for sending them back.
https://www.nhatcher.com/post/should_i_import_or_should_i_ro...
The code is a bit outdated, but the principle of linking against the browser implementation stands
So they decode one long concatenated string and then on the JS side split it into substrings? I wonder if that messes with the GC on the JS side of things.
Context: as far as I know Electron is still the king if you want to do (unsafe but performant) "IPC/RPC" between native and a webview.
All of the other options that exist in other languages (Deno, Rust, you name it) do the same "stringified JSON back and forth" which really isn't great for performance in my opinion.
It'd be cool if (obviously in a sandboxed or secure way) you could opt in to something albeit a bit reckless, but some way to provide native methods for the WASM part of V8 and its WebView (thinking Electron-esque here) to call.
VSCode IPC is kinda similar as it's designed to facilitate comms over an enforced process isolation barrier to protect the main thread from slow extensions etc. but it's actually IPC there (as in, there are multiple processes at the os level). The wasm/js stuff is handled within the same v8 context - it's not actually ipc.
(Happy to be corrected here, but this is my understanding)
Tell me how you'd do "native C/C++ FFI (to like a .so or .dylib or .dll)" between the webview using WASM or anything other than "WebKit's built in JSON-string based IPC"
Like a <button> that triggers a DLL call. How would you achieve it with WASM? How does WASM act as the bridge to the DOM and/or native? It doesn't, right?
andyferris•9h ago
I'd love for some native way of handling UTF-8 in JavaScript and the DOM (no, TextEncoder/TextDecoder do not count). Even a kind of "mode" you could choose for the whole page would be a huge step forward for the "compile native language to WASM + web" thing.
theSherwood•8h ago
continuational•7h ago
ethan_smith•7h ago