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 /// Canonical ABI-defined constant for the maximum number of "flat" parameters 22 /// to a wasm function, or the maximum number of parameters a core wasm function 23 /// will take for just the parameters used. Over this number the heap is used 24 /// for transferring parameters. 25 pub const MAX_FLAT_PARAMS: usize = 16; 26 27 /// Similar to `MAX_FLAT_PARAMS`, but used for async-lowered imports instead of 28 /// sync ones. 29 pub const MAX_FLAT_ASYNC_PARAMS: usize = 4; 30 31 /// Canonical ABI-defined constant for the maximum number of "flat" results. 32 /// This number of results are returned directly from wasm and otherwise results 33 /// are transferred through memory. 34 pub const MAX_FLAT_RESULTS: usize = 1; 35 36 /// Sentinel value in `result_count_or_max_if_async` as part of the 37 /// `prepare_call` libcall which indicates that preparation is being done for an 38 /// async function that produces no result, aka there is no return pointer. 39 pub const PREPARE_ASYNC_NO_RESULT: u32 = u32::MAX; 40 41 /// Sentinel value in `result_count_or_max_if_async` as part of the 42 /// `prepare_call` libcall which indicates that preparation is being done for an 43 /// async function that produces at least one result, aka there is a return 44 /// pointer. 45 pub const PREPARE_ASYNC_WITH_RESULT: u32 = u32::MAX - 1; 46 47 /// Bit flag for indicating async-lifted exports 48 /// 49 /// This flag may be passed to the `async-start` built-in function (which is 50 /// called from both async->async and async->sync adapters) to indicate that the 51 /// callee is an async-lifted export. 52 pub const START_FLAG_ASYNC_CALLEE: i32 = 1 << 0; 53 54 mod artifacts; 55 mod info; 56 mod intrinsic; 57 mod names; 58 mod types; 59 mod vmcomponent_offsets; 60 pub use self::artifacts::*; 61 pub use self::info::*; 62 pub use self::intrinsic::*; 63 pub use self::names::*; 64 pub use self::types::*; 65 pub use self::vmcomponent_offsets::*; 66 67 #[cfg(feature = "compile")] 68 mod compiler; 69 #[cfg(feature = "compile")] 70 pub mod dfg; 71 #[cfg(feature = "compile")] 72 mod translate; 73 #[cfg(feature = "compile")] 74 mod types_builder; 75 #[cfg(feature = "compile")] 76 pub use self::compiler::*; 77 #[cfg(feature = "compile")] 78 pub use self::translate::*; 79 #[cfg(feature = "compile")] 80 pub use self::types_builder::*; 81 82 /// Helper macro, like `foreach_transcoder`, to iterate over builtins for 83 /// components unrelated to transcoding. 84 #[macro_export] 85 macro_rules! foreach_builtin_component_function { 86 ($mac:ident) => { 87 $mac! { 88 resource_new32(vmctx: vmctx, caller_instance: u32, resource: u32, rep: u32) -> u64; 89 resource_rep32(vmctx: vmctx, caller_instance: u32, resource: u32, idx: u32) -> u64; 90 91 // Returns an `Option<u32>` where `None` is "no destructor needed" 92 // and `Some(val)` is "run the destructor on this rep". The option 93 // is encoded as a 64-bit integer where the low bit is Some/None 94 // and bits 1-33 are the payload. 95 resource_drop(vmctx: vmctx, caller_instance: u32, resource: u32, idx: u32) -> u64; 96 97 resource_transfer_own(vmctx: vmctx, src_idx: u32, src_table: u32, dst_table: u32) -> u64; 98 resource_transfer_borrow(vmctx: vmctx, src_idx: u32, src_table: u32, dst_table: u32) -> u64; 99 100 enter_sync_call(vmctx: vmctx, caller_instance: u32, callee_async: u32, callee_instance: u32) -> bool; 101 exit_sync_call(vmctx: vmctx) -> bool; 102 103 #[cfg(feature = "component-model-async")] 104 backpressure_modify(vmctx: vmctx, caller_instance: u32, increment: u8) -> bool; 105 #[cfg(feature = "component-model-async")] 106 task_return(vmctx: vmctx, caller_instance: u32, ty: u32, options: u32, storage: ptr_u8, storage_len: size) -> bool; 107 #[cfg(feature = "component-model-async")] 108 task_cancel(vmctx: vmctx, caller_instance: u32) -> bool; 109 #[cfg(feature = "component-model-async")] 110 waitable_set_new(vmctx: vmctx, caller_instance: u32) -> u64; 111 #[cfg(feature = "component-model-async")] 112 waitable_set_wait(vmctx: vmctx, caller_instance: u32, options: u32, set: u32, payload: u32) -> u64; 113 #[cfg(feature = "component-model-async")] 114 waitable_set_poll(vmctx: vmctx, caller_instance: u32, options: u32, set: u32, payload: u32) -> u64; 115 #[cfg(feature = "component-model-async")] 116 waitable_set_drop(vmctx: vmctx, caller_instance: u32, set: u32) -> bool; 117 #[cfg(feature = "component-model-async")] 118 waitable_join(vmctx: vmctx, caller_instance: u32, set: u32, waitable: u32) -> bool; 119 #[cfg(feature = "component-model-async")] 120 thread_yield(vmctx: vmctx, caller_instance: u32, cancellable: u8) -> u32; 121 #[cfg(feature = "component-model-async")] 122 subtask_drop(vmctx: vmctx, caller_instance: u32, task_id: u32) -> bool; 123 #[cfg(feature = "component-model-async")] 124 subtask_cancel(vmctx: vmctx, caller_instance: u32, async_: u8, task_id: u32) -> u64; 125 #[cfg(feature = "component-model-async")] 126 prepare_call( 127 vmctx: vmctx, 128 memory: ptr_u8, 129 start: ptr_u8, 130 return_: ptr_u8, 131 caller_instance: u32, 132 callee_instance: u32, 133 task_return_type: u32, 134 callee_async: u32, 135 string_encoding: u32, 136 result_count_or_max_if_async: u32, 137 storage: ptr_u8, 138 storage_len: size 139 ) -> bool; 140 #[cfg(feature = "component-model-async")] 141 sync_start(vmctx: vmctx, callback: ptr_u8, storage: ptr_u8, storage_len: size, callee: ptr_u8, param_count: u32) -> bool; 142 #[cfg(feature = "component-model-async")] 143 async_start(vmctx: vmctx, callback: ptr_u8, post_return: ptr_u8, callee: ptr_u8, param_count: u32, result_count: u32, flags: u32) -> u64; 144 #[cfg(feature = "component-model-async")] 145 future_new(vmctx: vmctx, caller_instance: u32, ty: u32) -> u64; 146 #[cfg(feature = "component-model-async")] 147 future_write(vmctx: vmctx, caller_instance: u32, ty: u32, options: u32, future: u32, address: u32) -> u64; 148 #[cfg(feature = "component-model-async")] 149 future_read(vmctx: vmctx, caller_instance: u32, ty: u32, options: u32, future: u32, address: u32) -> u64; 150 #[cfg(feature = "component-model-async")] 151 future_cancel_write(vmctx: vmctx, caller_instance: u32, ty: u32, async_: u8, writer: u32) -> u64; 152 #[cfg(feature = "component-model-async")] 153 future_cancel_read(vmctx: vmctx, caller_instance: u32, ty: u32, async_: u8, reader: u32) -> u64; 154 #[cfg(feature = "component-model-async")] 155 future_drop_writable(vmctx: vmctx, caller_instance: u32, ty: u32, writer: u32) -> bool; 156 #[cfg(feature = "component-model-async")] 157 future_drop_readable(vmctx: vmctx, caller_instance: u32, ty: u32, reader: u32) -> bool; 158 #[cfg(feature = "component-model-async")] 159 stream_new(vmctx: vmctx, caller_instance: u32, ty: u32) -> u64; 160 #[cfg(feature = "component-model-async")] 161 stream_write(vmctx: vmctx, caller_instance: u32, ty: u32, options: u32, stream: u32, address: u32, count: u32) -> u64; 162 #[cfg(feature = "component-model-async")] 163 stream_read(vmctx: vmctx, caller_instance: u32, ty: u32, options: u32, stream: u32, address: u32, count: u32) -> u64; 164 #[cfg(feature = "component-model-async")] 165 stream_cancel_write(vmctx: vmctx, caller_instance: u32, ty: u32, async_: u8, writer: u32) -> u64; 166 #[cfg(feature = "component-model-async")] 167 stream_cancel_read(vmctx: vmctx, caller_instance: u32, ty: u32, async_: u8, reader: u32) -> u64; 168 #[cfg(feature = "component-model-async")] 169 stream_drop_writable(vmctx: vmctx, caller_instance: u32, ty: u32, writer: u32) -> bool; 170 #[cfg(feature = "component-model-async")] 171 stream_drop_readable(vmctx: vmctx, caller_instance: u32, ty: u32, reader: u32) -> bool; 172 #[cfg(feature = "component-model-async")] 173 flat_stream_write(vmctx: vmctx, caller_instance: u32, ty: u32, options:u32, payload_size: u32, payload_align: u32, stream: u32, address: u32, count: u32) -> u64; 174 #[cfg(feature = "component-model-async")] 175 flat_stream_read(vmctx: vmctx, caller_instance: u32, ty: u32, options: u32, payload_size: u32, payload_align: u32, stream: u32, address: u32, count: u32) -> u64; 176 #[cfg(feature = "component-model-async")] 177 error_context_new(vmctx: vmctx, caller_instance: u32, ty: u32, options: u32, debug_msg_address: u32, debug_msg_len: u32) -> u64; 178 #[cfg(feature = "component-model-async")] 179 error_context_debug_message(vmctx: vmctx, caller_instance: u32, ty: u32, options: u32, err_ctx_handle: u32, debug_msg_address: u32) -> bool; 180 #[cfg(feature = "component-model-async")] 181 error_context_drop(vmctx: vmctx, caller_instance: u32, ty: u32, err_ctx_handle: u32) -> bool; 182 #[cfg(feature = "component-model-async")] 183 future_transfer(vmctx: vmctx, src_idx: u32, src_table: u32, dst_table: u32) -> u64; 184 #[cfg(feature = "component-model-async")] 185 stream_transfer(vmctx: vmctx, src_idx: u32, src_table: u32, dst_table: u32) -> u64; 186 #[cfg(feature = "component-model-async")] 187 error_context_transfer(vmctx: vmctx, src_idx: u32, src_table: u32, dst_table: u32) -> u64; 188 #[cfg(feature = "component-model-async")] 189 context_get(vmctx: vmctx, caller_instance: u32, slot: u32) -> u64; 190 #[cfg(feature = "component-model-async")] 191 context_set(vmctx: vmctx, caller_instance: u32, slot: u32, val: u32) -> bool; 192 #[cfg(feature = "component-model-async")] 193 thread_index(vmctx: vmctx) -> u64; 194 #[cfg(feature = "component-model-async")] 195 thread_new_indirect(vmctx: vmctx, caller_instance: u32, func_ty_id: u32, func_table_idx: u32, func_idx: u32, context: u32) -> u64; 196 #[cfg(feature = "component-model-async")] 197 thread_suspend_to_suspended(vmctx: vmctx, caller_instance: u32, cancellable: u8, thread_idx: u32) -> u32; 198 #[cfg(feature = "component-model-async")] 199 thread_suspend_to(vmctx: vmctx, caller_instance: u32, cancellable: u8, thread_idx: u32) -> u32; 200 #[cfg(feature = "component-model-async")] 201 thread_suspend(vmctx: vmctx, caller_instance: u32, cancellable: u8) -> u32; 202 #[cfg(feature = "component-model-async")] 203 thread_unsuspend(vmctx: vmctx, caller_instance: u32, thread_idx: u32) -> bool; 204 #[cfg(feature = "component-model-async")] 205 thread_yield_to_suspended(vmctx: vmctx, caller_instance: u32, cancellable: u8, thread_idx: u32) -> u32; 206 207 trap(vmctx: vmctx, code: u32) -> bool; 208 209 utf8_to_utf8(vmctx: vmctx, src: ptr_u8, len: size, dst: ptr_u8) -> bool; 210 utf16_to_utf16(vmctx: vmctx, src: ptr_u16, len: size, dst: ptr_u16) -> bool; 211 latin1_to_latin1(vmctx: vmctx, src: ptr_u8, len: size, dst: ptr_u8) -> bool; 212 latin1_to_utf16(vmctx: vmctx, src: ptr_u8, len: size, dst: ptr_u16) -> bool; 213 utf8_to_utf16(vmctx: vmctx, src: ptr_u8, len: size, dst: ptr_u16) -> size; 214 utf16_to_utf8(vmctx: vmctx, src: ptr_u16, src_len: size, dst: ptr_u8, dst_len: size, ret2: ptr_size) -> size; 215 latin1_to_utf8(vmctx: vmctx, src: ptr_u8, src_len: size, dst: ptr_u8, dst_len: size, ret2: ptr_size) -> size; 216 utf16_to_compact_probably_utf16(vmctx: vmctx, src: ptr_u16, len: size, dst: ptr_u16) -> size; 217 utf8_to_latin1(vmctx: vmctx, src: ptr_u8, len: size, dst: ptr_u8, ret2: ptr_size) -> size; 218 utf16_to_latin1(vmctx: vmctx, src: ptr_u16, len: size, dst: ptr_u8, ret2: ptr_size) -> size; 219 utf8_to_compact_utf16(vmctx: vmctx, src: ptr_u8, src_len: size, dst: ptr_u16, dst_len: size, bytes_so_far: size) -> size; 220 utf16_to_compact_utf16(vmctx: vmctx, src: ptr_u16, src_len: size, dst: ptr_u16, dst_len: size, bytes_so_far: size) -> size; 221 } 222 }; 223 } 224 225 // Define `struct ComponentBuiltinFunctionIndex` 226 declare_builtin_index! { 227 /// An index type for component builtin functions. 228 pub struct ComponentBuiltinFunctionIndex: foreach_builtin_component_function; 229 } 230