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