1 //! A type-erased trait wrapping the `Debugger<T>` to permit its use
2 //! within a resource.
3 
4 use crate::host::wit;
5 use crate::host::{api::WasmValue, bindings::val_type_to_wasm_type};
6 use wasmtime::{
7     Engine, ExnRef, ExnRefPre, ExnType, FrameHandle, Func, FuncType, Global, Instance, Memory,
8     Module, OwnedRooted, Result, Table, Tag, TagType, Val, ValType,
9 };
10 
11 /// Type-erased interface to the `Debugger<T>` implementing all
12 /// functionality necessary for the interfaces here. This needs to be
13 /// type-erased because the host-side resource APIs do not support
14 /// type-parameterized resource kinds -- e.g., we cannot have a
15 /// resource for a `Debugger<T>`, only a `Debugger`, so the debuggee
16 /// resource essentially needs to carry a vtable for the kind of store
17 /// the debuggee has.
18 ///
19 /// Methods here return `wasmtime::Result<T>`, where `Err` may wrap
20 /// either a `wit::Error` (which `convert_error` will extract and
21 /// return as an in-band WIT-level error to the component) or any
22 /// other error (which becomes a trap).
23 ///
24 /// These methods do not handle the "wrong state" errors (i.e.,
25 /// execution is continuing so we cannot query store state): those are
26 /// handled one level up, via moving ownership of the instance of this
27 /// trait between the execution future and the debuggee resource
28 /// itself.
29 #[async_trait::async_trait]
30 pub(crate) trait OpaqueDebugger {
all_instances(&mut self) -> Result<Vec<Instance>>31     async fn all_instances(&mut self) -> Result<Vec<Instance>>;
all_modules(&mut self) -> Result<Vec<Module>>32     async fn all_modules(&mut self) -> Result<Vec<Module>>;
handle_resumption(&mut self, resumption: &wit::ResumptionValue) -> Result<()>33     async fn handle_resumption(&mut self, resumption: &wit::ResumptionValue) -> Result<()>;
single_step(&mut self) -> Result<crate::DebugRunResult>34     async fn single_step(&mut self) -> Result<crate::DebugRunResult>;
continue_(&mut self) -> Result<crate::DebugRunResult>35     async fn continue_(&mut self) -> Result<crate::DebugRunResult>;
exit_frames(&mut self) -> Result<Vec<FrameHandle>>36     async fn exit_frames(&mut self) -> Result<Vec<FrameHandle>>;
get_instance_module(&mut self, instance: Instance) -> Result<Module>37     async fn get_instance_module(&mut self, instance: Instance) -> Result<Module>;
38 
instance_get_memory(&mut self, instance: Instance, idx: u32) -> Result<Option<Memory>>39     async fn instance_get_memory(&mut self, instance: Instance, idx: u32)
40     -> Result<Option<Memory>>;
instance_get_global(&mut self, instance: Instance, idx: u32) -> Result<Option<Global>>41     async fn instance_get_global(&mut self, instance: Instance, idx: u32)
42     -> Result<Option<Global>>;
instance_get_table(&mut self, instance: Instance, idx: u32) -> Result<Option<Table>>43     async fn instance_get_table(&mut self, instance: Instance, idx: u32) -> Result<Option<Table>>;
instance_get_func(&mut self, instance: Instance, idx: u32) -> Result<Option<Func>>44     async fn instance_get_func(&mut self, instance: Instance, idx: u32) -> Result<Option<Func>>;
instance_get_tag(&mut self, instance: Instance, idx: u32) -> Result<Option<Tag>>45     async fn instance_get_tag(&mut self, instance: Instance, idx: u32) -> Result<Option<Tag>>;
46 
memory_size_bytes(&mut self, memory: Memory) -> Result<u64>47     async fn memory_size_bytes(&mut self, memory: Memory) -> Result<u64>;
memory_page_size(&mut self, memory: Memory) -> Result<u64>48     async fn memory_page_size(&mut self, memory: Memory) -> Result<u64>;
memory_grow(&mut self, memory: Memory, delta_bytes: u64) -> Result<u64>49     async fn memory_grow(&mut self, memory: Memory, delta_bytes: u64) -> Result<u64>;
memory_read_bytes( &mut self, memory: Memory, addr: u64, len: u64, ) -> Result<Option<Vec<u8>>>50     async fn memory_read_bytes(
51         &mut self,
52         memory: Memory,
53         addr: u64,
54         len: u64,
55     ) -> Result<Option<Vec<u8>>>;
memory_write_bytes( &mut self, memory: Memory, addr: u64, bytes: Vec<u8>, ) -> Result<Option<()>>56     async fn memory_write_bytes(
57         &mut self,
58         memory: Memory,
59         addr: u64,
60         bytes: Vec<u8>,
61     ) -> Result<Option<()>>;
memory_read_u8(&mut self, memory: Memory, addr: u64) -> Result<Option<u8>>62     async fn memory_read_u8(&mut self, memory: Memory, addr: u64) -> Result<Option<u8>>;
memory_read_u16(&mut self, memory: Memory, addr: u64) -> Result<Option<u16>>63     async fn memory_read_u16(&mut self, memory: Memory, addr: u64) -> Result<Option<u16>>;
memory_read_u32(&mut self, memory: Memory, addr: u64) -> Result<Option<u32>>64     async fn memory_read_u32(&mut self, memory: Memory, addr: u64) -> Result<Option<u32>>;
memory_read_u64(&mut self, memory: Memory, addr: u64) -> Result<Option<u64>>65     async fn memory_read_u64(&mut self, memory: Memory, addr: u64) -> Result<Option<u64>>;
memory_write_u8(&mut self, memory: Memory, addr: u64, data: u8) -> Result<Option<()>>66     async fn memory_write_u8(&mut self, memory: Memory, addr: u64, data: u8) -> Result<Option<()>>;
memory_write_u16( &mut self, memory: Memory, addr: u64, data: u16, ) -> Result<Option<()>>67     async fn memory_write_u16(
68         &mut self,
69         memory: Memory,
70         addr: u64,
71         data: u16,
72     ) -> Result<Option<()>>;
memory_write_u32( &mut self, memory: Memory, addr: u64, data: u32, ) -> Result<Option<()>>73     async fn memory_write_u32(
74         &mut self,
75         memory: Memory,
76         addr: u64,
77         data: u32,
78     ) -> Result<Option<()>>;
memory_write_u64( &mut self, memory: Memory, addr: u64, data: u64, ) -> Result<Option<()>>79     async fn memory_write_u64(
80         &mut self,
81         memory: Memory,
82         addr: u64,
83         data: u64,
84     ) -> Result<Option<()>>;
85 
global_get(&mut self, global: Global) -> Result<WasmValue>86     async fn global_get(&mut self, global: Global) -> Result<WasmValue>;
global_set(&mut self, global: Global, val: WasmValue) -> Result<()>87     async fn global_set(&mut self, global: Global, val: WasmValue) -> Result<()>;
88 
table_len(&mut self, table: Table) -> Result<u64>89     async fn table_len(&mut self, table: Table) -> Result<u64>;
table_get_element(&mut self, table: Table, index: u64) -> Result<WasmValue>90     async fn table_get_element(&mut self, table: Table, index: u64) -> Result<WasmValue>;
table_set_element(&mut self, table: Table, index: u64, val: WasmValue) -> Result<()>91     async fn table_set_element(&mut self, table: Table, index: u64, val: WasmValue) -> Result<()>;
92 
func_params(&mut self, func: Func) -> Result<Vec<wit::WasmType>>93     async fn func_params(&mut self, func: Func) -> Result<Vec<wit::WasmType>>;
func_results(&mut self, func: Func) -> Result<Vec<wit::WasmType>>94     async fn func_results(&mut self, func: Func) -> Result<Vec<wit::WasmType>>;
95 
tag_params(&mut self, tag: Tag) -> Result<Vec<wit::WasmType>>96     async fn tag_params(&mut self, tag: Tag) -> Result<Vec<wit::WasmType>>;
tag_new(&mut self, engine: Engine, params: Vec<ValType>) -> Result<Tag>97     async fn tag_new(&mut self, engine: Engine, params: Vec<ValType>) -> Result<Tag>;
98 
exnref_get_tag(&mut self, exn: OwnedRooted<ExnRef>) -> Result<Tag>99     async fn exnref_get_tag(&mut self, exn: OwnedRooted<ExnRef>) -> Result<Tag>;
exnref_get_fields(&mut self, exn: OwnedRooted<ExnRef>) -> Result<Vec<WasmValue>>100     async fn exnref_get_fields(&mut self, exn: OwnedRooted<ExnRef>) -> Result<Vec<WasmValue>>;
exnref_new(&mut self, tag: Tag, fields: Vec<WasmValue>) -> Result<OwnedRooted<ExnRef>>101     async fn exnref_new(&mut self, tag: Tag, fields: Vec<WasmValue>)
102     -> Result<OwnedRooted<ExnRef>>;
103 
frame_instance(&mut self, frame: FrameHandle) -> Result<Instance>104     async fn frame_instance(&mut self, frame: FrameHandle) -> Result<Instance>;
frame_func_and_pc(&mut self, frame: FrameHandle) -> Result<(u32, u32)>105     async fn frame_func_and_pc(&mut self, frame: FrameHandle) -> Result<(u32, u32)>;
frame_locals(&mut self, frame: FrameHandle) -> Result<Vec<WasmValue>>106     async fn frame_locals(&mut self, frame: FrameHandle) -> Result<Vec<WasmValue>>;
frame_stack(&mut self, frame: FrameHandle) -> Result<Vec<WasmValue>>107     async fn frame_stack(&mut self, frame: FrameHandle) -> Result<Vec<WasmValue>>;
frame_parent(&mut self, frame: FrameHandle) -> Result<Option<FrameHandle>>108     async fn frame_parent(&mut self, frame: FrameHandle) -> Result<Option<FrameHandle>>;
109 
module_add_breakpoint(&mut self, module: Module, pc: u32) -> Result<()>110     async fn module_add_breakpoint(&mut self, module: Module, pc: u32) -> Result<()>;
module_remove_breakpoint(&mut self, module: Module, pc: u32) -> Result<()>111     async fn module_remove_breakpoint(&mut self, module: Module, pc: u32) -> Result<()>;
112 
finish(&mut self) -> Result<()>113     async fn finish(&mut self) -> Result<()>;
114 }
115 
116 #[async_trait::async_trait]
117 impl<T: Send + 'static> OpaqueDebugger for crate::Debuggee<T> {
all_instances(&mut self) -> Result<Vec<Instance>>118     async fn all_instances(&mut self) -> Result<Vec<Instance>> {
119         self.with_store(|store| store.debug_all_instances()).await
120     }
121 
all_modules(&mut self) -> Result<Vec<Module>>122     async fn all_modules(&mut self) -> Result<Vec<Module>> {
123         self.with_store(|store| store.debug_all_modules()).await
124     }
125 
single_step(&mut self) -> Result<crate::DebugRunResult>126     async fn single_step(&mut self) -> Result<crate::DebugRunResult> {
127         self.with_store(|store| store.edit_breakpoints().unwrap().single_step(true).unwrap())
128             .await?;
129 
130         self.run().await
131     }
132 
continue_(&mut self) -> Result<crate::DebugRunResult>133     async fn continue_(&mut self) -> Result<crate::DebugRunResult> {
134         self.with_store(|store| {
135             store
136                 .edit_breakpoints()
137                 .unwrap()
138                 .single_step(false)
139                 .unwrap()
140         })
141         .await?;
142 
143         self.run().await
144     }
145 
handle_resumption(&mut self, resumption: &wit::ResumptionValue) -> Result<()>146     async fn handle_resumption(&mut self, resumption: &wit::ResumptionValue) -> Result<()> {
147         match resumption {
148             wit::ResumptionValue::Normal => {}
149             _ => {
150                 unimplemented!("Non-`Normal` resumption not yet supported");
151             }
152         }
153         Ok(())
154     }
155 
exit_frames(&mut self) -> Result<Vec<FrameHandle>>156     async fn exit_frames(&mut self) -> Result<Vec<FrameHandle>> {
157         self.with_store(|mut store| store.debug_exit_frames().collect::<Vec<_>>())
158             .await
159     }
160 
get_instance_module(&mut self, instance: Instance) -> Result<Module>161     async fn get_instance_module(&mut self, instance: Instance) -> Result<Module> {
162         self.with_store(move |store| instance.module(&store).clone())
163             .await
164     }
165 
instance_get_memory( &mut self, instance: Instance, idx: u32, ) -> Result<Option<Memory>>166     async fn instance_get_memory(
167         &mut self,
168         instance: Instance,
169         idx: u32,
170     ) -> Result<Option<Memory>> {
171         self.with_store(move |mut store| instance.debug_memory(&mut store, idx))
172             .await
173     }
174 
instance_get_global( &mut self, instance: Instance, idx: u32, ) -> Result<Option<Global>>175     async fn instance_get_global(
176         &mut self,
177         instance: Instance,
178         idx: u32,
179     ) -> Result<Option<Global>> {
180         self.with_store(move |mut store| instance.debug_global(&mut store, idx))
181             .await
182     }
183 
instance_get_table(&mut self, instance: Instance, idx: u32) -> Result<Option<Table>>184     async fn instance_get_table(&mut self, instance: Instance, idx: u32) -> Result<Option<Table>> {
185         self.with_store(move |mut store| instance.debug_table(&mut store, idx))
186             .await
187     }
188 
instance_get_func(&mut self, instance: Instance, idx: u32) -> Result<Option<Func>>189     async fn instance_get_func(&mut self, instance: Instance, idx: u32) -> Result<Option<Func>> {
190         self.with_store(move |mut store| instance.debug_function(&mut store, idx))
191             .await
192     }
193 
instance_get_tag(&mut self, instance: Instance, idx: u32) -> Result<Option<Tag>>194     async fn instance_get_tag(&mut self, instance: Instance, idx: u32) -> Result<Option<Tag>> {
195         self.with_store(move |mut store| instance.debug_tag(&mut store, idx))
196             .await
197     }
198 
memory_size_bytes(&mut self, memory: Memory) -> Result<u64>199     async fn memory_size_bytes(&mut self, memory: Memory) -> Result<u64> {
200         self.with_store(move |store| u64::try_from(memory.data_size(&store)).unwrap())
201             .await
202     }
203 
memory_page_size(&mut self, memory: Memory) -> Result<u64>204     async fn memory_page_size(&mut self, memory: Memory) -> Result<u64> {
205         self.with_store(move |store| memory.page_size(&store)).await
206     }
207 
memory_grow(&mut self, memory: Memory, delta_bytes: u64) -> Result<u64>208     async fn memory_grow(&mut self, memory: Memory, delta_bytes: u64) -> Result<u64> {
209         self.with_store(move |mut store| -> Result<u64> {
210             let page_size = memory.page_size(&store);
211             if delta_bytes & (page_size - 1) != 0 {
212                 return Err(wit::Error::MemoryGrowFailure.into());
213             }
214             let delta_pages = delta_bytes / page_size;
215             let old_pages = memory
216                 .grow(&mut store, delta_pages)
217                 .map_err(|_| wit::Error::MemoryGrowFailure)?;
218             Ok(old_pages * page_size)
219         })
220         .await?
221     }
222 
memory_read_bytes( &mut self, memory: Memory, addr: u64, len: u64, ) -> Result<Option<Vec<u8>>>223     async fn memory_read_bytes(
224         &mut self,
225         memory: Memory,
226         addr: u64,
227         len: u64,
228     ) -> Result<Option<Vec<u8>>> {
229         self.with_store(move |store| {
230             let data = memory.data(&store);
231             let addr = usize::try_from(addr).unwrap();
232             let len = usize::try_from(len).unwrap();
233             data.get(addr..addr + len).map(|s| s.to_vec())
234         })
235         .await
236     }
237 
memory_write_bytes( &mut self, memory: Memory, addr: u64, bytes: Vec<u8>, ) -> Result<Option<()>>238     async fn memory_write_bytes(
239         &mut self,
240         memory: Memory,
241         addr: u64,
242         bytes: Vec<u8>,
243     ) -> Result<Option<()>> {
244         self.with_store(move |mut store| {
245             let data = memory.data_mut(&mut store);
246             let addr = usize::try_from(addr).unwrap();
247             let dest = data.get_mut(addr..addr + bytes.len())?;
248             dest.copy_from_slice(&bytes);
249             Some(())
250         })
251         .await
252     }
253 
memory_read_u8(&mut self, memory: Memory, addr: u64) -> Result<Option<u8>>254     async fn memory_read_u8(&mut self, memory: Memory, addr: u64) -> Result<Option<u8>> {
255         self.with_store(move |store| {
256             let data = memory.data(&store);
257             let addr = usize::try_from(addr).unwrap();
258             Some(*data.get(addr)?)
259         })
260         .await
261     }
262 
memory_read_u16(&mut self, memory: Memory, addr: u64) -> Result<Option<u16>>263     async fn memory_read_u16(&mut self, memory: Memory, addr: u64) -> Result<Option<u16>> {
264         self.with_store(move |store| {
265             let data = memory.data(&store);
266             let addr = usize::try_from(addr).unwrap();
267             Some(u16::from_le_bytes([*data.get(addr)?, *data.get(addr + 1)?]))
268         })
269         .await
270     }
271 
memory_read_u32(&mut self, memory: Memory, addr: u64) -> Result<Option<u32>>272     async fn memory_read_u32(&mut self, memory: Memory, addr: u64) -> Result<Option<u32>> {
273         self.with_store(move |store| {
274             let data = memory.data(&store);
275             let addr = usize::try_from(addr).unwrap();
276             Some(u32::from_le_bytes([
277                 *data.get(addr)?,
278                 *data.get(addr + 1)?,
279                 *data.get(addr + 2)?,
280                 *data.get(addr + 3)?,
281             ]))
282         })
283         .await
284     }
285 
memory_read_u64(&mut self, memory: Memory, addr: u64) -> Result<Option<u64>>286     async fn memory_read_u64(&mut self, memory: Memory, addr: u64) -> Result<Option<u64>> {
287         self.with_store(move |store| {
288             let data = memory.data(&store);
289             let addr = usize::try_from(addr).unwrap();
290             Some(u64::from_le_bytes([
291                 *data.get(addr)?,
292                 *data.get(addr + 1)?,
293                 *data.get(addr + 2)?,
294                 *data.get(addr + 3)?,
295                 *data.get(addr + 4)?,
296                 *data.get(addr + 5)?,
297                 *data.get(addr + 6)?,
298                 *data.get(addr + 7)?,
299             ]))
300         })
301         .await
302     }
303 
memory_write_u8( &mut self, memory: Memory, addr: u64, value: u8, ) -> Result<Option<()>>304     async fn memory_write_u8(
305         &mut self,
306         memory: Memory,
307         addr: u64,
308         value: u8,
309     ) -> Result<Option<()>> {
310         self.with_store(move |mut store| {
311             let data = memory.data_mut(&mut store);
312             let addr = usize::try_from(addr).unwrap();
313             *data.get_mut(addr)? = value;
314             Some(())
315         })
316         .await
317     }
318 
memory_write_u16( &mut self, memory: Memory, addr: u64, value: u16, ) -> Result<Option<()>>319     async fn memory_write_u16(
320         &mut self,
321         memory: Memory,
322         addr: u64,
323         value: u16,
324     ) -> Result<Option<()>> {
325         self.with_store(move |mut store| {
326             let data = memory.data_mut(&mut store);
327             let addr = usize::try_from(addr).unwrap();
328             data.get_mut(addr..(addr + 2))?
329                 .copy_from_slice(&value.to_le_bytes());
330             Some(())
331         })
332         .await
333     }
334 
memory_write_u32( &mut self, memory: Memory, addr: u64, value: u32, ) -> Result<Option<()>>335     async fn memory_write_u32(
336         &mut self,
337         memory: Memory,
338         addr: u64,
339         value: u32,
340     ) -> Result<Option<()>> {
341         self.with_store(move |mut store| {
342             let data = memory.data_mut(&mut store);
343             let addr = usize::try_from(addr).unwrap();
344             data.get_mut(addr..(addr + 4))?
345                 .copy_from_slice(&value.to_le_bytes());
346             Some(())
347         })
348         .await
349     }
350 
memory_write_u64( &mut self, memory: Memory, addr: u64, value: u64, ) -> Result<Option<()>>351     async fn memory_write_u64(
352         &mut self,
353         memory: Memory,
354         addr: u64,
355         value: u64,
356     ) -> Result<Option<()>> {
357         self.with_store(move |mut store| {
358             let data = memory.data_mut(&mut store);
359             let addr = usize::try_from(addr).unwrap();
360             data.get_mut(addr..(addr + 8))?
361                 .copy_from_slice(&value.to_le_bytes());
362             Some(())
363         })
364         .await
365     }
366 
global_get(&mut self, global: Global) -> Result<WasmValue>367     async fn global_get(&mut self, global: Global) -> Result<WasmValue> {
368         self.with_store(move |mut store| {
369             let val = global.get(&mut store);
370             WasmValue::new(&mut store, val)
371         })
372         .await?
373     }
374 
global_set(&mut self, global: Global, val: WasmValue) -> Result<()>375     async fn global_set(&mut self, global: Global, val: WasmValue) -> Result<()> {
376         self.with_store(move |mut store| -> Result<()> {
377             let v = val.into_val(&mut store);
378             global
379                 .set(&mut store, v)
380                 .map_err(|_| wit::Error::MismatchedType)?;
381             Ok(())
382         })
383         .await?
384     }
385 
table_len(&mut self, table: Table) -> Result<u64>386     async fn table_len(&mut self, table: Table) -> Result<u64> {
387         self.with_store(move |store| table.size(&store)).await
388     }
389 
table_get_element(&mut self, table: Table, index: u64) -> Result<WasmValue>390     async fn table_get_element(&mut self, table: Table, index: u64) -> Result<WasmValue> {
391         self.with_store(move |mut store| -> Result<WasmValue> {
392             let val = table
393                 .get(&mut store, index)
394                 .ok_or(wit::Error::OutOfBounds)?;
395             WasmValue::new(&mut store, val.into())
396         })
397         .await?
398     }
399 
table_set_element(&mut self, table: Table, index: u64, val: WasmValue) -> Result<()>400     async fn table_set_element(&mut self, table: Table, index: u64, val: WasmValue) -> Result<()> {
401         self.with_store(move |mut store| -> Result<()> {
402             let v = val.into_val(&mut store);
403             let r = v.ref_().ok_or(wit::Error::MismatchedType)?;
404             table
405                 .set(&mut store, index, r)
406                 .map_err(|_| wit::Error::MismatchedType)?;
407             Ok(())
408         })
409         .await?
410     }
411 
func_params(&mut self, func: Func) -> Result<Vec<wit::WasmType>>412     async fn func_params(&mut self, func: Func) -> Result<Vec<wit::WasmType>> {
413         self.with_store(move |store| {
414             let ty = func.ty(&store);
415             ty.params()
416                 .map(|ty| val_type_to_wasm_type(&ty))
417                 .collect::<Result<Vec<_>>>()
418         })
419         .await?
420     }
421 
func_results(&mut self, func: Func) -> Result<Vec<wit::WasmType>>422     async fn func_results(&mut self, func: Func) -> Result<Vec<wit::WasmType>> {
423         self.with_store(move |store| {
424             let ty = func.ty(&store);
425             ty.results()
426                 .map(|ty| val_type_to_wasm_type(&ty))
427                 .collect::<Result<Vec<_>>>()
428         })
429         .await?
430     }
431 
tag_params(&mut self, tag: Tag) -> Result<Vec<wit::WasmType>>432     async fn tag_params(&mut self, tag: Tag) -> Result<Vec<wit::WasmType>> {
433         self.with_store(move |store| {
434             let ty = tag.ty(&store);
435             ty.ty()
436                 .params()
437                 .map(|ty| val_type_to_wasm_type(&ty))
438                 .collect::<Result<Vec<_>>>()
439         })
440         .await?
441     }
442 
tag_new(&mut self, engine: Engine, params: Vec<ValType>) -> Result<Tag>443     async fn tag_new(&mut self, engine: Engine, params: Vec<ValType>) -> Result<Tag> {
444         self.with_store(move |mut store| {
445             let func_ty = FuncType::new(&engine, params, []);
446             let tag_ty = TagType::new(func_ty);
447             Tag::new(&mut store, &tag_ty)
448         })
449         .await?
450     }
451 
exnref_get_tag(&mut self, exn: OwnedRooted<ExnRef>) -> Result<Tag>452     async fn exnref_get_tag(&mut self, exn: OwnedRooted<ExnRef>) -> Result<Tag> {
453         self.with_store(move |mut store| exn.tag(&mut store).expect("reference must be rooted"))
454             .await
455     }
456 
exnref_get_fields(&mut self, exn: OwnedRooted<ExnRef>) -> Result<Vec<WasmValue>>457     async fn exnref_get_fields(&mut self, exn: OwnedRooted<ExnRef>) -> Result<Vec<WasmValue>> {
458         self.with_store(move |mut store| {
459             let fields = exn
460                 .fields(&mut store)
461                 .expect("reference must be rooted")
462                 .collect::<Vec<Val>>();
463             fields
464                 .into_iter()
465                 .map(|v| WasmValue::new(&mut store, v))
466                 .collect::<Result<Vec<_>>>()
467         })
468         .await?
469     }
470 
exnref_new( &mut self, tag: Tag, fields: Vec<WasmValue>, ) -> Result<OwnedRooted<ExnRef>>471     async fn exnref_new(
472         &mut self,
473         tag: Tag,
474         fields: Vec<WasmValue>,
475     ) -> Result<OwnedRooted<ExnRef>> {
476         self.with_store(move |mut store| -> Result<OwnedRooted<ExnRef>> {
477             let exn_ty =
478                 ExnType::from_tag_type(&tag.ty(&store)).expect("tag type is already validated");
479             let allocator = ExnRefPre::new(&mut store, exn_ty);
480             let field_vals = fields
481                 .into_iter()
482                 .map(|v| v.into_val(&mut store))
483                 .collect::<Vec<_>>();
484             let exn = ExnRef::new(&mut store, &allocator, &tag, &field_vals)
485                 .map_err(|_| wit::Error::AllocFailure)?;
486             Ok(exn.to_owned_rooted(&mut store).unwrap())
487         })
488         .await?
489     }
490 
frame_instance(&mut self, frame: FrameHandle) -> Result<Instance>491     async fn frame_instance(&mut self, frame: FrameHandle) -> Result<Instance> {
492         self.with_store(move |mut store| -> Result<Instance> {
493             Ok(frame
494                 .instance(&mut store)
495                 .map_err(|_| wit::Error::InvalidFrame)?)
496         })
497         .await?
498     }
499 
frame_func_and_pc(&mut self, frame: FrameHandle) -> Result<(u32, u32)>500     async fn frame_func_and_pc(&mut self, frame: FrameHandle) -> Result<(u32, u32)> {
501         self.with_store(move |mut store| -> Result<(u32, u32)> {
502             let (func, pc) = frame
503                 .wasm_function_index_and_pc(&mut store)
504                 .map_err(|_| wit::Error::InvalidFrame)?
505                 .ok_or(wit::Error::NonWasmFrame)?;
506             Ok((func.as_u32(), pc.raw()))
507         })
508         .await?
509     }
510 
frame_locals(&mut self, frame: FrameHandle) -> Result<Vec<WasmValue>>511     async fn frame_locals(&mut self, frame: FrameHandle) -> Result<Vec<WasmValue>> {
512         self.with_store(move |mut store| -> Result<Vec<WasmValue>> {
513             let n_locals = frame
514                 .num_locals(&mut store)
515                 .map_err(|_| wit::Error::InvalidFrame)?;
516             let mut result = vec![];
517             for i in 0..n_locals {
518                 let val = frame
519                     .local(&mut store, i)
520                     .expect("checked for validity above");
521                 result.push(WasmValue::new(&mut store, val)?);
522             }
523             Ok(result)
524         })
525         .await?
526     }
527 
frame_stack(&mut self, frame: FrameHandle) -> Result<Vec<WasmValue>>528     async fn frame_stack(&mut self, frame: FrameHandle) -> Result<Vec<WasmValue>> {
529         self.with_store(move |mut store| -> Result<Vec<WasmValue>> {
530             let n_stacks = frame
531                 .num_stacks(&mut store)
532                 .map_err(|_| wit::Error::InvalidFrame)?;
533             let mut result = vec![];
534             for i in 0..n_stacks {
535                 let val = frame
536                     .stack(&mut store, i)
537                     .expect("checked for validity above");
538                 result.push(WasmValue::new(&mut store, val)?);
539             }
540             Ok(result)
541         })
542         .await?
543     }
544 
frame_parent(&mut self, frame: FrameHandle) -> Result<Option<FrameHandle>>545     async fn frame_parent(&mut self, frame: FrameHandle) -> Result<Option<FrameHandle>> {
546         self.with_store(move |mut store| -> Result<Option<FrameHandle>> {
547             Ok(frame
548                 .parent(&mut store)
549                 .map_err(|_| wit::Error::InvalidFrame)?)
550         })
551         .await?
552     }
553 
module_add_breakpoint(&mut self, module: Module, pc: u32) -> Result<()>554     async fn module_add_breakpoint(&mut self, module: Module, pc: u32) -> Result<()> {
555         self.with_store(move |store| -> Result<()> {
556             store
557                 .edit_breakpoints()
558                 .expect("guest debugging is enabled")
559                 .add_breakpoint(&module, wasmtime::ModulePC::new(pc))
560                 .map_err(|_| wit::Error::InvalidPc)?;
561             Ok(())
562         })
563         .await?
564     }
565 
module_remove_breakpoint(&mut self, module: Module, pc: u32) -> Result<()>566     async fn module_remove_breakpoint(&mut self, module: Module, pc: u32) -> Result<()> {
567         self.with_store(move |store| -> Result<()> {
568             store
569                 .edit_breakpoints()
570                 .expect("guest debugging is enabled")
571                 .remove_breakpoint(&module, wasmtime::ModulePC::new(pc))
572                 .map_err(|_| wit::Error::InvalidPc)?;
573             Ok(())
574         })
575         .await?
576     }
577 
finish(&mut self) -> Result<()>578     async fn finish(&mut self) -> Result<()> {
579         self.finish().await?;
580         Ok(())
581     }
582 }
583