1 use crate::{ 2 WasmStoreRef, WasmtimeStoreContextMut, WasmtimeStoreData, wasm_extern_t, wasm_extern_vec_t, 3 wasm_module_t, wasm_store_t, wasm_trap_t, wasmtime_error_t, wasmtime_extern_t, 4 wasmtime_module_t, 5 }; 6 use std::mem::MaybeUninit; 7 use wasmtime::{Instance, InstancePre, Trap}; 8 9 #[derive(Clone)] 10 pub struct wasm_instance_t { 11 store: WasmStoreRef, 12 instance: Instance, 13 } 14 15 wasmtime_c_api_macros::declare_ref!(wasm_instance_t); 16 17 impl wasm_instance_t { 18 pub(crate) fn new(store: WasmStoreRef, instance: Instance) -> wasm_instance_t { 19 wasm_instance_t { store, instance } 20 } 21 } 22 23 #[unsafe(no_mangle)] 24 pub unsafe extern "C" fn wasm_instance_new( 25 store: &mut wasm_store_t, 26 wasm_module: &wasm_module_t, 27 imports: *const wasm_extern_vec_t, 28 result: Option<&mut *mut wasm_trap_t>, 29 ) -> Option<Box<wasm_instance_t>> { 30 let imports = (*imports) 31 .as_slice() 32 .iter() 33 .filter_map(|import| match import { 34 Some(i) => Some(i.which.clone()), 35 None => None, 36 }) 37 .collect::<Vec<_>>(); 38 match Instance::new(store.store.context_mut(), &wasm_module.module, &imports) { 39 Ok(instance) => Some(Box::new(wasm_instance_t::new( 40 store.store.clone(), 41 instance, 42 ))), 43 Err(e) => { 44 if let Some(ptr) = result { 45 *ptr = Box::into_raw(Box::new(wasm_trap_t::new(e))); 46 } 47 None 48 } 49 } 50 } 51 52 #[unsafe(no_mangle)] 53 pub unsafe extern "C" fn wasm_instance_exports( 54 instance: &mut wasm_instance_t, 55 out: &mut wasm_extern_vec_t, 56 ) { 57 let store = instance.store.clone(); 58 out.set_buffer( 59 instance 60 .instance 61 .exports(instance.store.context_mut()) 62 .map(|e| { 63 Some(Box::new(wasm_extern_t { 64 which: e.into_extern(), 65 store: store.clone(), 66 })) 67 }) 68 .collect(), 69 ); 70 } 71 72 #[unsafe(no_mangle)] 73 pub unsafe extern "C" fn wasmtime_instance_new( 74 store: WasmtimeStoreContextMut<'_>, 75 module: &wasmtime_module_t, 76 imports: *const wasmtime_extern_t, 77 nimports: usize, 78 instance: &mut Instance, 79 trap_ptr: &mut *mut wasm_trap_t, 80 ) -> Option<Box<wasmtime_error_t>> { 81 let imports = crate::slice_from_raw_parts(imports, nimports) 82 .iter() 83 .map(|i| i.to_extern()) 84 .collect::<Vec<_>>(); 85 handle_instantiate( 86 Instance::new(store, &module.module, &imports), 87 instance, 88 trap_ptr, 89 ) 90 } 91 92 pub(crate) fn handle_instantiate( 93 instance: wasmtime::Result<Instance>, 94 instance_ptr: &mut Instance, 95 trap_ptr: &mut *mut wasm_trap_t, 96 ) -> Option<Box<wasmtime_error_t>> { 97 match instance { 98 Ok(i) => { 99 *instance_ptr = i; 100 None 101 } 102 Err(e) => { 103 if e.is::<Trap>() { 104 *trap_ptr = Box::into_raw(Box::new(wasm_trap_t::new(e))); 105 None 106 } else { 107 Some(Box::new(e.into())) 108 } 109 } 110 } 111 } 112 113 #[unsafe(no_mangle)] 114 pub unsafe extern "C" fn wasmtime_instance_export_get( 115 store: WasmtimeStoreContextMut<'_>, 116 instance: &Instance, 117 name: *const u8, 118 name_len: usize, 119 item: &mut MaybeUninit<wasmtime_extern_t>, 120 ) -> bool { 121 let name = crate::slice_from_raw_parts(name, name_len); 122 let name = match std::str::from_utf8(name) { 123 Ok(name) => name, 124 Err(_) => return false, 125 }; 126 match instance.get_export(store, name) { 127 Some(e) => { 128 crate::initialize(item, e.into()); 129 true 130 } 131 None => false, 132 } 133 } 134 135 #[unsafe(no_mangle)] 136 pub unsafe extern "C" fn wasmtime_instance_export_nth( 137 store: WasmtimeStoreContextMut<'_>, 138 instance: &Instance, 139 index: usize, 140 name_ptr: &mut *const u8, 141 name_len: &mut usize, 142 item: &mut MaybeUninit<wasmtime_extern_t>, 143 ) -> bool { 144 match instance.exports(store).nth(index) { 145 Some(e) => { 146 *name_ptr = e.name().as_ptr(); 147 *name_len = e.name().len(); 148 crate::initialize(item, e.into_extern().into()); 149 true 150 } 151 None => false, 152 } 153 } 154 155 #[repr(transparent)] 156 pub struct wasmtime_instance_pre_t { 157 pub(crate) underlying: InstancePre<WasmtimeStoreData>, 158 } 159 160 #[unsafe(no_mangle)] 161 pub unsafe extern "C" fn wasmtime_instance_pre_delete(_instance_pre: Box<wasmtime_instance_pre_t>) { 162 } 163 164 #[unsafe(no_mangle)] 165 pub unsafe extern "C" fn wasmtime_instance_pre_instantiate( 166 instance_pre: &wasmtime_instance_pre_t, 167 store: WasmtimeStoreContextMut<'_>, 168 instance_ptr: &mut Instance, 169 trap_ptr: &mut *mut wasm_trap_t, 170 ) -> Option<Box<wasmtime_error_t>> { 171 let result = instance_pre.underlying.instantiate(store); 172 handle_instantiate(result, instance_ptr, trap_ptr) 173 } 174 175 #[unsafe(no_mangle)] 176 pub unsafe extern "C" fn wasmtime_instance_pre_module( 177 instance_pre: &wasmtime_instance_pre_t, 178 ) -> Box<wasmtime_module_t> { 179 let module = instance_pre.underlying.module().clone(); 180 Box::new(wasmtime_module_t { module }) 181 } 182