1 //! Implementations of the host API traits.
2
3 use crate::host::opaque::OpaqueDebugger;
4 use crate::host::wit;
5 use crate::{DebugRunResult, host::bindings::wasm_type_to_val_type};
6 use std::pin::Pin;
7 use std::sync::Arc;
8 use std::sync::atomic::{AtomicBool, Ordering};
9 use wasmtime::{
10 Engine, ExnRef, FrameHandle, Func, Global, Instance, Memory, Module, OwnedRooted, Result,
11 Table, Tag, Val, component::Resource, component::ResourceTable,
12 };
13 use 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.
17 pub 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
34 impl Debuggee {
35 /// Finish execution of the debuggee before returning.
finish(&mut self) -> Result<()>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
44 impl WasmValue {
new(store: impl wasmtime::AsContextMut, val: Val) -> Result<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
into_val(self, store: impl wasmtime::AsContextMut) -> Val62 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()`.
81 pub struct EventFuture {
82 state: EventFutureState,
83 }
84
85 enum 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
106 impl EventFuture {
new_single_step( mut inner: Box<dyn OpaqueDebugger + Send + 'static>, resumption: wit::ResumptionValue, ) -> Self107 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
new_continue( mut inner: Box<dyn OpaqueDebugger + Send + 'static>, resumption: wit::ResumptionValue, ) -> Self122 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]
139 impl wasmtime_wasi_io::poll::Pollable for EventFuture {
ready(&mut self)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)]
156 pub struct Frame(FrameHandle);
157
158 /// Representation of a Wasm exception object.
159 #[derive(Clone)]
160 pub 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)]
167 pub 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.
debugger<'a>( table: &'a mut ResourceTable, debuggee: &Resource<Debuggee>, ) -> Result<&'a mut dyn OpaqueDebugger>178 fn 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
188 impl wit::HostDebuggee for ResourceTable {
all_modules(&mut self, debuggee: Resource<Debuggee>) -> Result<Vec<Resource<Module>>>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
all_instances( &mut self, debuggee: Resource<Debuggee>, ) -> Result<Vec<Resource<Instance>>>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
interrupt(&mut self, debuggee: Resource<Debuggee>) -> Result<()>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
single_step( &mut self, debuggee: Resource<Debuggee>, resumption: wit::ResumptionValue, ) -> Result<Resource<EventFuture>>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
continue_( &mut self, debuggee: Resource<Debuggee>, resumption: wit::ResumptionValue, ) -> Result<Resource<EventFuture>>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
exit_frames(&mut self, debuggee: Resource<Debuggee>) -> Result<Vec<Resource<Frame>>>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
drop(&mut self, debuggee: Resource<Debuggee>) -> Result<()>247 async fn drop(&mut self, debuggee: Resource<Debuggee>) -> Result<()> {
248 self.delete(debuggee)?;
249 Ok(())
250 }
251 }
252
result_to_event(table: &mut ResourceTable, value: DebugRunResult) -> Result<wit::Event>253 fn 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
271 impl wit::HostEventFuture for ResourceTable {
finish( &mut self, self_: Resource<EventFuture>, debuggee: Resource<Debuggee>, ) -> Result<wit::Event>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
drop(&mut self, rep: Resource<EventFuture>) -> Result<()>293 async fn drop(&mut self, rep: Resource<EventFuture>) -> Result<()> {
294 self.delete(rep)?;
295 Ok(())
296 }
297
subscribe(&mut self, self_: Resource<EventFuture>) -> Result<Resource<DynPollable>>298 async fn subscribe(&mut self, self_: Resource<EventFuture>) -> Result<Resource<DynPollable>> {
299 subscribe(self, self_)
300 }
301 }
302
303 impl wit::HostInstance for ResourceTable {
get_module( &mut self, self_: Resource<Instance>, d: Resource<Debuggee>, ) -> Result<Resource<Module>>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
get_memory( &mut self, self_: Resource<Instance>, d: Resource<Debuggee>, memory_index: u32, ) -> Result<Resource<Memory>>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
get_global( &mut self, self_: Resource<Instance>, d: Resource<Debuggee>, global_index: u32, ) -> Result<Resource<Global>>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
get_table( &mut self, self_: Resource<Instance>, d: Resource<Debuggee>, table_index: u32, ) -> Result<Resource<Table>>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
get_func( &mut self, self_: Resource<Instance>, d: Resource<Debuggee>, func_index: u32, ) -> Result<Resource<Func>>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
get_tag( &mut self, self_: Resource<Instance>, d: Resource<Debuggee>, tag_index: u32, ) -> Result<Resource<Tag>>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
clone(&mut self, self_: Resource<Instance>) -> Result<Resource<Instance>>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
unique_id(&mut self, self_: Resource<Instance>) -> Result<u64>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
drop(&mut self, rep: Resource<Instance>) -> Result<()>401 async fn drop(&mut self, rep: Resource<Instance>) -> Result<()> {
402 self.delete(rep)?;
403 Ok(())
404 }
405 }
406
407 impl wit::HostModule for ResourceTable {
add_breakpoint( &mut self, self_: Resource<Module>, d: Resource<Debuggee>, pc: u32, ) -> Result<()>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
remove_breakpoint( &mut self, self_: Resource<Module>, d: Resource<Debuggee>, pc: u32, ) -> Result<()>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
bytecode(&mut self, self_: Resource<Module>) -> Result<Option<Vec<u8>>>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
clone(&mut self, self_: Resource<Module>) -> Result<Resource<Module>>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
unique_id(&mut self, self_: Resource<Module>) -> Result<u64>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
drop(&mut self, rep: Resource<Module>) -> Result<()>445 async fn drop(&mut self, rep: Resource<Module>) -> Result<()> {
446 self.delete(rep)?;
447 Ok(())
448 }
449 }
450
451 impl wit::HostMemory for ResourceTable {
size_bytes(&mut self, self_: Resource<Memory>, d: Resource<Debuggee>) -> Result<u64>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
page_size_bytes( &mut self, self_: Resource<Memory>, d: Resource<Debuggee>, ) -> Result<u64>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
grow_to_bytes( &mut self, self_: Resource<Memory>, d: Resource<Debuggee>, delta_bytes: u64, ) -> Result<u64>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
get_bytes( &mut self, self_: Resource<Memory>, d: Resource<Debuggee>, addr: u64, len: u64, ) -> Result<Vec<u8>>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
set_bytes( &mut self, self_: Resource<Memory>, d: Resource<Debuggee>, addr: u64, bytes: Vec<u8>, ) -> Result<()>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
get_u8( &mut self, self_: Resource<Memory>, d: Resource<Debuggee>, addr: u64, ) -> Result<u8>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
get_u16( &mut self, self_: Resource<Memory>, d: Resource<Debuggee>, addr: u64, ) -> Result<u16>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
get_u32( &mut self, self_: Resource<Memory>, d: Resource<Debuggee>, addr: u64, ) -> Result<u32>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
get_u64( &mut self, self_: Resource<Memory>, d: Resource<Debuggee>, addr: u64, ) -> Result<u64>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
set_u8( &mut self, self_: Resource<Memory>, d: Resource<Debuggee>, addr: u64, value: u8, ) -> Result<()>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
set_u16( &mut self, self_: Resource<Memory>, d: Resource<Debuggee>, addr: u64, value: u16, ) -> Result<()>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
set_u32( &mut self, self_: Resource<Memory>, d: Resource<Debuggee>, addr: u64, value: u32, ) -> Result<()>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
set_u64( &mut self, self_: Resource<Memory>, d: Resource<Debuggee>, addr: u64, value: u64, ) -> Result<()>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
clone(&mut self, self_: Resource<Memory>) -> Result<Resource<Memory>>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
unique_id(&mut self, self_: Resource<Memory>) -> Result<u64>625 async fn unique_id(&mut self, self_: Resource<Memory>) -> Result<u64> {
626 Ok(self.get(&self_)?.debug_index_in_store())
627 }
628
drop(&mut self, rep: Resource<Memory>) -> Result<()>629 async fn drop(&mut self, rep: Resource<Memory>) -> Result<()> {
630 self.delete(rep)?;
631 Ok(())
632 }
633 }
634
635 impl wit::HostGlobal for ResourceTable {
get( &mut self, self_: Resource<Global>, d: Resource<Debuggee>, ) -> Result<Resource<WasmValue>>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
set( &mut self, self_: Resource<Global>, d: Resource<Debuggee>, val: Resource<WasmValue>, ) -> Result<()>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
clone(&mut self, self_: Resource<Global>) -> Result<Resource<Global>>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
unique_id(&mut self, self_: Resource<Global>) -> Result<u64>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
drop(&mut self, rep: Resource<Global>) -> Result<()>672 async fn drop(&mut self, rep: Resource<Global>) -> Result<()> {
673 self.delete(rep)?;
674 Ok(())
675 }
676 }
677
678 impl wit::HostTable for ResourceTable {
len(&mut self, self_: Resource<Table>, d: Resource<Debuggee>) -> Result<u64>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
get_element( &mut self, self_: Resource<Table>, d: Resource<Debuggee>, index: u64, ) -> Result<Resource<WasmValue>>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
set_element( &mut self, self_: Resource<Table>, d: Resource<Debuggee>, index: u64, val: Resource<WasmValue>, ) -> Result<()>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
clone(&mut self, self_: Resource<Table>) -> Result<Resource<Table>>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
unique_id(&mut self, self_: Resource<Table>) -> Result<u64>715 async fn unique_id(&mut self, self_: Resource<Table>) -> Result<u64> {
716 Ok(self.get(&self_)?.debug_index_in_store())
717 }
718
drop(&mut self, rep: Resource<Table>) -> Result<()>719 async fn drop(&mut self, rep: Resource<Table>) -> Result<()> {
720 self.delete(rep)?;
721 Ok(())
722 }
723 }
724
725 impl wit::HostWasmFunc for ResourceTable {
params( &mut self, self_: Resource<Func>, d: Resource<Debuggee>, ) -> Result<Vec<wit::WasmType>>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
results( &mut self, self_: Resource<Func>, d: Resource<Debuggee>, ) -> Result<Vec<wit::WasmType>>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
clone(&mut self, self_: Resource<Func>) -> Result<Resource<Func>>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
drop(&mut self, rep: Resource<Func>) -> Result<()>751 async fn drop(&mut self, rep: Resource<Func>) -> Result<()> {
752 self.delete(rep)?;
753 Ok(())
754 }
755 }
756
757 impl wit::HostWasmException for ResourceTable {
get_tag( &mut self, self_: Resource<WasmException>, d: Resource<Debuggee>, ) -> Result<Resource<Tag>>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
get_values( &mut self, self_: Resource<WasmException>, d: Resource<Debuggee>, ) -> Result<Vec<Resource<WasmValue>>>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
clone( &mut self, self_: Resource<WasmException>, _d: Resource<Debuggee>, ) -> Result<Resource<WasmException>>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
make( &mut self, d: Resource<Debuggee>, tag: Resource<Tag>, values: Vec<Resource<WasmValue>>, ) -> Result<Resource<WasmException>>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
drop(&mut self, rep: Resource<WasmException>) -> Result<()>809 async fn drop(&mut self, rep: Resource<WasmException>) -> Result<()> {
810 self.delete(rep)?;
811 Ok(())
812 }
813 }
814
815 impl wit::HostWasmTag for ResourceTable {
params( &mut self, self_: Resource<Tag>, d: Resource<Debuggee>, ) -> Result<Vec<wit::WasmType>>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
unique_id(&mut self, self_: Resource<Tag>) -> Result<u64>826 async fn unique_id(&mut self, self_: Resource<Tag>) -> Result<u64> {
827 Ok(self.get(&self_)?.debug_index_in_store())
828 }
829
clone(&mut self, self_: Resource<Tag>) -> Result<Resource<Tag>>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
make( &mut self, d: Resource<Debuggee>, params: Vec<wit::WasmType>, ) -> Result<Resource<Tag>>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
drop(&mut self, rep: Resource<Tag>) -> Result<()>847 async fn drop(&mut self, rep: Resource<Tag>) -> Result<()> {
848 self.delete(rep)?;
849 Ok(())
850 }
851 }
852
853 impl wit::HostFrame for ResourceTable {
get_instance( &mut self, self_: Resource<Frame>, d: Resource<Debuggee>, ) -> Result<Resource<Instance>>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
get_func_index( &mut self, self_: Resource<Frame>, d: Resource<Debuggee>, ) -> Result<u32>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
get_pc(&mut self, self_: Resource<Frame>, d: Resource<Debuggee>) -> Result<u32>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
get_locals( &mut self, self_: Resource<Frame>, d: Resource<Debuggee>, ) -> Result<Vec<Resource<WasmValue>>>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
get_stack( &mut self, self_: Resource<Frame>, d: Resource<Debuggee>, ) -> Result<Vec<Resource<WasmValue>>>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
parent_frame( &mut self, self_: Resource<Frame>, d: Resource<Debuggee>, ) -> Result<Option<Resource<Frame>>>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
drop(&mut self, rep: Resource<Frame>) -> Result<()>927 async fn drop(&mut self, rep: Resource<Frame>) -> Result<()> {
928 self.delete(rep)?;
929 Ok(())
930 }
931 }
932
933 impl wit::HostWasmValue for ResourceTable {
get_type(&mut self, self_: Resource<WasmValue>) -> Result<wit::WasmType>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
unwrap_i32(&mut self, self_: Resource<WasmValue>) -> Result<u32>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
unwrap_i64(&mut self, self_: Resource<WasmValue>) -> Result<u64>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
unwrap_f32(&mut self, self_: Resource<WasmValue>) -> Result<f32>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
unwrap_f64(&mut self, self_: Resource<WasmValue>) -> Result<f64>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
unwrap_v128(&mut self, self_: Resource<WasmValue>) -> Result<Vec<u8>>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
unwrap_func(&mut self, self_: Resource<WasmValue>) -> Result<Option<Resource<Func>>>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
unwrap_exception( &mut self, self_: Resource<WasmValue>, ) -> Result<Option<Resource<WasmException>>>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
make_i32(&mut self, value: u32) -> Result<Resource<WasmValue>>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
make_i64(&mut self, value: u64) -> Result<Resource<WasmValue>>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
make_f32(&mut self, value: f32) -> Result<Resource<WasmValue>>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
make_f64(&mut self, value: f64) -> Result<Resource<WasmValue>>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
make_v128(&mut self, value: Vec<u8>) -> Result<Resource<WasmValue>>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
clone(&mut self, self_: Resource<WasmValue>) -> Result<Resource<WasmValue>>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
drop(&mut self, rep: Resource<WasmValue>) -> Result<()>1045 async fn drop(&mut self, rep: Resource<WasmValue>) -> Result<()> {
1046 self.delete(rep)?;
1047 Ok(())
1048 }
1049 }
1050
1051 impl wit::Host for ResourceTable {
convert_error(&mut self, err: wasmtime::Error) -> Result<wit::Error>1052 fn convert_error(&mut self, err: wasmtime::Error) -> Result<wit::Error> {
1053 err.downcast()
1054 }
1055 }
1056