| 174 | impl<T: Send + 'static> DebugHandler for Handler<T> { |
| 175 | type Data = T; |
| 176 | async fn handle(&self, mut store: StoreContextMut<'_, T>, event: DebugEvent<'_>) { |
| 177 | let mut in_rx = self.0.in_rx.lock().await; |
| 178 | |
| 179 | let result = match event { |
| 180 | DebugEvent::HostcallError(_) => DebugRunResult::HostcallError, |
| 181 | DebugEvent::Exception(exn) => DebugRunResult::Exception(exn), |
| 182 | DebugEvent::Trap(trap) => DebugRunResult::Trap(trap), |
| 183 | DebugEvent::Breakpoint => DebugRunResult::Breakpoint, |
| 184 | DebugEvent::EpochYield => { |
| 185 | // Only pause on epoch yields that were requested via |
| 186 | // interrupt(). Other epoch ticks simply yield to the |
| 187 | // event loop (functionality already implemented in |
| 188 | // core Wasmtime; no need to do that yield here in the |
| 189 | // debug handler). |
| 190 | if !self.0.interrupt_pending.swap(false, Ordering::SeqCst) { |
| 191 | return; |
| 192 | } |
| 193 | DebugRunResult::EpochYield |
| 194 | } |
| 195 | }; |
| 196 | if self.0.out_tx.send(Response::Paused(result)).await.is_err() { |
| 197 | // Outer Debuggee has been dropped: just continue |
| 198 | // executing. |
| 199 | return; |
| 200 | } |
| 201 | |
| 202 | while let Some(cmd) = in_rx.recv().await { |
| 203 | match cmd { |
| 204 | Command::Query(closure) => { |
| 205 | let result = closure(store.as_context_mut()); |
| 206 | if self |
| 207 | .0 |
| 208 | .out_tx |
| 209 | .send(Response::QueryResponse(result)) |
| 210 | .await |
| 211 | .is_err() |
| 212 | { |
| 213 | // Outer Debuggee has been dropped: just |
| 214 | // continue executing. |
| 215 | return; |
| 216 | } |
| 217 | } |
| 218 | Command::Continue => { |
| 219 | break; |
| 220 | } |
| 221 | } |
| 222 | } |
| 223 | } |
| 224 | } |
| 225 | |
| 226 | impl<T: Send + 'static> Debuggee<T> { |