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