wasmtime/runtime/component/concurrent/
futures_and_streams.rs

1use super::ConcurrentState;
2use crate::component::func::{self, LiftContext, LowerContext};
3use crate::component::matching::InstanceType;
4use crate::component::{Instance, Val};
5use crate::store::StoreOpaque;
6use crate::vm::{VMFuncRef, VMMemoryDefinition, VMStore};
7use anyhow::Result;
8use std::{marker::PhantomData, mem::MaybeUninit};
9use wasmtime_environ::component::{
10    CanonicalAbiInfo, InterfaceType, TypeComponentLocalErrorContextTableIndex,
11    TypeFutureTableIndex, TypeStreamTableIndex,
12};
13
14/// Represents the readable end of a Component Model `future`.
15///
16/// In order to actually read from or drop this `future`, first convert it to a
17/// [`FutureReader`] using the `into_reader` method.
18///
19/// Note that if a value of this type is dropped without either being converted
20/// to a `FutureReader` or passed to the guest, any writes on the write end may
21/// block forever.
22pub struct HostFuture<T> {
23    _phantom: PhantomData<T>,
24}
25
26impl<T> HostFuture<T> {
27    /// Convert this `HostFuture` into a [`Val`].
28    // See TODO comment for `FutureAny`; this is prone to handle leakage.
29    pub fn into_val(self) -> Val {
30        todo!()
31    }
32}
33
34// SAFETY: This relies on the `ComponentType` implementation for `u32` being
35// safe and correct since we lift and lower future handles as `u32`s.
36unsafe impl<T: Send + Sync> func::ComponentType for HostFuture<T> {
37    const ABI: CanonicalAbiInfo = CanonicalAbiInfo::SCALAR4;
38
39    type Lower = <u32 as func::ComponentType>::Lower;
40
41    fn typecheck(ty: &InterfaceType, _types: &InstanceType<'_>) -> Result<()> {
42        _ = ty;
43        todo!()
44    }
45}
46
47// SAFETY: See the comment on the `ComponentType` `impl` for this type.
48unsafe impl<T: Send + Sync> func::Lower for HostFuture<T> {
49    fn linear_lower_to_flat<U>(
50        &self,
51        cx: &mut LowerContext<'_, U>,
52        ty: InterfaceType,
53        dst: &mut MaybeUninit<Self::Lower>,
54    ) -> Result<()> {
55        _ = (cx, ty, dst);
56        todo!()
57    }
58
59    fn linear_lower_to_memory<U>(
60        &self,
61        cx: &mut LowerContext<'_, U>,
62        ty: InterfaceType,
63        offset: usize,
64    ) -> Result<()> {
65        _ = (cx, ty, offset);
66        todo!()
67    }
68}
69
70// SAFETY: See the comment on the `ComponentType` `impl` for this type.
71unsafe impl<T: Send + Sync> func::Lift for HostFuture<T> {
72    fn linear_lift_from_flat(
73        cx: &mut LiftContext<'_>,
74        ty: InterfaceType,
75        src: &Self::Lower,
76    ) -> Result<Self> {
77        _ = (cx, ty, src);
78        todo!()
79    }
80
81    fn linear_lift_from_memory(
82        cx: &mut LiftContext<'_>,
83        ty: InterfaceType,
84        bytes: &[u8],
85    ) -> Result<Self> {
86        _ = (cx, ty, bytes);
87        todo!()
88    }
89}
90
91/// Transfer ownership of the read end of a future from the host to a guest.
92pub(crate) fn lower_future_to_index<U>(
93    rep: u32,
94    cx: &mut LowerContext<'_, U>,
95    ty: InterfaceType,
96) -> Result<u32> {
97    _ = (rep, cx, ty);
98    todo!()
99}
100
101/// Represents the readable end of a Component Model `future`.
102pub struct FutureReader<T> {
103    _phantom: PhantomData<T>,
104}
105
106/// Represents the readable end of a Component Model `stream`.
107///
108/// In order to actually read from or drop this `stream`, first convert it to a
109/// [`FutureReader`] using the `into_reader` method.
110///
111/// Note that if a value of this type is dropped without either being converted
112/// to a `StreamReader` or passed to the guest, any writes on the write end may
113/// block forever.
114pub struct HostStream<T> {
115    _phantom: PhantomData<T>,
116}
117
118impl<T> HostStream<T> {
119    /// Convert this `HostStream` into a [`Val`].
120    // See TODO comment for `StreamAny`; this is prone to handle leakage.
121    pub fn into_val(self) -> Val {
122        todo!()
123    }
124}
125
126// SAFETY: This relies on the `ComponentType` implementation for `u32` being
127// safe and correct since we lift and lower stream handles as `u32`s.
128unsafe impl<T: Send + Sync> func::ComponentType for HostStream<T> {
129    const ABI: CanonicalAbiInfo = CanonicalAbiInfo::SCALAR4;
130
131    type Lower = <u32 as func::ComponentType>::Lower;
132
133    fn typecheck(ty: &InterfaceType, _types: &InstanceType<'_>) -> Result<()> {
134        _ = ty;
135        todo!()
136    }
137}
138
139// SAFETY: See the comment on the `ComponentType` `impl` for this type.
140unsafe impl<T: Send + Sync> func::Lower for HostStream<T> {
141    fn linear_lower_to_flat<U>(
142        &self,
143        cx: &mut LowerContext<'_, U>,
144        ty: InterfaceType,
145        dst: &mut MaybeUninit<Self::Lower>,
146    ) -> Result<()> {
147        _ = (cx, ty, dst);
148        todo!()
149    }
150
151    fn linear_lower_to_memory<U>(
152        &self,
153        cx: &mut LowerContext<'_, U>,
154        ty: InterfaceType,
155        offset: usize,
156    ) -> Result<()> {
157        _ = (cx, ty, offset);
158        todo!()
159    }
160}
161
162// SAFETY: See the comment on the `ComponentType` `impl` for this type.
163unsafe impl<T: Send + Sync> func::Lift for HostStream<T> {
164    fn linear_lift_from_flat(
165        cx: &mut LiftContext<'_>,
166        ty: InterfaceType,
167        src: &Self::Lower,
168    ) -> Result<Self> {
169        _ = (cx, ty, src);
170        todo!()
171    }
172
173    fn linear_lift_from_memory(
174        cx: &mut LiftContext<'_>,
175        ty: InterfaceType,
176        bytes: &[u8],
177    ) -> Result<Self> {
178        _ = (cx, ty, bytes);
179        todo!()
180    }
181}
182
183/// Transfer ownership of the read end of a stream from the host to a guest.
184pub(crate) fn lower_stream_to_index<U>(
185    rep: u32,
186    cx: &mut LowerContext<'_, U>,
187    ty: InterfaceType,
188) -> Result<u32> {
189    _ = (rep, cx, ty);
190    todo!()
191}
192
193/// Represents the readable end of a Component Model `stream`.
194pub struct StreamReader<T> {
195    _phantom: PhantomData<T>,
196}
197
198/// Represents the writable end of a Component Model `future`.
199pub struct FutureWriter<T> {
200    _phantom: PhantomData<T>,
201}
202
203/// Represents the writable end of a Component Model `stream`.
204pub struct StreamWriter<T> {
205    _phantom: PhantomData<T>,
206}
207
208/// Represents a Component Model `error-context`.
209pub struct ErrorContext {}
210
211impl ErrorContext {
212    /// Convert this `ErrorContext` into a [`Val`].
213    pub fn into_val(self) -> Val {
214        todo!()
215    }
216}
217
218// SAFETY: This relies on the `ComponentType` implementation for `u32` being
219// safe and correct since we lift and lower future handles as `u32`s.
220unsafe impl func::ComponentType for ErrorContext {
221    const ABI: CanonicalAbiInfo = CanonicalAbiInfo::SCALAR4;
222
223    type Lower = <u32 as func::ComponentType>::Lower;
224
225    fn typecheck(ty: &InterfaceType, _types: &InstanceType<'_>) -> Result<()> {
226        _ = ty;
227        todo!()
228    }
229}
230
231// SAFETY: See the comment on the `ComponentType` `impl` for this type.
232unsafe impl func::Lower for ErrorContext {
233    fn linear_lower_to_flat<T>(
234        &self,
235        cx: &mut LowerContext<'_, T>,
236        ty: InterfaceType,
237        dst: &mut MaybeUninit<Self::Lower>,
238    ) -> Result<()> {
239        _ = (cx, ty, dst);
240        todo!()
241    }
242
243    fn linear_lower_to_memory<T>(
244        &self,
245        cx: &mut LowerContext<'_, T>,
246        ty: InterfaceType,
247        offset: usize,
248    ) -> Result<()> {
249        _ = (cx, ty, offset);
250        todo!()
251    }
252}
253
254// SAFETY: See the comment on the `ComponentType` `impl` for this type.
255unsafe impl func::Lift for ErrorContext {
256    fn linear_lift_from_flat(
257        cx: &mut LiftContext<'_>,
258        ty: InterfaceType,
259        src: &Self::Lower,
260    ) -> Result<Self> {
261        _ = (cx, ty, src);
262        todo!()
263    }
264
265    fn linear_lift_from_memory(
266        cx: &mut LiftContext<'_>,
267        ty: InterfaceType,
268        bytes: &[u8],
269    ) -> Result<Self> {
270        _ = (cx, ty, bytes);
271        todo!()
272    }
273}
274
275/// Transfer ownership of an error-context from the host to a guest.
276pub(crate) fn lower_error_context_to_index<U>(
277    rep: u32,
278    cx: &mut LowerContext<'_, U>,
279    ty: InterfaceType,
280) -> Result<u32> {
281    _ = (rep, cx, ty);
282    todo!()
283}
284
285pub(crate) struct ResourcePair {
286    pub(crate) write: u32,
287    pub(crate) read: u32,
288}
289
290impl ConcurrentState {
291    pub(crate) fn future_new(&mut self, ty: TypeFutureTableIndex) -> Result<ResourcePair> {
292        _ = ty;
293        todo!()
294    }
295
296    /// Implements the `future.cancel-write` intrinsic.
297    pub(crate) fn future_cancel_write(
298        &mut self,
299        ty: TypeFutureTableIndex,
300        async_: bool,
301        writer: u32,
302    ) -> Result<u32> {
303        _ = (ty, async_, writer);
304        todo!()
305    }
306
307    /// Implements the `future.cancel-read` intrinsic.
308    pub(crate) fn future_cancel_read(
309        &mut self,
310        ty: TypeFutureTableIndex,
311        async_: bool,
312        reader: u32,
313    ) -> Result<u32> {
314        _ = (ty, async_, reader);
315        todo!()
316    }
317
318    /// Implements the `future.drop-writable` intrinsic.
319    pub(crate) fn future_drop_writable(
320        &mut self,
321        ty: TypeFutureTableIndex,
322        writer: u32,
323    ) -> Result<()> {
324        _ = (ty, writer);
325        todo!()
326    }
327
328    /// Implements the `stream.new` intrinsic.
329    pub(crate) fn stream_new(&mut self, ty: TypeStreamTableIndex) -> Result<ResourcePair> {
330        _ = ty;
331        todo!()
332    }
333
334    /// Implements the `stream.cancel-write` intrinsic.
335    pub(crate) fn stream_cancel_write(
336        &mut self,
337        ty: TypeStreamTableIndex,
338        async_: bool,
339        writer: u32,
340    ) -> Result<u32> {
341        _ = (ty, async_, writer);
342        todo!()
343    }
344
345    /// Implements the `stream.cancel-read` intrinsic.
346    pub(crate) fn stream_cancel_read(
347        &mut self,
348        ty: TypeStreamTableIndex,
349        async_: bool,
350        reader: u32,
351    ) -> Result<u32> {
352        _ = (ty, async_, reader);
353        todo!()
354    }
355
356    /// Implements the `stream.drop-writable` intrinsic.
357    pub(crate) fn stream_drop_writable(
358        &mut self,
359        ty: TypeStreamTableIndex,
360        writer: u32,
361    ) -> Result<()> {
362        _ = (ty, writer);
363        todo!()
364    }
365
366    pub(crate) fn future_transfer(
367        &mut self,
368        src_idx: u32,
369        src: TypeFutureTableIndex,
370        dst: TypeFutureTableIndex,
371    ) -> Result<u32> {
372        _ = (src_idx, src, dst);
373        todo!()
374    }
375
376    pub(crate) fn stream_transfer(
377        &mut self,
378        src_idx: u32,
379        src: TypeStreamTableIndex,
380        dst: TypeStreamTableIndex,
381    ) -> Result<u32> {
382        _ = (src_idx, src, dst);
383        todo!()
384    }
385
386    pub(crate) fn error_context_transfer(
387        &mut self,
388        src_idx: u32,
389        src: TypeComponentLocalErrorContextTableIndex,
390        dst: TypeComponentLocalErrorContextTableIndex,
391    ) -> Result<u32> {
392        _ = (src_idx, src, dst);
393        todo!()
394    }
395
396    pub(crate) fn error_context_drop(
397        &mut self,
398        ty: TypeComponentLocalErrorContextTableIndex,
399        error_context: u32,
400    ) -> Result<()> {
401        _ = (ty, error_context);
402        todo!()
403    }
404}
405
406impl Instance {
407    /// Implements the `future.drop-readable` intrinsic.
408    pub(crate) fn future_drop_readable(
409        self,
410        store: &mut dyn VMStore,
411        ty: TypeFutureTableIndex,
412        reader: u32,
413    ) -> Result<()> {
414        _ = (store, ty, reader);
415        todo!()
416    }
417
418    /// Implements the `stream.drop-readable` intrinsic.
419    pub(crate) fn stream_drop_readable(
420        self,
421        store: &mut dyn VMStore,
422        ty: TypeStreamTableIndex,
423        reader: u32,
424    ) -> Result<()> {
425        _ = (store, ty, reader);
426        todo!()
427    }
428
429    /// Create a new error context for the given component.
430    ///
431    /// SAFETY: `memory` and `realloc` must be valid pointers to their
432    /// respective guest entities.
433    pub(crate) unsafe fn error_context_new(
434        self,
435        store: &mut StoreOpaque,
436        memory: *mut VMMemoryDefinition,
437        realloc: *mut VMFuncRef,
438        string_encoding: u8,
439        ty: TypeComponentLocalErrorContextTableIndex,
440        debug_msg_address: u32,
441        debug_msg_len: u32,
442    ) -> Result<u32> {
443        _ = (
444            store,
445            memory,
446            realloc,
447            string_encoding,
448            ty,
449            debug_msg_address,
450            debug_msg_len,
451        );
452        todo!()
453    }
454}