Skip to main content

wasmer/entities/function/host/
imp.rs

1use crate::{
2    AsStoreMut, AsStoreRef, BackendFunctionEnv, BackendFunctionEnvMut, FunctionEnvMut,
3    FunctionType, HostFunction, RuntimeError, StoreInner, StoreMut, StoreRef, Value, WithEnv,
4    WithoutEnv,
5    utils::{FromToNativeWasmType, IntoResult, NativeWasmTypeInto, WasmTypeList},
6};
7
8use std::panic::{self, AssertUnwindSafe};
9use std::{cell::UnsafeCell, cmp::max, ffi::c_void};
10use wasmer_types::{NativeWasmType, RawValue};
11
12macro_rules! impl_host_function {
13    ([$c_struct_representation:ident] $c_struct_name:ident, $( $x:ident ),* ) => {
14        #[allow(unused_parens)]
15        impl< $( $x, )* Rets, RetsAsResult, T, Func> crate::HostFunction<T, ( $( $x ),* ), Rets, WithEnv> for Func where
16            $( $x: FromToNativeWasmType, )*
17            Rets: WasmTypeList,
18            RetsAsResult: IntoResult<Rets>,
19            T: Send + 'static,
20            Func: Fn(FunctionEnvMut<'_, T>, $( $x , )*) -> RetsAsResult + 'static,
21        {
22            #[allow(non_snake_case)]
23            fn function_callback(&self, rt: crate::backend::BackendKind) -> crate::vm::VMFunctionCallback {
24                paste::paste! {
25                    match rt {
26                        #[cfg(feature = "sys")]
27                        crate::backend::BackendKind::Headless => crate::vm::VMFunctionCallback::Sys(crate::backend::sys::function::[<gen_fn_callback_ $c_struct_name:lower >](self)),
28                        #[cfg(feature = "llvm")]
29                        crate::backend::BackendKind::LLVM => crate::vm::VMFunctionCallback::Sys(crate::backend::sys::function::[<gen_fn_callback_ $c_struct_name:lower >](self)),
30                        #[cfg(feature = "cranelift")]
31                        crate::backend::BackendKind::Cranelift => crate::vm::VMFunctionCallback::Sys(crate::backend::sys::function::[<gen_fn_callback_ $c_struct_name:lower >](self)),
32                        #[cfg(feature = "singlepass")]
33                        crate::backend::BackendKind::Singlepass => crate::vm::VMFunctionCallback::Sys(crate::backend::sys::function::[<gen_fn_callback_ $c_struct_name:lower >](self)),
34                        #[cfg(feature = "js")]
35                        crate::backend::BackendKind::Js => crate::vm::VMFunctionCallback::Js(crate::backend::js::function::[<gen_fn_callback_ $c_struct_name:lower >](self)),
36                        #[cfg(feature = "v8")]
37                        crate::backend::BackendKind::V8 => crate::vm::VMFunctionCallback::V8(crate::backend::v8::function::[<gen_fn_callback_ $c_struct_name:lower >](self))
38                    }
39                }
40            }
41
42            #[cfg(feature = "sys")]
43            fn function_callback_sys(&self) -> crate::vm::VMFunctionCallback {
44                paste::paste! {
45                    crate::vm::VMFunctionCallback::Sys(crate::backend::sys::function::[<gen_fn_callback_ $c_struct_name:lower >](self))
46                }
47            }
48
49            #[allow(non_snake_case)]
50            fn call_trampoline_address() -> crate::vm::VMTrampoline {
51                paste::paste! {
52                    #[cfg(feature = "sys")]
53                    {
54                        crate::vm::VMTrampoline::Sys(crate::backend::sys::function::[<gen_call_trampoline_address_ $c_struct_name:lower >]::<$($x,)* Rets>())
55                    }
56
57                    #[cfg(not(feature = "sys"))]
58                    {
59                        unimplemented!("No backend available")
60                    }
61                }
62            }
63        }
64
65        // Implement `HostFunction` for a function that has the same arity than the tuple.
66        #[allow(unused_parens)]
67        impl< $( $x, )* Rets, RetsAsResult, Func >
68            crate::HostFunction<(), ( $( $x ),* ), Rets, WithoutEnv>
69        for
70            Func
71        where
72            $( $x: FromToNativeWasmType, )*
73            Rets: WasmTypeList,
74            RetsAsResult: IntoResult<Rets>,
75            Func: Fn($( $x , )*) -> RetsAsResult + 'static
76        {
77            #[allow(non_snake_case)]
78            fn function_callback(&self, rt: crate::backend::BackendKind) -> crate::vm::VMFunctionCallback {
79                paste::paste! {
80                    match rt {
81                        #[cfg(feature = "sys")]
82                        crate::backend::BackendKind::Headless => crate::vm::VMFunctionCallback::Sys(crate::backend::sys::function::[<gen_fn_callback_ $c_struct_name:lower _no_env>](self)),
83                        #[cfg(feature = "llvm")]
84                        crate::backend::BackendKind::LLVM => crate::vm::VMFunctionCallback::Sys(crate::backend::sys::function::[<gen_fn_callback_ $c_struct_name:lower _no_env>](self)),
85                        #[cfg(feature = "cranelift")]
86                        crate::backend::BackendKind::Cranelift => crate::vm::VMFunctionCallback::Sys(crate::backend::sys::function::[<gen_fn_callback_ $c_struct_name:lower _no_env>](self)),
87                        #[cfg(feature = "singlepass")]
88                        crate::backend::BackendKind::Singlepass => crate::vm::VMFunctionCallback::Sys(crate::backend::sys::function::[<gen_fn_callback_ $c_struct_name:lower _no_env>](self)),
89                        #[cfg(feature = "js")]
90                        crate::backend::BackendKind::Js => crate::vm::VMFunctionCallback::Js(crate::backend::js::function::[<gen_fn_callback_ $c_struct_name:lower _no_env>](self)),
91                        #[cfg(feature = "v8")]
92                        crate::backend::BackendKind::V8 => crate::vm::VMFunctionCallback::V8(crate::backend::v8::function::[<gen_fn_callback_ $c_struct_name:lower _no_env>](self))
93                    }
94                }
95            }
96
97            #[allow(non_snake_case)]
98            #[cfg(feature = "sys")]
99            fn function_callback_sys(&self) -> crate::vm::VMFunctionCallback {
100                paste::paste! {
101                    crate::vm::VMFunctionCallback::Sys(crate::backend::sys::function::[<gen_fn_callback_ $c_struct_name:lower _no_env>](self))
102                }
103            }
104
105            #[allow(non_snake_case)]
106            fn call_trampoline_address() -> crate::vm::VMTrampoline {
107                paste::paste! {
108                    #[cfg(feature = "sys")]
109                    {
110                        crate::vm::VMTrampoline::Sys(crate::backend::sys::function::[<gen_call_trampoline_address_ $c_struct_name:lower _no_env>]::<$($x,)* Rets>())
111                    }
112
113                    #[cfg(not(feature = "sys"))]
114                    {
115                        unimplemented!("No backend available")
116                    }
117                }
118            }
119        }
120    };
121}
122
123// Black-magic to count the number of identifiers at compile-time.
124macro_rules! count_idents {
125    ( $($idents:ident),* ) => {
126        {
127            #[allow(dead_code, non_camel_case_types)]
128            enum Idents { $( $idents, )* __CountIdentsLast }
129            const COUNT: usize = Idents::__CountIdentsLast as usize;
130            COUNT
131        }
132    };
133}
134
135// Here we go! Let's generate all the C struct, `WasmTypeList`
136// implementations and `HostFunction` implementations.
137impl_host_function!([C] S0,);
138impl_host_function!([transparent] S1, A1);
139impl_host_function!([C] S2, A1, A2);
140impl_host_function!([C] S3, A1, A2, A3);
141impl_host_function!([C] S4, A1, A2, A3, A4);
142impl_host_function!([C] S5, A1, A2, A3, A4, A5);
143impl_host_function!([C] S6, A1, A2, A3, A4, A5, A6);
144impl_host_function!([C] S7, A1, A2, A3, A4, A5, A6, A7);
145impl_host_function!([C] S8, A1, A2, A3, A4, A5, A6, A7, A8);
146impl_host_function!([C] S9, A1, A2, A3, A4, A5, A6, A7, A8, A9);
147impl_host_function!([C] S10, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10);
148impl_host_function!([C] S11, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11);
149impl_host_function!([C] S12, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12);
150impl_host_function!([C] S13, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13);
151impl_host_function!([C] S14, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14);
152impl_host_function!([C] S15, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15);
153impl_host_function!([C] S16, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16);
154impl_host_function!([C] S17, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17);
155impl_host_function!([C] S18, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18);
156impl_host_function!([C] S19, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19);
157impl_host_function!([C] S20, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20);
158impl_host_function!([C] S21, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21);
159impl_host_function!([C] S22, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22);
160impl_host_function!([C] S23, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23);
161impl_host_function!([C] S24, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24);
162impl_host_function!([C] S25, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24, A25);
163impl_host_function!([C] S26, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24, A25, A26);