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