xref: /wasmtime-44.0.1/crates/c-api/src/module.rs (revision a7f592a0)
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_store_t, wasmtime_error_t,
4     wasmtime_moduletype_t, StoreRef,
5 };
6 use wasmtime::{Engine, Extern, Module};
7 
8 #[derive(Clone)]
9 #[repr(transparent)]
10 pub struct wasm_module_t {
11     ext: wasm_extern_t,
12 }
13 
14 wasmtime_c_api_macros::declare_ref!(wasm_module_t);
15 
16 impl wasm_module_t {
17     pub(crate) fn new(store: StoreRef, module: Module) -> wasm_module_t {
18         wasm_module_t {
19             ext: wasm_extern_t {
20                 store: store,
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 unsafe extern "C" fn wasm_module_new(
51     store: &mut wasm_store_t,
52     binary: &wasm_byte_vec_t,
53 ) -> Option<Box<wasm_module_t>> {
54     match Module::from_binary(store.store.context().engine(), binary.as_slice()) {
55         Ok(module) => Some(Box::new(wasm_module_t::new(store.store.clone(), module))),
56         Err(_) => None,
57     }
58 }
59 
60 #[no_mangle]
61 pub unsafe extern "C" fn wasm_module_validate(
62     store: &mut wasm_store_t,
63     binary: &wasm_byte_vec_t,
64 ) -> bool {
65     Module::validate(store.store.context().engine(), binary.as_slice()).is_ok()
66 }
67 
68 #[no_mangle]
69 pub extern "C" fn wasm_module_as_extern(m: &wasm_module_t) -> &wasm_extern_t {
70     &m.ext
71 }
72 
73 #[no_mangle]
74 pub extern "C" fn wasm_module_exports(module: &wasm_module_t, out: &mut wasm_exporttype_vec_t) {
75     let exports = module
76         .module()
77         .exports()
78         .map(|e| {
79             Some(Box::new(wasm_exporttype_t::new(
80                 e.name().to_owned(),
81                 e.ty(),
82             )))
83         })
84         .collect::<Vec<_>>();
85     out.set_buffer(exports);
86 }
87 
88 #[no_mangle]
89 pub extern "C" fn wasm_module_imports(module: &wasm_module_t, out: &mut wasm_importtype_vec_t) {
90     let imports = module
91         .module()
92         .imports()
93         .map(|i| {
94             Some(Box::new(wasm_importtype_t::new(
95                 i.module().to_owned(),
96                 i.name().map(|s| s.to_owned()),
97                 i.ty(),
98             )))
99         })
100         .collect::<Vec<_>>();
101     out.set_buffer(imports);
102 }
103 
104 #[no_mangle]
105 pub extern "C" fn wasm_module_share(module: &wasm_module_t) -> Box<wasm_shared_module_t> {
106     Box::new(wasm_shared_module_t {
107         module: module.module().clone(),
108     })
109 }
110 
111 #[no_mangle]
112 pub unsafe extern "C" fn wasm_module_obtain(
113     store: &mut wasm_store_t,
114     shared_module: &wasm_shared_module_t,
115 ) -> Option<Box<wasm_module_t>> {
116     let module = shared_module.module.clone();
117     if Engine::same(store.store.context().engine(), module.engine()) {
118         Some(Box::new(wasm_module_t::new(store.store.clone(), module)))
119     } else {
120         None
121     }
122 }
123 
124 #[no_mangle]
125 pub extern "C" fn wasm_module_serialize(module: &wasm_module_t, ret: &mut wasm_byte_vec_t) {
126     if let Ok(buf) = module.module().serialize() {
127         ret.set_buffer(buf);
128     }
129 }
130 
131 #[no_mangle]
132 pub unsafe extern "C" fn wasm_module_deserialize(
133     store: &mut wasm_store_t,
134     binary: &wasm_byte_vec_t,
135 ) -> Option<Box<wasm_module_t>> {
136     match Module::deserialize(store.store.context().engine(), binary.as_slice()) {
137         Ok(module) => Some(Box::new(wasm_module_t::new(store.store.clone(), module))),
138         Err(_) => None,
139     }
140 }
141 
142 #[derive(Clone)]
143 pub struct wasmtime_module_t {
144     pub(crate) module: Module,
145 }
146 
147 #[no_mangle]
148 pub unsafe extern "C" fn wasmtime_module_new(
149     engine: &wasm_engine_t,
150     wasm: *const u8,
151     len: usize,
152     out: &mut *mut wasmtime_module_t,
153 ) -> Option<Box<wasmtime_error_t>> {
154     handle_result(
155         Module::from_binary(&engine.engine, crate::slice_from_raw_parts(wasm, len)),
156         |module| {
157             *out = Box::into_raw(Box::new(wasmtime_module_t { module }));
158         },
159     )
160 }
161 
162 #[no_mangle]
163 pub extern "C" fn wasmtime_module_delete(_module: Box<wasmtime_module_t>) {}
164 
165 #[no_mangle]
166 pub extern "C" fn wasmtime_module_clone(module: &wasmtime_module_t) -> Box<wasmtime_module_t> {
167     Box::new(module.clone())
168 }
169 
170 #[no_mangle]
171 pub unsafe extern "C" fn wasmtime_module_validate(
172     engine: &wasm_engine_t,
173     wasm: *const u8,
174     len: usize,
175 ) -> Option<Box<wasmtime_error_t>> {
176     let binary = crate::slice_from_raw_parts(wasm, len);
177     handle_result(Module::validate(&engine.engine, binary), |()| {})
178 }
179 
180 #[no_mangle]
181 pub extern "C" fn wasmtime_module_type(m: &wasmtime_module_t) -> Box<wasmtime_moduletype_t> {
182     Box::new(wasmtime_moduletype_t::new(m.module.ty()))
183 }
184 
185 #[no_mangle]
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 #[no_mangle]
194 pub unsafe extern "C" fn wasmtime_module_deserialize(
195     engine: &wasm_engine_t,
196     bytes: *const u8,
197     len: usize,
198     out: &mut *mut wasmtime_module_t,
199 ) -> Option<Box<wasmtime_error_t>> {
200     let bytes = crate::slice_from_raw_parts(bytes, len);
201     handle_result(Module::deserialize(&engine.engine, bytes), |module| {
202         *out = Box::into_raw(Box::new(wasmtime_module_t { module }));
203     })
204 }
205