1 | // borrowed from https://github.com/neon-bindings/neon/tree/main/crates/neon/src/sys/bindings |
2 | |
3 | #![allow (ambiguous_glob_reexports)] |
4 | |
5 | #[cfg (any(windows, feature = "dyn-symbols" ))] |
6 | macro_rules! generate { |
7 | (extern "C" { |
8 | $(fn $name:ident($($param:ident: $ptype:ty$(,)?)*)$( -> $rtype:ty)?;)+ |
9 | }) => { |
10 | struct Napi { |
11 | $( |
12 | $name: unsafe extern "C" fn( |
13 | $($param: $ptype,)* |
14 | )$( -> $rtype)*, |
15 | )* |
16 | } |
17 | |
18 | #[inline(never)] |
19 | fn panic_load<T>() -> T { |
20 | panic!("Node-API symbol has not been loaded" ) |
21 | } |
22 | |
23 | static mut NAPI: Napi = { |
24 | $( |
25 | unsafe extern "C" fn $name($(_: $ptype,)*)$( -> $rtype)* { |
26 | panic_load() |
27 | } |
28 | )* |
29 | |
30 | Napi { |
31 | $( |
32 | $name, |
33 | )* |
34 | } |
35 | }; |
36 | |
37 | #[allow(clippy::missing_safety_doc)] |
38 | pub unsafe fn load( |
39 | host: &libloading::Library, |
40 | ) -> Result<(), libloading::Error> { |
41 | NAPI = Napi { |
42 | $( |
43 | $name: { |
44 | let symbol: Result<libloading::Symbol<unsafe extern "C" fn ($(_: $ptype,)*)$( -> $rtype)*>, libloading::Error> = host.get(stringify!($name).as_bytes()); |
45 | match symbol { |
46 | Ok(f) => *f, |
47 | Err(e) => { |
48 | #[cfg(debug_assertions)] { |
49 | eprintln!("Load Node-API [{}] from host runtime failed: {}" , stringify!($name), e); |
50 | } |
51 | NAPI.$name |
52 | } |
53 | } |
54 | }, |
55 | )* |
56 | }; |
57 | |
58 | Ok(()) |
59 | } |
60 | |
61 | $( |
62 | #[inline] |
63 | #[allow(clippy::missing_safety_doc)] |
64 | pub unsafe fn $name($($param: $ptype,)*)$( -> $rtype)* { |
65 | (NAPI.$name)($($param,)*) |
66 | } |
67 | )* |
68 | }; |
69 | } |
70 | |
71 | #[cfg (not(any(windows, feature = "dyn-symbols" )))] |
72 | macro_rules! generate { |
73 | (extern "C" { |
74 | $(fn $name:ident($($param:ident: $ptype:ty$(,)?)*)$( -> $rtype:ty)?;)+ |
75 | }) => { |
76 | extern "C" { |
77 | $( |
78 | pub fn $name($($param: $ptype,)*)$( -> $rtype)*; |
79 | ) * |
80 | } |
81 | }; |
82 | } |
83 | |
84 | mod functions; |
85 | mod types; |
86 | |
87 | pub use functions::*; |
88 | pub use types::*; |
89 | |
90 | /// Loads N-API symbols from host process. |
91 | /// Must be called at least once before using any functions in bindings or |
92 | /// they will panic. |
93 | /// Safety: `env` must be a valid `napi_env` for the current thread |
94 | #[cfg (any(windows, feature = "dyn-symbols" ))] |
95 | #[allow (clippy::missing_safety_doc)] |
96 | pub unsafe fn setup() -> libloading::Library { |
97 | match load_all() { |
98 | Err(err) => panic!("{}" , err), |
99 | Ok(l) => l, |
100 | } |
101 | } |
102 | |