Skip to main content

emscripten_rs_macros/
lib.rs

1use proc_macro::TokenStream;
2use quote::ToTokens;
3use syn::parse2;
4
5use crate::{
6    em_asm::AsmInput,
7    em_js::{InlineJsInput, JsInputs},
8};
9
10mod em_asm;
11mod em_js;
12
13#[proc_macro]
14pub fn js(input: TokenStream) -> TokenStream {
15    let tokens: proc_macro2::TokenStream = input.into();
16
17    parse2::<JsInputs>(tokens)
18        .map(ToTokens::into_token_stream)
19        .unwrap_or_else(|err| err.into_compile_error())
20        .into()
21}
22
23#[proc_macro]
24pub fn inline_js(input: TokenStream) -> TokenStream {
25    let tokens: proc_macro2::TokenStream = input.into();
26
27    parse2::<InlineJsInput>(tokens)
28        .map(ToTokens::into_token_stream)
29        .unwrap_or_else(|err| err.into_compile_error())
30        .into()
31}
32
33#[proc_macro]
34pub fn js_asm(input: TokenStream) -> TokenStream {
35    let tokens: proc_macro2::TokenStream = input.into();
36
37    parse2::<AsmInput>(tokens)
38        .map(ToTokens::into_token_stream)
39        .unwrap_or_else(|err| err.into_compile_error())
40        .into()
41}
42
43#[cfg(test)]
44mod tests {
45    use crate::JsInputs;
46    use quote::{ToTokens, quote};
47    use syn::parse2;
48
49    #[test]
50    fn simple() {
51        let input = quote! {fn f(){return 1;}
52        };
53        assert_eq!(
54            parse2::<JsInputs>(input)
55                .unwrap()
56                .into_token_stream()
57                .to_string(),
58            quote! {
59                mod _em_js_exports___em_js__f {
60                    #[used(linker)]
61                    #[unsafe(no_mangle)]
62                    #[allow(non_upper_case_globals)]
63                    static __em_js__f: [u8; 20usize] =
64                        *b"()<::>{return 1 ; }\0";
65                    std::arch::global_asm!(".globl __em_js__f");
66                }
67                #[link(wasm_import_module = "env")]
68                #[allow(dead_code)]
69                unsafe extern "C" {
70                    #[link_name = "f"]
71                    pub unsafe fn f();
72                }
73            }
74            .to_string()
75        )
76    }
77}