11use rustc_abi:: { BackendRepr , Float , Integer , Primitive , RegKind } ;
22use rustc_attr_parsing:: InstructionSetAttr ;
3+ use rustc_hir:: def_id:: DefId ;
34use rustc_middle:: mir:: mono:: { Linkage , MonoItem , MonoItemData , Visibility } ;
45use rustc_middle:: mir:: { Body , InlineAsmOperand } ;
56use rustc_middle:: ty:: layout:: { FnAbiOf , HasTyCtxt , HasTypingEnv , LayoutOf } ;
67use rustc_middle:: ty:: { Instance , Ty , TyCtxt } ;
7- use rustc_middle:: { bug, ty} ;
8+ use rustc_middle:: { bug, span_bug , ty} ;
89use rustc_span:: sym;
910use rustc_target:: callconv:: { ArgAbi , FnAbi , PassMode } ;
11+ use rustc_target:: spec:: WasmCAbi ;
1012
1113use crate :: common;
1214use crate :: traits:: { AsmCodegenMethods , BuilderMethods , GlobalAsmOperandRef , MiscCodegenMethods } ;
@@ -285,7 +287,12 @@ fn prefix_and_suffix<'tcx>(
285287 writeln ! ( begin, "{}" , arch_prefix) . unwrap ( ) ;
286288 }
287289 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 ( ) ;
289296
290297 writeln ! ( end) . unwrap ( ) ;
291298 // .size is ignored for function symbols, so we can skip it
@@ -299,7 +306,7 @@ fn prefix_and_suffix<'tcx>(
299306/// The webassembly type signature for the given function.
300307///
301308/// 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 {
303310 let mut signature = String :: with_capacity ( 64 ) ;
304311
305312 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
308315 other => bug ! ( "wasm pointer size cannot be {other} bits" ) ,
309316 } ;
310317
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 { .. } ) ;
313330
314331 signature. push ( '(' ) ;
315332
@@ -322,7 +339,7 @@ fn wasm_functype<'tcx>(tcx: TyCtxt<'tcx>, fn_abi: &FnAbi<'tcx, Ty<'tcx>>) -> Str
322339
323340 let mut it = fn_abi. args . iter ( ) . peekable ( ) ;
324341 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 ) ;
326343 if it. peek ( ) . is_some ( ) {
327344 signature. push_str ( ", " ) ;
328345 }
@@ -331,21 +348,35 @@ fn wasm_functype<'tcx>(tcx: TyCtxt<'tcx>, fn_abi: &FnAbi<'tcx, Ty<'tcx>>) -> Str
331348 signature. push_str ( ") -> (" ) ;
332349
333350 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 ) ;
335352 }
336353
337354 signature. push ( ')' ) ;
338355
339356 signature
340357}
341358
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+ ) {
343366 match arg_abi. mode {
344367 PassMode :: Ignore => { /* do nothing */ }
345368 PassMode :: Direct ( _) => {
346369 let direct_type = match arg_abi. layout . backend_repr {
347370 BackendRepr :: Scalar ( scalar) => wasm_primitive ( scalar. primitive ( ) , ptr_type) ,
348371 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+ }
349380 other => unreachable ! ( "unexpected BackendRepr: {:?}" , other) ,
350381 } ;
351382
0 commit comments