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/// Helper for running a C-defined finalizer over some data when the Rust
110/// structure is dropped.
111pub struct ForeignData {
112    data: *mut std::ffi::c_void,
113    finalizer: Option<extern "C" fn(*mut std::ffi::c_void)>,
114}
115
116unsafe impl Send for ForeignData {}
117unsafe impl Sync for ForeignData {}
118
119impl Drop for ForeignData {
120    fn drop(&mut self) {
121        if let Some(f) = self.finalizer {
122            f(self.data);
123        }
124    }
125}
126
127/// Helper for creating Rust slices from C inputs.
128///
129/// This specifically disregards the `ptr` argument if the length is zero. The
130/// `ptr` in that case maybe `NULL` or invalid, and it's not valid to have a
131/// zero-length Rust slice with a `NULL` pointer.
132unsafe fn slice_from_raw_parts<'a, T>(ptr: *const T, len: usize) -> &'a [T] {
133    if len == 0 {
134        &[]
135    } else {
136        std::slice::from_raw_parts(ptr, len)
137    }
138}
139
140/// Same as above, but for `*_mut`
141unsafe fn slice_from_raw_parts_mut<'a, T>(ptr: *mut T, len: usize) -> &'a mut [T] {
142    if len == 0 {
143        &mut []
144    } else {
145        std::slice::from_raw_parts_mut(ptr, len)
146    }
147}
148
149pub(crate) fn abort(name: &str) -> ! {
150    eprintln!("`{name}` is not implemented");
151    std::process::abort();
152}