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 });
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!`. For the synchronous
416/// version see [`bindings::sync::Command`](sync::Command).
417///
418/// This can be used for a more "typed" view of executing a command component
419/// through the [`Command::wasi_cli_run`] method plus
420/// [`Guest::call_run`](exports::wasi::cli::run::Guest::call_run).
421///
422/// [`wasmtime_wasi::p2::add_to_linker_async`]: crate::p2::add_to_linker_async
423///
424/// # Examples
425///
426/// ```no_run
427/// use wasmtime::{Engine, Result, Store, Config};
428/// use wasmtime::component::{ResourceTable, Linker, Component};
429/// use wasmtime_wasi::{WasiCtx, WasiCtxView, WasiView};
430/// use wasmtime_wasi::p2::bindings::Command;
431///
432/// // This example is an example shim of executing a component based on the
433/// // command line arguments provided to this program.
434/// #[tokio::main]
435/// async fn main() -> Result<()> {
436/// let args = std::env::args().skip(1).collect::<Vec<_>>();
437///
438/// // Configure and create `Engine`
439/// let engine = Engine::default();
440///
441/// // Configure a `Linker` with WASI, compile a component based on
442/// // command line arguments, and then pre-instantiate it.
443/// let mut linker = Linker::<MyState>::new(&engine);
444/// wasmtime_wasi::p2::add_to_linker_async(&mut linker)?;
445/// let component = Component::from_file(&engine, &args[0])?;
446///
447///
448/// // Configure a `WasiCtx` based on this program's environment. Then
449/// // build a `Store` to instantiate into.
450/// let mut builder = WasiCtx::builder();
451/// builder.inherit_stdio().inherit_env().args(&args);
452/// let mut store = Store::new(
453/// &engine,
454/// MyState {
455/// ctx: builder.build(),
456/// table: ResourceTable::new(),
457/// },
458/// );
459///
460/// // Instantiate the component and we're off to the races.
461/// let command = Command::instantiate_async(&mut store, &component, &linker).await?;
462/// let program_result = command.wasi_cli_run().call_run(&mut store).await?;
463/// match program_result {
464/// Ok(()) => Ok(()),
465/// Err(()) => std::process::exit(1),
466/// }
467/// }
468///
469/// struct MyState {
470/// ctx: WasiCtx,
471/// table: ResourceTable,
472/// }
473///
474/// impl WasiView for MyState {
475/// fn ctx(&mut self) -> WasiCtxView<'_> {
476/// WasiCtxView { ctx: &mut self.ctx, table: &mut self.table }
477/// }
478/// }
479/// ```
480///
481/// ---
482pub use self::async_io::Command;
483
484/// Pre-instantiated analog of [`Command`]
485///
486/// This can be used to front-load work such as export lookup before
487/// instantiation.
488///
489/// # Examples
490///
491/// ```no_run
492/// use wasmtime::{Engine, Result, Store};
493/// use wasmtime::component::{ResourceTable, Linker, Component};
494/// use wasmtime_wasi::{WasiCtx, WasiCtxView, WasiView};
495/// use wasmtime_wasi::p2::bindings::CommandPre;
496///
497/// // This example is an example shim of executing a component based on the
498/// // command line arguments provided to this program.
499/// #[tokio::main]
500/// async fn main() -> Result<()> {
501/// let args = std::env::args().skip(1).collect::<Vec<_>>();
502///
503/// // Configure and create `Engine`
504/// let engine = Engine::default();
505///
506/// // Configure a `Linker` with WASI, compile a component based on
507/// // command line arguments, and then pre-instantiate it.
508/// let mut linker = Linker::<MyState>::new(&engine);
509/// wasmtime_wasi::p2::add_to_linker_async(&mut linker)?;
510/// let component = Component::from_file(&engine, &args[0])?;
511/// let pre = CommandPre::new(linker.instantiate_pre(&component)?)?;
512///
513///
514/// // Configure a `WasiCtx` based on this program's environment. Then
515/// // build a `Store` to instantiate into.
516/// let mut builder = WasiCtx::builder();
517/// builder.inherit_stdio().inherit_env().args(&args);
518/// let mut store = Store::new(
519/// &engine,
520/// MyState {
521/// ctx: builder.build(),
522/// table: ResourceTable::new(),
523/// },
524/// );
525///
526/// // Instantiate the component and we're off to the races.
527/// let command = pre.instantiate_async(&mut store).await?;
528/// let program_result = command.wasi_cli_run().call_run(&mut store).await?;
529/// match program_result {
530/// Ok(()) => Ok(()),
531/// Err(()) => std::process::exit(1),
532/// }
533/// }
534///
535/// struct MyState {
536/// ctx: WasiCtx,
537/// table: ResourceTable,
538/// }
539///
540/// impl WasiView for MyState {
541/// fn ctx(&mut self) -> WasiCtxView<'_> {
542/// WasiCtxView { ctx: &mut self.ctx, table: &mut self.table }
543/// }
544/// }
545/// ```
546///
547/// ---
548pub use self::async_io::CommandPre;
549
550pub use self::async_io::CommandIndices;