1 //! Host implementation for the debugger world. 2 3 use wasmtime::{ 4 Result, 5 component::{Resource, ResourceTable}, 6 }; 7 8 mod api; 9 mod bindings; 10 mod opaque; 11 12 pub use api::Debuggee; 13 pub use bindings::DebugMain as DebuggerComponent; 14 pub use bindings::bytecodealliance::wasmtime::debuggee as wit; 15 use opaque::OpaqueDebugger; 16 17 /// Register a debuggee in a resource table. 18 pub fn add_debuggee<T: Send + 'static>( 19 table: &mut ResourceTable, 20 debuggee: crate::Debuggee<T>, 21 ) -> Result<Resource<Debuggee>> { 22 let engine = debuggee.engine().clone(); 23 let interrupt_pending = debuggee.interrupt_pending().clone(); 24 let inner: Option<Box<dyn OpaqueDebugger + Send + 'static>> = Some(Box::new(debuggee)); 25 Ok(table.push(Debuggee { 26 inner, 27 engine, 28 interrupt_pending, 29 })?) 30 } 31 32 impl bindings::DebugMainImports for ResourceTable { 33 async fn print_debugger_info(&mut self, message: String) -> wasmtime::Result<()> { 34 eprintln!("Debugger: {message}"); 35 Ok(()) 36 } 37 } 38 39 /// Add the debugger world's host functions to a [`wasmtime::component::Linker`]. 40 pub fn add_to_linker<T: Send + 'static>( 41 linker: &mut wasmtime::component::Linker<T>, 42 f: fn(&mut T) -> &mut ResourceTable, 43 ) -> wasmtime::Result<()> { 44 wit::add_to_linker::<_, wasmtime::component::HasSelf<ResourceTable>>(linker, f)?; 45 bindings::DebugMain::add_to_linker_imports::<_, wasmtime::component::HasSelf<ResourceTable>>( 46 linker, f, 47 )?; 48 Ok(()) 49 } 50