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(feature = "wat")] 70 mod wat2wasm; 71 #[cfg(feature = "wat")] 72 pub use crate::wat2wasm::*; 73 74 #[cfg(feature = "component-model")] 75 mod component; 76 #[cfg(feature = "component-model")] 77 pub use crate::component::*; 78 79 /// Initialize a `MaybeUninit<T>` 80 /// 81 /// TODO: Replace calls to this function with 82 /// https://doc.rust-lang.org/nightly/std/mem/union.MaybeUninit.html#method.write 83 /// once it is stable. 84 pub(crate) fn initialize<T>(dst: &mut std::mem::MaybeUninit<T>, val: T) { 85 unsafe { 86 std::ptr::write(dst.as_mut_ptr(), val); 87 } 88 } 89 90 /// Helper for running a C-defined finalizer over some data when the Rust 91 /// structure is dropped. 92 pub struct ForeignData { 93 data: *mut std::ffi::c_void, 94 finalizer: Option<extern "C" fn(*mut std::ffi::c_void)>, 95 } 96 97 unsafe impl Send for ForeignData {} 98 unsafe impl Sync for ForeignData {} 99 100 impl Drop for ForeignData { 101 fn drop(&mut self) { 102 if let Some(f) = self.finalizer { 103 f(self.data); 104 } 105 } 106 } 107 108 /// Helper for creating Rust slices from C inputs. 109 /// 110 /// This specifically disregards the `ptr` argument if the length is zero. The 111 /// `ptr` in that case maybe `NULL` or invalid, and it's not valid to have a 112 /// zero-length Rust slice with a `NULL` pointer. 113 unsafe fn slice_from_raw_parts<'a, T>(ptr: *const T, len: usize) -> &'a [T] { 114 if len == 0 { 115 &[] 116 } else { 117 std::slice::from_raw_parts(ptr, len) 118 } 119 } 120 121 /// Same as above, but for `*_mut` 122 unsafe fn slice_from_raw_parts_mut<'a, T>(ptr: *mut T, len: usize) -> &'a mut [T] { 123 if len == 0 { 124 &mut [] 125 } else { 126 std::slice::from_raw_parts_mut(ptr, len) 127 } 128 } 129 130 pub(crate) fn abort(name: &str) -> ! { 131 eprintln!("`{name}` is not implemented"); 132 std::process::abort(); 133 } 134