Skip to content

Commit

Permalink
Cider DAP State Inspection + Metadata Update (#2238)
Browse files Browse the repository at this point in the history
This branch provides groundwork for state inspection while debugging
Calyx programs in VSCode. It currently displays all the cells in the
program and provides methods used to obtain port information. Port
information is not currently displayed due to a still unclear issue.

This branch also updates the metadata table so that each entry takes on
the following form:
component_name.group_name : path/to/file start-end
this update fixes an issue where the metadata pass was not recognizing
Calyx programs where two unique components each have a group with the
same name and displays the range the group is on rather than just the
start line.

---------

Co-authored-by: Serena <[email protected]>
  • Loading branch information
smd21 and Serena committed Jul 31, 2024
1 parent f53de4f commit 9777e29
Show file tree
Hide file tree
Showing 13 changed files with 291 additions and 67 deletions.
37 changes: 27 additions & 10 deletions calyx-opt/src/passes/metadata_table_gen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use std::path::PathBuf;
/// Metadata stores a Map between each group name and data used in the metadata table (specified in PR #2022)
#[derive(Default)]
pub struct Metadata {
groups: LinkedHashMap<Id, (usize, PathBuf)>,
groups: LinkedHashMap<(Id, Id), ((usize, usize), PathBuf)>,
}

impl Metadata {
Expand All @@ -18,8 +18,14 @@ impl Metadata {
}

/// Add a new entry to the metadata table
fn add_entry(&mut self, name: Id, line: usize, path: PathBuf) {
let ins = self.groups.insert(name, (line, path));
fn add_entry(
&mut self,
comp_name: Id,
name: Id,
span: (usize, usize),
path: PathBuf,
) {
let ins = self.groups.insert((comp_name, name), (span, path));
if let Some(_v) = ins {
panic!("Two of same group name found")
}
Expand All @@ -30,9 +36,10 @@ impl fmt::Display for Metadata {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let grps = &self.groups;

for (name, (line_num, file)) in grps {
for ((comp, name), ((start, end), file)) in grps {
let file = file.to_str().unwrap();
writeln!(f, " {name}: {file} {line_num}")?;

writeln!(f, "{comp}.{name}: {file} {start}-{end}")?;
}

Ok(())
Expand All @@ -58,8 +65,13 @@ impl Visitor for Metadata {
for rcc_grp in cmpt_iter {
let grp = rcc_grp.borrow_mut();
let pos_data = grp.attributes.copy_span();
let (file, line_num) = pos_data.get_line_num();
table.add_entry(grp.name(), line_num, PathBuf::from(file));
let (file, span) = pos_data.get_line_num();
table.add_entry(
component.name,
grp.name(),
span,
PathBuf::from(file),
); //hm may need to actually use the full name of the group
}

ctx.metadata = Some(table.to_string());
Expand All @@ -83,9 +95,14 @@ mod tests {
assert_eq!(empt_string, "");

let path = PathBuf::from("/temp/path/for/testing.futil");
data.add_entry(Id::from("group_1"), 12, path.clone());
data.add_entry(Id::from("group_2"), 23, path);
data.add_entry(
Id::from("main"),
Id::from("group_1"),
(12, 16),
path.clone(),
);
data.add_entry(Id::from("main"), Id::from("group_2"), (23, 28), path);
let test_string = data.to_string();
assert_eq!(test_string, " group_1: /temp/path/for/testing.futil 12\n group_2: /temp/path/for/testing.futil 23\n")
assert_eq!(test_string, "main.group_1: /temp/path/for/testing.futil 12-16\nmain.group_2: /temp/path/for/testing.futil 23-28\n")
}
}
10 changes: 6 additions & 4 deletions calyx-utils/src/position.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,13 +186,15 @@ impl GPosIdx {

/// returns:
/// 1. the name of the file the span is in
/// 2. the starting line of a span
pub fn get_line_num(&self) -> (&String, usize) {
/// 2. the (inclusive) range of lines within the span
pub fn get_line_num(&self) -> (&String, (usize, usize)) {
let table = GlobalPositionTable::as_ref();
let pos_data = table.get_pos(self.0);
let file_name = &table.get_file_data(pos_data.file).name;
let (_, _, line_num) = self.get_lines();
(file_name, line_num)
let (buf, _, line_num) = self.get_lines();
//reformat to return the range (inclusive)
let rng = (line_num, line_num + buf.len() - 1);
(file_name, rng)
}

/// Format this position with the error message `err_msg`
Expand Down
5 changes: 3 additions & 2 deletions cider-dap/calyxDebug/built/extension.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ var CiderDebugAdapter = /** @class */ (function () {
});
_this.adapterProcess.on("spawn", function () {
logToPanel("Debugger started on port " + port + "!");
setTimeout(function () { return resolve(port); }, 200); //short wait to let the thing start running
setTimeout(function () { return resolve(port); }, 700); //short wait to let the thing start running
});
_this.adapterProcess.on("error", function () {
logToPanel("Debugger failed to start");
Expand Down Expand Up @@ -116,9 +116,10 @@ function activate(context) {
break;
}
context.subscriptions.push(vscode.debug.registerDebugAdapterDescriptorFactory("cider-dap", factory));
logToPanel("before disposables push");
disposables.push(vscode.debug.registerDebugAdapterDescriptorFactory("cider-dap", factory));
// Update the adapter path with the serverPort and use it for starting the debug adapter - ??
logToPanel("Hello, your extension is now activated!");
logToPanel("Hello, your extension is now activated! after disposables push");
}
function stopDebugging() {
if (debugAdapter) {
Expand Down
7 changes: 5 additions & 2 deletions cider-dap/calyxDebug/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ class CiderDebugAdapter {
});
this.adapterProcess.on("spawn", () => {
logToPanel("Debugger started on port " + port + "!");
setTimeout(() => resolve(port), 200) //short wait to let the thing start running
setTimeout(() => resolve(port), 700) //short wait to let the thing start running
});
this.adapterProcess.on("error", () => {
logToPanel("Debugger failed to start");
Expand Down Expand Up @@ -141,9 +141,12 @@ function activate(context) {
context.subscriptions.push(
vscode.debug.registerDebugAdapterDescriptorFactory("cider-dap", factory)
);
logToPanel("before disposables push")
disposables.push(vscode.debug.registerDebugAdapterDescriptorFactory("cider-dap", factory))
// Update the adapter path with the serverPort and use it for starting the debug adapter - ??
logToPanel("Hello, your extension is now activated!");
logToPanel("Hello, your extension is now activated! after disposables push");


}

function stopDebugging() {
Expand Down
77 changes: 72 additions & 5 deletions cider-dap/src/adapter.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use crate::error::AdapterResult;
use dap::types::{Breakpoint, Source, SourceBreakpoint, StackFrame, Thread};
use dap::types::{
Breakpoint, Scope, Source, SourceBreakpoint, StackFrame, Thread, Variable,
};
use interp::debugger::source::structures::NewSourceMap;
use interp::debugger::OwnedDebugger;
use std::collections::HashMap;
use std::path::PathBuf;

pub struct MyAdapter {
Expand All @@ -13,6 +16,7 @@ pub struct MyAdapter {
breakpoints: Vec<(Source, i64)>, // This field is a placeholder
stack_frames: Vec<StackFrame>, // This field is a placeholder
threads: Vec<Thread>, // This field is a placeholder
object_references: HashMap<i64, Vec<String>>,
source: String,
ids: NewSourceMap,
}
Expand All @@ -29,10 +33,12 @@ impl MyAdapter {
breakpoints: Vec::new(),
stack_frames: Vec::new(),
threads: Vec::new(),
object_references: HashMap::new(),
source: path.to_string(),
ids: metadata,
})
}

///Set breakpoints for adapter
pub fn set_breakpoint(
&mut self,
Expand All @@ -42,7 +48,7 @@ impl MyAdapter {
//Keep all the new breakpoints made
let mut out_vec: Vec<Breakpoint> = vec![];

//Loop over all breakpoints
//Loop over all breakpoints - why do we need to loop over all of them? is it bc input vec isnt mutable?
for source_point in source {
self.breakpoints.push((path.clone(), source_point.line));
//Create new Breakpoint instance
Expand All @@ -55,12 +61,13 @@ impl MyAdapter {

out_vec.push(breakpoint);
}

//push breakpoints to cider debugger once have go ahead
out_vec
}

///Creates a thread using the parameter name.
pub fn create_thread(&mut self, name: String) -> Thread {
//how do we attach the thread to the program
let thread = Thread {
id: self.thread_count.increment(),
name,
Expand Down Expand Up @@ -109,8 +116,10 @@ impl MyAdapter {
}

pub fn next_line(&mut self, _thread: i64) -> bool {
self.object_references.clear();
//return a more informative enum
// Step through once
let status = self.debugger.step(1).unwrap();
let status = self.debugger.step(1).unwrap(); //need to unwrap a different way

// Check if done:
if status.get_done() {
Expand All @@ -123,14 +132,70 @@ impl MyAdapter {
// the code for now goes to the line of the last group running in the map, should deal
// with this in the future for when groups run in parallel.
for id in map {
let value = self.ids.lookup(id.to_string()).unwrap().line;
let value = self.ids.lookup(id.to_string()).unwrap().start_line;
line_number = value;
}
// Set line of the stack frame and tell debugger we're not finished.
self.stack_frames[0].line = line_number as i64;
false
}
}

//display ports of each cell
pub fn get_variables(&self, var_ref: i64) -> Vec<Variable> {
let ports = self.object_references.get(&var_ref);
match ports {
None => Vec::default(),
Some(p) => {
let out: Vec<Variable> = p
.iter()
.map(|x| Variable {
name: String::from(x),
value: String::from("1"),
type_field: None,
presentation_hint: None,
evaluate_name: None,
variables_reference: 0,
named_variables: None,
indexed_variables: None,
memory_reference: None,
})
.collect();
out
}
}
}
// return cells in calyx context (later should hopefully just return ones w current component)
pub fn get_scopes(&mut self, _frame: i64) -> Vec<Scope> {
let mut out_vec = vec![];
let cell_names = self.debugger.get_cells();
let mut var_ref_count = 1;
for (name, ports) in cell_names {
self.object_references.insert(var_ref_count, ports);
let scope = Scope {
name,
presentation_hint: Some(
dap::types::ScopePresentationhint::Locals,
),
variables_reference: var_ref_count,
named_variables: None,
indexed_variables: None,
expensive: false,
source: None,
line: None,
column: None,
end_line: None,
end_column: None,
};
var_ref_count += 1;
out_vec.push(scope);
}
out_vec
}

pub fn on_pause(&mut self) {
self.object_references.clear();
}
}

/// Simple struct used to keep an index of the breakpoints used.
Expand All @@ -156,11 +221,13 @@ impl Counter {
/// This function takes in relevant fields in Breakpoint that are used
/// by the adapter. This is subject to change.
pub fn make_breakpoint(
//probably add debugger call here?
id: Option<i64>,
verified: bool,
source: Option<Source>,
line: Option<i64>,
) -> Breakpoint {
println!("bkpt");
Breakpoint {
id,
verified,
Expand Down
Loading

0 comments on commit 9777e29

Please sign in to comment.