diff --git a/src/langserver/debugger/auxtools.rs b/src/langserver/debugger/auxtools.rs index a3fad8ba..c6825fad 100644 --- a/src/langserver/debugger/auxtools.rs +++ b/src/langserver/debugger/auxtools.rs @@ -146,6 +146,46 @@ impl Auxtools { self.stream = StreamState::Disconnected; } + pub fn configured(&mut self) -> Result<(), Box> { + debug_output!(in self.seq, "[auxtools] configured"); + self.send_or_disconnect(Request::Configured)?; + + match self.read_response_or_disconnect()? { + Response::Ack { .. } => Ok(()), + response => Err(Box::new(UnexpectedResponse::new("Ack", response))), + } + } + + pub fn get_stddef(&mut self) -> Result, Box> { + self.send_or_disconnect(Request::StdDef)?; + + match self.read_response_or_disconnect()? { + Response::StdDef(contents) => Ok(contents), + response => Err(Box::new(UnexpectedResponse::new("StdDef", response))), + } + } + + pub fn disassemble(&mut self, path: &str, override_id: u32) -> Result> { + self.send_or_disconnect(Request::Disassemble(ProcRef { + path: path.to_owned(), + override_id, + }))?; + + match self.read_response_or_disconnect()? { + Response::Disassemble(res) => Ok(res), + response => Err(Box::new(UnexpectedResponse::new("Disassemble", response))), + } + } + + pub fn get_current_proc(&mut self, frame_id: u32) -> Result, Box> { + self.send_or_disconnect(Request::CurrentInstruction { frame_id })?; + + match self.read_response_or_disconnect()? { + Response::CurrentInstruction(ins) => Ok(ins.map(|x| (x.proc.path, x.proc.override_id))), + response => Err(Box::new(UnexpectedResponse::new("CurrentInstruction", response))), + } + } + pub fn get_line_number(&mut self, path: &str, override_id: u32, offset: u32) -> Result, Box> { self.send_or_disconnect(Request::LineNumber { proc: ProcRef { diff --git a/src/langserver/debugger/auxtools_types.rs b/src/langserver/debugger/auxtools_types.rs index f01ed3ad..5ba985c6 100644 --- a/src/langserver/debugger/auxtools_types.rs +++ b/src/langserver/debugger/auxtools_types.rs @@ -9,6 +9,12 @@ pub const DEFAULT_PORT: u16 = 2448; #[derive(Serialize, Deserialize, Debug)] pub enum Request { Disconnect, + Configured, + StdDef, + Disassemble(ProcRef), + CurrentInstruction { + frame_id: u32, + }, BreakpointSet { instruction: InstructionRef, }, @@ -48,6 +54,9 @@ pub enum Request { #[derive(Serialize, Deserialize, Debug)] pub enum Response { Ack, + StdDef(Option), + Disassemble(String), + CurrentInstruction(Option), BreakpointSet { result: BreakpointSetResult, }, diff --git a/src/langserver/debugger/evaluate.rs b/src/langserver/debugger/evaluate.rs index e813f1ee..7d3caaa1 100644 --- a/src/langserver/debugger/evaluate.rs +++ b/src/langserver/debugger/evaluate.rs @@ -1,23 +1,31 @@ +use regex::Regex; +use lazy_static; + use super::dap_types::*; use super::*; -const EVALUATE_HELP: &str = " +const EXTOOLS_HELP: &str = " #dis, #disassemble: show disassembly for current stack frame"; +const AUXTOOLS_HELP: &str = " +#dis, #disassemble: show disassembly for current stack frame +#dis, #disassemble : show disassembly for specified proc"; + impl Debugger { pub fn evaluate( &mut self, params: EvaluateArguments, ) -> Result> { let input = params.expression.trim_start(); - if input.starts_with("#help") { - return Ok(EvaluateResponse::from(EVALUATE_HELP.trim())); - } match &mut self.client { DebugClient::Extools(extools) => { let extools = extools.get()?; + if input.starts_with("#help") { + return Ok(EvaluateResponse::from(EXTOOLS_HELP.trim())); + } + guard!(let Some(frame_id) = params.frameId else { return Err(Box::new(GenericError("Must select a stack frame to evaluate in"))); }); @@ -36,7 +44,37 @@ impl Debugger { } } - DebugClient::Auxtools(_) => {} + DebugClient::Auxtools(auxtools) => { + lazy_static! { + static ref DISASSEMBLE_REGEX: Regex = Regex::new(r"^#dis(?:assemble)? (?P[^ ]+) ?(?P[0-9]*)$").unwrap(); + } + + if input.starts_with("#help") { + return Ok(EvaluateResponse::from(AUXTOOLS_HELP.trim())); + } + + if input == "#dis" || input == "#disassemble" { + guard!(let Some(frame_id) = params.frameId else { + return Err(Box::new(GenericError("Must select a stack frame to evaluate in"))); + }); + + let (path, override_id) = auxtools.get_current_proc(frame_id as u32)?.ok_or_else(|| { + Box::new(GenericError("Couldn't find current proc")) + })?; + + return Ok(EvaluateResponse::from(auxtools.disassemble(&path, override_id)?)); + } + + if let Some(captures) = DISASSEMBLE_REGEX.captures(input) { + let path = &captures["path"]; + let override_id = match captures.name("override").map(|x| x.as_str()) { + Some(str) => str.parse::().unwrap_or(0), + _ => 0, + }; + + return Ok(EvaluateResponse::from(auxtools.disassemble(path, override_id)?)); + } + } } Err(Box::new(GenericError("Not yet implemented"))) diff --git a/src/langserver/debugger/mod.rs b/src/langserver/debugger/mod.rs index 009986f4..efd5fa29 100644 --- a/src/langserver/debugger/mod.rs +++ b/src/langserver/debugger/mod.rs @@ -504,7 +504,10 @@ handle_request! { extools.configuration_done(); } - DebugClient::Auxtools(_) => {} + DebugClient::Auxtools(auxtools) => { + self.stddef_dm_info = auxtools.get_stddef()?.map(|x| StddefDmInfo::new(x)); + auxtools.configured()?; + } } }