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