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