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