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