wasmtime_environ/
component.rs

1//! Support for the component model in Wasmtime.
2//!
3//! This module contains all of the internal type definitions used by Wasmtime
4//! to process the component model. Despite everything being `pub` here this is
5//! not the public interface of Wasmtime to the component model. Instead this is
6//! the internal support to mirror the core wasm support that Wasmtime already
7//! implements.
8//!
9//! Some main items contained within here are:
10//!
11//! * Type hierarchy information for the component model
12//! * Translation of a component into Wasmtime's representation
13//! * Type information about a component used at runtime
14//!
15//! This module also contains a lot of Serialize/Deserialize types which are
16//! encoded in the final compiled image for a component.
17//!
18//! Note that this entire module is gated behind the `component-model` Cargo
19//! feature.
20//!
21//! ## Warning: In-progress
22//!
23//! As-of the time of this writing this module is incomplete and under
24//! development. It will be added to incrementally over time as more features
25//! are implemented. Current design decisions are also susceptible to change at
26//! any time. Some comments may reflect historical rather than current state as
27//! well (sorry).
28
29/// Canonical ABI-defined constant for the maximum number of "flat" parameters
30/// to a wasm function, or the maximum number of parameters a core wasm function
31/// will take for just the parameters used. Over this number the heap is used
32/// for transferring parameters.
33pub const MAX_FLAT_PARAMS: usize = 16;
34
35/// Similar to `MAX_FLAT_PARAMS`, but used for async-lowered imports instead of
36/// sync ones.
37pub const MAX_FLAT_ASYNC_PARAMS: usize = 4;
38
39/// Canonical ABI-defined constant for the maximum number of "flat" results.
40/// This number of results are returned directly from wasm and otherwise results
41/// are transferred through memory.
42pub const MAX_FLAT_RESULTS: usize = 1;
43
44/// Sentinel value in `result_count_or_max_if_async` as part of the
45/// `prepare_call` libcall which indicates that preparation is being done for an
46/// async function that produces no result, aka there is no return pointer.
47pub const PREPARE_ASYNC_NO_RESULT: u32 = u32::MAX;
48
49/// Sentinel value in `result_count_or_max_if_async` as part of the
50/// `prepare_call` libcall which indicates that preparation is being done for an
51/// async function that produces at least one result, aka there is a return
52/// pointer.
53pub const PREPARE_ASYNC_WITH_RESULT: u32 = u32::MAX - 1;
54
55mod artifacts;
56mod info;
57mod names;
58mod types;
59mod vmcomponent_offsets;
60pub use self::artifacts::*;
61pub use self::info::*;
62pub use self::names::*;
63pub use self::types::*;
64pub use self::vmcomponent_offsets::*;
65
66#[cfg(feature = "compile")]
67mod compiler;
68#[cfg(feature = "compile")]
69pub mod dfg;
70#[cfg(feature = "compile")]
71mod translate;
72#[cfg(feature = "compile")]
73mod types_builder;
74#[cfg(feature = "compile")]
75pub use self::compiler::*;
76#[cfg(feature = "compile")]
77pub use self::translate::*;
78#[cfg(feature = "compile")]
79pub use self::types_builder::*;
80
81/// Helper macro, like `foreach_transcoder`, to iterate over builtins for
82/// components unrelated to transcoding.
83#[macro_export]
84macro_rules! foreach_builtin_component_function {
85    ($mac:ident) => {
86        $mac! {
87            resource_new32(vmctx: vmctx, resource: u32, rep: u32) -> u64;
88            resource_rep32(vmctx: vmctx, resource: u32, idx: u32) -> u64;
89
90            // Returns an `Option<u32>` where `None` is "no destructor needed"
91            // and `Some(val)` is "run the destructor on this rep". The option
92            // is encoded as a 64-bit integer where the low bit is Some/None
93            // and bits 1-33 are the payload.
94            resource_drop(vmctx: vmctx, resource: u32, idx: u32) -> u64;
95
96            resource_transfer_own(vmctx: vmctx, src_idx: u32, src_table: u32, dst_table: u32) -> u64;
97            resource_transfer_borrow(vmctx: vmctx, src_idx: u32, src_table: u32, dst_table: u32) -> u64;
98            resource_enter_call(vmctx: vmctx);
99            resource_exit_call(vmctx: vmctx) -> bool;
100
101            #[cfg(feature = "component-model-async")]
102            backpressure_set(vmctx: vmctx, caller_instance: u32, enabled: u32) -> bool;
103            #[cfg(feature = "component-model-async")]
104            task_return(vmctx: vmctx, ty: u32, memory: ptr_u8, string_encoding: u8, storage: ptr_u8, storage_len: size) -> bool;
105            #[cfg(feature = "component-model-async")]
106            task_cancel(vmctx: vmctx, caller_instance: u32) -> bool;
107            #[cfg(feature = "component-model-async")]
108            waitable_set_new(vmctx: vmctx, caller_instance: u32) -> u64;
109            #[cfg(feature = "component-model-async")]
110            waitable_set_wait(vmctx: vmctx, caller_instance: u32, async_: u8, memory: ptr_u8, set: u32, payload: u32) -> u64;
111            #[cfg(feature = "component-model-async")]
112            waitable_set_poll(vmctx: vmctx, caller_instance: u32, async_: u8, memory: ptr_u8, set: u32, payload: u32) -> u64;
113            #[cfg(feature = "component-model-async")]
114            waitable_set_drop(vmctx: vmctx, caller_instance: u32, set: u32) -> bool;
115            #[cfg(feature = "component-model-async")]
116            waitable_join(vmctx: vmctx, caller_instance: u32, set: u32, waitable: u32) -> bool;
117            #[cfg(feature = "component-model-async")]
118            yield_(vmctx: vmctx, async_: u8) -> u32;
119            #[cfg(feature = "component-model-async")]
120            subtask_drop(vmctx: vmctx, caller_instance: u32, task_id: u32) -> bool;
121            #[cfg(feature = "component-model-async")]
122            subtask_cancel(vmctx: vmctx, caller_instance: u32, async_: u8, task_id: u32) -> u64;
123            #[cfg(feature = "component-model-async")]
124            prepare_call(
125                vmctx: vmctx,
126                memory: ptr_u8,
127                start: ptr_u8,
128                return_: ptr_u8,
129                caller_instance: u32,
130                callee_instance: u32,
131                task_return_type: u32,
132                string_encoding: u32,
133                result_count_or_max_if_async: u32,
134                storage: ptr_u8,
135                torage_len: size
136            ) -> bool;
137            #[cfg(feature = "component-model-async")]
138            sync_start(vmctx: vmctx, callback: ptr_u8, callee: ptr_u8, param_count: u32, storage: ptr_u8, storage_len: size) -> bool;
139            #[cfg(feature = "component-model-async")]
140            async_start(vmctx: vmctx, callback: ptr_u8, post_return: ptr_u8, callee: ptr_u8, param_count: u32, result_count: u32, flags: u32) -> u64;
141            #[cfg(feature = "component-model-async")]
142            future_new(vmctx: vmctx, ty: u32) -> u64;
143            #[cfg(feature = "component-model-async")]
144            future_write(vmctx: vmctx, memory: ptr_u8, realloc: ptr_u8, string_encoding: u8, async_: u8, ty: u32, future: u32, address: u32) -> u64;
145            #[cfg(feature = "component-model-async")]
146            future_read(vmctx: vmctx, memory: ptr_u8, realloc: ptr_u8, string_encoding: u8, async_: u8, ty: u32, future: u32, address: u32) -> u64;
147            #[cfg(feature = "component-model-async")]
148            future_cancel_write(vmctx: vmctx, ty: u32, async_: u8, writer: u32) -> u64;
149            #[cfg(feature = "component-model-async")]
150            future_cancel_read(vmctx: vmctx, ty: u32, async_: u8, reader: u32) -> u64;
151            #[cfg(feature = "component-model-async")]
152            future_close_writable(vmctx: vmctx, ty: u32, writer: u32) -> bool;
153            #[cfg(feature = "component-model-async")]
154            future_close_readable(vmctx: vmctx, ty: u32, reader: u32) -> bool;
155            #[cfg(feature = "component-model-async")]
156            stream_new(vmctx: vmctx, ty: u32) -> u64;
157            #[cfg(feature = "component-model-async")]
158            stream_write(vmctx: vmctx, memory: ptr_u8, realloc: ptr_u8, string_encoding: u8, async_: u8, ty: u32, stream: u32, address: u32, count: u32) -> u64;
159            #[cfg(feature = "component-model-async")]
160            stream_read(vmctx: vmctx, memory: ptr_u8, realloc: ptr_u8, string_encoding: u8, async_: u8, ty: u32, stream: u32, address: u32, count: u32) -> u64;
161            #[cfg(feature = "component-model-async")]
162            stream_cancel_write(vmctx: vmctx, ty: u32, async_: u8, writer: u32) -> u64;
163            #[cfg(feature = "component-model-async")]
164            stream_cancel_read(vmctx: vmctx, ty: u32, async_: u8, reader: u32) -> u64;
165            #[cfg(feature = "component-model-async")]
166            stream_close_writable(vmctx: vmctx, ty: u32, writer: u32) -> bool;
167            #[cfg(feature = "component-model-async")]
168            stream_close_readable(vmctx: vmctx, ty: u32, reader: u32) -> bool;
169            #[cfg(feature = "component-model-async")]
170            flat_stream_write(vmctx: vmctx, memory: ptr_u8, realloc: ptr_u8, async_: u8, ty: u32, payload_size: u32, payload_align: u32, stream: u32, address: u32, count: u32) -> u64;
171            #[cfg(feature = "component-model-async")]
172            flat_stream_read(vmctx: vmctx, memory: ptr_u8, realloc: ptr_u8, async_: u8, ty: u32, payload_size: u32, payload_align: u32, stream: u32, address: u32, count: u32) -> u64;
173            #[cfg(feature = "component-model-async")]
174            error_context_new(vmctx: vmctx, memory: ptr_u8, realloc: ptr_u8, string_encoding: u8, ty: u32, debug_msg_address: u32, debug_msg_len: u32) -> u64;
175            #[cfg(feature = "component-model-async")]
176            error_context_debug_message(vmctx: vmctx, memory: ptr_u8, realloc: ptr_u8, string_encoding: u8, ty: u32, err_ctx_handle: u32, debug_msg_address: u32) -> bool;
177            #[cfg(feature = "component-model-async")]
178            error_context_drop(vmctx: vmctx, ty: u32, err_ctx_handle: u32) -> bool;
179            #[cfg(feature = "component-model-async")]
180            future_transfer(vmctx: vmctx, src_idx: u32, src_table: u32, dst_table: u32) -> u64;
181            #[cfg(feature = "component-model-async")]
182            stream_transfer(vmctx: vmctx, src_idx: u32, src_table: u32, dst_table: u32) -> u64;
183            #[cfg(feature = "component-model-async")]
184            error_context_transfer(vmctx: vmctx, src_idx: u32, src_table: u32, dst_table: u32) -> u64;
185            #[cfg(feature = "component-model-async")]
186            context_get(vmctx: vmctx, slot: u32) -> u64;
187            #[cfg(feature = "component-model-async")]
188            context_set(vmctx: vmctx, slot: u32, val: u32) -> bool;
189
190            trap(vmctx: vmctx, code: u8);
191
192            utf8_to_utf8(vmctx: vmctx, src: ptr_u8, len: size, dst: ptr_u8) -> bool;
193            utf16_to_utf16(vmctx: vmctx, src: ptr_u16, len: size, dst: ptr_u16) -> bool;
194            latin1_to_latin1(vmctx: vmctx, src: ptr_u8, len: size, dst: ptr_u8) -> bool;
195            latin1_to_utf16(vmctx: vmctx, src: ptr_u8, len: size, dst: ptr_u16) -> bool;
196            utf8_to_utf16(vmctx: vmctx, src: ptr_u8, len: size, dst: ptr_u16) -> size;
197            utf16_to_utf8(vmctx: vmctx, src: ptr_u16, src_len: size, dst: ptr_u8, dst_len: size, ret2: ptr_size) -> size;
198            latin1_to_utf8(vmctx: vmctx, src: ptr_u8, src_len: size, dst: ptr_u8, dst_len: size, ret2: ptr_size) -> size;
199            utf16_to_compact_probably_utf16(vmctx: vmctx, src: ptr_u16, len: size, dst: ptr_u16) -> size;
200            utf8_to_latin1(vmctx: vmctx, src: ptr_u8, len: size, dst: ptr_u8, ret2: ptr_size) -> size;
201            utf16_to_latin1(vmctx: vmctx, src: ptr_u16, len: size, dst: ptr_u8, ret2: ptr_size) -> size;
202            utf8_to_compact_utf16(vmctx: vmctx, src: ptr_u8, src_len: size, dst: ptr_u16, dst_len: size, bytes_so_far: size) -> size;
203            utf16_to_compact_utf16(vmctx: vmctx, src: ptr_u16, src_len: size, dst: ptr_u16, dst_len: size, bytes_so_far: size) -> size;
204        }
205    };
206}
207
208// Define `struct ComponentBuiltinFunctionIndex`
209declare_builtin_index!(
210    ComponentBuiltinFunctionIndex,
211    foreach_builtin_component_function
212);