1#[cfg(feature = "experimental-async")]
2use crate::AsStoreAsync;
3use crate::{
4 AsStoreMut, AsStoreRef, FunctionEnv, FunctionEnvMut, StoreMut, StoreRef,
5 macros::backend::match_rt,
6};
7use std::{any::Any, marker::PhantomData};
8
9#[derive(Debug, derive_more::From)]
10pub enum BackendFunctionEnv<T> {
13 #[cfg(feature = "sys")]
14 Sys(crate::backend::sys::function::env::FunctionEnv<T>),
16 #[cfg(feature = "wamr")]
17 Wamr(crate::backend::wamr::function::env::FunctionEnv<T>),
19 #[cfg(feature = "wasmi")]
20 Wasmi(crate::backend::wasmi::function::env::FunctionEnv<T>),
22 #[cfg(feature = "v8")]
23 V8(crate::backend::v8::function::env::FunctionEnv<T>),
25 #[cfg(feature = "js")]
26 Js(crate::backend::js::function::env::FunctionEnv<T>),
28 #[cfg(feature = "jsc")]
29 Jsc(crate::backend::jsc::function::env::FunctionEnv<T>),
31}
32
33impl<T> Clone for BackendFunctionEnv<T> {
34 fn clone(&self) -> Self {
35 match self {
36 #[cfg(feature = "sys")]
37 Self::Sys(s) => Self::Sys(s.clone()),
38 #[cfg(feature = "wamr")]
39 Self::Wamr(s) => Self::Wamr(s.clone()),
40
41 #[cfg(feature = "wasmi")]
42 Self::Wasmi(s) => Self::Wasmi(s.clone()),
43 #[cfg(feature = "v8")]
44 Self::V8(s) => Self::V8(s.clone()),
45 #[cfg(feature = "js")]
46 Self::Js(s) => Self::Js(s.clone()),
47 #[cfg(feature = "jsc")]
48 Self::Jsc(s) => Self::Jsc(s.clone()),
49 }
50 }
51}
52
53impl<T> BackendFunctionEnv<T> {
54 pub fn new(store: &mut impl AsStoreMut, value: T) -> Self
56 where
57 T: Any + Send + 'static + Sized,
58 {
59 match store.as_store_mut().inner.store {
60 #[cfg(feature = "sys")]
61 crate::BackendStore::Sys(_) => Self::Sys(
62 crate::backend::sys::function::env::FunctionEnv::new(store, value),
63 ),
64 #[cfg(feature = "wamr")]
65 crate::BackendStore::Wamr(_) => Self::Wamr(
66 crate::backend::wamr::function::env::FunctionEnv::new(store, value),
67 ),
68
69 #[cfg(feature = "wasmi")]
70 crate::BackendStore::Wasmi(_) => Self::Wasmi(
71 crate::backend::wasmi::function::env::FunctionEnv::new(store, value),
72 ),
73
74 #[cfg(feature = "v8")]
75 crate::BackendStore::V8(_) => Self::V8(
76 crate::backend::v8::function::env::FunctionEnv::new(store, value),
77 ),
78
79 #[cfg(feature = "js")]
80 crate::BackendStore::Js(_) => Self::Js(
81 crate::backend::js::function::env::FunctionEnv::new(store, value),
82 ),
83 #[cfg(feature = "jsc")]
84 crate::BackendStore::Jsc(_) => Self::Jsc(
85 crate::backend::jsc::function::env::FunctionEnv::new(store, value),
86 ),
87 }
88 }
89
90 pub fn as_ref<'a>(&self, store: &'a impl AsStoreRef) -> &'a T
92 where
93 T: Any + Send + 'static + Sized,
94 {
95 match_rt!(on self => f {
96 f.as_ref(store)
97 })
98 }
99
100 pub fn as_mut<'a>(&self, store: &'a mut impl AsStoreMut) -> &'a mut T
102 where
103 T: Any + Send + 'static + Sized,
104 {
105 match_rt!(on self => s {
106 s.as_mut(store)
107 })
108 }
109
110 pub fn into_mut(self, store: &mut impl AsStoreMut) -> FunctionEnvMut<'_, T>
112 where
113 T: Any + Send + 'static + Sized,
114 {
115 match_rt!(on self => f {
116 f.into_mut(store).into()
117 })
118 }
119}
120
121#[derive(derive_more::From)]
123pub enum BackendFunctionEnvMut<'a, T: 'a> {
124 #[cfg(feature = "sys")]
125 Sys(crate::backend::sys::function::env::FunctionEnvMut<'a, T>),
127
128 #[cfg(feature = "wamr")]
129 Wamr(crate::backend::wamr::function::env::FunctionEnvMut<'a, T>),
131
132 #[cfg(feature = "wasmi")]
133 Wasmi(crate::backend::wasmi::function::env::FunctionEnvMut<'a, T>),
135
136 #[cfg(feature = "v8")]
137 V8(crate::backend::v8::function::env::FunctionEnvMut<'a, T>),
139
140 #[cfg(feature = "js")]
141 Js(crate::backend::js::function::env::FunctionEnvMut<'a, T>),
143
144 #[cfg(feature = "jsc")]
145 Jsc(crate::backend::jsc::function::env::FunctionEnvMut<'a, T>),
147}
148
149impl<T: Send + 'static> BackendFunctionEnvMut<'_, T> {
150 pub fn data(&self) -> &T {
152 match_rt!(on self => f {
153 f.data()
154 })
155 }
156
157 pub fn data_mut(&mut self) -> &mut T {
159 match_rt!(on self => f {
160 f.data_mut()
161 })
162 }
163
164 pub fn as_ref(&self) -> FunctionEnv<T> {
166 match self {
167 #[cfg(feature = "sys")]
168 Self::Sys(f) => BackendFunctionEnv::Sys(f.as_ref()).into(),
169 #[cfg(feature = "wamr")]
170 Self::Wamr(f) => BackendFunctionEnv::Wamr(f.as_ref()).into(),
171 #[cfg(feature = "wasmi")]
172 Self::Wasmi(f) => BackendFunctionEnv::Wasmi(f.as_ref()).into(),
173 #[cfg(feature = "v8")]
174 Self::V8(f) => BackendFunctionEnv::V8(f.as_ref()).into(),
175 #[cfg(feature = "js")]
176 Self::Js(f) => BackendFunctionEnv::Js(f.as_ref()).into(),
177 #[cfg(feature = "jsc")]
178 Self::Jsc(f) => BackendFunctionEnv::Jsc(f.as_ref()).into(),
179 }
180 }
181
182 pub fn as_mut(&mut self) -> FunctionEnvMut<'_, T> {
184 match self {
185 #[cfg(feature = "sys")]
186 Self::Sys(f) => BackendFunctionEnvMut::Sys(f.as_mut()).into(),
187 #[cfg(feature = "wamr")]
188 Self::Wamr(f) => BackendFunctionEnvMut::Wamr(f.as_mut()).into(),
189 #[cfg(feature = "wasmi")]
190 Self::Wasmi(f) => BackendFunctionEnvMut::Wasmi(f.as_mut()).into(),
191 #[cfg(feature = "v8")]
192 Self::V8(f) => BackendFunctionEnvMut::V8(f.as_mut()).into(),
193 #[cfg(feature = "js")]
194 Self::Js(f) => BackendFunctionEnvMut::Js(f.as_mut()).into(),
195 #[cfg(feature = "jsc")]
196 Self::Jsc(f) => BackendFunctionEnvMut::Jsc(f.as_mut()).into(),
197 }
198 }
199
200 pub fn data_and_store_mut(&mut self) -> (&mut T, StoreMut<'_>) {
202 match_rt!(on self => f {
203 f.data_and_store_mut()
204 })
205 }
206
207 #[cfg(feature = "experimental-async")]
210 pub fn as_store_async(&self) -> Option<impl AsStoreAsync + 'static> {
211 match self {
212 #[cfg(feature = "sys")]
213 Self::Sys(f) => f.as_store_async(),
214 #[cfg(feature = "sys")]
215 _ => unsupported_async_backend(),
216 #[cfg(not(feature = "sys"))]
217 _ => unsupported_async_backend::<Option<crate::StoreAsync>>(),
218 }
219 }
220}
221
222impl<T> AsStoreRef for BackendFunctionEnvMut<'_, T> {
223 fn as_store_ref(&self) -> StoreRef<'_> {
224 match_rt!(on self => s {
225 s.as_store_ref()
226 })
227 }
228}
229
230impl<T> AsStoreMut for BackendFunctionEnvMut<'_, T> {
231 fn as_store_mut(&mut self) -> StoreMut<'_> {
232 match_rt!(on self => s {
233 s.as_store_mut()
234 })
235 }
236
237 fn objects_mut(&mut self) -> &mut crate::StoreObjects {
238 match_rt!(on self => s {
239 s.objects_mut()
240 })
241 }
242}
243
244impl<T> std::fmt::Debug for BackendFunctionEnvMut<'_, T>
245where
246 T: Send + std::fmt::Debug + 'static,
247{
248 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
249 match_rt!(on self => s {
250 write!(f, "{s:?}")
251 })
252 }
253}
254
255#[derive(derive_more::From)]
258#[cfg(feature = "experimental-async")]
259pub enum BackendAsyncFunctionEnvMut<T> {
260 #[cfg(feature = "sys")]
261 Sys(crate::backend::sys::function::env::AsyncFunctionEnvMut<T>),
263 #[cfg(any(
264 feature = "wamr",
265 feature = "wasmi",
266 feature = "v8",
267 feature = "js",
268 feature = "jsc"
269 ))]
270 Unsupported(PhantomData<T>),
272}
273
274#[cfg(feature = "experimental-async")]
276pub enum BackendAsyncFunctionEnvHandle<T> {
277 #[cfg(feature = "sys")]
278 Sys(crate::backend::sys::function::env::AsyncFunctionEnvHandle<T>),
280 #[cfg(any(
281 feature = "wamr",
282 feature = "wasmi",
283 feature = "v8",
284 feature = "js",
285 feature = "jsc"
286 ))]
287 Unsupported(PhantomData<T>),
289}
290
291#[cfg(feature = "experimental-async")]
293pub enum BackendAsyncFunctionEnvHandleMut<T> {
294 #[cfg(feature = "sys")]
295 Sys(crate::backend::sys::function::env::AsyncFunctionEnvHandleMut<T>),
297 #[cfg(any(
298 feature = "wamr",
299 feature = "wasmi",
300 feature = "v8",
301 feature = "js",
302 feature = "jsc"
303 ))]
304 Unsupported(PhantomData<T>),
306}
307
308#[cfg(feature = "experimental-async")]
309impl<T: 'static> BackendAsyncFunctionEnvMut<T> {
310 pub async fn read(&self) -> BackendAsyncFunctionEnvHandle<T> {
313 match self {
314 #[cfg(feature = "sys")]
315 Self::Sys(f) => BackendAsyncFunctionEnvHandle::Sys(f.read().await),
316 #[cfg(any(
317 feature = "wamr",
318 feature = "wasmi",
319 feature = "v8",
320 feature = "js",
321 feature = "jsc"
322 ))]
323 _ => unsupported_async_backend(),
324 }
325 }
326
327 pub async fn write(&self) -> BackendAsyncFunctionEnvHandleMut<T> {
330 match self {
331 #[cfg(feature = "sys")]
332 Self::Sys(f) => BackendAsyncFunctionEnvHandleMut::Sys(f.write().await),
333 #[cfg(any(
334 feature = "wamr",
335 feature = "wasmi",
336 feature = "v8",
337 feature = "js",
338 feature = "jsc"
339 ))]
340 _ => unsupported_async_backend(),
341 }
342 }
343
344 pub fn as_ref(&self) -> BackendFunctionEnv<T> {
346 match self {
347 #[cfg(feature = "sys")]
348 Self::Sys(f) => BackendFunctionEnv::Sys(f.as_ref()),
349 #[cfg(any(
350 feature = "wamr",
351 feature = "wasmi",
352 feature = "v8",
353 feature = "js",
354 feature = "jsc"
355 ))]
356 _ => unsupported_async_backend(),
357 }
358 }
359
360 pub fn as_mut(&mut self) -> Self {
362 match self {
363 #[cfg(feature = "sys")]
364 Self::Sys(f) => Self::Sys(f.as_mut()),
365 #[cfg(any(
366 feature = "wamr",
367 feature = "wasmi",
368 feature = "v8",
369 feature = "js",
370 feature = "jsc"
371 ))]
372 _ => unsupported_async_backend(),
373 }
374 }
375
376 pub fn as_store_async(&self) -> impl AsStoreAsync + 'static {
378 match self {
379 #[cfg(feature = "sys")]
380 Self::Sys(f) => f.as_store_async(),
381 #[cfg(all(
382 feature = "sys",
383 any(
384 feature = "wamr",
385 feature = "wasmi",
386 feature = "v8",
387 feature = "js",
388 feature = "jsc"
389 )
390 ))]
391 _ => unsupported_async_backend(),
392 #[cfg(all(
393 not(feature = "sys"),
394 any(
395 feature = "wamr",
396 feature = "wasmi",
397 feature = "v8",
398 feature = "js",
399 feature = "jsc"
400 )
401 ))]
402 _ => unsupported_async_backend::<crate::StoreAsync>(),
403 }
404 }
405}
406
407#[cfg(feature = "experimental-async")]
408impl<T: 'static> BackendAsyncFunctionEnvHandle<T> {
409 pub fn data(&self) -> &T {
411 match self {
412 #[cfg(feature = "sys")]
413 Self::Sys(f) => f.data(),
414 #[cfg(any(
415 feature = "wamr",
416 feature = "wasmi",
417 feature = "v8",
418 feature = "js",
419 feature = "jsc"
420 ))]
421 _ => unsupported_async_backend(),
422 }
423 }
424
425 pub fn data_and_store(&self) -> (&T, &impl AsStoreRef) {
427 match self {
428 #[cfg(feature = "sys")]
429 Self::Sys(f) => f.data_and_store(),
430 #[cfg(all(
431 feature = "sys",
432 any(
433 feature = "wamr",
434 feature = "wasmi",
435 feature = "v8",
436 feature = "js",
437 feature = "jsc"
438 )
439 ))]
440 _ => unsupported_async_backend(),
441 #[cfg(all(
442 not(feature = "sys"),
443 any(
444 feature = "wamr",
445 feature = "wasmi",
446 feature = "v8",
447 feature = "js",
448 feature = "jsc"
449 )
450 ))]
451 _ => unsupported_async_backend::<(&T, &StoreRef)>(),
452 }
453 }
454}
455
456#[cfg(feature = "experimental-async")]
457impl<T: 'static> AsStoreRef for BackendAsyncFunctionEnvHandle<T> {
458 fn as_store_ref(&self) -> StoreRef<'_> {
459 match self {
460 #[cfg(feature = "sys")]
461 Self::Sys(f) => AsStoreRef::as_store_ref(f),
462 #[cfg(any(
463 feature = "wamr",
464 feature = "wasmi",
465 feature = "v8",
466 feature = "js",
467 feature = "jsc"
468 ))]
469 _ => unsupported_async_backend(),
470 }
471 }
472}
473
474#[cfg(feature = "experimental-async")]
475impl<T: 'static> BackendAsyncFunctionEnvHandleMut<T> {
476 pub fn data_mut(&mut self) -> &mut T {
478 match self {
479 #[cfg(feature = "sys")]
480 Self::Sys(f) => f.data_mut(),
481 #[cfg(any(
482 feature = "wamr",
483 feature = "wasmi",
484 feature = "v8",
485 feature = "js",
486 feature = "jsc"
487 ))]
488 _ => unsupported_async_backend(),
489 }
490 }
491
492 pub fn data_and_store_mut(&mut self) -> (&mut T, &mut impl AsStoreMut) {
494 match self {
495 #[cfg(feature = "sys")]
496 Self::Sys(f) => f.data_and_store_mut(),
497 #[cfg(all(
498 feature = "sys",
499 any(
500 feature = "wamr",
501 feature = "wasmi",
502 feature = "v8",
503 feature = "js",
504 feature = "jsc"
505 )
506 ))]
507 _ => unsupported_async_backend(),
508 #[cfg(all(
509 not(feature = "sys"),
510 any(
511 feature = "wamr",
512 feature = "wasmi",
513 feature = "v8",
514 feature = "js",
515 feature = "jsc"
516 )
517 ))]
518 _ => unsupported_async_backend::<(&mut T, &mut crate::StoreMut)>(),
519 }
520 }
521
522 pub fn as_function_env_mut(&mut self) -> BackendFunctionEnvMut<'_, T> {
525 match self {
526 #[cfg(feature = "sys")]
527 Self::Sys(f) => BackendFunctionEnvMut::Sys(f.as_function_env_mut()),
528 #[cfg(any(
529 feature = "wamr",
530 feature = "wasmi",
531 feature = "v8",
532 feature = "js",
533 feature = "jsc"
534 ))]
535 _ => unsupported_async_backend(),
536 }
537 }
538}
539
540#[cfg(feature = "experimental-async")]
541impl<T: 'static> AsStoreRef for BackendAsyncFunctionEnvHandleMut<T> {
542 fn as_store_ref(&self) -> StoreRef<'_> {
543 match self {
544 #[cfg(feature = "sys")]
545 Self::Sys(f) => AsStoreRef::as_store_ref(f),
546 #[cfg(any(
547 feature = "wamr",
548 feature = "wasmi",
549 feature = "v8",
550 feature = "js",
551 feature = "jsc"
552 ))]
553 _ => unsupported_async_backend(),
554 }
555 }
556}
557
558#[cfg(feature = "experimental-async")]
559impl<T: 'static> AsStoreMut for BackendAsyncFunctionEnvHandleMut<T> {
560 fn as_store_mut(&mut self) -> StoreMut<'_> {
561 match self {
562 #[cfg(feature = "sys")]
563 Self::Sys(f) => AsStoreMut::as_store_mut(f),
564 #[cfg(any(
565 feature = "wamr",
566 feature = "wasmi",
567 feature = "v8",
568 feature = "js",
569 feature = "jsc"
570 ))]
571 _ => unsupported_async_backend(),
572 }
573 }
574
575 fn objects_mut(&mut self) -> &mut crate::StoreObjects {
576 match self {
577 #[cfg(feature = "sys")]
578 Self::Sys(f) => AsStoreMut::objects_mut(f),
579 #[cfg(any(
580 feature = "wamr",
581 feature = "wasmi",
582 feature = "v8",
583 feature = "js",
584 feature = "jsc"
585 ))]
586 _ => unsupported_async_backend(),
587 }
588 }
589}
590
591#[cfg(feature = "experimental-async")]
592fn unsupported_async_backend<T>() -> T {
593 panic!("async functions are only supported with the `sys` backend");
594}