wasmtime_c_api/
lib.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
//! This crate is the implementation of Wasmtime's C API.
//!
//! This crate is normally not intended to be used from Rust itself. For that,
//! see the `wasmtime` crate. It is possible to use this crate via Cargo, for
//! Rust crates that wrap C libraries that use wasmtime. Most often, this crate
//! is compiled as a cdylib or staticlib, via the `wasmtime-c-api` crate.
//!
//! 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)]

pub use wasmtime;

mod config;
mod engine;
mod error;
mod r#extern;
mod func;
mod global;
mod instance;
mod linker;
mod memory;
mod module;
#[cfg(feature = "profiling")]
mod profiling;
mod r#ref;
mod sharedmemory;
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 = "async")]
mod r#async;
#[cfg(feature = "async")]
pub use crate::r#async::*;

#[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)
    }
}

pub(crate) fn abort(name: &str) -> ! {
    eprintln!("`{name}` is not implemented");
    std::process::abort();
}