difftreelog
fix loop_invariant should use innermost frame for dependency analysis
in: master
4 files changed
crates/jrsonnet-evaluator/src/analyze.rsdiffbeforeafterboth40pub struct AnalysisResult {40pub struct AnalysisResult {41 /// Highest object, on which identity the value is dependent. `u32::MAX` = not dependent at all41 /// Highest object, on which identity the value is dependent. `u32::MAX` = not dependent at all42 pub object_dependent_depth: u32,42 pub object_dependent_depth: u32,43 /// Highest local frame, on which this value depends. `u32::MAX` = not dependent at all43 /// Highest (outermost) local frame, on which this value depends.44 /// `u32::MAX` = not dependent at all.44 pub local_dependent_depth: u32,45 pub local_dependent_depth: u32,46 /// Deepest (innermost) local frame, on which this value depends.47 /// `<local_dependent_depth` = not dependent at all.48 pub local_dependent_depth_max: u32,45}49}465047impl Default for AnalysisResult {51impl Default for AnalysisResult {48 fn default() -> Self {52 fn default() -> Self {49 Self {53 Self {50 object_dependent_depth: u32::MAX,54 object_dependent_depth: u32::MAX,51 local_dependent_depth: u32::MAX,55 local_dependent_depth: u32::MAX,56 local_dependent_depth_max: 0,52 }57 }53 }58 }54}59}60 }65 }61 }66 }62 fn depend_on_local(&mut self, depth: u32) {67 fn depend_on_local(&mut self, depth: u32) {63 if depth < self.local_dependent_depth {68 self.local_dependent_depth = self.local_dependent_depth.min(depth);64 self.local_dependent_depth = depth;69 self.local_dependent_depth_max = self.local_dependent_depth_max.max(depth);65 }66 }70 }67 fn taint_by(&mut self, other: AnalysisResult) {71 fn taint_by(&mut self, other: AnalysisResult) {68 self.depend_on_object(other.object_dependent_depth);72 self.depend_on_object(other.object_dependent_depth);69 self.depend_on_local(other.local_dependent_depth);73 self.local_dependent_depth = self.local_dependent_depth.min(other.local_dependent_depth);74 self.local_dependent_depth_max = self75 .local_dependent_depth_max76 .max(other.local_dependent_depth_max);70 }77 }78 /// True if any local was depended on. False for the default (no-deps) state.79 fn has_local_deps(&self) -> bool {80 self.local_dependent_depth_max >= self.local_dependent_depth81 }71}82}728373#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Acyclic)]84#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Acyclic)]1164 let user_def = &mut self.local_defs[user.idx()];1175 let user_def = &mut self.local_defs[user.idx()];1165 let before_obj = user_def.analysis.object_dependent_depth;1176 let before_obj = user_def.analysis.object_dependent_depth;1166 let before_loc = user_def.analysis.local_dependent_depth;1177 let before_loc = user_def.analysis.local_dependent_depth;1178 let before_loc_max = user_def.analysis.local_dependent_depth_max;1167 user_def.analysis.taint_by(used_analysis);1179 user_def.analysis.taint_by(used_analysis);1168 user_def.analysis.depend_on_local(used_defined_at_depth);1180 user_def.analysis.depend_on_local(used_defined_at_depth);1169 before_obj != user_def.analysis.object_dependent_depth1181 before_obj != user_def.analysis.object_dependent_depth1170 || before_loc != user_def.analysis.local_dependent_depth1182 || before_loc != user_def.analysis.local_dependent_depth1183 || before_loc_max != user_def.analysis.local_dependent_depth_max1171 }1184 }1172}1185}117311861948 CompSpec::ForSpec(ForSpecData { destruct, over }) => {1961 CompSpec::ForSpec(ForSpecData { destruct, over }) => {1949 let mut over_taint = AnalysisResult::default();1962 let mut over_taint = AnalysisResult::default();1950 let over_l = analyze(over, stack, &mut over_taint);1963 let over_l = analyze(over, stack, &mut over_taint);1951 let loop_invariant = over_taint.local_dependent_depth > outer_depth;1964 let loop_invariant = !over_taint.has_local_deps()1965 || over_taint.local_dependent_depth_max < outer_depth;1952 taint.taint_by(over_taint);1966 taint.taint_by(over_taint);195319671954 let mut alloc = FrameAlloc::new(stack);1968 let mut alloc = FrameAlloc::new(stack);1984 CompSpec::ForObjSpec(data) => {1998 CompSpec::ForObjSpec(data) => {1985 let mut over_taint = AnalysisResult::default();1999 let mut over_taint = AnalysisResult::default();1986 let over_l = analyze(&data.over, stack, &mut over_taint);2000 let over_l = analyze(&data.over, stack, &mut over_taint);1987 let loop_invariant = over_taint.local_dependent_depth > outer_depth;2001 let loop_invariant = !over_taint.has_local_deps()2002 || over_taint.local_dependent_depth_max < outer_depth;1988 taint.taint_by(over_taint);2003 taint.taint_by(over_taint);198920041990 let mut alloc = FrameAlloc::new(stack);2005 let mut alloc = FrameAlloc::new(stack);crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@issue224.jsonnet.snapdiffbeforeafterboth128 ),128 ),129 ),129 ),130 ),130 ),131 loop_invariant: true,131 loop_invariant: false,132 },132 },133 ],133 ],134 },134 },crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@issue224_hoisting.jsonnet.snapdiffbeforeafterboth1---1---2source: crates/jrsonnet-evaluator/src/analyze.rs2source: crates/jrsonnet-evaluator/src/analyze.rs3assertion_line: 22783expression: rendered4expression: rendered4input_file: crates/jrsonnet-evaluator/src/analysis_tests/issue224_hoisting.jsonnet5input_file: crates/jrsonnet-evaluator/src/analysis_tests/issue224_hoisting.jsonnet5---6---tests/tests/snapshots/golden__golden@issue224.jsonnet.snapdiffbeforeafterbothno changes