Auto merge of #90382 - alexcrichton:wasm64-libstd, r=joshtriplett
std: Get the standard library compiling for wasm64 This commit goes through and updates various `#[cfg]` as appropriate to get the wasm64-unknown-unknown target behaving similarly to the wasm32-unknown-unknown target. Most of this is just updating various conditions for `target_arch = "wasm32"` to also account for `target_arch = "wasm64"` where appropriate. This commit also lists `wasm64` as an allow-listed architecture to not have the `restricted_std` feature enabled, enabling experimentation with `-Z build-std` externally. The main goal of this commit is to enable playing around with `wasm64-unknown-unknown` externally via `-Z build-std` in a way that's similar to the `wasm32-unknown-unknown` target. These targets are effectively the same and only differ in their pointer size, but wasm64 is much newer and has much less ecosystem/library support so it'll still take time to get wasm64 fully-fledged.
This commit is contained in:
commit
b6f580acc0
31 changed files with 183 additions and 60 deletions
|
@ -678,9 +678,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "compiler_builtins"
|
name = "compiler_builtins"
|
||||||
version = "0.1.49"
|
version = "0.1.52"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "20b1438ef42c655665a8ab2c1c6d605a305f031d38d9be689ddfef41a20f3aa2"
|
checksum = "b6591c2442ee984e2b264638a8b5e7ae44fd47b32d28e3a08e2e9c3cdb0c2fb0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"rustc-std-workspace-core",
|
"rustc-std-workspace-core",
|
||||||
|
@ -1028,9 +1028,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dlmalloc"
|
name = "dlmalloc"
|
||||||
version = "0.2.1"
|
version = "0.2.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "332570860c2edf2d57914987bf9e24835425f75825086b6ba7d1e6a3e4f1f254"
|
checksum = "a6fe28e0bf9357092740362502f5cc7955d8dc125ebda71dec72336c2e15c62e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"compiler_builtins",
|
"compiler_builtins",
|
||||||
"libc",
|
"libc",
|
||||||
|
|
|
@ -320,7 +320,7 @@ impl AsmBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
|
||||||
InlineAsmArch::Mips | InlineAsmArch::Mips64 => {}
|
InlineAsmArch::Mips | InlineAsmArch::Mips64 => {}
|
||||||
InlineAsmArch::S390x => {}
|
InlineAsmArch::S390x => {}
|
||||||
InlineAsmArch::SpirV => {}
|
InlineAsmArch::SpirV => {}
|
||||||
InlineAsmArch::Wasm32 => {}
|
InlineAsmArch::Wasm32 | InlineAsmArch::Wasm64 => {}
|
||||||
InlineAsmArch::Bpf => {}
|
InlineAsmArch::Bpf => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -769,7 +769,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
|
||||||
// we like. To ensure that LLVM picks the right instruction we choose
|
// we like. To ensure that LLVM picks the right instruction we choose
|
||||||
// the raw wasm intrinsic functions which avoid LLVM inserting all the
|
// the raw wasm intrinsic functions which avoid LLVM inserting all the
|
||||||
// other control flow automatically.
|
// other control flow automatically.
|
||||||
if self.sess().target.arch == "wasm32" {
|
if self.sess().target.is_like_wasm {
|
||||||
let src_ty = self.cx.val_ty(val);
|
let src_ty = self.cx.val_ty(val);
|
||||||
if self.cx.type_kind(src_ty) != TypeKind::Vector {
|
if self.cx.type_kind(src_ty) != TypeKind::Vector {
|
||||||
let float_width = self.cx.float_width(src_ty);
|
let float_width = self.cx.float_width(src_ty);
|
||||||
|
@ -791,7 +791,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
|
||||||
|
|
||||||
fn fptosi(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
|
fn fptosi(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
|
||||||
// see `fptoui` above for why wasm is different here
|
// see `fptoui` above for why wasm is different here
|
||||||
if self.sess().target.arch == "wasm32" {
|
if self.sess().target.is_like_wasm {
|
||||||
let src_ty = self.cx.val_ty(val);
|
let src_ty = self.cx.val_ty(val);
|
||||||
if self.cx.type_kind(src_ty) != TypeKind::Vector {
|
if self.cx.type_kind(src_ty) != TypeKind::Vector {
|
||||||
let float_width = self.cx.float_width(src_ty);
|
let float_width = self.cx.float_width(src_ty);
|
||||||
|
|
|
@ -490,7 +490,7 @@ impl StaticMethods for CodegenCx<'ll, 'tcx> {
|
||||||
|
|
||||||
// Wasm statics with custom link sections get special treatment as they
|
// Wasm statics with custom link sections get special treatment as they
|
||||||
// go into custom sections of the wasm executable.
|
// go into custom sections of the wasm executable.
|
||||||
if self.tcx.sess.opts.target_triple.triple().starts_with("wasm32") {
|
if self.tcx.sess.target.is_like_wasm {
|
||||||
if let Some(section) = attrs.link_section {
|
if let Some(section) = attrs.link_section {
|
||||||
let section = llvm::LLVMMDStringInContext(
|
let section = llvm::LLVMMDStringInContext(
|
||||||
self.llcx,
|
self.llcx,
|
||||||
|
|
|
@ -75,7 +75,9 @@ unsafe fn configure_llvm(sess: &Session) {
|
||||||
if sess.print_llvm_passes() {
|
if sess.print_llvm_passes() {
|
||||||
add("-debug-pass=Structure", false);
|
add("-debug-pass=Structure", false);
|
||||||
}
|
}
|
||||||
if !sess.opts.debugging_opts.no_generate_arange_section {
|
if sess.target.generate_arange_section
|
||||||
|
&& !sess.opts.debugging_opts.no_generate_arange_section
|
||||||
|
{
|
||||||
add("-generate-arange-section", false);
|
add("-generate-arange-section", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -189,6 +189,7 @@ pub enum InlineAsmArch {
|
||||||
S390x,
|
S390x,
|
||||||
SpirV,
|
SpirV,
|
||||||
Wasm32,
|
Wasm32,
|
||||||
|
Wasm64,
|
||||||
Bpf,
|
Bpf,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,6 +213,7 @@ impl FromStr for InlineAsmArch {
|
||||||
"s390x" => Ok(Self::S390x),
|
"s390x" => Ok(Self::S390x),
|
||||||
"spirv" => Ok(Self::SpirV),
|
"spirv" => Ok(Self::SpirV),
|
||||||
"wasm32" => Ok(Self::Wasm32),
|
"wasm32" => Ok(Self::Wasm32),
|
||||||
|
"wasm64" => Ok(Self::Wasm64),
|
||||||
"bpf" => Ok(Self::Bpf),
|
"bpf" => Ok(Self::Bpf),
|
||||||
_ => Err(()),
|
_ => Err(()),
|
||||||
}
|
}
|
||||||
|
@ -318,7 +320,7 @@ impl InlineAsmReg {
|
||||||
InlineAsmArch::SpirV => {
|
InlineAsmArch::SpirV => {
|
||||||
Self::SpirV(SpirVInlineAsmReg::parse(arch, has_feature, target, &name)?)
|
Self::SpirV(SpirVInlineAsmReg::parse(arch, has_feature, target, &name)?)
|
||||||
}
|
}
|
||||||
InlineAsmArch::Wasm32 => {
|
InlineAsmArch::Wasm32 | InlineAsmArch::Wasm64 => {
|
||||||
Self::Wasm(WasmInlineAsmReg::parse(arch, has_feature, target, &name)?)
|
Self::Wasm(WasmInlineAsmReg::parse(arch, has_feature, target, &name)?)
|
||||||
}
|
}
|
||||||
InlineAsmArch::Bpf => {
|
InlineAsmArch::Bpf => {
|
||||||
|
@ -529,7 +531,9 @@ impl InlineAsmRegClass {
|
||||||
}
|
}
|
||||||
InlineAsmArch::S390x => Self::S390x(S390xInlineAsmRegClass::parse(arch, name)?),
|
InlineAsmArch::S390x => Self::S390x(S390xInlineAsmRegClass::parse(arch, name)?),
|
||||||
InlineAsmArch::SpirV => Self::SpirV(SpirVInlineAsmRegClass::parse(arch, name)?),
|
InlineAsmArch::SpirV => Self::SpirV(SpirVInlineAsmRegClass::parse(arch, name)?),
|
||||||
InlineAsmArch::Wasm32 => Self::Wasm(WasmInlineAsmRegClass::parse(arch, name)?),
|
InlineAsmArch::Wasm32 | InlineAsmArch::Wasm64 => {
|
||||||
|
Self::Wasm(WasmInlineAsmRegClass::parse(arch, name)?)
|
||||||
|
}
|
||||||
InlineAsmArch::Bpf => Self::Bpf(BpfInlineAsmRegClass::parse(arch, name)?),
|
InlineAsmArch::Bpf => Self::Bpf(BpfInlineAsmRegClass::parse(arch, name)?),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -725,7 +729,7 @@ pub fn allocatable_registers(
|
||||||
spirv::fill_reg_map(arch, has_feature, target, &mut map);
|
spirv::fill_reg_map(arch, has_feature, target, &mut map);
|
||||||
map
|
map
|
||||||
}
|
}
|
||||||
InlineAsmArch::Wasm32 => {
|
InlineAsmArch::Wasm32 | InlineAsmArch::Wasm64 => {
|
||||||
let mut map = wasm::regclass_map();
|
let mut map = wasm::regclass_map();
|
||||||
wasm::fill_reg_map(arch, has_feature, target, &mut map);
|
wasm::fill_reg_map(arch, has_feature, target, &mut map);
|
||||||
map
|
map
|
||||||
|
|
|
@ -1357,6 +1357,9 @@ pub struct TargetOptions {
|
||||||
|
|
||||||
/// Minimum number of bits in #[repr(C)] enum. Defaults to 32.
|
/// Minimum number of bits in #[repr(C)] enum. Defaults to 32.
|
||||||
pub c_enum_min_bits: u64,
|
pub c_enum_min_bits: u64,
|
||||||
|
|
||||||
|
/// Whether or not the DWARF `.debug_aranges` section should be generated.
|
||||||
|
pub generate_arange_section: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for TargetOptions {
|
impl Default for TargetOptions {
|
||||||
|
@ -1462,6 +1465,7 @@ impl Default for TargetOptions {
|
||||||
supported_sanitizers: SanitizerSet::empty(),
|
supported_sanitizers: SanitizerSet::empty(),
|
||||||
default_adjusted_cabi: None,
|
default_adjusted_cabi: None,
|
||||||
c_enum_min_bits: 32,
|
c_enum_min_bits: 32,
|
||||||
|
generate_arange_section: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2047,6 +2051,7 @@ impl Target {
|
||||||
key!(supported_sanitizers, SanitizerSet)?;
|
key!(supported_sanitizers, SanitizerSet)?;
|
||||||
key!(default_adjusted_cabi, Option<Abi>)?;
|
key!(default_adjusted_cabi, Option<Abi>)?;
|
||||||
key!(c_enum_min_bits, u64);
|
key!(c_enum_min_bits, u64);
|
||||||
|
key!(generate_arange_section, bool);
|
||||||
|
|
||||||
if base.is_builtin {
|
if base.is_builtin {
|
||||||
// This can cause unfortunate ICEs later down the line.
|
// This can cause unfortunate ICEs later down the line.
|
||||||
|
@ -2286,6 +2291,7 @@ impl ToJson for Target {
|
||||||
target_option_val!(split_debuginfo);
|
target_option_val!(split_debuginfo);
|
||||||
target_option_val!(supported_sanitizers);
|
target_option_val!(supported_sanitizers);
|
||||||
target_option_val!(c_enum_min_bits);
|
target_option_val!(c_enum_min_bits);
|
||||||
|
target_option_val!(generate_arange_section);
|
||||||
|
|
||||||
if let Some(abi) = self.default_adjusted_cabi {
|
if let Some(abi) = self.default_adjusted_cabi {
|
||||||
d.insert("default-adjusted-cabi".to_string(), Abi::name(abi).to_json());
|
d.insert("default-adjusted-cabi".to_string(), Abi::name(abi).to_json());
|
||||||
|
|
|
@ -37,7 +37,7 @@ pub fn target() -> Target {
|
||||||
is_like_emscripten: true,
|
is_like_emscripten: true,
|
||||||
panic_strategy: PanicStrategy::Unwind,
|
panic_strategy: PanicStrategy::Unwind,
|
||||||
post_link_args,
|
post_link_args,
|
||||||
families: vec!["unix".to_string()],
|
families: vec!["unix".to_string(), "wasm".to_string()],
|
||||||
..options
|
..options
|
||||||
};
|
};
|
||||||
Target {
|
Target {
|
||||||
|
|
|
@ -23,11 +23,15 @@ pub fn target() -> Target {
|
||||||
// For now this target just never has an entry symbol no matter the output
|
// For now this target just never has an entry symbol no matter the output
|
||||||
// type, so unconditionally pass this.
|
// type, so unconditionally pass this.
|
||||||
clang_args.push("-Wl,--no-entry".to_string());
|
clang_args.push("-Wl,--no-entry".to_string());
|
||||||
options
|
|
||||||
.pre_link_args
|
let lld_args = options.pre_link_args.get_mut(&LinkerFlavor::Lld(LldFlavor::Wasm)).unwrap();
|
||||||
.get_mut(&LinkerFlavor::Lld(LldFlavor::Wasm))
|
lld_args.push("--no-entry".to_string());
|
||||||
.unwrap()
|
lld_args.push("-mwasm64".to_string());
|
||||||
.push("--no-entry".to_string());
|
|
||||||
|
// Any engine that implements wasm64 will surely implement the rest of these
|
||||||
|
// features since they were all merged into the official spec by the time
|
||||||
|
// wasm64 was designed.
|
||||||
|
options.features = "+bulk-memory,+mutable-globals,+sign-ext,+nontrapping-fptoint".to_string();
|
||||||
|
|
||||||
Target {
|
Target {
|
||||||
llvm_target: "wasm64-unknown-unknown".to_string(),
|
llvm_target: "wasm64-unknown-unknown".to_string(),
|
||||||
|
|
|
@ -128,6 +128,12 @@ pub fn options() -> TargetOptions {
|
||||||
// gdb scripts don't work on wasm blobs
|
// gdb scripts don't work on wasm blobs
|
||||||
emit_debug_gdb_scripts: false,
|
emit_debug_gdb_scripts: false,
|
||||||
|
|
||||||
|
// There's more discussion of this at
|
||||||
|
// https://bugs.llvm.org/show_bug.cgi?id=52442 but the general result is
|
||||||
|
// that this isn't useful for wasm and has tricky issues with
|
||||||
|
// representation, so this is disabled.
|
||||||
|
generate_arange_section: false,
|
||||||
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -536,8 +536,8 @@ fn fn_maybe_err(tcx: TyCtxt<'_>, sp: Span, abi: Abi) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: LocalDefId, span: Span) {
|
fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: LocalDefId, span: Span) {
|
||||||
// Only restricted on wasm32 target for now
|
// Only restricted on wasm target for now
|
||||||
if !tcx.sess.opts.target_triple.triple().starts_with("wasm32") {
|
if !tcx.sess.target.is_like_wasm {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,7 @@ impl fmt::Debug for c_void {
|
||||||
#[cfg(any(
|
#[cfg(any(
|
||||||
all(not(target_arch = "aarch64"), not(target_arch = "powerpc"), not(target_arch = "x86_64")),
|
all(not(target_arch = "aarch64"), not(target_arch = "powerpc"), not(target_arch = "x86_64")),
|
||||||
all(target_arch = "aarch64", any(target_os = "macos", target_os = "ios")),
|
all(target_arch = "aarch64", any(target_os = "macos", target_os = "ios")),
|
||||||
target_arch = "wasm32",
|
target_family = "wasm",
|
||||||
target_arch = "asmjs",
|
target_arch = "asmjs",
|
||||||
windows
|
windows
|
||||||
))]
|
))]
|
||||||
|
@ -85,7 +85,7 @@ pub struct VaListImpl<'f> {
|
||||||
#[cfg(any(
|
#[cfg(any(
|
||||||
all(not(target_arch = "aarch64"), not(target_arch = "powerpc"), not(target_arch = "x86_64")),
|
all(not(target_arch = "aarch64"), not(target_arch = "powerpc"), not(target_arch = "x86_64")),
|
||||||
all(target_arch = "aarch64", any(target_os = "macos", target_os = "ios")),
|
all(target_arch = "aarch64", any(target_os = "macos", target_os = "ios")),
|
||||||
target_arch = "wasm32",
|
target_family = "wasm",
|
||||||
target_arch = "asmjs",
|
target_arch = "asmjs",
|
||||||
windows
|
windows
|
||||||
))]
|
))]
|
||||||
|
@ -185,7 +185,7 @@ pub struct VaList<'a, 'f: 'a> {
|
||||||
not(target_arch = "x86_64")
|
not(target_arch = "x86_64")
|
||||||
),
|
),
|
||||||
all(target_arch = "aarch64", any(target_os = "macos", target_os = "ios")),
|
all(target_arch = "aarch64", any(target_os = "macos", target_os = "ios")),
|
||||||
target_arch = "wasm32",
|
target_family = "wasm",
|
||||||
target_arch = "asmjs",
|
target_arch = "asmjs",
|
||||||
windows
|
windows
|
||||||
))]
|
))]
|
||||||
|
@ -194,7 +194,7 @@ pub struct VaList<'a, 'f: 'a> {
|
||||||
#[cfg(all(
|
#[cfg(all(
|
||||||
any(target_arch = "aarch64", target_arch = "powerpc", target_arch = "x86_64"),
|
any(target_arch = "aarch64", target_arch = "powerpc", target_arch = "x86_64"),
|
||||||
any(not(target_arch = "aarch64"), not(any(target_os = "macos", target_os = "ios"))),
|
any(not(target_arch = "aarch64"), not(any(target_os = "macos", target_os = "ios"))),
|
||||||
not(target_arch = "wasm32"),
|
not(target_family = "wasm"),
|
||||||
not(target_arch = "asmjs"),
|
not(target_arch = "asmjs"),
|
||||||
not(windows)
|
not(windows)
|
||||||
))]
|
))]
|
||||||
|
@ -206,7 +206,7 @@ pub struct VaList<'a, 'f: 'a> {
|
||||||
#[cfg(any(
|
#[cfg(any(
|
||||||
all(not(target_arch = "aarch64"), not(target_arch = "powerpc"), not(target_arch = "x86_64")),
|
all(not(target_arch = "aarch64"), not(target_arch = "powerpc"), not(target_arch = "x86_64")),
|
||||||
all(target_arch = "aarch64", any(target_os = "macos", target_os = "ios")),
|
all(target_arch = "aarch64", any(target_os = "macos", target_os = "ios")),
|
||||||
target_arch = "wasm32",
|
target_family = "wasm",
|
||||||
target_arch = "asmjs",
|
target_arch = "asmjs",
|
||||||
windows
|
windows
|
||||||
))]
|
))]
|
||||||
|
@ -227,7 +227,7 @@ impl<'f> VaListImpl<'f> {
|
||||||
#[cfg(all(
|
#[cfg(all(
|
||||||
any(target_arch = "aarch64", target_arch = "powerpc", target_arch = "x86_64"),
|
any(target_arch = "aarch64", target_arch = "powerpc", target_arch = "x86_64"),
|
||||||
any(not(target_arch = "aarch64"), not(any(target_os = "macos", target_os = "ios"))),
|
any(not(target_arch = "aarch64"), not(any(target_os = "macos", target_os = "ios"))),
|
||||||
not(target_arch = "wasm32"),
|
not(target_family = "wasm"),
|
||||||
not(target_arch = "asmjs"),
|
not(target_arch = "asmjs"),
|
||||||
not(windows)
|
not(windows)
|
||||||
))]
|
))]
|
||||||
|
|
|
@ -117,7 +117,7 @@ pub unsafe extern "C-unwind" fn __rust_start_panic(_payload: *mut &mut dyn BoxMe
|
||||||
pub mod personalities {
|
pub mod personalities {
|
||||||
#[rustc_std_internal_symbol]
|
#[rustc_std_internal_symbol]
|
||||||
#[cfg(not(any(
|
#[cfg(not(any(
|
||||||
all(target_arch = "wasm32", not(target_os = "emscripten"),),
|
all(target_family = "wasm", not(target_os = "emscripten")),
|
||||||
all(target_os = "windows", target_env = "gnu", target_arch = "x86_64",),
|
all(target_os = "windows", target_env = "gnu", target_arch = "x86_64",),
|
||||||
)))]
|
)))]
|
||||||
pub extern "C" fn rust_eh_personality() {}
|
pub extern "C" fn rust_eh_personality() {}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//! Unwinding for *wasm32* target.
|
//! Unwinding for unsupported target.
|
||||||
//!
|
//!
|
||||||
//! Right now we don't support this, so this is just stubs.
|
//! Stubs that simply abort for targets that don't support unwinding otherwise.
|
||||||
|
|
||||||
use alloc::boxed::Box;
|
use alloc::boxed::Box;
|
||||||
use core::any::Any;
|
use core::any::Any;
|
||||||
|
|
|
@ -56,7 +56,7 @@ cfg_if::cfg_if! {
|
||||||
mod real_imp;
|
mod real_imp;
|
||||||
} else {
|
} else {
|
||||||
// Targets that don't support unwinding.
|
// Targets that don't support unwinding.
|
||||||
// - arch=wasm32
|
// - family=wasm
|
||||||
// - os=none ("bare metal" targets)
|
// - os=none ("bare metal" targets)
|
||||||
// - os=uefi
|
// - os=uefi
|
||||||
// - os=espidf
|
// - os=espidf
|
||||||
|
|
|
@ -16,7 +16,7 @@ panic_unwind = { path = "../panic_unwind", optional = true }
|
||||||
panic_abort = { path = "../panic_abort" }
|
panic_abort = { path = "../panic_abort" }
|
||||||
core = { path = "../core" }
|
core = { path = "../core" }
|
||||||
libc = { version = "0.2.106", default-features = false, features = ['rustc-dep-of-std'] }
|
libc = { version = "0.2.106", default-features = false, features = ['rustc-dep-of-std'] }
|
||||||
compiler_builtins = { version = "0.1.44" }
|
compiler_builtins = { version = "0.1.52" }
|
||||||
profiler_builtins = { path = "../profiler_builtins", optional = true }
|
profiler_builtins = { path = "../profiler_builtins", optional = true }
|
||||||
unwind = { path = "../unwind" }
|
unwind = { path = "../unwind" }
|
||||||
hashbrown = { version = "0.11", default-features = false, features = ['rustc-dep-of-std'] }
|
hashbrown = { version = "0.11", default-features = false, features = ['rustc-dep-of-std'] }
|
||||||
|
@ -35,8 +35,8 @@ features = ['read_core', 'elf', 'macho', 'pe', 'unaligned', 'archive']
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
rand = "0.7"
|
rand = "0.7"
|
||||||
|
|
||||||
[target.'cfg(any(all(target_arch = "wasm32", not(target_os = "emscripten")), all(target_vendor = "fortanix", target_env = "sgx")))'.dependencies]
|
[target.'cfg(any(all(target_family = "wasm", not(target_os = "emscripten")), all(target_vendor = "fortanix", target_env = "sgx")))'.dependencies]
|
||||||
dlmalloc = { version = "0.2.1", features = ['rustc-dep-of-std'] }
|
dlmalloc = { version = "0.2.3", features = ['rustc-dep-of-std'] }
|
||||||
|
|
||||||
[target.x86_64-fortanix-unknown-sgx.dependencies]
|
[target.x86_64-fortanix-unknown-sgx.dependencies]
|
||||||
fortanix-sgx-abi = { version = "0.3.2", features = ['rustc-dep-of-std'] }
|
fortanix-sgx-abi = { version = "0.3.2", features = ['rustc-dep-of-std'] }
|
||||||
|
|
|
@ -25,6 +25,7 @@ fn main() {
|
||||||
|| target.contains("haiku")
|
|| target.contains("haiku")
|
||||||
|| target.contains("vxworks")
|
|| target.contains("vxworks")
|
||||||
|| target.contains("wasm32")
|
|| target.contains("wasm32")
|
||||||
|
|| target.contains("wasm64")
|
||||||
|| target.contains("asmjs")
|
|| target.contains("asmjs")
|
||||||
|| target.contains("espidf")
|
|| target.contains("espidf")
|
||||||
|| target.contains("solid")
|
|| target.contains("solid")
|
||||||
|
|
|
@ -24,7 +24,8 @@ pub const MIN_ALIGN: usize = 8;
|
||||||
target_arch = "mips64",
|
target_arch = "mips64",
|
||||||
target_arch = "s390x",
|
target_arch = "s390x",
|
||||||
target_arch = "sparc64",
|
target_arch = "sparc64",
|
||||||
target_arch = "riscv64"
|
target_arch = "riscv64",
|
||||||
|
target_arch = "wasm64",
|
||||||
)))]
|
)))]
|
||||||
pub const MIN_ALIGN: usize = 16;
|
pub const MIN_ALIGN: usize = 16;
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ cfg_if::cfg_if! {
|
||||||
} else if #[cfg(target_os = "wasi")] {
|
} else if #[cfg(target_os = "wasi")] {
|
||||||
mod wasi;
|
mod wasi;
|
||||||
pub use self::wasi::*;
|
pub use self::wasi::*;
|
||||||
} else if #[cfg(target_arch = "wasm32")] {
|
} else if #[cfg(target_family = "wasm")] {
|
||||||
mod wasm;
|
mod wasm;
|
||||||
pub use self::wasm::*;
|
pub use self::wasm::*;
|
||||||
} else if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] {
|
} else if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] {
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
//! This is an implementation of a global allocator on the wasm32 platform when
|
//! This is an implementation of a global allocator on wasm targets when
|
||||||
//! emscripten is not in use. In that situation there's no actual runtime for us
|
//! emscripten is not in use. In that situation there's no actual runtime for us
|
||||||
//! to lean on for allocation, so instead we provide our own!
|
//! to lean on for allocation, so instead we provide our own!
|
||||||
//!
|
//!
|
||||||
//! The wasm32 instruction set has two instructions for getting the current
|
//! The wasm instruction set has two instructions for getting the current
|
||||||
//! amount of memory and growing the amount of memory. These instructions are the
|
//! amount of memory and growing the amount of memory. These instructions are the
|
||||||
//! foundation on which we're able to build an allocator, so we do so! Note that
|
//! foundation on which we're able to build an allocator, so we do so! Note that
|
||||||
//! the instructions are also pretty "global" and this is the "global" allocator
|
//! the instructions are also pretty "global" and this is the "global" allocator
|
||||||
|
|
|
@ -40,7 +40,7 @@ cfg_if::cfg_if! {
|
||||||
if #[cfg(any(target_os = "l4re",
|
if #[cfg(any(target_os = "l4re",
|
||||||
target_os = "hermit",
|
target_os = "hermit",
|
||||||
feature = "restricted-std",
|
feature = "restricted-std",
|
||||||
all(target_arch = "wasm32", not(target_os = "emscripten")),
|
all(target_family = "wasm", not(target_os = "emscripten")),
|
||||||
all(target_vendor = "fortanix", target_env = "sgx")))] {
|
all(target_vendor = "fortanix", target_env = "sgx")))] {
|
||||||
pub use crate::sys::net;
|
pub use crate::sys::net;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -172,7 +172,7 @@ macro_rules! __thread_local_inner {
|
||||||
//
|
//
|
||||||
// FIXME(#84224) this should come after the `target_thread_local`
|
// FIXME(#84224) this should come after the `target_thread_local`
|
||||||
// block.
|
// block.
|
||||||
#[cfg(all(target_arch = "wasm32", not(target_feature = "atomics")))]
|
#[cfg(all(target_family = "wasm", not(target_feature = "atomics")))]
|
||||||
{
|
{
|
||||||
static mut VAL: $t = $init;
|
static mut VAL: $t = $init;
|
||||||
Some(&VAL)
|
Some(&VAL)
|
||||||
|
@ -181,7 +181,7 @@ macro_rules! __thread_local_inner {
|
||||||
// If the platform has support for `#[thread_local]`, use it.
|
// If the platform has support for `#[thread_local]`, use it.
|
||||||
#[cfg(all(
|
#[cfg(all(
|
||||||
target_thread_local,
|
target_thread_local,
|
||||||
not(all(target_arch = "wasm32", not(target_feature = "atomics"))),
|
not(all(target_family = "wasm", not(target_feature = "atomics"))),
|
||||||
))]
|
))]
|
||||||
{
|
{
|
||||||
// If a dtor isn't needed we can do something "very raw" and
|
// If a dtor isn't needed we can do something "very raw" and
|
||||||
|
@ -238,7 +238,7 @@ macro_rules! __thread_local_inner {
|
||||||
// same implementation as below for os thread locals.
|
// same implementation as below for os thread locals.
|
||||||
#[cfg(all(
|
#[cfg(all(
|
||||||
not(target_thread_local),
|
not(target_thread_local),
|
||||||
not(all(target_arch = "wasm32", not(target_feature = "atomics"))),
|
not(all(target_family = "wasm", not(target_feature = "atomics"))),
|
||||||
))]
|
))]
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -285,21 +285,21 @@ macro_rules! __thread_local_inner {
|
||||||
// The issue of "should enable on Windows sometimes" is #84933
|
// The issue of "should enable on Windows sometimes" is #84933
|
||||||
#[cfg_attr(not(windows), inline)]
|
#[cfg_attr(not(windows), inline)]
|
||||||
unsafe fn __getit() -> $crate::option::Option<&'static $t> {
|
unsafe fn __getit() -> $crate::option::Option<&'static $t> {
|
||||||
#[cfg(all(target_arch = "wasm32", not(target_feature = "atomics")))]
|
#[cfg(all(target_family = "wasm", not(target_feature = "atomics")))]
|
||||||
static __KEY: $crate::thread::__StaticLocalKeyInner<$t> =
|
static __KEY: $crate::thread::__StaticLocalKeyInner<$t> =
|
||||||
$crate::thread::__StaticLocalKeyInner::new();
|
$crate::thread::__StaticLocalKeyInner::new();
|
||||||
|
|
||||||
#[thread_local]
|
#[thread_local]
|
||||||
#[cfg(all(
|
#[cfg(all(
|
||||||
target_thread_local,
|
target_thread_local,
|
||||||
not(all(target_arch = "wasm32", not(target_feature = "atomics"))),
|
not(all(target_family = "wasm", not(target_feature = "atomics"))),
|
||||||
))]
|
))]
|
||||||
static __KEY: $crate::thread::__FastLocalKeyInner<$t> =
|
static __KEY: $crate::thread::__FastLocalKeyInner<$t> =
|
||||||
$crate::thread::__FastLocalKeyInner::new();
|
$crate::thread::__FastLocalKeyInner::new();
|
||||||
|
|
||||||
#[cfg(all(
|
#[cfg(all(
|
||||||
not(target_thread_local),
|
not(target_thread_local),
|
||||||
not(all(target_arch = "wasm32", not(target_feature = "atomics"))),
|
not(all(target_family = "wasm", not(target_feature = "atomics"))),
|
||||||
))]
|
))]
|
||||||
static __KEY: $crate::thread::__OsLocalKeyInner<$t> =
|
static __KEY: $crate::thread::__OsLocalKeyInner<$t> =
|
||||||
$crate::thread::__OsLocalKeyInner::new();
|
$crate::thread::__OsLocalKeyInner::new();
|
||||||
|
@ -479,10 +479,10 @@ mod lazy {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// On some platforms like wasm32 there's no threads, so no need to generate
|
/// On some targets like wasm there's no threads, so no need to generate
|
||||||
/// thread locals and we can instead just use plain statics!
|
/// thread locals and we can instead just use plain statics!
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
#[cfg(all(target_arch = "wasm32", not(target_feature = "atomics")))]
|
#[cfg(all(target_family = "wasm", not(target_feature = "atomics")))]
|
||||||
pub mod statik {
|
pub mod statik {
|
||||||
use super::lazy::LazyKeyInner;
|
use super::lazy::LazyKeyInner;
|
||||||
use crate::fmt;
|
use crate::fmt;
|
||||||
|
|
|
@ -200,7 +200,7 @@ pub use self::local::fast::Key as __FastLocalKeyInner;
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub use self::local::os::Key as __OsLocalKeyInner;
|
pub use self::local::os::Key as __OsLocalKeyInner;
|
||||||
#[unstable(feature = "libstd_thread_internals", issue = "none")]
|
#[unstable(feature = "libstd_thread_internals", issue = "none")]
|
||||||
#[cfg(all(target_arch = "wasm32", not(target_feature = "atomics")))]
|
#[cfg(all(target_family = "wasm", not(target_feature = "atomics")))]
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub use self::local::statik::Key as __StaticLocalKeyInner;
|
pub use self::local::statik::Key as __StaticLocalKeyInner;
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 5fdbc476afc81a789806697fc4a2d9d19b8c9993
|
Subproject commit 815d55c610dab39e92e7c83bf5fd4b7a020b4d46
|
|
@ -284,7 +284,7 @@ pub fn run_tests_console(opts: &TestOpts, tests: Vec<TestDescAndFn>) -> io::Resu
|
||||||
// Prevent the usage of `Instant` in some cases:
|
// Prevent the usage of `Instant` in some cases:
|
||||||
// - It's currently not supported for wasm targets.
|
// - It's currently not supported for wasm targets.
|
||||||
// - We disable it for miri because it's not available when isolation is enabled.
|
// - We disable it for miri because it's not available when isolation is enabled.
|
||||||
let is_instant_supported = !cfg!(target_arch = "wasm32") && !cfg!(miri);
|
let is_instant_supported = !cfg!(target_family = "wasm") && !cfg!(miri);
|
||||||
|
|
||||||
let start_time = is_instant_supported.then(Instant::now);
|
let start_time = is_instant_supported.then(Instant::now);
|
||||||
run_tests(opts, tests, |x| on_test_event(&x, &mut st, &mut *out))?;
|
run_tests(opts, tests, |x| on_test_event(&x, &mut st, &mut *out))?;
|
||||||
|
|
|
@ -470,7 +470,7 @@ pub fn run_test(
|
||||||
|
|
||||||
// Emscripten can catch panics but other wasm targets cannot
|
// Emscripten can catch panics but other wasm targets cannot
|
||||||
let ignore_because_no_process_support = desc.should_panic != ShouldPanic::No
|
let ignore_because_no_process_support = desc.should_panic != ShouldPanic::No
|
||||||
&& cfg!(target_arch = "wasm32")
|
&& cfg!(target_family = "wasm")
|
||||||
&& !cfg!(target_os = "emscripten");
|
&& !cfg!(target_os = "emscripten");
|
||||||
|
|
||||||
if force_ignore || desc.ignore || ignore_because_no_process_support {
|
if force_ignore || desc.ignore || ignore_because_no_process_support {
|
||||||
|
@ -519,7 +519,7 @@ pub fn run_test(
|
||||||
// If the platform is single-threaded we're just going to run
|
// If the platform is single-threaded we're just going to run
|
||||||
// the test synchronously, regardless of the concurrency
|
// the test synchronously, regardless of the concurrency
|
||||||
// level.
|
// level.
|
||||||
let supports_threads = !cfg!(target_os = "emscripten") && !cfg!(target_arch = "wasm32");
|
let supports_threads = !cfg!(target_os = "emscripten") && !cfg!(target_family = "wasm");
|
||||||
if concurrency == Concurrent::Yes && supports_threads {
|
if concurrency == Concurrent::Yes && supports_threads {
|
||||||
let cfg = thread::Builder::new().name(name.as_slice().to_owned());
|
let cfg = thread::Builder::new().name(name.as_slice().to_owned());
|
||||||
let mut runtest = Arc::new(Mutex::new(Some(runtest)));
|
let mut runtest = Arc::new(Mutex::new(Some(runtest)));
|
||||||
|
|
|
@ -1276,7 +1276,7 @@ note: if you're sure you want to do this, please open an issue as to why. In the
|
||||||
builder.ensure(native::TestHelpers { target: compiler.host });
|
builder.ensure(native::TestHelpers { target: compiler.host });
|
||||||
|
|
||||||
// As well as the target, except for plain wasm32, which can't build it
|
// As well as the target, except for plain wasm32, which can't build it
|
||||||
if !target.contains("wasm32") || target.contains("emscripten") {
|
if !target.contains("wasm") || target.contains("emscripten") {
|
||||||
builder.ensure(native::TestHelpers { target });
|
builder.ensure(native::TestHelpers { target });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
- [aarch64-apple-ios-sim](platform-support/aarch64-apple-ios-sim.md)
|
- [aarch64-apple-ios-sim](platform-support/aarch64-apple-ios-sim.md)
|
||||||
- [\*-kmc-solid_\*](platform-support/kmc-solid.md)
|
- [\*-kmc-solid_\*](platform-support/kmc-solid.md)
|
||||||
- [x86_64-unknown-none](platform-support/x86_64-unknown-none.md)
|
- [x86_64-unknown-none](platform-support/x86_64-unknown-none.md)
|
||||||
|
- [wasm64-unknown-unknown](platform-support/wasm64-unknown-unknown.md)
|
||||||
- [Target Tier Policy](target-tier-policy.md)
|
- [Target Tier Policy](target-tier-policy.md)
|
||||||
- [Targets](targets/index.md)
|
- [Targets](targets/index.md)
|
||||||
- [Built-in Targets](targets/built-in.md)
|
- [Built-in Targets](targets/built-in.md)
|
||||||
|
|
|
@ -276,7 +276,7 @@ target | std | host | notes
|
||||||
`thumbv7a-pc-windows-msvc` | ? | |
|
`thumbv7a-pc-windows-msvc` | ? | |
|
||||||
`thumbv7a-uwp-windows-msvc` | ✓ | |
|
`thumbv7a-uwp-windows-msvc` | ✓ | |
|
||||||
`thumbv7neon-unknown-linux-musleabihf` | ? | | Thumb2-mode ARMv7a Linux with NEON, MUSL
|
`thumbv7neon-unknown-linux-musleabihf` | ? | | Thumb2-mode ARMv7a Linux with NEON, MUSL
|
||||||
`wasm64-unknown-unknown` | * | | WebAssembly
|
[`wasm64-unknown-unknown`](platform-support/wasm64-unknown-unknown.md) | ? | | WebAssembly
|
||||||
`x86_64-apple-ios-macabi` | ✓ | | Apple Catalyst on x86_64
|
`x86_64-apple-ios-macabi` | ✓ | | Apple Catalyst on x86_64
|
||||||
`x86_64-apple-tvos` | * | | x86 64-bit tvOS
|
`x86_64-apple-tvos` | * | | x86 64-bit tvOS
|
||||||
`x86_64-pc-windows-msvc` | ✓ | | 64-bit Windows XP support
|
`x86_64-pc-windows-msvc` | ✓ | | 64-bit Windows XP support
|
||||||
|
|
101
src/doc/rustc/src/platform-support/wasm64-unknown-unknown.md
Normal file
101
src/doc/rustc/src/platform-support/wasm64-unknown-unknown.md
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
# `wasm64-unknown-unknown`
|
||||||
|
|
||||||
|
**Tier: 3**
|
||||||
|
|
||||||
|
WebAssembly target which uses 64-bit memories, relying on the [memory64]
|
||||||
|
WebAssembly proposal.
|
||||||
|
|
||||||
|
[memory64]: https://github.com/webassembly/memory64
|
||||||
|
|
||||||
|
## Target maintainers
|
||||||
|
|
||||||
|
- Alex Crichton, https://github.com/alexcrichton
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
This target is cross-compiled. The target supports `std` in the same manner as
|
||||||
|
the `wasm32-unknown-unknown` target which is to say that it comes with the
|
||||||
|
standard library but many I/O functions such as `std::fs` and `std::net` will
|
||||||
|
simply return error. Additionally I/O operations like `println!` don't actually
|
||||||
|
do anything and the prints aren't routed anywhere. This is the same as the
|
||||||
|
`wasm32-unknown-unknown` target. This target comes by default with an allocator,
|
||||||
|
currently [dlmalloc] which is [ported to rust][dlmalloc-rs].
|
||||||
|
|
||||||
|
[dlmalloc]: http://gee.cs.oswego.edu/dl/html/malloc.html
|
||||||
|
[dlmalloc-rs]: https://github.com/alexcrichton/dlmalloc-rs
|
||||||
|
|
||||||
|
The difference of this target with `wasm32-unknown-unknown` is that it's
|
||||||
|
compiled for 64-bit memories instead of 32-bit memories. This means that `usize`
|
||||||
|
is 8-bytes large as well as pointers. The tradeoff, though, is that the maximum
|
||||||
|
memory size is now the full 64-bit address space instead of the 4GB as limited
|
||||||
|
by the 32-bit address space for `wasm32-unknown-unknown`.
|
||||||
|
|
||||||
|
This target is not a stable target. The [memory64] WebAssembly proposal is stil
|
||||||
|
in-progress and not standardized. This means that there are not many engines
|
||||||
|
which implement the `memory64` feature and if they do they're likely behind a
|
||||||
|
flag, for example:
|
||||||
|
|
||||||
|
* Nodejs - `--experimental-wasm-memory64`
|
||||||
|
* Wasmtime - `--wasm-features memory64`
|
||||||
|
|
||||||
|
Also note that at this time the `wasm64-unknown-unknown` target assumes the
|
||||||
|
presence of other merged wasm proposals such as (with their LLVM feature flags):
|
||||||
|
|
||||||
|
* [Bulk memory] - `+bulk-memory`
|
||||||
|
* Mutable imported globals - `+mutable-globals`
|
||||||
|
* [Sign-extending operations] - `+sign-ext`
|
||||||
|
* [Non-trapping fp-to-int operations] - `+nontrapping-fptoint`
|
||||||
|
|
||||||
|
[Bulk memory]: https://github.com/WebAssembly/spec/blob/main/proposals/bulk-memory-operations/Overview.md
|
||||||
|
[Sign-extending operations]: https://github.com/WebAssembly/spec/blob/main/proposals/sign-extension-ops/Overview.md
|
||||||
|
[Non-trapping fp-to-int operations]: https://github.com/WebAssembly/spec/blob/main/proposals/nontrapping-float-to-int-conversion/Overview.md
|
||||||
|
|
||||||
|
The `wasm64-unknown-unknown` target intends to match the default Clang targets
|
||||||
|
for its `"C"` ABI, which is likely to be the same as Clang's
|
||||||
|
`wasm32-unknown-unknown` largely.
|
||||||
|
|
||||||
|
> **Note**: due to the relatively early-days nature of this target when working
|
||||||
|
> with this target you may encounter LLVM bugs. If an assertion hit or a bug is
|
||||||
|
> found it's recommended to open an issue either with rust-lang/rust or ideally
|
||||||
|
> with LLVM itself.
|
||||||
|
|
||||||
|
This target does not support `panic=unwind` at this time.
|
||||||
|
|
||||||
|
## Building the target
|
||||||
|
|
||||||
|
You can build Rust with support for the target by adding it to the `target`
|
||||||
|
list in `config.toml`, and the target also requires `lld` to be built to work.
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[build]
|
||||||
|
target = ["wasm64-unknown-unknown"]
|
||||||
|
|
||||||
|
[rust]
|
||||||
|
lld = true
|
||||||
|
```
|
||||||
|
|
||||||
|
## Building Rust programs
|
||||||
|
|
||||||
|
Rust does not yet ship pre-compiled artifacts for this target. To compile for
|
||||||
|
this target, you will either need to build Rust with the target enabled (see
|
||||||
|
"Building the target" above), or build your own copy of `std` by using
|
||||||
|
`build-std` or similar.
|
||||||
|
|
||||||
|
Note that the following `cfg` directives are set for `wasm64-unknown-unknown`:
|
||||||
|
|
||||||
|
* `cfg(target_arch = "wasm64")`
|
||||||
|
* `cfg(target_family = "wasm")`
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
Currently testing is not well supported for `wasm64-unknown-unknown` and the
|
||||||
|
Rust project doesn't run any tests for this target. Testing support sort of
|
||||||
|
works but without `println!` it's not the most exciting tests to run.
|
||||||
|
|
||||||
|
## Cross-compilation toolchains and C code
|
||||||
|
|
||||||
|
Compiling Rust code with C code for `wasm64-unknown-unknown` is theoretically
|
||||||
|
possible, but there are no known toolchains to do this at this time. At the time
|
||||||
|
of this writing there is no known "libc" for wasm that works with
|
||||||
|
`wasm64-unknown-unknown`, which means that mixing C & Rust with this target
|
||||||
|
effectively cannot be done.
|
|
@ -4,13 +4,10 @@
|
||||||
// pretty-expanded FIXME #23616
|
// pretty-expanded FIXME #23616
|
||||||
|
|
||||||
#[cfg(target_family = "windows")]
|
#[cfg(target_family = "windows")]
|
||||||
pub fn main() {
|
pub fn main() {}
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(target_family = "unix")]
|
#[cfg(target_family = "unix")]
|
||||||
pub fn main() {
|
pub fn main() {}
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(target_family="wasm")]
|
#[cfg(all(target_family = "wasm", not(target_os = "emscripten")))]
|
||||||
pub fn main() {
|
pub fn main() {}
|
||||||
}
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue