Skip to content

Commit 13e63f7

Browse files
committed
Auto merge of #117919 - daxpedda:wasm-c-abi, r=wesleywiser
Introduce perma-unstable `wasm-c-abi` flag Now that `wasm-bindgen` v0.2.88 supports the spec-compliant C ABI, the idea is to switch to that in a future version of Rust. In the meantime it would be good to let people test and play around with it. This PR introduces a new perma-unstable `-Zwasm-c-abi` compiler flag, which switches to the new spec-compliant C ABI when targeting `wasm32-unknown-unknown`. Alternatively, we could also stabilize this and then deprecate it when we switch. I will leave this to the Rust maintainers to decide. This is a companion PR to #117918, but they could be merged independently. MCP: rust-lang/compiler-team#703 Tracking issue: #122532
2 parents fa0068b + 9e2c658 commit 13e63f7

11 files changed

Lines changed: 95 additions & 44 deletions

File tree

‎compiler/rustc_codegen_gcc/src/builder.rs‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ use rustc_span::Span;
3131
use rustc_target::abi::{
3232
self, call::FnAbi,Align,HasDataLayout,Size,TargetDataLayout,WrappingRange,
3333
};
34-
use rustc_target::spec::{HasTargetSpec,Target};
34+
use rustc_target::spec::{HasTargetSpec,HasWasmCAbiOpt,Target,WasmCAbi};
3535

3636
usecrate::common::{type_is_pointer,SignType,TypeReflection};
3737
usecrate::context::CodegenCx;
@@ -2352,6 +2352,12 @@ impl<'tcx> HasTargetSpec for Builder<'_, '_, 'tcx> {
23522352
}
23532353
}
23542354

2355+
impl<'tcx>HasWasmCAbiOptforBuilder<'_,'_,'tcx>{
2356+
fnwasm_c_abi_opt(&self) -> WasmCAbi{
2357+
self.cx.wasm_c_abi_opt()
2358+
}
2359+
}
2360+
23552361
pubtraitToGccComp{
23562362
fnto_gcc_comparison(&self) -> ComparisonOp;
23572363
}

‎compiler/rustc_codegen_gcc/src/context.rs‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use rustc_span::{source_map::respan, Span};
2020
use rustc_target::abi::{
2121
call::FnAbi,HasDataLayout,PointeeInfo,Size,TargetDataLayout,VariantIdx,
2222
};
23-
use rustc_target::spec::{HasTargetSpec,Target,TlsModel};
23+
use rustc_target::spec::{HasTargetSpec,HasWasmCAbiOpt,Target,TlsModel,WasmCAbi};
2424

2525
usecrate::callee::get_fn;
2626
usecrate::common::SignType;
@@ -557,6 +557,12 @@ impl<'gcc, 'tcx> HasTargetSpec for CodegenCx<'gcc, 'tcx> {
557557
}
558558
}
559559

560+
impl<'gcc,'tcx>HasWasmCAbiOptforCodegenCx<'gcc,'tcx>{
561+
fnwasm_c_abi_opt(&self) -> WasmCAbi{
562+
self.tcx.sess.opts.unstable_opts.wasm_c_abi
563+
}
564+
}
565+
560566
impl<'gcc,'tcx>LayoutOfHelpers<'tcx>forCodegenCx<'gcc,'tcx>{
561567
typeLayoutOfResult = TyAndLayout<'tcx>;
562568

‎compiler/rustc_interface/src/tests.rs‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ use rustc_span::edition::{Edition, DEFAULT_EDITION};
1919
use rustc_span::source_map::{RealFileLoader,SourceMapInputs};
2020
use rustc_span::symbol::sym;
2121
use rustc_span::{FileName,SourceFileHashAlgorithm};
22-
use rustc_target::spec::{CodeModel,LinkerFlavorCli,MergeFunctions,PanicStrategy,RelocModel};
22+
use rustc_target::spec::{
23+
CodeModel,LinkerFlavorCli,MergeFunctions,PanicStrategy,RelocModel,WasmCAbi,
24+
};
2325
use rustc_target::spec::{RelroLevel,SanitizerSet,SplitDebuginfo,StackProtector,TlsModel};
2426
use std::collections::{BTreeMap,BTreeSet};
2527
use std::num::NonZero;
@@ -851,6 +853,7 @@ fn test_unstable_options_tracking_hash() {
851853
tracked!(verify_llvm_ir,true);
852854
tracked!(virtual_function_elimination,true);
853855
tracked!(wasi_exec_model,Some(WasiExecModel::Reactor));
856+
tracked!(wasm_c_abi,WasmCAbi::Spec);
854857
// tidy-alphabetical-end
855858

856859
macro_rules! tracked_no_crate_hash {

‎compiler/rustc_middle/src/ty/layout.rs‎

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ use rustc_span::symbol::{sym, Symbol};
1515
use rustc_span::{ErrorGuaranteed,Span,DUMMY_SP};
1616
use rustc_target::abi::call::FnAbi;
1717
use rustc_target::abi::*;
18-
use rustc_target::spec::{abi::AbiasSpecAbi,HasTargetSpec,PanicStrategy,Target};
18+
use rustc_target::spec::{
19+
abi::AbiasSpecAbi,HasTargetSpec,HasWasmCAbiOpt,PanicStrategy,Target,WasmCAbi,
20+
};
1921

2022
use std::borrow::Cow;
2123
use std::cmp;
@@ -483,6 +485,12 @@ impl<'tcx> HasTargetSpec for TyCtxt<'tcx> {
483485
}
484486
}
485487

488+
impl<'tcx>HasWasmCAbiOptforTyCtxt<'tcx>{
489+
fnwasm_c_abi_opt(&self) -> WasmCAbi{
490+
self.sess.opts.unstable_opts.wasm_c_abi
491+
}
492+
}
493+
486494
impl<'tcx>HasTyCtxt<'tcx>forTyCtxt<'tcx>{
487495
#[inline]
488496
fntcx(&self) -> TyCtxt<'tcx>{
@@ -528,6 +536,12 @@ impl<'tcx, T: HasTargetSpec> HasTargetSpec for LayoutCx<'tcx, T> {
528536
}
529537
}
530538

539+
impl<'tcx,T:HasWasmCAbiOpt>HasWasmCAbiOptforLayoutCx<'tcx,T>{
540+
fnwasm_c_abi_opt(&self) -> WasmCAbi{
541+
self.tcx.wasm_c_abi_opt()
542+
}
543+
}
544+
531545
impl<'tcx,T:HasTyCtxt<'tcx>>HasTyCtxt<'tcx>forLayoutCx<'tcx,T>{
532546
fntcx(&self) -> TyCtxt<'tcx>{
533547
self.tcx.tcx()

‎compiler/rustc_session/src/config.rs‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2880,7 +2880,7 @@ pub(crate) mod dep_tracking {
28802880
use rustc_feature::UnstableFeatures;
28812881
use rustc_span::edition::Edition;
28822882
use rustc_span::RealFileName;
2883-
use rustc_target::spec::{CodeModel,MergeFunctions,PanicStrategy,RelocModel};
2883+
use rustc_target::spec::{CodeModel,MergeFunctions,PanicStrategy,RelocModel,WasmCAbi};
28842884
use rustc_target::spec::{
28852885
RelroLevel,SanitizerSet,SplitDebuginfo,StackProtector,TargetTriple,TlsModel,
28862886
};
@@ -2978,6 +2978,7 @@ pub(crate) mod dep_tracking {
29782978
Polonius,
29792979
InliningThreshold,
29802980
FunctionReturn,
2981+
WasmCAbi,
29812982
);
29822983

29832984
impl<T1,T2>DepTrackingHashfor(T1,T2)

‎compiler/rustc_session/src/options.rs‎

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ use rustc_data_structures::profiling::TimePassesFormat;
88
use rustc_data_structures::stable_hasher::Hash64;
99
use rustc_errors::ColorConfig;
1010
use rustc_errors::{LanguageIdentifier,TerminalUrl};
11-
use rustc_target::spec::{CodeModel,LinkerFlavorCli,MergeFunctions,PanicStrategy,SanitizerSet};
11+
use rustc_target::spec::{
12+
CodeModel,LinkerFlavorCli,MergeFunctions,PanicStrategy,SanitizerSet,WasmCAbi,
13+
};
1214
use rustc_target::spec::{
1315
RelocModel,RelroLevel,SplitDebuginfo,StackProtector,TargetTriple,TlsModel,
1416
};
@@ -441,6 +443,7 @@ mod desc {
441443
"either a boolean (`yes`, `no`, `on`, `off`, etc), or a non-negative number";
442444
pubconst parse_llvm_module_flag:&str = "<key>:<type>:<value>:<behavior>. Type must currently be `u32`. Behavior should be one of (`error`, `warning`, `require`, `override`, `append`, `appendunique`, `max`, `min`)";
443445
pubconst parse_function_return:&str = "`keep` or `thunk-extern`";
446+
pubconst parse_wasm_c_abi:&str = "`legacy` or `spec`";
444447
}
445448

446449
mod parse {
@@ -1433,6 +1436,15 @@ mod parse {
14331436
}
14341437
true
14351438
}
1439+
1440+
pub(crate)fnparse_wasm_c_abi(slot:&mutWasmCAbi,v:Option<&str>) -> bool{
1441+
match v {
1442+
Some("spec") => *slot = WasmCAbi::Spec,
1443+
Some("legacy") => *slot = WasmCAbi::Legacy,
1444+
_ => returnfalse,
1445+
}
1446+
true
1447+
}
14361448
}
14371449

14381450
options!{
@@ -2061,6 +2073,8 @@ written to standard error output)"),
20612073
Requires `-Clto[=[fat,yes]]`"),
20622074
wasi_exec_model:Option<WasiExecModel> = (None, parse_wasi_exec_model,[TRACKED],
20632075
"whether to build a wasi command or reactor"),
2076+
wasm_c_abi:WasmCAbi = (WasmCAbi::Legacy, parse_wasm_c_abi,[TRACKED],
2077+
"use spec-compliant C ABI for `wasm32-unknown-unknown` (default: legacy)"),
20642078
write_long_types_to_disk:bool = (true, parse_bool,[UNTRACKED],
20652079
"whether long type names should be written to files instead of being printed in errors"),
20662080
// tidy-alphabetical-end

‎compiler/rustc_target/src/abi/call/mod.rs‎

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
usecrate::abi::{self,Abi,Align,FieldsShape,Size};
22
usecrate::abi::{HasDataLayout,TyAbiInterface,TyAndLayout};
3-
usecrate::spec::{self,HasTargetSpec};
3+
usecrate::spec::{self,HasTargetSpec,HasWasmCAbiOpt};
44
use rustc_span::Symbol;
55
use std::fmt;
66
use std::str::FromStr;
@@ -829,7 +829,7 @@ impl<'a, Ty> FnAbi<'a, Ty> {
829829
) -> Result<(),AdjustForForeignAbiError>
830830
where
831831
Ty:TyAbiInterface<'a,C> + Copy,
832-
C:HasDataLayout + HasTargetSpec,
832+
C:HasDataLayout + HasTargetSpec + HasWasmCAbiOpt,
833833
{
834834
if abi == spec::abi::Abi::X86Interrupt{
835835
ifletSome(arg) = self.args.first_mut(){
@@ -886,7 +886,9 @@ impl<'a, Ty> FnAbi<'a, Ty> {
886886
"sparc" => sparc::compute_abi_info(cx,self),
887887
"sparc64" => sparc64::compute_abi_info(cx,self),
888888
"nvptx64" => {
889-
if cx.target_spec().adjust_abi(abi,self.c_variadic) == spec::abi::Abi::PtxKernel{
889+
if cx.target_spec().adjust_abi(cx, abi,self.c_variadic)
890+
== spec::abi::Abi::PtxKernel
891+
{
890892
nvptx64::compute_ptx_kernel_abi_info(cx,self)
891893
}else{
892894
nvptx64::compute_abi_info(self)
@@ -895,7 +897,7 @@ impl<'a, Ty> FnAbi<'a, Ty> {
895897
"hexagon" => hexagon::compute_abi_info(self),
896898
"riscv32" | "riscv64" => riscv::compute_abi_info(cx,self),
897899
"wasm32" | "wasm64" => {
898-
if cx.target_spec().adjust_abi(abi,self.c_variadic) == spec::abi::Abi::Wasm{
900+
if cx.target_spec().adjust_abi(cx,abi,self.c_variadic) == spec::abi::Abi::Wasm{
899901
wasm::compute_wasm_abi_info(self)
900902
}else{
901903
wasm::compute_c_abi_info(cx,self)

‎compiler/rustc_target/src/spec/mod.rs‎

Lines changed: 28 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
usecrate::abi::call::Conv;
3838
usecrate::abi::{Endian,Integer,Size,TargetDataLayout,TargetDataLayoutErrors};
3939
usecrate::json::{Json,ToJson};
40-
usecrate::spec::abi::{lookup as lookup_abi,Abi};
40+
usecrate::spec::abi::Abi;
4141
usecrate::spec::crt_objects::CrtObjects;
4242
use rustc_fs_util::try_canonicalize;
4343
use rustc_serialize::{Decodable,Decoder,Encodable,Encoder};
@@ -1915,6 +1915,19 @@ impl HasTargetSpec for Target {
19151915
}
19161916
}
19171917

1918+
/// Which C ABI to use for `wasm32-unknown-unknown`.
1919+
#[derive(Debug,Copy,Clone,Hash,PartialEq,Eq)]
1920+
pubenumWasmCAbi{
1921+
/// Spec-compliant C ABI.
1922+
Spec,
1923+
/// Legacy ABI. Which is non-spec-compliant.
1924+
Legacy,
1925+
}
1926+
1927+
pubtraitHasWasmCAbiOpt{
1928+
fnwasm_c_abi_opt(&self) -> WasmCAbi;
1929+
}
1930+
19181931
typeStaticCow<T> = Cow<'static,T>;
19191932

19201933
/// Optional aspects of a target specification.
@@ -2273,9 +2286,6 @@ pub struct TargetOptions {
22732286
/// distributed with the target, the sanitizer should still appear in this list for the target.
22742287
pubsupported_sanitizers:SanitizerSet,
22752288

2276-
/// If present it's a default value to use for adjusting the C ABI.
2277-
pubdefault_adjusted_cabi:Option<Abi>,
2278-
22792289
/// Minimum number of bits in #[repr(C)] enum. Defaults to the size of c_int
22802290
pubc_enum_min_bits:Option<u64>,
22812291

@@ -2507,7 +2517,6 @@ impl Default for TargetOptions {
25072517
// `Off` is supported by default, but targets can remove this manually, e.g. Windows.
25082518
supported_split_debuginfo:Cow::Borrowed(&[SplitDebuginfo::Off]),
25092519
supported_sanitizers:SanitizerSet::empty(),
2510-
default_adjusted_cabi:None,
25112520
c_enum_min_bits:None,
25122521
generate_arange_section:true,
25132522
supports_stack_protector:true,
@@ -2538,9 +2547,21 @@ impl DerefMut for Target {
25382547

25392548
implTarget{
25402549
/// Given a function ABI, turn it into the correct ABI for this target.
2541-
pubfnadjust_abi(&self,abi:Abi,c_variadic:bool) -> Abi{
2550+
pubfnadjust_abi<C>(&self,cx:&C,abi:Abi,c_variadic:bool) -> Abi
2551+
where
2552+
C:HasWasmCAbiOpt,
2553+
{
25422554
match abi {
2543-
Abi::C{ .. } => self.default_adjusted_cabi.unwrap_or(abi),
2555+
Abi::C{ .. } => {
2556+
ifself.arch == "wasm32"
2557+
&& self.os == "unknown"
2558+
&& cx.wasm_c_abi_opt() == WasmCAbi::Legacy
2559+
{
2560+
Abi::Wasm
2561+
}else{
2562+
abi
2563+
}
2564+
}
25442565

25452566
// On Windows, `extern "system"` behaves like msvc's `__stdcall`.
25462567
// `__stdcall` only applies on x86 and on non-variadic functions:
@@ -3079,16 +3100,6 @@ impl Target {
30793100
}
30803101
}
30813102
});
3082-
($key_name:ident,Option<Abi>) => ({
3083-
let name = (stringify!($key_name)).replace("_","-");
3084-
obj.remove(&name).and_then(|o| o.as_str().and_then(|s| {
3085-
match lookup_abi(s){
3086-
Ok(abi) => base.$key_name = Some(abi),
3087-
_ => returnSome(Err(format!("'{}' is not a valid value for abi", s))),
3088-
}
3089-
Some(Ok(()))
3090-
})).unwrap_or(Ok(()))
3091-
});
30923103
($key_name:ident,TargetFamilies) => ({
30933104
ifletSome(value) = obj.remove("target-family"){
30943105
ifletSome(v) = value.as_array(){
@@ -3238,7 +3249,6 @@ impl Target {
32383249
key!(split_debuginfo,SplitDebuginfo)?;
32393250
key!(supported_split_debuginfo, fallible_list)?;
32403251
key!(supported_sanitizers,SanitizerSet)?;
3241-
key!(default_adjusted_cabi,Option<Abi>)?;
32423252
key!(generate_arange_section,bool);
32433253
key!(supports_stack_protector,bool);
32443254
key!(entry_name);
@@ -3502,10 +3512,6 @@ impl ToJson for Target {
35023512
target_option_val!(entry_abi);
35033513
target_option_val!(supports_xray);
35043514

3505-
ifletSome(abi) = self.default_adjusted_cabi{
3506-
d.insert("default-adjusted-cabi".into(),Abi::name(abi).to_json());
3507-
}
3508-
35093515
// Serializing `-Clink-self-contained` needs a dynamic key to support the
35103516
// backwards-compatible variants.
35113517
d.insert(self.link_self_contained.json_key().into(),self.link_self_contained.to_json());

‎compiler/rustc_target/src/spec/targets/wasm32_unknown_unknown.rs‎

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,23 +10,12 @@
1010
//! This target is more or less managed by the Rust and WebAssembly Working
1111
//! Group nowadays at <https://github.com/rustwasm>.
1212
13-
usecrate::spec::abi::Abi;
1413
usecrate::spec::{base,Cc,LinkerFlavor,Target};
1514

1615
pubfntarget() -> Target{
1716
letmut options = base::wasm::options();
1817
options.os = "unknown".into();
1918

20-
// This is a default for backwards-compatibility with the original
21-
// definition of this target oh-so-long-ago. Once the "wasm" ABI is
22-
// stable and the wasm-bindgen project has switched to using it then there's
23-
// no need for this and it can be removed.
24-
//
25-
// Currently this is the reason that this target's ABI is mismatched with
26-
// clang's ABI. This means that, in the limit, you can't merge C and Rust
27-
// code on this target due to this ABI mismatch.
28-
options.default_adjusted_cabi = Some(Abi::Wasm);
29-
3019
options.add_pre_link_args(
3120
LinkerFlavor::WasmLld(Cc::No),
3221
&[

‎compiler/rustc_ty_utils/src/abi.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ fn fn_sig_for_fn_abi<'tcx>(
322322
#[inline]
323323
fnconv_from_spec_abi(tcx:TyCtxt<'_>,abi:SpecAbi,c_variadic:bool) -> Conv{
324324
use rustc_target::spec::abi::Abi::*;
325-
match tcx.sess.target.adjust_abi(abi, c_variadic){
325+
match tcx.sess.target.adjust_abi(&tcx,abi, c_variadic){
326326
RustIntrinsic | Rust | RustCall => Conv::Rust,
327327

328328
// This is intentionally not using `Conv::Cold`, as that has to preserve

0 commit comments

Comments
 (0)