-
Notifications
You must be signed in to change notification settings - Fork 73
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Requirements for JS Interop #235
Comments
My thoughts:
Nice to have:
Open questions:
Quick comments on @RossTate 's sketch: |
Thanks for the great thoughts! I'll respond to your comments, since one's a question, and the other shows that I need to clarify something:
My understanding is that
Sorry, it seems I used the wrong term. By shape I was meaning something more like hidden class, i.e. the description of how field and method accesses work for the given object, rather than the memory layout of the object. My understanding is that, for JS interop in a multithreaded setting (with shareable wasm references), it will be important that shareable JS values have fixed hidden classes so that critical engine optimizations cannot be broken by other threads, and consequently shareable wasm references will need to have fixed hidden classes as well. One comment on @jakobkummerow's thoughts as it pulls out an assumption I was making and should make explicit:
I would expect hiding a field to have no performance or memory cost: you're simply not giving it a name in JS, and so it's not accessible in JS. Also, I expect any ergonomic interop will have two views for any of these coercible reference types: the wasm view (which is very low level, e.g. field offsets and such), and the JS view (which has named fields and methods and such). If we don't do this, then I suspect the two-views thing will likely happen anyways because people will build JS proxies for wasm refs on the JS side in order to get ergonomic interop (with much less efficiency). So, admittedly, I'm implicitly assuming that a good JS-interop story will have some sort of two-views story to it, though that's my assumption and not necessarily others'. |
I'm quite interested in the JS API for the GC proposal as well, and broadly agree with a lot of what's been said here. I agree that it would be great to be able to manipulate GC objects in an ergonomic way with names from JS, so that mixed JS and source-language programs work well. And of course that casting in interop works in both directions, ideally.
Just to clarify this point, is this essentially saying if you export Wasm GC objects in the Wasm→JS direction it should be possible and cheap? That would make sense to me. Re: nominal types and the JS API, since there's now some discussion of prototyping a minimal addition of nominal types in parallel with trying structural types, I think it'd be interesting to consider how the JS API should look in that case. In particular, would it be a requirement that the API provide the same abilities no matter which types you use or not? I could imagine that you get different API features depending on your types. For example, it could be the case that you can get automatic downcasts if you use the nominally typed subset (like Jakob noted above), and have to do more work to get interop if you use structural types. |
Thanks for the thoughts, @takikawa!
Yes, though let me refine that. For "possible", I wouldn't necessarily require all wasm GC objects to cross into JS. I think it would be fine if wasm GC objects had to be explicitly marked/allocated in some fashion in order to cross into JS. For example, there are lots of GC objects that just implement machinery of the language runtime and really have no need to go into JS. (That said, I'm not opposed to having all wasm GC objects be coercible—just noting where I see some flexibility.) For "cheap", based on what we've seen in the gradual-typing language-interop space, my recommendation would be that coercions (in either direction) should not require memory allocation for the typical case. In particular, my recommendation would be to avoid approaches requiring allocating proxies for ergonomic interop (though, of course, modules wanting a proxy-based interop semantics should be able to implement proxies themselves using the lower-level wasm and JS-interop primitives, thereby opting into the associated costs without imposing such costs upon others). |
To be able to compile Scala.js to Wasm+GC, in addition to the capabilities laid out in the first message, we would need the following capabilities:
Together with named methods, named properties are necessary to implement member exports of Scala.js. We can annotate methods and properties of Scala classes with The error objects is necessary for us to define the |
Ah, those both make sense, and I suspect they're also useful for other languages already discussed but got overlooked. Thanks! |
For This approach requires that as part of the WasmGC/JS interop, it is specified that Wasm objects can be used as keys in the JS |
Interesting use case. More generally, it seems like JS interop should respect object identity. Thanks! |
Similarly, Dart will also need the capability to register WasmGC objects (structs in particular) in a JS |
We have consensus on a "no-frills" JS interop approach for the MVP (#279), so closing this. Feel free to make PRs adding ideas for richer JS interop to the post-MVP doc. |
@littledan brought up the issue of JS Interop during today's meeting. I did find this conversation in the PR for the tentative Requirements document, but in that conversation it's suggested that we flesh this out more. So I'm starting this thread to do so. To get things started, here are some concrete requirements that I believe the MVP should provide (or at least have a thought-out plan for) based on what people compiling to JS already get and on what JS is looking to add (and on what I know is possible).
externref
), with the performance expectation that these coercions (or subtypings) are no-ops (or at least very cheap).externref
(or the like?) values to its own reference types (with restrictions, such as using the right rtt)externref
, my references are a black box to everyone else except for the explicit decorations I gave it)As I said, those are what I believe we should provide, as they are what I would expect if I were compiling to JS. I'm interested to hear what others believe. After hearing various thoughts, maybe we can develop a variant of #121 for specifically JS interop.
The text was updated successfully, but these errors were encountered: