Skip to content

Commit 80babf0

Browse files
committed
wip
1 parent 755979d commit 80babf0

4 files changed

Lines changed: 165 additions & 47 deletions

File tree

crates/wasmtime/src/runtime/component/func.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,13 @@ use wasmtime_environ::component::{
2020
use crate::component::concurrent::{self, AsAccessor, PreparedCall};
2121

2222
mod host;
23+
mod witness;
2324
mod options;
2425
mod typed;
2526
pub use self::host::*;
2627
pub use self::options::*;
2728
pub use self::typed::*;
29+
pub use self::witness::*;
2830

2931
/// A WebAssembly component function which can be called.
3032
///

crates/wasmtime/src/runtime/component/func/host.rs

Lines changed: 46 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
use crate::component::concurrent;
55
#[cfg(feature = "component-model-async")]
66
use crate::component::concurrent::{Accessor, Status};
7-
use crate::component::func::{LiftContext, LowerContext};
7+
use crate::component::func::{LiftContext, LowerContext, Witness};
88
use crate::component::matching::InstanceType;
99
use crate::component::storage::{slice_to_storage, slice_to_storage_mut};
1010
use crate::component::types::ComponentFunc;
@@ -91,7 +91,7 @@ impl HostFunc {
9191
}
9292

9393
/// Equivalent for `Linker::func_wrap`
94-
pub(crate) fn func_wrap<T, F, P, R>(func: F) -> Arc<HostFunc>
94+
pub(crate) fn func_wrap<T, F, P, R>(func: F, witness: Option<Witness<T>>) -> Arc<HostFunc>
9595
where
9696
T: 'static,
9797
F: Fn(StoreContextMut<T>, P) -> Result<R> + Send + Sync + 'static,
@@ -100,15 +100,16 @@ impl HostFunc {
100100
{
101101
Self::new(
102102
Asyncness::No,
103-
StaticHostFn::<_, false>::new(move |store, params| {
104-
HostResult::Done(func(store, params))
105-
}),
103+
StaticHostFn::<_, T, false>::new(
104+
move |store, params| HostResult::Done(func(store, params)),
105+
witness,
106+
),
106107
)
107108
}
108109

109110
/// Equivalent for `Linker::func_wrap_async`
110111
#[cfg(feature = "async")]
111-
pub(crate) fn func_wrap_async<T, F, P, R>(func: F) -> Arc<HostFunc>
112+
pub(crate) fn func_wrap_async<T, F, P, R>(func: F, witness: Option<Witness<T>>) -> Arc<HostFunc>
112113
where
113114
T: 'static,
114115
F: Fn(StoreContextMut<'_, T>, P) -> Box<dyn Future<Output = Result<R>> + Send + '_>
@@ -120,19 +121,22 @@ impl HostFunc {
120121
{
121122
Self::new(
122123
Asyncness::Yes,
123-
StaticHostFn::<_, false>::new(move |store, params| {
124-
HostResult::Done(
125-
store
126-
.block_on(|store| Pin::from(func(store, params)))
127-
.and_then(|r| r),
128-
)
129-
}),
124+
StaticHostFn::<_, T, false>::new(
125+
move |store, params| {
126+
HostResult::Done(
127+
store
128+
.block_on(|store| Pin::from(func(store, params)))
129+
.and_then(|r| r),
130+
)
131+
},
132+
witness,
133+
),
130134
)
131135
}
132136

133137
/// Equivalent for `Linker::func_wrap_concurrent`
134138
#[cfg(feature = "component-model-async")]
135-
pub(crate) fn func_wrap_concurrent<T, F, P, R>(func: F) -> Arc<HostFunc>
139+
pub(crate) fn func_wrap_concurrent<T, F, P, R>(func: F, witness: Option<Witness<T>>) -> Arc<HostFunc>
136140
where
137141
T: 'static,
138142
F: Fn(&Accessor<T>, P) -> Pin<Box<dyn Future<Output = Result<R>> + Send + '_>>
@@ -145,17 +149,20 @@ impl HostFunc {
145149
let func = Arc::new(func);
146150
Self::new(
147151
Asyncness::Yes,
148-
StaticHostFn::<_, true>::new(move |store, params| {
149-
let func = func.clone();
150-
HostResult::Future(Box::pin(
151-
store.wrap_call(move |accessor| func(accessor, params)),
152-
))
153-
}),
152+
StaticHostFn::<_, T, true>::new(
153+
move |store, params| {
154+
let func = func.clone();
155+
HostResult::Future(Box::pin(
156+
store.wrap_call(move |accessor| func(accessor, params)),
157+
))
158+
},
159+
witness,
160+
),
154161
)
155162
}
156163

157164
/// Equivalent of `Linker::func_new`
158-
pub(crate) fn func_new<T, F>(func: F) -> Arc<HostFunc>
165+
pub(crate) fn func_new<T, F>(func: F, witness: Option<Witness<T>>) -> Arc<HostFunc>
159166
where
160167
T: 'static,
161168
F: Fn(StoreContextMut<'_, T>, ComponentFunc, &[Val], &mut [Val]) -> Result<()>
@@ -165,19 +172,20 @@ impl HostFunc {
165172
{
166173
Self::new(
167174
Asyncness::No,
168-
DynamicHostFn::<_, false>::new(
175+
DynamicHostFn::<_, T, false>::new(
169176
move |store, ty, mut params_and_results, result_start| {
170177
let (params, results) = params_and_results.split_at_mut(result_start);
171178
let result = func(store, ty, params, results).map(move |()| params_and_results);
172179
HostResult::Done(result)
173180
},
181+
witness,
174182
),
175183
)
176184
}
177185

178186
/// Equivalent of `Linker::func_new_async`
179187
#[cfg(feature = "async")]
180-
pub(crate) fn func_new_async<T, F>(func: F) -> Arc<HostFunc>
188+
pub(crate) fn func_new_async<T, F>(func: F, witness: Option<Witness<T>>) -> Arc<HostFunc>
181189
where
182190
T: 'static,
183191
F: for<'a> Fn(
@@ -192,7 +200,7 @@ impl HostFunc {
192200
{
193201
Self::new(
194202
Asyncness::Yes,
195-
DynamicHostFn::<_, false>::new(
203+
DynamicHostFn::<_, T, false>::new(
196204
move |store, ty, mut params_and_results, result_start| {
197205
let (params, results) = params_and_results.split_at_mut(result_start);
198206
let result = store
@@ -203,13 +211,14 @@ impl HostFunc {
203211
let result = result.map(move |()| params_and_results);
204212
HostResult::Done(result)
205213
},
214+
witness,
206215
),
207216
)
208217
}
209218

210219
/// Equivalent of `Linker::func_new_concurrent`
211220
#[cfg(feature = "component-model-async")]
212-
pub(crate) fn func_new_concurrent<T, F>(func: F) -> Arc<HostFunc>
221+
pub(crate) fn func_new_concurrent<T, F>(func: F, witness: Option<Witness<T>>) -> Arc<HostFunc>
213222
where
214223
T: 'static,
215224
F: for<'a> Fn(
@@ -225,7 +234,7 @@ impl HostFunc {
225234
let func = Arc::new(func);
226235
Self::new(
227236
Asyncness::Yes,
228-
DynamicHostFn::<_, true>::new(
237+
DynamicHostFn::<_, T, true>::new(
229238
move |store, ty, mut params_and_results, result_start| {
230239
let func = func.clone();
231240
HostResult::Future(Box::pin(store.wrap_call(move |accessor| {
@@ -236,6 +245,7 @@ impl HostFunc {
236245
})
237246
})))
238247
},
248+
witness,
239249
),
240250
)
241251
}
@@ -587,22 +597,21 @@ where
587597

588598
/// Implementation of a "static" host function where the parameters and results
589599
/// of a function are known at compile time.
590-
#[repr(transparent)]
591-
struct StaticHostFn<F, const ASYNC: bool>(F);
600+
struct StaticHostFn<F, T, const ASYNC: bool>(F, Option<Witness<T>>);
592601

593-
impl<F, const ASYNC: bool> StaticHostFn<F, ASYNC> {
594-
fn new<T, P, R>(func: F) -> Self
602+
impl<F, T, const ASYNC: bool> StaticHostFn<F, T, ASYNC> {
603+
fn new<P, R>(func: F, witness: Option<Witness<T>>) -> Self
595604
where
596605
T: 'static,
597606
P: ComponentNamedList + Lift + 'static,
598607
R: ComponentNamedList + Lower + 'static,
599608
F: Fn(StoreContextMut<'_, T>, P) -> HostResult<R>,
600609
{
601-
Self(func)
610+
Self(func, witness)
602611
}
603612
}
604613

605-
impl<T, F, P, R, const ASYNC: bool> HostFn<T, P, R> for StaticHostFn<F, ASYNC>
614+
impl<T, F, P, R, const ASYNC: bool> HostFn<T, P, R> for StaticHostFn<F, T, ASYNC>
606615
where
607616
T: 'static,
608617
F: Fn(StoreContextMut<'_, T>, P) -> HostResult<R>,
@@ -671,20 +680,20 @@ where
671680
///
672681
/// This is intended for more-dynamic use cases than `StaticHostFn` above such
673682
/// as demos, gluing things together quickly, and `wast` testing.
674-
struct DynamicHostFn<F, const ASYNC: bool>(F);
683+
struct DynamicHostFn<F, T, const ASYNC: bool>(F, Option<Witness<T>>);
675684

676-
impl<F, const ASYNC: bool> DynamicHostFn<F, ASYNC> {
677-
fn new<T>(func: F) -> Self
685+
impl<F, T, const ASYNC: bool> DynamicHostFn<F, T, ASYNC> {
686+
fn new(func: F, witness: Option<Witness<T>>) -> Self
678687
where
679688
T: 'static,
680689
F: Fn(StoreContextMut<'_, T>, ComponentFunc, Vec<Val>, usize) -> HostResult<Vec<Val>>,
681690
{
682-
Self(func)
691+
Self(func, witness)
683692
}
684693
}
685694

686695
impl<T, F, const ASYNC: bool> HostFn<T, (ComponentFunc, Vec<Val>), Vec<Val>>
687-
for DynamicHostFn<F, ASYNC>
696+
for DynamicHostFn<F, T, ASYNC>
688697
where
689698
T: 'static,
690699
F: Fn(StoreContextMut<'_, T>, ComponentFunc, Vec<Val>, usize) -> HostResult<Vec<Val>>,
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
2+
use crate::prelude::*;
3+
use core::marker::PhantomData;
4+
use alloc::sync::Arc;
5+
6+
pub struct Witness<T> {
7+
param_witness: Arc<dyn Fn(&mut T, &[String], ParamWitness<'_>) -> Result<()> + Send + Sync>,
8+
result_witness: Arc<dyn Fn(&mut T, &[String], ResultWitness<'_>) -> Result<()> + Send + Sync>,
9+
position: Arc<Vec<String>>,
10+
}
11+
impl<T> Witness<T> {
12+
pub fn new(
13+
param: impl Fn(&mut T, &[String], ParamWitness<'_>) -> Result<()> + Send + Sync + 'static,
14+
result: impl Fn(&mut T, &[String], ResultWitness<'_>) -> Result<()> + Send + Sync + 'static,
15+
) -> Self {
16+
Self {
17+
param_witness: Arc::new(param),
18+
result_witness: Arc::new(result),
19+
position: Arc::new(Vec::new()),
20+
}
21+
}
22+
pub fn in_instance(&self, name: &str) -> Self {
23+
let mut position: Vec<String> = (&*self.position).clone();
24+
position.push(name.to_owned());
25+
Self {
26+
param_witness: self.param_witness.clone(),
27+
result_witness: self.result_witness.clone(),
28+
position: Arc::new(position),
29+
}
30+
}
31+
}
32+
33+
impl<T> Clone for Witness<T> {
34+
fn clone(&self) -> Self {
35+
Self {
36+
param_witness: self.param_witness.clone(),
37+
result_witness: self.result_witness.clone(),
38+
position: self.position.clone(),
39+
}
40+
}
41+
}
42+
43+
pub struct ParamWitness<'a> {
44+
_marker: PhantomData<&'a ()>,
45+
}
46+
47+
impl<'a> ParamWitness<'a> {
48+
49+
}
50+
51+
pub struct ResultWitness<'a> {
52+
_marker: PhantomData<&'a ()>,
53+
}
54+
55+
impl<'a> ResultWitness<'a> {
56+
57+
}

0 commit comments

Comments
 (0)