(
func: &mut wasm_func_t,
args: *const wasm_val_vec_t,
results: *mut wasm_val_vec_t,
)
| 134 | |
| 135 | #[unsafe(no_mangle)] |
| 136 | pub unsafe extern "C" fn wasm_func_call( |
| 137 | func: &mut wasm_func_t, |
| 138 | args: *const wasm_val_vec_t, |
| 139 | results: *mut wasm_val_vec_t, |
| 140 | ) -> *mut wasm_trap_t { |
| 141 | let f = func.func(); |
| 142 | let results = (*results).as_uninit_slice(); |
| 143 | let args = (*args).as_slice(); |
| 144 | let mut dst = Vec::new(); |
| 145 | let (wt_params, wt_results) = |
| 146 | translate_args(&mut dst, args.iter().map(|i| i.val()), results.len()); |
| 147 | |
| 148 | // We're calling arbitrary code here most of the time, and we in general |
| 149 | // want to try to insulate callers against bugs in wasmtime/wasi/etc if we |
| 150 | // can. As a result we catch panics here and transform them to traps to |
| 151 | // allow the caller to have any insulation possible against Rust panics. |
| 152 | let result = panic::catch_unwind(AssertUnwindSafe(|| { |
| 153 | f.call(func.ext.store.context_mut(), wt_params, wt_results) |
| 154 | })); |
| 155 | match result { |
| 156 | Ok(Ok(())) => { |
| 157 | for (slot, val) in results.iter_mut().zip(wt_results.iter().cloned()) { |
| 158 | crate::initialize(slot, wasm_val_t::from_val(val)); |
| 159 | } |
| 160 | ptr::null_mut() |
| 161 | } |
| 162 | Ok(Err(err)) => Box::into_raw(Box::new(wasm_trap_t::new(err))), |
| 163 | Err(panic) => { |
| 164 | let err = error_from_panic(panic); |
| 165 | let trap = Box::new(wasm_trap_t::new(err)); |
| 166 | Box::into_raw(trap) |
| 167 | } |
| 168 | } |
| 169 | } |
| 170 | |
| 171 | fn error_from_panic(panic: Box<dyn Any + Send>) -> Error { |
| 172 | if let Some(msg) = panic.downcast_ref::<String>() { |
no test coverage detected