1 use crate::host_ref::HostRef; 2 use crate::{ 3 handle_result, wasm_byte_vec_t, wasm_exporttype_t, wasm_exporttype_vec_t, wasm_importtype_t, 4 wasm_importtype_vec_t, wasm_store_t, wasmtime_error_t, 5 }; 6 use std::ptr; 7 use wasmtime::{Engine, Module}; 8 9 #[repr(C)] 10 #[derive(Clone)] 11 pub struct wasm_module_t { 12 pub(crate) module: HostRef<Module>, 13 pub(crate) imports: Vec<wasm_importtype_t>, 14 pub(crate) exports: Vec<wasm_exporttype_t>, 15 } 16 17 wasmtime_c_api_macros::declare_ref!(wasm_module_t); 18 19 impl wasm_module_t { 20 fn externref(&self) -> wasmtime::ExternRef { 21 self.module.clone().into() 22 } 23 } 24 25 #[repr(C)] 26 #[derive(Clone)] 27 pub struct wasm_shared_module_t { 28 module: Module, 29 } 30 31 wasmtime_c_api_macros::declare_own!(wasm_shared_module_t); 32 33 #[no_mangle] 34 pub extern "C" fn wasm_module_new( 35 store: &wasm_store_t, 36 binary: &wasm_byte_vec_t, 37 ) -> Option<Box<wasm_module_t>> { 38 let mut ret = ptr::null_mut(); 39 match wasmtime_module_new(store, binary, &mut ret) { 40 Some(_err) => None, 41 None => { 42 assert!(!ret.is_null()); 43 Some(unsafe { Box::from_raw(ret) }) 44 } 45 } 46 } 47 48 #[no_mangle] 49 pub extern "C" fn wasmtime_module_new( 50 store: &wasm_store_t, 51 binary: &wasm_byte_vec_t, 52 ret: &mut *mut wasm_module_t, 53 ) -> Option<Box<wasmtime_error_t>> { 54 let binary = binary.as_slice(); 55 let store = &store.store; 56 handle_result(Module::from_binary(store.engine(), binary), |module| { 57 let imports = module 58 .imports() 59 .map(|i| wasm_importtype_t::new(i.module().to_owned(), i.name().to_owned(), i.ty())) 60 .collect::<Vec<_>>(); 61 let exports = module 62 .exports() 63 .map(|e| wasm_exporttype_t::new(e.name().to_owned(), e.ty())) 64 .collect::<Vec<_>>(); 65 let module = Box::new(wasm_module_t { 66 module: HostRef::new(store, module), 67 imports, 68 exports, 69 }); 70 *ret = Box::into_raw(module); 71 }) 72 } 73 74 #[no_mangle] 75 pub extern "C" fn wasm_module_validate(store: &wasm_store_t, binary: &wasm_byte_vec_t) -> bool { 76 wasmtime_module_validate(store, binary).is_none() 77 } 78 79 #[no_mangle] 80 pub extern "C" fn wasmtime_module_validate( 81 store: &wasm_store_t, 82 binary: &wasm_byte_vec_t, 83 ) -> Option<Box<wasmtime_error_t>> { 84 let binary = binary.as_slice(); 85 handle_result(Module::validate(store.store.engine(), binary), |()| {}) 86 } 87 88 #[no_mangle] 89 pub extern "C" fn wasm_module_exports(module: &wasm_module_t, out: &mut wasm_exporttype_vec_t) { 90 let buffer = module 91 .exports 92 .iter() 93 .map(|et| Some(Box::new(et.clone()))) 94 .collect::<Vec<_>>(); 95 out.set_buffer(buffer); 96 } 97 98 #[no_mangle] 99 pub extern "C" fn wasm_module_imports(module: &wasm_module_t, out: &mut wasm_importtype_vec_t) { 100 let buffer = module 101 .imports 102 .iter() 103 .map(|it| Some(Box::new(it.clone()))) 104 .collect::<Vec<_>>(); 105 out.set_buffer(buffer); 106 } 107 108 #[no_mangle] 109 pub extern "C" fn wasm_module_share(module: &wasm_module_t) -> Box<wasm_shared_module_t> { 110 Box::new(wasm_shared_module_t { 111 module: module.module.borrow().clone(), 112 }) 113 } 114 115 #[no_mangle] 116 pub extern "C" fn wasm_module_obtain( 117 store: &wasm_store_t, 118 shared_module: &wasm_shared_module_t, 119 ) -> Option<Box<wasm_module_t>> { 120 let module = shared_module.module.clone(); 121 if !Engine::same(store.store.engine(), module.engine()) { 122 return None; 123 } 124 let imports = module 125 .imports() 126 .map(|i| wasm_importtype_t::new(i.module().to_owned(), i.name().to_owned(), i.ty())) 127 .collect::<Vec<_>>(); 128 let exports = module 129 .exports() 130 .map(|e| wasm_exporttype_t::new(e.name().to_owned(), e.ty())) 131 .collect::<Vec<_>>(); 132 Some(Box::new(wasm_module_t { 133 module: HostRef::new(&store.store, module), 134 imports, 135 exports, 136 })) 137 } 138