xref: /wasmtime-44.0.1/crates/c-api/src/lib.rs (revision 0dbb6f3d)
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 
18 pub use wasmtime;
19 
20 mod config;
21 mod engine;
22 mod error;
23 mod exn;
24 mod r#extern;
25 mod func;
26 mod global;
27 mod instance;
28 mod linker;
29 mod memory;
30 mod module;
31 #[cfg(feature = "profiling")]
32 mod profiling;
33 mod r#ref;
34 mod sharedmemory;
35 mod store;
36 mod table;
37 mod tag;
38 mod trap;
39 mod types;
40 mod val;
41 mod vec;
42 
43 pub use crate::config::*;
44 pub use crate::engine::*;
45 pub use crate::error::*;
46 pub use crate::exn::*;
47 pub use crate::r#extern::*;
48 pub use crate::func::*;
49 pub use crate::global::*;
50 pub use crate::instance::*;
51 pub use crate::linker::*;
52 pub use crate::memory::*;
53 pub use crate::module::*;
54 pub use crate::r#ref::*;
55 pub use crate::store::*;
56 pub use crate::table::*;
57 pub use crate::tag::*;
58 pub use crate::trap::*;
59 pub use crate::types::*;
60 pub use crate::val::*;
61 pub use crate::vec::*;
62 
63 #[cfg(feature = "async")]
64 mod r#async;
65 #[cfg(feature = "async")]
66 pub use crate::r#async::*;
67 
68 #[cfg(feature = "wasi")]
69 mod wasi;
70 #[cfg(feature = "wasi")]
71 pub use crate::wasi::*;
72 
73 #[cfg(feature = "wat")]
74 mod wat2wasm;
75 #[cfg(feature = "wat")]
76 pub use crate::wat2wasm::*;
77 
78 #[cfg(feature = "component-model")]
79 mod component;
80 #[cfg(feature = "component-model")]
81 pub 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.
initialize<T>(dst: &mut std::mem::MaybeUninit<T>, val: T)88 pub(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.
96 pub struct ForeignData {
97     data: *mut std::ffi::c_void,
98     finalizer: Option<extern "C" fn(*mut std::ffi::c_void)>,
99 }
100 
101 unsafe impl Send for ForeignData {}
102 unsafe impl Sync for ForeignData {}
103 
104 impl Drop for ForeignData {
drop(&mut self)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.
slice_from_raw_parts<'a, T>(ptr: *const T, len: usize) -> &'a [T]117 unsafe 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`
slice_from_raw_parts_mut<'a, T>(ptr: *mut T, len: usize) -> &'a mut [T]126 unsafe 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 
abort(name: &str) -> !134 pub(crate) fn abort(name: &str) -> ! {
135     eprintln!("`{name}` is not implemented");
136     std::process::abort();
137 }
138