xref: /wasmtime-44.0.1/crates/c-api/src/module.rs (revision e9e4afe2)
1 use crate::{
2     handle_result, wasm_byte_vec_t, wasm_engine_t, wasm_exporttype_t, wasm_exporttype_vec_t,
3     wasm_extern_t, wasm_importtype_t, wasm_importtype_vec_t, wasm_moduletype_t, wasm_store_t,
4     wasmtime_error_t,
5 };
6 use std::ptr;
7 use wasmtime::{Engine, Extern, Module};
8 
9 #[derive(Clone)]
10 #[repr(transparent)]
11 pub struct wasm_module_t {
12     ext: wasm_extern_t,
13 }
14 
15 wasmtime_c_api_macros::declare_ref!(wasm_module_t);
16 
17 impl wasm_module_t {
18     pub(crate) fn new(module: Module) -> wasm_module_t {
19         wasm_module_t {
20             ext: wasm_extern_t {
21                 which: module.into(),
22             },
23         }
24     }
25 
26     pub(crate) fn try_from(e: &wasm_extern_t) -> Option<&wasm_module_t> {
27         match &e.which {
28             Extern::Module(_) => Some(unsafe { &*(e as *const _ as *const _) }),
29             _ => None,
30         }
31     }
32 
33     pub(crate) fn module(&self) -> &Module {
34         match &self.ext.which {
35             Extern::Module(i) => i,
36             _ => unreachable!(),
37         }
38     }
39 }
40 
41 #[repr(C)]
42 #[derive(Clone)]
43 pub struct wasm_shared_module_t {
44     module: Module,
45 }
46 
47 wasmtime_c_api_macros::declare_own!(wasm_shared_module_t);
48 
49 #[no_mangle]
50 pub extern "C" fn wasm_module_new(
51     store: &wasm_store_t,
52     binary: &wasm_byte_vec_t,
53 ) -> Option<Box<wasm_module_t>> {
54     let mut ret = ptr::null_mut();
55     let engine = wasm_engine_t {
56         engine: store.store.engine().clone(),
57     };
58     match wasmtime_module_new(&engine, binary, &mut ret) {
59         Some(_err) => None,
60         None => {
61             assert!(!ret.is_null());
62             Some(unsafe { Box::from_raw(ret) })
63         }
64     }
65 }
66 
67 #[no_mangle]
68 pub extern "C" fn wasmtime_module_new(
69     engine: &wasm_engine_t,
70     binary: &wasm_byte_vec_t,
71     ret: &mut *mut wasm_module_t,
72 ) -> Option<Box<wasmtime_error_t>> {
73     let binary = binary.as_slice();
74     handle_result(Module::from_binary(&engine.engine, binary), |module| {
75         let module = Box::new(wasm_module_t::new(module));
76         *ret = Box::into_raw(module);
77     })
78 }
79 
80 #[no_mangle]
81 pub extern "C" fn wasm_module_validate(store: &wasm_store_t, binary: &wasm_byte_vec_t) -> bool {
82     wasmtime_module_validate(store, binary).is_none()
83 }
84 
85 #[no_mangle]
86 pub extern "C" fn wasmtime_module_validate(
87     store: &wasm_store_t,
88     binary: &wasm_byte_vec_t,
89 ) -> Option<Box<wasmtime_error_t>> {
90     let binary = binary.as_slice();
91     handle_result(Module::validate(store.store.engine(), binary), |()| {})
92 }
93 
94 #[no_mangle]
95 pub extern "C" fn wasm_module_as_extern(m: &wasm_module_t) -> &wasm_extern_t {
96     &m.ext
97 }
98 
99 #[no_mangle]
100 pub extern "C" fn wasm_module_exports(module: &wasm_module_t, out: &mut wasm_exporttype_vec_t) {
101     let exports = module
102         .module()
103         .exports()
104         .map(|e| {
105             Some(Box::new(wasm_exporttype_t::new(
106                 e.name().to_owned(),
107                 e.ty(),
108             )))
109         })
110         .collect::<Vec<_>>();
111     out.set_buffer(exports);
112 }
113 
114 #[no_mangle]
115 pub extern "C" fn wasm_module_imports(module: &wasm_module_t, out: &mut wasm_importtype_vec_t) {
116     let imports = module
117         .module()
118         .imports()
119         .map(|i| {
120             Some(Box::new(wasm_importtype_t::new(
121                 i.module().to_owned(),
122                 i.name().map(|s| s.to_owned()),
123                 i.ty(),
124             )))
125         })
126         .collect::<Vec<_>>();
127     out.set_buffer(imports);
128 }
129 
130 #[no_mangle]
131 pub extern "C" fn wasm_module_share(module: &wasm_module_t) -> Box<wasm_shared_module_t> {
132     Box::new(wasm_shared_module_t {
133         module: module.module().clone(),
134     })
135 }
136 
137 #[no_mangle]
138 pub extern "C" fn wasm_module_obtain(
139     store: &wasm_store_t,
140     shared_module: &wasm_shared_module_t,
141 ) -> Option<Box<wasm_module_t>> {
142     let module = shared_module.module.clone();
143     if !Engine::same(store.store.engine(), module.engine()) {
144         return None;
145     }
146     Some(Box::new(wasm_module_t::new(module)))
147 }
148 
149 #[no_mangle]
150 pub extern "C" fn wasm_module_serialize(module: &wasm_module_t, ret: &mut wasm_byte_vec_t) {
151     drop(wasmtime_module_serialize(module, ret));
152 }
153 
154 #[no_mangle]
155 pub extern "C" fn wasm_module_deserialize(
156     store: &wasm_store_t,
157     binary: &wasm_byte_vec_t,
158 ) -> Option<Box<wasm_module_t>> {
159     let mut ret = ptr::null_mut();
160     let engine = wasm_engine_t {
161         engine: store.store.engine().clone(),
162     };
163     match wasmtime_module_deserialize(&engine, binary, &mut ret) {
164         Some(_err) => None,
165         None => {
166             assert!(!ret.is_null());
167             Some(unsafe { Box::from_raw(ret) })
168         }
169     }
170 }
171 
172 #[no_mangle]
173 pub extern "C" fn wasmtime_module_serialize(
174     module: &wasm_module_t,
175     ret: &mut wasm_byte_vec_t,
176 ) -> Option<Box<wasmtime_error_t>> {
177     handle_result(module.module().serialize(), |buf| {
178         ret.set_buffer(buf);
179     })
180 }
181 
182 #[no_mangle]
183 pub extern "C" fn wasmtime_module_deserialize(
184     engine: &wasm_engine_t,
185     binary: &wasm_byte_vec_t,
186     ret: &mut *mut wasm_module_t,
187 ) -> Option<Box<wasmtime_error_t>> {
188     handle_result(Module::new(&engine.engine, binary.as_slice()), |module| {
189         let module = Box::new(wasm_module_t::new(module));
190         *ret = Box::into_raw(module);
191     })
192 }
193 
194 #[no_mangle]
195 pub extern "C" fn wasm_module_type(f: &wasm_module_t) -> Box<wasm_moduletype_t> {
196     Box::new(wasm_moduletype_t::new(f.module().ty()))
197 }
198