(
cb: wasmtime_func_async_callback_t,
data: CallbackDataPtr,
mut caller: WasmtimeCaller<'a>,
params: &'a [Val],
results: &'a mut [Val],
)
| 94 | pub type wasmtime_func_async_continuation_callback_t = extern "C" fn(*mut c_void) -> bool; |
| 95 | |
| 96 | async fn invoke_c_async_callback<'a>( |
| 97 | cb: wasmtime_func_async_callback_t, |
| 98 | data: CallbackDataPtr, |
| 99 | mut caller: WasmtimeCaller<'a>, |
| 100 | params: &'a [Val], |
| 101 | results: &'a mut [Val], |
| 102 | ) -> Result<()> { |
| 103 | // Convert `params/results` to `wasmtime_val_t`. Use the previous |
| 104 | // storage in `hostcall_val_storage` to help avoid allocations all the |
| 105 | // time. |
| 106 | let mut hostcall_val_storage = mem::take(&mut caller.data_mut().hostcall_val_storage); |
| 107 | debug_assert!(hostcall_val_storage.is_empty()); |
| 108 | hostcall_val_storage.reserve(params.len() + results.len()); |
| 109 | hostcall_val_storage.extend( |
| 110 | params |
| 111 | .iter() |
| 112 | .cloned() |
| 113 | .map(|p| wasmtime_val_t::from_val_unscoped(&mut caller, p)), |
| 114 | ); |
| 115 | hostcall_val_storage.extend((0..results.len()).map(|_| wasmtime_val_t { |
| 116 | kind: WASMTIME_I32, |
| 117 | of: wasmtime_val_union { i32: 0 }, |
| 118 | })); |
| 119 | let (params, out_results) = hostcall_val_storage.split_at_mut(params.len()); |
| 120 | |
| 121 | // Invoke the C function pointer. |
| 122 | // The result will be a continuation which we will wrap in a Future. |
| 123 | let mut caller = wasmtime_caller_t { caller }; |
| 124 | let mut trap = None; |
| 125 | extern "C" fn panic_callback(_: *mut c_void) -> bool { |
| 126 | panic!("callback must be set") |
| 127 | } |
| 128 | let mut continuation = wasmtime_async_continuation_t { |
| 129 | callback: panic_callback, |
| 130 | env: ptr::null_mut(), |
| 131 | finalizer: None, |
| 132 | }; |
| 133 | cb( |
| 134 | data.ptr, |
| 135 | &mut caller, |
| 136 | params.as_ptr(), |
| 137 | params.len(), |
| 138 | out_results.as_mut_ptr(), |
| 139 | out_results.len(), |
| 140 | &mut trap, |
| 141 | &mut continuation, |
| 142 | ); |
| 143 | continuation.await; |
| 144 | |
| 145 | if let Some(trap) = trap { |
| 146 | return Err(trap.error); |
| 147 | } |
| 148 | |
| 149 | // Translate the `wasmtime_val_t` results into the `results` space |
| 150 | for (i, result) in out_results.iter().enumerate() { |
| 151 | unsafe { |
| 152 | results[i] = result.to_val_unscoped(&mut caller.caller); |
| 153 | } |
no test coverage detected