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 exn; 24 mod r#extern; 25 mod func; 26 mod global; 27 mod instance; 28 mod linker; 29 mod memory; 30 mod module; 31 #[cfg(feature = "profiling")] 32 mod profiling; 33 mod r#ref; 34 mod sharedmemory; 35 mod store; 36 mod table; 37 mod tag; 38 mod trap; 39 mod types; 40 mod val; 41 mod vec; 42 43 pub use crate::config::*; 44 pub use crate::engine::*; 45 pub use crate::error::*; 46 pub use crate::exn::*; 47 pub use crate::r#extern::*; 48 pub use crate::func::*; 49 pub use crate::global::*; 50 pub use crate::instance::*; 51 pub use crate::linker::*; 52 pub use crate::memory::*; 53 pub use crate::module::*; 54 pub use crate::r#ref::*; 55 pub use crate::store::*; 56 pub use crate::table::*; 57 pub use crate::tag::*; 58 pub use crate::trap::*; 59 pub use crate::types::*; 60 pub use crate::val::*; 61 pub use crate::vec::*; 62 63 #[cfg(feature = "async")] 64 mod r#async; 65 #[cfg(feature = "async")] 66 pub use crate::r#async::*; 67 68 #[cfg(feature = "wasi")] 69 mod wasi; 70 #[cfg(feature = "wasi")] 71 pub use crate::wasi::*; 72 73 #[cfg(feature = "wat")] 74 mod wat2wasm; 75 #[cfg(feature = "wat")] 76 pub use crate::wat2wasm::*; 77 78 #[cfg(feature = "component-model")] 79 mod component; 80 #[cfg(feature = "component-model")] 81 pub use crate::component::*; 82 83 /// Initialize a `MaybeUninit<T>` 84 /// 85 /// TODO: Replace calls to this function with 86 /// https://doc.rust-lang.org/nightly/std/mem/union.MaybeUninit.html#method.write 87 /// once it is stable. 88 pub(crate) fn initialize<T>(dst: &mut std::mem::MaybeUninit<T>, val: T) { 89 unsafe { 90 std::ptr::write(dst.as_mut_ptr(), val); 91 } 92 } 93 94 /// Helper for running a C-defined finalizer over some data when the Rust 95 /// structure is dropped. 96 pub struct ForeignData { 97 data: *mut std::ffi::c_void, 98 finalizer: Option<extern "C" fn(*mut std::ffi::c_void)>, 99 } 100 101 unsafe impl Send for ForeignData {} 102 unsafe impl Sync for ForeignData {} 103 104 impl Drop for ForeignData { 105 fn drop(&mut self) { 106 if let Some(f) = self.finalizer { 107 f(self.data); 108 } 109 } 110 } 111 112 /// Helper for creating Rust slices from C inputs. 113 /// 114 /// This specifically disregards the `ptr` argument if the length is zero. The 115 /// `ptr` in that case maybe `NULL` or invalid, and it's not valid to have a 116 /// zero-length Rust slice with a `NULL` pointer. 117 unsafe fn slice_from_raw_parts<'a, T>(ptr: *const T, len: usize) -> &'a [T] { 118 if len == 0 { 119 &[] 120 } else { 121 std::slice::from_raw_parts(ptr, len) 122 } 123 } 124 125 /// Same as above, but for `*_mut` 126 unsafe fn slice_from_raw_parts_mut<'a, T>(ptr: *mut T, len: usize) -> &'a mut [T] { 127 if len == 0 { 128 &mut [] 129 } else { 130 std::slice::from_raw_parts_mut(ptr, len) 131 } 132 } 133 134 pub(crate) fn abort(name: &str) -> ! { 135 eprintln!("`{name}` is not implemented"); 136 std::process::abort(); 137 } 138