Skip to main content

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 sharedmemory;
33mod store;
34mod table;
35mod tag;
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::store::*;
52pub use crate::table::*;
53pub use crate::tag::*;
54pub use crate::trap::*;
55pub use crate::types::*;
56pub use crate::val::*;
57pub use crate::vec::*;
58
59#[cfg(feature = "gc")]
60mod anyref;
61#[cfg(feature = "gc")]
62mod arrayref;
63#[cfg(feature = "gc")]
64mod eqref;
65#[cfg(feature = "gc")]
66mod exnref;
67#[cfg(feature = "gc")]
68mod externref;
69#[cfg(feature = "gc")]
70mod r#ref;
71#[cfg(feature = "gc")]
72mod structref;
73
74#[cfg(feature = "gc")]
75pub use crate::anyref::*;
76#[cfg(feature = "gc")]
77pub use crate::arrayref::*;
78#[cfg(feature = "gc")]
79pub use crate::eqref::*;
80#[cfg(feature = "gc")]
81pub use crate::exnref::*;
82#[cfg(feature = "gc")]
83pub use crate::externref::*;
84#[cfg(feature = "gc")]
85pub use crate::r#ref::*;
86#[cfg(feature = "gc")]
87pub use crate::structref::*;
88
89#[cfg(feature = "async")]
90mod r#async;
91#[cfg(feature = "async")]
92pub use crate::r#async::*;
93
94#[cfg(feature = "wasi")]
95mod wasi;
96#[cfg(feature = "wasi")]
97pub use crate::wasi::*;
98
99#[cfg(feature = "wat")]
100mod wat2wasm;
101#[cfg(feature = "wat")]
102pub use crate::wat2wasm::*;
103
104#[cfg(feature = "component-model")]
105mod component;
106#[cfg(feature = "component-model")]
107pub use crate::component::*;
108
109/// Initialize a `MaybeUninit<T>`
110///
111/// TODO: Replace calls to this function with
112/// https://doc.rust-lang.org/nightly/std/mem/union.MaybeUninit.html#method.write
113/// once it is stable.
114pub(crate) fn initialize<T>(dst: &mut std::mem::MaybeUninit<T>, val: T) {
115    unsafe {
116        std::ptr::write(dst.as_mut_ptr(), val);
117    }
118}
119
120/// Helper for running a C-defined finalizer over some data when the Rust
121/// structure is dropped.
122pub struct ForeignData {
123    data: *mut std::ffi::c_void,
124    finalizer: Option<extern "C" fn(*mut std::ffi::c_void)>,
125}
126
127unsafe impl Send for ForeignData {}
128unsafe impl Sync for ForeignData {}
129
130impl Drop for ForeignData {
131    fn drop(&mut self) {
132        if let Some(f) = self.finalizer {
133            f(self.data);
134        }
135    }
136}
137
138/// Helper for creating Rust slices from C inputs.
139///
140/// This specifically disregards the `ptr` argument if the length is zero. The
141/// `ptr` in that case maybe `NULL` or invalid, and it's not valid to have a
142/// zero-length Rust slice with a `NULL` pointer.
143unsafe fn slice_from_raw_parts<'a, T>(ptr: *const T, len: usize) -> &'a [T] {
144    if len == 0 {
145        &[]
146    } else {
147        std::slice::from_raw_parts(ptr, len)
148    }
149}
150
151/// Same as above, but for `*_mut`
152unsafe fn slice_from_raw_parts_mut<'a, T>(ptr: *mut T, len: usize) -> &'a mut [T] {
153    if len == 0 {
154        &mut []
155    } else {
156        std::slice::from_raw_parts_mut(ptr, len)
157    }
158}
159
160pub(crate) fn abort(name: &str) -> ! {
161    eprintln!("`{name}` is not implemented");
162    std::process::abort();
163}