wasmtime/runtime/component/
concurrent.rs

1use crate::component::{Component, Func, HasData, HasSelf, Instance};
2use crate::store::{StoreInner, StoreOpaque};
3use crate::vm::{VMFuncRef, VMMemoryDefinition, VMStore, component::ComponentInstance};
4use crate::{AsContextMut, StoreContextMut, ValRaw};
5use anyhow::Result;
6use std::any::Any;
7use std::boxed::Box;
8use std::future::Future;
9use std::marker::PhantomData;
10use std::mem::MaybeUninit;
11use std::pin::{Pin, pin};
12use std::task::{Context, Poll, Waker};
13use wasmtime_environ::component::{
14    RuntimeComponentInstanceIndex, TypeComponentLocalErrorContextTableIndex, TypeFutureTableIndex,
15    TypeStreamTableIndex, TypeTupleIndex,
16};
17
18pub(crate) use futures_and_streams::ResourcePair;
19pub use futures_and_streams::{
20    ErrorContext, FutureReader, FutureWriter, HostFuture, HostStream, StreamReader, StreamWriter,
21};
22pub(crate) use futures_and_streams::{
23    lower_error_context_to_index, lower_future_to_index, lower_stream_to_index,
24};
25
26mod futures_and_streams;
27
28#[allow(dead_code)]
29pub enum Status {
30    Starting = 0,
31    Started = 1,
32    Returned = 2,
33    StartCancelled = 3,
34    ReturnCancelled = 4,
35}
36
37impl Status {
38    /// Packs this status and the optional `waitable` provided into a 32-bit
39    /// result that the canonical ABI requires.
40    ///
41    /// The low 4 bits are reserved for the status while the upper 28 bits are
42    /// the waitable, if present.
43    pub fn pack(self, waitable: Option<u32>) -> u32 {
44        _ = waitable;
45        todo!()
46    }
47}
48
49pub(crate) struct ConcurrentState {}
50
51impl ConcurrentState {
52    pub(crate) fn new(component: &Component) -> Self {
53        _ = component;
54        Self {}
55    }
56
57    /// Implements the `context.get` intrinsic.
58    pub(crate) fn context_get(&mut self, slot: u32) -> Result<u32> {
59        _ = slot;
60        todo!()
61    }
62
63    /// Implements the `context.set` intrinsic.
64    pub(crate) fn context_set(&mut self, slot: u32, val: u32) -> Result<()> {
65        _ = (slot, val);
66        todo!()
67    }
68
69    /// Implements the `backpressure.set` intrinsic.
70    pub(crate) fn backpressure_set(
71        &mut self,
72        caller_instance: RuntimeComponentInstanceIndex,
73        enabled: u32,
74    ) -> Result<()> {
75        _ = (caller_instance, enabled);
76        todo!()
77    }
78
79    /// Implements the `waitable-set.new` intrinsic.
80    pub(crate) fn waitable_set_new(
81        &mut self,
82        caller_instance: RuntimeComponentInstanceIndex,
83    ) -> Result<u32> {
84        _ = caller_instance;
85        todo!()
86    }
87
88    /// Implements the `waitable-set.drop` intrinsic.
89    pub(crate) fn waitable_set_drop(
90        &mut self,
91        caller_instance: RuntimeComponentInstanceIndex,
92        set: u32,
93    ) -> Result<()> {
94        _ = (caller_instance, set);
95        todo!()
96    }
97
98    /// Implements the `waitable.join` intrinsic.
99    pub(crate) fn waitable_join(
100        &mut self,
101        caller_instance: RuntimeComponentInstanceIndex,
102        waitable_handle: u32,
103        set_handle: u32,
104    ) -> Result<()> {
105        _ = (caller_instance, waitable_handle, set_handle);
106        todo!()
107    }
108
109    /// Implements the `subtask.drop` intrinsic.
110    pub(crate) fn subtask_drop(
111        &mut self,
112        caller_instance: RuntimeComponentInstanceIndex,
113        task_id: u32,
114    ) -> Result<()> {
115        _ = (caller_instance, task_id);
116        todo!()
117    }
118}
119
120/// Provides access to either store data (via the `get` method) or the store
121/// itself (via [`AsContext`]/[`AsContextMut`]), as well as the component
122/// instance to which the current host task belongs.
123///
124/// See [`Accessor::with`] for details.
125pub struct Access<'a, T: 'static, D: HasData = HasSelf<T>> {
126    _phantom: PhantomData<(&'a (), T, D)>,
127}
128
129/// Provides scoped mutable access to store data in the context of a concurrent
130/// host task future.
131///
132/// This allows multiple host task futures to execute concurrently and access
133/// the store between (but not across) `await` points.
134pub struct Accessor<T: 'static, D = HasSelf<T>>
135where
136    D: HasData,
137{
138    #[expect(dead_code, reason = "to be used in the future")]
139    get: fn() -> *mut dyn VMStore,
140    #[expect(dead_code, reason = "to be used in the future")]
141    get_data: fn(&mut T) -> D::Data<'_>,
142    #[expect(dead_code, reason = "to be used in the future")]
143    instance: Instance,
144}
145
146impl<T, D> Accessor<T, D>
147where
148    D: HasData,
149{
150    #[doc(hidden)]
151    pub fn with_data<D2: HasData>(
152        &mut self,
153        get_data: fn(&mut T) -> D2::Data<'_>,
154    ) -> Accessor<T, D2> {
155        let _ = get_data;
156        todo!()
157    }
158}
159
160impl Instance {
161    /// Wrap the specified host function in a future which will call it, passing
162    /// it an `&mut Accessor<T>`.
163    ///
164    /// See the `Accessor` documentation for details.
165    pub(crate) fn wrap_call<T: 'static, F, R>(
166        self,
167        store: StoreContextMut<T>,
168        closure: F,
169    ) -> impl Future<Output = Result<R>> + 'static
170    where
171        T: 'static,
172        F: FnOnce(&mut Accessor<T>) -> Pin<Box<dyn Future<Output = Result<R>> + Send + '_>>
173            + Send
174            + Sync
175            + 'static,
176        R: Send + Sync + 'static,
177    {
178        _ = (store, closure);
179        async { todo!() }
180    }
181
182    /// Poll the specified future once on behalf of a guest->host call using an
183    /// async-lowered import.
184    ///
185    /// If it returns `Ready`, return `Ok(None)`.  Otherwise, if it returns
186    /// `Pending`, add it to the set of futures to be polled as part of this
187    /// instance's event loop until it completes, and then return
188    /// `Ok(Some(handle))` where `handle` is the waitable handle to return.
189    ///
190    /// Whether the future returns `Ready` immediately or later, the `lower`
191    /// function will be used to lower the result, if any, into the guest caller's
192    /// stack and linear memory unless the task has been cancelled.
193    pub(crate) fn first_poll<T: 'static, R: Send + 'static>(
194        self,
195        mut store: StoreContextMut<T>,
196        future: impl Future<Output = Result<R>> + Send + 'static,
197        caller_instance: RuntimeComponentInstanceIndex,
198        lower: impl FnOnce(StoreContextMut<T>, Instance, R) -> Result<()> + Send + 'static,
199    ) -> Result<Option<u32>> {
200        _ = (&mut store, future, caller_instance, lower);
201        todo!()
202    }
203
204    /// Poll the specified future until it completes on behalf of a guest->host
205    /// call using a sync-lowered import.
206    ///
207    /// This is similar to `Self::first_poll` except it's for sync-lowered
208    /// imports, meaning we don't need to handle cancellation and we can block
209    /// the caller until the task completes, at which point the caller can
210    /// handle lowering the result to the guest's stack and linear memory.
211    pub(crate) fn poll_and_block<R: Send + Sync + 'static>(
212        self,
213        store: &mut dyn VMStore,
214        future: impl Future<Output = Result<R>> + Send + 'static,
215        caller_instance: RuntimeComponentInstanceIndex,
216    ) -> Result<R> {
217        _ = (store, caller_instance);
218        match pin!(future).poll(&mut Context::from_waker(Waker::noop())) {
219            Poll::Ready(result) => result,
220            Poll::Pending => {
221                todo!()
222            }
223        }
224    }
225
226    /// TODO: docs
227    pub async fn run<F>(&self, mut store: impl AsContextMut, fut: F) -> Result<F::Output>
228    where
229        F: Future,
230    {
231        _ = (&mut store, fut);
232        todo!()
233    }
234
235    /// Implements the `task.return` intrinsic, lifting the result for the
236    /// current guest task.
237    ///
238    /// SAFETY: The `memory` and `storage` pointers must be valid, and `storage`
239    /// must contain at least `storage_len` items.
240    pub(crate) unsafe fn task_return(
241        self,
242        store: &mut dyn VMStore,
243        ty: TypeTupleIndex,
244        memory: *mut VMMemoryDefinition,
245        string_encoding: u8,
246        storage: *mut ValRaw,
247        storage_len: usize,
248    ) -> Result<()> {
249        _ = (store, ty, memory, string_encoding, storage, storage_len);
250        todo!()
251    }
252
253    /// Implements the `task.cancel` intrinsic.
254    pub(crate) fn task_cancel(
255        self,
256        store: &mut dyn VMStore,
257        _caller_instance: RuntimeComponentInstanceIndex,
258    ) -> Result<()> {
259        _ = store;
260        todo!()
261    }
262
263    /// Implements the `waitable-set.wait` intrinsic.
264    pub(crate) fn waitable_set_wait(
265        self,
266        store: &mut dyn VMStore,
267        caller_instance: RuntimeComponentInstanceIndex,
268        async_: bool,
269        memory: *mut VMMemoryDefinition,
270        set: u32,
271        payload: u32,
272    ) -> Result<u32> {
273        _ = (store, caller_instance, async_, memory, set, payload);
274        todo!()
275    }
276
277    /// Implements the `waitable-set.poll` intrinsic.
278    pub(crate) fn waitable_set_poll(
279        self,
280        store: &mut dyn VMStore,
281        caller_instance: RuntimeComponentInstanceIndex,
282        async_: bool,
283        memory: *mut VMMemoryDefinition,
284        set: u32,
285        payload: u32,
286    ) -> Result<u32> {
287        _ = (store, caller_instance, async_, memory, set, payload);
288        todo!()
289    }
290
291    /// Implements the `yield` intrinsic.
292    pub(crate) fn yield_(self, store: &mut dyn VMStore, async_: bool) -> Result<bool> {
293        _ = (store, async_);
294        todo!()
295    }
296
297    /// Implements the `subtask.cancel` intrinsic.
298    pub(crate) fn subtask_cancel(
299        self,
300        store: &mut dyn VMStore,
301        caller_instance: RuntimeComponentInstanceIndex,
302        async_: bool,
303        task_id: u32,
304    ) -> Result<u32> {
305        _ = (store, caller_instance, async_, task_id);
306        todo!()
307    }
308
309    /// Convenience function to reduce boilerplate.
310    pub(crate) fn concurrent_state_mut<'a>(
311        &self,
312        store: &'a mut StoreOpaque,
313    ) -> &'a mut ConcurrentState {
314        _ = store;
315        todo!()
316    }
317}
318
319/// Trait representing component model ABI async intrinsics and fused adapter
320/// helper functions.
321pub unsafe trait VMComponentAsyncStore {
322    /// A helper function for fused adapter modules involving calls where the
323    /// one of the caller or callee is async.
324    ///
325    /// This helper is not used when the caller and callee both use the sync
326    /// ABI, only when at least one is async is this used.
327    unsafe fn prepare_call(
328        &mut self,
329        instance: Instance,
330        memory: *mut VMMemoryDefinition,
331        start: *mut VMFuncRef,
332        return_: *mut VMFuncRef,
333        caller_instance: RuntimeComponentInstanceIndex,
334        callee_instance: RuntimeComponentInstanceIndex,
335        task_return_type: TypeTupleIndex,
336        string_encoding: u8,
337        result_count: u32,
338        storage: *mut ValRaw,
339        storage_len: usize,
340    ) -> Result<()>;
341
342    /// A helper function for fused adapter modules involving calls where the
343    /// caller is sync-lowered but the callee is async-lifted.
344    unsafe fn sync_start(
345        &mut self,
346        instance: Instance,
347        callback: *mut VMFuncRef,
348        callee: *mut VMFuncRef,
349        param_count: u32,
350        storage: *mut MaybeUninit<ValRaw>,
351        storage_len: usize,
352    ) -> Result<()>;
353
354    /// A helper function for fused adapter modules involving calls where the
355    /// caller is async-lowered.
356    unsafe fn async_start(
357        &mut self,
358        instance: Instance,
359        callback: *mut VMFuncRef,
360        post_return: *mut VMFuncRef,
361        callee: *mut VMFuncRef,
362        param_count: u32,
363        result_count: u32,
364        flags: u32,
365    ) -> Result<u32>;
366
367    /// The `backpressure.set` intrinsic.
368    fn backpressure_set(
369        &mut self,
370        caller_instance: RuntimeComponentInstanceIndex,
371        enabled: u32,
372    ) -> Result<()>;
373
374    /// The `task.return` intrinsic.
375    fn task_return(
376        &mut self,
377        instance: &mut ComponentInstance,
378        ty: TypeTupleIndex,
379        storage: *mut ValRaw,
380        storage_len: usize,
381    ) -> Result<()>;
382
383    /// The `waitable-set.new` intrinsic.
384    fn waitable_set_new(
385        &mut self,
386        instance: &mut ComponentInstance,
387        caller_instance: RuntimeComponentInstanceIndex,
388    ) -> Result<u32>;
389
390    /// The `waitable-set.wait` intrinsic.
391    fn waitable_set_wait(
392        &mut self,
393        instance: &mut ComponentInstance,
394        caller_instance: RuntimeComponentInstanceIndex,
395        set: u32,
396        async_: bool,
397        memory: *mut VMMemoryDefinition,
398        payload: u32,
399    ) -> Result<u32>;
400
401    /// The `waitable-set.poll` intrinsic.
402    fn waitable_set_poll(
403        &mut self,
404        instance: &mut ComponentInstance,
405        caller_instance: RuntimeComponentInstanceIndex,
406        set: u32,
407        async_: bool,
408        memory: *mut VMMemoryDefinition,
409        payload: u32,
410    ) -> Result<u32>;
411
412    /// The `waitable-set.drop` intrinsic.
413    fn waitable_set_drop(
414        &mut self,
415        instance: &mut ComponentInstance,
416        caller_instance: RuntimeComponentInstanceIndex,
417        set: u32,
418    ) -> Result<()>;
419
420    /// The `waitable.join` intrinsic.
421    fn waitable_join(
422        &mut self,
423        instance: &mut ComponentInstance,
424        caller_instance: RuntimeComponentInstanceIndex,
425        set: u32,
426        waitable: u32,
427    ) -> Result<()>;
428
429    /// The `yield` intrinsic.
430    fn yield_(&mut self, instance: &mut ComponentInstance, async_: bool) -> Result<()>;
431
432    /// The `subtask.drop` intrinsic.
433    fn subtask_drop(
434        &mut self,
435        instance: &mut ComponentInstance,
436        caller_instance: RuntimeComponentInstanceIndex,
437        task_id: u32,
438    ) -> Result<()>;
439
440    /// A helper function for fused adapter modules involving calls where the
441    /// caller is sync-lowered but the callee is async-lifted.
442    fn sync_enter(
443        &mut self,
444        start: *mut VMFuncRef,
445        return_: *mut VMFuncRef,
446        caller_instance: RuntimeComponentInstanceIndex,
447        task_return_type: TypeTupleIndex,
448        result_count: u32,
449        storage: *mut ValRaw,
450        storage_len: usize,
451    ) -> Result<()>;
452
453    /// A helper function for fused adapter modules involving calls where the
454    /// caller is sync-lowered but the callee is async-lifted.
455    fn sync_exit(
456        &mut self,
457        instance: &mut ComponentInstance,
458        callback: *mut VMFuncRef,
459        caller_instance: RuntimeComponentInstanceIndex,
460        callee: *mut VMFuncRef,
461        callee_instance: RuntimeComponentInstanceIndex,
462        param_count: u32,
463        storage: *mut MaybeUninit<ValRaw>,
464        storage_len: usize,
465    ) -> Result<()>;
466
467    /// A helper function for fused adapter modules involving calls where the
468    /// caller is async-lowered.
469    fn async_enter(
470        &mut self,
471        start: *mut VMFuncRef,
472        return_: *mut VMFuncRef,
473        caller_instance: RuntimeComponentInstanceIndex,
474        task_return_type: TypeTupleIndex,
475        params: u32,
476        results: u32,
477    ) -> Result<()>;
478
479    /// A helper function for fused adapter modules involving calls where the
480    /// caller is async-lowered.
481    fn async_exit(
482        &mut self,
483        instance: &mut ComponentInstance,
484        callback: *mut VMFuncRef,
485        post_return: *mut VMFuncRef,
486        caller_instance: RuntimeComponentInstanceIndex,
487        callee: *mut VMFuncRef,
488        callee_instance: RuntimeComponentInstanceIndex,
489        param_count: u32,
490        result_count: u32,
491        flags: u32,
492    ) -> Result<u32>;
493
494    /// The `future.write` intrinsic.
495    unsafe fn future_write(
496        &mut self,
497        instance: Instance,
498        memory: *mut VMMemoryDefinition,
499        realloc: *mut VMFuncRef,
500        string_encoding: u8,
501        async_: bool,
502        ty: TypeFutureTableIndex,
503        future: u32,
504        address: u32,
505    ) -> Result<u32>;
506
507    /// The `future.read` intrinsic.
508    unsafe fn future_read(
509        &mut self,
510        instance: Instance,
511        memory: *mut VMMemoryDefinition,
512        realloc: *mut VMFuncRef,
513        string_encoding: u8,
514        async_: bool,
515        ty: TypeFutureTableIndex,
516        future: u32,
517        address: u32,
518    ) -> Result<u32>;
519
520    /// The `stream.write` intrinsic.
521    unsafe fn stream_write(
522        &mut self,
523        instance: Instance,
524        memory: *mut VMMemoryDefinition,
525        realloc: *mut VMFuncRef,
526        string_encoding: u8,
527        async_: bool,
528        ty: TypeStreamTableIndex,
529        stream: u32,
530        address: u32,
531        count: u32,
532    ) -> Result<u32>;
533
534    /// The `stream.read` intrinsic.
535    unsafe fn stream_read(
536        &mut self,
537        instance: Instance,
538        memory: *mut VMMemoryDefinition,
539        realloc: *mut VMFuncRef,
540        string_encoding: u8,
541        async_: bool,
542        ty: TypeStreamTableIndex,
543        stream: u32,
544        address: u32,
545        count: u32,
546    ) -> Result<u32>;
547
548    /// The "fast-path" implementation of the `stream.write` intrinsic for
549    /// "flat" (i.e. memcpy-able) payloads.
550    unsafe fn flat_stream_write(
551        &mut self,
552        instance: Instance,
553        memory: *mut VMMemoryDefinition,
554        realloc: *mut VMFuncRef,
555        async_: bool,
556        ty: TypeStreamTableIndex,
557        payload_size: u32,
558        payload_align: u32,
559        stream: u32,
560        address: u32,
561        count: u32,
562    ) -> Result<u32>;
563
564    /// The "fast-path" implementation of the `stream.read` intrinsic for "flat"
565    /// (i.e. memcpy-able) payloads.
566    unsafe fn flat_stream_read(
567        &mut self,
568        instance: Instance,
569        memory: *mut VMMemoryDefinition,
570        realloc: *mut VMFuncRef,
571        async_: bool,
572        ty: TypeStreamTableIndex,
573        payload_size: u32,
574        payload_align: u32,
575        stream: u32,
576        address: u32,
577        count: u32,
578    ) -> Result<u32>;
579
580    /// The `error-context.debug-message` intrinsic.
581    unsafe fn error_context_debug_message(
582        &mut self,
583        instance: Instance,
584        memory: *mut VMMemoryDefinition,
585        realloc: *mut VMFuncRef,
586        string_encoding: u8,
587        ty: TypeComponentLocalErrorContextTableIndex,
588        err_ctx_handle: u32,
589        debug_msg_address: u32,
590    ) -> Result<()>;
591}
592
593unsafe impl<T> VMComponentAsyncStore for StoreInner<T> {
594    unsafe fn prepare_call(
595        &mut self,
596        instance: Instance,
597        memory: *mut VMMemoryDefinition,
598        start: *mut VMFuncRef,
599        return_: *mut VMFuncRef,
600        caller_instance: RuntimeComponentInstanceIndex,
601        callee_instance: RuntimeComponentInstanceIndex,
602        task_return_type: TypeTupleIndex,
603        string_encoding: u8,
604        result_count: u32,
605        storage: *mut ValRaw,
606        storage_len: usize,
607    ) -> Result<()> {
608        _ = (
609            instance,
610            memory,
611            start,
612            return_,
613            caller_instance,
614            callee_instance,
615            task_return_type,
616            string_encoding,
617            result_count,
618            storage,
619            storage_len,
620        );
621        todo!()
622    }
623
624    unsafe fn sync_start(
625        &mut self,
626        instance: Instance,
627        callback: *mut VMFuncRef,
628        callee: *mut VMFuncRef,
629        param_count: u32,
630        storage: *mut MaybeUninit<ValRaw>,
631        storage_len: usize,
632    ) -> Result<()> {
633        _ = (
634            instance,
635            callback,
636            callee,
637            param_count,
638            storage,
639            storage_len,
640        );
641        todo!()
642    }
643
644    unsafe fn async_start(
645        &mut self,
646        instance: Instance,
647        callback: *mut VMFuncRef,
648        post_return: *mut VMFuncRef,
649        callee: *mut VMFuncRef,
650        param_count: u32,
651        result_count: u32,
652        flags: u32,
653    ) -> Result<u32> {
654        _ = (
655            instance,
656            callback,
657            post_return,
658            callee,
659            param_count,
660            result_count,
661            flags,
662        );
663        todo!()
664    }
665
666    fn backpressure_set(
667        &mut self,
668        caller_instance: RuntimeComponentInstanceIndex,
669        enabled: u32,
670    ) -> Result<()> {
671        _ = (caller_instance, enabled);
672        todo!()
673    }
674
675    fn task_return(
676        &mut self,
677        instance: &mut ComponentInstance,
678        ty: TypeTupleIndex,
679        storage: *mut ValRaw,
680        storage_len: usize,
681    ) -> Result<()> {
682        _ = (instance, ty, storage, storage_len);
683        todo!()
684    }
685
686    fn waitable_set_new(
687        &mut self,
688        instance: &mut ComponentInstance,
689        caller_instance: RuntimeComponentInstanceIndex,
690    ) -> Result<u32> {
691        _ = (instance, caller_instance);
692        todo!();
693    }
694
695    fn waitable_set_wait(
696        &mut self,
697        instance: &mut ComponentInstance,
698        caller_instance: RuntimeComponentInstanceIndex,
699        set: u32,
700        async_: bool,
701        memory: *mut VMMemoryDefinition,
702        payload: u32,
703    ) -> Result<u32> {
704        _ = (instance, caller_instance, set, async_, memory, payload);
705        todo!();
706    }
707
708    fn waitable_set_poll(
709        &mut self,
710        instance: &mut ComponentInstance,
711        caller_instance: RuntimeComponentInstanceIndex,
712        set: u32,
713        async_: bool,
714        memory: *mut VMMemoryDefinition,
715        payload: u32,
716    ) -> Result<u32> {
717        _ = (instance, caller_instance, set, async_, memory, payload);
718        todo!();
719    }
720
721    fn waitable_set_drop(
722        &mut self,
723        instance: &mut ComponentInstance,
724        caller_instance: RuntimeComponentInstanceIndex,
725        set: u32,
726    ) -> Result<()> {
727        _ = (instance, caller_instance, set);
728        todo!();
729    }
730
731    fn waitable_join(
732        &mut self,
733        instance: &mut ComponentInstance,
734        caller_instance: RuntimeComponentInstanceIndex,
735        set: u32,
736        waitable: u32,
737    ) -> Result<()> {
738        _ = (instance, caller_instance, set, waitable);
739        todo!();
740    }
741
742    fn yield_(&mut self, instance: &mut ComponentInstance, async_: bool) -> Result<()> {
743        _ = (instance, async_);
744        todo!()
745    }
746
747    fn subtask_drop(
748        &mut self,
749        instance: &mut ComponentInstance,
750        caller_instance: RuntimeComponentInstanceIndex,
751        task_id: u32,
752    ) -> Result<()> {
753        _ = (instance, caller_instance, task_id);
754        todo!()
755    }
756
757    fn sync_enter(
758        &mut self,
759        start: *mut VMFuncRef,
760        return_: *mut VMFuncRef,
761        caller_instance: RuntimeComponentInstanceIndex,
762        task_return_type: TypeTupleIndex,
763        result_count: u32,
764        storage: *mut ValRaw,
765        storage_len: usize,
766    ) -> Result<()> {
767        _ = (
768            start,
769            return_,
770            caller_instance,
771            task_return_type,
772            result_count,
773            storage,
774            storage_len,
775        );
776        todo!()
777    }
778
779    fn sync_exit(
780        &mut self,
781        instance: &mut ComponentInstance,
782        callback: *mut VMFuncRef,
783        caller_instance: RuntimeComponentInstanceIndex,
784        callee: *mut VMFuncRef,
785        callee_instance: RuntimeComponentInstanceIndex,
786        param_count: u32,
787        storage: *mut MaybeUninit<ValRaw>,
788        storage_len: usize,
789    ) -> Result<()> {
790        _ = (
791            instance,
792            callback,
793            caller_instance,
794            callee,
795            callee_instance,
796            param_count,
797            storage,
798            storage_len,
799        );
800        todo!()
801    }
802
803    fn async_enter(
804        &mut self,
805        start: *mut VMFuncRef,
806        return_: *mut VMFuncRef,
807        caller_instance: RuntimeComponentInstanceIndex,
808        task_return_type: TypeTupleIndex,
809        params: u32,
810        results: u32,
811    ) -> Result<()> {
812        _ = (
813            start,
814            return_,
815            caller_instance,
816            task_return_type,
817            params,
818            results,
819        );
820        todo!()
821    }
822
823    fn async_exit(
824        &mut self,
825        instance: &mut ComponentInstance,
826        callback: *mut VMFuncRef,
827        post_return: *mut VMFuncRef,
828        caller_instance: RuntimeComponentInstanceIndex,
829        callee: *mut VMFuncRef,
830        callee_instance: RuntimeComponentInstanceIndex,
831        param_count: u32,
832        result_count: u32,
833        flags: u32,
834    ) -> Result<u32> {
835        _ = (
836            instance,
837            callback,
838            post_return,
839            caller_instance,
840            callee,
841            callee_instance,
842            param_count,
843            result_count,
844            flags,
845        );
846        todo!()
847    }
848
849    unsafe fn future_write(
850        &mut self,
851        instance: Instance,
852        memory: *mut VMMemoryDefinition,
853        realloc: *mut VMFuncRef,
854        string_encoding: u8,
855        async_: bool,
856        ty: TypeFutureTableIndex,
857        future: u32,
858        address: u32,
859    ) -> Result<u32> {
860        _ = (
861            instance,
862            memory,
863            realloc,
864            string_encoding,
865            async_,
866            ty,
867            future,
868            address,
869        );
870        todo!()
871    }
872
873    unsafe fn future_read(
874        &mut self,
875        instance: Instance,
876        memory: *mut VMMemoryDefinition,
877        realloc: *mut VMFuncRef,
878        string_encoding: u8,
879        async_: bool,
880        ty: TypeFutureTableIndex,
881        future: u32,
882        address: u32,
883    ) -> Result<u32> {
884        _ = (
885            instance,
886            memory,
887            realloc,
888            string_encoding,
889            async_,
890            ty,
891            future,
892            address,
893        );
894        todo!()
895    }
896
897    unsafe fn stream_write(
898        &mut self,
899        instance: Instance,
900        memory: *mut VMMemoryDefinition,
901        realloc: *mut VMFuncRef,
902        string_encoding: u8,
903        async_: bool,
904        ty: TypeStreamTableIndex,
905        stream: u32,
906        address: u32,
907        count: u32,
908    ) -> Result<u32> {
909        _ = (
910            instance,
911            memory,
912            realloc,
913            string_encoding,
914            async_,
915            ty,
916            stream,
917            address,
918            count,
919        );
920        todo!()
921    }
922
923    unsafe fn stream_read(
924        &mut self,
925        instance: Instance,
926        memory: *mut VMMemoryDefinition,
927        realloc: *mut VMFuncRef,
928        string_encoding: u8,
929        async_: bool,
930        ty: TypeStreamTableIndex,
931        stream: u32,
932        address: u32,
933        count: u32,
934    ) -> Result<u32> {
935        _ = (
936            instance,
937            memory,
938            realloc,
939            string_encoding,
940            async_,
941            ty,
942            stream,
943            address,
944            count,
945        );
946        todo!()
947    }
948
949    unsafe fn flat_stream_write(
950        &mut self,
951        instance: Instance,
952        memory: *mut VMMemoryDefinition,
953        realloc: *mut VMFuncRef,
954        async_: bool,
955        ty: TypeStreamTableIndex,
956        payload_size: u32,
957        payload_align: u32,
958        stream: u32,
959        address: u32,
960        count: u32,
961    ) -> Result<u32> {
962        _ = (
963            instance,
964            memory,
965            realloc,
966            async_,
967            ty,
968            payload_size,
969            payload_align,
970            stream,
971            address,
972            count,
973        );
974        todo!()
975    }
976
977    unsafe fn flat_stream_read(
978        &mut self,
979        instance: Instance,
980        memory: *mut VMMemoryDefinition,
981        realloc: *mut VMFuncRef,
982        async_: bool,
983        ty: TypeStreamTableIndex,
984        payload_size: u32,
985        payload_align: u32,
986        stream: u32,
987        address: u32,
988        count: u32,
989    ) -> Result<u32> {
990        _ = (
991            instance,
992            memory,
993            realloc,
994            async_,
995            ty,
996            payload_size,
997            payload_align,
998            stream,
999            address,
1000            count,
1001        );
1002        todo!()
1003    }
1004
1005    unsafe fn error_context_debug_message(
1006        &mut self,
1007        instance: Instance,
1008        memory: *mut VMMemoryDefinition,
1009        realloc: *mut VMFuncRef,
1010        string_encoding: u8,
1011        ty: TypeComponentLocalErrorContextTableIndex,
1012        err_ctx_handle: u32,
1013        debug_msg_address: u32,
1014    ) -> Result<()> {
1015        _ = (
1016            instance,
1017            memory,
1018            realloc,
1019            string_encoding,
1020            ty,
1021            err_ctx_handle,
1022            debug_msg_address,
1023        );
1024        todo!()
1025    }
1026}
1027
1028pub(crate) struct PreparedCall<R> {
1029    _phantom: PhantomData<R>,
1030}
1031
1032/// Prepare a call to the specified exported Wasm function, providing functions
1033/// for lowering the parameters and lifting the result.
1034///
1035/// To enqueue the returned `PreparedCall` in the `ComponentInstance`'s event
1036/// loop, use `queue_call`.
1037///
1038/// Note that this function is used in `TypedFunc::call_async`, which accepts
1039/// parameters of a generic type which might not be `'static`.  However the
1040/// `GuestTask` created by this function must be `'static`, so it can't safely
1041/// close over those parameters.  Instead, `PreparedCall` has a `params` field
1042/// of type `Arc<AtomicPtr<u8>>`, which the caller is responsible for setting to
1043/// a valid, non-null pointer to the params prior to polling the event loop (at
1044/// least until the parameters have been lowered), and then resetting back to
1045/// null afterward.  That ensures that the lowering code never sees a stale
1046/// pointer, even if the application `drop`s or `mem::forget`s the future
1047/// returned by `TypedFunc::call_async`.
1048///
1049/// In the case where the parameters are passed using a type that _is_
1050/// `'static`, they can be boxed and stored in `PreparedCall::params`
1051/// indefinitely; `drop_params` will be called when they are no longer needed.
1052pub(crate) fn prepare_call<T, R>(
1053    mut store: StoreContextMut<T>,
1054    lower_params: impl FnOnce(Func, StoreContextMut<T>, &mut [MaybeUninit<ValRaw>]) -> Result<()>
1055    + Send
1056    + Sync
1057    + 'static,
1058    lift_result: impl FnOnce(Func, &mut StoreOpaque, &[ValRaw]) -> Result<Box<dyn Any + Send + Sync>>
1059    + Send
1060    + Sync
1061    + 'static,
1062    handle: Func,
1063    param_count: usize,
1064) -> Result<PreparedCall<R>> {
1065    let _ = (&mut store, lower_params, lift_result, handle, param_count);
1066    todo!()
1067}
1068
1069/// Queue a call previously prepared using `prepare_call` to be run as part of
1070/// the associated `ComponentInstance`'s event loop.
1071///
1072/// The returned future will resolve to the result once it is available, but
1073/// must only be polled via the instance's event loop.  See `Instance::run` for
1074/// details.
1075pub(crate) fn queue_call<T: 'static, R: Send + 'static>(
1076    mut store: StoreContextMut<T>,
1077    prepared: PreparedCall<R>,
1078) -> Result<impl Future<Output = Result<R>> + Send + 'static + use<T, R>> {
1079    _ = (&mut store, prepared);
1080    Ok(async { todo!() })
1081}