Skip to main content

wasmtime_wasi/p2/
bindings.rs

1//! Auto-generated bindings for WASI interfaces.
2//!
3//! This module contains the output of the [`bindgen!`] macro when run over
4//! the `wasi:cli/command` world. That means this module has all the generated
5//! types for WASI for all of its base interfaces used by the CLI world. This
6//! module itself by default contains bindings for `async`-related traits. The
7//! [`sync`] module contains bindings for a non-`async` version of types.
8//!
9//! [`bindgen!`]: https://docs.rs/wasmtime/latest/wasmtime/component/macro.bindgen.html
10//!
11//! # Examples
12//!
13//! If you have a WIT world which refers to WASI interfaces you probably want to
14//! use this modules's bindings rather than generate fresh bindings. That can be
15//! done using the `with` option to [`bindgen!`]:
16//!
17//! ```rust
18//! use wasmtime_wasi::{WasiCtx, WasiCtxView, WasiView};
19//! use wasmtime::{Result, Engine};
20//! use wasmtime::component::{Linker, ResourceTable, HasSelf};
21//!
22//! wasmtime::component::bindgen!({
23//!     inline: "
24//!         package example:wasi;
25//!
26//!         // An example of extending the `wasi:cli/command` world with a
27//!         // custom host interface.
28//!         world my-world {
29//!             include wasi:cli/command@0.2.12;
30//!
31//!             import custom-host;
32//!         }
33//!
34//!         interface custom-host {
35//!             my-custom-function: func();
36//!         }
37//!     ",
38//!     path: "src/p2/wit",
39//!     with: {
40//!         "wasi": wasmtime_wasi::p2::bindings,
41//!     },
42//!     imports: { default: async },
43//! });
44//!
45//! struct MyState {
46//!     table: ResourceTable,
47//!     ctx: WasiCtx,
48//! }
49//!
50//! impl example::wasi::custom_host::Host for MyState {
51//!     async fn my_custom_function(&mut self) {
52//!         // ..
53//!     }
54//! }
55//!
56//! impl WasiView for MyState {
57//!     fn ctx(&mut self) -> WasiCtxView<'_> {
58//!         WasiCtxView { ctx: &mut self.ctx, table: &mut self.table }
59//!     }
60//! }
61//!
62//! fn main() -> Result<()> {
63//!     let engine = Engine::default();
64//!     let mut linker: Linker<MyState> = Linker::new(&engine);
65//!     wasmtime_wasi::p2::add_to_linker_async(&mut linker)?;
66//!     example::wasi::custom_host::add_to_linker::<_, HasSelf<_>>(&mut linker, |state| state)?;
67//!
68//!     // .. use `Linker` to instantiate component ...
69//!
70//!     Ok(())
71//! }
72//! ```
73
74/// Synchronous-generated bindings for WASI interfaces.
75///
76/// This is the same as the top-level [`bindings`](crate::p2::bindings) submodule of
77/// this module except that it's for synchronous calls.
78///
79/// # Examples
80///
81/// If you have a WIT world which refers to WASI interfaces you probably want to
82/// use this modules's bindings rather than generate fresh bindings. That can be
83/// done using the `with` option to `bindgen!`:
84///
85/// ```rust
86/// use wasmtime_wasi::{WasiCtx, WasiCtxView, WasiView};
87/// use wasmtime::{Result, Engine};
88/// use wasmtime::component::{Linker, ResourceTable, HasSelf};
89///
90/// wasmtime::component::bindgen!({
91///     inline: "
92///         package example:wasi;
93///
94///         // An example of extending the `wasi:cli/command` world with a
95///         // custom host interface.
96///         world my-world {
97///             include wasi:cli/command@0.2.12;
98///
99///             import custom-host;
100///         }
101///
102///         interface custom-host {
103///             my-custom-function: func();
104///         }
105///     ",
106///     path: "src/p2/wit",
107///     with: {
108///         "wasi": wasmtime_wasi::p2::bindings::sync,
109///     },
110///     // This is required for bindings using `wasmtime-wasi` and it otherwise
111///     // isn't the default for non-async bindings.
112///     require_store_data_send: true,
113/// });
114///
115/// struct MyState {
116///     table: ResourceTable,
117///     ctx: WasiCtx,
118/// }
119///
120/// impl example::wasi::custom_host::Host for MyState {
121///     fn my_custom_function(&mut self) {
122///         // ..
123///     }
124/// }
125///
126/// impl WasiView for MyState {
127///     fn ctx(&mut self) -> WasiCtxView<'_> {
128///         WasiCtxView { ctx: &mut self.ctx, table: &mut self.table }
129///     }
130/// }
131///
132/// fn main() -> Result<()> {
133///     let engine = Engine::default();
134///     let mut linker: Linker<MyState> = Linker::new(&engine);
135///     wasmtime_wasi::p2::add_to_linker_sync(&mut linker)?;
136///     example::wasi::custom_host::add_to_linker::<_, HasSelf<_>>(&mut linker, |state| state)?;
137///
138///     // .. use `Linker` to instantiate component ...
139///
140///     Ok(())
141/// }
142/// ```
143pub mod sync {
144    mod generated {
145        use crate::p2::{FsError, SocketError};
146        use wasmtime_wasi_io::streams::StreamError;
147
148        wasmtime::component::bindgen!({
149            path: "src/p2/wit",
150            world: "wasi:cli/command",
151            trappable_error_type: {
152                "wasi:io/streams.stream-error" => StreamError,
153                "wasi:filesystem/types.error-code" => FsError,
154                "wasi:sockets/network.error-code" => SocketError,
155            },
156            imports: { default: tracing | trappable },
157            with: {
158                // These interfaces contain only synchronous methods, so they
159                // can be aliased directly
160                "wasi:clocks": crate::p2::bindings::clocks,
161                "wasi:random": crate::p2::bindings::random,
162                "wasi:cli": crate::p2::bindings::cli,
163                "wasi:filesystem/preopens": crate::p2::bindings::filesystem::preopens,
164                "wasi:sockets/network": crate::p2::bindings::sockets::network,
165
166                // Configure the resource types of the bound interfaces here
167                // to be the same as the async versions of the resources, that
168                // way everything has the same type.
169                "wasi:filesystem/types.descriptor": crate::filesystem::Descriptor,
170                "wasi:filesystem/types.directory-entry-stream": super::super::filesystem::types::DirectoryEntryStream,
171                "wasi:sockets/tcp.tcp-socket": super::super::sockets::tcp::TcpSocket,
172                "wasi:sockets/udp.incoming-datagram-stream": super::super::sockets::udp::IncomingDatagramStream,
173                "wasi:sockets/udp.outgoing-datagram-stream": super::super::sockets::udp::OutgoingDatagramStream,
174                "wasi:sockets/udp.udp-socket": crate::p2::UdpSocket,
175                "wasi:sockets/ip-name-lookup.resolve-address-stream": crate::p2::ip_name_lookup::ResolveAddressStream,
176
177                // Error host trait from wasmtime-wasi-io is synchronous, so we can alias it
178                "wasi:io/error": wasmtime_wasi_io::bindings::wasi::io::error,
179                // Configure the resource types from wasmtime-wasi-io, though
180                // this bindgen will make a new synchronous Host traits
181                "wasi:io/poll.pollable": wasmtime_wasi_io::poll::DynPollable,
182                "wasi:io/streams.input-stream": wasmtime_wasi_io::streams::DynInputStream,
183                "wasi:io/streams.output-stream": wasmtime_wasi_io::streams::DynOutputStream,
184
185            },
186            require_store_data_send: true,
187        });
188    }
189    pub use self::generated::exports;
190    pub use self::generated::wasi::*;
191
192    /// Synchronous bindings to execute and run a `wasi:cli/command`.
193    ///
194    /// This structure is automatically generated by `bindgen!`. For the
195    /// asynchronous version see [`bindings::Command`](super::Command).
196    ///
197    /// This can be used for a more "typed" view of executing a command
198    /// component through the [`Command::wasi_cli_run`] method plus
199    /// [`Guest::call_run`](exports::wasi::cli::run::Guest::call_run).
200    ///
201    /// [`wasmtime_wasi::p2::add_to_linker_sync`]: crate::p2::add_to_linker_sync
202    ///
203    /// # Examples
204    ///
205    /// ```no_run
206    /// use wasmtime::{Engine, Result, Store, Config};
207    /// use wasmtime::component::{ResourceTable, Linker, Component};
208    /// use wasmtime_wasi::{WasiCtx, WasiCtxView, WasiView};
209    /// use wasmtime_wasi::p2::bindings::sync::Command;
210    ///
211    /// // This example is an example shim of executing a component based on the
212    /// // command line arguments provided to this program.
213    /// fn main() -> Result<()> {
214    ///     let args = std::env::args().skip(1).collect::<Vec<_>>();
215    ///
216    ///     // Configure and create `Engine`
217    ///     let engine = Engine::default();
218    ///
219    ///     // Configure a `Linker` with WASI, compile a component based on
220    ///     // command line arguments.
221    ///     let mut linker = Linker::<MyState>::new(&engine);
222    ///     wasmtime_wasi::p2::add_to_linker_sync(&mut linker)?;
223    ///     let component = Component::from_file(&engine, &args[0])?;
224    ///
225    ///
226    ///     // Configure a `WasiCtx` based on this program's environment. Then
227    ///     // build a `Store` to instantiate into.
228    ///     let mut builder = WasiCtx::builder();
229    ///     builder.inherit_stdio().inherit_env().args(&args[2..]);
230    ///     let mut store = Store::new(
231    ///         &engine,
232    ///         MyState {
233    ///             ctx: builder.build(),
234    ///             table: ResourceTable::new(),
235    ///         },
236    ///     );
237    ///
238    ///     // Instantiate the component and we're off to the races.
239    ///     let command = Command::instantiate(&mut store, &component, &linker)?;
240    ///     let program_result = command.wasi_cli_run().call_run(&mut store)?;
241    ///     match program_result {
242    ///         Ok(()) => Ok(()),
243    ///         Err(()) => std::process::exit(1),
244    ///     }
245    /// }
246    ///
247    /// struct MyState {
248    ///     ctx: WasiCtx,
249    ///     table: ResourceTable,
250    /// }
251    ///
252    /// impl WasiView for MyState {
253    ///     fn ctx(&mut self) -> WasiCtxView<'_> {
254    ///         WasiCtxView { ctx: &mut self.ctx, table: &mut self.table }
255    ///     }
256    /// }
257    /// ```
258    ///
259    /// ---
260    pub use self::generated::Command;
261
262    /// Pre-instantiated analogue of [`Command`].
263    ///
264    /// This works the same as [`Command`] but enables front-loading work such
265    /// as export lookup to before instantiation.
266    ///
267    /// # Examples
268    ///
269    /// ```no_run
270    /// use wasmtime::{Engine, Result, Store, Config};
271    /// use wasmtime::component::{ResourceTable, Linker, Component};
272    /// use wasmtime_wasi::{WasiCtx, WasiCtxView, WasiView};
273    /// use wasmtime_wasi::p2::bindings::sync::CommandPre;
274    ///
275    /// // This example is an example shim of executing a component based on the
276    /// // command line arguments provided to this program.
277    /// fn main() -> Result<()> {
278    ///     let args = std::env::args().skip(1).collect::<Vec<_>>();
279    ///
280    ///     // Configure and create `Engine`
281    ///     let engine = Engine::default();
282    ///
283    ///     // Configure a `Linker` with WASI, compile a component based on
284    ///     // command line arguments, and then pre-instantiate it.
285    ///     let mut linker = Linker::<MyState>::new(&engine);
286    ///     wasmtime_wasi::p2::add_to_linker_sync(&mut linker)?;
287    ///     let component = Component::from_file(&engine, &args[0])?;
288    ///     let pre = CommandPre::new(linker.instantiate_pre(&component)?)?;
289    ///
290    ///
291    ///     // Configure a `WasiCtx` based on this program's environment. Then
292    ///     // build a `Store` to instantiate into.
293    ///     let mut builder = WasiCtx::builder();
294    ///     builder.inherit_stdio().inherit_env().args(&args);
295    ///     let mut store = Store::new(
296    ///         &engine,
297    ///         MyState {
298    ///             ctx: builder.build(),
299    ///             table: ResourceTable::new(),
300    ///         },
301    ///     );
302    ///
303    ///     // Instantiate the component and we're off to the races.
304    ///     let command = pre.instantiate(&mut store)?;
305    ///     let program_result = command.wasi_cli_run().call_run(&mut store)?;
306    ///     match program_result {
307    ///         Ok(()) => Ok(()),
308    ///         Err(()) => std::process::exit(1),
309    ///     }
310    /// }
311    ///
312    /// struct MyState {
313    ///     ctx: WasiCtx,
314    ///     table: ResourceTable,
315    /// }
316    ///
317    /// impl WasiView for MyState {
318    ///     fn ctx(&mut self) -> WasiCtxView<'_> {
319    ///         WasiCtxView { ctx: &mut self.ctx, table: &mut self.table }
320    ///     }
321    /// }
322    /// ```
323    ///
324    /// ---
325    pub use self::generated::CommandPre;
326
327    pub use self::generated::CommandIndices;
328
329    pub use self::generated::LinkOptions;
330}
331
332mod async_io {
333    wasmtime::component::bindgen!({
334        path: "src/p2/wit",
335        world: "wasi:cli/command",
336        imports: {
337            // Only these functions are `async` and everything else is sync
338            // meaning that it basically doesn't need to block. These functions
339            // are the only ones that need to block.
340            //
341            // Note that at this time `only_imports` works on function names
342            // which in theory can be shared across interfaces, so this may
343            // need fancier syntax in the future.
344            "wasi:filesystem/types.[method]descriptor.advise": async | tracing | trappable,
345            "wasi:filesystem/types.[method]descriptor.create-directory-at": async | tracing | trappable,
346            "wasi:filesystem/types.[method]descriptor.get-flags": async | tracing | trappable,
347            "wasi:filesystem/types.[method]descriptor.get-type": async | tracing | trappable,
348            "wasi:filesystem/types.[method]descriptor.is-same-object": async | tracing | trappable,
349            "wasi:filesystem/types.[method]descriptor.link-at": async | tracing | trappable,
350            "wasi:filesystem/types.[method]descriptor.metadata-hash": async | tracing | trappable,
351            "wasi:filesystem/types.[method]descriptor.metadata-hash-at": async | tracing | trappable,
352            "wasi:filesystem/types.[method]descriptor.open-at": async | tracing | trappable,
353            "wasi:filesystem/types.[method]descriptor.read": async | tracing | trappable,
354            "wasi:filesystem/types.[method]descriptor.read-directory": async | tracing | trappable,
355            "wasi:filesystem/types.[method]descriptor.readlink-at": async | tracing | trappable,
356            "wasi:filesystem/types.[method]descriptor.remove-directory-at": async | tracing | trappable,
357            "wasi:filesystem/types.[method]descriptor.rename-at": async | tracing | trappable,
358            "wasi:filesystem/types.[method]descriptor.set-size": async | tracing | trappable,
359            "wasi:filesystem/types.[method]descriptor.set-times": async | tracing | trappable,
360            "wasi:filesystem/types.[method]descriptor.set-times-at": async | tracing | trappable,
361            "wasi:filesystem/types.[method]descriptor.stat": async | tracing | trappable,
362            "wasi:filesystem/types.[method]descriptor.stat-at": async | tracing | trappable,
363            "wasi:filesystem/types.[method]descriptor.symlink-at": async | tracing | trappable,
364            "wasi:filesystem/types.[method]descriptor.sync": async | tracing | trappable,
365            "wasi:filesystem/types.[method]descriptor.sync-data": async | tracing | trappable,
366            "wasi:filesystem/types.[method]descriptor.unlink-file-at": async | tracing | trappable,
367            "wasi:filesystem/types.[method]descriptor.write": async | tracing | trappable,
368            "wasi:filesystem/types.[method]directory-entry-stream.read-directory-entry": async | tracing | trappable,
369            "wasi:sockets/udp-create-socket.create-udp-socket": async | tracing | trappable,
370            "wasi:sockets/tcp.[method]tcp-socket.start-bind": async | tracing | trappable,
371            "wasi:sockets/tcp.[method]tcp-socket.start-listen": async | tracing | trappable,
372            "wasi:sockets/udp.[method]udp-socket.start-bind": async | tracing | trappable,
373            "wasi:sockets/udp.[method]udp-socket.stream": async | tracing | trappable,
374            "wasi:sockets/udp.[drop]outgoing-datagram-stream": async | tracing | trappable,
375            "wasi:sockets/udp.[drop]incoming-datagram-stream": async | tracing | trappable,
376            "wasi:sockets/ip-name-lookup.[drop]resolve-address-stream": async | tracing | trappable,
377            default: tracing | trappable,
378        },
379        exports: { default: async },
380        trappable_error_type: {
381            "wasi:io/streams.stream-error" => wasmtime_wasi_io::streams::StreamError,
382            "wasi:filesystem/types.error-code" => crate::p2::FsError,
383            "wasi:sockets/network.error-code" => crate::p2::SocketError,
384        },
385        with: {
386            // All interfaces in the wasi:io package should be aliased to
387            // the wasmtime-wasi-io generated code. Note that this will also
388            // map the resource types to those defined in that crate as well.
389            "wasi:io/poll": wasmtime_wasi_io::bindings::wasi::io::poll,
390            "wasi:io/streams": wasmtime_wasi_io::bindings::wasi::io::streams,
391            "wasi:io/error": wasmtime_wasi_io::bindings::wasi::io::error,
392
393            // Configure all other resources to be concrete types defined in
394            // this crate
395            "wasi:sockets/network.network": crate::p2::network::Network,
396            "wasi:sockets/tcp.tcp-socket": crate::p2::TcpSocket,
397            "wasi:sockets/udp.udp-socket": crate::p2::UdpSocket,
398            "wasi:sockets/udp.incoming-datagram-stream": crate::p2::udp::IncomingDatagramStream,
399            "wasi:sockets/udp.outgoing-datagram-stream": crate::p2::udp::OutgoingDatagramStream,
400            "wasi:sockets/ip-name-lookup.resolve-address-stream": crate::p2::ip_name_lookup::ResolveAddressStream,
401            "wasi:filesystem/types.directory-entry-stream": crate::p2::filesystem::ReaddirIterator,
402            "wasi:filesystem/types.descriptor": crate::filesystem::Descriptor,
403            "wasi:cli/terminal-input.terminal-input": crate::p2::stdio::TerminalInput,
404            "wasi:cli/terminal-output.terminal-output": crate::p2::stdio::TerminalOutput,
405        },
406        named_imports: {
407            "wasi:clocks/monotonic-clock": crate::NamedId,
408            "wasi:clocks/wall-clock": crate::NamedId,
409            "wasi:random/random": crate::NamedId,
410            "wasi:random/insecure": crate::NamedId,
411            "wasi:random/insecure-seed": crate::NamedId,
412            "wasi:cli/exit": crate::NamedId,
413            "wasi:cli/environment": crate::NamedId,
414            "wasi:cli/stdin": crate::NamedId,
415            "wasi:cli/stdout": crate::NamedId,
416            "wasi:cli/stderr": crate::NamedId,
417            "wasi:cli/terminal-input": crate::NamedId,
418            "wasi:cli/terminal-output": crate::NamedId,
419            "wasi:cli/terminal-stdin": crate::NamedId,
420            "wasi:cli/terminal-stdout": crate::NamedId,
421            "wasi:cli/terminal-stderr": crate::NamedId,
422            "wasi:filesystem/types": crate::NamedId,
423            "wasi:filesystem/preopens": crate::NamedId,
424            "wasi:sockets/instance-network": crate::NamedId,
425            "wasi:sockets/network": crate::NamedId,
426            "wasi:sockets/ip-name-lookup": crate::NamedId,
427            "wasi:sockets/tcp-create-socket": crate::NamedId,
428            "wasi:sockets/tcp": crate::NamedId,
429            "wasi:sockets/udp-create-socket": crate::NamedId,
430            "wasi:sockets/udp": crate::NamedId,
431        },
432    });
433}
434
435pub use self::async_io::LinkOptions;
436pub use self::async_io::exports;
437pub use self::async_io::named_imports;
438pub use self::async_io::wasi::*;
439
440/// Asynchronous bindings to execute and run a `wasi:cli/command`.
441///
442/// This structure is automatically generated by `bindgen!`. For the synchronous
443/// version see [`bindings::sync::Command`](sync::Command).
444///
445/// This can be used for a more "typed" view of executing a command component
446/// through the [`Command::wasi_cli_run`] method plus
447/// [`Guest::call_run`](exports::wasi::cli::run::Guest::call_run).
448///
449/// [`wasmtime_wasi::p2::add_to_linker_async`]: crate::p2::add_to_linker_async
450///
451/// # Examples
452///
453/// ```no_run
454/// use wasmtime::{Engine, Result, Store, Config};
455/// use wasmtime::component::{ResourceTable, Linker, Component};
456/// use wasmtime_wasi::{WasiCtx, WasiCtxView, WasiView};
457/// use wasmtime_wasi::p2::bindings::Command;
458///
459/// // This example is an example shim of executing a component based on the
460/// // command line arguments provided to this program.
461/// #[tokio::main]
462/// async fn main() -> Result<()> {
463///     let args = std::env::args().skip(1).collect::<Vec<_>>();
464///
465///     // Configure and create `Engine`
466///     let engine = Engine::default();
467///
468///     // Configure a `Linker` with WASI, compile a component based on
469///     // command line arguments, and then pre-instantiate it.
470///     let mut linker = Linker::<MyState>::new(&engine);
471///     wasmtime_wasi::p2::add_to_linker_async(&mut linker)?;
472///     let component = Component::from_file(&engine, &args[0])?;
473///
474///
475///     // Configure a `WasiCtx` based on this program's environment. Then
476///     // build a `Store` to instantiate into.
477///     let mut builder = WasiCtx::builder();
478///     builder.inherit_stdio().inherit_env().args(&args);
479///     let mut store = Store::new(
480///         &engine,
481///         MyState {
482///             ctx: builder.build(),
483///             table: ResourceTable::new(),
484///         },
485///     );
486///
487///     // Instantiate the component and we're off to the races.
488///     let command = Command::instantiate_async(&mut store, &component, &linker).await?;
489///     let program_result = command.wasi_cli_run().call_run(&mut store).await?;
490///     match program_result {
491///         Ok(()) => Ok(()),
492///         Err(()) => std::process::exit(1),
493///     }
494/// }
495///
496/// struct MyState {
497///     ctx: WasiCtx,
498///     table: ResourceTable,
499/// }
500///
501/// impl WasiView for MyState {
502///     fn ctx(&mut self) -> WasiCtxView<'_> {
503///         WasiCtxView { ctx: &mut self.ctx, table: &mut self.table }
504///     }
505/// }
506/// ```
507///
508/// ---
509pub use self::async_io::Command;
510
511/// Pre-instantiated analog of [`Command`]
512///
513/// This can be used to front-load work such as export lookup before
514/// instantiation.
515///
516/// # Examples
517///
518/// ```no_run
519/// use wasmtime::{Engine, Result, Store};
520/// use wasmtime::component::{ResourceTable, Linker, Component};
521/// use wasmtime_wasi::{WasiCtx, WasiCtxView, WasiView};
522/// use wasmtime_wasi::p2::bindings::CommandPre;
523///
524/// // This example is an example shim of executing a component based on the
525/// // command line arguments provided to this program.
526/// #[tokio::main]
527/// async fn main() -> Result<()> {
528///     let args = std::env::args().skip(1).collect::<Vec<_>>();
529///
530///     // Configure and create `Engine`
531///     let engine = Engine::default();
532///
533///     // Configure a `Linker` with WASI, compile a component based on
534///     // command line arguments, and then pre-instantiate it.
535///     let mut linker = Linker::<MyState>::new(&engine);
536///     wasmtime_wasi::p2::add_to_linker_async(&mut linker)?;
537///     let component = Component::from_file(&engine, &args[0])?;
538///     let pre = CommandPre::new(linker.instantiate_pre(&component)?)?;
539///
540///
541///     // Configure a `WasiCtx` based on this program's environment. Then
542///     // build a `Store` to instantiate into.
543///     let mut builder = WasiCtx::builder();
544///     builder.inherit_stdio().inherit_env().args(&args);
545///     let mut store = Store::new(
546///         &engine,
547///         MyState {
548///             ctx: builder.build(),
549///             table: ResourceTable::new(),
550///         },
551///     );
552///
553///     // Instantiate the component and we're off to the races.
554///     let command = pre.instantiate_async(&mut store).await?;
555///     let program_result = command.wasi_cli_run().call_run(&mut store).await?;
556///     match program_result {
557///         Ok(()) => Ok(()),
558///         Err(()) => std::process::exit(1),
559///     }
560/// }
561///
562/// struct MyState {
563///     ctx: WasiCtx,
564///     table: ResourceTable,
565/// }
566///
567/// impl WasiView for MyState {
568///     fn ctx(&mut self) -> WasiCtxView<'_> {
569///         WasiCtxView { ctx: &mut self.ctx, table: &mut self.table }
570///     }
571/// }
572/// ```
573///
574/// ---
575pub use self::async_io::CommandPre;
576
577pub use self::async_io::CommandIndices;