Skip to content

Commit 005adbf

Browse files
committed
Refactor how InitContext works with factors
This commit is a refactoring to replace the concrete `InitContext` structure with a generic type parameter instead. The motivation for this is to prepare for handling bytecodealliance/wasmtime#10770. That's a big change to how `add_to_linker` functions work, notably that the argument to the generated functions is a `fn`, not a `F: Fn`. WASI factors currently rely on the closure-like nature this argument which means it's not compatible with that change. The refactoring to use a `trait InitContext` here enables plumbing a type parameter through a function to be able to get a function pointer without relying on closures.
1 parent 4223521 commit 005adbf

File tree

18 files changed

+201
-158
lines changed

18 files changed

+201
-158
lines changed

crates/factor-key-value/src/lib.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,10 @@ impl Factor for KeyValueFactor {
3838
type AppState = AppState;
3939
type InstanceBuilder = InstanceBuilder;
4040

41-
fn init<T: Send + 'static>(&mut self, mut ctx: InitContext<T, Self>) -> anyhow::Result<()> {
41+
fn init<C>(&mut self, ctx: &mut C) -> anyhow::Result<()>
42+
where
43+
C: InitContext<Self>,
44+
{
4245
ctx.link_bindings(spin_world::v1::key_value::add_to_linker)?;
4346
ctx.link_bindings(spin_world::v2::key_value::add_to_linker)?;
4447
ctx.link_bindings(spin_world::wasi::keyvalue::store::add_to_linker)?;

crates/factor-llm/src/lib.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,10 @@ impl Factor for LlmFactor {
3636
type AppState = AppState;
3737
type InstanceBuilder = InstanceState;
3838

39-
fn init<T: Send + 'static>(
40-
&mut self,
41-
mut ctx: spin_factors::InitContext<T, Self>,
42-
) -> anyhow::Result<()> {
39+
fn init<C>(&mut self, ctx: &mut C) -> anyhow::Result<()>
40+
where
41+
C: spin_factors::InitContext<Self>,
42+
{
4343
ctx.link_bindings(spin_world::v1::llm::add_to_linker)?;
4444
ctx.link_bindings(spin_world::v2::llm::add_to_linker)?;
4545
Ok(())

crates/factor-outbound-http/src/lib.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,12 @@ impl Factor for OutboundHttpFactor {
5252
type AppState = ();
5353
type InstanceBuilder = InstanceState;
5454

55-
fn init<T: Send + 'static>(
56-
&mut self,
57-
mut ctx: spin_factors::InitContext<T, Self>,
58-
) -> anyhow::Result<()> {
55+
fn init<C>(&mut self, ctx: &mut C) -> anyhow::Result<()>
56+
where
57+
C: spin_factors::InitContext<Self>,
58+
{
5959
ctx.link_bindings(spin_world::v1::http::add_to_linker)?;
60-
wasi::add_to_linker::<T>(&mut ctx)?;
60+
wasi::add_to_linker(ctx)?;
6161
Ok(())
6262
}
6363

crates/factor-outbound-http/src/wasi.rs

+13-15
Original file line numberDiff line numberDiff line change
@@ -23,26 +23,24 @@ use crate::{
2323
wasi_2023_10_18, wasi_2023_11_10, InstanceState, OutboundHttpFactor, SelfRequestOrigin,
2424
};
2525

26-
pub(crate) fn add_to_linker<T: Send + 'static>(
27-
ctx: &mut spin_factors::InitContext<T, OutboundHttpFactor>,
28-
) -> anyhow::Result<()> {
29-
fn type_annotate<T, F>(f: F) -> F
26+
pub(crate) fn add_to_linker<C>(ctx: &mut C) -> anyhow::Result<()>
27+
where
28+
C: spin_factors::InitContext<OutboundHttpFactor>,
29+
{
30+
fn get_http<C>(store: &mut C::StoreData) -> WasiHttpImpl<WasiHttpImplInner<'_>>
3031
where
31-
F: Fn(&mut T) -> WasiHttpImpl<WasiHttpImplInner>,
32+
C: spin_factors::InitContext<OutboundHttpFactor>,
3233
{
33-
f
34-
}
35-
let get_data_with_table = ctx.get_data_with_table_fn();
36-
let closure = type_annotate(move |data| {
37-
let (state, table) = get_data_with_table(data);
34+
let (state, table) = C::get_data_with_table(store);
3835
WasiHttpImpl(IoImpl(WasiHttpImplInner { state, table }))
39-
});
36+
}
37+
let get_http = get_http::<C> as fn(&mut C::StoreData) -> WasiHttpImpl<WasiHttpImplInner<'_>>;
4038
let linker = ctx.linker();
41-
wasmtime_wasi_http::bindings::http::outgoing_handler::add_to_linker_get_host(linker, closure)?;
42-
wasmtime_wasi_http::bindings::http::types::add_to_linker_get_host(linker, closure)?;
39+
wasmtime_wasi_http::bindings::http::outgoing_handler::add_to_linker_get_host(linker, get_http)?;
40+
wasmtime_wasi_http::bindings::http::types::add_to_linker_get_host(linker, get_http)?;
4341

44-
wasi_2023_10_18::add_to_linker(linker, closure)?;
45-
wasi_2023_11_10::add_to_linker(linker, closure)?;
42+
wasi_2023_10_18::add_to_linker(linker, get_http)?;
43+
wasi_2023_11_10::add_to_linker(linker, get_http)?;
4644

4745
Ok(())
4846
}

crates/factor-outbound-http/src/wasi_2023_10_18.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,12 @@ use wasi::io::streams::{InputStream, OutputStream};
5454

5555
use crate::wasi::WasiHttpImplInner;
5656

57-
pub(crate) fn add_to_linker<T, F>(linker: &mut Linker<T>, closure: F) -> Result<()>
57+
pub(crate) fn add_to_linker<T>(
58+
linker: &mut Linker<T>,
59+
closure: fn(&mut T) -> WasiHttpImpl<WasiHttpImplInner<'_>>,
60+
) -> Result<()>
5861
where
59-
T: Send,
60-
F: Fn(&mut T) -> WasiHttpImpl<WasiHttpImplInner> + Send + Sync + Copy + 'static,
62+
T: Send + 'static,
6163
{
6264
wasi::http::types::add_to_linker_get_host(linker, closure)?;
6365
wasi::http::outgoing_handler::add_to_linker_get_host(linker, closure)?;

crates/factor-outbound-http/src/wasi_2023_11_10.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,12 @@ use wasi::io::streams::{Error as IoError, InputStream, OutputStream};
5959

6060
use crate::wasi::WasiHttpImplInner;
6161

62-
pub(crate) fn add_to_linker<T, F>(linker: &mut Linker<T>, closure: F) -> Result<()>
62+
pub(crate) fn add_to_linker<T>(
63+
linker: &mut Linker<T>,
64+
closure: fn(&mut T) -> WasiHttpImpl<WasiHttpImplInner<'_>>,
65+
) -> Result<()>
6366
where
64-
T: Send,
65-
F: Fn(&mut T) -> WasiHttpImpl<WasiHttpImplInner> + Send + Sync + Copy + 'static,
67+
T: Send + 'static,
6668
{
6769
wasi::http::types::add_to_linker_get_host(linker, closure)?;
6870
wasi::http::outgoing_handler::add_to_linker_get_host(linker, closure)?;

crates/factor-outbound-mqtt/src/lib.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,10 @@ impl Factor for OutboundMqttFactor {
3131
type AppState = ();
3232
type InstanceBuilder = InstanceState;
3333

34-
fn init<T: Send + 'static>(
35-
&mut self,
36-
mut ctx: spin_factors::InitContext<T, Self>,
37-
) -> anyhow::Result<()> {
34+
fn init<C>(&mut self, ctx: &mut C) -> anyhow::Result<()>
35+
where
36+
C: spin_factors::InitContext<Self>,
37+
{
3838
ctx.link_bindings(spin_world::v2::mqtt::add_to_linker)?;
3939
Ok(())
4040
}

crates/factor-outbound-mysql/src/lib.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@ impl<C: Send + Sync + Client + 'static> Factor for OutboundMysqlFactor<C> {
1717
type AppState = ();
1818
type InstanceBuilder = InstanceState<C>;
1919

20-
fn init<T: Send + 'static>(&mut self, mut ctx: InitContext<T, Self>) -> anyhow::Result<()> {
20+
fn init<I>(&mut self, ctx: &mut I) -> anyhow::Result<()>
21+
where
22+
I: InitContext<Self>,
23+
{
2124
ctx.link_bindings(v1::add_to_linker)?;
2225
ctx.link_bindings(v2::add_to_linker)?;
2326
Ok(())

crates/factor-outbound-pg/src/lib.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@ impl<C: Send + Sync + Client + 'static> Factor for OutboundPgFactor<C> {
1717
type AppState = ();
1818
type InstanceBuilder = InstanceState<C>;
1919

20-
fn init<T: Send + 'static>(
21-
&mut self,
22-
mut ctx: spin_factors::InitContext<T, Self>,
23-
) -> anyhow::Result<()> {
20+
fn init<I>(&mut self, ctx: &mut I) -> anyhow::Result<()>
21+
where
22+
I: spin_factors::InitContext<Self>,
23+
{
2424
ctx.link_bindings(spin_world::v1::postgres::add_to_linker)?;
2525
ctx.link_bindings(spin_world::v2::postgres::add_to_linker)?;
2626
ctx.link_bindings(spin_world::spin::postgres::postgres::add_to_linker)?;

crates/factor-outbound-redis/src/lib.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@ impl Factor for OutboundRedisFactor {
2323
type AppState = ();
2424
type InstanceBuilder = InstanceState;
2525

26-
fn init<T: Send + 'static>(
27-
&mut self,
28-
mut ctx: spin_factors::InitContext<T, Self>,
29-
) -> anyhow::Result<()> {
26+
fn init<C>(&mut self, ctx: &mut C) -> anyhow::Result<()>
27+
where
28+
C: spin_factors::InitContext<Self>,
29+
{
3030
ctx.link_bindings(spin_world::v1::redis::add_to_linker)?;
3131
ctx.link_bindings(spin_world::v2::redis::add_to_linker)?;
3232
Ok(())

crates/factor-sqlite/src/lib.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,10 @@ impl Factor for SqliteFactor {
3232
type AppState = AppState;
3333
type InstanceBuilder = InstanceState;
3434

35-
fn init<T: Send + 'static>(
36-
&mut self,
37-
mut ctx: spin_factors::InitContext<T, Self>,
38-
) -> anyhow::Result<()> {
35+
fn init<C>(&mut self, ctx: &mut C) -> anyhow::Result<()>
36+
where
37+
C: spin_factors::InitContext<Self>,
38+
{
3939
ctx.link_bindings(v1::add_to_linker)?;
4040
ctx.link_bindings(v2::add_to_linker)?;
4141
ctx.link_bindings(v3::add_to_linker)?;

crates/factor-variables/src/lib.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,10 @@ impl Factor for VariablesFactor {
2828
type AppState = AppState;
2929
type InstanceBuilder = InstanceState;
3030

31-
fn init<T: Send + 'static>(&mut self, mut ctx: InitContext<T, Self>) -> anyhow::Result<()> {
31+
fn init<C>(&mut self, ctx: &mut C) -> anyhow::Result<()>
32+
where
33+
C: InitContext<Self>,
34+
{
3235
ctx.link_bindings(spin_world::v1::config::add_to_linker)?;
3336
ctx.link_bindings(spin_world::v2::variables::add_to_linker)?;
3437
ctx.link_bindings(spin_world::wasi::config::store::add_to_linker)?;

crates/factor-wasi/src/lib.rs

+48-52
Original file line numberDiff line numberDiff line change
@@ -49,64 +49,60 @@ impl Factor for WasiFactor {
4949
type AppState = ();
5050
type InstanceBuilder = InstanceBuilder;
5151

52-
fn init<T: Send + 'static>(&mut self, mut ctx: InitContext<T, Self>) -> anyhow::Result<()> {
53-
fn type_annotate_wasi<T, F>(f: F) -> F
54-
where
55-
F: Fn(&mut T) -> WasiImpl<WasiImplInner>,
56-
{
57-
f
58-
}
59-
fn type_annotate_io<T, F>(f: F) -> F
60-
where
61-
F: Fn(&mut T) -> IoImpl<WasiImplInner>,
62-
{
63-
f
64-
}
65-
let get_data_with_table = ctx.get_data_with_table_fn();
66-
let io_closure = type_annotate_io(move |data| {
67-
let (state, table) = get_data_with_table(data);
52+
fn init<C>(&mut self, ctx: &mut C) -> anyhow::Result<()>
53+
where
54+
C: InitContext<Self>,
55+
{
56+
fn get_io<C: InitContext<WasiFactor>>(
57+
data: &mut C::StoreData,
58+
) -> IoImpl<WasiImplInner<'_>> {
59+
let (state, table) = C::get_data_with_table(data);
6860
IoImpl(WasiImplInner {
6961
ctx: &mut state.ctx,
7062
table,
7163
})
72-
});
73-
let wasi_closure = type_annotate_wasi(move |data| WasiImpl(io_closure(data)));
64+
}
65+
66+
fn get_wasi<C: InitContext<WasiFactor>>(
67+
data: &mut C::StoreData,
68+
) -> WasiImpl<WasiImplInner<'_>> {
69+
WasiImpl(get_io::<C>(data))
70+
}
71+
72+
let get_io = get_io::<C> as fn(&mut C::StoreData) -> IoImpl<WasiImplInner<'_>>;
73+
let get_wasi = get_wasi::<C> as fn(&mut C::StoreData) -> WasiImpl<WasiImplInner<'_>>;
7474
let linker = ctx.linker();
7575
use wasmtime_wasi::bindings;
76-
bindings::clocks::wall_clock::add_to_linker_get_host(linker, wasi_closure)?;
77-
bindings::clocks::monotonic_clock::add_to_linker_get_host(linker, wasi_closure)?;
78-
bindings::filesystem::types::add_to_linker_get_host(linker, wasi_closure)?;
79-
bindings::filesystem::preopens::add_to_linker_get_host(linker, wasi_closure)?;
80-
bindings::io::error::add_to_linker_get_host(linker, io_closure)?;
81-
bindings::io::poll::add_to_linker_get_host(linker, io_closure)?;
82-
bindings::io::streams::add_to_linker_get_host(linker, io_closure)?;
83-
bindings::random::random::add_to_linker_get_host(linker, wasi_closure)?;
84-
bindings::random::insecure::add_to_linker_get_host(linker, wasi_closure)?;
85-
bindings::random::insecure_seed::add_to_linker_get_host(linker, wasi_closure)?;
86-
bindings::cli::exit::add_to_linker_get_host(linker, &Default::default(), wasi_closure)?;
87-
bindings::cli::environment::add_to_linker_get_host(linker, wasi_closure)?;
88-
bindings::cli::stdin::add_to_linker_get_host(linker, wasi_closure)?;
89-
bindings::cli::stdout::add_to_linker_get_host(linker, wasi_closure)?;
90-
bindings::cli::stderr::add_to_linker_get_host(linker, wasi_closure)?;
91-
bindings::cli::terminal_input::add_to_linker_get_host(linker, wasi_closure)?;
92-
bindings::cli::terminal_output::add_to_linker_get_host(linker, wasi_closure)?;
93-
bindings::cli::terminal_stdin::add_to_linker_get_host(linker, wasi_closure)?;
94-
bindings::cli::terminal_stdout::add_to_linker_get_host(linker, wasi_closure)?;
95-
bindings::cli::terminal_stderr::add_to_linker_get_host(linker, wasi_closure)?;
96-
bindings::sockets::tcp::add_to_linker_get_host(linker, wasi_closure)?;
97-
bindings::sockets::tcp_create_socket::add_to_linker_get_host(linker, wasi_closure)?;
98-
bindings::sockets::udp::add_to_linker_get_host(linker, wasi_closure)?;
99-
bindings::sockets::udp_create_socket::add_to_linker_get_host(linker, wasi_closure)?;
100-
bindings::sockets::instance_network::add_to_linker_get_host(linker, wasi_closure)?;
101-
bindings::sockets::network::add_to_linker_get_host(
102-
linker,
103-
&Default::default(),
104-
wasi_closure,
105-
)?;
106-
bindings::sockets::ip_name_lookup::add_to_linker_get_host(linker, wasi_closure)?;
107-
108-
wasi_2023_10_18::add_to_linker(linker, wasi_closure)?;
109-
wasi_2023_11_10::add_to_linker(linker, wasi_closure)?;
76+
bindings::clocks::wall_clock::add_to_linker_get_host(linker, get_wasi)?;
77+
bindings::clocks::monotonic_clock::add_to_linker_get_host(linker, get_wasi)?;
78+
bindings::filesystem::types::add_to_linker_get_host(linker, get_wasi)?;
79+
bindings::filesystem::preopens::add_to_linker_get_host(linker, get_wasi)?;
80+
bindings::io::error::add_to_linker_get_host(linker, get_io)?;
81+
bindings::io::poll::add_to_linker_get_host(linker, get_io)?;
82+
bindings::io::streams::add_to_linker_get_host(linker, get_io)?;
83+
bindings::random::random::add_to_linker_get_host(linker, get_wasi)?;
84+
bindings::random::insecure::add_to_linker_get_host(linker, get_wasi)?;
85+
bindings::random::insecure_seed::add_to_linker_get_host(linker, get_wasi)?;
86+
bindings::cli::exit::add_to_linker_get_host(linker, &Default::default(), get_wasi)?;
87+
bindings::cli::environment::add_to_linker_get_host(linker, get_wasi)?;
88+
bindings::cli::stdin::add_to_linker_get_host(linker, get_wasi)?;
89+
bindings::cli::stdout::add_to_linker_get_host(linker, get_wasi)?;
90+
bindings::cli::stderr::add_to_linker_get_host(linker, get_wasi)?;
91+
bindings::cli::terminal_input::add_to_linker_get_host(linker, get_wasi)?;
92+
bindings::cli::terminal_output::add_to_linker_get_host(linker, get_wasi)?;
93+
bindings::cli::terminal_stdin::add_to_linker_get_host(linker, get_wasi)?;
94+
bindings::cli::terminal_stdout::add_to_linker_get_host(linker, get_wasi)?;
95+
bindings::cli::terminal_stderr::add_to_linker_get_host(linker, get_wasi)?;
96+
bindings::sockets::tcp::add_to_linker_get_host(linker, get_wasi)?;
97+
bindings::sockets::tcp_create_socket::add_to_linker_get_host(linker, get_wasi)?;
98+
bindings::sockets::udp::add_to_linker_get_host(linker, get_wasi)?;
99+
bindings::sockets::udp_create_socket::add_to_linker_get_host(linker, get_wasi)?;
100+
bindings::sockets::instance_network::add_to_linker_get_host(linker, get_wasi)?;
101+
bindings::sockets::network::add_to_linker_get_host(linker, &Default::default(), get_wasi)?;
102+
bindings::sockets::ip_name_lookup::add_to_linker_get_host(linker, get_wasi)?;
103+
104+
wasi_2023_10_18::add_to_linker(linker, get_wasi)?;
105+
wasi_2023_11_10::add_to_linker(linker, get_wasi)?;
110106

111107
Ok(())
112108
}

crates/factor-wasi/src/wasi_2023_10_18.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -118,10 +118,12 @@ use wasi::sockets::udp::Datagram;
118118

119119
use crate::WasiImplInner;
120120

121-
pub fn add_to_linker<T, F>(linker: &mut Linker<T>, closure: F) -> Result<()>
121+
pub fn add_to_linker<T>(
122+
linker: &mut Linker<T>,
123+
closure: fn(&mut T) -> WasiImpl<WasiImplInner<'_>>,
124+
) -> Result<()>
122125
where
123-
T: Send,
124-
F: Fn(&mut T) -> WasiImpl<WasiImplInner> + Send + Sync + Copy + 'static,
126+
T: Send + 'static,
125127
{
126128
wasi::clocks::monotonic_clock::add_to_linker_get_host(linker, closure)?;
127129
wasi::clocks::wall_clock::add_to_linker_get_host(linker, closure)?;

crates/factor-wasi/src/wasi_2023_11_10.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -111,10 +111,12 @@ use wasi::sockets::udp::{
111111

112112
use crate::WasiImplInner;
113113

114-
pub fn add_to_linker<T, F>(linker: &mut Linker<T>, closure: F) -> Result<()>
114+
pub fn add_to_linker<T>(
115+
linker: &mut Linker<T>,
116+
closure: fn(&mut T) -> WasiImpl<WasiImplInner<'_>>,
117+
) -> Result<()>
115118
where
116-
T: Send,
117-
F: Fn(&mut T) -> WasiImpl<WasiImplInner> + Send + Sync + Copy + 'static,
119+
T: Send + 'static,
118120
{
119121
wasi::clocks::monotonic_clock::add_to_linker_get_host(linker, closure)?;
120122
wasi::clocks::wall_clock::add_to_linker_get_host(linker, closure)?;

crates/factors-derive/src/lib.rs

+19-8
Original file line numberDiff line numberDiff line change
@@ -94,16 +94,27 @@ fn expand_factors(input: &DeriveInput) -> syn::Result<TokenStream> {
9494
}
9595

9696
#(
97-
#Factor::init::<T>(
97+
#[allow(non_camel_case_types)]
98+
struct #factor_names;
99+
100+
impl #factors_path::FactorField for #factor_names {
101+
type State = #state_name;
102+
type Factor = #factor_types;
103+
104+
fn get(state: &mut #state_name) -> (
105+
&mut #factors_path::FactorInstanceState<#factor_types>,
106+
&mut #wasmtime::component::ResourceTable,
107+
) {
108+
(&mut state.#factor_names, &mut state.__table)
109+
}
110+
}
111+
112+
#Factor::init(
98113
&mut self.#factor_names,
99-
#factors_path::InitContext::<T, #factor_types>::new(
114+
&mut #factors_path::FactorInitContext::<'_, T, #factor_names> {
100115
linker,
101-
|data| &mut data.as_instance_state().#factor_names,
102-
|data| {
103-
let state = data.as_instance_state();
104-
(&mut state.#factor_names, &mut state.__table)
105-
},
106-
)
116+
_marker: std::marker::PhantomData,
117+
},
107118
).map_err(#Error::factor_init_error::<#factor_types>)?;
108119
)*
109120
Ok(())

0 commit comments

Comments
 (0)