115c68f2cSYury Delendik use crate::{
290ac295eSAlex Crichton CExternType, handle_result, wasm_byte_vec_t, wasm_engine_t, wasm_exporttype_t,
390ac295eSAlex Crichton wasm_exporttype_vec_t, wasm_importtype_t, wasm_importtype_vec_t, wasm_store_t,
490ac295eSAlex Crichton wasmtime_error_t,
515c68f2cSYury Delendik };
69e0c9100SAlex Crichton use std::ffi::CStr;
79e0c9100SAlex Crichton use std::os::raw::c_char;
8*dc029724SNick Fitzgerald use wasmtime::error::Context;
976b82910SAlex Crichton use wasmtime::{Engine, Module};
106ef09359SAlex Crichton
116ef09359SAlex Crichton #[derive(Clone)]
126ef09359SAlex Crichton pub struct wasm_module_t {
1376b82910SAlex Crichton pub(crate) module: Module,
146ef09359SAlex Crichton }
156ef09359SAlex Crichton
166ef09359SAlex Crichton wasmtime_c_api_macros::declare_ref!(wasm_module_t);
176ef09359SAlex Crichton
1841caf67aSAlex Crichton impl wasm_module_t {
new(module: Module) -> wasm_module_t1976b82910SAlex Crichton pub(crate) fn new(module: Module) -> wasm_module_t {
2076b82910SAlex Crichton wasm_module_t { module }
2141caf67aSAlex Crichton }
2241caf67aSAlex Crichton }
2341caf67aSAlex Crichton
2415c68f2cSYury Delendik #[repr(C)]
2515c68f2cSYury Delendik #[derive(Clone)]
2615c68f2cSYury Delendik pub struct wasm_shared_module_t {
2715c68f2cSYury Delendik module: Module,
2815c68f2cSYury Delendik }
2915c68f2cSYury Delendik
3015c68f2cSYury Delendik wasmtime_c_api_macros::declare_own!(wasm_shared_module_t);
3115c68f2cSYury Delendik
32ae84e6edSAlex Crichton #[unsafe(no_mangle)]
33b7631976SAlex Crichton #[cfg(any(feature = "cranelift", feature = "winch"))]
wasm_module_new( store: &mut wasm_store_t, binary: &wasm_byte_vec_t, ) -> Option<Box<wasm_module_t>>347a1b7cdfSAlex Crichton pub unsafe extern "C" fn wasm_module_new(
357a1b7cdfSAlex Crichton store: &mut wasm_store_t,
366ef09359SAlex Crichton binary: &wasm_byte_vec_t,
376ef09359SAlex Crichton ) -> Option<Box<wasm_module_t>> {
387a1b7cdfSAlex Crichton match Module::from_binary(store.store.context().engine(), binary.as_slice()) {
3976b82910SAlex Crichton Ok(module) => Some(Box::new(wasm_module_t::new(module))),
407a1b7cdfSAlex Crichton Err(_) => None,
41bd374fd6SAlex Crichton }
42bd374fd6SAlex Crichton }
43bd374fd6SAlex Crichton
44ae84e6edSAlex Crichton #[unsafe(no_mangle)]
45b7631976SAlex Crichton #[cfg(any(feature = "cranelift", feature = "winch"))]
wasm_module_validate( store: &mut wasm_store_t, binary: &wasm_byte_vec_t, ) -> bool467a1b7cdfSAlex Crichton pub unsafe extern "C" fn wasm_module_validate(
477a1b7cdfSAlex Crichton store: &mut wasm_store_t,
48bd374fd6SAlex Crichton binary: &wasm_byte_vec_t,
497a1b7cdfSAlex Crichton ) -> bool {
507a1b7cdfSAlex Crichton Module::validate(store.store.context().engine(), binary.as_slice()).is_ok()
516ef09359SAlex Crichton }
526ef09359SAlex Crichton
fill_exports(module: &Module, out: &mut wasm_exporttype_vec_t)5313ec5ff6SAlex Crichton fn fill_exports(module: &Module, out: &mut wasm_exporttype_vec_t) {
5441caf67aSAlex Crichton let exports = module
5541caf67aSAlex Crichton .exports()
5641caf67aSAlex Crichton .map(|e| {
5741caf67aSAlex Crichton Some(Box::new(wasm_exporttype_t::new(
5841caf67aSAlex Crichton e.name().to_owned(),
598652011fSNick Fitzgerald CExternType::new(e.ty()),
6041caf67aSAlex Crichton )))
6141caf67aSAlex Crichton })
626ef09359SAlex Crichton .collect::<Vec<_>>();
6341caf67aSAlex Crichton out.set_buffer(exports);
646ef09359SAlex Crichton }
656ef09359SAlex Crichton
fill_imports(module: &Module, out: &mut wasm_importtype_vec_t)6613ec5ff6SAlex Crichton fn fill_imports(module: &Module, out: &mut wasm_importtype_vec_t) {
6741caf67aSAlex Crichton let imports = module
6841caf67aSAlex Crichton .imports()
6941caf67aSAlex Crichton .map(|i| {
7041caf67aSAlex Crichton Some(Box::new(wasm_importtype_t::new(
7141caf67aSAlex Crichton i.module().to_owned(),
7276b82910SAlex Crichton i.name().to_owned(),
738652011fSNick Fitzgerald CExternType::new(i.ty()),
7441caf67aSAlex Crichton )))
7541caf67aSAlex Crichton })
766ef09359SAlex Crichton .collect::<Vec<_>>();
7741caf67aSAlex Crichton out.set_buffer(imports);
786ef09359SAlex Crichton }
7915c68f2cSYury Delendik
80ae84e6edSAlex Crichton #[unsafe(no_mangle)]
wasm_module_exports(module: &wasm_module_t, out: &mut wasm_exporttype_vec_t)8113ec5ff6SAlex Crichton pub extern "C" fn wasm_module_exports(module: &wasm_module_t, out: &mut wasm_exporttype_vec_t) {
8213ec5ff6SAlex Crichton fill_exports(&module.module, out);
8313ec5ff6SAlex Crichton }
8413ec5ff6SAlex Crichton
85ae84e6edSAlex Crichton #[unsafe(no_mangle)]
wasm_module_imports(module: &wasm_module_t, out: &mut wasm_importtype_vec_t)8613ec5ff6SAlex Crichton pub extern "C" fn wasm_module_imports(module: &wasm_module_t, out: &mut wasm_importtype_vec_t) {
8713ec5ff6SAlex Crichton fill_imports(&module.module, out);
8813ec5ff6SAlex Crichton }
8913ec5ff6SAlex Crichton
90ae84e6edSAlex Crichton #[unsafe(no_mangle)]
wasm_module_share(module: &wasm_module_t) -> Box<wasm_shared_module_t>9115c68f2cSYury Delendik pub extern "C" fn wasm_module_share(module: &wasm_module_t) -> Box<wasm_shared_module_t> {
9215c68f2cSYury Delendik Box::new(wasm_shared_module_t {
9376b82910SAlex Crichton module: module.module.clone(),
9415c68f2cSYury Delendik })
9515c68f2cSYury Delendik }
9615c68f2cSYury Delendik
97ae84e6edSAlex Crichton #[unsafe(no_mangle)]
wasm_module_obtain( store: &mut wasm_store_t, shared_module: &wasm_shared_module_t, ) -> Option<Box<wasm_module_t>>987a1b7cdfSAlex Crichton pub unsafe extern "C" fn wasm_module_obtain(
997a1b7cdfSAlex Crichton store: &mut wasm_store_t,
10015c68f2cSYury Delendik shared_module: &wasm_shared_module_t,
10115c68f2cSYury Delendik ) -> Option<Box<wasm_module_t>> {
10215c68f2cSYury Delendik let module = shared_module.module.clone();
1037a1b7cdfSAlex Crichton if Engine::same(store.store.context().engine(), module.engine()) {
10476b82910SAlex Crichton Some(Box::new(wasm_module_t::new(module)))
1057a1b7cdfSAlex Crichton } else {
1067a1b7cdfSAlex Crichton None
10715c68f2cSYury Delendik }
10815c68f2cSYury Delendik }
109399ee0a5SYury Delendik
110ae84e6edSAlex Crichton #[unsafe(no_mangle)]
111b7631976SAlex Crichton #[cfg(any(feature = "cranelift", feature = "winch"))]
wasm_module_serialize(module: &wasm_module_t, ret: &mut wasm_byte_vec_t)112399ee0a5SYury Delendik pub extern "C" fn wasm_module_serialize(module: &wasm_module_t, ret: &mut wasm_byte_vec_t) {
11376b82910SAlex Crichton if let Ok(buf) = module.module.serialize() {
1147a1b7cdfSAlex Crichton ret.set_buffer(buf);
1157a1b7cdfSAlex Crichton }
116399ee0a5SYury Delendik }
117399ee0a5SYury Delendik
118ae84e6edSAlex Crichton #[unsafe(no_mangle)]
wasm_module_deserialize( store: &mut wasm_store_t, binary: &wasm_byte_vec_t, ) -> Option<Box<wasm_module_t>>1197a1b7cdfSAlex Crichton pub unsafe extern "C" fn wasm_module_deserialize(
1207a1b7cdfSAlex Crichton store: &mut wasm_store_t,
121399ee0a5SYury Delendik binary: &wasm_byte_vec_t,
122399ee0a5SYury Delendik ) -> Option<Box<wasm_module_t>> {
1237a1b7cdfSAlex Crichton match Module::deserialize(store.store.context().engine(), binary.as_slice()) {
12476b82910SAlex Crichton Ok(module) => Some(Box::new(wasm_module_t::new(module))),
1257a1b7cdfSAlex Crichton Err(_) => None,
126399ee0a5SYury Delendik }
127399ee0a5SYury Delendik }
128399ee0a5SYury Delendik
1297a1b7cdfSAlex Crichton #[derive(Clone)]
1307a1b7cdfSAlex Crichton pub struct wasmtime_module_t {
1317a1b7cdfSAlex Crichton pub(crate) module: Module,
132399ee0a5SYury Delendik }
133399ee0a5SYury Delendik
1341d319c0eS罗泽轩 wasmtime_c_api_macros::declare_own!(wasmtime_module_t);
1351d319c0eS罗泽轩
136ae84e6edSAlex Crichton #[unsafe(no_mangle)]
137b7631976SAlex Crichton #[cfg(any(feature = "cranelift", feature = "winch"))]
wasmtime_module_new( engine: &wasm_engine_t, wasm: *const u8, len: usize, out: &mut *mut wasmtime_module_t, ) -> Option<Box<wasmtime_error_t>>1387a1b7cdfSAlex Crichton pub unsafe extern "C" fn wasmtime_module_new(
139399ee0a5SYury Delendik engine: &wasm_engine_t,
1407a1b7cdfSAlex Crichton wasm: *const u8,
1417a1b7cdfSAlex Crichton len: usize,
1427a1b7cdfSAlex Crichton out: &mut *mut wasmtime_module_t,
143399ee0a5SYury Delendik ) -> Option<Box<wasmtime_error_t>> {
1448384f3a3SAlex Crichton handle_result(
1457a1b7cdfSAlex Crichton Module::from_binary(&engine.engine, crate::slice_from_raw_parts(wasm, len)),
1468384f3a3SAlex Crichton |module| {
1477a1b7cdfSAlex Crichton *out = Box::into_raw(Box::new(wasmtime_module_t { module }));
1488384f3a3SAlex Crichton },
1498384f3a3SAlex Crichton )
150399ee0a5SYury Delendik }
15141caf67aSAlex Crichton
152ae84e6edSAlex Crichton #[unsafe(no_mangle)]
wasmtime_module_clone(module: &wasmtime_module_t) -> Box<wasmtime_module_t>1537a1b7cdfSAlex Crichton pub extern "C" fn wasmtime_module_clone(module: &wasmtime_module_t) -> Box<wasmtime_module_t> {
1547a1b7cdfSAlex Crichton Box::new(module.clone())
1557a1b7cdfSAlex Crichton }
1567a1b7cdfSAlex Crichton
157ae84e6edSAlex Crichton #[unsafe(no_mangle)]
wasmtime_module_exports( module: &wasmtime_module_t, out: &mut wasm_exporttype_vec_t, )15813ec5ff6SAlex Crichton pub extern "C" fn wasmtime_module_exports(
15913ec5ff6SAlex Crichton module: &wasmtime_module_t,
16013ec5ff6SAlex Crichton out: &mut wasm_exporttype_vec_t,
16113ec5ff6SAlex Crichton ) {
16213ec5ff6SAlex Crichton fill_exports(&module.module, out);
16313ec5ff6SAlex Crichton }
16413ec5ff6SAlex Crichton
165ae84e6edSAlex Crichton #[unsafe(no_mangle)]
wasmtime_module_imports( module: &wasmtime_module_t, out: &mut wasm_importtype_vec_t, )16613ec5ff6SAlex Crichton pub extern "C" fn wasmtime_module_imports(
16713ec5ff6SAlex Crichton module: &wasmtime_module_t,
16813ec5ff6SAlex Crichton out: &mut wasm_importtype_vec_t,
16913ec5ff6SAlex Crichton ) {
17013ec5ff6SAlex Crichton fill_imports(&module.module, out);
17113ec5ff6SAlex Crichton }
17213ec5ff6SAlex Crichton
173ae84e6edSAlex Crichton #[unsafe(no_mangle)]
174b7631976SAlex Crichton #[cfg(any(feature = "cranelift", feature = "winch"))]
wasmtime_module_validate( engine: &wasm_engine_t, wasm: *const u8, len: usize, ) -> Option<Box<wasmtime_error_t>>1757a1b7cdfSAlex Crichton pub unsafe extern "C" fn wasmtime_module_validate(
1767a1b7cdfSAlex Crichton engine: &wasm_engine_t,
1777a1b7cdfSAlex Crichton wasm: *const u8,
1787a1b7cdfSAlex Crichton len: usize,
1797a1b7cdfSAlex Crichton ) -> Option<Box<wasmtime_error_t>> {
1807a1b7cdfSAlex Crichton let binary = crate::slice_from_raw_parts(wasm, len);
1817a1b7cdfSAlex Crichton handle_result(Module::validate(&engine.engine, binary), |()| {})
1827a1b7cdfSAlex Crichton }
1837a1b7cdfSAlex Crichton
184ae84e6edSAlex Crichton #[unsafe(no_mangle)]
185b7631976SAlex Crichton #[cfg(any(feature = "cranelift", feature = "winch"))]
wasmtime_module_serialize( module: &wasmtime_module_t, ret: &mut wasm_byte_vec_t, ) -> Option<Box<wasmtime_error_t>>1867a1b7cdfSAlex Crichton pub extern "C" fn wasmtime_module_serialize(
1877a1b7cdfSAlex Crichton module: &wasmtime_module_t,
1887a1b7cdfSAlex Crichton ret: &mut wasm_byte_vec_t,
1897a1b7cdfSAlex Crichton ) -> Option<Box<wasmtime_error_t>> {
1907a1b7cdfSAlex Crichton handle_result(module.module.serialize(), |buf| ret.set_buffer(buf))
1917a1b7cdfSAlex Crichton }
1927a1b7cdfSAlex Crichton
193ae84e6edSAlex Crichton #[unsafe(no_mangle)]
wasmtime_module_image_range( module: &wasmtime_module_t, start: &mut *const u8, end: &mut *const u8, )1942d43a28fSTyler Rockwood pub extern "C" fn wasmtime_module_image_range(
1952d43a28fSTyler Rockwood module: &wasmtime_module_t,
196120e6b23SAlex Crichton start: &mut *const u8,
197120e6b23SAlex Crichton end: &mut *const u8,
1982d43a28fSTyler Rockwood ) {
1992d43a28fSTyler Rockwood let range = module.module.image_range();
2002d43a28fSTyler Rockwood *start = range.start;
2012d43a28fSTyler Rockwood *end = range.end;
2022d43a28fSTyler Rockwood }
2032d43a28fSTyler Rockwood
204ae84e6edSAlex Crichton #[unsafe(no_mangle)]
wasmtime_module_deserialize( engine: &wasm_engine_t, bytes: *const u8, len: usize, out: &mut *mut wasmtime_module_t, ) -> Option<Box<wasmtime_error_t>>2057a1b7cdfSAlex Crichton pub unsafe extern "C" fn wasmtime_module_deserialize(
2067a1b7cdfSAlex Crichton engine: &wasm_engine_t,
2077a1b7cdfSAlex Crichton bytes: *const u8,
2087a1b7cdfSAlex Crichton len: usize,
2097a1b7cdfSAlex Crichton out: &mut *mut wasmtime_module_t,
2107a1b7cdfSAlex Crichton ) -> Option<Box<wasmtime_error_t>> {
2117a1b7cdfSAlex Crichton let bytes = crate::slice_from_raw_parts(bytes, len);
2127a1b7cdfSAlex Crichton handle_result(Module::deserialize(&engine.engine, bytes), |module| {
2137a1b7cdfSAlex Crichton *out = Box::into_raw(Box::new(wasmtime_module_t { module }));
2147a1b7cdfSAlex Crichton })
21541caf67aSAlex Crichton }
2169e0c9100SAlex Crichton
217ae84e6edSAlex Crichton #[unsafe(no_mangle)]
wasmtime_module_deserialize_file( engine: &wasm_engine_t, path: *const c_char, out: &mut *mut wasmtime_module_t, ) -> Option<Box<wasmtime_error_t>>2189e0c9100SAlex Crichton pub unsafe extern "C" fn wasmtime_module_deserialize_file(
2199e0c9100SAlex Crichton engine: &wasm_engine_t,
2209e0c9100SAlex Crichton path: *const c_char,
2219e0c9100SAlex Crichton out: &mut *mut wasmtime_module_t,
2229e0c9100SAlex Crichton ) -> Option<Box<wasmtime_error_t>> {
2239e0c9100SAlex Crichton let path = CStr::from_ptr(path);
2249e0c9100SAlex Crichton let result = path
2259e0c9100SAlex Crichton .to_str()
2269e0c9100SAlex Crichton .context("input path is not valid utf-8")
2279e0c9100SAlex Crichton .and_then(|path| Module::deserialize_file(&engine.engine, path));
2289e0c9100SAlex Crichton handle_result(result, |module| {
2299e0c9100SAlex Crichton *out = Box::into_raw(Box::new(wasmtime_module_t { module }));
2309e0c9100SAlex Crichton })
2319e0c9100SAlex Crichton }
232