Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/crates/wiggle/generate/src/lib.rs
1693 views
1
mod codegen_settings;
2
pub mod config;
3
mod funcs;
4
mod lifetimes;
5
mod module_trait;
6
pub mod names;
7
mod types;
8
pub mod wasmtime;
9
10
use heck::ToShoutySnakeCase;
11
use lifetimes::anon_lifetime;
12
use proc_macro2::{Literal, TokenStream};
13
use quote::quote;
14
15
pub use codegen_settings::{CodegenSettings, ErrorType, UserErrorType};
16
pub use config::{Config, WasmtimeConfig};
17
pub use funcs::define_func;
18
pub use module_trait::define_module_trait;
19
pub use types::define_datatype;
20
21
pub fn generate(doc: &witx::Document, settings: &CodegenSettings) -> TokenStream {
22
let types = doc
23
.typenames()
24
.map(|t| define_datatype(&t, settings.errors.for_name(&t)));
25
26
let constants = doc.constants().map(|c| {
27
let name = quote::format_ident!(
28
"{}_{}",
29
c.ty.as_str().to_shouty_snake_case(),
30
c.name.as_str().to_shouty_snake_case()
31
);
32
let ty = names::type_(&c.ty);
33
let value = Literal::u64_unsuffixed(c.value);
34
quote! {
35
pub const #name: #ty = #value;
36
}
37
});
38
39
let user_error_methods = settings.errors.iter().filter_map(|errtype| match errtype {
40
ErrorType::User(errtype) => {
41
let abi_typename = names::type_ref(&errtype.abi_type(), anon_lifetime());
42
let user_typename = errtype.typename();
43
let methodname = names::user_error_conversion_method(&errtype);
44
Some(quote! {
45
fn #methodname(&mut self, e: super::#user_typename)
46
-> wiggle::anyhow::Result<#abi_typename>;
47
})
48
}
49
ErrorType::Generated(_) => None,
50
});
51
let user_error_conversion = quote! {
52
pub trait UserErrorConversion {
53
#(#user_error_methods)*
54
}
55
};
56
let modules = doc.modules().map(|module| {
57
let modname = names::module(&module.name);
58
let fs = module.funcs().map(|f| define_func(&module, &f, &settings));
59
let modtrait = define_module_trait(&module, &settings);
60
let wasmtime = if settings.wasmtime {
61
crate::wasmtime::link_module(&module, None, &settings)
62
} else {
63
quote! {}
64
};
65
quote!(
66
pub mod #modname {
67
use super::types::*;
68
pub use super::types::UserErrorConversion;
69
#(#fs)*
70
71
#modtrait
72
73
#wasmtime
74
}
75
)
76
});
77
78
quote!(
79
pub mod types {
80
use std::convert::TryFrom;
81
82
#(#types)*
83
#(#constants)*
84
#user_error_conversion
85
}
86
#(#modules)*
87
)
88
}
89
90
pub fn generate_metadata(doc: &witx::Document) -> TokenStream {
91
let doc_text = &format!("{doc}");
92
quote! {
93
pub mod metadata {
94
pub const DOC_TEXT: &str = #doc_text;
95
pub fn document() -> wiggle::witx::Document {
96
wiggle::witx::parse(DOC_TEXT).unwrap()
97
}
98
}
99
}
100
}
101
102