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#![expect(unsafe_op_in_unsafe_fn, reason = "crate isn't migrated yet")]
17
18pub use wasmtime;
19
20mod config;
21mod engine;
22mod error;
23mod r#extern;
24mod func;
25mod global;
26mod instance;
27mod linker;
28mod memory;
29mod module;
30#[cfg(feature = "profiling")]
31mod profiling;
32mod r#ref;
33mod sharedmemory;
34mod store;
35mod table;
36mod trap;
37mod types;
38mod val;
39mod vec;
40
41pub use crate::config::*;
42pub use crate::engine::*;
43pub use crate::error::*;
44pub use crate::r#extern::*;
45pub use crate::func::*;
46pub use crate::global::*;
47pub use crate::instance::*;
48pub use crate::linker::*;
49pub use crate::memory::*;
50pub use crate::module::*;
51pub use crate::r#ref::*;
52pub use crate::store::*;
53pub use crate::table::*;
54pub use crate::trap::*;
55pub use crate::types::*;
56pub use crate::val::*;
57pub use crate::vec::*;
58
59#[cfg(feature = "async")]
60mod r#async;
61#[cfg(feature = "async")]
62pub use crate::r#async::*;
63
64#[cfg(feature = "wasi")]
65mod wasi;
66#[cfg(feature = "wasi")]
67pub use crate::wasi::*;
68
69#[cfg(all(feature = "component-model", feature = "wasi"))]
70mod wasip2;
71#[cfg(all(feature = "component-model", feature = "wasi"))]
72pub use crate::wasip2::*;
73
74#[cfg(feature = "wat")]
75mod wat2wasm;
76#[cfg(feature = "wat")]
77pub use crate::wat2wasm::*;
78
79#[cfg(feature = "component-model")]
80mod component;
81#[cfg(feature = "component-model")]
82pub 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.
89pub(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.
97pub struct ForeignData {
98    data: *mut std::ffi::c_void,
99    finalizer: Option<extern "C" fn(*mut std::ffi::c_void)>,
100}
101
102unsafe impl Send for ForeignData {}
103unsafe impl Sync for ForeignData {}
104
105impl 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.
118unsafe 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`
127unsafe 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
135pub(crate) fn abort(name: &str) -> ! {
136    eprintln!("`{name}` is not implemented");
137    std::process::abort();
138}