Skip to content

Commit bfc22b4

Browse files
committed
fix: start using ValueRecordWithType to be able to embed types in the newer value form
useful for rr: for now add some convert functions for compatibility; maybe in the future try to replace the old `Value` with the newer versions
1 parent c708ded commit bfc22b4

File tree

7 files changed

+308
-39
lines changed

7 files changed

+308
-39
lines changed

src/db-backend/src/db.rs

Lines changed: 63 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ use crate::distinct_vec::DistinctVec;
1515
use crate::expr_loader::ExprLoader;
1616
use crate::lang::Lang;
1717
use crate::replay::{Events, Replay};
18-
use crate::task::{Action, Breakpoint, Call, CallArg, CoreTrace, Location, ProgramEvent, RRTicks, NO_INDEX, NO_PATH, NO_POSITION, CtLoadLocalsArguments, Variable};
19-
use crate::value::{Type, Value};
18+
use crate::task::{Action, Breakpoint, Call, CallArg, CoreTrace, Location, ProgramEvent, RRTicks, NO_INDEX, NO_PATH, NO_POSITION, CtLoadLocalsArguments, VariableWithRecord};
19+
use crate::value::{Type, Value, ValueRecordWithType};
2020

2121
const NEXT_INTERNAL_STEP_OVERS_LIMIT: usize = 1_000;
2222

@@ -795,6 +795,52 @@ impl DbReplay {
795795
DbReplay { db, step_id: StepId(0), call_key: CallKey(0), breakpoint_list, breakpoint_next_id: 0 }
796796
}
797797

798+
pub fn register_type(&mut self, typ: TypeRecord) -> TypeId {
799+
// for no checking for typ.name logic: eventually in ensure_type?
800+
self.db.types.push(typ);
801+
TypeId(self.db.types.len() - 1)
802+
}
803+
804+
pub fn to_value_record(&mut self, v: ValueRecordWithType) -> ValueRecord {
805+
match v {
806+
ValueRecordWithType::Int { i, typ } => {
807+
let type_id = self.register_type(typ);
808+
ValueRecord::Int { i, type_id }
809+
},
810+
ValueRecordWithType::Float { f, typ } => {
811+
let type_id = self.register_type(typ);
812+
ValueRecord::Float { f, type_id }
813+
}
814+
ValueRecordWithType::Bool { b, typ } => {
815+
let type_id = self.register_type(typ);
816+
ValueRecord::Bool { b, type_id }
817+
}
818+
ValueRecordWithType::String { text, typ } => {
819+
let type_id = self.register_type(typ);
820+
ValueRecord::String { text, type_id }
821+
}
822+
_ => todo!()
823+
}
824+
}
825+
826+
pub fn to_value_record_with_type(&mut self, v: &ValueRecord) -> ValueRecordWithType {
827+
match v {
828+
ValueRecord::Int { i, type_id } => {
829+
ValueRecordWithType::Int { i: *i, typ: self.db.types[*type_id].clone() }
830+
},
831+
ValueRecord::Float { f, type_id } => {
832+
ValueRecordWithType::Float { f: *f, typ: self.db.types[*type_id].clone() }
833+
}
834+
ValueRecord::Bool { b, type_id } => {
835+
ValueRecordWithType::Bool { b: *b, typ: self.db.types[*type_id].clone() }
836+
}
837+
ValueRecord::String { text, type_id } => {
838+
ValueRecordWithType::String { text: text.to_string(), typ: self.db.types[*type_id].clone() }
839+
}
840+
_ => todo!()
841+
}
842+
}
843+
798844
pub fn step_id_jump(&mut self, step_id: StepId) {
799845
if step_id.0 != NO_INDEX {
800846
self.step_id = step_id;
@@ -973,30 +1019,33 @@ impl Replay for DbReplay {
9731019
}
9741020
}
9751021

976-
fn load_locals(&mut self, _arg: CtLoadLocalsArguments) -> Result<Vec<Variable>, Box<dyn Error>> {
977-
let full_value_locals: Vec<Variable> = self.db.variables[self.step_id]
1022+
fn load_locals(&mut self, _arg: CtLoadLocalsArguments) -> Result<Vec<VariableWithRecord>, Box<dyn Error>> {
1023+
let variables_for_step = self.db.variables[self.step_id].clone();
1024+
let full_value_locals: Vec<VariableWithRecord> = variables_for_step
9781025
.iter()
979-
.map(|v| Variable {
1026+
.map(|v| VariableWithRecord {
9801027
expression: self.db.variable_name(v.variable_id).to_string(),
981-
value: self.db.to_ct_value(&v.value),
1028+
value: self.to_value_record_with_type(&v.value),
1029+
// &self.db.to_ct_value(&v.value),
9821030
})
9831031
.collect();
9841032

9851033
// TODO: fix random order here as well: ensure order(or in final locals?)
986-
let value_tracking_locals: Vec<Variable> = self.db.variable_cells[self.step_id]
1034+
let variable_cells_for_step = self.db.variable_cells[self.step_id].clone();
1035+
let value_tracking_locals: Vec<VariableWithRecord> = variable_cells_for_step
9871036
.iter()
9881037
.map(|(variable_id, place)| {
9891038
let name = self.db.variable_name(*variable_id);
9901039
info!("log local {variable_id:?} {name} place: {place:?}");
9911040
let value = self.db.load_value_for_place(*place, self.step_id);
992-
Variable {
1041+
VariableWithRecord {
9931042
expression: self.db.variable_name(*variable_id).to_string(),
994-
value: self.db.to_ct_value(&value),
1043+
value: self.to_value_record_with_type(&value),
9951044
}
9961045
})
9971046
.collect();
9981047
// based on https://stackoverflow.com/a/56490417/438099
999-
let mut locals: Vec<Variable> = full_value_locals.into_iter().chain(value_tracking_locals).collect();
1048+
let mut locals: Vec<VariableWithRecord> = full_value_locals.into_iter().chain(value_tracking_locals).collect();
10001049

10011050
locals.sort_by(|left, right| Ord::cmp(&left.expression, &right.expression));
10021051
// for now just removing duplicated variables/expressions: even if storing different values
@@ -1005,21 +1054,21 @@ impl Replay for DbReplay {
10051054
Ok(locals)
10061055
}
10071056

1008-
fn load_value(&mut self, expression: &str) -> Result<ValueRecord, Box<dyn Error>> {
1057+
fn load_value(&mut self, expression: &str) -> Result<ValueRecordWithType, Box<dyn Error>> {
10091058
// TODO: a more optimal way: cache a hashmap? or change structure?
10101059
// or again start directly loading available values matching all expressions in the same time?:
10111060
// taking a set of expressions: probably best(maybe add an additional load_values)
10121061
for variable in &self.db.variables[self.step_id] {
10131062
if self.db.variable_names[variable.variable_id] == expression {
1014-
return Ok(variable.value.clone())
1063+
return Ok(self.to_value_record_with_type(&variable.value.clone()))
10151064
}
10161065
}
10171066
return Err(format!("variable {expression} not found on this step").into())
10181067
}
10191068

1020-
fn load_return_value(&mut self) -> Result<ValueRecord, Box<dyn Error>> {
1069+
fn load_return_value(&mut self) -> Result<ValueRecordWithType, Box<dyn Error>> {
10211070
// assumes self.load_location() has been ran, and that we have the current call key
1022-
Ok(self.db.calls[self.call_key].return_value.clone())
1071+
Ok(self.to_value_record_with_type(&self.db.calls[self.call_key].return_value.clone()))
10231072
}
10241073

10251074
fn load_step_events(&mut self, step_id: StepId, exact: bool) -> Vec<DbRecordEvent> {

src/db-backend/src/flow_preloader.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ use crate::{
66
FlowMode, FlowViewUpdate, Iteration, Location, Loop, LoopId, LoopIterationSteps, Position, RRTicks, StepCount, TraceKind,
77
},
88
replay::Replay,
9-
value::Value,
9+
value::{to_ct_value, Value, ValueRecordWithType},
1010
};
1111
use log::{info, warn, error};
12-
use runtime_tracing::{CallKey, Line, StepId, ValueRecord, TypeId};
12+
use runtime_tracing::{CallKey, Line, StepId, TypeKind, TypeRecord, TypeSpecificInfo};
1313
use std::collections::{HashMap, HashSet};
1414
use std::path::PathBuf;
1515
use std::error::Error;
@@ -179,12 +179,11 @@ impl<'a> CallFlowPreloader<'a> {
179179
// are never None, so it is safe to unwrap them.
180180
if !flow_view_update.steps.is_empty() {
181181

182-
let db = Db::new(&PathBuf::from("")); // we don't need its state for to_ct_value
183-
let return_value_record = replay.load_return_value().unwrap_or(ValueRecord::Error {
182+
let return_value_record = replay.load_return_value().unwrap_or(ValueRecordWithType::Error {
184183
msg: "<return value error>".to_string(),
185-
type_id: TypeId(0),
184+
typ: TypeRecord { kind: TypeKind::Error, lang_type: "<error>".to_string(), specific_info: TypeSpecificInfo::None },
186185
});
187-
let return_value = db.to_ct_value(&return_value_record);
186+
let return_value = to_ct_value(&return_value_record);
188187

189188
#[allow(clippy::unwrap_used)]
190189
flow_view_update.steps.last_mut().unwrap().before_values.insert(
@@ -513,8 +512,7 @@ impl<'a> CallFlowPreloader<'a> {
513512
for value_name in &var_list {
514513
if let Ok(value) = replay.load_value(value_name) {
515514
// if variable_map.contains_key(value_name) {
516-
let db = Db::new(&PathBuf::from("")); // no state needed for to_ct_value
517-
let ct_value = db.to_ct_value(&value);
515+
let ct_value = to_ct_value(&value);
518516
flow_view_update
519517
.steps
520518
.last_mut()

src/db-backend/src/handler.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ use crate::task::{
3131
UpdateTableArgs, Variable, NO_INDEX, NO_PATH, NO_POSITION, NO_STEP_ID,
3232
};
3333
use crate::tracepoint_interpreter::TracepointInterpreter;
34+
use crate::value::to_ct_value;
3435

3536
const TRACEPOINT_RESULTS_LIMIT_BEFORE_UPDATE: usize = 5;
3637

@@ -328,7 +329,11 @@ impl Handler {
328329
// if self.trace_kind == TraceKind::RR {
329330
// let locals: Vec<Variable> = vec![];
330331
// warn!("load_locals not implemented for rr yet");
331-
let locals = self.replay.load_locals(args)?;
332+
let locals_with_records = self.replay.load_locals(args)?;
333+
let locals = locals_with_records.iter().map(|l| Variable {
334+
expression: l.expression.clone(),
335+
value: to_ct_value(&l.value)
336+
}).collect();
332337
self.respond_dap(req, task::CtLoadLocalsResponseBody { locals })?;
333338
Ok(())
334339
// }

src/db-backend/src/replay.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
use runtime_tracing::{StepId, ValueRecord};
1+
use runtime_tracing::StepId;
22
use std::error::Error;
33

44
use crate::db::DbRecordEvent;
55
use crate::expr_loader::ExprLoader;
6-
use crate::task::{Action, Breakpoint, Location, ProgramEvent, CtLoadLocalsArguments, Variable};
6+
use crate::task::{Action, Breakpoint, Location, ProgramEvent, CtLoadLocalsArguments, VariableWithRecord};
7+
use crate::value::ValueRecordWithType;
78

89
#[derive(Debug, Clone)]
910
pub struct Events {
@@ -17,10 +18,10 @@ pub trait Replay: std::fmt::Debug {
1718
fn run_to_entry(&mut self) -> Result<(), Box<dyn Error>>;
1819
fn load_events(&mut self) -> Result<Events, Box<dyn Error>>;
1920
fn step(&mut self, action: Action, forward: bool) -> Result<bool, Box<dyn Error>>;
20-
fn load_locals(&mut self, arg: CtLoadLocalsArguments) -> Result<Vec<Variable>, Box<dyn Error>>;
21-
fn load_value(&mut self, expression: &str) -> Result<ValueRecord, Box<dyn Error>>;
21+
fn load_locals(&mut self, arg: CtLoadLocalsArguments) -> Result<Vec<VariableWithRecord>, Box<dyn Error>>;
22+
fn load_value(&mut self, expression: &str) -> Result<ValueRecordWithType, Box<dyn Error>>;
2223
// assuming currently in the right call for both trace kinds; and if rr: possibly near the return value
23-
fn load_return_value(&mut self) -> Result<ValueRecord, Box<dyn Error>>;
24+
fn load_return_value(&mut self) -> Result<ValueRecordWithType, Box<dyn Error>>;
2425
fn load_step_events(&mut self, step_id: StepId, exact: bool) -> Vec<DbRecordEvent>;
2526
fn jump_to(&mut self, step_id: StepId) -> Result<bool, Box<dyn Error>>;
2627
fn add_breakpoint(&mut self, path: &str, line: i64) -> Result<Breakpoint, Box<dyn Error>>;

src/db-backend/src/rr_dispatcher.rs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,15 @@ use std::thread;
88
use std::time::Duration;
99

1010
use log::{info, warn, error};
11-
use runtime_tracing::{StepId, ValueRecord};
11+
use runtime_tracing::StepId;
1212

1313
use crate::db::DbRecordEvent;
1414
use crate::expr_loader::ExprLoader;
1515
use crate::paths::ct_rr_worker_socket_path;
1616
use crate::query::CtRRQuery;
1717
use crate::replay::{Events, Replay};
18-
use crate::task::{Action, Breakpoint, Location, CtLoadLocalsArguments, Variable};
18+
use crate::task::{Action, Breakpoint, Location, CtLoadLocalsArguments, VariableWithRecord};
19+
use crate::value::ValueRecordWithType;
1920

2021
#[derive(Debug)]
2122
pub struct RRDispatcher {
@@ -123,7 +124,7 @@ impl CtRRWorker {
123124

124125
res = String::from(res.trim()); // trim newlines/whitespace!
125126

126-
info!("res {res}");
127+
info!("res: `{res}`");
127128

128129
if !res.starts_with("error:") {
129130
Ok(res)
@@ -192,21 +193,21 @@ impl Replay for RRDispatcher {
192193
Ok(res)
193194
}
194195

195-
fn load_locals(&mut self, arg: CtLoadLocalsArguments) -> Result<Vec<Variable>, Box<dyn Error>> {
196+
fn load_locals(&mut self, arg: CtLoadLocalsArguments) -> Result<Vec<VariableWithRecord>, Box<dyn Error>> {
196197
self.ensure_active_stable()?;
197-
let res = serde_json::from_str::<Vec<Variable>>(&self.stable.run_query(CtRRQuery::LoadLocals { arg })?)?;
198+
let res = serde_json::from_str::<Vec<VariableWithRecord>>(&self.stable.run_query(CtRRQuery::LoadLocals { arg })?)?;
198199
Ok(res)
199200
}
200201

201-
fn load_value(&mut self, expression: &str) -> Result<ValueRecord, Box<dyn Error>> {
202+
fn load_value(&mut self, expression: &str) -> Result<ValueRecordWithType, Box<dyn Error>> {
202203
self.ensure_active_stable()?;
203-
let res = serde_json::from_str::<ValueRecord>(&self.stable.run_query(CtRRQuery::LoadValue { expression: expression.to_string() })?)?;
204+
let res = serde_json::from_str::<ValueRecordWithType>(&self.stable.run_query(CtRRQuery::LoadValue { expression: expression.to_string() })?)?;
204205
Ok(res)
205206
}
206207

207-
fn load_return_value(&mut self) -> Result<ValueRecord, Box<dyn Error>> {
208+
fn load_return_value(&mut self) -> Result<ValueRecordWithType, Box<dyn Error>> {
208209
self.ensure_active_stable()?;
209-
let res = serde_json::from_str::<ValueRecord>(&self.stable.run_query(CtRRQuery::LoadReturnValue)?)?;
210+
let res = serde_json::from_str::<ValueRecordWithType>(&self.stable.run_query(CtRRQuery::LoadReturnValue)?)?;
210211
Ok(res)
211212
}
212213

src/db-backend/src/task.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use serde::{Deserialize, Serialize};
1111
use serde_repr::*;
1212

1313
use crate::lang::*;
14-
use crate::value::{Type, Value};
14+
use crate::value::{Type, Value, ValueRecordWithType};
1515
use schemars::JsonSchema;
1616

1717
// IMPORTANT: must keep in sync with `EventLogKind` definition in common_types.nim!
@@ -124,6 +124,20 @@ pub struct Variable {
124124
pub value: Value,
125125
}
126126

127+
128+
#[derive(Debug, Clone, Serialize, Deserialize)]
129+
#[serde(rename_all(serialize = "camelCase", deserialize = "camelCase"))]
130+
pub struct VariableWithRecord {
131+
pub expression: String,
132+
pub value: ValueRecordWithType,
133+
}
134+
135+
// pub struct ValueRecordAndType {
136+
// value: ValueRecord,
137+
// typ: Type,
138+
// }
139+
140+
127141
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
128142
#[serde(rename_all(serialize = "camelCase", deserialize = "camelCase"))]
129143
pub struct Instruction {

0 commit comments

Comments
 (0)