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