1 //! ISA-specific stack-switching routines.
2 
3 // The bodies are defined in inline assembly in the conditionally
4 // included modules below; their symbols are visible in the binary and
5 // accessed via the `extern "C"` declarations below that.
6 
7 cfg_if::cfg_if! {
8     if #[cfg(target_arch = "aarch64")] {
9         mod aarch64;
10         pub(crate) use supported::*;
11     } else if #[cfg(target_arch = "x86_64")] {
12         mod x86_64;
13         pub(crate) use supported::*;
14     } else if #[cfg(target_arch = "x86")] {
15         mod x86;
16         pub(crate) use supported::*;
17     } else if #[cfg(target_arch = "arm")] {
18         mod arm;
19         pub(crate) use supported::*;
20     } else if #[cfg(target_arch = "s390x")] {
21         // currently `global_asm!` isn't stable on s390x so this is an external
22         // assembler file built with the `build.rs`.
23         pub(crate) use supported::*;
24     } else if #[cfg(target_arch = "riscv64")]  {
25         mod riscv64;
26         pub(crate) use supported::*;
27     } else {
28         // No support for this platform. Don't fail compilation though and
29         // instead defer the error to happen at runtime when a fiber is created.
30         // Should help keep compiles working and narrows the failure to only
31         // situations that need fibers on unsupported platforms.
32         pub(crate) use unsupported::*;
33     }
34 }
35 
36 /// A helper module to get reeported above in each case that we actually have
37 /// stack-switching routines available in in line asm. The fall-through case
38 /// though reexports the `unsupported` module instead.
39 #[allow(
40     dead_code,
41     reason = "expected to have dead code in some configurations"
42 )]
43 mod supported {
44     pub const SUPPORTED_ARCH: bool = true;
45     unsafe extern "C" {
46         #[wasmtime_versioned_export_macros::versioned_link]
47         pub(crate) fn wasmtime_fiber_init(
48             top_of_stack: *mut u8,
49             entry: extern "C" fn(*mut u8, *mut u8),
50             entry_arg0: *mut u8,
51         );
52         #[wasmtime_versioned_export_macros::versioned_link]
53         pub(crate) fn wasmtime_fiber_switch(top_of_stack: *mut u8);
54         #[wasmtime_versioned_export_macros::versioned_link]
55         pub(crate) fn wasmtime_fiber_start();
56     }
57 }
58 
59 /// Helper module reexported in the fallback case above when the current host
60 /// architecture is not supported for stack switching. The `SUPPORTED_ARCH`
61 /// boolean here is set to `false` which causes `Fiber::new` to return `false`.
62 #[allow(
63     dead_code,
64     reason = "expected to have dead code in some configurations"
65 )]
66 mod unsupported {
67     pub const SUPPORTED_ARCH: bool = false;
68 
69     pub(crate) unsafe fn wasmtime_fiber_init(
70         _top_of_stack: *mut u8,
71         _entry: extern "C" fn(*mut u8, *mut u8),
72         _entry_arg0: *mut u8,
73     ) {
74         unreachable!();
75     }
76 
77     pub(crate) unsafe fn wasmtime_fiber_switch(_top_of_stack: *mut u8) {
78         unreachable!();
79     }
80 }
81