1 use crate::host_ref::HostRef;
2 use crate::{
3 handle_result, wasm_byte_vec_t, wasm_exporttype_t, wasm_exporttype_vec_t, wasm_importtype_t,
4 wasm_importtype_vec_t, wasm_store_t, wasmtime_error_t,
5 };
6 use std::ptr;
7 use wasmtime::{Engine, Module};
8
9 #[repr(C)]
10 #[derive(Clone)]
11 pub struct wasm_module_t {
12 pub(crate) module: HostRef<Module>,
13 pub(crate) imports: Vec<wasm_importtype_t>,
14 pub(crate) exports: Vec<wasm_exporttype_t>,
15 }
16
17 wasmtime_c_api_macros::declare_ref!(wasm_module_t);
18
19 impl wasm_module_t {
externref(&self) -> wasmtime::ExternRef20 fn externref(&self) -> wasmtime::ExternRef {
21 self.module.clone().into()
22 }
23 }
24
25 #[repr(C)]
26 #[derive(Clone)]
27 pub struct wasm_shared_module_t {
28 module: Module,
29 }
30
31 wasmtime_c_api_macros::declare_own!(wasm_shared_module_t);
32
33 #[no_mangle]
wasm_module_new( store: &wasm_store_t, binary: &wasm_byte_vec_t, ) -> Option<Box<wasm_module_t>>34 pub extern "C" fn wasm_module_new(
35 store: &wasm_store_t,
36 binary: &wasm_byte_vec_t,
37 ) -> Option<Box<wasm_module_t>> {
38 let mut ret = ptr::null_mut();
39 match wasmtime_module_new(store, binary, &mut ret) {
40 Some(_err) => None,
41 None => {
42 assert!(!ret.is_null());
43 Some(unsafe { Box::from_raw(ret) })
44 }
45 }
46 }
47
48 #[no_mangle]
wasmtime_module_new( store: &wasm_store_t, binary: &wasm_byte_vec_t, ret: &mut *mut wasm_module_t, ) -> Option<Box<wasmtime_error_t>>49 pub extern "C" fn wasmtime_module_new(
50 store: &wasm_store_t,
51 binary: &wasm_byte_vec_t,
52 ret: &mut *mut wasm_module_t,
53 ) -> Option<Box<wasmtime_error_t>> {
54 let binary = binary.as_slice();
55 let store = &store.store;
56 handle_result(Module::from_binary(store.engine(), binary), |module| {
57 let imports = module
58 .imports()
59 .map(|i| wasm_importtype_t::new(i.module().to_owned(), i.name().to_owned(), i.ty()))
60 .collect::<Vec<_>>();
61 let exports = module
62 .exports()
63 .map(|e| wasm_exporttype_t::new(e.name().to_owned(), e.ty()))
64 .collect::<Vec<_>>();
65 let module = Box::new(wasm_module_t {
66 module: HostRef::new(store, module),
67 imports,
68 exports,
69 });
70 *ret = Box::into_raw(module);
71 })
72 }
73
74 #[no_mangle]
wasm_module_validate(store: &wasm_store_t, binary: &wasm_byte_vec_t) -> bool75 pub extern "C" fn wasm_module_validate(store: &wasm_store_t, binary: &wasm_byte_vec_t) -> bool {
76 wasmtime_module_validate(store, binary).is_none()
77 }
78
79 #[no_mangle]
wasmtime_module_validate( store: &wasm_store_t, binary: &wasm_byte_vec_t, ) -> Option<Box<wasmtime_error_t>>80 pub extern "C" fn wasmtime_module_validate(
81 store: &wasm_store_t,
82 binary: &wasm_byte_vec_t,
83 ) -> Option<Box<wasmtime_error_t>> {
84 let binary = binary.as_slice();
85 handle_result(Module::validate(store.store.engine(), binary), |()| {})
86 }
87
88 #[no_mangle]
wasm_module_exports(module: &wasm_module_t, out: &mut wasm_exporttype_vec_t)89 pub extern "C" fn wasm_module_exports(module: &wasm_module_t, out: &mut wasm_exporttype_vec_t) {
90 let buffer = module
91 .exports
92 .iter()
93 .map(|et| Some(Box::new(et.clone())))
94 .collect::<Vec<_>>();
95 out.set_buffer(buffer);
96 }
97
98 #[no_mangle]
wasm_module_imports(module: &wasm_module_t, out: &mut wasm_importtype_vec_t)99 pub extern "C" fn wasm_module_imports(module: &wasm_module_t, out: &mut wasm_importtype_vec_t) {
100 let buffer = module
101 .imports
102 .iter()
103 .map(|it| Some(Box::new(it.clone())))
104 .collect::<Vec<_>>();
105 out.set_buffer(buffer);
106 }
107
108 #[no_mangle]
wasm_module_share(module: &wasm_module_t) -> Box<wasm_shared_module_t>109 pub extern "C" fn wasm_module_share(module: &wasm_module_t) -> Box<wasm_shared_module_t> {
110 Box::new(wasm_shared_module_t {
111 module: module.module.borrow().clone(),
112 })
113 }
114
115 #[no_mangle]
wasm_module_obtain( store: &wasm_store_t, shared_module: &wasm_shared_module_t, ) -> Option<Box<wasm_module_t>>116 pub extern "C" fn wasm_module_obtain(
117 store: &wasm_store_t,
118 shared_module: &wasm_shared_module_t,
119 ) -> Option<Box<wasm_module_t>> {
120 let module = shared_module.module.clone();
121 if !Engine::same(store.store.engine(), module.engine()) {
122 return None;
123 }
124 let imports = module
125 .imports()
126 .map(|i| wasm_importtype_t::new(i.module().to_owned(), i.name().to_owned(), i.ty()))
127 .collect::<Vec<_>>();
128 let exports = module
129 .exports()
130 .map(|e| wasm_exporttype_t::new(e.name().to_owned(), e.ty()))
131 .collect::<Vec<_>>();
132 Some(Box::new(wasm_module_t {
133 module: HostRef::new(&store.store, module),
134 imports,
135 exports,
136 }))
137 }
138