Skip to content

Commit

Permalink
Auto merge of #90382 - alexcrichton:wasm64-libstd, r=joshtriplett
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
bors committed Nov 18, 2021
2 parents 6414e0b + af217f7 commit b6f580a
Show file tree
Hide file tree
Showing 31 changed files with 183 additions and 60 deletions.
8 changes: 4 additions & 4 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -678,9 +678,9 @@ dependencies = [

[[package]]
name = "compiler_builtins"
version = "0.1.49"
version = "0.1.52"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "20b1438ef42c655665a8ab2c1c6d605a305f031d38d9be689ddfef41a20f3aa2"
checksum = "b6591c2442ee984e2b264638a8b5e7ae44fd47b32d28e3a08e2e9c3cdb0c2fb0"
dependencies = [
"cc",
"rustc-std-workspace-core",
Expand Down Expand Up @@ -1028,9 +1028,9 @@ dependencies = [

[[package]]
name = "dlmalloc"
version = "0.2.1"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "332570860c2edf2d57914987bf9e24835425f75825086b6ba7d1e6a3e4f1f254"
checksum = "a6fe28e0bf9357092740362502f5cc7955d8dc125ebda71dec72336c2e15c62e"
dependencies = [
"compiler_builtins",
"libc",
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_llvm/src/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ impl AsmBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
InlineAsmArch::Mips | InlineAsmArch::Mips64 => {}
InlineAsmArch::S390x => {}
InlineAsmArch::SpirV => {}
InlineAsmArch::Wasm32 => {}
InlineAsmArch::Wasm32 | InlineAsmArch::Wasm64 => {}
InlineAsmArch::Bpf => {}
}
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_codegen_llvm/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
// the raw wasm intrinsic functions which avoid LLVM inserting all the
// 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);
if self.cx.type_kind(src_ty) != TypeKind::Vector {
let float_width = self.cx.float_width(src_ty);
Expand All @@ -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 {
// 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);
if self.cx.type_kind(src_ty) != TypeKind::Vector {
let float_width = self.cx.float_width(src_ty);
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_llvm/src/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,7 @@ impl StaticMethods for CodegenCx<'ll, 'tcx> {

// Wasm statics with custom link sections get special treatment as they
// 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 {
let section = llvm::LLVMMDStringInContext(
self.llcx,
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_codegen_llvm/src/llvm_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,9 @@ unsafe fn configure_llvm(sess: &Session) {
if sess.print_llvm_passes() {
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);
}

Expand Down
10 changes: 7 additions & 3 deletions compiler/rustc_target/src/asm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ pub enum InlineAsmArch {
S390x,
SpirV,
Wasm32,
Wasm64,
Bpf,
}

Expand All @@ -212,6 +213,7 @@ impl FromStr for InlineAsmArch {
"s390x" => Ok(Self::S390x),
"spirv" => Ok(Self::SpirV),
"wasm32" => Ok(Self::Wasm32),
"wasm64" => Ok(Self::Wasm64),
"bpf" => Ok(Self::Bpf),
_ => Err(()),
}
Expand Down Expand Up @@ -318,7 +320,7 @@ impl InlineAsmReg {
InlineAsmArch::SpirV => {
Self::SpirV(SpirVInlineAsmReg::parse(arch, has_feature, target, &name)?)
}
InlineAsmArch::Wasm32 => {
InlineAsmArch::Wasm32 | InlineAsmArch::Wasm64 => {
Self::Wasm(WasmInlineAsmReg::parse(arch, has_feature, target, &name)?)
}
InlineAsmArch::Bpf => {
Expand Down Expand Up @@ -529,7 +531,9 @@ impl InlineAsmRegClass {
}
InlineAsmArch::S390x => Self::S390x(S390xInlineAsmRegClass::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)?),
})
}
Expand Down Expand Up @@ -725,7 +729,7 @@ pub fn allocatable_registers(
spirv::fill_reg_map(arch, has_feature, target, &mut map);
map
}
InlineAsmArch::Wasm32 => {
InlineAsmArch::Wasm32 | InlineAsmArch::Wasm64 => {
let mut map = wasm::regclass_map();
wasm::fill_reg_map(arch, has_feature, target, &mut map);
map
Expand Down
6 changes: 6 additions & 0 deletions compiler/rustc_target/src/spec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1357,6 +1357,9 @@ pub struct TargetOptions {

/// Minimum number of bits in #[repr(C)] enum. Defaults to 32.
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 {
Expand Down Expand Up @@ -1462,6 +1465,7 @@ impl Default for TargetOptions {
supported_sanitizers: SanitizerSet::empty(),
default_adjusted_cabi: None,
c_enum_min_bits: 32,
generate_arange_section: true,
}
}
}
Expand Down Expand Up @@ -2047,6 +2051,7 @@ impl Target {
key!(supported_sanitizers, SanitizerSet)?;
key!(default_adjusted_cabi, Option<Abi>)?;
key!(c_enum_min_bits, u64);
key!(generate_arange_section, bool);

if base.is_builtin {
// This can cause unfortunate ICEs later down the line.
Expand Down Expand Up @@ -2286,6 +2291,7 @@ impl ToJson for Target {
target_option_val!(split_debuginfo);
target_option_val!(supported_sanitizers);
target_option_val!(c_enum_min_bits);
target_option_val!(generate_arange_section);

if let Some(abi) = self.default_adjusted_cabi {
d.insert("default-adjusted-cabi".to_string(), Abi::name(abi).to_json());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ pub fn target() -> Target {
is_like_emscripten: true,
panic_strategy: PanicStrategy::Unwind,
post_link_args,
families: vec!["unix".to_string()],
families: vec!["unix".to_string(), "wasm".to_string()],
..options
};
Target {
Expand Down
14 changes: 9 additions & 5 deletions compiler/rustc_target/src/spec/wasm64_unknown_unknown.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,15 @@ pub fn target() -> Target {
// For now this target just never has an entry symbol no matter the output
// type, so unconditionally pass this.
clang_args.push("-Wl,--no-entry".to_string());
options
.pre_link_args
.get_mut(&LinkerFlavor::Lld(LldFlavor::Wasm))
.unwrap()
.push("--no-entry".to_string());

let lld_args = options.pre_link_args.get_mut(&LinkerFlavor::Lld(LldFlavor::Wasm)).unwrap();
lld_args.push("--no-entry".to_string());
lld_args.push("-mwasm64".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 {
llvm_target: "wasm64-unknown-unknown".to_string(),
Expand Down
6 changes: 6 additions & 0 deletions compiler/rustc_target/src/spec/wasm_base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,12 @@ pub fn options() -> TargetOptions {
// gdb scripts don't work on wasm blobs
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()
}
}
4 changes: 2 additions & 2 deletions compiler/rustc_typeck/src/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
// Only restricted on wasm32 target for now
if !tcx.sess.opts.target_triple.triple().starts_with("wasm32") {
// Only restricted on wasm target for now
if !tcx.sess.target.is_like_wasm {
return;
}

Expand Down
12 changes: 6 additions & 6 deletions library/core/src/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ impl fmt::Debug for c_void {
#[cfg(any(
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")),
target_arch = "wasm32",
target_family = "wasm",
target_arch = "asmjs",
windows
))]
Expand All @@ -85,7 +85,7 @@ pub struct VaListImpl<'f> {
#[cfg(any(
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")),
target_arch = "wasm32",
target_family = "wasm",
target_arch = "asmjs",
windows
))]
Expand Down Expand Up @@ -185,7 +185,7 @@ pub struct VaList<'a, 'f: 'a> {
not(target_arch = "x86_64")
),
all(target_arch = "aarch64", any(target_os = "macos", target_os = "ios")),
target_arch = "wasm32",
target_family = "wasm",
target_arch = "asmjs",
windows
))]
Expand All @@ -194,7 +194,7 @@ pub struct VaList<'a, 'f: 'a> {
#[cfg(all(
any(target_arch = "aarch64", target_arch = "powerpc", target_arch = "x86_64"),
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(windows)
))]
Expand All @@ -206,7 +206,7 @@ pub struct VaList<'a, 'f: 'a> {
#[cfg(any(
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")),
target_arch = "wasm32",
target_family = "wasm",
target_arch = "asmjs",
windows
))]
Expand All @@ -227,7 +227,7 @@ impl<'f> VaListImpl<'f> {
#[cfg(all(
any(target_arch = "aarch64", target_arch = "powerpc", target_arch = "x86_64"),
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(windows)
))]
Expand Down
2 changes: 1 addition & 1 deletion library/panic_abort/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ pub unsafe extern "C-unwind" fn __rust_start_panic(_payload: *mut &mut dyn BoxMe
pub mod personalities {
#[rustc_std_internal_symbol]
#[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",),
)))]
pub extern "C" fn rust_eh_personality() {}
Expand Down
4 changes: 2 additions & 2 deletions library/panic_unwind/src/dummy.rs
Original file line number Diff line number Diff line change
@@ -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 core::any::Any;
Expand Down
2 changes: 1 addition & 1 deletion library/panic_unwind/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ cfg_if::cfg_if! {
mod real_imp;
} else {
// Targets that don't support unwinding.
// - arch=wasm32
// - family=wasm
// - os=none ("bare metal" targets)
// - os=uefi
// - os=espidf
Expand Down
6 changes: 3 additions & 3 deletions library/std/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ panic_unwind = { path = "../panic_unwind", optional = true }
panic_abort = { path = "../panic_abort" }
core = { path = "../core" }
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 }
unwind = { path = "../unwind" }
hashbrown = { version = "0.11", default-features = false, features = ['rustc-dep-of-std'] }
Expand All @@ -35,8 +35,8 @@ features = ['read_core', 'elf', 'macho', 'pe', 'unaligned', 'archive']
[dev-dependencies]
rand = "0.7"

[target.'cfg(any(all(target_arch = "wasm32", not(target_os = "emscripten")), all(target_vendor = "fortanix", target_env = "sgx")))'.dependencies]
dlmalloc = { version = "0.2.1", features = ['rustc-dep-of-std'] }
[target.'cfg(any(all(target_family = "wasm", not(target_os = "emscripten")), all(target_vendor = "fortanix", target_env = "sgx")))'.dependencies]
dlmalloc = { version = "0.2.3", features = ['rustc-dep-of-std'] }

[target.x86_64-fortanix-unknown-sgx.dependencies]
fortanix-sgx-abi = { version = "0.3.2", features = ['rustc-dep-of-std'] }
Expand Down
1 change: 1 addition & 0 deletions library/std/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ fn main() {
|| target.contains("haiku")
|| target.contains("vxworks")
|| target.contains("wasm32")
|| target.contains("wasm64")
|| target.contains("asmjs")
|| target.contains("espidf")
|| target.contains("solid")
Expand Down
3 changes: 2 additions & 1 deletion library/std/src/sys/common/alloc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ pub const MIN_ALIGN: usize = 8;
target_arch = "mips64",
target_arch = "s390x",
target_arch = "sparc64",
target_arch = "riscv64"
target_arch = "riscv64",
target_arch = "wasm64",
)))]
pub const MIN_ALIGN: usize = 16;

Expand Down
2 changes: 1 addition & 1 deletion library/std/src/sys/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ cfg_if::cfg_if! {
} else if #[cfg(target_os = "wasi")] {
mod wasi;
pub use self::wasi::*;
} else if #[cfg(target_arch = "wasm32")] {
} else if #[cfg(target_family = "wasm")] {
mod wasm;
pub use self::wasm::*;
} else if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] {
Expand Down
4 changes: 2 additions & 2 deletions library/std/src/sys/wasm/alloc.rs
Original file line number Diff line number Diff line change
@@ -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
//! 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
//! 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
Expand Down
2 changes: 1 addition & 1 deletion library/std/src/sys_common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ cfg_if::cfg_if! {
if #[cfg(any(target_os = "l4re",
target_os = "hermit",
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")))] {
pub use crate::sys::net;
} else {
Expand Down
Loading

0 comments on commit b6f580a

Please sign in to comment.