1 //! This crate is the implementation of Wasmtime's C API. 2 //! 3 //! This crate is normally not intended to be used from Rust itself. For that, 4 //! see the `wasmtime` crate. It is possible to use this crate via Cargo, for 5 //! Rust crates that wrap C libraries that use wasmtime. Most often, this crate 6 //! is compiled as a cdylib or staticlib, via the `wasmtime-c-api` crate. 7 //! 8 //! Documentation for this crate largely lives in the header 9 //! files of the `include` directory for this crate. 10 //! 11 //! At a high level this crate implements the `wasm.h` API with some gymnastics, 12 //! but otherwise an accompanying `wasmtime.h` API is provided which is more 13 //! specific to Wasmtime and has fewer gymnastics to implement. 14 15 #![expect(non_camel_case_types, reason = "matching C style, not Rust")] 16 #![expect(unsafe_op_in_unsafe_fn, reason = "crate isn't migrated yet")] 17 18 pub use wasmtime; 19 20 mod config; 21 mod engine; 22 mod error; 23 mod r#extern; 24 mod func; 25 mod global; 26 mod instance; 27 mod linker; 28 mod memory; 29 mod module; 30 #[cfg(feature = "profiling")] 31 mod profiling; 32 mod r#ref; 33 mod sharedmemory; 34 mod store; 35 mod table; 36 mod trap; 37 mod types; 38 mod val; 39 mod vec; 40 41 pub use crate::config::*; 42 pub use crate::engine::*; 43 pub use crate::error::*; 44 pub use crate::r#extern::*; 45 pub use crate::func::*; 46 pub use crate::global::*; 47 pub use crate::instance::*; 48 pub use crate::linker::*; 49 pub use crate::memory::*; 50 pub use crate::module::*; 51 pub use crate::r#ref::*; 52 pub use crate::store::*; 53 pub use crate::table::*; 54 pub use crate::trap::*; 55 pub use crate::types::*; 56 pub use crate::val::*; 57 pub use crate::vec::*; 58 59 #[cfg(feature = "async")] 60 mod r#async; 61 #[cfg(feature = "async")] 62 pub use crate::r#async::*; 63 64 #[cfg(feature = "wasi")] 65 mod wasi; 66 #[cfg(feature = "wasi")] 67 pub use crate::wasi::*; 68 69 #[cfg(all(feature = "component-model", feature = "wasi"))] 70 mod wasip2; 71 #[cfg(all(feature = "component-model", feature = "wasi"))] 72 pub use crate::wasip2::*; 73 74 #[cfg(feature = "wat")] 75 mod wat2wasm; 76 #[cfg(feature = "wat")] 77 pub use crate::wat2wasm::*; 78 79 #[cfg(feature = "component-model")] 80 mod component; 81 #[cfg(feature = "component-model")] 82 pub use crate::component::*; 83 84 /// Initialize a `MaybeUninit<T>` 85 /// 86 /// TODO: Replace calls to this function with 87 /// https://doc.rust-lang.org/nightly/std/mem/union.MaybeUninit.html#method.write 88 /// once it is stable. 89 pub(crate) fn initialize<T>(dst: &mut std::mem::MaybeUninit<T>, val: T) { 90 unsafe { 91 std::ptr::write(dst.as_mut_ptr(), val); 92 } 93 } 94 95 /// Helper for running a C-defined finalizer over some data when the Rust 96 /// structure is dropped. 97 pub struct ForeignData { 98 data: *mut std::ffi::c_void, 99 finalizer: Option<extern "C" fn(*mut std::ffi::c_void)>, 100 } 101 102 unsafe impl Send for ForeignData {} 103 unsafe impl Sync for ForeignData {} 104 105 impl Drop for ForeignData { 106 fn drop(&mut self) { 107 if let Some(f) = self.finalizer { 108 f(self.data); 109 } 110 } 111 } 112 113 /// Helper for creating Rust slices from C inputs. 114 /// 115 /// This specifically disregards the `ptr` argument if the length is zero. The 116 /// `ptr` in that case maybe `NULL` or invalid, and it's not valid to have a 117 /// zero-length Rust slice with a `NULL` pointer. 118 unsafe fn slice_from_raw_parts<'a, T>(ptr: *const T, len: usize) -> &'a [T] { 119 if len == 0 { 120 &[] 121 } else { 122 std::slice::from_raw_parts(ptr, len) 123 } 124 } 125 126 /// Same as above, but for `*_mut` 127 unsafe fn slice_from_raw_parts_mut<'a, T>(ptr: *mut T, len: usize) -> &'a mut [T] { 128 if len == 0 { 129 &mut [] 130 } else { 131 std::slice::from_raw_parts_mut(ptr, len) 132 } 133 } 134 135 pub(crate) fn abort(name: &str) -> ! { 136 eprintln!("`{name}` is not implemented"); 137 std::process::abort(); 138 } 139