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