wasmtime_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#![no_std]
10
11cfg_if::cfg_if! {
12    if #[cfg(target_vendor = "apple")] {
13        #[macro_export]
14        macro_rules! asm_func {
15            ($name:expr, $body:expr $(, $($args:tt)*)?) => {
16                core::arch::global_asm!(
17                    concat!(
18                        ".p2align 4\n",
19                        ".private_extern _", $name, "\n",
20                        ".global _", $name, "\n",
21                        "_", $name, ":\n",
22                        $body,
23                    ),
24                    $($($args)*)?
25                );
26            };
27        }
28    } else if #[cfg(target_os = "windows")] {
29        #[macro_export]
30        macro_rules! asm_func {
31            ($name:expr, $body:expr $(, $($args:tt)*)?) => {
32                core::arch::global_asm!(
33                    concat!(
34                        ".def ", $name, "\n",
35                        ".scl 2\n",
36                        ".type 32\n",
37                        ".endef\n",
38                        ".global ", $name, "\n",
39                        ".p2align 4\n",
40                        $name, ":\n",
41                        $body
42                    ),
43                    $($($args)*)?
44                );
45            };
46        }
47    } else {
48        // Note that for now this "else" clause just assumes that everything
49        // other than macOS is ELF and has the various directives here for
50        // that.
51        cfg_if::cfg_if! {
52            if #[cfg(target_arch = "arm")] {
53                #[macro_export]
54                macro_rules! elf_func_type_header {
55                    ($name:tt) => (concat!(".type ", $name, ",%function\n"))
56                }
57            } else {
58                #[macro_export]
59                macro_rules! elf_func_type_header {
60                    ($name:tt) => (concat!(".type ", $name, ",@function\n"))
61                }
62            }
63        }
64
65        #[macro_export]
66        macro_rules! asm_func {
67            ($name:expr, $body:expr $(, $($args:tt)*)?) => {
68                core::arch::global_asm!(
69                    concat!(
70                        ".p2align 4\n",
71                        ".hidden ", $name, "\n",
72                        ".global ", $name, "\n",
73                        $crate::elf_func_type_header!($name),
74                        $name, ":\n",
75                        $body,
76                        ".size ", $name, ",.-", $name,
77                    )
78                    $(, $($args)*)?
79                );
80            };
81        }
82    }
83}