rustc assumes that regular `extern "Rust"` functions unwind only if the
`unwind` panic runtime is linked. `throw` was annotated as such, but
unwound unconditionally. This could cause UB when a crate built with `-C
panic=abort` called `throw` from `core` built with `-C panic=unwind`,
since no terminator was added to handle the panic arising from calling an
allegedly non-unwinding `extern "Rust"` function.
rustc was taught to recognize this condition since
https://github.com/rust-lang/rust/pull/144225 and prevented such
linkage, but this caused regressions in
https://github.com/rust-lang/rust/issues/148246, since this meant that
Emscripten projects could not be built with `-C panic=abort` without
recompiling std.
The most straightforward solution would be to move `throw` into the
`panic_unwind` crate, so that it's only compiled if the panic runtime is
guaranteed to be `unwind`, but this is messy due to our architecture.
Instead, move it into `unwind::wasm`, which is only compiled for
bare-metal targets that default to `panic = "abort"`, rendering the
issue moot.
This instruction is only available when the jsconv target_feature is available,
so on ARMv8.3 or higher.
It is used e.g. by Ruffle[0] to speed up its conversion from f64 to i32, or by
any JS engine probably.
I’ve picked the stdarch_aarch64_jscvt feature because it’s the name of the
FEAT_JSCVT, but hesitated with naming it stdarch_aarch64_jsconv (the name of
the target_feature) or stdarch_aarch64_jcvt (the name of the C intrinsic) or
stdarch_aarch64_fjcvtzs (the name of the instruction), this choice is purely
arbitrary and I guess it could be argued one way or another. I wouldn’t expect
it to stay unstable for too long, so ultimately this shouldn’t matter much.
This feature is now tracked in this issue[1].
[0] https://github.com/ruffle-rs/ruffle/pull/21780
[1] https://github.com/rust-lang/rust/issues/147555
They are defined in the aarch64 module, so this cfg is pointless.
Note that these instructions do exist for arm, but the aarch64 ones are
already stable, so this would need some additional work to implement
them for arm.
While many intrinsics use `.insn` to generate raw machine code from
numbers, all ratified instructions can be symbolic
using `.option` directives.
By saving the assembler environment with `.option push` then modifying
the architecture with `.option arch`, we can temporarily enable certain
extensions (as we use `.option pop` immediately after the target
instruction, surrounding environment is completely intact in this
commit; *almost* completely intact in general).
This commit modifies the `pause` *hint* intrinsic to use symbolic
*instruction* because we want to expose it even if the Zihintpause
extension is unavailable on the target.