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::CaughtExceptionThrown(e) => {
261            let e = table.push(WasmException(e))?;
262            wit::Event::CaughtExceptionThrown(e)
263        }
264        DebugRunResult::UncaughtExceptionThrown(e) => {
265            let e = table.push(WasmException(e))?;
266            wit::Event::UncaughtExceptionThrown(e)
267        }
268    })
269}
270
271impl wit::HostEventFuture for ResourceTable {
272    async fn finish(
273        &mut self,
274        self_: Resource<EventFuture>,
275        debuggee: Resource<Debuggee>,
276    ) -> Result<wit::Event> {
277        let mut f = self.delete(self_)?;
278        f.ready().await;
279        match f.state {
280            EventFutureState::Running(..) => {
281                unreachable!("ready() cannot return until setting Done state")
282            }
283            EventFutureState::Done { inner, result } => {
284                self.get_mut(&debuggee)?.inner = Some(inner);
285                match result.unwrap() {
286                    Ok(result) => Ok(result_to_event(self, result)?),
287                    Err(e) => Err(e),
288                }
289            }
290        }
291    }
292
293    async fn drop(&mut self, rep: Resource<EventFuture>) -> Result<()> {
294        self.delete(rep)?;
295        Ok(())
296    }
297
298    async fn subscribe(&mut self, self_: Resource<EventFuture>) -> Result<Resource<DynPollable>> {
299        subscribe(self, self_)
300    }
301}
302
303impl wit::HostInstance for ResourceTable {
304    async fn get_module(
305        &mut self,
306        self_: Resource<Instance>,
307        d: Resource<Debuggee>,
308    ) -> Result<Resource<Module>> {
309        let i = *self.get(&self_)?;
310        let d = debugger(self, &d)?;
311        let module = d.get_instance_module(i).await?;
312        let module = self.push(module)?;
313        Ok(module)
314    }
315
316    async fn get_memory(
317        &mut self,
318        self_: Resource<Instance>,
319        d: Resource<Debuggee>,
320        memory_index: u32,
321    ) -> Result<Resource<Memory>> {
322        let instance = *self.get(&self_)?;
323        let d = debugger(self, &d)?;
324        let memory = d
325            .instance_get_memory(instance, memory_index)
326            .await?
327            .ok_or(wit::Error::InvalidEntity)?;
328        Ok(self.push(memory)?)
329    }
330
331    async fn get_global(
332        &mut self,
333        self_: Resource<Instance>,
334        d: Resource<Debuggee>,
335        global_index: u32,
336    ) -> Result<Resource<Global>> {
337        let instance = *self.get(&self_)?;
338        let d = debugger(self, &d)?;
339        let global = d
340            .instance_get_global(instance, global_index)
341            .await?
342            .ok_or(wit::Error::InvalidEntity)?;
343        Ok(self.push(global)?)
344    }
345
346    async fn get_table(
347        &mut self,
348        self_: Resource<Instance>,
349        d: Resource<Debuggee>,
350        table_index: u32,
351    ) -> Result<Resource<Table>> {
352        let instance = *self.get(&self_)?;
353        let d = debugger(self, &d)?;
354        let table = d
355            .instance_get_table(instance, table_index)
356            .await?
357            .ok_or(wit::Error::InvalidEntity)?;
358        Ok(self.push(table)?)
359    }
360
361    async fn get_func(
362        &mut self,
363        self_: Resource<Instance>,
364        d: Resource<Debuggee>,
365        func_index: u32,
366    ) -> Result<Resource<Func>> {
367        let instance = *self.get(&self_)?;
368        let d = debugger(self, &d)?;
369        let func = d
370            .instance_get_func(instance, func_index)
371            .await?
372            .ok_or(wit::Error::InvalidEntity)?;
373        Ok(self.push(func)?)
374    }
375
376    async fn get_tag(
377        &mut self,
378        self_: Resource<Instance>,
379        d: Resource<Debuggee>,
380        tag_index: u32,
381    ) -> Result<Resource<Tag>> {
382        let instance = *self.get(&self_)?;
383        let d = debugger(self, &d)?;
384        let tag = d
385            .instance_get_tag(instance, tag_index)
386            .await?
387            .ok_or(wit::Error::InvalidEntity)?;
388        Ok(self.push(tag)?)
389    }
390
391    async fn clone(&mut self, self_: Resource<Instance>) -> Result<Resource<Instance>> {
392        let instance = *self.get(&self_)?;
393        Ok(self.push(instance)?)
394    }
395
396    async fn unique_id(&mut self, self_: Resource<Instance>) -> Result<u64> {
397        let instance = self.get(&self_)?;
398        Ok(u64::from(instance.debug_index_in_store()))
399    }
400
401    async fn drop(&mut self, rep: Resource<Instance>) -> Result<()> {
402        self.delete(rep)?;
403        Ok(())
404    }
405}
406
407impl wit::HostModule for ResourceTable {
408    async fn add_breakpoint(
409        &mut self,
410        self_: Resource<Module>,
411        d: Resource<Debuggee>,
412        pc: u32,
413    ) -> Result<()> {
414        let module = self.get(&self_)?.clone();
415        let d = debugger(self, &d)?;
416        d.module_add_breakpoint(module, pc).await
417    }
418
419    async fn remove_breakpoint(
420        &mut self,
421        self_: Resource<Module>,
422        d: Resource<Debuggee>,
423        pc: u32,
424    ) -> Result<()> {
425        let module = self.get(&self_)?.clone();
426        let d = debugger(self, &d)?;
427        d.module_remove_breakpoint(module, pc).await
428    }
429
430    async fn bytecode(&mut self, self_: Resource<Module>) -> Result<Option<Vec<u8>>> {
431        let module = self.get(&self_)?;
432        Ok(module.debug_bytecode().map(|b| b.to_vec()))
433    }
434
435    async fn clone(&mut self, self_: Resource<Module>) -> Result<Resource<Module>> {
436        let module = self.get(&self_)?.clone();
437        Ok(self.push(module)?)
438    }
439
440    async fn unique_id(&mut self, self_: Resource<Module>) -> Result<u64> {
441        let module = self.get(&self_)?;
442        Ok(module.debug_index_in_engine())
443    }
444
445    async fn drop(&mut self, rep: Resource<Module>) -> Result<()> {
446        self.delete(rep)?;
447        Ok(())
448    }
449}
450
451impl wit::HostMemory for ResourceTable {
452    async fn size_bytes(&mut self, self_: Resource<Memory>, d: Resource<Debuggee>) -> Result<u64> {
453        let memory = *self.get(&self_)?;
454        let d = debugger(self, &d)?;
455        d.memory_size_bytes(memory).await
456    }
457
458    async fn page_size_bytes(
459        &mut self,
460        self_: Resource<Memory>,
461        d: Resource<Debuggee>,
462    ) -> Result<u64> {
463        let memory = *self.get(&self_)?;
464        let d = debugger(self, &d)?;
465        d.memory_page_size(memory).await
466    }
467
468    async fn grow_to_bytes(
469        &mut self,
470        self_: Resource<Memory>,
471        d: Resource<Debuggee>,
472        delta_bytes: u64,
473    ) -> Result<u64> {
474        let memory = *self.get(&self_)?;
475        let d = debugger(self, &d)?;
476        d.memory_grow(memory, delta_bytes).await
477    }
478
479    async fn get_bytes(
480        &mut self,
481        self_: Resource<Memory>,
482        d: Resource<Debuggee>,
483        addr: u64,
484        len: u64,
485    ) -> Result<Vec<u8>> {
486        let memory = *self.get(&self_)?;
487        let d = debugger(self, &d)?;
488        Ok(d.memory_read_bytes(memory, addr, len)
489            .await?
490            .ok_or(wit::Error::OutOfBounds)?)
491    }
492
493    async fn set_bytes(
494        &mut self,
495        self_: Resource<Memory>,
496        d: Resource<Debuggee>,
497        addr: u64,
498        bytes: Vec<u8>,
499    ) -> Result<()> {
500        let memory = *self.get(&self_)?;
501        let d = debugger(self, &d)?;
502        d.memory_write_bytes(memory, addr, bytes)
503            .await?
504            .ok_or(wit::Error::OutOfBounds)?;
505        Ok(())
506    }
507
508    async fn get_u8(
509        &mut self,
510        self_: Resource<Memory>,
511        d: Resource<Debuggee>,
512        addr: u64,
513    ) -> Result<u8> {
514        let memory = *self.get(&self_)?;
515        let d = debugger(self, &d)?;
516        Ok(d.memory_read_u8(memory, addr)
517            .await?
518            .ok_or(wit::Error::OutOfBounds)?)
519    }
520
521    async fn get_u16(
522        &mut self,
523        self_: Resource<Memory>,
524        d: Resource<Debuggee>,
525        addr: u64,
526    ) -> Result<u16> {
527        let memory = *self.get(&self_)?;
528        let d = debugger(self, &d)?;
529        Ok(d.memory_read_u16(memory, addr)
530            .await?
531            .ok_or(wit::Error::OutOfBounds)?)
532    }
533
534    async fn get_u32(
535        &mut self,
536        self_: Resource<Memory>,
537        d: Resource<Debuggee>,
538        addr: u64,
539    ) -> Result<u32> {
540        let memory = *self.get(&self_)?;
541        let d = debugger(self, &d)?;
542        Ok(d.memory_read_u32(memory, addr)
543            .await?
544            .ok_or(wit::Error::OutOfBounds)?)
545    }
546
547    async fn get_u64(
548        &mut self,
549        self_: Resource<Memory>,
550        d: Resource<Debuggee>,
551        addr: u64,
552    ) -> Result<u64> {
553        let memory = *self.get(&self_)?;
554        let d = debugger(self, &d)?;
555        Ok(d.memory_read_u64(memory, addr)
556            .await?
557            .ok_or(wit::Error::OutOfBounds)?)
558    }
559
560    async fn set_u8(
561        &mut self,
562        self_: Resource<Memory>,
563        d: Resource<Debuggee>,
564        addr: u64,
565        value: u8,
566    ) -> Result<()> {
567        let memory = *self.get(&self_)?;
568        let d = debugger(self, &d)?;
569        d.memory_write_u8(memory, addr, value)
570            .await?
571            .ok_or(wit::Error::OutOfBounds)?;
572        Ok(())
573    }
574
575    async fn set_u16(
576        &mut self,
577        self_: Resource<Memory>,
578        d: Resource<Debuggee>,
579        addr: u64,
580        value: u16,
581    ) -> Result<()> {
582        let memory = *self.get(&self_)?;
583        let d = debugger(self, &d)?;
584        d.memory_write_u16(memory, addr, value)
585            .await?
586            .ok_or(wit::Error::OutOfBounds)?;
587        Ok(())
588    }
589
590    async fn set_u32(
591        &mut self,
592        self_: Resource<Memory>,
593        d: Resource<Debuggee>,
594        addr: u64,
595        value: u32,
596    ) -> Result<()> {
597        let memory = *self.get(&self_)?;
598        let d = debugger(self, &d)?;
599        d.memory_write_u32(memory, addr, value)
600            .await?
601            .ok_or(wit::Error::OutOfBounds)?;
602        Ok(())
603    }
604
605    async fn set_u64(
606        &mut self,
607        self_: Resource<Memory>,
608        d: Resource<Debuggee>,
609        addr: u64,
610        value: u64,
611    ) -> Result<()> {
612        let memory = *self.get(&self_)?;
613        let d = debugger(self, &d)?;
614        d.memory_write_u64(memory, addr, value)
615            .await?
616            .ok_or(wit::Error::OutOfBounds)?;
617        Ok(())
618    }
619
620    async fn clone(&mut self, self_: Resource<Memory>) -> Result<Resource<Memory>> {
621        let memory = *self.get(&self_)?;
622        Ok(self.push(memory)?)
623    }
624
625    async fn unique_id(&mut self, self_: Resource<Memory>) -> Result<u64> {
626        Ok(self.get(&self_)?.debug_index_in_store())
627    }
628
629    async fn drop(&mut self, rep: Resource<Memory>) -> Result<()> {
630        self.delete(rep)?;
631        Ok(())
632    }
633}
634
635impl wit::HostGlobal for ResourceTable {
636    async fn get(
637        &mut self,
638        self_: Resource<Global>,
639        d: Resource<Debuggee>,
640    ) -> Result<Resource<WasmValue>> {
641        // N.B.: we use UFCS here because `HostGlobal::get` conflicts
642        // with `ResourceTable::get` and we're implementing the WIT
643        // trait directly on the `ResourceTable`.
644        let global = *ResourceTable::get(self, &self_)?;
645        let d = debugger(self, &d)?;
646        let value = d.global_get(global).await?;
647        Ok(self.push(value)?)
648    }
649
650    async fn set(
651        &mut self,
652        self_: Resource<Global>,
653        d: Resource<Debuggee>,
654        val: Resource<WasmValue>,
655    ) -> Result<()> {
656        let global = *ResourceTable::get(self, &self_)?;
657        let value = ResourceTable::get(self, &val)?.clone();
658        let d = debugger(self, &d)?;
659        d.global_set(global, value).await
660    }
661
662    async fn clone(&mut self, self_: Resource<Global>) -> Result<Resource<Global>> {
663        let global = *ResourceTable::get(self, &self_)?;
664        Ok(self.push(global)?)
665    }
666
667    async fn unique_id(&mut self, self_: Resource<Global>) -> Result<u64> {
668        let global = *ResourceTable::get(self, &self_)?;
669        Ok(global.debug_index_in_store())
670    }
671
672    async fn drop(&mut self, rep: Resource<Global>) -> Result<()> {
673        self.delete(rep)?;
674        Ok(())
675    }
676}
677
678impl wit::HostTable for ResourceTable {
679    async fn len(&mut self, self_: Resource<Table>, d: Resource<Debuggee>) -> Result<u64> {
680        let table = *self.get(&self_)?;
681        let d = debugger(self, &d)?;
682        d.table_len(table).await
683    }
684
685    async fn get_element(
686        &mut self,
687        self_: Resource<Table>,
688        d: Resource<Debuggee>,
689        index: u64,
690    ) -> Result<Resource<WasmValue>> {
691        let table = *self.get(&self_)?;
692        let d = debugger(self, &d)?;
693        let value = d.table_get_element(table, index).await?;
694        Ok(self.push(value)?)
695    }
696
697    async fn set_element(
698        &mut self,
699        self_: Resource<Table>,
700        d: Resource<Debuggee>,
701        index: u64,
702        val: Resource<WasmValue>,
703    ) -> Result<()> {
704        let table = *self.get(&self_)?;
705        let value = self.get(&val)?.clone();
706        let d = debugger(self, &d)?;
707        d.table_set_element(table, index, value).await
708    }
709
710    async fn clone(&mut self, self_: Resource<Table>) -> Result<Resource<Table>> {
711        let table = *self.get(&self_)?;
712        Ok(self.push(table)?)
713    }
714
715    async fn unique_id(&mut self, self_: Resource<Table>) -> Result<u64> {
716        Ok(self.get(&self_)?.debug_index_in_store())
717    }
718
719    async fn drop(&mut self, rep: Resource<Table>) -> Result<()> {
720        self.delete(rep)?;
721        Ok(())
722    }
723}
724
725impl wit::HostWasmFunc for ResourceTable {
726    async fn params(
727        &mut self,
728        self_: Resource<Func>,
729        d: Resource<Debuggee>,
730    ) -> Result<Vec<wit::WasmType>> {
731        let func = *self.get(&self_)?;
732        let d = debugger(self, &d)?;
733        d.func_params(func).await
734    }
735
736    async fn results(
737        &mut self,
738        self_: Resource<Func>,
739        d: Resource<Debuggee>,
740    ) -> Result<Vec<wit::WasmType>> {
741        let func = *self.get(&self_)?;
742        let d = debugger(self, &d)?;
743        d.func_results(func).await
744    }
745
746    async fn clone(&mut self, self_: Resource<Func>) -> Result<Resource<Func>> {
747        let func = *self.get(&self_)?;
748        Ok(self.push(func)?)
749    }
750
751    async fn drop(&mut self, rep: Resource<Func>) -> Result<()> {
752        self.delete(rep)?;
753        Ok(())
754    }
755}
756
757impl wit::HostWasmException for ResourceTable {
758    async fn get_tag(
759        &mut self,
760        self_: Resource<WasmException>,
761        d: Resource<Debuggee>,
762    ) -> Result<Resource<Tag>> {
763        let exn = self.get(&self_)?.clone();
764        let d = debugger(self, &d)?;
765        let tag = d.exnref_get_tag(exn.0).await?;
766        Ok(self.push(tag)?)
767    }
768
769    async fn get_values(
770        &mut self,
771        self_: Resource<WasmException>,
772        d: Resource<Debuggee>,
773    ) -> Result<Vec<Resource<WasmValue>>> {
774        let exn = self.get(&self_)?.clone();
775        let d = debugger(self, &d)?;
776        let values = d.exnref_get_fields(exn.0).await?;
777        let mut resources = vec![];
778        for v in values {
779            resources.push(self.push(v)?);
780        }
781        Ok(resources)
782    }
783
784    async fn clone(
785        &mut self,
786        self_: Resource<WasmException>,
787        _d: Resource<Debuggee>,
788    ) -> Result<Resource<WasmException>> {
789        let exn = self.get(&self_)?.clone();
790        Ok(self.push(exn)?)
791    }
792
793    async fn make(
794        &mut self,
795        d: Resource<Debuggee>,
796        tag: Resource<Tag>,
797        values: Vec<Resource<WasmValue>>,
798    ) -> Result<Resource<WasmException>> {
799        let tag_val = *self.get(&tag)?;
800        let mut wasm_values = vec![];
801        for v in &values {
802            wasm_values.push(self.get(v)?.clone());
803        }
804        let d = debugger(self, &d)?;
805        let owned = d.exnref_new(tag_val, wasm_values).await?;
806        Ok(self.push(WasmException(owned))?)
807    }
808
809    async fn drop(&mut self, rep: Resource<WasmException>) -> Result<()> {
810        self.delete(rep)?;
811        Ok(())
812    }
813}
814
815impl wit::HostWasmTag for ResourceTable {
816    async fn params(
817        &mut self,
818        self_: Resource<Tag>,
819        d: Resource<Debuggee>,
820    ) -> Result<Vec<wit::WasmType>> {
821        let tag = *self.get(&self_)?;
822        let d = debugger(self, &d)?;
823        d.tag_params(tag).await
824    }
825
826    async fn unique_id(&mut self, self_: Resource<Tag>) -> Result<u64> {
827        Ok(self.get(&self_)?.debug_index_in_store())
828    }
829
830    async fn clone(&mut self, self_: Resource<Tag>) -> Result<Resource<Tag>> {
831        let tag = *self.get(&self_)?;
832        Ok(self.push(tag)?)
833    }
834
835    async fn make(
836        &mut self,
837        d: Resource<Debuggee>,
838        params: Vec<wit::WasmType>,
839    ) -> Result<Resource<Tag>> {
840        let engine = self.get(&d)?.engine.clone();
841        let val_types = params.into_iter().map(wasm_type_to_val_type).collect();
842        let d = debugger(self, &d)?;
843        let tag = d.tag_new(engine, val_types).await?;
844        Ok(self.push(tag)?)
845    }
846
847    async fn drop(&mut self, rep: Resource<Tag>) -> Result<()> {
848        self.delete(rep)?;
849        Ok(())
850    }
851}
852
853impl wit::HostFrame for ResourceTable {
854    async fn get_instance(
855        &mut self,
856        self_: Resource<Frame>,
857        d: Resource<Debuggee>,
858    ) -> Result<Resource<Instance>> {
859        let frame = self.get(&self_)?.0.clone();
860        let d = debugger(self, &d)?;
861        let instance = d.frame_instance(frame).await?;
862        Ok(self.push(instance)?)
863    }
864
865    async fn get_func_index(
866        &mut self,
867        self_: Resource<Frame>,
868        d: Resource<Debuggee>,
869    ) -> Result<u32> {
870        let frame = self.get(&self_)?.0.clone();
871        let d = debugger(self, &d)?;
872        let (f, _) = d.frame_func_and_pc(frame).await?;
873        Ok(f)
874    }
875
876    async fn get_pc(&mut self, self_: Resource<Frame>, d: Resource<Debuggee>) -> Result<u32> {
877        let frame = self.get(&self_)?.0.clone();
878        let d = debugger(self, &d)?;
879        let (_, pc) = d.frame_func_and_pc(frame).await?;
880        Ok(pc)
881    }
882
883    async fn get_locals(
884        &mut self,
885        self_: Resource<Frame>,
886        d: Resource<Debuggee>,
887    ) -> Result<Vec<Resource<WasmValue>>> {
888        let frame = self.get(&self_)?.0.clone();
889        let d = debugger(self, &d)?;
890        let locals = d.frame_locals(frame).await?;
891        let mut resources = vec![];
892        for local in locals {
893            resources.push(self.push(local)?);
894        }
895        Ok(resources)
896    }
897
898    async fn get_stack(
899        &mut self,
900        self_: Resource<Frame>,
901        d: Resource<Debuggee>,
902    ) -> Result<Vec<Resource<WasmValue>>> {
903        let frame = self.get(&self_)?.0.clone();
904        let d = debugger(self, &d)?;
905        let stacks = d.frame_stack(frame).await?;
906        let mut resources = vec![];
907        for val in stacks {
908            resources.push(self.push(val)?);
909        }
910        Ok(resources)
911    }
912
913    async fn parent_frame(
914        &mut self,
915        self_: Resource<Frame>,
916        d: Resource<Debuggee>,
917    ) -> Result<Option<Resource<Frame>>> {
918        let frame = self.get(&self_)?.0.clone();
919        let d = debugger(self, &d)?;
920        let parent = d.frame_parent(frame).await?;
921        match parent {
922            Some(p) => Ok(Some(self.push(Frame(p))?)),
923            None => Ok(None),
924        }
925    }
926
927    async fn drop(&mut self, rep: Resource<Frame>) -> Result<()> {
928        self.delete(rep)?;
929        Ok(())
930    }
931}
932
933impl wit::HostWasmValue for ResourceTable {
934    async fn get_type(&mut self, self_: Resource<WasmValue>) -> Result<wit::WasmType> {
935        let value = self.get(&self_)?;
936        match value {
937            WasmValue::Primitive(Val::I32(_)) => Ok(wit::WasmType::WasmI32),
938            WasmValue::Primitive(Val::I64(_)) => Ok(wit::WasmType::WasmI64),
939            WasmValue::Primitive(Val::F32(_)) => Ok(wit::WasmType::WasmF32),
940            WasmValue::Primitive(Val::F64(_)) => Ok(wit::WasmType::WasmF64),
941            WasmValue::Primitive(Val::V128(_)) => Ok(wit::WasmType::WasmV128),
942            WasmValue::Func(_) => Ok(wit::WasmType::WasmFuncref),
943            WasmValue::Exn(_) => Ok(wit::WasmType::WasmExnref),
944            WasmValue::Primitive(_) => unreachable!(),
945        }
946    }
947
948    async fn unwrap_i32(&mut self, self_: Resource<WasmValue>) -> Result<u32> {
949        let value = self.get(&self_)?;
950        match value {
951            WasmValue::Primitive(Val::I32(x)) => Ok(x.cast_unsigned()),
952            _ => wasmtime::bail!("Wasm value is not an i32."),
953        }
954    }
955
956    async fn unwrap_i64(&mut self, self_: Resource<WasmValue>) -> Result<u64> {
957        let value = self.get(&self_)?;
958        match value {
959            WasmValue::Primitive(Val::I64(x)) => Ok(x.cast_unsigned()),
960            _ => wasmtime::bail!("Wasm value is not an i64."),
961        }
962    }
963
964    async fn unwrap_f32(&mut self, self_: Resource<WasmValue>) -> Result<f32> {
965        let value = self.get(&self_)?;
966        match value {
967            WasmValue::Primitive(Val::F32(x)) => Ok(f32::from_bits(*x)),
968            _ => wasmtime::bail!("Wasm value is not an f32."),
969        }
970    }
971
972    async fn unwrap_f64(&mut self, self_: Resource<WasmValue>) -> Result<f64> {
973        let value = self.get(&self_)?;
974        match value {
975            WasmValue::Primitive(Val::F64(x)) => Ok(f64::from_bits(*x)),
976            _ => wasmtime::bail!("Wasm value is not an f64."),
977        }
978    }
979
980    async fn unwrap_v128(&mut self, self_: Resource<WasmValue>) -> Result<Vec<u8>> {
981        let value = self.get(&self_)?;
982        match value {
983            WasmValue::Primitive(Val::V128(x)) => Ok(x.as_u128().to_le_bytes().to_vec()),
984            _ => wasmtime::bail!("Wasm value is not a v128."),
985        }
986    }
987
988    async fn unwrap_func(&mut self, self_: Resource<WasmValue>) -> Result<Option<Resource<Func>>> {
989        let value = self.get(&self_)?;
990        match value {
991            WasmValue::Func(Some(f)) => {
992                let f = *f;
993                Ok(Some(self.push(f)?))
994            }
995            WasmValue::Func(None) => Ok(None),
996            _ => wasmtime::bail!("Wasm value is not a funcref."),
997        }
998    }
999
1000    async fn unwrap_exception(
1001        &mut self,
1002        self_: Resource<WasmValue>,
1003    ) -> Result<Option<Resource<WasmException>>> {
1004        let value = self.get(&self_)?;
1005        match value {
1006            WasmValue::Exn(Some(e)) => {
1007                let e = e.clone();
1008                Ok(Some(self.push(WasmException(e))?))
1009            }
1010            WasmValue::Exn(None) => Ok(None),
1011            _ => wasmtime::bail!("Wasm value is not an exnref."),
1012        }
1013    }
1014
1015    async fn make_i32(&mut self, value: u32) -> Result<Resource<WasmValue>> {
1016        Ok(self.push(WasmValue::Primitive(Val::I32(value.cast_signed())))?)
1017    }
1018
1019    async fn make_i64(&mut self, value: u64) -> Result<Resource<WasmValue>> {
1020        Ok(self.push(WasmValue::Primitive(Val::I64(value.cast_signed())))?)
1021    }
1022
1023    async fn make_f32(&mut self, value: f32) -> Result<Resource<WasmValue>> {
1024        Ok(self.push(WasmValue::Primitive(Val::F32(value.to_bits())))?)
1025    }
1026
1027    async fn make_f64(&mut self, value: f64) -> Result<Resource<WasmValue>> {
1028        Ok(self.push(WasmValue::Primitive(Val::F64(value.to_bits())))?)
1029    }
1030
1031    async fn make_v128(&mut self, value: Vec<u8>) -> Result<Resource<WasmValue>> {
1032        let bytes: [u8; 16] = value
1033            .try_into()
1034            .map_err(|_| wasmtime::format_err!("v128 requires exactly 16 bytes"))?;
1035        Ok(self.push(WasmValue::Primitive(Val::V128(
1036            u128::from_le_bytes(bytes).into(),
1037        )))?)
1038    }
1039
1040    async fn clone(&mut self, self_: Resource<WasmValue>) -> Result<Resource<WasmValue>> {
1041        let value = self.get(&self_)?.clone();
1042        Ok(self.push(value)?)
1043    }
1044
1045    async fn drop(&mut self, rep: Resource<WasmValue>) -> Result<()> {
1046        self.delete(rep)?;
1047        Ok(())
1048    }
1049}
1050
1051impl wit::Host for ResourceTable {
1052    fn convert_error(&mut self, err: wasmtime::Error) -> Result<wit::Error> {
1053        err.downcast()
1054    }
1055}