wasmtime_internal_asm_macros/
lib.rs

1//! This crate defines a macro named `asm_func!` which is suitable for
2//! generating a single `global_asm!`-defined function.
3//!
4//! This macro takes care of platform-specific directives to get the symbol
5//! attributes correct (e.g. ELF symbols get a size and are flagged as a
6//! function) and additionally handles visibility across platforms. All symbols
7//! should be visible to Rust but not visible externally outside of a `*.so`.
8//!
9//! > **⚠️ Warning ⚠️**: this crate is an internal-only crate for the Wasmtime
10//! > project and is not intended for general use. APIs are not strictly
11//! > reviewed for safety and usage outside of Wasmtime may have bugs. If
12//! > you're interested in using this feel free to file an issue on the
13//! > Wasmtime repository to start a discussion about doing so, but otherwise
14//! > be aware that your usage of this crate is not supported.
15
16#![no_std]
17
18cfg_if::cfg_if! {
19    if #[cfg(target_vendor = "apple")] {
20        #[macro_export]
21        macro_rules! asm_func {
22            ($name:expr, $body:expr $(, $($args:tt)*)?) => {
23                core::arch::global_asm!(
24                    concat!(
25                        ".p2align 4\n",
26                        ".private_extern _", $name, "\n",
27                        ".global _", $name, "\n",
28                        "_", $name, ":\n",
29                        $body,
30                    ),
31                    $($($args)*)?
32                );
33            };
34        }
35    } else if #[cfg(target_os = "windows")] {
36        #[macro_export]
37        macro_rules! asm_func {
38            ($name:expr, $body:expr $(, $($args:tt)*)?) => {
39                core::arch::global_asm!(
40                    concat!(
41                        ".def ", $name, "\n",
42                        ".scl 2\n",
43                        ".type 32\n",
44                        ".endef\n",
45                        ".global ", $name, "\n",
46                        ".p2align 4\n",
47                        $name, ":\n",
48                        $body
49                    ),
50                    $($($args)*)?
51                );
52            };
53        }
54    } else {
55        // Note that for now this "else" clause just assumes that everything
56        // other than macOS is ELF and has the various directives here for
57        // that.
58        cfg_if::cfg_if! {
59            if #[cfg(target_arch = "arm")] {
60                #[macro_export]
61                macro_rules! elf_func_type_header {
62                    ($name:tt) => (concat!(".type ", $name, ",%function\n"))
63                }
64            } else {
65                #[macro_export]
66                macro_rules! elf_func_type_header {
67                    ($name:tt) => (concat!(".type ", $name, ",@function\n"))
68                }
69            }
70        }
71
72        #[macro_export]
73        macro_rules! asm_func {
74            ($name:expr, $body:expr $(, $($args:tt)*)?) => {
75                core::arch::global_asm!(
76                    concat!(
77                        ".p2align 4\n",
78                        ".hidden ", $name, "\n",
79                        ".global ", $name, "\n",
80                        $crate::elf_func_type_header!($name),
81                        $name, ":\n",
82                        $body,
83                        ".size ", $name, ",.-", $name,
84                    )
85                    $(, $($args)*)?
86                );
87            };
88        }
89    }
90}