Skip to main content

warp_runtime/
libm.rs

1//! The libm functions programs import from "m" (`cos(x)`, `pow(x, y)` …), for a store of any state: Rust's own f64
2//! functions, so a standalone executable loads no C library (warp itself links the system's libm, ffi.rs)
3use wasmtime::{Linker, Result};
4
5pub const LIBM: &str = "m";
6type Unary = (&'static str, fn(f64) -> f64);
7type Binary = (&'static str, fn(f64, f64) -> f64);
8const UNARY: [Unary; 11] = [
9	("fabs", f64::abs),
10	("floor", f64::floor),
11	("ceil", f64::ceil),
12	("round", f64::round),
13	("sqrt", f64::sqrt),
14	("sin", f64::sin),
15	("cos", f64::cos),
16	("tan", f64::tan),
17	("exp", f64::exp),
18	("log", f64::ln),
19	("log10", f64::log10),
20];
21const BINARY: [Binary; 4] = [("fmin", f64::min), ("fmax", f64::max), ("fmod", fmod), ("pow", f64::powf)];
22
23/// C's fmod: the remainder with the sign of the dividend, which is Rust's %
24fn fmod(dividend: f64, divisor: f64) -> f64 {
25	dividend % divisor
26}
27
28pub fn link_libm<T: 'static>(linker: &mut Linker<T>) -> Result<()> {
29	for (name, function) in UNARY {
30		linker.func_wrap(LIBM, name, move |x: f64| function(x))?;
31	}
32	for (name, function) in BINARY {
33		linker.func_wrap(LIBM, name, move |x: f64, y: f64| function(x, y))?;
34	}
35	Ok(())
36}
37
38/// The names link_libm provides
39pub fn libm_names() -> impl Iterator<Item = &'static str> {
40	UNARY.iter().map(|(name, _)| *name).chain(BINARY.iter().map(|(name, _)| *name))
41}