1use 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
15pub struct Debuggee {
18 pub(crate) inner: Option<Box<dyn OpaqueDebugger + Send + 'static>>,
23
24 pub(crate) engine: Engine,
28
29 pub(crate) interrupt_pending: Arc<AtomicBool>,
32}
33
34impl Debuggee {
35 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
73pub struct EventFuture {
82 state: EventFutureState,
83}
84
85enum EventFutureState {
86 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 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#[derive(Clone)]
156pub struct Frame(FrameHandle);
157
158#[derive(Clone)]
160pub struct WasmException(OwnedRooted<ExnRef>);
161
162#[derive(Clone)]
167pub enum WasmValue {
168 Primitive(Val),
170 Exn(Option<OwnedRooted<ExnRef>>),
172 Func(Option<Func>),
174 }
176
177fn 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 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}