Skip to content

Commit

Permalink
Cider dap rework (#1986)
Browse files Browse the repository at this point in the history
* quick and dirty scaffolding for stuff to come

* quick and dirty scaffolding for stuff to come

* tidy up

* Edited MyAdapter to return a result

* Handled Scopes, edited stack funcs, and finished from_file

* Enabled stepping through .futil files

* cidr.rs:
- Created a struct ProgramStatus which contains an arbitrary type T in cidr.rs
- Edited step function to return ProgramStatus

adapter.rs:
- created a sourcemap and hardcoded ids for reg_seq.futil
- Changed next function to adapt to these mappings

* made debugger disconnect when program finishes, also cleaned up code

* Added NewSourceMap

* Slightly edited comments and used cargo fmt

* Changed formating to clippy suggestions

* More clippy fixes

* Feedback changes

* Made std_lib path a configuration

* Deleted comments

---------

Co-authored-by: Griffin Berlstein <[email protected]>
  • Loading branch information
eliascxstro and EclecticGriffin authored Apr 16, 2024
1 parent 33b05e7 commit 21c2f7b
Show file tree
Hide file tree
Showing 15 changed files with 449 additions and 91 deletions.
2 changes: 1 addition & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -99,4 +99,4 @@
]
}
]
}
}
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions cider-dap/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ slog = "2.7.0"
slog-term = "2.8.0"
slog-async = "2.7.0"

interp = { path = "../interp" }

[[bin]]
name = "cider-dap"
path = "src/main.rs"
2 changes: 1 addition & 1 deletion cider-dap/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ the cider-dap binary somewhere on your path. From some directory on your PATH:
ln -s <PATH TO CALYX ROOT>/target/debug/cider-dap
```

You will have to configure user settings of cider-dap in VSCode and input your cider binary path, session type, and port number (if debug adapter is started as a server). You can then launch the adapter with the Debug w/ Cider action.
You will have to configure user settings of cider-dap in VSCode and input your cider binary path, calyx std_lib path, session type, and port number (if debug adapter is started as a server). You can then launch the adapter with the Debug w/ Cider action.

## Known issues

Expand Down
14 changes: 8 additions & 6 deletions cider-dap/calyxDebug/built/extension.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (g && (g = 0, op[0] && (_ = 0)), _) try {
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
Expand Down Expand Up @@ -76,9 +76,10 @@ function getProgramName() {
}
// Factory for multi-session
var CiderDebugAdapterDescriptorFactoryServer = /** @class */ (function () {
function CiderDebugAdapterDescriptorFactoryServer(adapterPath, workspace, outputChannel) {
function CiderDebugAdapterDescriptorFactoryServer(adapterPath, stdPath, workspace, outputChannel) {
logToPanel("inside constructor");
this.adapter = new CiderDebugAdapter(adapterPath, workspace, outputChannel);
this.adapter = new CiderDebugAdapter(adapterPath, stdPath, workspace, outputChannel);
this.stdPath = stdPath;
this.adapterPath = adapterPath;
this.workspace = workspace;
this.outputChannel = outputChannel;
Expand All @@ -103,9 +104,10 @@ var CiderDebugAdapterDescriptorFactoryServer = /** @class */ (function () {
return CiderDebugAdapterDescriptorFactoryServer;
}());
var CiderDebugAdapter = /** @class */ (function () {
function CiderDebugAdapter(adapterPath, cwd, outputChannel) {
function CiderDebugAdapter(adapterPath, stdPath, cwd, outputChannel) {
logToPanel("inside CiderDebugAdapter");
this.adapterPath = adapterPath;
this.stdPath = stdPath;
this.cwd = cwd;
this.outputChannel = outputChannel;
this.adapterProcess = null;
Expand All @@ -120,7 +122,7 @@ var CiderDebugAdapter = /** @class */ (function () {
logToPanel("beginning of start");
// Spawn a new child process for the debug adapter
// Include the port as a command line argument
this.adapterProcess = cp.spawn(this.adapterPath, ["--port", port, "--tcp"], { cwd: this.cwd });
this.adapterProcess = cp.spawn(this.adapterPath, ["--port", port, "--tcp", "-l", this.stdPath], { cwd: this.cwd });
// Attach event listener to capture standard output of the adapter process and log it to the output channel
this.adapterProcess.stdout.on("data", function (data) {
logToPanel(data.toString());
Expand Down Expand Up @@ -165,7 +167,7 @@ function activate(context) {
logToPanel("setting up with configuration '" + vscode.workspace.getConfiguration("cider-dap").sessionType + "'. You will need to reload after changing the settings if a different mode is desired.");
switch (vscode.workspace.getConfiguration("cider-dap").sessionType) {
case "Multi-Session":
factory = new CiderDebugAdapterDescriptorFactoryServer(vscode.workspace.getConfiguration("cider-dap").path, vscode.workspace.rootPath, outputChannel);
factory = new CiderDebugAdapterDescriptorFactoryServer(vscode.workspace.getConfiguration("cider-dap").path, vscode.workspace.getConfiguration("cider-dap").std_lib, vscode.workspace.rootPath, outputChannel);
break;
case "Single-Session":
default:
Expand Down
13 changes: 9 additions & 4 deletions cider-dap/calyxDebug/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,14 @@ async function getProgramName() {
class CiderDebugAdapterDescriptorFactoryServer {
adapter: CiderDebugAdapter;
adapterPath: string;
stdPath: string;
workspace: string;
outputChannel: object;

constructor(adapterPath, workspace, outputChannel) {
constructor(adapterPath, stdPath, workspace, outputChannel) {
logToPanel("inside constructor");
this.adapter = new CiderDebugAdapter(adapterPath, workspace, outputChannel);
this.adapter = new CiderDebugAdapter(adapterPath, stdPath, workspace, outputChannel);
this.stdPath = stdPath;
this.adapterPath = adapterPath;
this.workspace = workspace;
this.outputChannel = outputChannel;
Expand Down Expand Up @@ -73,14 +75,16 @@ class CiderDebugAdapterDescriptorFactoryServer {
}
class CiderDebugAdapter {
adapterPath: string;
stdPath: string;
outputChannel: object;
cwd: string;
adapterProcess: cp.ChildProcessWithoutNullStreams | null;
isRunning: boolean;

constructor(adapterPath, cwd, outputChannel) {
constructor(adapterPath, stdPath, cwd, outputChannel) {
logToPanel("inside CiderDebugAdapter");
this.adapterPath = adapterPath;
this.stdPath = stdPath;
this.cwd = cwd;
this.outputChannel = outputChannel;
this.adapterProcess = null;
Expand All @@ -98,7 +102,7 @@ class CiderDebugAdapter {
// Include the port as a command line argument
this.adapterProcess = cp.spawn(
this.adapterPath,
["--port", port, "--tcp"],
["--port", port, "--tcp", "-l", this.stdPath],
{ cwd: this.cwd }
);

Expand Down Expand Up @@ -157,6 +161,7 @@ function activate(context) {
case "Multi-Session":
factory = new CiderDebugAdapterDescriptorFactoryServer(
vscode.workspace.getConfiguration("cider-dap").path,
vscode.workspace.getConfiguration("cider-dap").std_lib,
vscode.workspace.rootPath,
outputChannel
);
Expand Down
10 changes: 8 additions & 2 deletions cider-dap/calyxDebug/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@
"default": "cider-dap",
"description": "Cider Binary Path"
},
"cider-dap.std_lib": {
"type": "string",
"scope": "machine",
"default": "",
"description": "Calyx std_lib Path"
},
"cider-dap.port": {
"type": "number",
"scope": "machine",
Expand Down Expand Up @@ -67,7 +73,7 @@
"vscode:prepublish": "npx tsc"
},
"devDependencies": {
"@types/node": "^20.11.6",
"@types/node": "^20.12.7",
"@types/vscode": "^1.54.0"
}
}
}
105 changes: 93 additions & 12 deletions cider-dap/src/adapter.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,40 @@
use dap::types::{Breakpoint, Source, SourceBreakpoint, Thread};
use std::fs::File;
use crate::error::AdapterResult;
use dap::types::{Breakpoint, Source, SourceBreakpoint, StackFrame, Thread};
use interp::debugger::source::structures::NewSourceMap;
use interp::debugger::Debugger;
use std::collections::HashMap;
use std::path::PathBuf;

pub struct MyAdapter {
#[allow(dead_code)]
file: File,
breakpoints: Vec<(Source, i64)>, //This field is a placeholder
debugger: Debugger,
break_count: Counter,
thread_count: Counter,
threads: Vec<Thread>, //This field is a placeholder
stack_count: Counter,
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
source: String,
ids: NewSourceMap,
}

// New metadata in interp/debugger

impl MyAdapter {
pub fn new(file: File) -> Self {
MyAdapter {
file,
breakpoints: Vec::new(),
pub fn new(path: &str, std_path: PathBuf) -> AdapterResult<Self> {
Ok(MyAdapter {
debugger: Debugger::from_file(&PathBuf::from(path), &std_path)
.unwrap(),
break_count: Counter::new(),
thread_count: Counter::new(),
stack_count: Counter::new(),
breakpoints: Vec::new(),
stack_frames: Vec::new(),
threads: Vec::new(),
}
source: path.to_string(),
ids: create_map(),
})
}

///Set breakpoints for adapter
pub fn set_breakpoint(
&mut self,
Expand All @@ -37,6 +52,7 @@ impl MyAdapter {
self.break_count.increment().into(),
true,
Some(path.clone()),
Some(source_point.line),
);

out_vec.push(breakpoint);
Expand All @@ -59,6 +75,61 @@ impl MyAdapter {
pub fn clone_threads(&self) -> Vec<Thread> {
self.threads.clone()
}

//Returns a dummy stack frame, set to change.
pub fn create_stack(&mut self) -> Vec<StackFrame> {
let frame = StackFrame {
id: self.stack_count.increment(),
// TODO: edit name field
name: String::from("Hi"),
source: Some(Source {
name: None,
path: Some(self.source.clone()),
source_reference: None,
presentation_hint: None,
origin: None,
sources: None,
adapter_data: None,
checksums: None,
}),
line: 1,
column: 0,
end_line: None,
end_column: None,
can_restart: None,
instruction_pointer_reference: None,
module_id: None,
presentation_hint: None,
};
self.stack_frames.push(frame);
// Return all stack frames
self.stack_frames.clone()
}

pub fn clone_stack(&self) -> Vec<StackFrame> {
self.stack_frames.clone()
}

pub fn next_line(&mut self, _thread: i64) -> bool {
let status = self.debugger.step(1).unwrap();

// Check if done:
if status.get_done() {
true
} else {
let map = status.get_status().clone();
// Declare line number beforehand
let mut line_number = 0;
// Return -1 should a lookup not be found. This really shouldn't
// happen though
for id in map {
let value = *self.ids.lookup(id.to_string()).unwrap_or(&-1);
line_number = value;
}
self.stack_frames[0].line = line_number;
false
}
}
}

/// Simple struct used to keep an index of the breakpoints used.
Expand Down Expand Up @@ -87,17 +158,27 @@ pub fn make_breakpoint(
id: Option<i64>,
verified: bool,
source: Option<Source>,
line: Option<i64>,
) -> Breakpoint {
Breakpoint {
id,
verified,
message: None,
source,
line: None,
line,
column: None,
end_line: None,
end_column: None,
instruction_reference: None,
offset: None,
}
}

// Hardcode mapping for now, this mapping is for reg_seq.futil
fn create_map() -> NewSourceMap {
let mut hashmap = HashMap::new();
// Hardcode
hashmap.insert(String::from("wr_reg0"), 10);
hashmap.insert(String::from("wr_reg1"), 15);
NewSourceMap::from(hashmap)
}
Loading

0 comments on commit 21c2f7b

Please sign in to comment.