Skip to content

Commit 7955e07

Browse files
committed
Introduce perma-unstable wasm-c-abi flag
1 parent a1c65db commit 7955e07

File tree

10 files changed

+92
-13
lines changed

10 files changed

+92
-13
lines changed

compiler/rustc_codegen_gcc/src/builder.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ use rustc_target::abi::{
4848
TargetDataLayout,
4949
WrappingRange,
5050
};
51-
use rustc_target::spec::{HasTargetSpec, Target};
51+
use rustc_target::spec::{HasTargetSpec, HasWasmCAbiOpt, Target, WasmCAbi};
5252

5353
use crate::common::{SignType, TypeReflection, type_is_pointer};
5454
use crate::context::CodegenCx;
@@ -1952,6 +1952,12 @@ impl<'tcx> HasTargetSpec for Builder<'_, '_, 'tcx> {
19521952
}
19531953
}
19541954

1955+
impl<'tcx> HasWasmCAbiOpt for Builder<'_, '_, 'tcx> {
1956+
fn wasm_c_abi_opt(&self) -> WasmCAbi {
1957+
self.cx.wasm_c_abi_opt()
1958+
}
1959+
}
1960+
19551961
pub trait ToGccComp {
19561962
fn to_gcc_comparison(&self) -> ComparisonOp;
19571963
}

compiler/rustc_codegen_gcc/src/context.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use rustc_middle::ty::layout::{FnAbiError, FnAbiOf, FnAbiOfHelpers, FnAbiRequest
1717
use rustc_session::Session;
1818
use rustc_span::{Span, source_map::respan};
1919
use rustc_target::abi::{call::FnAbi, HasDataLayout, PointeeInfo, Size, TargetDataLayout, VariantIdx};
20-
use rustc_target::spec::{HasTargetSpec, Target, TlsModel};
20+
use rustc_target::spec::{HasTargetSpec, HasWasmCAbiOpt, Target, TlsModel, WasmCAbi};
2121

2222
use crate::callee::get_fn;
2323
use crate::common::SignType;
@@ -500,6 +500,12 @@ impl<'gcc, 'tcx> HasTargetSpec for CodegenCx<'gcc, 'tcx> {
500500
}
501501
}
502502

503+
impl<'gcc, 'tcx> HasWasmCAbiOpt for CodegenCx<'gcc, 'tcx> {
504+
fn wasm_c_abi_opt(&self) -> WasmCAbi {
505+
self.tcx.sess.opts.unstable_opts.wasm_c_abi
506+
}
507+
}
508+
503509
impl<'gcc, 'tcx> LayoutOfHelpers<'tcx> for CodegenCx<'gcc, 'tcx> {
504510
type LayoutOfResult = TyAndLayout<'tcx>;
505511

compiler/rustc_interface/src/tests.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ use rustc_session::{build_session, getopts, CompilerIO, EarlyErrorHandler, Sessi
1818
use rustc_span::edition::{Edition, DEFAULT_EDITION};
1919
use rustc_span::symbol::sym;
2020
use rustc_span::{FileName, SourceFileHashAlgorithm};
21-
use rustc_target::spec::{CodeModel, LinkerFlavorCli, MergeFunctions, PanicStrategy, RelocModel};
21+
use rustc_target::spec::{
22+
CodeModel, LinkerFlavorCli, MergeFunctions, PanicStrategy, RelocModel, WasmCAbi,
23+
};
2224
use rustc_target::spec::{RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, TlsModel};
2325
use std::collections::{BTreeMap, BTreeSet};
2426
use std::num::NonZeroUsize;
@@ -834,6 +836,7 @@ fn test_unstable_options_tracking_hash() {
834836
tracked!(verify_llvm_ir, true);
835837
tracked!(virtual_function_elimination, true);
836838
tracked!(wasi_exec_model, Some(WasiExecModel::Reactor));
839+
tracked!(wasm_c_abi, WasmCAbi::Spec);
837840
// tidy-alphabetical-end
838841

839842
macro_rules! tracked_no_crate_hash {

compiler/rustc_middle/src/ty/layout.rs

+15-1
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::Abi as SpecAbi, HasTargetSpec, PanicStrategy, Target};
18+
use rustc_target::spec::{
19+
abi::Abi as SpecAbi, HasTargetSpec, HasWasmCAbiOpt, PanicStrategy, Target, WasmCAbi,
20+
};
1921

2022
use std::cmp;
2123
use std::fmt;
@@ -552,6 +554,12 @@ impl<'tcx> HasTargetSpec for TyCtxt<'tcx> {
552554
}
553555
}
554556

557+
impl<'tcx> HasWasmCAbiOpt for TyCtxt<'tcx> {
558+
fn wasm_c_abi_opt(&self) -> WasmCAbi {
559+
self.sess.opts.unstable_opts.wasm_c_abi
560+
}
561+
}
562+
555563
impl<'tcx> HasTyCtxt<'tcx> for TyCtxt<'tcx> {
556564
#[inline]
557565
fn tcx(&self) -> TyCtxt<'tcx> {
@@ -597,6 +605,12 @@ impl<'tcx, T: HasTargetSpec> HasTargetSpec for LayoutCx<'tcx, T> {
597605
}
598606
}
599607

608+
impl<'tcx, T: HasWasmCAbiOpt> HasWasmCAbiOpt for LayoutCx<'tcx, T> {
609+
fn wasm_c_abi_opt(&self) -> WasmCAbi {
610+
self.tcx.wasm_c_abi_opt()
611+
}
612+
}
613+
600614
impl<'tcx, T: HasTyCtxt<'tcx>> HasTyCtxt<'tcx> for LayoutCx<'tcx, T> {
601615
fn tcx(&self) -> TyCtxt<'tcx> {
602616
self.tcx.tcx()

compiler/rustc_session/src/config.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -3183,7 +3183,7 @@ pub(crate) mod dep_tracking {
31833183
use rustc_feature::UnstableFeatures;
31843184
use rustc_span::edition::Edition;
31853185
use rustc_span::RealFileName;
3186-
use rustc_target::spec::{CodeModel, MergeFunctions, PanicStrategy, RelocModel};
3186+
use rustc_target::spec::{CodeModel, MergeFunctions, PanicStrategy, RelocModel, WasmCAbi};
31873187
use rustc_target::spec::{
31883188
RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, TargetTriple, TlsModel,
31893189
};
@@ -3280,6 +3280,7 @@ pub(crate) mod dep_tracking {
32803280
Polonius,
32813281
InliningThreshold,
32823282
FunctionReturn,
3283+
WasmCAbi,
32833284
);
32843285

32853286
impl<T1, T2> DepTrackingHash for (T1, T2)

compiler/rustc_session/src/options.rs

+15-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ use rustc_data_structures::profiling::TimePassesFormat;
77
use rustc_data_structures::stable_hasher::Hash64;
88
use rustc_errors::ColorConfig;
99
use rustc_errors::{LanguageIdentifier, TerminalUrl};
10-
use rustc_target::spec::{CodeModel, LinkerFlavorCli, MergeFunctions, PanicStrategy, SanitizerSet};
10+
use rustc_target::spec::{
11+
CodeModel, LinkerFlavorCli, MergeFunctions, PanicStrategy, SanitizerSet, WasmCAbi,
12+
};
1113
use rustc_target::spec::{
1214
RelocModel, RelroLevel, SplitDebuginfo, StackProtector, TargetTriple, TlsModel,
1315
};
@@ -431,6 +433,7 @@ mod desc {
431433
"either a boolean (`yes`, `no`, `on`, `off`, etc), or a non-negative number";
432434
pub const 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`)";
433435
pub const parse_function_return: &str = "`keep` or `thunk-extern`";
436+
pub const parse_wasm_c_abi: &str = "`legacy` or `spec`";
434437
}
435438

436439
mod parse {
@@ -1369,6 +1372,15 @@ mod parse {
13691372
}
13701373
true
13711374
}
1375+
1376+
pub(crate) fn parse_wasm_c_abi(slot: &mut WasmCAbi, v: Option<&str>) -> bool {
1377+
match v {
1378+
Some("spec") => *slot = WasmCAbi::Spec,
1379+
Some("legacy") => *slot = WasmCAbi::Legacy,
1380+
_ => return false,
1381+
}
1382+
true
1383+
}
13721384
}
13731385

13741386
options! {
@@ -1977,6 +1989,8 @@ written to standard error output)"),
19771989
Requires `-Clto[=[fat,yes]]`"),
19781990
wasi_exec_model: Option<WasiExecModel> = (None, parse_wasi_exec_model, [TRACKED],
19791991
"whether to build a wasi command or reactor"),
1992+
wasm_c_abi: WasmCAbi = (WasmCAbi::Legacy, parse_wasm_c_abi, [TRACKED],
1993+
"use spec-compliant C ABI for `wasm32-unknown-unknown` (default: legacy)"),
19801994
write_long_types_to_disk: bool = (true, parse_bool, [UNTRACKED],
19811995
"whether long type names should be written to files instead of being printed in errors"),
19821996
// tidy-alphabetical-end

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

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::abi::{self, Abi, Align, FieldsShape, Size};
22
use crate::abi::{HasDataLayout, TyAbiInterface, TyAndLayout};
3-
use crate::spec::{self, HasTargetSpec};
3+
use crate::spec::{self, HasTargetSpec, HasWasmCAbiOpt};
44
use rustc_span::Symbol;
55
use std::fmt;
66
use std::str::FromStr;
@@ -781,7 +781,7 @@ impl<'a, Ty> FnAbi<'a, Ty> {
781781
) -> Result<(), AdjustForForeignAbiError>
782782
where
783783
Ty: TyAbiInterface<'a, C> + Copy,
784-
C: HasDataLayout + HasTargetSpec,
784+
C: HasDataLayout + HasTargetSpec + HasWasmCAbiOpt,
785785
{
786786
if abi == spec::abi::Abi::X86Interrupt {
787787
if let Some(arg) = self.args.first_mut() {
@@ -838,7 +838,7 @@ impl<'a, Ty> FnAbi<'a, Ty> {
838838
"sparc" => sparc::compute_abi_info(cx, self),
839839
"sparc64" => sparc64::compute_abi_info(cx, self),
840840
"nvptx64" => {
841-
if cx.target_spec().adjust_abi(abi) == spec::abi::Abi::PtxKernel {
841+
if cx.target_spec().adjust_abi(cx, abi) == spec::abi::Abi::PtxKernel {
842842
nvptx64::compute_ptx_kernel_abi_info(cx, self)
843843
} else {
844844
nvptx64::compute_abi_info(self)
@@ -847,7 +847,7 @@ impl<'a, Ty> FnAbi<'a, Ty> {
847847
"hexagon" => hexagon::compute_abi_info(self),
848848
"riscv32" | "riscv64" => riscv::compute_abi_info(cx, self),
849849
"wasm32" | "wasm64" => {
850-
if cx.target_spec().adjust_abi(abi) == spec::abi::Abi::Wasm {
850+
if cx.target_spec().adjust_abi(cx, abi) == spec::abi::Abi::Wasm {
851851
wasm::compute_wasm_abi_info(self)
852852
} else {
853853
wasm::compute_c_abi_info(cx, self)

compiler/rustc_target/src/spec/mod.rs

+27-2
Original file line numberDiff line numberDiff line change
@@ -1826,6 +1826,19 @@ impl HasTargetSpec for Target {
18261826
}
18271827
}
18281828

1829+
/// Which C ABI to use for `wasm32-unknown-unknown`.
1830+
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
1831+
pub enum WasmCAbi {
1832+
/// Spec-compliant C ABI.
1833+
Spec,
1834+
/// Legacy ABI. Which is non-spec-compliant.
1835+
Legacy,
1836+
}
1837+
1838+
pub trait HasWasmCAbiOpt {
1839+
fn wasm_c_abi_opt(&self) -> WasmCAbi;
1840+
}
1841+
18291842
type StaticCow<T> = Cow<'static, T>;
18301843

18311844
/// Optional aspects of a target specification.
@@ -2433,9 +2446,21 @@ impl DerefMut for Target {
24332446

24342447
impl Target {
24352448
/// Given a function ABI, turn it into the correct ABI for this target.
2436-
pub fn adjust_abi(&self, abi: Abi) -> Abi {
2449+
pub fn adjust_abi<C>(&self, cx: &C, abi: Abi) -> Abi
2450+
where
2451+
C: HasWasmCAbiOpt,
2452+
{
24372453
match abi {
2438-
Abi::C { .. } => self.default_adjusted_cabi.unwrap_or(abi),
2454+
Abi::C { .. } => {
2455+
if self.arch == "wasm32"
2456+
&& self.os == "unknown"
2457+
&& cx.wasm_c_abi_opt() == WasmCAbi::Spec
2458+
{
2459+
abi
2460+
} else {
2461+
self.default_adjusted_cabi.unwrap_or(abi)
2462+
}
2463+
}
24392464
Abi::System { unwind } if self.is_like_windows && self.arch == "x86" => {
24402465
Abi::Stdcall { unwind }
24412466
}

compiler/rustc_ty_utils/src/abi.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ fn fn_sig_for_fn_abi<'tcx>(
207207
#[inline]
208208
fn conv_from_spec_abi(tcx: TyCtxt<'_>, abi: SpecAbi) -> Conv {
209209
use rustc_target::spec::abi::Abi::*;
210-
match tcx.sess.target.adjust_abi(abi) {
210+
match tcx.sess.target.adjust_abi(&tcx, abi) {
211211
RustIntrinsic | PlatformIntrinsic | Rust | RustCall => Conv::Rust,
212212

213213
// This is intentionally not using `Conv::Cold`, as that has to preserve
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# `wasm-c-abi`
2+
3+
This option controls whether Rust uses the spec-compliant C ABI when compiling
4+
for the `wasm32-unknown-unknown` target.
5+
6+
This makes it possible to be ABI-compatible with all other spec-compliant Wasm
7+
like Rusts `wasm32-wasi`.
8+
9+
This compiler flag is perma-unstable, as it will be enabled by default in the
10+
future with no option to fall back to the old non-spec-compliant ABI.

0 commit comments

Comments
 (0)