1
1
use rustc_abi::{BackendRepr, Float, Integer, Primitive, RegKind};
2
2
use rustc_attr_parsing::InstructionSetAttr;
3
+ use rustc_hir::def_id::DefId;
3
4
use rustc_middle::mir::mono::{Linkage, MonoItem, MonoItemData, Visibility};
4
5
use rustc_middle::mir::{Body, InlineAsmOperand};
5
6
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, HasTypingEnv, LayoutOf};
6
7
use rustc_middle::ty::{Instance, Ty, TyCtxt};
7
- use rustc_middle::{bug, ty};
8
+ use rustc_middle::{bug, span_bug, ty};
8
9
use rustc_span::sym;
9
10
use rustc_target::callconv::{ArgAbi, FnAbi, PassMode};
11
+ use rustc_target::spec::WasmCAbi;
10
12
11
13
use crate::common;
12
14
use crate::traits::{AsmCodegenMethods, BuilderMethods, GlobalAsmOperandRef, MiscCodegenMethods};
@@ -285,7 +287,12 @@ fn prefix_and_suffix<'tcx>(
285
287
writeln!(begin, "{}", arch_prefix).unwrap();
286
288
}
287
289
writeln!(begin, "{asm_name}:").unwrap();
288
- writeln!(begin, ".functype {asm_name} {}", wasm_functype(tcx, fn_abi)).unwrap();
290
+ writeln!(
291
+ begin,
292
+ ".functype {asm_name} {}",
293
+ wasm_functype(tcx, fn_abi, instance.def_id())
294
+ )
295
+ .unwrap();
289
296
290
297
writeln!(end).unwrap();
291
298
// .size is ignored for function symbols, so we can skip it
@@ -299,7 +306,7 @@ fn prefix_and_suffix<'tcx>(
299
306
/// The webassembly type signature for the given function.
300
307
///
301
308
/// Used by the `.functype` directive on wasm targets.
302
- fn wasm_functype<'tcx>(tcx: TyCtxt<'tcx>, fn_abi: &FnAbi<'tcx, Ty<'tcx>>) -> String {
309
+ fn wasm_functype<'tcx>(tcx: TyCtxt<'tcx>, fn_abi: &FnAbi<'tcx, Ty<'tcx>>, def_id: DefId ) -> String {
303
310
let mut signature = String::with_capacity(64);
304
311
305
312
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
308
315
other => bug!("wasm pointer size cannot be {other} bits"),
309
316
};
310
317
311
- let hidden_return =
312
- matches!(fn_abi.ret.mode, PassMode::Indirect { .. } | PassMode::Pair { .. });
318
+ // FIXME: remove this once the wasm32-unknown-unknown ABI is fixed
319
+ // please also add `wasm32-unknown-unknown` back in `tests/assembly/wasm32-naked-fn.rs`
320
+ // basically the commit introducing this comment should be reverted
321
+ if let PassMode::Pair { .. } = fn_abi.ret.mode {
322
+ let _ = WasmCAbi::Legacy;
323
+ span_bug!(
324
+ tcx.def_span(def_id),
325
+ "cannot return a pair (the wasm32-unknown-unknown ABI is broken, see https://github.com/rust-lang/rust/issues/115666"
326
+ );
327
+ }
328
+
329
+ let hidden_return = matches!(fn_abi.ret.mode, PassMode::Indirect { .. });
313
330
314
331
signature.push('(');
315
332
@@ -322,7 +339,7 @@ fn wasm_functype<'tcx>(tcx: TyCtxt<'tcx>, fn_abi: &FnAbi<'tcx, Ty<'tcx>>) -> Str
322
339
323
340
let mut it = fn_abi.args.iter().peekable();
324
341
while let Some(arg_abi) = it.next() {
325
- wasm_type(&mut signature, arg_abi, ptr_type);
342
+ wasm_type(tcx, &mut signature, arg_abi, ptr_type, def_id );
326
343
if it.peek().is_some() {
327
344
signature.push_str(", ");
328
345
}
@@ -331,21 +348,35 @@ fn wasm_functype<'tcx>(tcx: TyCtxt<'tcx>, fn_abi: &FnAbi<'tcx, Ty<'tcx>>) -> Str
331
348
signature.push_str(") -> (");
332
349
333
350
if !hidden_return {
334
- wasm_type(&mut signature, &fn_abi.ret, ptr_type);
351
+ wasm_type(tcx, &mut signature, &fn_abi.ret, ptr_type, def_id );
335
352
}
336
353
337
354
signature.push(')');
338
355
339
356
signature
340
357
}
341
358
342
- fn wasm_type<'tcx>(signature: &mut String, arg_abi: &ArgAbi<'_, Ty<'tcx>>, ptr_type: &'static str) {
359
+ fn wasm_type<'tcx>(
360
+ tcx: TyCtxt<'tcx>,
361
+ signature: &mut String,
362
+ arg_abi: &ArgAbi<'_, Ty<'tcx>>,
363
+ ptr_type: &'static str,
364
+ def_id: DefId,
365
+ ) {
343
366
match arg_abi.mode {
344
367
PassMode::Ignore => { /* do nothing */ }
345
368
PassMode::Direct(_) => {
346
369
let direct_type = match arg_abi.layout.backend_repr {
347
370
BackendRepr::Scalar(scalar) => wasm_primitive(scalar.primitive(), ptr_type),
348
371
BackendRepr::Vector { .. } => "v128",
372
+ BackendRepr::Memory { .. } => {
373
+ // FIXME: remove this branch once the wasm32-unknown-unknown ABI is fixed
374
+ let _ = WasmCAbi::Legacy;
375
+ span_bug!(
376
+ tcx.def_span(def_id),
377
+ "cannot use memory args (the wasm32-unknown-unknown ABI is broken, see https://github.com/rust-lang/rust/issues/115666"
378
+ );
379
+ }
349
380
other => unreachable!("unexpected BackendRepr: {:?}", other),
350
381
};
351
382
0 commit comments