1 use crate::Wizer;
2 use ::wasmtime::{Result, bail};
3 
4 mod info;
5 mod instrument;
6 mod parse;
7 mod rewrite;
8 mod snapshot;
9 #[cfg(feature = "wasmtime")]
10 mod wasmtime;
11 #[cfg(feature = "wasmtime")]
12 pub use wasmtime::*;
13 
14 const WIZER_INSTANCE: &str = "wasmtime:wizer/access";
15 
16 pub use self::info::ComponentContext;
17 
18 impl Wizer {
19     /// Same as [`Wizer::instrument`], except for components.
instrument_component<'a>( &self, wasm: &'a [u8], ) -> Result<(ComponentContext<'a>, Vec<u8>)>20     pub fn instrument_component<'a>(
21         &self,
22         wasm: &'a [u8],
23     ) -> Result<(ComponentContext<'a>, Vec<u8>)> {
24         // Make sure we're given valid Wasm from the get go.
25         self.wasm_validate(&wasm)?;
26 
27         let mut cx = parse::parse(wasm)?;
28         let instrumented_wasm = instrument::instrument(&mut cx)?;
29         self.debug_assert_valid_wasm(&instrumented_wasm);
30 
31         Ok((cx, instrumented_wasm))
32     }
33 
34     /// Same as [`Wizer::snapshot`], except for components.
snapshot_component( &self, mut cx: ComponentContext<'_>, instance: &mut impl ComponentInstanceState, ) -> Result<Vec<u8>>35     pub async fn snapshot_component(
36         &self,
37         mut cx: ComponentContext<'_>,
38         instance: &mut impl ComponentInstanceState,
39     ) -> Result<Vec<u8>> {
40         if !self.func_renames.is_empty() {
41             bail!("components do not support renaming functions");
42         }
43 
44         let snapshot = snapshot::snapshot(&cx, instance).await;
45         let rewritten_wasm = self.rewrite_component(&mut cx, &snapshot);
46         self.debug_assert_valid_wasm(&rewritten_wasm);
47 
48         Ok(rewritten_wasm)
49     }
50 }
51 
52 /// Trait representing the ability to invoke functions on a component to learn
53 /// about its internal state.
54 pub trait ComponentInstanceState: Send {
55     /// Looks up the exported `instance` which has `func` as an export, calls
56     /// it, and returns the `list<u8>` return type.
call_func_ret_list_u8( &mut self, instance: &str, func: &str, contents: impl FnOnce(&[u8]) + Send, ) -> impl Future<Output = ()> + Send57     fn call_func_ret_list_u8(
58         &mut self,
59         instance: &str,
60         func: &str,
61         contents: impl FnOnce(&[u8]) + Send,
62     ) -> impl Future<Output = ()> + Send;
63 
64     /// Same as [`Self::call_func_ret_list_u8`], but for the `s32` WIT type.
call_func_ret_s32(&mut self, instance: &str, func: &str) -> impl Future<Output = i32> + Send65     fn call_func_ret_s32(&mut self, instance: &str, func: &str)
66     -> impl Future<Output = i32> + Send;
67 
68     /// Same as [`Self::call_func_ret_list_u8`], but for the `s64` WIT type.
call_func_ret_s64(&mut self, instance: &str, func: &str) -> impl Future<Output = i64> + Send69     fn call_func_ret_s64(&mut self, instance: &str, func: &str)
70     -> impl Future<Output = i64> + Send;
71 
72     /// Same as [`Self::call_func_ret_list_u8`], but for the `f32` WIT type.
call_func_ret_f32(&mut self, instance: &str, func: &str) -> impl Future<Output = u32> + Send73     fn call_func_ret_f32(&mut self, instance: &str, func: &str)
74     -> impl Future<Output = u32> + Send;
75 
76     /// Same as [`Self::call_func_ret_list_u8`], but for the `f64` WIT type.
call_func_ret_f64(&mut self, instance: &str, func: &str) -> impl Future<Output = u64> + Send77     fn call_func_ret_f64(&mut self, instance: &str, func: &str)
78     -> impl Future<Output = u64> + Send;
79 }
80