Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/pulley/macros/src/interp_disable_if_cfg.rs
1692 views
1
use proc_macro::TokenStream;
2
use quote::{ToTokens, TokenStreamExt, quote};
3
use syn::{
4
Attribute, Result, Signature, Visibility, braced,
5
parse::{Parse, ParseStream},
6
parse_macro_input, token,
7
};
8
9
pub fn run(attrs: TokenStream, item: TokenStream) -> TokenStream {
10
let mut cfg = None;
11
12
let config_parser = syn::meta::parser(|meta| {
13
cfg = Some(meta.path.require_ident()?.clone());
14
Ok(())
15
});
16
17
parse_macro_input!(attrs with config_parser);
18
19
match expand(cfg.unwrap(), parse_macro_input!(item as Fn)) {
20
Ok(tok) => tok,
21
Err(e) => e.into_compile_error().into(),
22
}
23
}
24
25
/// Custom function parser.
26
/// Parses the function's attributes, visibility and signature, leaving the
27
/// block as an opaque [`TokenStream`].
28
struct Fn {
29
attrs: Vec<Attribute>,
30
visibility: Visibility,
31
sig: Signature,
32
body: Block,
33
}
34
35
impl Parse for Fn {
36
fn parse(input: ParseStream) -> Result<Self> {
37
let attrs = input.call(Attribute::parse_outer)?;
38
let visibility: Visibility = input.parse()?;
39
let sig: Signature = input.parse()?;
40
let body: Block = input.parse()?;
41
42
Ok(Self {
43
attrs,
44
visibility,
45
sig,
46
body,
47
})
48
}
49
}
50
51
impl ToTokens for Fn {
52
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
53
for attr in &self.attrs {
54
attr.to_tokens(tokens);
55
}
56
self.visibility.to_tokens(tokens);
57
self.sig.to_tokens(tokens);
58
self.body.to_tokens(tokens);
59
}
60
}
61
62
/// A generic function body represented as a braced [`TokenStream`].
63
struct Block {
64
brace: token::Brace,
65
rest: proc_macro2::TokenStream,
66
}
67
68
impl Parse for Block {
69
fn parse(input: ParseStream) -> Result<Self> {
70
let content;
71
Ok(Self {
72
brace: braced!(content in input),
73
rest: content.parse()?,
74
})
75
}
76
}
77
78
impl ToTokens for Block {
79
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
80
self.brace.surround(tokens, |tokens| {
81
tokens.append_all(self.rest.clone());
82
});
83
}
84
}
85
86
fn expand(cfg: syn::Ident, func: Fn) -> Result<TokenStream> {
87
let Fn {
88
attrs,
89
visibility,
90
sig,
91
body: _,
92
} = &func;
93
let name = &sig.ident;
94
Ok(quote! {
95
#[cfg(#cfg)]
96
#(#attrs)*
97
#[allow(unused_variables)]
98
#visibility #sig {
99
self.done_trap_kind::<crate::#name>(Some(TrapKind::DisabledOpcode))
100
}
101
102
#[cfg(not(#cfg))]
103
#func
104
}
105
.into())
106
}
107
108