-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Fix abi for wasm-bindgen #81388
Fix abi for wasm-bindgen #81388
Conversation
I don't really understand #80594 or why it would break wasm. Similarly I don't understand the code this is modifying in this PR at this moment to fix the issue. I would expect that this issue would get fixed in this file https://github.com/rust-lang/rust/blob/master/compiler/rustc_target/src/abi/call/wasm32_bindgen_compat.rs, however. |
Previously |
Sorry a short explanation won't really help me review this, to review this PR as-is I would have to dive in myself to understand things, which I don't have time to do right now. There is already one specific location, however, which selects the wasm ABI: rust/compiler/rustc_target/src/abi/call/mod.rs Lines 634 to 637 in 7fba12b
I don't think we should have two different checks for the ABI, and even less so two different checks. I hope that in the long-term the previous ABI (e.g. that on the stable/beta channel) will be the final ABI for wasm, in which case I don't think there should be a "if wasm do this" check in the middle of otherwise platform-independent code. |
That would make it impossible to link against C code, which uses the official wasm C abi instead of the wasm-bindgen compat abi.
There are already several target checks in the platform-independent code. For example some targets don't ignore ZST arguments, which the platform-independent code normally sets to ignore. (and it must always ignore them for the rust abi to make closure to fn-ptr casts work.) |
I'm thinking more broadly than what's the case right-this-red-hot-second. I would hope that Clang changes ABI as well. Again, I can't review changes to this code as-is. One comment I would have, however, is that this is a different check that the one already existing in the codebase. Those two checks should probably not be different nor entirely isolated from one another. |
The job Click to see the possible cause of the failure (guessed by this bot)
|
0d1a319
to
e7a056f
Compare
I expect that the wasm-bindgen abi is slower due to making it impossible to construct large arguments in place and passing a pointer rather than requiring the wasm compiler to copy them to the arguments location. In addition as noted in #81386 (comment) the abi is actually much more complex than it seems. LLVM does a lot of adjustments behind the back, including one for which I can't think of a clear rule as evidenced by the example there where a struct containing an i8 wrapped inside a struct and two standalone i32 turn into 6! i32 arguments at the abi level. I wouldn't expect more than three arguments. |
The job Click to see the possible cause of the failure (guessed by this bot)
|
I think I figured the abi out. There are 3 i8's used as padding in this case. These get promoted to i32. #[repr(C)]
pub struct Bar {
pub foo: u8,
}
#[repr(C)]
pub struct Foo {
pub a: Bar,
pub b: u32,
pub c: u32,
}
#[no_mangle]
pub extern "C" fn foo(a: Foo) {} %Foo = type { [0 x i8], %Bar, [3 x i8], i32, [0 x i32], i32, [0 x i32] }
%Bar = type { [0 x i8], i8, [0 x i8] }
; Function Attrs: norecurse nounwind readnone
define void @foo(%Foo %0) unnamed_addr #0 {
start:
ret void
} I think the rule is that it will flatten nested structs and extend any i8 used as padding to i32. I don't think |
I pushed a new version that doesn't change the abi independent part. It should have the same ABI for all structs without padding. As far as I could see wasm-bindgen doesn't ever use any types with padding, nor could I find any code to handle padding, so this should be compatible with wasm-bindgen. |
This reverts commit 903c553.
The more I think about it the less I am certain that defaulting |
This comment has been minimized.
This comment has been minimized.
9a3cec1
to
a8da209
Compare
a8da209
to
c1c06f3
Compare
This is unfortunately well beyond my ability to review at this point. |
@bors r+ p=1 |
📌 Commit c1c06f3 has been approved by |
☀️ Test successful - checks-actions |
Ensure sanity of all computed ABIs This moves the ABI sanity assertions from the codegen backend to the ABI computation logic. Sadly, due to past mistakes, we [have to](rust-lang#117351 (comment)) be able to compute a sane ABI for nonsensical function types like `extern "C" fn(str) -> str`. So to make the sanity check pass we first need to make all ABI adjustment deal with unsized types... and we have no shared infrastructure for those adjustments, so that's a bunch of copy-paste. At least we have assertions failing loudly when one accidentally sets a different mode for an unsized argument. To achieve this, this re-lands the parts of rust-lang#80594 that got reverted in rust-lang#81388. To avoid breaking wasm ABI again, that ABI now explicitly opts-in to the (wrong, broken) ABI that we currently keep for backwards compatibility. That's still better than having *every* ABI use the wrong broken default! Cc `@bjorn3` Fixes rust-lang#115845
Ensure sanity of all computed ABIs This moves the ABI sanity assertions from the codegen backend to the ABI computation logic. Sadly, due to past mistakes, we [have to](rust-lang#117351 (comment)) be able to compute a sane ABI for nonsensical function types like `extern "C" fn(str) -> str`. So to make the sanity check pass we first need to make all ABI adjustment deal with unsized types... and we have no shared infrastructure for those adjustments, so that's a bunch of copy-paste. At least we have assertions failing loudly when one accidentally sets a different mode for an unsized argument. To achieve this, this re-lands the parts of rust-lang#80594 that got reverted in rust-lang#81388. To avoid breaking wasm ABI again, that ABI now explicitly opts-in to the (wrong, broken) ABI that we currently keep for backwards compatibility. That's still better than having *every* ABI use the wrong broken default! Cc `@bjorn3` Fixes rust-lang#115845
Ensure sanity of all computed ABIs This moves the ABI sanity assertions from the codegen backend to the ABI computation logic. Sadly, due to past mistakes, we [have to](rust-lang#117351 (comment)) be able to compute a sane ABI for nonsensical function types like `extern "C" fn(str) -> str`. So to make the sanity check pass we first need to make all ABI adjustment deal with unsized types... and we have no shared infrastructure for those adjustments, so that's a bunch of copy-paste. At least we have assertions failing loudly when one accidentally sets a different mode for an unsized argument. To achieve this, this re-lands the parts of rust-lang#80594 that got reverted in rust-lang#81388. To avoid breaking wasm ABI again, that ABI now explicitly opts-in to the (wrong, broken) ABI that we currently keep for backwards compatibility. That's still better than having *every* ABI use the wrong broken default! Cc `@bjorn3` Fixes rust-lang#115845
Ensure sanity of all computed ABIs This moves the ABI sanity assertions from the codegen backend to the ABI computation logic. Sadly, due to past mistakes, we [have to](rust-lang/rust#117351 (comment)) be able to compute a sane ABI for nonsensical function types like `extern "C" fn(str) -> str`. So to make the sanity check pass we first need to make all ABI adjustment deal with unsized types... and we have no shared infrastructure for those adjustments, so that's a bunch of copy-paste. At least we have assertions failing loudly when one accidentally sets a different mode for an unsized argument. To achieve this, this re-lands the parts of rust-lang/rust#80594 that got reverted in rust-lang/rust#81388. To avoid breaking wasm ABI again, that ABI now explicitly opts-in to the (wrong, broken) ABI that we currently keep for backwards compatibility. That's still better than having *every* ABI use the wrong broken default! Cc `@bjorn3` Fixes rust-lang/rust#115845
Ensure sanity of all computed ABIs This moves the ABI sanity assertions from the codegen backend to the ABI computation logic. Sadly, due to past mistakes, we [have to](rust-lang/rust#117351 (comment)) be able to compute a sane ABI for nonsensical function types like `extern "C" fn(str) -> str`. So to make the sanity check pass we first need to make all ABI adjustment deal with unsized types... and we have no shared infrastructure for those adjustments, so that's a bunch of copy-paste. At least we have assertions failing loudly when one accidentally sets a different mode for an unsized argument. To achieve this, this re-lands the parts of rust-lang/rust#80594 that got reverted in rust-lang/rust#81388. To avoid breaking wasm ABI again, that ABI now explicitly opts-in to the (wrong, broken) ABI that we currently keep for backwards compatibility. That's still better than having *every* ABI use the wrong broken default! Cc `@bjorn3` Fixes rust-lang/rust#115845
Ensure sanity of all computed ABIs This moves the ABI sanity assertions from the codegen backend to the ABI computation logic. Sadly, due to past mistakes, we [have to](rust-lang/rust#117351 (comment)) be able to compute a sane ABI for nonsensical function types like `extern "C" fn(str) -> str`. So to make the sanity check pass we first need to make all ABI adjustment deal with unsized types... and we have no shared infrastructure for those adjustments, so that's a bunch of copy-paste. At least we have assertions failing loudly when one accidentally sets a different mode for an unsized argument. To achieve this, this re-lands the parts of rust-lang/rust#80594 that got reverted in rust-lang/rust#81388. To avoid breaking wasm ABI again, that ABI now explicitly opts-in to the (wrong, broken) ABI that we currently keep for backwards compatibility. That's still better than having *every* ABI use the wrong broken default! Cc `@bjorn3` Fixes rust-lang/rust#115845
Hopefully fixes #81386. @alexcrichton can you confirm this fixes wasm-bindgen?
r? @alexcrichton