From 439f566f3f73d991644b446503b5407684187ee0 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Fri, 15 Jul 2022 14:10:27 -0700 Subject: [PATCH] Split `global_asm!` helper macros out from `wasmtime-fibers` (#4454) This moves them into a new `wasmtime-asm-macros` crate that can be used not just from the `wasmtime-fibers` crate but also from other crates (e.g. we will need them in https://github.com/bytecodealliance/wasmtime/pull/4431). --- Cargo.lock | 8 ++++ crates/asm-macros/Cargo.toml | 13 +++++++ crates/asm-macros/src/lib.rs | 66 ++++++++++++++++++++++++++++++++ crates/fiber/Cargo.toml | 1 + crates/fiber/src/unix.rs | 57 --------------------------- crates/fiber/src/unix/aarch64.rs | 2 + crates/fiber/src/unix/arm.rs | 2 + crates/fiber/src/unix/x86.rs | 2 + crates/fiber/src/unix/x86_64.rs | 2 + scripts/publish.rs | 1 + 10 files changed, 97 insertions(+), 57 deletions(-) create mode 100644 crates/asm-macros/Cargo.toml create mode 100644 crates/asm-macros/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index cf4e6122a0..367d13e9a3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3339,6 +3339,13 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "wasmtime-asm-macros" +version = "0.40.0" +dependencies = [ + "cfg-if", +] + [[package]] name = "wasmtime-bench-api" version = "0.19.0" @@ -3509,6 +3516,7 @@ dependencies = [ "cc", "cfg-if", "rustix", + "wasmtime-asm-macros", "windows-sys", ] diff --git a/crates/asm-macros/Cargo.toml b/crates/asm-macros/Cargo.toml new file mode 100644 index 0000000000..2c853b00d5 --- /dev/null +++ b/crates/asm-macros/Cargo.toml @@ -0,0 +1,13 @@ +[package] +authors = ["The Wasmtime Project Developers"] +description = "Macros for defining asm functions in Wasmtime" +edition = "2021" +license = "Apache-2.0 WITH LLVM-exception" +name = "wasmtime-asm-macros" +repository = "https://github.com/bytecodealliance/wasmtime" +version = "0.40.0" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +cfg-if = "1" diff --git a/crates/asm-macros/src/lib.rs b/crates/asm-macros/src/lib.rs new file mode 100644 index 0000000000..6c9061eaf9 --- /dev/null +++ b/crates/asm-macros/src/lib.rs @@ -0,0 +1,66 @@ +//! This crate defines a macro named `asm_func!` which is suitable for +//! generating a single `global_asm!`-defined function. +//! +//! This macro takes care of platform-specific directives to get the symbol +//! attributes correct (e.g. ELF symbols get a size and are flagged as a +//! function) and additionally handles visibility across platforms. All symbols +//! should be visible to Rust but not visible externally outside of a `*.so`. + +cfg_if::cfg_if! { + if #[cfg(target_os = "macos")] { + #[macro_export] + macro_rules! asm_func { + ($name:tt, $($body:tt)*) => { + std::arch::global_asm!(concat!( + ".p2align 4\n", + ".private_extern _", $name, "\n", + ".global _", $name, "\n", + "_", $name, ":\n", + $($body)* + )); + }; + } + + #[macro_export] + macro_rules! asm_sym { + ($name:tt) => (concat!("_", $name)) + } + } else { + // Note that for now this "else" clause just assumes that everything + // other than macOS is ELF and has the various directives here for + // that. + cfg_if::cfg_if! { + if #[cfg(target_arch = "arm")] { + #[macro_export] + macro_rules! elf_func_type_header { + ($name:tt) => (concat!(".type ", $name, ",%function\n")) + } + } else { + #[macro_export] + macro_rules! elf_func_type_header { + ($name:tt) => (concat!(".type ", $name, ",@function\n")) + } + } + } + + #[macro_export] + macro_rules! asm_func { + ($name:tt, $($body:tt)*) => { + std::arch::global_asm!(concat!( + ".p2align 4\n", + ".hidden ", $name, "\n", + ".global ", $name, "\n", + $crate::elf_func_type_header!($name), + $name, ":\n", + $($body)* + ".size ", $name, ",.-", $name, + )); + }; + } + + #[macro_export] + macro_rules! asm_sym { + ($name:tt) => ($name) + } + } +} diff --git a/crates/fiber/Cargo.toml b/crates/fiber/Cargo.toml index f224489cfd..61cf5ed4f0 100644 --- a/crates/fiber/Cargo.toml +++ b/crates/fiber/Cargo.toml @@ -18,6 +18,7 @@ cfg-if = "1.0" [target.'cfg(unix)'.dependencies] rustix = { version = "0.35.6", features = ["mm", "param"] } +wasmtime-asm-macros = { version = "=0.40.0", path = "../asm-macros" } [target.'cfg(windows)'.dependencies.windows-sys] version = "0.36.1" diff --git a/crates/fiber/src/unix.rs b/crates/fiber/src/unix.rs index 9da6b564e6..571ed1be8f 100644 --- a/crates/fiber/src/unix.rs +++ b/crates/fiber/src/unix.rs @@ -177,63 +177,6 @@ impl Suspend { } } -// This macro itself generates a macro named `asm_func!` which is suitable for -// generating a single `global_asm!`-defined function. This takes care of -// platform-specific directives to get the symbol attributes correct (e.g. ELF -// symbols get a size and are flagged as a function) and additionally handles -// visibility across platforms. All symbols should be visible to Rust but not -// visible externally outside of a `*.so`. -cfg_if::cfg_if! { - if #[cfg(target_os = "macos")] { - macro_rules! asm_func { - ($name:tt, $($body:tt)*) => { - std::arch::global_asm!(concat!( - ".p2align 4\n", - ".private_extern _", $name, "\n", - ".global _", $name, "\n", - "_", $name, ":\n", - $($body)* - )); - }; - } - macro_rules! asm_sym { - ($name:tt) => (concat!("_", $name)) - } - } else { - // Note that for now this "else" clause just assumes that everything - // other than macOS is ELF and has the various directives here for - // that. - cfg_if::cfg_if! { - if #[cfg(target_arch = "arm")] { - macro_rules! elf_func_type_header { - ($name:tt) => (concat!(".type ", $name, ",%function\n")) - } - } else { - macro_rules! elf_func_type_header { - ($name:tt) => (concat!(".type ", $name, ",@function\n")) - } - } - } - - macro_rules! asm_func { - ($name:tt, $($body:tt)*) => { - std::arch::global_asm!(concat!( - ".p2align 4\n", - ".hidden ", $name, "\n", - ".global ", $name, "\n", - elf_func_type_header!($name), - $name, ":\n", - $($body)* - ".size ", $name, ",.-", $name, - )); - }; - } - macro_rules! asm_sym { - ($name:tt) => ($name) - } - } -} - cfg_if::cfg_if! { if #[cfg(target_arch = "aarch64")] { mod aarch64; diff --git a/crates/fiber/src/unix/aarch64.rs b/crates/fiber/src/unix/aarch64.rs index 92a3bfcb4d..295d99e26e 100644 --- a/crates/fiber/src/unix/aarch64.rs +++ b/crates/fiber/src/unix/aarch64.rs @@ -18,6 +18,8 @@ // `DW_CFA_AARCH64_negate_ra_state` DWARF operation (aliased with the // `.cfi_window_save` assembler directive) informs an unwinder about this +use wasmtime_asm_macros::asm_func; + cfg_if::cfg_if! { if #[cfg(target_os = "macos")] { macro_rules! cfi_window_save { () => (""); } diff --git a/crates/fiber/src/unix/arm.rs b/crates/fiber/src/unix/arm.rs index c580ef98ce..1d320fd1f8 100644 --- a/crates/fiber/src/unix/arm.rs +++ b/crates/fiber/src/unix/arm.rs @@ -8,6 +8,8 @@ // Also at this time this file is heavily based off the x86_64 file, so you'll // probably want to read that one as well. +use wasmtime_asm_macros::{asm_func, asm_sym}; + // fn(top_of_stack(%r0): *mut u8) asm_func!( "wasmtime_fiber_switch", diff --git a/crates/fiber/src/unix/x86.rs b/crates/fiber/src/unix/x86.rs index 88eb81df34..6965560d91 100644 --- a/crates/fiber/src/unix/x86.rs +++ b/crates/fiber/src/unix/x86.rs @@ -10,6 +10,8 @@ // different so the reserved space at the top of the stack is 8 bytes, not 16 // bytes. Still two pointers though. +use wasmtime_asm_macros::{asm_func, asm_sym}; + // fn(top_of_stack: *mut u8) asm_func!( "wasmtime_fiber_switch", diff --git a/crates/fiber/src/unix/x86_64.rs b/crates/fiber/src/unix/x86_64.rs index d057763a45..b7d73dc21e 100644 --- a/crates/fiber/src/unix/x86_64.rs +++ b/crates/fiber/src/unix/x86_64.rs @@ -5,6 +5,8 @@ // all the other bits. Documentation tries to reference various bits here and // there but try to make sure to read over everything before tweaking things! +use wasmtime_asm_macros::{asm_func, asm_sym}; + // fn(top_of_stack(rdi): *mut u8) asm_func!( "wasmtime_fiber_switch", diff --git a/scripts/publish.rs b/scripts/publish.rs index 292aba531c..a2b1c5b812 100644 --- a/scripts/publish.rs +++ b/scripts/publish.rs @@ -40,6 +40,7 @@ const CRATES_TO_PUBLISH: &[&str] = &[ "wiggle-generate", "wiggle-macro", // wasmtime + "wasmtime-asm-macros", "wasmtime-component-macro", "wasmtime-jit-debug", "wasmtime-fiber",