Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/crates/c-api/src/module.rs
1692 views
1
use crate::{
2
CExternType, handle_result, wasm_byte_vec_t, wasm_engine_t, wasm_exporttype_t,
3
wasm_exporttype_vec_t, wasm_importtype_t, wasm_importtype_vec_t, wasm_store_t,
4
wasmtime_error_t,
5
};
6
use anyhow::Context;
7
use std::ffi::CStr;
8
use std::os::raw::c_char;
9
use wasmtime::{Engine, Module};
10
11
#[derive(Clone)]
12
pub struct wasm_module_t {
13
pub(crate) module: Module,
14
}
15
16
wasmtime_c_api_macros::declare_ref!(wasm_module_t);
17
18
impl wasm_module_t {
19
pub(crate) fn new(module: Module) -> wasm_module_t {
20
wasm_module_t { module }
21
}
22
}
23
24
#[repr(C)]
25
#[derive(Clone)]
26
pub struct wasm_shared_module_t {
27
module: Module,
28
}
29
30
wasmtime_c_api_macros::declare_own!(wasm_shared_module_t);
31
32
#[unsafe(no_mangle)]
33
#[cfg(any(feature = "cranelift", feature = "winch"))]
34
pub unsafe extern "C" fn wasm_module_new(
35
store: &mut wasm_store_t,
36
binary: &wasm_byte_vec_t,
37
) -> Option<Box<wasm_module_t>> {
38
match Module::from_binary(store.store.context().engine(), binary.as_slice()) {
39
Ok(module) => Some(Box::new(wasm_module_t::new(module))),
40
Err(_) => None,
41
}
42
}
43
44
#[unsafe(no_mangle)]
45
#[cfg(any(feature = "cranelift", feature = "winch"))]
46
pub unsafe extern "C" fn wasm_module_validate(
47
store: &mut wasm_store_t,
48
binary: &wasm_byte_vec_t,
49
) -> bool {
50
Module::validate(store.store.context().engine(), binary.as_slice()).is_ok()
51
}
52
53
fn fill_exports(module: &Module, out: &mut wasm_exporttype_vec_t) {
54
let exports = module
55
.exports()
56
.map(|e| {
57
Some(Box::new(wasm_exporttype_t::new(
58
e.name().to_owned(),
59
CExternType::new(e.ty()),
60
)))
61
})
62
.collect::<Vec<_>>();
63
out.set_buffer(exports);
64
}
65
66
fn fill_imports(module: &Module, out: &mut wasm_importtype_vec_t) {
67
let imports = module
68
.imports()
69
.map(|i| {
70
Some(Box::new(wasm_importtype_t::new(
71
i.module().to_owned(),
72
i.name().to_owned(),
73
CExternType::new(i.ty()),
74
)))
75
})
76
.collect::<Vec<_>>();
77
out.set_buffer(imports);
78
}
79
80
#[unsafe(no_mangle)]
81
pub extern "C" fn wasm_module_exports(module: &wasm_module_t, out: &mut wasm_exporttype_vec_t) {
82
fill_exports(&module.module, out);
83
}
84
85
#[unsafe(no_mangle)]
86
pub extern "C" fn wasm_module_imports(module: &wasm_module_t, out: &mut wasm_importtype_vec_t) {
87
fill_imports(&module.module, out);
88
}
89
90
#[unsafe(no_mangle)]
91
pub extern "C" fn wasm_module_share(module: &wasm_module_t) -> Box<wasm_shared_module_t> {
92
Box::new(wasm_shared_module_t {
93
module: module.module.clone(),
94
})
95
}
96
97
#[unsafe(no_mangle)]
98
pub unsafe extern "C" fn wasm_module_obtain(
99
store: &mut wasm_store_t,
100
shared_module: &wasm_shared_module_t,
101
) -> Option<Box<wasm_module_t>> {
102
let module = shared_module.module.clone();
103
if Engine::same(store.store.context().engine(), module.engine()) {
104
Some(Box::new(wasm_module_t::new(module)))
105
} else {
106
None
107
}
108
}
109
110
#[unsafe(no_mangle)]
111
#[cfg(any(feature = "cranelift", feature = "winch"))]
112
pub extern "C" fn wasm_module_serialize(module: &wasm_module_t, ret: &mut wasm_byte_vec_t) {
113
if let Ok(buf) = module.module.serialize() {
114
ret.set_buffer(buf);
115
}
116
}
117
118
#[unsafe(no_mangle)]
119
pub unsafe extern "C" fn wasm_module_deserialize(
120
store: &mut wasm_store_t,
121
binary: &wasm_byte_vec_t,
122
) -> Option<Box<wasm_module_t>> {
123
match Module::deserialize(store.store.context().engine(), binary.as_slice()) {
124
Ok(module) => Some(Box::new(wasm_module_t::new(module))),
125
Err(_) => None,
126
}
127
}
128
129
#[derive(Clone)]
130
pub struct wasmtime_module_t {
131
pub(crate) module: Module,
132
}
133
134
wasmtime_c_api_macros::declare_own!(wasmtime_module_t);
135
136
#[unsafe(no_mangle)]
137
#[cfg(any(feature = "cranelift", feature = "winch"))]
138
pub unsafe extern "C" fn wasmtime_module_new(
139
engine: &wasm_engine_t,
140
wasm: *const u8,
141
len: usize,
142
out: &mut *mut wasmtime_module_t,
143
) -> Option<Box<wasmtime_error_t>> {
144
handle_result(
145
Module::from_binary(&engine.engine, crate::slice_from_raw_parts(wasm, len)),
146
|module| {
147
*out = Box::into_raw(Box::new(wasmtime_module_t { module }));
148
},
149
)
150
}
151
152
#[unsafe(no_mangle)]
153
pub extern "C" fn wasmtime_module_clone(module: &wasmtime_module_t) -> Box<wasmtime_module_t> {
154
Box::new(module.clone())
155
}
156
157
#[unsafe(no_mangle)]
158
pub extern "C" fn wasmtime_module_exports(
159
module: &wasmtime_module_t,
160
out: &mut wasm_exporttype_vec_t,
161
) {
162
fill_exports(&module.module, out);
163
}
164
165
#[unsafe(no_mangle)]
166
pub extern "C" fn wasmtime_module_imports(
167
module: &wasmtime_module_t,
168
out: &mut wasm_importtype_vec_t,
169
) {
170
fill_imports(&module.module, out);
171
}
172
173
#[unsafe(no_mangle)]
174
#[cfg(any(feature = "cranelift", feature = "winch"))]
175
pub unsafe extern "C" fn wasmtime_module_validate(
176
engine: &wasm_engine_t,
177
wasm: *const u8,
178
len: usize,
179
) -> Option<Box<wasmtime_error_t>> {
180
let binary = crate::slice_from_raw_parts(wasm, len);
181
handle_result(Module::validate(&engine.engine, binary), |()| {})
182
}
183
184
#[unsafe(no_mangle)]
185
#[cfg(any(feature = "cranelift", feature = "winch"))]
186
pub extern "C" fn wasmtime_module_serialize(
187
module: &wasmtime_module_t,
188
ret: &mut wasm_byte_vec_t,
189
) -> Option<Box<wasmtime_error_t>> {
190
handle_result(module.module.serialize(), |buf| ret.set_buffer(buf))
191
}
192
193
#[unsafe(no_mangle)]
194
pub extern "C" fn wasmtime_module_image_range(
195
module: &wasmtime_module_t,
196
start: &mut *const u8,
197
end: &mut *const u8,
198
) {
199
let range = module.module.image_range();
200
*start = range.start;
201
*end = range.end;
202
}
203
204
#[unsafe(no_mangle)]
205
pub unsafe extern "C" fn wasmtime_module_deserialize(
206
engine: &wasm_engine_t,
207
bytes: *const u8,
208
len: usize,
209
out: &mut *mut wasmtime_module_t,
210
) -> Option<Box<wasmtime_error_t>> {
211
let bytes = crate::slice_from_raw_parts(bytes, len);
212
handle_result(Module::deserialize(&engine.engine, bytes), |module| {
213
*out = Box::into_raw(Box::new(wasmtime_module_t { module }));
214
})
215
}
216
217
#[unsafe(no_mangle)]
218
pub unsafe extern "C" fn wasmtime_module_deserialize_file(
219
engine: &wasm_engine_t,
220
path: *const c_char,
221
out: &mut *mut wasmtime_module_t,
222
) -> Option<Box<wasmtime_error_t>> {
223
let path = CStr::from_ptr(path);
224
let result = path
225
.to_str()
226
.context("input path is not valid utf-8")
227
.and_then(|path| Module::deserialize_file(&engine.engine, path));
228
handle_result(result, |module| {
229
*out = Box::into_raw(Box::new(wasmtime_module_t { module }));
230
})
231
}
232
233