work around the wasm32-unknown-unknown
ABI being broken
This commit is contained in:
parent
8dec09f3c5
commit
bcf478b7a6
2 changed files with 48 additions and 16 deletions
|
@ -1,12 +1,14 @@
|
||||||
use rustc_abi::{BackendRepr, Float, Integer, Primitive, RegKind};
|
use rustc_abi::{BackendRepr, Float, Integer, Primitive, RegKind};
|
||||||
use rustc_attr_parsing::InstructionSetAttr;
|
use rustc_attr_parsing::InstructionSetAttr;
|
||||||
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_middle::mir::mono::{Linkage, MonoItem, MonoItemData, Visibility};
|
use rustc_middle::mir::mono::{Linkage, MonoItem, MonoItemData, Visibility};
|
||||||
use rustc_middle::mir::{Body, InlineAsmOperand};
|
use rustc_middle::mir::{Body, InlineAsmOperand};
|
||||||
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, HasTypingEnv, LayoutOf};
|
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, HasTypingEnv, LayoutOf};
|
||||||
use rustc_middle::ty::{Instance, Ty, TyCtxt};
|
use rustc_middle::ty::{Instance, Ty, TyCtxt};
|
||||||
use rustc_middle::{bug, ty};
|
use rustc_middle::{bug, span_bug, ty};
|
||||||
use rustc_span::sym;
|
use rustc_span::sym;
|
||||||
use rustc_target::callconv::{ArgAbi, FnAbi, PassMode};
|
use rustc_target::callconv::{ArgAbi, FnAbi, PassMode};
|
||||||
|
use rustc_target::spec::WasmCAbi;
|
||||||
|
|
||||||
use crate::common;
|
use crate::common;
|
||||||
use crate::traits::{AsmCodegenMethods, BuilderMethods, GlobalAsmOperandRef, MiscCodegenMethods};
|
use crate::traits::{AsmCodegenMethods, BuilderMethods, GlobalAsmOperandRef, MiscCodegenMethods};
|
||||||
|
@ -285,7 +287,12 @@ fn prefix_and_suffix<'tcx>(
|
||||||
writeln!(begin, "{}", arch_prefix).unwrap();
|
writeln!(begin, "{}", arch_prefix).unwrap();
|
||||||
}
|
}
|
||||||
writeln!(begin, "{asm_name}:").unwrap();
|
writeln!(begin, "{asm_name}:").unwrap();
|
||||||
writeln!(begin, ".functype {asm_name} {}", wasm_functype(tcx, fn_abi)).unwrap();
|
writeln!(
|
||||||
|
begin,
|
||||||
|
".functype {asm_name} {}",
|
||||||
|
wasm_functype(tcx, fn_abi, instance.def_id())
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
writeln!(end).unwrap();
|
writeln!(end).unwrap();
|
||||||
// .size is ignored for function symbols, so we can skip it
|
// .size is ignored for function symbols, so we can skip it
|
||||||
|
@ -299,7 +306,7 @@ fn prefix_and_suffix<'tcx>(
|
||||||
/// The webassembly type signature for the given function.
|
/// The webassembly type signature for the given function.
|
||||||
///
|
///
|
||||||
/// Used by the `.functype` directive on wasm targets.
|
/// Used by the `.functype` directive on wasm targets.
|
||||||
fn wasm_functype<'tcx>(tcx: TyCtxt<'tcx>, fn_abi: &FnAbi<'tcx, Ty<'tcx>>) -> String {
|
fn wasm_functype<'tcx>(tcx: TyCtxt<'tcx>, fn_abi: &FnAbi<'tcx, Ty<'tcx>>, def_id: DefId) -> String {
|
||||||
let mut signature = String::with_capacity(64);
|
let mut signature = String::with_capacity(64);
|
||||||
|
|
||||||
let ptr_type = match tcx.data_layout.pointer_size.bits() {
|
let ptr_type = match tcx.data_layout.pointer_size.bits() {
|
||||||
|
@ -308,8 +315,18 @@ fn wasm_functype<'tcx>(tcx: TyCtxt<'tcx>, fn_abi: &FnAbi<'tcx, Ty<'tcx>>) -> Str
|
||||||
other => bug!("wasm pointer size cannot be {other} bits"),
|
other => bug!("wasm pointer size cannot be {other} bits"),
|
||||||
};
|
};
|
||||||
|
|
||||||
let hidden_return =
|
// FIXME: remove this once the wasm32-unknown-unknown ABI is fixed
|
||||||
matches!(fn_abi.ret.mode, PassMode::Indirect { .. } | PassMode::Pair { .. });
|
// please also add `wasm32-unknown-unknown` back in `tests/assembly/wasm32-naked-fn.rs`
|
||||||
|
// basically the commit introducing this comment should be reverted
|
||||||
|
if let PassMode::Pair { .. } = fn_abi.ret.mode {
|
||||||
|
let _ = WasmCAbi::Legacy;
|
||||||
|
span_bug!(
|
||||||
|
tcx.def_span(def_id),
|
||||||
|
"cannot return a pair (the wasm32-unknown-unknown ABI is broken, see https://github.com/rust-lang/rust/issues/115666"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let hidden_return = matches!(fn_abi.ret.mode, PassMode::Indirect { .. });
|
||||||
|
|
||||||
signature.push('(');
|
signature.push('(');
|
||||||
|
|
||||||
|
@ -322,7 +339,7 @@ fn wasm_functype<'tcx>(tcx: TyCtxt<'tcx>, fn_abi: &FnAbi<'tcx, Ty<'tcx>>) -> Str
|
||||||
|
|
||||||
let mut it = fn_abi.args.iter().peekable();
|
let mut it = fn_abi.args.iter().peekable();
|
||||||
while let Some(arg_abi) = it.next() {
|
while let Some(arg_abi) = it.next() {
|
||||||
wasm_type(&mut signature, arg_abi, ptr_type);
|
wasm_type(tcx, &mut signature, arg_abi, ptr_type, def_id);
|
||||||
if it.peek().is_some() {
|
if it.peek().is_some() {
|
||||||
signature.push_str(", ");
|
signature.push_str(", ");
|
||||||
}
|
}
|
||||||
|
@ -331,7 +348,7 @@ fn wasm_functype<'tcx>(tcx: TyCtxt<'tcx>, fn_abi: &FnAbi<'tcx, Ty<'tcx>>) -> Str
|
||||||
signature.push_str(") -> (");
|
signature.push_str(") -> (");
|
||||||
|
|
||||||
if !hidden_return {
|
if !hidden_return {
|
||||||
wasm_type(&mut signature, &fn_abi.ret, ptr_type);
|
wasm_type(tcx, &mut signature, &fn_abi.ret, ptr_type, def_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
signature.push(')');
|
signature.push(')');
|
||||||
|
@ -339,13 +356,27 @@ fn wasm_functype<'tcx>(tcx: TyCtxt<'tcx>, fn_abi: &FnAbi<'tcx, Ty<'tcx>>) -> Str
|
||||||
signature
|
signature
|
||||||
}
|
}
|
||||||
|
|
||||||
fn wasm_type<'tcx>(signature: &mut String, arg_abi: &ArgAbi<'_, Ty<'tcx>>, ptr_type: &'static str) {
|
fn wasm_type<'tcx>(
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
|
signature: &mut String,
|
||||||
|
arg_abi: &ArgAbi<'_, Ty<'tcx>>,
|
||||||
|
ptr_type: &'static str,
|
||||||
|
def_id: DefId,
|
||||||
|
) {
|
||||||
match arg_abi.mode {
|
match arg_abi.mode {
|
||||||
PassMode::Ignore => { /* do nothing */ }
|
PassMode::Ignore => { /* do nothing */ }
|
||||||
PassMode::Direct(_) => {
|
PassMode::Direct(_) => {
|
||||||
let direct_type = match arg_abi.layout.backend_repr {
|
let direct_type = match arg_abi.layout.backend_repr {
|
||||||
BackendRepr::Scalar(scalar) => wasm_primitive(scalar.primitive(), ptr_type),
|
BackendRepr::Scalar(scalar) => wasm_primitive(scalar.primitive(), ptr_type),
|
||||||
BackendRepr::Vector { .. } => "v128",
|
BackendRepr::Vector { .. } => "v128",
|
||||||
|
BackendRepr::Memory { .. } => {
|
||||||
|
// FIXME: remove this branch once the wasm32-unknown-unknown ABI is fixed
|
||||||
|
let _ = WasmCAbi::Legacy;
|
||||||
|
span_bug!(
|
||||||
|
tcx.def_span(def_id),
|
||||||
|
"cannot use memory args (the wasm32-unknown-unknown ABI is broken, see https://github.com/rust-lang/rust/issues/115666"
|
||||||
|
);
|
||||||
|
}
|
||||||
other => unreachable!("unexpected BackendRepr: {:?}", other),
|
other => unreachable!("unexpected BackendRepr: {:?}", other),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
//@ revisions: wasm32-unknown wasm64-unknown wasm32-wasip1
|
// FIXME: add wasm32-unknown when the wasm32-unknown-unknown ABI is fixed
|
||||||
|
// see https://github.com/rust-lang/rust/issues/115666
|
||||||
|
//@ revisions: wasm64-unknown wasm32-wasip1
|
||||||
//@ add-core-stubs
|
//@ add-core-stubs
|
||||||
//@ assembly-output: emit-asm
|
//@ assembly-output: emit-asm
|
||||||
//@ [wasm32-unknown] compile-flags: --target wasm32-unknown-unknown
|
|
||||||
//@ [wasm64-unknown] compile-flags: --target wasm64-unknown-unknown
|
//@ [wasm64-unknown] compile-flags: --target wasm64-unknown-unknown
|
||||||
//@ [wasm32-wasip1] compile-flags: --target wasm32-wasip1
|
//@ [wasm32-wasip1] compile-flags: --target wasm32-wasip1
|
||||||
//@ [wasm32-unknown] needs-llvm-components: webassembly
|
|
||||||
//@ [wasm64-unknown] needs-llvm-components: webassembly
|
//@ [wasm64-unknown] needs-llvm-components: webassembly
|
||||||
//@ [wasm32-wasip1] needs-llvm-components: webassembly
|
//@ [wasm32-wasip1] needs-llvm-components: webassembly
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ unsafe extern "C" fn fn_i64_i64(num: i64) -> i64 {
|
||||||
}
|
}
|
||||||
|
|
||||||
// CHECK-LABEL: fn_i128_i128:
|
// CHECK-LABEL: fn_i128_i128:
|
||||||
// wasm32-unknown,wasm32-wasip1: .functype fn_i128_i128 (i32, i64, i64) -> ()
|
// wasm32-wasip1: .functype fn_i128_i128 (i32, i64, i64) -> ()
|
||||||
// wasm64-unknown: .functype fn_i128_i128 (i64, i64, i64) -> ()
|
// wasm64-unknown: .functype fn_i128_i128 (i64, i64, i64) -> ()
|
||||||
#[allow(improper_ctypes_definitions)]
|
#[allow(improper_ctypes_definitions)]
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
@ -114,7 +114,7 @@ unsafe extern "C" fn fn_i128_i128(num: i128) -> i128 {
|
||||||
}
|
}
|
||||||
|
|
||||||
// CHECK-LABEL: fn_f128_f128:
|
// CHECK-LABEL: fn_f128_f128:
|
||||||
// wasm32-unknown,wasm32-wasip1: .functype fn_f128_f128 (i32, i64, i64) -> ()
|
// wasm32-wasip1: .functype fn_f128_f128 (i32, i64, i64) -> ()
|
||||||
// wasm64-unknown: .functype fn_f128_f128 (i64, i64, i64) -> ()
|
// wasm64-unknown: .functype fn_f128_f128 (i64, i64, i64) -> ()
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
#[naked]
|
#[naked]
|
||||||
|
@ -137,18 +137,19 @@ struct Compound {
|
||||||
|
|
||||||
// CHECK-LABEL: fn_compound_compound:
|
// CHECK-LABEL: fn_compound_compound:
|
||||||
// wasm32-wasip1: .functype fn_compound_compound (i32, i32) -> ()
|
// wasm32-wasip1: .functype fn_compound_compound (i32, i32) -> ()
|
||||||
// wasm32-unknown: .functype fn_compound_compound (i32, i32, i64) -> ()
|
|
||||||
// wasm64-unknown: .functype fn_compound_compound (i64, i64) -> ()
|
// wasm64-unknown: .functype fn_compound_compound (i64, i64) -> ()
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
#[naked]
|
#[naked]
|
||||||
unsafe extern "C" fn fn_compound_compound(_: Compound) -> Compound {
|
unsafe extern "C" fn fn_compound_compound(_: Compound) -> Compound {
|
||||||
// this is the wasm32-unknown-unknown assembly
|
// this is the wasm32-wasip1 assembly
|
||||||
naked_asm!(
|
naked_asm!(
|
||||||
"local.get 0",
|
"local.get 0",
|
||||||
"local.get 2",
|
"local.get 1",
|
||||||
|
"i64.load 8",
|
||||||
"i64.store 8",
|
"i64.store 8",
|
||||||
"local.get 0",
|
"local.get 0",
|
||||||
"local.get 1",
|
"local.get 1",
|
||||||
|
"i32.load16_u 0",
|
||||||
"i32.store16 0",
|
"i32.store16 0",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue