xref: /wasmtime-44.0.1/crates/c-api/src/module.rs (revision dc029724)
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 std::ffi::CStr;
7 use std::os::raw::c_char;
8 use wasmtime::error::Context;
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 {
new(module: Module) -> wasm_module_t19     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"))]
wasm_module_new( store: &mut wasm_store_t, binary: &wasm_byte_vec_t, ) -> Option<Box<wasm_module_t>>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"))]
wasm_module_validate( store: &mut wasm_store_t, binary: &wasm_byte_vec_t, ) -> bool46 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 
fill_exports(module: &Module, out: &mut wasm_exporttype_vec_t)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 
fill_imports(module: &Module, out: &mut wasm_importtype_vec_t)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)]
wasm_module_exports(module: &wasm_module_t, out: &mut wasm_exporttype_vec_t)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)]
wasm_module_imports(module: &wasm_module_t, out: &mut wasm_importtype_vec_t)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)]
wasm_module_share(module: &wasm_module_t) -> Box<wasm_shared_module_t>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)]
wasm_module_obtain( store: &mut wasm_store_t, shared_module: &wasm_shared_module_t, ) -> Option<Box<wasm_module_t>>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"))]
wasm_module_serialize(module: &wasm_module_t, ret: &mut wasm_byte_vec_t)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)]
wasm_module_deserialize( store: &mut wasm_store_t, binary: &wasm_byte_vec_t, ) -> Option<Box<wasm_module_t>>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"))]
wasmtime_module_new( engine: &wasm_engine_t, wasm: *const u8, len: usize, out: &mut *mut wasmtime_module_t, ) -> Option<Box<wasmtime_error_t>>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)]
wasmtime_module_clone(module: &wasmtime_module_t) -> Box<wasmtime_module_t>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)]
wasmtime_module_exports( module: &wasmtime_module_t, out: &mut wasm_exporttype_vec_t, )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)]
wasmtime_module_imports( module: &wasmtime_module_t, out: &mut wasm_importtype_vec_t, )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"))]
wasmtime_module_validate( engine: &wasm_engine_t, wasm: *const u8, len: usize, ) -> Option<Box<wasmtime_error_t>>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"))]
wasmtime_module_serialize( module: &wasmtime_module_t, ret: &mut wasm_byte_vec_t, ) -> Option<Box<wasmtime_error_t>>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)]
wasmtime_module_image_range( module: &wasmtime_module_t, start: &mut *const u8, end: &mut *const u8, )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)]
wasmtime_module_deserialize( engine: &wasm_engine_t, bytes: *const u8, len: usize, out: &mut *mut wasmtime_module_t, ) -> Option<Box<wasmtime_error_t>>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)]
wasmtime_module_deserialize_file( engine: &wasm_engine_t, path: *const c_char, out: &mut *mut wasmtime_module_t, ) -> Option<Box<wasmtime_error_t>>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