wasmtime_c_api/
lib.rs

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
17pub use wasmtime;
18
19mod config;
20mod engine;
21mod error;
22mod r#extern;
23mod func;
24mod global;
25mod instance;
26mod linker;
27mod memory;
28mod module;
29#[cfg(feature = "profiling")]
30mod profiling;
31mod r#ref;
32mod sharedmemory;
33mod store;
34mod table;
35mod trap;
36mod types;
37mod val;
38mod vec;
39
40pub use crate::config::*;
41pub use crate::engine::*;
42pub use crate::error::*;
43pub use crate::func::*;
44pub use crate::global::*;
45pub use crate::instance::*;
46pub use crate::linker::*;
47pub use crate::memory::*;
48pub use crate::module::*;
49pub use crate::r#extern::*;
50pub use crate::r#ref::*;
51pub use crate::store::*;
52pub use crate::table::*;
53pub use crate::trap::*;
54pub use crate::types::*;
55pub use crate::val::*;
56pub use crate::vec::*;
57
58#[cfg(feature = "async")]
59mod r#async;
60#[cfg(feature = "async")]
61pub use crate::r#async::*;
62
63#[cfg(feature = "wasi")]
64mod wasi;
65#[cfg(feature = "wasi")]
66pub use crate::wasi::*;
67
68#[cfg(feature = "wat")]
69mod wat2wasm;
70#[cfg(feature = "wat")]
71pub 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.
78pub(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.
86pub struct ForeignData {
87    data: *mut std::ffi::c_void,
88    finalizer: Option<extern "C" fn(*mut std::ffi::c_void)>,
89}
90
91unsafe impl Send for ForeignData {}
92unsafe impl Sync for ForeignData {}
93
94impl 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.
107unsafe 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`
116unsafe 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
124pub(crate) fn abort(name: &str) -> ! {
125    eprintln!("`{name}` is not implemented");
126    std::process::abort();
127}