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