Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/crates/c-api/src/extern.rs
1692 views
1
use crate::{
2
WasmStoreRef, WasmtimeStoreContext, wasm_externkind_t, wasm_externtype_t, wasm_func_t,
3
wasm_global_t, wasm_memory_t, wasm_table_t,
4
};
5
use std::mem::ManuallyDrop;
6
use wasmtime::{Extern, Func, Global, Memory, SharedMemory, Table};
7
8
#[derive(Clone)]
9
pub struct wasm_extern_t {
10
pub(crate) store: WasmStoreRef,
11
pub(crate) which: Extern,
12
}
13
14
wasmtime_c_api_macros::declare_ref!(wasm_extern_t);
15
16
#[unsafe(no_mangle)]
17
pub extern "C" fn wasm_extern_kind(e: &wasm_extern_t) -> wasm_externkind_t {
18
match e.which {
19
Extern::Func(_) => crate::WASM_EXTERN_FUNC,
20
Extern::Global(_) => crate::WASM_EXTERN_GLOBAL,
21
Extern::Table(_) => crate::WASM_EXTERN_TABLE,
22
Extern::Memory(_) => crate::WASM_EXTERN_MEMORY,
23
Extern::SharedMemory(_) => panic!(
24
"Shared Memory no implemented for wasm_* types. Please use wasmtime_* types instead"
25
),
26
Extern::Tag(_) => todo!(), // FIXME: #10252 C embedder API for exceptions and control tags.
27
}
28
}
29
30
#[unsafe(no_mangle)]
31
pub unsafe extern "C" fn wasm_extern_type(e: &wasm_extern_t) -> Box<wasm_externtype_t> {
32
Box::new(wasm_externtype_t::from_extern_type(
33
e.which.ty(&e.store.context()),
34
))
35
}
36
37
#[unsafe(no_mangle)]
38
pub extern "C" fn wasm_extern_as_func(e: &wasm_extern_t) -> Option<&wasm_func_t> {
39
wasm_func_t::try_from(e)
40
}
41
42
#[unsafe(no_mangle)]
43
pub extern "C" fn wasm_extern_as_func_const(e: &wasm_extern_t) -> Option<&wasm_func_t> {
44
wasm_extern_as_func(e)
45
}
46
47
#[unsafe(no_mangle)]
48
pub extern "C" fn wasm_extern_as_global(e: &wasm_extern_t) -> Option<&wasm_global_t> {
49
wasm_global_t::try_from(e)
50
}
51
52
#[unsafe(no_mangle)]
53
pub extern "C" fn wasm_extern_as_global_const(e: &wasm_extern_t) -> Option<&wasm_global_t> {
54
wasm_extern_as_global(e)
55
}
56
57
#[unsafe(no_mangle)]
58
pub extern "C" fn wasm_extern_as_table(e: &wasm_extern_t) -> Option<&wasm_table_t> {
59
wasm_table_t::try_from(e)
60
}
61
62
#[unsafe(no_mangle)]
63
pub extern "C" fn wasm_extern_as_table_const(e: &wasm_extern_t) -> Option<&wasm_table_t> {
64
wasm_extern_as_table(e)
65
}
66
67
#[unsafe(no_mangle)]
68
pub extern "C" fn wasm_extern_as_memory(e: &wasm_extern_t) -> Option<&wasm_memory_t> {
69
wasm_memory_t::try_from(e)
70
}
71
72
#[unsafe(no_mangle)]
73
pub extern "C" fn wasm_extern_as_memory_const(e: &wasm_extern_t) -> Option<&wasm_memory_t> {
74
wasm_extern_as_memory(e)
75
}
76
77
#[repr(C)]
78
pub struct wasmtime_extern_t {
79
pub kind: wasmtime_extern_kind_t,
80
pub of: wasmtime_extern_union,
81
}
82
83
pub type wasmtime_extern_kind_t = u8;
84
pub const WASMTIME_EXTERN_FUNC: wasmtime_extern_kind_t = 0;
85
pub const WASMTIME_EXTERN_GLOBAL: wasmtime_extern_kind_t = 1;
86
pub const WASMTIME_EXTERN_TABLE: wasmtime_extern_kind_t = 2;
87
pub const WASMTIME_EXTERN_MEMORY: wasmtime_extern_kind_t = 3;
88
pub const WASMTIME_EXTERN_SHAREDMEMORY: wasmtime_extern_kind_t = 4;
89
90
#[repr(C)]
91
pub union wasmtime_extern_union {
92
pub func: Func,
93
pub table: Table,
94
pub global: Global,
95
pub memory: Memory,
96
pub sharedmemory: ManuallyDrop<Box<SharedMemory>>,
97
}
98
99
impl Drop for wasmtime_extern_t {
100
fn drop(&mut self) {
101
if self.kind == WASMTIME_EXTERN_SHAREDMEMORY {
102
unsafe {
103
ManuallyDrop::drop(&mut self.of.sharedmemory);
104
}
105
}
106
}
107
}
108
109
impl wasmtime_extern_t {
110
pub unsafe fn to_extern(&self) -> Extern {
111
match self.kind {
112
WASMTIME_EXTERN_FUNC => Extern::Func(self.of.func),
113
WASMTIME_EXTERN_GLOBAL => Extern::Global(self.of.global),
114
WASMTIME_EXTERN_TABLE => Extern::Table(self.of.table),
115
WASMTIME_EXTERN_MEMORY => Extern::Memory(self.of.memory),
116
WASMTIME_EXTERN_SHAREDMEMORY => Extern::SharedMemory((**self.of.sharedmemory).clone()),
117
other => panic!("unknown wasmtime_extern_kind_t: {other}"),
118
}
119
}
120
}
121
122
impl From<Extern> for wasmtime_extern_t {
123
fn from(item: Extern) -> wasmtime_extern_t {
124
match item {
125
Extern::Func(func) => wasmtime_extern_t {
126
kind: WASMTIME_EXTERN_FUNC,
127
of: wasmtime_extern_union { func },
128
},
129
Extern::Global(global) => wasmtime_extern_t {
130
kind: WASMTIME_EXTERN_GLOBAL,
131
of: wasmtime_extern_union { global },
132
},
133
Extern::Table(table) => wasmtime_extern_t {
134
kind: WASMTIME_EXTERN_TABLE,
135
of: wasmtime_extern_union { table },
136
},
137
Extern::Memory(memory) => wasmtime_extern_t {
138
kind: WASMTIME_EXTERN_MEMORY,
139
of: wasmtime_extern_union { memory },
140
},
141
Extern::SharedMemory(sharedmemory) => wasmtime_extern_t {
142
kind: WASMTIME_EXTERN_SHAREDMEMORY,
143
of: wasmtime_extern_union {
144
sharedmemory: ManuallyDrop::new(Box::new(sharedmemory)),
145
},
146
},
147
Extern::Tag(_) => todo!(), // FIXME: #10252 C embedder API for exceptions and control tags.
148
}
149
}
150
}
151
152
#[unsafe(no_mangle)]
153
pub unsafe extern "C" fn wasmtime_extern_delete(e: &mut ManuallyDrop<wasmtime_extern_t>) {
154
ManuallyDrop::drop(e);
155
}
156
157
#[unsafe(no_mangle)]
158
pub unsafe extern "C" fn wasmtime_extern_type(
159
store: WasmtimeStoreContext<'_>,
160
e: &wasmtime_extern_t,
161
) -> Box<wasm_externtype_t> {
162
Box::new(wasm_externtype_t::from_extern_type(e.to_extern().ty(store)))
163
}
164
165