Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/crates/wasi/src/p2/bindings.rs
1692 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/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/[email protected];
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/[email protected];
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
/// ```
145
pub 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
335
mod 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
409
pub use self::async_io::LinkOptions;
410
pub use self::async_io::exports;
411
pub 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
/// ---
486
pub 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
/// ---
554
pub use self::async_io::CommandPre;
555
556
pub use self::async_io::CommandIndices;
557
558