-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Make wasm-bindgen
compatible with the standard C ABI
#3595
Conversation
For some reason a couple of functions got switched around; no actual meaningful changes.
I've given it a quick glance, really nice solution! I imagined this to be way messier, but it's pretty neat! Even though this only touched unstable ABI would you mind adding an entry in the changelog? Thinking of deployment here, we could expose an unstable |
Done. I've also just realised that I forgot to add a changelog entry in #3554, should I open a PR to add one? (edit: opened #3599)
I'm not sure what you mean. The new generated bindings still work fine with the existing C ABI, the whole point is that they now work with both that and the standard one. So there's no need for this to be unstable. I'm now realising that I've been using the word 'ABI' to mean two different things interchangeably: actual Rust ABIs like |
I mean specifically to switch to the new ABI, that doesn't work until Rust fixes it's C ABI, right? |
I've been assuming that Rust will just directly cut over to the fixed ABI, so that all of Are you suggesting that there should be some kind of testing period, where there's a perma-nightly |
I was assuming that this would be the case, but I'm not advocating for it. If we can skip it and move directly to the fixed C ABI I'm fine with that, but that's not up to us. In any case, there's nothing for us to do here right now until we know what will happen on Rusts side. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
Co-authored-by: daxpedda <daxpedda@gmail.com>
This is the first step of #3454: making
wasm-bindgen
compatible with the standard(ish) Wasm C ABI, whichclang
uses.This PR more or less implements @alexcrichton's suggestion in #3454 (comment), to allow
{From,Into}WasmAbi
impls to manually specify multiple types thatSelf
should get splatted into when passed as an argument. I implemented it a bit differently though - instead of actually adding multiple associated types to{From,Into}WasmAbi
, I changed the meaning ofWasmAbi
:This means that
{From,Into}WasmAbi
impls can still return single, typed values like before, and then it's up to those types to implementWasmAbi
and specify how they should be splatted. Also,WasmAbi
types no longer actually have to be FFI-safe themselves - even when they're passed as return values,split
is still called, and those values are then put into a#[repr(C)]
struct (WasmRet<T>
).The new trait
WasmPrimitive
now has the old meaning ofWasmAbi
, minus allowing#[repr(C)]
types - any Wasm primitive type.This PR doesn't actually change
wasm-bindgen
's ABI at all, just how it's implemented. This meant that I didn't have to touch the CLI.One thing that this PR doesn't fix is #3552.
extern "C"
functions still return#[repr(C)]
structs the same as before, since the retptr handling happens to be the same between the current and standard C ABI. That is, unless you turn on multivalue, in which case the return value will get splatted with the current ABI. (I'm referring torustc
'smultivalue
target feature here, notwasm-bindgen
's own multivalue post processing step.)It's not a blocker for migrating the ABI, since
wasm-bindgen
's already broken when multivalue is enabled, but it's still be nice to fix it.I'm not sure how it could be fixed without always using a retptr though, which I'd rather avoid. I've experimented a little with type system shenanigans like this:
There'd be one impl where
Retptr
andRet
get set to()
andSelf::Prim1
respectively, ifSelf
's last 3 primitives are all()
, and another one whereRetptr
andRet
get set to*mut WasmRet<Self>
and()
respectively, ifSelf::Prim2
(and potentiallyPrim3
,Prim4
) isn't()
. Then a generated importfoo() -> T
would look something like this:Unfortunately, I couldn't convince
rustc
thatPrim2
not being()
meant that those two impls didn't conflict. Maybe someone who's more of a type system guru than me can figure it out, but it might be impossible without specialisation. It'll become unnecessary if/when the C ABI gets fixed anyway.