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: https://github.com/rust-lang/compiler-team/issues/703 Tracking issue: https://github.com/rust-lang/rust/issues/122532
This commit is contained in:
commit
13e63f7490
@ -31,7 +31,7 @@ use rustc_span::Span;
|
|||||||
use rustc_target::abi::{
|
use rustc_target::abi::{
|
||||||
self, call::FnAbi, Align, HasDataLayout, Size, TargetDataLayout, WrappingRange,
|
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::common::{type_is_pointer, SignType, TypeReflection};
|
||||||
use crate::context::CodegenCx;
|
use crate::context::CodegenCx;
|
||||||
@ -2352,6 +2352,12 @@ impl<'tcx> HasTargetSpec for Builder<'_, '_, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'tcx> HasWasmCAbiOpt for Builder<'_, '_, 'tcx> {
|
||||||
|
fn wasm_c_abi_opt(&self) -> WasmCAbi {
|
||||||
|
self.cx.wasm_c_abi_opt()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub trait ToGccComp {
|
pub trait ToGccComp {
|
||||||
fn to_gcc_comparison(&self) -> ComparisonOp;
|
fn to_gcc_comparison(&self) -> ComparisonOp;
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ use rustc_span::{source_map::respan, Span};
|
|||||||
use rustc_target::abi::{
|
use rustc_target::abi::{
|
||||||
call::FnAbi, HasDataLayout, PointeeInfo, Size, TargetDataLayout, VariantIdx,
|
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::callee::get_fn;
|
||||||
use crate::common::SignType;
|
use crate::common::SignType;
|
||||||
@ -557,6 +557,12 @@ impl<'gcc, 'tcx> HasTargetSpec for CodegenCx<'gcc, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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> {
|
impl<'gcc, 'tcx> LayoutOfHelpers<'tcx> for CodegenCx<'gcc, 'tcx> {
|
||||||
type LayoutOfResult = TyAndLayout<'tcx>;
|
type LayoutOfResult = TyAndLayout<'tcx>;
|
||||||
|
|
||||||
|
@ -19,7 +19,9 @@ use rustc_span::edition::{Edition, DEFAULT_EDITION};
|
|||||||
use rustc_span::source_map::{RealFileLoader, SourceMapInputs};
|
use rustc_span::source_map::{RealFileLoader, SourceMapInputs};
|
||||||
use rustc_span::symbol::sym;
|
use rustc_span::symbol::sym;
|
||||||
use rustc_span::{FileName, SourceFileHashAlgorithm};
|
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 rustc_target::spec::{RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, TlsModel};
|
||||||
use std::collections::{BTreeMap, BTreeSet};
|
use std::collections::{BTreeMap, BTreeSet};
|
||||||
use std::num::NonZero;
|
use std::num::NonZero;
|
||||||
@ -851,6 +853,7 @@ fn test_unstable_options_tracking_hash() {
|
|||||||
tracked!(verify_llvm_ir, true);
|
tracked!(verify_llvm_ir, true);
|
||||||
tracked!(virtual_function_elimination, true);
|
tracked!(virtual_function_elimination, true);
|
||||||
tracked!(wasi_exec_model, Some(WasiExecModel::Reactor));
|
tracked!(wasi_exec_model, Some(WasiExecModel::Reactor));
|
||||||
|
tracked!(wasm_c_abi, WasmCAbi::Spec);
|
||||||
// tidy-alphabetical-end
|
// tidy-alphabetical-end
|
||||||
|
|
||||||
macro_rules! tracked_no_crate_hash {
|
macro_rules! tracked_no_crate_hash {
|
||||||
|
@ -15,7 +15,9 @@ use rustc_span::symbol::{sym, Symbol};
|
|||||||
use rustc_span::{ErrorGuaranteed, Span, DUMMY_SP};
|
use rustc_span::{ErrorGuaranteed, Span, DUMMY_SP};
|
||||||
use rustc_target::abi::call::FnAbi;
|
use rustc_target::abi::call::FnAbi;
|
||||||
use rustc_target::abi::*;
|
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::borrow::Cow;
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
@ -483,6 +485,12 @@ impl<'tcx> HasTargetSpec for TyCtxt<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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> {
|
impl<'tcx> HasTyCtxt<'tcx> for TyCtxt<'tcx> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn tcx(&self) -> TyCtxt<'tcx> {
|
fn tcx(&self) -> TyCtxt<'tcx> {
|
||||||
@ -528,6 +536,12 @@ impl<'tcx, T: HasTargetSpec> HasTargetSpec for LayoutCx<'tcx, T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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> {
|
impl<'tcx, T: HasTyCtxt<'tcx>> HasTyCtxt<'tcx> for LayoutCx<'tcx, T> {
|
||||||
fn tcx(&self) -> TyCtxt<'tcx> {
|
fn tcx(&self) -> TyCtxt<'tcx> {
|
||||||
self.tcx.tcx()
|
self.tcx.tcx()
|
||||||
|
@ -2880,7 +2880,7 @@ pub(crate) mod dep_tracking {
|
|||||||
use rustc_feature::UnstableFeatures;
|
use rustc_feature::UnstableFeatures;
|
||||||
use rustc_span::edition::Edition;
|
use rustc_span::edition::Edition;
|
||||||
use rustc_span::RealFileName;
|
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::{
|
use rustc_target::spec::{
|
||||||
RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, TargetTriple, TlsModel,
|
RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, TargetTriple, TlsModel,
|
||||||
};
|
};
|
||||||
@ -2978,6 +2978,7 @@ pub(crate) mod dep_tracking {
|
|||||||
Polonius,
|
Polonius,
|
||||||
InliningThreshold,
|
InliningThreshold,
|
||||||
FunctionReturn,
|
FunctionReturn,
|
||||||
|
WasmCAbi,
|
||||||
);
|
);
|
||||||
|
|
||||||
impl<T1, T2> DepTrackingHash for (T1, T2)
|
impl<T1, T2> DepTrackingHash for (T1, T2)
|
||||||
|
@ -8,7 +8,9 @@ use rustc_data_structures::profiling::TimePassesFormat;
|
|||||||
use rustc_data_structures::stable_hasher::Hash64;
|
use rustc_data_structures::stable_hasher::Hash64;
|
||||||
use rustc_errors::ColorConfig;
|
use rustc_errors::ColorConfig;
|
||||||
use rustc_errors::{LanguageIdentifier, TerminalUrl};
|
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::{
|
use rustc_target::spec::{
|
||||||
RelocModel, RelroLevel, SplitDebuginfo, StackProtector, TargetTriple, TlsModel,
|
RelocModel, RelroLevel, SplitDebuginfo, StackProtector, TargetTriple, TlsModel,
|
||||||
};
|
};
|
||||||
@ -441,6 +443,7 @@ mod desc {
|
|||||||
"either a boolean (`yes`, `no`, `on`, `off`, etc), or a non-negative number";
|
"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_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_function_return: &str = "`keep` or `thunk-extern`";
|
||||||
|
pub const parse_wasm_c_abi: &str = "`legacy` or `spec`";
|
||||||
}
|
}
|
||||||
|
|
||||||
mod parse {
|
mod parse {
|
||||||
@ -1433,6 +1436,15 @@ mod parse {
|
|||||||
}
|
}
|
||||||
true
|
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! {
|
options! {
|
||||||
@ -2061,6 +2073,8 @@ written to standard error output)"),
|
|||||||
Requires `-Clto[=[fat,yes]]`"),
|
Requires `-Clto[=[fat,yes]]`"),
|
||||||
wasi_exec_model: Option<WasiExecModel> = (None, parse_wasi_exec_model, [TRACKED],
|
wasi_exec_model: Option<WasiExecModel> = (None, parse_wasi_exec_model, [TRACKED],
|
||||||
"whether to build a wasi command or reactor"),
|
"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],
|
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"),
|
"whether long type names should be written to files instead of being printed in errors"),
|
||||||
// tidy-alphabetical-end
|
// tidy-alphabetical-end
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::abi::{self, Abi, Align, FieldsShape, Size};
|
use crate::abi::{self, Abi, Align, FieldsShape, Size};
|
||||||
use crate::abi::{HasDataLayout, TyAbiInterface, TyAndLayout};
|
use crate::abi::{HasDataLayout, TyAbiInterface, TyAndLayout};
|
||||||
use crate::spec::{self, HasTargetSpec};
|
use crate::spec::{self, HasTargetSpec, HasWasmCAbiOpt};
|
||||||
use rustc_span::Symbol;
|
use rustc_span::Symbol;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
@ -829,7 +829,7 @@ impl<'a, Ty> FnAbi<'a, Ty> {
|
|||||||
) -> Result<(), AdjustForForeignAbiError>
|
) -> Result<(), AdjustForForeignAbiError>
|
||||||
where
|
where
|
||||||
Ty: TyAbiInterface<'a, C> + Copy,
|
Ty: TyAbiInterface<'a, C> + Copy,
|
||||||
C: HasDataLayout + HasTargetSpec,
|
C: HasDataLayout + HasTargetSpec + HasWasmCAbiOpt,
|
||||||
{
|
{
|
||||||
if abi == spec::abi::Abi::X86Interrupt {
|
if abi == spec::abi::Abi::X86Interrupt {
|
||||||
if let Some(arg) = self.args.first_mut() {
|
if let Some(arg) = self.args.first_mut() {
|
||||||
@ -886,7 +886,9 @@ impl<'a, Ty> FnAbi<'a, Ty> {
|
|||||||
"sparc" => sparc::compute_abi_info(cx, self),
|
"sparc" => sparc::compute_abi_info(cx, self),
|
||||||
"sparc64" => sparc64::compute_abi_info(cx, self),
|
"sparc64" => sparc64::compute_abi_info(cx, self),
|
||||||
"nvptx64" => {
|
"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)
|
nvptx64::compute_ptx_kernel_abi_info(cx, self)
|
||||||
} else {
|
} else {
|
||||||
nvptx64::compute_abi_info(self)
|
nvptx64::compute_abi_info(self)
|
||||||
@ -895,7 +897,7 @@ impl<'a, Ty> FnAbi<'a, Ty> {
|
|||||||
"hexagon" => hexagon::compute_abi_info(self),
|
"hexagon" => hexagon::compute_abi_info(self),
|
||||||
"riscv32" | "riscv64" => riscv::compute_abi_info(cx, self),
|
"riscv32" | "riscv64" => riscv::compute_abi_info(cx, self),
|
||||||
"wasm32" | "wasm64" => {
|
"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)
|
wasm::compute_wasm_abi_info(self)
|
||||||
} else {
|
} else {
|
||||||
wasm::compute_c_abi_info(cx, self)
|
wasm::compute_c_abi_info(cx, self)
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
use crate::abi::call::Conv;
|
use crate::abi::call::Conv;
|
||||||
use crate::abi::{Endian, Integer, Size, TargetDataLayout, TargetDataLayoutErrors};
|
use crate::abi::{Endian, Integer, Size, TargetDataLayout, TargetDataLayoutErrors};
|
||||||
use crate::json::{Json, ToJson};
|
use crate::json::{Json, ToJson};
|
||||||
use crate::spec::abi::{lookup as lookup_abi, Abi};
|
use crate::spec::abi::Abi;
|
||||||
use crate::spec::crt_objects::CrtObjects;
|
use crate::spec::crt_objects::CrtObjects;
|
||||||
use rustc_fs_util::try_canonicalize;
|
use rustc_fs_util::try_canonicalize;
|
||||||
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
|
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
|
||||||
@ -1915,6 +1915,19 @@ impl HasTargetSpec for 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>;
|
type StaticCow<T> = Cow<'static, T>;
|
||||||
|
|
||||||
/// Optional aspects of a target specification.
|
/// Optional aspects of a target specification.
|
||||||
@ -2273,9 +2286,6 @@ pub struct TargetOptions {
|
|||||||
/// distributed with the target, the sanitizer should still appear in this list for the target.
|
/// distributed with the target, the sanitizer should still appear in this list for the target.
|
||||||
pub supported_sanitizers: SanitizerSet,
|
pub supported_sanitizers: SanitizerSet,
|
||||||
|
|
||||||
/// If present it's a default value to use for adjusting the C ABI.
|
|
||||||
pub default_adjusted_cabi: Option<Abi>,
|
|
||||||
|
|
||||||
/// Minimum number of bits in #[repr(C)] enum. Defaults to the size of c_int
|
/// Minimum number of bits in #[repr(C)] enum. Defaults to the size of c_int
|
||||||
pub c_enum_min_bits: Option<u64>,
|
pub c_enum_min_bits: Option<u64>,
|
||||||
|
|
||||||
@ -2507,7 +2517,6 @@ impl Default for TargetOptions {
|
|||||||
// `Off` is supported by default, but targets can remove this manually, e.g. Windows.
|
// `Off` is supported by default, but targets can remove this manually, e.g. Windows.
|
||||||
supported_split_debuginfo: Cow::Borrowed(&[SplitDebuginfo::Off]),
|
supported_split_debuginfo: Cow::Borrowed(&[SplitDebuginfo::Off]),
|
||||||
supported_sanitizers: SanitizerSet::empty(),
|
supported_sanitizers: SanitizerSet::empty(),
|
||||||
default_adjusted_cabi: None,
|
|
||||||
c_enum_min_bits: None,
|
c_enum_min_bits: None,
|
||||||
generate_arange_section: true,
|
generate_arange_section: true,
|
||||||
supports_stack_protector: true,
|
supports_stack_protector: true,
|
||||||
@ -2538,9 +2547,21 @@ impl DerefMut for Target {
|
|||||||
|
|
||||||
impl Target {
|
impl Target {
|
||||||
/// Given a function ABI, turn it into the correct ABI for this 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 {
|
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::Legacy
|
||||||
|
{
|
||||||
|
Abi::Wasm
|
||||||
|
} else {
|
||||||
|
abi
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// On Windows, `extern "system"` behaves like msvc's `__stdcall`.
|
// On Windows, `extern "system"` behaves like msvc's `__stdcall`.
|
||||||
// `__stdcall` only applies on x86 and on non-variadic functions:
|
// `__stdcall` only applies on x86 and on non-variadic functions:
|
||||||
@ -3079,16 +3100,6 @@ impl Target {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
($key_name:ident, Option<Abi>) => ( {
|
|
||||||
let name = (stringify!($key_name)).replace("_", "-");
|
|
||||||
obj.remove(&name).and_then(|o| o.as_str().and_then(|s| {
|
|
||||||
match lookup_abi(s) {
|
|
||||||
Ok(abi) => base.$key_name = Some(abi),
|
|
||||||
_ => return Some(Err(format!("'{}' is not a valid value for abi", s))),
|
|
||||||
}
|
|
||||||
Some(Ok(()))
|
|
||||||
})).unwrap_or(Ok(()))
|
|
||||||
} );
|
|
||||||
($key_name:ident, TargetFamilies) => ( {
|
($key_name:ident, TargetFamilies) => ( {
|
||||||
if let Some(value) = obj.remove("target-family") {
|
if let Some(value) = obj.remove("target-family") {
|
||||||
if let Some(v) = value.as_array() {
|
if let Some(v) = value.as_array() {
|
||||||
@ -3238,7 +3249,6 @@ impl Target {
|
|||||||
key!(split_debuginfo, SplitDebuginfo)?;
|
key!(split_debuginfo, SplitDebuginfo)?;
|
||||||
key!(supported_split_debuginfo, fallible_list)?;
|
key!(supported_split_debuginfo, fallible_list)?;
|
||||||
key!(supported_sanitizers, SanitizerSet)?;
|
key!(supported_sanitizers, SanitizerSet)?;
|
||||||
key!(default_adjusted_cabi, Option<Abi>)?;
|
|
||||||
key!(generate_arange_section, bool);
|
key!(generate_arange_section, bool);
|
||||||
key!(supports_stack_protector, bool);
|
key!(supports_stack_protector, bool);
|
||||||
key!(entry_name);
|
key!(entry_name);
|
||||||
@ -3502,10 +3512,6 @@ impl ToJson for Target {
|
|||||||
target_option_val!(entry_abi);
|
target_option_val!(entry_abi);
|
||||||
target_option_val!(supports_xray);
|
target_option_val!(supports_xray);
|
||||||
|
|
||||||
if let Some(abi) = self.default_adjusted_cabi {
|
|
||||||
d.insert("default-adjusted-cabi".into(), Abi::name(abi).to_json());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Serializing `-Clink-self-contained` needs a dynamic key to support the
|
// Serializing `-Clink-self-contained` needs a dynamic key to support the
|
||||||
// backwards-compatible variants.
|
// backwards-compatible variants.
|
||||||
d.insert(self.link_self_contained.json_key().into(), self.link_self_contained.to_json());
|
d.insert(self.link_self_contained.json_key().into(), self.link_self_contained.to_json());
|
||||||
|
@ -10,23 +10,12 @@
|
|||||||
//! This target is more or less managed by the Rust and WebAssembly Working
|
//! This target is more or less managed by the Rust and WebAssembly Working
|
||||||
//! Group nowadays at <https://github.com/rustwasm>.
|
//! Group nowadays at <https://github.com/rustwasm>.
|
||||||
|
|
||||||
use crate::spec::abi::Abi;
|
|
||||||
use crate::spec::{base, Cc, LinkerFlavor, Target};
|
use crate::spec::{base, Cc, LinkerFlavor, Target};
|
||||||
|
|
||||||
pub fn target() -> Target {
|
pub fn target() -> Target {
|
||||||
let mut options = base::wasm::options();
|
let mut options = base::wasm::options();
|
||||||
options.os = "unknown".into();
|
options.os = "unknown".into();
|
||||||
|
|
||||||
// This is a default for backwards-compatibility with the original
|
|
||||||
// definition of this target oh-so-long-ago. Once the "wasm" ABI is
|
|
||||||
// stable and the wasm-bindgen project has switched to using it then there's
|
|
||||||
// no need for this and it can be removed.
|
|
||||||
//
|
|
||||||
// Currently this is the reason that this target's ABI is mismatched with
|
|
||||||
// clang's ABI. This means that, in the limit, you can't merge C and Rust
|
|
||||||
// code on this target due to this ABI mismatch.
|
|
||||||
options.default_adjusted_cabi = Some(Abi::Wasm);
|
|
||||||
|
|
||||||
options.add_pre_link_args(
|
options.add_pre_link_args(
|
||||||
LinkerFlavor::WasmLld(Cc::No),
|
LinkerFlavor::WasmLld(Cc::No),
|
||||||
&[
|
&[
|
||||||
|
@ -322,7 +322,7 @@ fn fn_sig_for_fn_abi<'tcx>(
|
|||||||
#[inline]
|
#[inline]
|
||||||
fn conv_from_spec_abi(tcx: TyCtxt<'_>, abi: SpecAbi, c_variadic: bool) -> Conv {
|
fn conv_from_spec_abi(tcx: TyCtxt<'_>, abi: SpecAbi, c_variadic: bool) -> Conv {
|
||||||
use rustc_target::spec::abi::Abi::*;
|
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,
|
RustIntrinsic | Rust | RustCall => Conv::Rust,
|
||||||
|
|
||||||
// This is intentionally not using `Conv::Cold`, as that has to preserve
|
// This is intentionally not using `Conv::Cold`, as that has to preserve
|
||||||
|
10
src/doc/unstable-book/src/compiler-flags/wasm-c-abi.md
Normal file
10
src/doc/unstable-book/src/compiler-flags/wasm-c-abi.md
Normal 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.
|
Loading…
x
Reference in New Issue
Block a user