Skip to content

Commit

Permalink
fix(ranges): Clean up range executions (#76)
Browse files Browse the repository at this point in the history
* idk

* lint

* begin range refactor

* lint

* add range exec tests

* lint

* more refactor

* lint

* refactor range execution

* lint

* further refactor of range exec

* more range work

* lint

* more tests

* lint

* remove commented code

* MOAR: mother of all refactors

* lint

* more improvements

* lint
  • Loading branch information
brockelmore authored Jun 21, 2024
1 parent e6173b0 commit a329c79
Show file tree
Hide file tree
Showing 141 changed files with 14,379 additions and 9,028 deletions.
11 changes: 11 additions & 0 deletions Cargo.lock

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

32 changes: 20 additions & 12 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
[workspace]
members = [
"crates/analyzers",
"crates/cli",
"crates/graph",
"crates/pyrometer",
"crates/queries",
"crates/shared",
"crates/solc-expressions",
"crates/analyzers",
"crates/cli",
"crates/graph",
"crates/pyrometer",
"crates/queries",
"crates/shared",
"crates/solc-expressions",
]
resolver = "2"

Expand All @@ -17,14 +17,18 @@ authors = ["Brock Elmore"]
license = "MIT OR Apache-2.0"
homepage = "https://github.com/nascentxyz/pyrometer"
repository = "https://github.com/nascentxyz/pyrometer"
exclude = ["benches/", "tests/", "examples/"] # exclude the benches directory from the build
exclude = [
"benches/",
"tests/",
"examples/",
] # exclude the benches directory from the build
rust-version = "1.74"

[profile.release]
debug = true

[profile.dev]
opt-level = 1 # Enable some optimizations like tail call
# opt-level = 1 # Enable some optimizations like tail call
inline = true

[profile.bench]
Expand All @@ -40,7 +44,11 @@ solc-expressions = { path = "crates/solc-expressions" }

solang-parser = { version = "0.2.4", features = ["pt-serde"] }
tracing = { version = "0.1", features = ["attributes"] }
tracing-subscriber = { version = "0.3", features = ["registry", "env-filter", "fmt"] }
tracing-subscriber = { version = "0.3", features = [
"registry",
"env-filter",
"fmt",
] }
tracing-tree = "0.3.0"
ethers-core = "*"
hex = "0.4.3"
Expand All @@ -55,12 +63,12 @@ ahash = "0.8.10"

# we patch ariadne to allow for counting by bytes because solang uses byte locations not char locations
[patch.crates-io]
ariadne = {git = "https://github.com/brockelmore/ariadne"}
ariadne = { git = "https://github.com/brockelmore/ariadne" }

# ######################################
# # Benchmarks
# ######################################

# [[bench]]
# name = "parse"
# harness = false
# harness = false
50 changes: 30 additions & 20 deletions crates/analyzers/src/bounds.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
use crate::{FunctionVarsBoundAnalysis, LocSpan, LocStrSpan, ReportConfig, VarBoundAnalysis};

use graph::{
nodes::ContextNode, range_string::ToRangeString, GraphBackend, Range, RangeEval, SolcRange,
elem::Elem,
nodes::{Concrete, ContextNode},
range_string::ToRangeString,
GraphBackend, Range, RangeEval, SolcRange,
};
use shared::StorageLocation;
use shared::{RangeArena, StorageLocation};

use ariadne::{Color, Fmt, Label, Span};
use std::collections::{BTreeMap, BTreeSet};
Expand Down Expand Up @@ -71,9 +74,13 @@ pub struct OrderedAnalysis {
}

impl OrderedAnalysis {
pub fn from_bound_analysis(ba: VarBoundAnalysis, analyzer: &impl GraphBackend) -> Self {
pub fn from_bound_analysis(
ba: VarBoundAnalysis,
analyzer: &impl GraphBackend,
arena: &mut RangeArena<Elem<Concrete>>,
) -> Self {
let mut analyses: BTreeMap<usize, BTreeSet<StrippedAnalysisItem>> = Default::default();
if let Some(init) = ba.init_item(analyzer) {
if let Some(init) = ba.init_item(analyzer, arena) {
let source: usize = *LocSpan(init.loc.1).source();
let mut set = BTreeSet::new();
set.insert(init.into());
Expand All @@ -83,15 +90,16 @@ impl OrderedAnalysis {
.iter()
.enumerate()
.for_each(|(_i, bound_change)| {
let (parts, unsat) = range_parts(analyzer, &ba.report_config, &bound_change.1);
let (parts, unsat) =
range_parts(analyzer, arena, &ba.report_config, &bound_change.1);
let item = StrippedAnalysisItem {
init: false,
name: ba.var_display_name.clone(),
loc: LocSpan(bound_change.0 .1),
order: (bound_change.0.end() - bound_change.0.start()) as i32, //i as i32,
// storage: ba.storage.clone(),
ctx: ba.ctx,
ctx_conditionals: ba.conditionals(analyzer),
ctx_conditionals: ba.conditionals(analyzer, arena),
parts,
unsat,
};
Expand All @@ -107,11 +115,12 @@ impl OrderedAnalysis {
pub fn from_func_analysis(
fvba: FunctionVarsBoundAnalysis,
analyzer: &impl GraphBackend,
arena: &mut RangeArena<Elem<Concrete>>,
) -> Self {
let mut analyses = Self::default();
fvba.vars_by_ctx.iter().for_each(|(_ctx, bas)| {
bas.iter().for_each(|ba| {
analyses.extend(Self::from_bound_analysis(ba.clone(), analyzer));
analyses.extend(Self::from_bound_analysis(ba.clone(), analyzer, arena));
})
});
analyses
Expand Down Expand Up @@ -254,39 +263,40 @@ impl ToString for RangePart {
/// Creates an Vec<[RangePart]> from a range based on the current [ReportConfig]
pub fn range_parts(
analyzer: &impl GraphBackend,
arena: &mut RangeArena<Elem<Concrete>>,
report_config: &ReportConfig,
range: &SolcRange,
) -> (Vec<RangePart>, bool) {
let mut parts = vec![];
let min = if report_config.eval_bounds {
range
.evaled_range_min(analyzer)
.evaled_range_min(analyzer, arena)
.unwrap()
.to_range_string(false, analyzer)
.to_range_string(false, analyzer, arena)
.s
} else if report_config.simplify_bounds {
range
.simplified_range_min(analyzer)
.simplified_range_min(analyzer, arena)
.unwrap()
.to_range_string(false, analyzer)
.to_range_string(false, analyzer, arena)
.s
} else {
range.range_min().to_range_string(false, analyzer).s
range.range_min().to_range_string(false, analyzer, arena).s
};
let max = if report_config.eval_bounds {
range
.evaled_range_max(analyzer)
.evaled_range_max(analyzer, arena)
.unwrap()
.to_range_string(true, analyzer)
.to_range_string(true, analyzer, arena)
.s
} else if report_config.simplify_bounds {
range
.simplified_range_max(analyzer)
.simplified_range_max(analyzer, arena)
.unwrap()
.to_range_string(true, analyzer)
.to_range_string(true, analyzer, arena)
.s
} else {
range.range_max().to_range_string(true, analyzer).s
range.range_max().to_range_string(true, analyzer, arena).s
};

if min == max {
Expand All @@ -301,8 +311,8 @@ pub fn range_parts(
let mut excls = range_excl
.iter()
.map(|range| {
let min = range.to_range_string(false, analyzer).s;
let max = range.to_range_string(true, analyzer).s;
let min = range.to_range_string(false, analyzer, arena).s;
let max = range.to_range_string(true, analyzer, arena).s;
if min == max {
RangePart::Equal(min)
} else {
Expand All @@ -314,6 +324,6 @@ pub fn range_parts(
excls
}));
}
let unsat = range.unsat(analyzer);
let unsat = range.unsat(analyzer, arena);
(parts, unsat)
}
25 changes: 16 additions & 9 deletions crates/analyzers/src/func_analyzer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ use crate::{
};

use graph::{
nodes::{ContextNode, KilledKind},
elem::Elem,
nodes::{Concrete, ContextNode, KilledKind},
AnalyzerBackend, GraphBackend,
};
use shared::Search;
use shared::{RangeArena, Search};

use ariadne::{Color, Config, Fmt, Label, Report, Span};
use solang_parser::pt::CodeLocation;
Expand Down Expand Up @@ -46,6 +47,7 @@ impl<'a> FunctionVarsBoundAnalysis {
&self,
file_mapping: &'a BTreeMap<usize, String>,
analyzer: &impl GraphBackend,
arena: &mut RangeArena<Elem<Concrete>>,
) -> Vec<Report<LocStrSpan>> {
let mut handled_ctx_switches = BTreeSet::default();
let reports = self
Expand All @@ -56,15 +58,15 @@ impl<'a> FunctionVarsBoundAnalysis {
let deps = ctx.ctx_deps(analyzer).unwrap();
let deps = deps
.iter()
.map(|var| (var.as_controllable_name(analyzer).unwrap(), var))
.map(|var| (var.as_controllable_name(analyzer, arena).unwrap(), var))
.collect::<BTreeMap<_, _>>();
// create the bound strings
// let atoms = ctx.dep_atoms(analyzer).unwrap();
// println!("had {} atoms", atoms.len());
// let mut handled_atom = vec![];
// let mut bounds_string: Vec<String> = vec![];
// atoms.iter().enumerate().for_each(|(i, atom)| {
// let atom_str = atom.to_range_string(true, analyzer).s;
// let atom_str = atom.to_range_string(true, analyzer, arena).s;
// if !handled_atom.contains(&atom_str) {
// handled_atom.push(atom_str.clone());
// bounds_string.push(format!("{}. {}", i + 1, atom_str))
Expand All @@ -78,7 +80,8 @@ impl<'a> FunctionVarsBoundAnalysis {
.filter_map(|(i, (name, cvar))| {
let range = cvar.ref_range(analyzer).unwrap()?;

let (parts, _unsat) = range_parts(analyzer, &self.report_config, &range);
let (parts, _unsat) =
range_parts(analyzer, arena, &self.report_config, &range);
let ret = parts.into_iter().fold(
format!("{}. {name}", i + 1),
|mut acc, _part| {
Expand Down Expand Up @@ -119,7 +122,7 @@ impl<'a> FunctionVarsBoundAnalysis {
let mut labels: Vec<_> = analyses
.iter()
.flat_map(|analysis| {
let mut labels = analysis.labels(analyzer);
let mut labels = analysis.labels(analyzer, arena);
labels.extend(
analysis
.spanned_ctx_info
Expand Down Expand Up @@ -197,6 +200,7 @@ impl<'a> FunctionVarsBoundAnalysis {
let range = var.ref_range(analyzer).unwrap()?;
let (parts, _unsat) = range_parts(
analyzer,
arena,
&self.report_config,
&range,
);
Expand Down Expand Up @@ -255,7 +259,7 @@ impl<'a> FunctionVarsBoundAnalysis {
.filter_map(|(loc, var)| {
let range = var.ref_range(analyzer).unwrap()?;
let (parts, _unsat) =
range_parts(analyzer, &self.report_config, &range);
range_parts(analyzer, arena, &self.report_config, &range);
Some(
Label::new(LocStrSpan::new(file_mapping, loc))
.with_message(
Expand Down Expand Up @@ -306,6 +310,7 @@ impl<T> FunctionVarsBoundAnalyzer for T where T: VarBoundAnalyzer + Search + Ana
pub trait FunctionVarsBoundAnalyzer: VarBoundAnalyzer + Search + AnalyzerBackend + Sized {
fn bounds_for_lineage<'a>(
&'a self,
arena: &mut RangeArena<Elem<Concrete>>,
file_mapping: &'a BTreeMap<usize, String>,
ctx: ContextNode,
edges: Vec<ContextNode>,
Expand Down Expand Up @@ -353,10 +358,11 @@ pub trait FunctionVarsBoundAnalyzer: VarBoundAnalyzer + Search + AnalyzerBackend
let is_ret = var.is_return_node_in_any(&parents, self);
if is_ret
| report_config.show_tmps
| (report_config.show_consts && var.is_const(self).unwrap())
| (report_config.show_consts && var.is_const(self, arena).unwrap())
| (report_config.show_symbolics && var.is_symbolic(self).unwrap())
{
Some(self.bounds_for_var_in_family_tree(
arena,
file_mapping,
parents.clone(),
var.name(self).unwrap(),
Expand Down Expand Up @@ -385,6 +391,7 @@ pub trait FunctionVarsBoundAnalyzer: VarBoundAnalyzer + Search + AnalyzerBackend

fn bounds_for_all<'a>(
&'a self,
arena: &mut RangeArena<Elem<Concrete>>,
file_mapping: &'a BTreeMap<usize, String>,
ctx: ContextNode,
report_config: ReportConfig,
Expand All @@ -393,6 +400,6 @@ pub trait FunctionVarsBoundAnalyzer: VarBoundAnalyzer + Search + AnalyzerBackend
if edges.is_empty() {
edges.push(ctx);
}
self.bounds_for_lineage(file_mapping, ctx, edges, report_config)
self.bounds_for_lineage(arena, file_mapping, ctx, edges, report_config)
}
}
Loading

0 comments on commit a329c79

Please sign in to comment.