Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/crates/component-macro/tests/expanded/multiversion.rs
3073 views
1
/// Auto-generated bindings for a pre-instantiated version of a
2
/// component which implements the world `foo`.
3
///
4
/// This structure is created through [`FooPre::new`] which
5
/// takes a [`InstancePre`](wasmtime::component::InstancePre) that
6
/// has been created through a [`Linker`](wasmtime::component::Linker).
7
///
8
/// For more information see [`Foo`] as well.
9
pub struct FooPre<T: 'static> {
10
instance_pre: wasmtime::component::InstancePre<T>,
11
indices: FooIndices,
12
}
13
impl<T: 'static> Clone for FooPre<T> {
14
fn clone(&self) -> Self {
15
Self {
16
instance_pre: self.instance_pre.clone(),
17
indices: self.indices.clone(),
18
}
19
}
20
}
21
impl<_T: 'static> FooPre<_T> {
22
/// Creates a new copy of `FooPre` bindings which can then
23
/// be used to instantiate into a particular store.
24
///
25
/// This method may fail if the component behind `instance_pre`
26
/// does not have the required exports.
27
pub fn new(
28
instance_pre: wasmtime::component::InstancePre<_T>,
29
) -> wasmtime::Result<Self> {
30
let indices = FooIndices::new(&instance_pre)?;
31
Ok(Self { instance_pre, indices })
32
}
33
pub fn engine(&self) -> &wasmtime::Engine {
34
self.instance_pre.engine()
35
}
36
pub fn instance_pre(&self) -> &wasmtime::component::InstancePre<_T> {
37
&self.instance_pre
38
}
39
/// Instantiates a new instance of [`Foo`] within the
40
/// `store` provided.
41
///
42
/// This function will use `self` as the pre-instantiated
43
/// instance to perform instantiation. Afterwards the preloaded
44
/// indices in `self` are used to lookup all exports on the
45
/// resulting instance.
46
pub fn instantiate(
47
&self,
48
mut store: impl wasmtime::AsContextMut<Data = _T>,
49
) -> wasmtime::Result<Foo> {
50
let mut store = store.as_context_mut();
51
let instance = self.instance_pre.instantiate(&mut store)?;
52
self.indices.load(&mut store, &instance)
53
}
54
}
55
impl<_T: Send + 'static> FooPre<_T> {
56
/// Same as [`Self::instantiate`], except with `async`.
57
pub async fn instantiate_async(
58
&self,
59
mut store: impl wasmtime::AsContextMut<Data = _T>,
60
) -> wasmtime::Result<Foo> {
61
let mut store = store.as_context_mut();
62
let instance = self.instance_pre.instantiate_async(&mut store).await?;
63
self.indices.load(&mut store, &instance)
64
}
65
}
66
/// Auto-generated bindings for index of the exports of
67
/// `foo`.
68
///
69
/// This is an implementation detail of [`FooPre`] and can
70
/// be constructed if needed as well.
71
///
72
/// For more information see [`Foo`] as well.
73
#[derive(Clone)]
74
pub struct FooIndices {
75
interface0: exports::my::dep0_1_0::a::GuestIndices,
76
interface1: exports::my::dep0_2_0::a::GuestIndices,
77
}
78
/// Auto-generated bindings for an instance a component which
79
/// implements the world `foo`.
80
///
81
/// This structure can be created through a number of means
82
/// depending on your requirements and what you have on hand:
83
///
84
/// * The most convenient way is to use
85
/// [`Foo::instantiate`] which only needs a
86
/// [`Store`], [`Component`], and [`Linker`].
87
///
88
/// * Alternatively you can create a [`FooPre`] ahead of
89
/// time with a [`Component`] to front-load string lookups
90
/// of exports once instead of per-instantiation. This
91
/// method then uses [`FooPre::instantiate`] to
92
/// create a [`Foo`].
93
///
94
/// * If you've instantiated the instance yourself already
95
/// then you can use [`Foo::new`].
96
///
97
/// These methods are all equivalent to one another and move
98
/// around the tradeoff of what work is performed when.
99
///
100
/// [`Store`]: wasmtime::Store
101
/// [`Component`]: wasmtime::component::Component
102
/// [`Linker`]: wasmtime::component::Linker
103
pub struct Foo {
104
interface0: exports::my::dep0_1_0::a::Guest,
105
interface1: exports::my::dep0_2_0::a::Guest,
106
}
107
const _: () = {
108
impl FooIndices {
109
/// Creates a new copy of `FooIndices` bindings which can then
110
/// be used to instantiate into a particular store.
111
///
112
/// This method may fail if the component does not have the
113
/// required exports.
114
pub fn new<_T>(
115
_instance_pre: &wasmtime::component::InstancePre<_T>,
116
) -> wasmtime::Result<Self> {
117
let _component = _instance_pre.component();
118
let _instance_type = _instance_pre.instance_type();
119
let interface0 = exports::my::dep0_1_0::a::GuestIndices::new(_instance_pre)?;
120
let interface1 = exports::my::dep0_2_0::a::GuestIndices::new(_instance_pre)?;
121
Ok(FooIndices {
122
interface0,
123
interface1,
124
})
125
}
126
/// Uses the indices stored in `self` to load an instance
127
/// of [`Foo`] from the instance provided.
128
///
129
/// Note that at this time this method will additionally
130
/// perform type-checks of all exports.
131
pub fn load(
132
&self,
133
mut store: impl wasmtime::AsContextMut,
134
instance: &wasmtime::component::Instance,
135
) -> wasmtime::Result<Foo> {
136
let _ = &mut store;
137
let _instance = instance;
138
let interface0 = self.interface0.load(&mut store, &_instance)?;
139
let interface1 = self.interface1.load(&mut store, &_instance)?;
140
Ok(Foo { interface0, interface1 })
141
}
142
}
143
impl Foo {
144
/// Convenience wrapper around [`FooPre::new`] and
145
/// [`FooPre::instantiate`].
146
pub fn instantiate<_T>(
147
store: impl wasmtime::AsContextMut<Data = _T>,
148
component: &wasmtime::component::Component,
149
linker: &wasmtime::component::Linker<_T>,
150
) -> wasmtime::Result<Foo> {
151
let pre = linker.instantiate_pre(component)?;
152
FooPre::new(pre)?.instantiate(store)
153
}
154
/// Convenience wrapper around [`FooIndices::new`] and
155
/// [`FooIndices::load`].
156
pub fn new(
157
mut store: impl wasmtime::AsContextMut,
158
instance: &wasmtime::component::Instance,
159
) -> wasmtime::Result<Foo> {
160
let indices = FooIndices::new(&instance.instance_pre(&store))?;
161
indices.load(&mut store, instance)
162
}
163
/// Convenience wrapper around [`FooPre::new`] and
164
/// [`FooPre::instantiate_async`].
165
pub async fn instantiate_async<_T>(
166
store: impl wasmtime::AsContextMut<Data = _T>,
167
component: &wasmtime::component::Component,
168
linker: &wasmtime::component::Linker<_T>,
169
) -> wasmtime::Result<Foo>
170
where
171
_T: Send,
172
{
173
let pre = linker.instantiate_pre(component)?;
174
FooPre::new(pre)?.instantiate_async(store).await
175
}
176
pub fn add_to_linker<T, D>(
177
linker: &mut wasmtime::component::Linker<T>,
178
host_getter: fn(&mut T) -> D::Data<'_>,
179
) -> wasmtime::Result<()>
180
where
181
D: my::dep0_1_0::a::HostWithStore + my::dep0_2_0::a::HostWithStore,
182
for<'a> D::Data<'a>: my::dep0_1_0::a::Host + my::dep0_2_0::a::Host,
183
T: 'static,
184
{
185
my::dep0_1_0::a::add_to_linker::<T, D>(linker, host_getter)?;
186
my::dep0_2_0::a::add_to_linker::<T, D>(linker, host_getter)?;
187
Ok(())
188
}
189
pub fn my_dep0_1_0_a(&self) -> &exports::my::dep0_1_0::a::Guest {
190
&self.interface0
191
}
192
pub fn my_dep0_2_0_a(&self) -> &exports::my::dep0_2_0::a::Guest {
193
&self.interface1
194
}
195
}
196
};
197
pub mod my {
198
pub mod dep0_1_0 {
199
#[allow(clippy::all)]
200
pub mod a {
201
#[allow(unused_imports)]
202
use wasmtime::component::__internal::Box;
203
pub trait HostWithStore: wasmtime::component::HasData {}
204
impl<_T: ?Sized> HostWithStore for _T
205
where
206
_T: wasmtime::component::HasData,
207
{}
208
pub trait Host {
209
fn x(&mut self) -> ();
210
}
211
impl<_T: Host + ?Sized> Host for &mut _T {
212
fn x(&mut self) -> () {
213
Host::x(*self)
214
}
215
}
216
pub fn add_to_linker<T, D>(
217
linker: &mut wasmtime::component::Linker<T>,
218
host_getter: fn(&mut T) -> D::Data<'_>,
219
) -> wasmtime::Result<()>
220
where
221
D: HostWithStore,
222
for<'a> D::Data<'a>: Host,
223
T: 'static,
224
{
225
let mut inst = linker.instance("my:dep/[email protected]")?;
226
inst.func_wrap(
227
"x",
228
move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| {
229
let host = &mut host_getter(caller.data_mut());
230
let r = Host::x(host);
231
Ok(r)
232
},
233
)?;
234
Ok(())
235
}
236
}
237
}
238
pub mod dep0_2_0 {
239
#[allow(clippy::all)]
240
pub mod a {
241
#[allow(unused_imports)]
242
use wasmtime::component::__internal::Box;
243
pub trait HostWithStore: wasmtime::component::HasData {}
244
impl<_T: ?Sized> HostWithStore for _T
245
where
246
_T: wasmtime::component::HasData,
247
{}
248
pub trait Host {
249
fn x(&mut self) -> ();
250
}
251
impl<_T: Host + ?Sized> Host for &mut _T {
252
fn x(&mut self) -> () {
253
Host::x(*self)
254
}
255
}
256
pub fn add_to_linker<T, D>(
257
linker: &mut wasmtime::component::Linker<T>,
258
host_getter: fn(&mut T) -> D::Data<'_>,
259
) -> wasmtime::Result<()>
260
where
261
D: HostWithStore,
262
for<'a> D::Data<'a>: Host,
263
T: 'static,
264
{
265
let mut inst = linker.instance("my:dep/[email protected]")?;
266
inst.func_wrap(
267
"x",
268
move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| {
269
let host = &mut host_getter(caller.data_mut());
270
let r = Host::x(host);
271
Ok(r)
272
},
273
)?;
274
Ok(())
275
}
276
}
277
}
278
}
279
pub mod exports {
280
pub mod my {
281
pub mod dep0_1_0 {
282
#[allow(clippy::all)]
283
pub mod a {
284
#[allow(unused_imports)]
285
use wasmtime::component::__internal::Box;
286
#[derive(Clone)]
287
pub struct Guest {
288
x: wasmtime::component::Func,
289
}
290
#[derive(Clone)]
291
pub struct GuestIndices {
292
x: wasmtime::component::ComponentExportIndex,
293
}
294
impl GuestIndices {
295
/// Constructor for [`GuestIndices`] which takes a
296
/// [`Component`](wasmtime::component::Component) as input and can be executed
297
/// before instantiation.
298
///
299
/// This constructor can be used to front-load string lookups to find exports
300
/// within a component.
301
pub fn new<_T>(
302
_instance_pre: &wasmtime::component::InstancePre<_T>,
303
) -> wasmtime::Result<GuestIndices> {
304
let instance = _instance_pre
305
.component()
306
.get_export_index(None, "my:dep/[email protected]")
307
.ok_or_else(|| {
308
wasmtime::format_err!(
309
"no exported instance named `my:dep/[email protected]`"
310
)
311
})?;
312
let mut lookup = move |name| {
313
_instance_pre
314
.component()
315
.get_export_index(Some(&instance), name)
316
.ok_or_else(|| {
317
wasmtime::format_err!(
318
"instance export `my:dep/[email protected]` does \
319
not have export `{name}`"
320
)
321
})
322
};
323
let _ = &mut lookup;
324
let x = lookup("x")?;
325
Ok(GuestIndices { x })
326
}
327
pub fn load(
328
&self,
329
mut store: impl wasmtime::AsContextMut,
330
instance: &wasmtime::component::Instance,
331
) -> wasmtime::Result<Guest> {
332
let _instance = instance;
333
let _instance_pre = _instance.instance_pre(&store);
334
let _instance_type = _instance_pre.instance_type();
335
let mut store = store.as_context_mut();
336
let _ = &mut store;
337
let x = *_instance
338
.get_typed_func::<(), ()>(&mut store, &self.x)?
339
.func();
340
Ok(Guest { x })
341
}
342
}
343
impl Guest {
344
pub fn call_x<S: wasmtime::AsContextMut>(
345
&self,
346
mut store: S,
347
) -> wasmtime::Result<()> {
348
let callee = unsafe {
349
wasmtime::component::TypedFunc::<
350
(),
351
(),
352
>::new_unchecked(self.x)
353
};
354
let () = callee.call(store.as_context_mut(), ())?;
355
Ok(())
356
}
357
}
358
}
359
}
360
pub mod dep0_2_0 {
361
#[allow(clippy::all)]
362
pub mod a {
363
#[allow(unused_imports)]
364
use wasmtime::component::__internal::Box;
365
#[derive(Clone)]
366
pub struct Guest {
367
x: wasmtime::component::Func,
368
}
369
#[derive(Clone)]
370
pub struct GuestIndices {
371
x: wasmtime::component::ComponentExportIndex,
372
}
373
impl GuestIndices {
374
/// Constructor for [`GuestIndices`] which takes a
375
/// [`Component`](wasmtime::component::Component) as input and can be executed
376
/// before instantiation.
377
///
378
/// This constructor can be used to front-load string lookups to find exports
379
/// within a component.
380
pub fn new<_T>(
381
_instance_pre: &wasmtime::component::InstancePre<_T>,
382
) -> wasmtime::Result<GuestIndices> {
383
let instance = _instance_pre
384
.component()
385
.get_export_index(None, "my:dep/[email protected]")
386
.ok_or_else(|| {
387
wasmtime::format_err!(
388
"no exported instance named `my:dep/[email protected]`"
389
)
390
})?;
391
let mut lookup = move |name| {
392
_instance_pre
393
.component()
394
.get_export_index(Some(&instance), name)
395
.ok_or_else(|| {
396
wasmtime::format_err!(
397
"instance export `my:dep/[email protected]` does \
398
not have export `{name}`"
399
)
400
})
401
};
402
let _ = &mut lookup;
403
let x = lookup("x")?;
404
Ok(GuestIndices { x })
405
}
406
pub fn load(
407
&self,
408
mut store: impl wasmtime::AsContextMut,
409
instance: &wasmtime::component::Instance,
410
) -> wasmtime::Result<Guest> {
411
let _instance = instance;
412
let _instance_pre = _instance.instance_pre(&store);
413
let _instance_type = _instance_pre.instance_type();
414
let mut store = store.as_context_mut();
415
let _ = &mut store;
416
let x = *_instance
417
.get_typed_func::<(), ()>(&mut store, &self.x)?
418
.func();
419
Ok(Guest { x })
420
}
421
}
422
impl Guest {
423
pub fn call_x<S: wasmtime::AsContextMut>(
424
&self,
425
mut store: S,
426
) -> wasmtime::Result<()> {
427
let callee = unsafe {
428
wasmtime::component::TypedFunc::<
429
(),
430
(),
431
>::new_unchecked(self.x)
432
};
433
let () = callee.call(store.as_context_mut(), ())?;
434
Ok(())
435
}
436
}
437
}
438
}
439
}
440
}
441
442