Browse Source

wiggle: allow disable tracing in Wiggle-generated code (#5146)

Wiggle generates code that instruments APIs with tracing code. This is
handy for diagnosing issues at runtime, but when inspecting the output
of Wiggle, it can make the generated code difficult for a human to
decipher. This change makes tracing a default but optional feature,
allowing users to avoid tracing code with commands like `cargo expand
--no-default-features`. This should be no change for current crates
depending on `wiggle`, `wiggle-macro`, and `wiggle-generate`.

review: add 'tracing' feature to wasi-common

review: switch to using macro configuration parsing

Co-authored-by: Andrew Brown <andrew.brown@intel.com>
pull/5150/head
Pat Hickey 2 years ago
committed by GitHub
parent
commit
2702619427
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      crates/wasi-common/src/snapshots/preview_1.rs
  2. 6
      crates/wiggle/generate/src/codegen_settings.rs
  3. 15
      crates/wiggle/generate/src/config.rs
  4. 36
      crates/wiggle/generate/src/funcs.rs
  5. 10
      crates/wiggle/macro/src/lib.rs

2
crates/wasi-common/src/snapshots/preview_1.rs

@ -25,7 +25,7 @@ wiggle::from_witx!({
// keeping that set the same in this macro and the wasmtime_wiggle / lucet_wiggle macros is // keeping that set the same in this macro and the wasmtime_wiggle / lucet_wiggle macros is
// tedious, and there is no cost to having a sync function be async in this case. // tedious, and there is no cost to having a sync function be async in this case.
async: *, async: *,
wasmtime: false wasmtime: false,
}); });
impl wiggle::GuestErrorType for types::Errno { impl wiggle::GuestErrorType for types::Errno {

6
crates/wiggle/generate/src/codegen_settings.rs

@ -12,6 +12,10 @@ pub struct CodegenSettings {
pub errors: ErrorTransform, pub errors: ErrorTransform,
pub async_: AsyncConf, pub async_: AsyncConf,
pub wasmtime: bool, pub wasmtime: bool,
// Disabling this feature makes it possible to remove all of the tracing
// code emitted in the Wiggle-generated code; this can be helpful while
// inspecting the code (e.g., with `cargo expand`).
pub tracing: bool,
} }
impl CodegenSettings { impl CodegenSettings {
pub fn new( pub fn new(
@ -19,12 +23,14 @@ impl CodegenSettings {
async_: &AsyncConf, async_: &AsyncConf,
doc: &Document, doc: &Document,
wasmtime: bool, wasmtime: bool,
tracing: bool,
) -> Result<Self, Error> { ) -> Result<Self, Error> {
let errors = ErrorTransform::new(error_conf, doc)?; let errors = ErrorTransform::new(error_conf, doc)?;
Ok(Self { Ok(Self {
errors, errors,
async_: async_.clone(), async_: async_.clone(),
wasmtime, wasmtime,
tracing,
}) })
} }
pub fn get_async(&self, module: &Module, func: &InterfaceFunc) -> Asyncness { pub fn get_async(&self, module: &Module, func: &InterfaceFunc) -> Asyncness {

15
crates/wiggle/generate/src/config.rs

@ -15,6 +15,7 @@ pub struct Config {
pub errors: ErrorConf, pub errors: ErrorConf,
pub async_: AsyncConf, pub async_: AsyncConf,
pub wasmtime: bool, pub wasmtime: bool,
pub tracing: bool,
} }
mod kw { mod kw {
@ -24,6 +25,7 @@ mod kw {
syn::custom_keyword!(errors); syn::custom_keyword!(errors);
syn::custom_keyword!(target); syn::custom_keyword!(target);
syn::custom_keyword!(wasmtime); syn::custom_keyword!(wasmtime);
syn::custom_keyword!(tracing);
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -32,6 +34,7 @@ pub enum ConfigField {
Error(ErrorConf), Error(ErrorConf),
Async(AsyncConf), Async(AsyncConf),
Wasmtime(bool), Wasmtime(bool),
Tracing(bool),
} }
impl Parse for ConfigField { impl Parse for ConfigField {
@ -67,6 +70,10 @@ impl Parse for ConfigField {
input.parse::<kw::wasmtime>()?; input.parse::<kw::wasmtime>()?;
input.parse::<Token![:]>()?; input.parse::<Token![:]>()?;
Ok(ConfigField::Wasmtime(input.parse::<syn::LitBool>()?.value)) Ok(ConfigField::Wasmtime(input.parse::<syn::LitBool>()?.value))
} else if lookahead.peek(kw::tracing) {
input.parse::<kw::tracing>()?;
input.parse::<Token![:]>()?;
Ok(ConfigField::Tracing(input.parse::<syn::LitBool>()?.value))
} else { } else {
Err(lookahead.error()) Err(lookahead.error())
} }
@ -79,6 +86,7 @@ impl Config {
let mut errors = None; let mut errors = None;
let mut async_ = None; let mut async_ = None;
let mut wasmtime = None; let mut wasmtime = None;
let mut tracing = None;
for f in fields { for f in fields {
match f { match f {
ConfigField::Witx(c) => { ConfigField::Witx(c) => {
@ -105,6 +113,12 @@ impl Config {
} }
wasmtime = Some(c); wasmtime = Some(c);
} }
ConfigField::Tracing(c) => {
if tracing.is_some() {
return Err(Error::new(err_loc, "duplicate `tracing` field"));
}
tracing = Some(c);
}
} }
} }
Ok(Config { Ok(Config {
@ -114,6 +128,7 @@ impl Config {
errors: errors.take().unwrap_or_default(), errors: errors.take().unwrap_or_default(),
async_: async_.take().unwrap_or_default(), async_: async_.take().unwrap_or_default(),
wasmtime: wasmtime.unwrap_or(true), wasmtime: wasmtime.unwrap_or(true),
tracing: tracing.unwrap_or(true),
}) })
} }

36
crates/wiggle/generate/src/funcs.rs

@ -84,6 +84,16 @@ fn _define_func(
); );
); );
if settings.get_async(&module, &func).is_sync() { if settings.get_async(&module, &func).is_sync() {
let traced_body = if settings.tracing {
quote!(
#mk_span
_span.in_scope(|| {
#body
})
)
} else {
quote!(#body)
};
( (
quote!( quote!(
#[allow(unreachable_code)] // deals with warnings in noreturn functions #[allow(unreachable_code)] // deals with warnings in noreturn functions
@ -93,15 +103,23 @@ fn _define_func(
#(#abi_params),* #(#abi_params),*
) -> Result<#abi_ret, #rt::wasmtime_crate::Trap> { ) -> Result<#abi_ret, #rt::wasmtime_crate::Trap> {
use std::convert::TryFrom as _; use std::convert::TryFrom as _;
#mk_span #traced_body
_span.in_scope(|| {
#body
})
} }
), ),
bounds, bounds,
) )
} else { } else {
let traced_body = if settings.tracing {
quote!(
use #rt::tracing::Instrument as _;
#mk_span
async move {
#body
}.instrument(_span)
)
} else {
quote!(#body)
};
( (
quote!( quote!(
#[allow(unreachable_code)] // deals with warnings in noreturn functions #[allow(unreachable_code)] // deals with warnings in noreturn functions
@ -111,11 +129,7 @@ fn _define_func(
#(#abi_params),* #(#abi_params),*
) -> impl std::future::Future<Output = Result<#abi_ret, #rt::wasmtime_crate::Trap>> + 'a { ) -> impl std::future::Future<Output = Result<#abi_ret, #rt::wasmtime_crate::Trap>> + 'a {
use std::convert::TryFrom as _; use std::convert::TryFrom as _;
use #rt::tracing::Instrument as _; #traced_body
#mk_span
async move {
#body
}.instrument(_span)
} }
), ),
bounds, bounds,
@ -243,7 +257,7 @@ impl witx::Bindgen for Rust<'_> {
args.push(quote!(#name)); args.push(quote!(#name));
} }
} }
if func.params.len() > 0 { if self.settings.tracing && func.params.len() > 0 {
let args = func let args = func
.params .params
.iter() .iter()
@ -272,12 +286,14 @@ impl witx::Bindgen for Rust<'_> {
let ret = #trait_name::#ident(ctx, #(#args),*).await; let ret = #trait_name::#ident(ctx, #(#args),*).await;
}) })
}; };
if self.settings.tracing {
self.src.extend(quote! { self.src.extend(quote! {
#rt::tracing::event!( #rt::tracing::event!(
#rt::tracing::Level::TRACE, #rt::tracing::Level::TRACE,
result = #rt::tracing::field::debug(&ret), result = #rt::tracing::field::debug(&ret),
); );
}); });
}
if func.results.len() > 0 { if func.results.len() > 0 {
results.push(quote!(ret)); results.push(quote!(ret));

10
crates/wiggle/macro/src/lib.rs

@ -153,6 +153,7 @@ pub fn from_witx(args: TokenStream) -> TokenStream {
&config.async_, &config.async_,
&doc, &doc,
config.wasmtime, config.wasmtime,
config.tracing,
) )
.expect("validating codegen settings"); .expect("validating codegen settings");
@ -189,8 +190,13 @@ pub fn wasmtime_integration(args: TokenStream) -> TokenStream {
let doc = config.c.load_document(); let doc = config.c.load_document();
let names = wiggle_generate::Names::new(quote!(wiggle)); let names = wiggle_generate::Names::new(quote!(wiggle));
let settings = let settings = wiggle_generate::CodegenSettings::new(
wiggle_generate::CodegenSettings::new(&config.c.errors, &config.c.async_, &doc, true) &config.c.errors,
&config.c.async_,
&doc,
true,
config.c.tracing,
)
.expect("validating codegen settings"); .expect("validating codegen settings");
let modules = doc.modules().map(|module| { let modules = doc.modules().map(|module| {

Loading…
Cancel
Save