emscripten_rs_macros/
lib.rs1#![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}