Generate trace logs in wiggle albeit behind a feature gate
This commit augments `wiggle` with trace log generation for the shims,
returned errno values, and returned values proper (if any, i.e.,
different than unit type `()`). What that means is that every syscall
will have auto-generated up to 3 traces, for instance,
```
TRACE wasi_common::wasi::wasi_snapshot_preview1 > fd_prestat_get(fd=Fd(3))
TRACE wasi_common::wasi::wasi_snapshot_preview1 > | result=(buf=Dir(PrestatDir { pr_name_len: 1 }))
TRACE wasi_common::wasi::wasi_snapshot_preview1 > | errno=No error occurred. System call completed successfully. (Errno::Success(0))
```
Putting logging behind a feature gate in this case means that the log calls
are generated by the `wiggle` crate regardless if the client requested
the feature or not, however, then their usage in the client lib is
dictated by the presence of the feature flag. So, for instance, `wasi-common`
has this feature enabled by default, while any other client lib
using `wiggle` if they don't want tracing enabled, they will just
leave the feature off. I'm not sure if this is what we wanted
but seemed easiest to implement quickly. Lemme y'all know your thoughts
about this!
This commit is contained in:
@@ -38,9 +38,17 @@ pub fn define_func(names: &Names, func: &witx::InterfaceFunc) -> TokenStream {
|
||||
};
|
||||
|
||||
let err_type = coretype.ret.map(|ret| ret.param.tref);
|
||||
let err_val = err_type
|
||||
let ret_err = err_type
|
||||
.clone()
|
||||
.map(|_res| quote!(#abi_ret::from(e)))
|
||||
.map(|_res| {
|
||||
quote! {
|
||||
#[cfg(feature = "trace_log")]
|
||||
{
|
||||
log::trace!(" | errno={}", e);
|
||||
}
|
||||
return #abi_ret::from(e);
|
||||
}
|
||||
})
|
||||
.unwrap_or_else(|| quote!(()));
|
||||
|
||||
let error_handling = |location: &str| -> TokenStream {
|
||||
@@ -78,13 +86,39 @@ pub fn define_func(names: &Names, func: &witx::InterfaceFunc) -> TokenStream {
|
||||
let (trait_rets, trait_bindings) = if func.results.len() < 2 {
|
||||
(quote!({}), quote!(_))
|
||||
} else {
|
||||
let trait_rets = func
|
||||
let trait_rets: Vec<_> = func
|
||||
.results
|
||||
.iter()
|
||||
.skip(1)
|
||||
.map(|result| names.func_param(&result.name));
|
||||
let tuple = quote!((#(#trait_rets),*));
|
||||
(tuple.clone(), tuple)
|
||||
.map(|result| names.func_param(&result.name))
|
||||
.collect();
|
||||
let bindings = quote!((#(#trait_rets),*));
|
||||
let names: Vec<_> = func
|
||||
.results
|
||||
.iter()
|
||||
.skip(1)
|
||||
.map(|result| {
|
||||
let name = names.func_param(&result.name);
|
||||
let fmt = match &*result.tref.type_() {
|
||||
witx::Type::Builtin(_)
|
||||
| witx::Type::Enum(_)
|
||||
| witx::Type::Flags(_)
|
||||
| witx::Type::Handle(_)
|
||||
| witx::Type::Int(_) => "{}",
|
||||
_ => "{:?}",
|
||||
};
|
||||
format!("{}={}", name.to_string(), fmt)
|
||||
})
|
||||
.collect();
|
||||
let trace_fmt = format!(" | result=({})", names.join(","));
|
||||
let rets = quote! {
|
||||
#[cfg(feature = "trace_log")]
|
||||
{
|
||||
log::trace!(#trace_fmt, #(#trait_rets),*);
|
||||
}
|
||||
(#(#trait_rets),*)
|
||||
};
|
||||
(rets, bindings)
|
||||
};
|
||||
|
||||
// Return value pointers need to be validated before the api call, then
|
||||
@@ -101,18 +135,40 @@ pub fn define_func(names: &Names, func: &witx::InterfaceFunc) -> TokenStream {
|
||||
let err_typename = names.type_ref(&err_type, anon_lifetime());
|
||||
quote! {
|
||||
let success:#err_typename = wiggle::GuestErrorType::success();
|
||||
#[cfg(feature = "trace_log")]
|
||||
{
|
||||
log::trace!(" | errno={}", success);
|
||||
}
|
||||
#abi_ret::from(success)
|
||||
}
|
||||
} else {
|
||||
quote!()
|
||||
};
|
||||
|
||||
let (placeholders, args): (Vec<_>, Vec<_>) = func
|
||||
.params
|
||||
.iter()
|
||||
.map(|param| {
|
||||
let name = names.func_param(¶m.name);
|
||||
let fmt = if passed_by_reference(&*param.tref.type_()) {
|
||||
"{:?}"
|
||||
} else {
|
||||
"{}"
|
||||
};
|
||||
(format!("{}={}", name.to_string(), fmt), quote!(#name))
|
||||
})
|
||||
.unzip();
|
||||
let trace_fmt = format!("{}({})", ident.to_string(), placeholders.join(","));
|
||||
quote!(pub fn #ident(#abi_args) -> #abi_ret {
|
||||
#(#marshal_args)*
|
||||
#(#marshal_rets_pre)*
|
||||
#[cfg(feature = "trace_log")]
|
||||
{
|
||||
log::trace!(#trace_fmt, #(#args),*);
|
||||
}
|
||||
let #trait_bindings = match ctx.#ident(#(#trait_args),*) {
|
||||
Ok(#trait_bindings) => #trait_rets,
|
||||
Err(e) => { return #err_val; },
|
||||
Ok(#trait_bindings) => { #trait_rets },
|
||||
Err(e) => { #ret_err },
|
||||
};
|
||||
#(#marshal_rets_post)*
|
||||
#success
|
||||
|
||||
Reference in New Issue
Block a user