Implement Wasmtime's new API as designed by RFC 11. This is quite a large commit which has had lots of discussion externally, so for more information it's best to read the RFC thread and the PR thread.
110 lines
2.8 KiB
Rust
110 lines
2.8 KiB
Rust
//! This crate is the implementation of Wasmtime's C API.
|
|
//!
|
|
//! This crate is not intended to be used from Rust itself, for that see the
|
|
//! `wasmtime` crate. Otherwise this is typically compiled as a
|
|
//! cdylib/staticlib. Documentation for this crate largely lives in the header
|
|
//! files of the `include` directory for this crate.
|
|
//!
|
|
//! At a high level this crate implements the `wasm.h` API with some gymnastics,
|
|
//! but otherwise an accompanying `wasmtime.h` API is provided which is more
|
|
//! specific to Wasmtime and has fewer gymnastics to implement.
|
|
|
|
#![allow(non_snake_case, non_camel_case_types, non_upper_case_globals)]
|
|
|
|
mod config;
|
|
mod engine;
|
|
mod error;
|
|
mod r#extern;
|
|
mod func;
|
|
mod global;
|
|
mod instance;
|
|
mod linker;
|
|
mod memory;
|
|
mod module;
|
|
mod r#ref;
|
|
mod store;
|
|
mod table;
|
|
mod trap;
|
|
mod types;
|
|
mod val;
|
|
mod vec;
|
|
|
|
pub use crate::config::*;
|
|
pub use crate::engine::*;
|
|
pub use crate::error::*;
|
|
pub use crate::func::*;
|
|
pub use crate::global::*;
|
|
pub use crate::instance::*;
|
|
pub use crate::linker::*;
|
|
pub use crate::memory::*;
|
|
pub use crate::module::*;
|
|
pub use crate::r#extern::*;
|
|
pub use crate::r#ref::*;
|
|
pub use crate::store::*;
|
|
pub use crate::table::*;
|
|
pub use crate::trap::*;
|
|
pub use crate::types::*;
|
|
pub use crate::val::*;
|
|
pub use crate::vec::*;
|
|
|
|
#[cfg(feature = "wasi")]
|
|
mod wasi;
|
|
#[cfg(feature = "wasi")]
|
|
pub use crate::wasi::*;
|
|
|
|
#[cfg(feature = "wat")]
|
|
mod wat2wasm;
|
|
#[cfg(feature = "wat")]
|
|
pub use crate::wat2wasm::*;
|
|
|
|
/// Initialize a `MaybeUninit<T>`
|
|
///
|
|
/// TODO: Replace calls to this function with
|
|
/// https://doc.rust-lang.org/nightly/std/mem/union.MaybeUninit.html#method.write
|
|
/// once it is stable.
|
|
pub(crate) fn initialize<T>(dst: &mut std::mem::MaybeUninit<T>, val: T) {
|
|
unsafe {
|
|
std::ptr::write(dst.as_mut_ptr(), val);
|
|
}
|
|
}
|
|
|
|
/// Helper for running a C-defined finalizer over some data when the Rust
|
|
/// structure is dropped.
|
|
pub struct ForeignData {
|
|
data: *mut std::ffi::c_void,
|
|
finalizer: Option<extern "C" fn(*mut std::ffi::c_void)>,
|
|
}
|
|
|
|
unsafe impl Send for ForeignData {}
|
|
unsafe impl Sync for ForeignData {}
|
|
|
|
impl Drop for ForeignData {
|
|
fn drop(&mut self) {
|
|
if let Some(f) = self.finalizer {
|
|
f(self.data);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Helper for creating Rust slices from C inputs.
|
|
///
|
|
/// This specifically disregards the `ptr` argument if the length is zero. The
|
|
/// `ptr` in that case maybe `NULL` or invalid, and it's not valid to have a
|
|
/// zero-length Rust slice with a `NULL` pointer.
|
|
unsafe fn slice_from_raw_parts<'a, T>(ptr: *const T, len: usize) -> &'a [T] {
|
|
if len == 0 {
|
|
&[]
|
|
} else {
|
|
std::slice::from_raw_parts(ptr, len)
|
|
}
|
|
}
|
|
|
|
/// Same as above, but for `*_mut`
|
|
unsafe fn slice_from_raw_parts_mut<'a, T>(ptr: *mut T, len: usize) -> &'a mut [T] {
|
|
if len == 0 {
|
|
&mut []
|
|
} else {
|
|
std::slice::from_raw_parts_mut(ptr, len)
|
|
}
|
|
}
|