3 ms·
I believe it's mainly because of the requirements for (1) integration with a single GC (the one in the browser), and (2) zero-copy inter-op with JavaScript st
by chubot 3y ago
I believe it's mainly because of the requirements for
(1) integration with a single GC (the one in the browser), and
(2) zero-copy inter-op with JavaScript strings.
If you take them as axioms, those pretty much force you to put strings as a native type in WASM. They can't really be done as libraries.
Not sure if it helps, but I wrote about my experience writing a GC here, and the "reality sandwich" metaphor:
https://www.oilshell.org/blog/2023/01/garbage-collector.html https://www.oilshell.org/blog/2023/01/garbage-collector.html
https://lobste.rs/s/v5ferx/scheme_browser_hoot_tale#c_n87bzw https://lobste.rs/s/v5ferx/scheme_browser_hoot_tale#c_n87bzw
https://lobste.rs/s/v5ferx/scheme_browser_hoot_tale#c_mw6tfx https://lobste.rs/s/v5ferx/scheme_browser_hoot_tale#c_mw6tfx
The sandwich has:
(1) the mutator's view on one side
(2) the single bit representation of data types in the middle
(3) the GC's view on the other side
Basically a bunch of people thought that you could just have one half of the sandwich -- you could just have the GC, and use whatever data types you want.
Implementing a GC will disabuse you of that notion (ESPECIALLY a GC that runs remote, untrusted code, but it's true for any GC.)
The core data types and the GC are tightly coupled, and the GC already lives in the browser.
So WASM necessarily gives you the WHOLE sandwich -- both data types and the GC. Fundamentally, it can't do anything else.
But that means that the data types are a huge design compromise -- there are winners and losers. Now you have a MAPPING problem from every language to WASM types.
---
As a concrete example, I mentioned that Go has slices, which are reference types, and they have pointers to anywhere in a string.
This means the GC has to be able to find the head of a string from an interior pointer, which is hard in general.
So, without being very close to WASM GC, I suspect Go will be a loser in this respect (it will perform less well), simply because JS GC's don't have to deal with interior pointers.
Every design decision involves winners and losers -- "universal VM" is a bit of a fallacy.
---
Strings are another area where there are winners and losers -- UTF-16 means JS/Java perform better, but UTF-8 means other languages perform better.
Although this stringref proposal is interesting because it tries not to be biased -- it tries to develop an API that can be implemented with both UTF-8 or UTF-16 representations. Still, it's very hard problem and involves deep compromises.
- haberman 3y ago> They can't really be done as libraries. It's definitely the case that you can't implement a string type in WASM and have it interoperate with JavaScript strings. But there is no reason that JavaScript strings can't be a "special" kind of import that provides functionality implemented by the engine. In other words, #include <wasm/wtf16string.h> could provide an API for the built-in JavaScript string, much like #include <ruby.h> provides access to the native Ruby string in Ruby extensions. I believe this is how the counter-proposal works: https://github.com/WebAssembly/js-string-builtins/blob/main/proposals/js-string-builtins/Overview.md https://github.com/WebAssembly/js-string-builtins/blob/main/... For engines that do not have a built-in JavaScript-like string type, the wasm/wtf16string.h library could be implemented in WASM as a polyfill. In that case, there is no native string to interoperate with, so no disadvantage to implementing directly in WASM (except perhaps a bit of speed penalty).
- chubot 3y agoWhat I'm reading there is that it's less ambitious -- it would only work for languages that have JavaScript string semantics. Some languages targeting WebAssembly may have compatible primitives and would benefit from being able to use the equivalent JavaScript primitive for their implementation I believe Java fits that bill (it's UTF-16, at least). So if you were writing a JVM to work on WASM, then you could possibly just import the JS string and use it, and get zero-copy inter-op. --- But what the Wingo article is saying is they want something even more ambitious: have a working Scheme or Python or Lua implementation with zero-copy JS inter-op. If they can paper over the bytes vs. UTF-16 vs. code points API issue, making a single string type that's not biased toward one or the other, I think it's a step in the right direction. (The aside about decoupling JS itself from UTF-16 string APIs is pretty intriguing too!) But it's still not obvious to me that even this gets you all the way there. For example, Python interns some strings, and Lua apparently interns ALL strings, and they both have hash codes in the string object, and expose it to users. (Even changes to the hash function may break some programs) Unique object IDs in many languages are another issue -- the JVM apparently uses space for them in the header of every object. So you still may have more compromises about how to implement the WASM string, that produces winners and losers. The only way to know how the compromises pan out is to try, and I'm glad people are doing that. --- So anyway, I'm not very close to WASM, but I do see a pretty clear difference between the proposals. I think it depends on what the goals are -- is "running Python or Scheme with zero-copy JS string interop" a goal? I guess people want to manipulate the DOM directly from Scheme or Python, which seems reasonable. If you have to copy all the strings, that will be a huge drag. DOM operations are already hugely expensive and have tons of objects. It seems like the proposal you linked doesn't address that issue.