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