Introduce perma-unstable wasm-c-abi flag

This commit is contained in:
daxpedda 2024-02-27 23:06:44 +01:00
parent 5bc7b9ac8a
commit f09c19ac3a
No known key found for this signature in database
GPG Key ID: 43D62A3EA388E46F
10 changed files with 94 additions and 13 deletions

View File

@ -31,7 +31,7 @@
use rustc_target::abi::{
self, call::FnAbi, Align, HasDataLayout, Size, TargetDataLayout, WrappingRange,
};
use rustc_target::spec::{HasTargetSpec, Target};
use rustc_target::spec::{HasTargetSpec, HasWasmCAbiOpt, Target, WasmCAbi};
use crate::common::{type_is_pointer, SignType, TypeReflection};
use crate::context::CodegenCx;
@ -2349,6 +2349,12 @@ fn target_spec(&self) -> &Target {
}
}
impl<'tcx> HasWasmCAbiOpt for Builder<'_, '_, 'tcx> {
fn wasm_c_abi_opt(&self) -> WasmCAbi {
self.cx.wasm_c_abi_opt()
}
}
pub trait ToGccComp {
fn to_gcc_comparison(&self) -> ComparisonOp;
}

View File

@ -20,7 +20,7 @@
use rustc_target::abi::{
call::FnAbi, HasDataLayout, PointeeInfo, Size, TargetDataLayout, VariantIdx,
};
use rustc_target::spec::{HasTargetSpec, Target, TlsModel};
use rustc_target::spec::{HasTargetSpec, HasWasmCAbiOpt, Target, TlsModel, WasmCAbi};
use crate::callee::get_fn;
use crate::common::SignType;
@ -555,6 +555,12 @@ fn target_spec(&self) -> &Target {
}
}
impl<'gcc, 'tcx> HasWasmCAbiOpt for CodegenCx<'gcc, 'tcx> {
fn wasm_c_abi_opt(&self) -> WasmCAbi {
self.tcx.sess.opts.unstable_opts.wasm_c_abi
}
}
impl<'gcc, 'tcx> LayoutOfHelpers<'tcx> for CodegenCx<'gcc, 'tcx> {
type LayoutOfResult = TyAndLayout<'tcx>;

View File

@ -17,7 +17,9 @@
use rustc_span::edition::{Edition, DEFAULT_EDITION};
use rustc_span::symbol::sym;
use rustc_span::{FileName, SourceFileHashAlgorithm};
use rustc_target::spec::{CodeModel, LinkerFlavorCli, MergeFunctions, PanicStrategy, RelocModel};
use rustc_target::spec::{
CodeModel, LinkerFlavorCli, MergeFunctions, PanicStrategy, RelocModel, WasmCAbi,
};
use rustc_target::spec::{RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, TlsModel};
use std::collections::{BTreeMap, BTreeSet};
use std::num::NonZero;
@ -836,6 +838,7 @@ macro_rules! tracked {
tracked!(verify_llvm_ir, true);
tracked!(virtual_function_elimination, true);
tracked!(wasi_exec_model, Some(WasiExecModel::Reactor));
tracked!(wasm_c_abi, WasmCAbi::Spec);
// tidy-alphabetical-end
macro_rules! tracked_no_crate_hash {

View File

@ -15,7 +15,9 @@
use rustc_span::{ErrorGuaranteed, Span, DUMMY_SP};
use rustc_target::abi::call::FnAbi;
use rustc_target::abi::*;
use rustc_target::spec::{abi::Abi as SpecAbi, HasTargetSpec, PanicStrategy, Target};
use rustc_target::spec::{
abi::Abi as SpecAbi, HasTargetSpec, HasWasmCAbiOpt, PanicStrategy, Target, WasmCAbi,
};
use std::borrow::Cow;
use std::cmp;
@ -539,6 +541,12 @@ fn target_spec(&self) -> &Target {
}
}
impl<'tcx> HasWasmCAbiOpt for TyCtxt<'tcx> {
fn wasm_c_abi_opt(&self) -> WasmCAbi {
self.sess.opts.unstable_opts.wasm_c_abi
}
}
impl<'tcx> HasTyCtxt<'tcx> for TyCtxt<'tcx> {
#[inline]
fn tcx(&self) -> TyCtxt<'tcx> {
@ -584,6 +592,12 @@ fn target_spec(&self) -> &Target {
}
}
impl<'tcx, T: HasWasmCAbiOpt> HasWasmCAbiOpt for LayoutCx<'tcx, T> {
fn wasm_c_abi_opt(&self) -> WasmCAbi {
self.tcx.wasm_c_abi_opt()
}
}
impl<'tcx, T: HasTyCtxt<'tcx>> HasTyCtxt<'tcx> for LayoutCx<'tcx, T> {
fn tcx(&self) -> TyCtxt<'tcx> {
self.tcx.tcx()

View File

@ -3227,7 +3227,7 @@ pub(crate) mod dep_tracking {
use rustc_feature::UnstableFeatures;
use rustc_span::edition::Edition;
use rustc_span::RealFileName;
use rustc_target::spec::{CodeModel, MergeFunctions, PanicStrategy, RelocModel};
use rustc_target::spec::{CodeModel, MergeFunctions, PanicStrategy, RelocModel, WasmCAbi};
use rustc_target::spec::{
RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, TargetTriple, TlsModel,
};
@ -3324,6 +3324,7 @@ fn hash(
Polonius,
InliningThreshold,
FunctionReturn,
WasmCAbi,
);
impl<T1, T2> DepTrackingHash for (T1, T2)

View File

@ -8,7 +8,9 @@
use rustc_data_structures::stable_hasher::Hash64;
use rustc_errors::ColorConfig;
use rustc_errors::{LanguageIdentifier, TerminalUrl};
use rustc_target::spec::{CodeModel, LinkerFlavorCli, MergeFunctions, PanicStrategy, SanitizerSet};
use rustc_target::spec::{
CodeModel, LinkerFlavorCli, MergeFunctions, PanicStrategy, SanitizerSet, WasmCAbi,
};
use rustc_target::spec::{
RelocModel, RelroLevel, SplitDebuginfo, StackProtector, TargetTriple, TlsModel,
};
@ -437,6 +439,7 @@ mod desc {
"either a boolean (`yes`, `no`, `on`, `off`, etc), or a non-negative number";
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`)";
pub const parse_function_return: &str = "`keep` or `thunk-extern`";
pub const parse_wasm_c_abi: &str = "`legacy` or `spec`";
}
mod parse {
@ -1402,6 +1405,15 @@ pub(crate) fn parse_function_return(slot: &mut FunctionReturn, v: Option<&str>)
}
true
}
pub(crate) fn parse_wasm_c_abi(slot: &mut WasmCAbi, v: Option<&str>) -> bool {
match v {
Some("spec") => *slot = WasmCAbi::Spec,
Some("legacy") => *slot = WasmCAbi::Legacy,
_ => return false,
}
true
}
}
options! {
@ -2021,6 +2033,8 @@ pub(crate) fn parse_function_return(slot: &mut FunctionReturn, v: Option<&str>)
Requires `-Clto[=[fat,yes]]`"),
wasi_exec_model: Option<WasiExecModel> = (None, parse_wasi_exec_model, [TRACKED],
"whether to build a wasi command or reactor"),
wasm_c_abi: WasmCAbi = (WasmCAbi::Legacy, parse_wasm_c_abi, [TRACKED],
"use spec-compliant C ABI for `wasm32-unknown-unknown` (default: legacy)"),
write_long_types_to_disk: bool = (true, parse_bool, [UNTRACKED],
"whether long type names should be written to files instead of being printed in errors"),
// tidy-alphabetical-end

View File

@ -1,6 +1,6 @@
use crate::abi::{self, Abi, Align, FieldsShape, Size};
use crate::abi::{HasDataLayout, TyAbiInterface, TyAndLayout};
use crate::spec::{self, HasTargetSpec};
use crate::spec::{self, HasTargetSpec, HasWasmCAbiOpt};
use rustc_span::Symbol;
use std::fmt;
use std::str::FromStr;
@ -782,7 +782,7 @@ pub fn adjust_for_foreign_abi<C>(
) -> Result<(), AdjustForForeignAbiError>
where
Ty: TyAbiInterface<'a, C> + Copy,
C: HasDataLayout + HasTargetSpec,
C: HasDataLayout + HasTargetSpec + HasWasmCAbiOpt,
{
if abi == spec::abi::Abi::X86Interrupt {
if let Some(arg) = self.args.first_mut() {
@ -839,7 +839,9 @@ pub fn adjust_for_foreign_abi<C>(
"sparc" => sparc::compute_abi_info(cx, self),
"sparc64" => sparc64::compute_abi_info(cx, self),
"nvptx64" => {
if cx.target_spec().adjust_abi(abi, self.c_variadic) == spec::abi::Abi::PtxKernel {
if cx.target_spec().adjust_abi(cx, abi, self.c_variadic)
== spec::abi::Abi::PtxKernel
{
nvptx64::compute_ptx_kernel_abi_info(cx, self)
} else {
nvptx64::compute_abi_info(self)
@ -848,7 +850,7 @@ pub fn adjust_for_foreign_abi<C>(
"hexagon" => hexagon::compute_abi_info(self),
"riscv32" | "riscv64" => riscv::compute_abi_info(cx, self),
"wasm32" | "wasm64" => {
if cx.target_spec().adjust_abi(abi, self.c_variadic) == spec::abi::Abi::Wasm {
if cx.target_spec().adjust_abi(cx, abi, self.c_variadic) == spec::abi::Abi::Wasm {
wasm::compute_wasm_abi_info(self)
} else {
wasm::compute_c_abi_info(cx, self)

View File

@ -1807,6 +1807,19 @@ fn target_spec(&self) -> &Target {
}
}
/// Which C ABI to use for `wasm32-unknown-unknown`.
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub enum WasmCAbi {
/// Spec-compliant C ABI.
Spec,
/// Legacy ABI. Which is non-spec-compliant.
Legacy,
}
pub trait HasWasmCAbiOpt {
fn wasm_c_abi_opt(&self) -> WasmCAbi;
}
type StaticCow<T> = Cow<'static, T>;
/// Optional aspects of a target specification.
@ -2417,9 +2430,21 @@ fn deref_mut(&mut self) -> &mut Self::Target {
impl Target {
/// Given a function ABI, turn it into the correct ABI for this target.
pub fn adjust_abi(&self, abi: Abi, c_variadic: bool) -> Abi {
pub fn adjust_abi<C>(&self, cx: &C, abi: Abi, c_variadic: bool) -> Abi
where
C: HasWasmCAbiOpt,
{
match abi {
Abi::C { .. } => self.default_adjusted_cabi.unwrap_or(abi),
Abi::C { .. } => {
if self.arch == "wasm32"
&& self.os == "unknown"
&& cx.wasm_c_abi_opt() == WasmCAbi::Spec
{
abi
} else {
self.default_adjusted_cabi.unwrap_or(abi)
}
}
// On Windows, `extern "system"` behaves like msvc's `__stdcall`.
// `__stdcall` only applies on x86 and on non-variadic functions:

View File

@ -311,7 +311,7 @@ fn fn_sig_for_fn_abi<'tcx>(
#[inline]
fn conv_from_spec_abi(tcx: TyCtxt<'_>, abi: SpecAbi, c_variadic: bool) -> Conv {
use rustc_target::spec::abi::Abi::*;
match tcx.sess.target.adjust_abi(abi, c_variadic) {
match tcx.sess.target.adjust_abi(&tcx, abi, c_variadic) {
RustIntrinsic | Rust | RustCall => Conv::Rust,
// This is intentionally not using `Conv::Cold`, as that has to preserve

View File

@ -0,0 +1,10 @@
# `wasm-c-abi`
This option controls whether Rust uses the spec-compliant C ABI when compiling
for the `wasm32-unknown-unknown` target.
This makes it possible to be ABI-compatible with all other spec-compliant Wasm
like Rusts `wasm32-wasi`.
This compiler flag is perma-unstable, as it will be enabled by default in the
future with no option to fall back to the old non-spec-compliant ABI.