Skip to main content

wasmtime_internal_debugger/host/
api.rs

1//! Implementations of the host API traits.
2
3use crate::host::opaque::OpaqueDebugger;
4use crate::host::wit;
5use crate::{DebugRunResult, host::bindings::wasm_type_to_val_type};
6use std::pin::Pin;
7use std::sync::Arc;
8use std::sync::atomic::{AtomicBool, Ordering};
9use wasmtime::{
10    Engine, ExnRef, FrameHandle, Func, Global, Instance, Memory, Module, OwnedRooted, Result,
11    Table, Tag, Val, component::Resource, component::ResourceTable,
12};
13use wasmtime_wasi::p2::{DynPollable, Pollable, subscribe};
14
15/// Representation of one debuggee: a store with debugged code inside,
16/// under the control of the debugger.
17pub struct Debuggee {
18    /// The type-erased debugger implementation. This field is `Some`
19    /// when execution is paused, and `None`, with ownership of the
20    /// debugger (hence debuggee's store) passed to the future when
21    /// executing.
22    pub(crate) inner: Option<Box<dyn OpaqueDebugger + Send + 'static>>,
23
24    /// A separate handle to the Engine, allowing incrementing the
25    /// epoch (hence interrupting a running debuggee) without taking
26    /// the mutex.
27    pub(crate) engine: Engine,
28
29    /// Shared flag: set to `true` by `interrupt()` so the inner
30    /// handler treats the next epoch yield as an `Interrupted` event.
31    pub(crate) interrupt_pending: Arc<AtomicBool>,
32}
33
34impl Debuggee {
35    /// Finish execution of the debuggee before returning.
36    pub async fn finish(&mut self) -> Result<()> {
37        if let Some(inner) = self.inner.as_mut() {
38            inner.finish().await?;
39        }
40        Ok(())
41    }
42}
43
44impl WasmValue {
45    pub(crate) fn new(store: impl wasmtime::AsContextMut, val: Val) -> Result<WasmValue> {
46        Ok(match val {
47            Val::ExnRef(Some(rooted)) => {
48                WasmValue::Exn(Some(rooted.to_owned_rooted(store).unwrap()))
49            }
50            Val::ExnRef(None) => WasmValue::Exn(None),
51            Val::FuncRef(Some(f)) => WasmValue::Func(Some(f)),
52            Val::FuncRef(None) => WasmValue::Func(None),
53            Val::ExternRef(_) | Val::AnyRef(_) | Val::ContRef(_) => {
54                return Err(wit::Error::UnsupportedType.into());
55            }
56            Val::I32(_) | Val::I64(_) | Val::F32(_) | Val::F64(_) | Val::V128(_) => {
57                WasmValue::Primitive(val)
58            }
59        })
60    }
61
62    pub(crate) fn into_val(self, store: impl wasmtime::AsContextMut) -> Val {
63        match self {
64            WasmValue::Primitive(v) => v,
65            WasmValue::Exn(Some(owned)) => Val::ExnRef(Some(owned.to_rooted(store))),
66            WasmValue::Exn(None) => Val::ExnRef(None),
67            WasmValue::Func(Some(f)) => Val::FuncRef(Some(f)),
68            WasmValue::Func(None) => Val::FuncRef(None),
69        }
70    }
71}
72
73/// Representation of an async debug event that the debugger is
74/// waiting on.
75///
76/// Cancel-safety: the non-cancel-safe OpaqueDebugger async methods
77/// are called inside an `async move` block that owns the debugger.
78/// `ready()` merely polls this stored future, which is always safe to
79/// re-poll after cancelation. The debugger is returned in the `Done`
80/// state and extracted by `finish()`.
81pub struct EventFuture {
82    state: EventFutureState,
83}
84
85enum EventFutureState {
86    /// The future is running; owns the debugger.
87    Running(
88        Pin<
89            Box<
90                dyn Future<
91                        Output = (
92                            Box<dyn OpaqueDebugger + Send + 'static>,
93                            Result<DebugRunResult>,
94                        ),
95                    > + Send,
96            >,
97        >,
98    ),
99    /// The future has completed; debugger is ready to be returned.
100    Done {
101        inner: Box<dyn OpaqueDebugger + Send + 'static>,
102        result: Option<Result<DebugRunResult>>,
103    },
104}
105
106impl EventFuture {
107    fn new_single_step(
108        mut inner: Box<dyn OpaqueDebugger + Send + 'static>,
109        resumption: wit::ResumptionValue,
110    ) -> Self {
111        EventFuture {
112            state: EventFutureState::Running(Box::pin(async move {
113                if let Err(e) = inner.handle_resumption(&resumption).await {
114                    return (inner, Err(e));
115                }
116                let result = inner.single_step().await;
117                (inner, result)
118            })),
119        }
120    }
121
122    fn new_continue(
123        mut inner: Box<dyn OpaqueDebugger + Send + 'static>,
124        resumption: wit::ResumptionValue,
125    ) -> Self {
126        EventFuture {
127            state: EventFutureState::Running(Box::pin(async move {
128                if let Err(e) = inner.handle_resumption(&resumption).await {
129                    return (inner, Err(e));
130                }
131                let result = inner.continue_().await;
132                (inner, result)
133            })),
134        }
135    }
136}
137
138#[async_trait::async_trait]
139impl wasmtime_wasi_io::poll::Pollable for EventFuture {
140    async fn ready(&mut self) {
141        match &mut self.state {
142            EventFutureState::Running(future) => {
143                let (inner, result) = future.await;
144                self.state = EventFutureState::Done {
145                    inner,
146                    result: Some(result),
147                };
148            }
149            EventFutureState::Done { .. } => {}
150        }
151    }
152}
153
154/// Representation of a frame within a debuggee.
155#[derive(Clone)]
156pub struct Frame(FrameHandle);
157
158/// Representation of a Wasm exception object.
159#[derive(Clone)]
160pub struct WasmException(OwnedRooted<ExnRef>);
161
162/// Representation of a Wasm value.
163///
164/// This is distinct from `wasmtime::Val` because we need the Owned
165/// variants of GC references here.
166#[derive(Clone)]
167pub enum WasmValue {
168    /// A primitive (non-GC) value.
169    Primitive(Val),
170    /// An exception object.
171    Exn(Option<OwnedRooted<ExnRef>>),
172    /// A funcref.
173    Func(Option<Func>),
174    // TODO: GC structs and arrays.
175}
176
177/// Get the `OpaqueDebugger` or raise an error.
178fn debugger<'a>(
179    table: &'a mut ResourceTable,
180    debuggee: &Resource<Debuggee>,
181) -> Result<&'a mut dyn OpaqueDebugger> {
182    let d = table.get_mut(&debuggee)?.inner.as_mut().ok_or_else(|| {
183        wasmtime::error::format_err!("Attempt to use debuggee API while a future is pending")
184    })?;
185    Ok(&mut **d)
186}
187
188impl wit::HostDebuggee for ResourceTable {
189    async fn all_modules(&mut self, debuggee: Resource<Debuggee>) -> Result<Vec<Resource<Module>>> {
190        let d = debugger(self, &debuggee)?;
191        let modules = d.all_modules().await?;
192        let mut resources = vec![];
193        for module in modules {
194            resources.push(self.push_child(module, &debuggee)?);
195        }
196        Ok(resources)
197    }
198
199    async fn all_instances(
200        &mut self,
201        debuggee: Resource<Debuggee>,
202    ) -> Result<Vec<Resource<Instance>>> {
203        let d = debugger(self, &debuggee)?;
204        let instances = d.all_instances().await?;
205        let mut resources = vec![];
206        for instance in instances {
207            resources.push(self.push_child(instance, &debuggee)?);
208        }
209        Ok(resources)
210    }
211
212    async fn interrupt(&mut self, debuggee: Resource<Debuggee>) -> Result<()> {
213        let d = self.get_mut(&debuggee)?;
214        d.interrupt_pending.store(true, Ordering::SeqCst);
215        d.engine.increment_epoch();
216        Ok(())
217    }
218
219    async fn single_step(
220        &mut self,
221        debuggee: Resource<Debuggee>,
222        resumption: wit::ResumptionValue,
223    ) -> Result<Resource<EventFuture>> {
224        let d = self.get_mut(&debuggee).unwrap().inner.take().unwrap();
225        Ok(self.push_child(EventFuture::new_single_step(d, resumption), &debuggee)?)
226    }
227
228    async fn continue_(
229        &mut self,
230        debuggee: Resource<Debuggee>,
231        resumption: wit::ResumptionValue,
232    ) -> Result<Resource<EventFuture>> {
233        let d = self.get_mut(&debuggee).unwrap().inner.take().unwrap();
234        Ok(self.push_child(EventFuture::new_continue(d, resumption), &debuggee)?)
235    }
236
237    async fn exit_frames(&mut self, debuggee: Resource<Debuggee>) -> Result<Vec<Resource<Frame>>> {
238        let d = debugger(self, &debuggee)?;
239        let frames = d.exit_frames().await?;
240        let mut result = vec![];
241        for frame in frames {
242            result.push(self.push_child(Frame(frame), &debuggee)?);
243        }
244        Ok(result)
245    }
246
247    async fn drop(&mut self, debuggee: Resource<Debuggee>) -> Result<()> {
248        self.delete(debuggee)?;
249        Ok(())
250    }
251}
252
253fn result_to_event(table: &mut ResourceTable, value: DebugRunResult) -> Result<wit::Event> {
254    Ok(match value {
255        DebugRunResult::Finished => wit::Event::Complete,
256        DebugRunResult::HostcallError => wit::Event::Trap,
257        DebugRunResult::Trap(_t) => wit::Event::Trap,
258        DebugRunResult::Breakpoint => wit::Event::Breakpoint,
259        DebugRunResult::EpochYield => wit::Event::Interrupted,
260        DebugRunResult::Exception(e) => {
261            let e = table.push(WasmException(e))?;
262            wit::Event::Exception(e)
263        }
264    })
265}
266
267impl wit::HostEventFuture for ResourceTable {
268    async fn finish(
269        &mut self,
270        self_: Resource<EventFuture>,
271        debuggee: Resource<Debuggee>,
272    ) -> Result<wit::Event> {
273        let mut f = self.delete(self_)?;
274        f.ready().await;
275        match f.state {
276            EventFutureState::Running(..) => {
277                unreachable!("ready() cannot return until setting Done state")
278            }
279            EventFutureState::Done { inner, result } => {
280                self.get_mut(&debuggee)?.inner = Some(inner);
281                match result.unwrap() {
282                    Ok(result) => Ok(result_to_event(self, result)?),
283                    Err(e) => Err(e),
284                }
285            }
286        }
287    }
288
289    async fn drop(&mut self, rep: Resource<EventFuture>) -> Result<()> {
290        self.delete(rep)?;
291        Ok(())
292    }
293
294    async fn subscribe(&mut self, self_: Resource<EventFuture>) -> Result<Resource<DynPollable>> {
295        subscribe(self, self_)
296    }
297}
298
299impl wit::HostInstance for ResourceTable {
300    async fn get_module(
301        &mut self,
302        self_: Resource<Instance>,
303        d: Resource<Debuggee>,
304    ) -> Result<Resource<Module>> {
305        let i = *self.get(&self_)?;
306        let d = debugger(self, &d)?;
307        let module = d.get_instance_module(i).await?;
308        let module = self.push(module)?;
309        Ok(module)
310    }
311
312    async fn get_memory(
313        &mut self,
314        self_: Resource<Instance>,
315        d: Resource<Debuggee>,
316        memory_index: u32,
317    ) -> Result<Resource<Memory>> {
318        let instance = *self.get(&self_)?;
319        let d = debugger(self, &d)?;
320        let memory = d
321            .instance_get_memory(instance, memory_index)
322            .await?
323            .ok_or(wit::Error::InvalidEntity)?;
324        Ok(self.push(memory)?)
325    }
326
327    async fn get_global(
328        &mut self,
329        self_: Resource<Instance>,
330        d: Resource<Debuggee>,
331        global_index: u32,
332    ) -> Result<Resource<Global>> {
333        let instance = *self.get(&self_)?;
334        let d = debugger(self, &d)?;
335        let global = d
336            .instance_get_global(instance, global_index)
337            .await?
338            .ok_or(wit::Error::InvalidEntity)?;
339        Ok(self.push(global)?)
340    }
341
342    async fn get_table(
343        &mut self,
344        self_: Resource<Instance>,
345        d: Resource<Debuggee>,
346        table_index: u32,
347    ) -> Result<Resource<Table>> {
348        let instance = *self.get(&self_)?;
349        let d = debugger(self, &d)?;
350        let table = d
351            .instance_get_table(instance, table_index)
352            .await?
353            .ok_or(wit::Error::InvalidEntity)?;
354        Ok(self.push(table)?)
355    }
356
357    async fn get_func(
358        &mut self,
359        self_: Resource<Instance>,
360        d: Resource<Debuggee>,
361        func_index: u32,
362    ) -> Result<Resource<Func>> {
363        let instance = *self.get(&self_)?;
364        let d = debugger(self, &d)?;
365        let func = d
366            .instance_get_func(instance, func_index)
367            .await?
368            .ok_or(wit::Error::InvalidEntity)?;
369        Ok(self.push(func)?)
370    }
371
372    async fn get_tag(
373        &mut self,
374        self_: Resource<Instance>,
375        d: Resource<Debuggee>,
376        tag_index: u32,
377    ) -> Result<Resource<Tag>> {
378        let instance = *self.get(&self_)?;
379        let d = debugger(self, &d)?;
380        let tag = d
381            .instance_get_tag(instance, tag_index)
382            .await?
383            .ok_or(wit::Error::InvalidEntity)?;
384        Ok(self.push(tag)?)
385    }
386
387    async fn clone(&mut self, self_: Resource<Instance>) -> Result<Resource<Instance>> {
388        let instance = *self.get(&self_)?;
389        Ok(self.push(instance)?)
390    }
391
392    async fn unique_id(&mut self, self_: Resource<Instance>) -> Result<u64> {
393        let instance = self.get(&self_)?;
394        Ok(u64::from(instance.debug_index_in_store()))
395    }
396
397    async fn drop(&mut self, rep: Resource<Instance>) -> Result<()> {
398        self.delete(rep)?;
399        Ok(())
400    }
401}
402
403impl wit::HostModule for ResourceTable {
404    async fn add_breakpoint(
405        &mut self,
406        self_: Resource<Module>,
407        d: Resource<Debuggee>,
408        pc: u32,
409    ) -> Result<()> {
410        let module = self.get(&self_)?.clone();
411        let d = debugger(self, &d)?;
412        d.module_add_breakpoint(module, pc).await
413    }
414
415    async fn remove_breakpoint(
416        &mut self,
417        self_: Resource<Module>,
418        d: Resource<Debuggee>,
419        pc: u32,
420    ) -> Result<()> {
421        let module = self.get(&self_)?.clone();
422        let d = debugger(self, &d)?;
423        d.module_remove_breakpoint(module, pc).await
424    }
425
426    async fn bytecode(&mut self, self_: Resource<Module>) -> Result<Option<Vec<u8>>> {
427        let module = self.get(&self_)?;
428        Ok(module.debug_bytecode().map(|b| b.to_vec()))
429    }
430
431    async fn clone(&mut self, self_: Resource<Module>) -> Result<Resource<Module>> {
432        let module = self.get(&self_)?.clone();
433        Ok(self.push(module)?)
434    }
435
436    async fn unique_id(&mut self, self_: Resource<Module>) -> Result<u64> {
437        let module = self.get(&self_)?;
438        Ok(module.debug_index_in_engine())
439    }
440
441    async fn drop(&mut self, rep: Resource<Module>) -> Result<()> {
442        self.delete(rep)?;
443        Ok(())
444    }
445}
446
447impl wit::HostMemory for ResourceTable {
448    async fn size_bytes(&mut self, self_: Resource<Memory>, d: Resource<Debuggee>) -> Result<u64> {
449        let memory = *self.get(&self_)?;
450        let d = debugger(self, &d)?;
451        d.memory_size_bytes(memory).await
452    }
453
454    async fn page_size_bytes(
455        &mut self,
456        self_: Resource<Memory>,
457        d: Resource<Debuggee>,
458    ) -> Result<u64> {
459        let memory = *self.get(&self_)?;
460        let d = debugger(self, &d)?;
461        d.memory_page_size(memory).await
462    }
463
464    async fn grow_to_bytes(
465        &mut self,
466        self_: Resource<Memory>,
467        d: Resource<Debuggee>,
468        delta_bytes: u64,
469    ) -> Result<u64> {
470        let memory = *self.get(&self_)?;
471        let d = debugger(self, &d)?;
472        d.memory_grow(memory, delta_bytes).await
473    }
474
475    async fn get_bytes(
476        &mut self,
477        self_: Resource<Memory>,
478        d: Resource<Debuggee>,
479        addr: u64,
480        len: u64,
481    ) -> Result<Vec<u8>> {
482        let memory = *self.get(&self_)?;
483        let d = debugger(self, &d)?;
484        Ok(d.memory_read_bytes(memory, addr, len)
485            .await?
486            .ok_or(wit::Error::OutOfBounds)?)
487    }
488
489    async fn set_bytes(
490        &mut self,
491        self_: Resource<Memory>,
492        d: Resource<Debuggee>,
493        addr: u64,
494        bytes: Vec<u8>,
495    ) -> Result<()> {
496        let memory = *self.get(&self_)?;
497        let d = debugger(self, &d)?;
498        d.memory_write_bytes(memory, addr, bytes)
499            .await?
500            .ok_or(wit::Error::OutOfBounds)?;
501        Ok(())
502    }
503
504    async fn get_u8(
505        &mut self,
506        self_: Resource<Memory>,
507        d: Resource<Debuggee>,
508        addr: u64,
509    ) -> Result<u8> {
510        let memory = *self.get(&self_)?;
511        let d = debugger(self, &d)?;
512        Ok(d.memory_read_u8(memory, addr)
513            .await?
514            .ok_or(wit::Error::OutOfBounds)?)
515    }
516
517    async fn get_u16(
518        &mut self,
519        self_: Resource<Memory>,
520        d: Resource<Debuggee>,
521        addr: u64,
522    ) -> Result<u16> {
523        let memory = *self.get(&self_)?;
524        let d = debugger(self, &d)?;
525        Ok(d.memory_read_u16(memory, addr)
526            .await?
527            .ok_or(wit::Error::OutOfBounds)?)
528    }
529
530    async fn get_u32(
531        &mut self,
532        self_: Resource<Memory>,
533        d: Resource<Debuggee>,
534        addr: u64,
535    ) -> Result<u32> {
536        let memory = *self.get(&self_)?;
537        let d = debugger(self, &d)?;
538        Ok(d.memory_read_u32(memory, addr)
539            .await?
540            .ok_or(wit::Error::OutOfBounds)?)
541    }
542
543    async fn get_u64(
544        &mut self,
545        self_: Resource<Memory>,
546        d: Resource<Debuggee>,
547        addr: u64,
548    ) -> Result<u64> {
549        let memory = *self.get(&self_)?;
550        let d = debugger(self, &d)?;
551        Ok(d.memory_read_u64(memory, addr)
552            .await?
553            .ok_or(wit::Error::OutOfBounds)?)
554    }
555
556    async fn set_u8(
557        &mut self,
558        self_: Resource<Memory>,
559        d: Resource<Debuggee>,
560        addr: u64,
561        value: u8,
562    ) -> Result<()> {
563        let memory = *self.get(&self_)?;
564        let d = debugger(self, &d)?;
565        d.memory_write_u8(memory, addr, value)
566            .await?
567            .ok_or(wit::Error::OutOfBounds)?;
568        Ok(())
569    }
570
571    async fn set_u16(
572        &mut self,
573        self_: Resource<Memory>,
574        d: Resource<Debuggee>,
575        addr: u64,
576        value: u16,
577    ) -> Result<()> {
578        let memory = *self.get(&self_)?;
579        let d = debugger(self, &d)?;
580        d.memory_write_u16(memory, addr, value)
581            .await?
582            .ok_or(wit::Error::OutOfBounds)?;
583        Ok(())
584    }
585
586    async fn set_u32(
587        &mut self,
588        self_: Resource<Memory>,
589        d: Resource<Debuggee>,
590        addr: u64,
591        value: u32,
592    ) -> Result<()> {
593        let memory = *self.get(&self_)?;
594        let d = debugger(self, &d)?;
595        d.memory_write_u32(memory, addr, value)
596            .await?
597            .ok_or(wit::Error::OutOfBounds)?;
598        Ok(())
599    }
600
601    async fn set_u64(
602        &mut self,
603        self_: Resource<Memory>,
604        d: Resource<Debuggee>,
605        addr: u64,
606        value: u64,
607    ) -> Result<()> {
608        let memory = *self.get(&self_)?;
609        let d = debugger(self, &d)?;
610        d.memory_write_u64(memory, addr, value)
611            .await?
612            .ok_or(wit::Error::OutOfBounds)?;
613        Ok(())
614    }
615
616    async fn clone(&mut self, self_: Resource<Memory>) -> Result<Resource<Memory>> {
617        let memory = *self.get(&self_)?;
618        Ok(self.push(memory)?)
619    }
620
621    async fn unique_id(&mut self, self_: Resource<Memory>) -> Result<u64> {
622        Ok(self.get(&self_)?.debug_index_in_store())
623    }
624
625    async fn drop(&mut self, rep: Resource<Memory>) -> Result<()> {
626        self.delete(rep)?;
627        Ok(())
628    }
629}
630
631impl wit::HostGlobal for ResourceTable {
632    async fn get(
633        &mut self,
634        self_: Resource<Global>,
635        d: Resource<Debuggee>,
636    ) -> Result<Resource<WasmValue>> {
637        // N.B.: we use UFCS here because `HostGlobal::get` conflicts
638        // with `ResourceTable::get` and we're implementing the WIT
639        // trait directly on the `ResourceTable`.
640        let global = *ResourceTable::get(self, &self_)?;
641        let d = debugger(self, &d)?;
642        let value = d.global_get(global).await?;
643        Ok(self.push(value)?)
644    }
645
646    async fn set(
647        &mut self,
648        self_: Resource<Global>,
649        d: Resource<Debuggee>,
650        val: Resource<WasmValue>,
651    ) -> Result<()> {
652        let global = *ResourceTable::get(self, &self_)?;
653        let value = ResourceTable::get(self, &val)?.clone();
654        let d = debugger(self, &d)?;
655        d.global_set(global, value).await
656    }
657
658    async fn clone(&mut self, self_: Resource<Global>) -> Result<Resource<Global>> {
659        let global = *ResourceTable::get(self, &self_)?;
660        Ok(self.push(global)?)
661    }
662
663    async fn unique_id(&mut self, self_: Resource<Global>) -> Result<u64> {
664        let global = *ResourceTable::get(self, &self_)?;
665        Ok(global.debug_index_in_store())
666    }
667
668    async fn drop(&mut self, rep: Resource<Global>) -> Result<()> {
669        self.delete(rep)?;
670        Ok(())
671    }
672}
673
674impl wit::HostTable for ResourceTable {
675    async fn len(&mut self, self_: Resource<Table>, d: Resource<Debuggee>) -> Result<u64> {
676        let table = *self.get(&self_)?;
677        let d = debugger(self, &d)?;
678        d.table_len(table).await
679    }
680
681    async fn get_element(
682        &mut self,
683        self_: Resource<Table>,
684        d: Resource<Debuggee>,
685        index: u64,
686    ) -> Result<Resource<WasmValue>> {
687        let table = *self.get(&self_)?;
688        let d = debugger(self, &d)?;
689        let value = d.table_get_element(table, index).await?;
690        Ok(self.push(value)?)
691    }
692
693    async fn set_element(
694        &mut self,
695        self_: Resource<Table>,
696        d: Resource<Debuggee>,
697        index: u64,
698        val: Resource<WasmValue>,
699    ) -> Result<()> {
700        let table = *self.get(&self_)?;
701        let value = self.get(&val)?.clone();
702        let d = debugger(self, &d)?;
703        d.table_set_element(table, index, value).await
704    }
705
706    async fn clone(&mut self, self_: Resource<Table>) -> Result<Resource<Table>> {
707        let table = *self.get(&self_)?;
708        Ok(self.push(table)?)
709    }
710
711    async fn unique_id(&mut self, self_: Resource<Table>) -> Result<u64> {
712        Ok(self.get(&self_)?.debug_index_in_store())
713    }
714
715    async fn drop(&mut self, rep: Resource<Table>) -> Result<()> {
716        self.delete(rep)?;
717        Ok(())
718    }
719}
720
721impl wit::HostWasmFunc for ResourceTable {
722    async fn params(
723        &mut self,
724        self_: Resource<Func>,
725        d: Resource<Debuggee>,
726    ) -> Result<Vec<wit::WasmType>> {
727        let func = *self.get(&self_)?;
728        let d = debugger(self, &d)?;
729        d.func_params(func).await
730    }
731
732    async fn results(
733        &mut self,
734        self_: Resource<Func>,
735        d: Resource<Debuggee>,
736    ) -> Result<Vec<wit::WasmType>> {
737        let func = *self.get(&self_)?;
738        let d = debugger(self, &d)?;
739        d.func_results(func).await
740    }
741
742    async fn clone(&mut self, self_: Resource<Func>) -> Result<Resource<Func>> {
743        let func = *self.get(&self_)?;
744        Ok(self.push(func)?)
745    }
746
747    async fn drop(&mut self, rep: Resource<Func>) -> Result<()> {
748        self.delete(rep)?;
749        Ok(())
750    }
751}
752
753impl wit::HostWasmException for ResourceTable {
754    async fn get_tag(
755        &mut self,
756        self_: Resource<WasmException>,
757        d: Resource<Debuggee>,
758    ) -> Result<Resource<Tag>> {
759        let exn = self.get(&self_)?.clone();
760        let d = debugger(self, &d)?;
761        let tag = d.exnref_get_tag(exn.0).await?;
762        Ok(self.push(tag)?)
763    }
764
765    async fn get_values(
766        &mut self,
767        self_: Resource<WasmException>,
768        d: Resource<Debuggee>,
769    ) -> Result<Vec<Resource<WasmValue>>> {
770        let exn = self.get(&self_)?.clone();
771        let d = debugger(self, &d)?;
772        let values = d.exnref_get_fields(exn.0).await?;
773        let mut resources = vec![];
774        for v in values {
775            resources.push(self.push(v)?);
776        }
777        Ok(resources)
778    }
779
780    async fn clone(
781        &mut self,
782        self_: Resource<WasmException>,
783        _d: Resource<Debuggee>,
784    ) -> Result<Resource<WasmException>> {
785        let exn = self.get(&self_)?.clone();
786        Ok(self.push(exn)?)
787    }
788
789    async fn make(
790        &mut self,
791        d: Resource<Debuggee>,
792        tag: Resource<Tag>,
793        values: Vec<Resource<WasmValue>>,
794    ) -> Result<Resource<WasmException>> {
795        let tag_val = *self.get(&tag)?;
796        let mut wasm_values = vec![];
797        for v in &values {
798            wasm_values.push(self.get(v)?.clone());
799        }
800        let d = debugger(self, &d)?;
801        let owned = d.exnref_new(tag_val, wasm_values).await?;
802        Ok(self.push(WasmException(owned))?)
803    }
804
805    async fn drop(&mut self, rep: Resource<WasmException>) -> Result<()> {
806        self.delete(rep)?;
807        Ok(())
808    }
809}
810
811impl wit::HostWasmTag for ResourceTable {
812    async fn params(
813        &mut self,
814        self_: Resource<Tag>,
815        d: Resource<Debuggee>,
816    ) -> Result<Vec<wit::WasmType>> {
817        let tag = *self.get(&self_)?;
818        let d = debugger(self, &d)?;
819        d.tag_params(tag).await
820    }
821
822    async fn unique_id(&mut self, self_: Resource<Tag>) -> Result<u64> {
823        Ok(self.get(&self_)?.debug_index_in_store())
824    }
825
826    async fn clone(&mut self, self_: Resource<Tag>) -> Result<Resource<Tag>> {
827        let tag = *self.get(&self_)?;
828        Ok(self.push(tag)?)
829    }
830
831    async fn make(
832        &mut self,
833        d: Resource<Debuggee>,
834        params: Vec<wit::WasmType>,
835    ) -> Result<Resource<Tag>> {
836        let engine = self.get(&d)?.engine.clone();
837        let val_types = params.into_iter().map(wasm_type_to_val_type).collect();
838        let d = debugger(self, &d)?;
839        let tag = d.tag_new(engine, val_types).await?;
840        Ok(self.push(tag)?)
841    }
842
843    async fn drop(&mut self, rep: Resource<Tag>) -> Result<()> {
844        self.delete(rep)?;
845        Ok(())
846    }
847}
848
849impl wit::HostFrame for ResourceTable {
850    async fn get_instance(
851        &mut self,
852        self_: Resource<Frame>,
853        d: Resource<Debuggee>,
854    ) -> Result<Resource<Instance>> {
855        let frame = self.get(&self_)?.0.clone();
856        let d = debugger(self, &d)?;
857        let instance = d.frame_instance(frame).await?;
858        Ok(self.push(instance)?)
859    }
860
861    async fn get_func_index(
862        &mut self,
863        self_: Resource<Frame>,
864        d: Resource<Debuggee>,
865    ) -> Result<u32> {
866        let frame = self.get(&self_)?.0.clone();
867        let d = debugger(self, &d)?;
868        let (f, _) = d.frame_func_and_pc(frame).await?;
869        Ok(f)
870    }
871
872    async fn get_pc(&mut self, self_: Resource<Frame>, d: Resource<Debuggee>) -> Result<u32> {
873        let frame = self.get(&self_)?.0.clone();
874        let d = debugger(self, &d)?;
875        let (_, pc) = d.frame_func_and_pc(frame).await?;
876        Ok(pc)
877    }
878
879    async fn get_locals(
880        &mut self,
881        self_: Resource<Frame>,
882        d: Resource<Debuggee>,
883    ) -> Result<Vec<Resource<WasmValue>>> {
884        let frame = self.get(&self_)?.0.clone();
885        let d = debugger(self, &d)?;
886        let locals = d.frame_locals(frame).await?;
887        let mut resources = vec![];
888        for local in locals {
889            resources.push(self.push(local)?);
890        }
891        Ok(resources)
892    }
893
894    async fn get_stack(
895        &mut self,
896        self_: Resource<Frame>,
897        d: Resource<Debuggee>,
898    ) -> Result<Vec<Resource<WasmValue>>> {
899        let frame = self.get(&self_)?.0.clone();
900        let d = debugger(self, &d)?;
901        let stacks = d.frame_stack(frame).await?;
902        let mut resources = vec![];
903        for val in stacks {
904            resources.push(self.push(val)?);
905        }
906        Ok(resources)
907    }
908
909    async fn parent_frame(
910        &mut self,
911        self_: Resource<Frame>,
912        d: Resource<Debuggee>,
913    ) -> Result<Option<Resource<Frame>>> {
914        let frame = self.get(&self_)?.0.clone();
915        let d = debugger(self, &d)?;
916        let parent = d.frame_parent(frame).await?;
917        match parent {
918            Some(p) => Ok(Some(self.push(Frame(p))?)),
919            None => Ok(None),
920        }
921    }
922
923    async fn drop(&mut self, rep: Resource<Frame>) -> Result<()> {
924        self.delete(rep)?;
925        Ok(())
926    }
927}
928
929impl wit::HostWasmValue for ResourceTable {
930    async fn get_type(&mut self, self_: Resource<WasmValue>) -> Result<wit::WasmType> {
931        let value = self.get(&self_)?;
932        match value {
933            WasmValue::Primitive(Val::I32(_)) => Ok(wit::WasmType::WasmI32),
934            WasmValue::Primitive(Val::I64(_)) => Ok(wit::WasmType::WasmI64),
935            WasmValue::Primitive(Val::F32(_)) => Ok(wit::WasmType::WasmF32),
936            WasmValue::Primitive(Val::F64(_)) => Ok(wit::WasmType::WasmF64),
937            WasmValue::Primitive(Val::V128(_)) => Ok(wit::WasmType::WasmV128),
938            WasmValue::Func(_) => Ok(wit::WasmType::WasmFuncref),
939            WasmValue::Exn(_) => Ok(wit::WasmType::WasmExnref),
940            WasmValue::Primitive(_) => unreachable!(),
941        }
942    }
943
944    async fn unwrap_i32(&mut self, self_: Resource<WasmValue>) -> Result<u32> {
945        let value = self.get(&self_)?;
946        match value {
947            WasmValue::Primitive(Val::I32(x)) => Ok(x.cast_unsigned()),
948            _ => wasmtime::bail!("Wasm value is not an i32."),
949        }
950    }
951
952    async fn unwrap_i64(&mut self, self_: Resource<WasmValue>) -> Result<u64> {
953        let value = self.get(&self_)?;
954        match value {
955            WasmValue::Primitive(Val::I64(x)) => Ok(x.cast_unsigned()),
956            _ => wasmtime::bail!("Wasm value is not an i64."),
957        }
958    }
959
960    async fn unwrap_f32(&mut self, self_: Resource<WasmValue>) -> Result<f32> {
961        let value = self.get(&self_)?;
962        match value {
963            WasmValue::Primitive(Val::F32(x)) => Ok(f32::from_bits(*x)),
964            _ => wasmtime::bail!("Wasm value is not an f32."),
965        }
966    }
967
968    async fn unwrap_f64(&mut self, self_: Resource<WasmValue>) -> Result<f64> {
969        let value = self.get(&self_)?;
970        match value {
971            WasmValue::Primitive(Val::F64(x)) => Ok(f64::from_bits(*x)),
972            _ => wasmtime::bail!("Wasm value is not an f64."),
973        }
974    }
975
976    async fn unwrap_v128(&mut self, self_: Resource<WasmValue>) -> Result<Vec<u8>> {
977        let value = self.get(&self_)?;
978        match value {
979            WasmValue::Primitive(Val::V128(x)) => Ok(x.as_u128().to_le_bytes().to_vec()),
980            _ => wasmtime::bail!("Wasm value is not a v128."),
981        }
982    }
983
984    async fn unwrap_func(&mut self, self_: Resource<WasmValue>) -> Result<Option<Resource<Func>>> {
985        let value = self.get(&self_)?;
986        match value {
987            WasmValue::Func(Some(f)) => {
988                let f = *f;
989                Ok(Some(self.push(f)?))
990            }
991            WasmValue::Func(None) => Ok(None),
992            _ => wasmtime::bail!("Wasm value is not a funcref."),
993        }
994    }
995
996    async fn unwrap_exception(
997        &mut self,
998        self_: Resource<WasmValue>,
999    ) -> Result<Option<Resource<WasmException>>> {
1000        let value = self.get(&self_)?;
1001        match value {
1002            WasmValue::Exn(Some(e)) => {
1003                let e = e.clone();
1004                Ok(Some(self.push(WasmException(e))?))
1005            }
1006            WasmValue::Exn(None) => Ok(None),
1007            _ => wasmtime::bail!("Wasm value is not an exnref."),
1008        }
1009    }
1010
1011    async fn make_i32(&mut self, value: u32) -> Result<Resource<WasmValue>> {
1012        Ok(self.push(WasmValue::Primitive(Val::I32(value.cast_signed())))?)
1013    }
1014
1015    async fn make_i64(&mut self, value: u64) -> Result<Resource<WasmValue>> {
1016        Ok(self.push(WasmValue::Primitive(Val::I64(value.cast_signed())))?)
1017    }
1018
1019    async fn make_f32(&mut self, value: f32) -> Result<Resource<WasmValue>> {
1020        Ok(self.push(WasmValue::Primitive(Val::F32(value.to_bits())))?)
1021    }
1022
1023    async fn make_f64(&mut self, value: f64) -> Result<Resource<WasmValue>> {
1024        Ok(self.push(WasmValue::Primitive(Val::F64(value.to_bits())))?)
1025    }
1026
1027    async fn make_v128(&mut self, value: Vec<u8>) -> Result<Resource<WasmValue>> {
1028        let bytes: [u8; 16] = value
1029            .try_into()
1030            .map_err(|_| wasmtime::format_err!("v128 requires exactly 16 bytes"))?;
1031        Ok(self.push(WasmValue::Primitive(Val::V128(
1032            u128::from_le_bytes(bytes).into(),
1033        )))?)
1034    }
1035
1036    async fn clone(&mut self, self_: Resource<WasmValue>) -> Result<Resource<WasmValue>> {
1037        let value = self.get(&self_)?.clone();
1038        Ok(self.push(value)?)
1039    }
1040
1041    async fn drop(&mut self, rep: Resource<WasmValue>) -> Result<()> {
1042        self.delete(rep)?;
1043        Ok(())
1044    }
1045}
1046
1047impl wit::Host for ResourceTable {
1048    fn convert_error(&mut self, err: wasmtime::Error) -> Result<wit::Error> {
1049        err.downcast()
1050    }
1051}