Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/crates/wasi/src/p3/bindings.rs
3050 views
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/imports` world.
5
//!
6
//! [`bindgen!`]: https://docs.rs/wasmtime/latest/wasmtime/component/macro.bindgen.html
7
//!
8
//! # Examples
9
//!
10
//! If you have a WIT world which refers to WASI interfaces you probably want to
11
//! use this modules's bindings rather than generate fresh bindings. That can be
12
//! done using the `with` option to [`bindgen!`]:
13
//!
14
//! ```rust
15
//! use wasmtime_wasi::{WasiCtx, WasiCtxView, WasiView};
16
//! use wasmtime::{Result, Engine, Config};
17
//! use wasmtime::component::{Linker, HasSelf, ResourceTable};
18
//!
19
//! wasmtime::component::bindgen!({
20
//! inline: "
21
//! package example:wasi;
22
//!
23
//! // An example of extending the `wasi:cli/command` world with a
24
//! // custom host interface.
25
//! world my-world {
26
//! include wasi:cli/[email protected];
27
//!
28
//! import custom-host;
29
//! }
30
//!
31
//! interface custom-host {
32
//! my-custom-function: func();
33
//! }
34
//! ",
35
//! path: "src/p3/wit",
36
//! with: {
37
//! "wasi": wasmtime_wasi::p3::bindings,
38
//! },
39
//! require_store_data_send: true,
40
//! });
41
//!
42
//! struct MyState {
43
//! ctx: WasiCtx,
44
//! table: ResourceTable,
45
//! }
46
//!
47
//! impl example::wasi::custom_host::Host for MyState {
48
//! fn my_custom_function(&mut self) {
49
//! // ..
50
//! }
51
//! }
52
//!
53
//! impl WasiView for MyState {
54
//! fn ctx(&mut self) -> WasiCtxView<'_> {
55
//! WasiCtxView{
56
//! ctx: &mut self.ctx,
57
//! table: &mut self.table,
58
//! }
59
//! }
60
//! }
61
//!
62
//! fn main() -> Result<()> {
63
//! let mut config = Config::default();
64
//! config.wasm_component_model_async(true);
65
//! let engine = Engine::new(&config)?;
66
//! let mut linker: Linker<MyState> = Linker::new(&engine);
67
//! wasmtime_wasi::p3::add_to_linker(&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
mod generated {
77
wasmtime::component::bindgen!({
78
path: "src/p3/wit",
79
world: "wasi:cli/command",
80
imports: {
81
"wasi:cli/stdin": store | tracing | trappable,
82
"wasi:cli/stdout": store | tracing | trappable,
83
"wasi:cli/stderr": store | tracing | trappable,
84
"wasi:filesystem/types.[method]descriptor.read-via-stream": store | tracing | trappable,
85
"wasi:sockets/types.[method]tcp-socket.bind": async | tracing | trappable,
86
"wasi:sockets/types.[method]tcp-socket.listen": store | tracing | trappable,
87
"wasi:sockets/types.[method]tcp-socket.receive": store | tracing | trappable,
88
"wasi:sockets/types.[method]udp-socket.bind": async | tracing | trappable,
89
"wasi:sockets/types.[method]udp-socket.connect": async | tracing | trappable,
90
default: tracing | trappable,
91
},
92
exports: { default: async | store | task_exit },
93
with: {
94
"wasi:cli/terminal-input.terminal-input": crate::p3::cli::TerminalInput,
95
"wasi:cli/terminal-output.terminal-output": crate::p3::cli::TerminalOutput,
96
"wasi:filesystem/types.descriptor": crate::filesystem::Descriptor,
97
"wasi:sockets/types.tcp-socket": crate::sockets::TcpSocket,
98
"wasi:sockets/types.udp-socket": crate::sockets::UdpSocket,
99
},
100
trappable_error_type: {
101
"wasi:filesystem/types.error-code" => crate::p3::filesystem::FilesystemError,
102
"wasi:sockets/types.error-code" => crate::p3::sockets::SocketError,
103
},
104
});
105
}
106
pub use self::generated::LinkOptions;
107
pub use self::generated::exports;
108
pub use self::generated::wasi::*;
109
110
/// Bindings to execute and run a `wasi:cli/command`.
111
///
112
/// This structure is automatically generated by `bindgen!`.
113
///
114
/// This can be used for a more "typed" view of executing a command component
115
/// through the [`Command::wasi_cli_run`] method plus
116
/// [`Guest::call_run`](exports::wasi::cli::run::Guest::call_run).
117
///
118
/// # Examples
119
///
120
/// ```no_run
121
/// use wasmtime::{Engine, Result, Store, Config};
122
/// use wasmtime::component::{Component, Linker, ResourceTable};
123
/// use wasmtime_wasi::{WasiCtx, WasiCtxView, WasiView};
124
/// use wasmtime_wasi::p3::bindings::Command;
125
///
126
/// // This example is an example shim of executing a component based on the
127
/// // command line arguments provided to this program.
128
/// #[tokio::main]
129
/// async fn main() -> Result<()> {
130
/// let args = std::env::args().skip(1).collect::<Vec<_>>();
131
///
132
/// // Configure and create `Engine`
133
/// let mut config = Config::new();
134
/// config.wasm_component_model_async(true);
135
/// let engine = Engine::new(&config)?;
136
///
137
/// // Configure a `Linker` with WASI, compile a component based on
138
/// // command line arguments, and then pre-instantiate it.
139
/// let mut linker = Linker::<MyState>::new(&engine);
140
/// wasmtime_wasi::p3::add_to_linker(&mut linker)?;
141
/// let component = Component::from_file(&engine, &args[0])?;
142
///
143
///
144
/// // Configure a `WasiCtx` based on this program's environment. Then
145
/// // build a `Store` to instantiate into.
146
/// let mut builder = WasiCtx::builder();
147
/// builder.inherit_stdio().inherit_env().args(&args);
148
/// let mut store = Store::new(
149
/// &engine,
150
/// MyState {
151
/// ctx: builder.build(),
152
/// table: ResourceTable::default(),
153
/// },
154
/// );
155
///
156
/// // Instantiate the component and we're off to the races.
157
/// let command = Command::instantiate_async(&mut store, &component, &linker).await?;
158
/// let program_result = store.run_concurrent(async move |store| {
159
/// command.wasi_cli_run().call_run(store).await
160
/// }).await??.0;
161
/// match program_result {
162
/// Ok(()) => Ok(()),
163
/// Err(()) => std::process::exit(1),
164
/// }
165
/// }
166
///
167
/// struct MyState {
168
/// ctx: WasiCtx,
169
/// table: ResourceTable,
170
/// }
171
///
172
/// impl WasiView for MyState {
173
/// fn ctx(&mut self) -> WasiCtxView<'_> {
174
/// WasiCtxView{
175
/// ctx: &mut self.ctx,
176
/// table: &mut self.table,
177
/// }
178
/// }
179
/// }
180
/// ```
181
///
182
/// ---
183
pub use self::generated::Command;
184
185
/// Pre-instantiated analog of [`Command`]
186
///
187
/// This can be used to front-load work such as export lookup before
188
/// instantiation.
189
///
190
/// # Examples
191
///
192
/// ```no_run
193
/// use wasmtime::{Engine, Result, Store, Config};
194
/// use wasmtime::component::{Linker, Component, ResourceTable};
195
/// use wasmtime_wasi::{WasiCtx, WasiCtxView, WasiView};
196
/// use wasmtime_wasi::p3::bindings::CommandPre;
197
///
198
/// // This example is an example shim of executing a component based on the
199
/// // command line arguments provided to this program.
200
/// #[tokio::main]
201
/// async fn main() -> Result<()> {
202
/// let args = std::env::args().skip(1).collect::<Vec<_>>();
203
///
204
/// // Configure and create `Engine`
205
/// let mut config = Config::new();
206
/// config.wasm_component_model_async(true);
207
/// let engine = Engine::new(&config)?;
208
///
209
/// // Configure a `Linker` with WASI, compile a component based on
210
/// // command line arguments, and then pre-instantiate it.
211
/// let mut linker = Linker::<MyState>::new(&engine);
212
/// wasmtime_wasi::p3::add_to_linker(&mut linker)?;
213
/// let component = Component::from_file(&engine, &args[0])?;
214
/// let pre = CommandPre::new(linker.instantiate_pre(&component)?)?;
215
///
216
///
217
/// // Configure a `WasiCtx` based on this program's environment. Then
218
/// // build a `Store` to instantiate into.
219
/// let mut builder = WasiCtx::builder();
220
/// builder.inherit_stdio().inherit_env().args(&args);
221
/// let mut store = Store::new(
222
/// &engine,
223
/// MyState {
224
/// ctx: builder.build(),
225
/// table: ResourceTable::default(),
226
/// },
227
/// );
228
///
229
/// // Instantiate the component and we're off to the races.
230
/// let command = pre.instantiate_async(&mut store).await?;
231
/// // TODO: Construct an accessor from `store` to call `run`
232
/// // https://github.com/bytecodealliance/wasmtime/issues/11249
233
/// //let program_result = command.wasi_cli_run().call_run(&mut store).await?;
234
/// let program_result = todo!();
235
/// match program_result {
236
/// Ok(()) => Ok(()),
237
/// Err(()) => std::process::exit(1),
238
/// }
239
/// }
240
///
241
/// struct MyState {
242
/// ctx: WasiCtx,
243
/// table: ResourceTable,
244
/// }
245
///
246
/// impl WasiView for MyState {
247
/// fn ctx(&mut self) -> WasiCtxView<'_> {
248
/// WasiCtxView{
249
/// ctx: &mut self.ctx,
250
/// table: &mut self.table,
251
/// }
252
/// }
253
/// }
254
/// ```
255
///
256
/// ---
257
// TODO: Make this public, once `CommandPre` can be used for
258
// calling exports
259
// https://github.com/bytecodealliance/wasmtime/issues/11249
260
#[doc(hidden)]
261
pub use self::generated::CommandPre;
262
263
pub use self::generated::CommandIndices;
264
265