Skip to main content

emscripten_rs_macros/
lib.rs

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