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