Skip to content

Commit

Permalink
refactor(cfg)!: make BasicBlock::unreachable private (#6321)
Browse files Browse the repository at this point in the history
Protect `unreachable` property of basic blocks in preparation of upcoming
refactors. This is technically a breaking change.
  • Loading branch information
DonIsaac committed Oct 7, 2024
1 parent fa4d505 commit 95e018f
Show file tree
Hide file tree
Showing 8 changed files with 27 additions and 12 deletions.
17 changes: 16 additions & 1 deletion crates/oxc_cfg/src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ pub type BasicBlockId = NodeIndex;
#[derive(Debug, Clone)]
pub struct BasicBlock {
pub instructions: Vec<Instruction>,
pub unreachable: bool,
unreachable: bool,
}

impl BasicBlock {
Expand All @@ -17,6 +17,21 @@ impl BasicBlock {
pub fn instructions(&self) -> &Vec<Instruction> {
&self.instructions
}

#[inline]
pub fn is_unreachable(&self) -> bool {
self.unreachable
}

#[inline]
pub fn mark_as_unreachable(&mut self) {
self.unreachable = true;
}

#[inline]
pub fn mark_as_reachable(&mut self) {
self.unreachable = false;
}
}

#[derive(Debug, Clone)]
Expand Down
10 changes: 5 additions & 5 deletions crates/oxc_cfg/src/builder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,18 +91,18 @@ impl<'a> ControlFlowGraphBuilder<'a> {

pub fn add_edge(&mut self, a: BasicBlockId, b: BasicBlockId, weight: EdgeType) {
if matches!(weight, EdgeType::NewFunction) {
self.basic_block_mut(b).unreachable = false;
} else if matches!(weight, EdgeType::Unreachable) || self.basic_block(a).unreachable {
self.basic_block_mut(b).mark_as_reachable();
} else if matches!(weight, EdgeType::Unreachable) || self.basic_block(a).is_unreachable() {
if self.graph.edges_directed(b, Direction::Incoming).count() == 0 {
self.basic_block_mut(b).unreachable = true;
self.basic_block_mut(b).mark_as_unreachable();
}
} else if !self
.basic_block(b)
.instructions()
.iter()
.any(|it| matches!(it, Instruction { kind: InstructionKind::Unreachable, .. }))
{
self.basic_block_mut(b).unreachable = false;
self.basic_block_mut(b).mark_as_reachable();
}
self.graph.add_edge(a, b, weight);
}
Expand Down Expand Up @@ -211,7 +211,7 @@ impl<'a> ControlFlowGraphBuilder<'a> {
let current_node_ix = self.current_node_ix;
let basic_block_with_unreachable_graph_ix = self.new_basic_block_normal();
self.push_instruction(InstructionKind::Unreachable, None);
self.current_basic_block().unreachable = true;
self.current_basic_block().mark_as_unreachable();
self.add_edge(
current_node_ix,
basic_block_with_unreachable_graph_ix,
Expand Down
2 changes: 1 addition & 1 deletion crates/oxc_cfg/src/dot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ impl DisplayDot for ControlFlowGraph {
let mut attrs = Attrs::default().with("label", format!("{weight:?}"));

if matches!(weight, EdgeType::Unreachable)
|| self.basic_block(edge.source()).unreachable
|| self.basic_block(edge.source()).is_unreachable()
{
attrs += ("style", "dotted");
} else if matches!(weight, EdgeType::Error(_)) {
Expand Down
2 changes: 1 addition & 1 deletion crates/oxc_linter/src/rules/eslint/no_fallthrough.rs
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ impl Rule for NoFallthrough {
if tests.contains_key(&node) {
return (last_cond, true);
}
if cfg.basic_block(node).unreachable {
if cfg.basic_block(node).is_unreachable() {
return (None, false);
}

Expand Down
2 changes: 1 addition & 1 deletion crates/oxc_linter/src/rules/eslint/no_unreachable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ impl Rule for NoUnreachable {
// prevent other reachable blocks from ever getting executed.
let _: Control<()> = depth_first_search(graph, Some(root.cfg_id()), |event| {
if let DfsEvent::Finish(node, _) = event {
let unreachable = cfg.basic_block(node).unreachable;
let unreachable = cfg.basic_block(node).is_unreachable();
unreachables[node.index()] = unreachable;

if !unreachable {
Expand Down
2 changes: 1 addition & 1 deletion crates/oxc_semantic/examples/cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ fn main() -> std::io::Result<()> {
let weight = edge.weight();
let label = format!("label = \"{weight:?}\"");
if matches!(weight, EdgeType::Unreachable)
|| cfg.basic_block(edge.source()).unreachable
|| cfg.basic_block(edge.source()).is_unreachable()
{
format!("{label}, style = \"dotted\" ")
} else {
Expand Down
2 changes: 1 addition & 1 deletion crates/oxc_semantic/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1528,7 +1528,7 @@ impl<'a> Visit<'a> for SemanticBuilder<'a> {
cfg.add_edge(
finally_block_end_ix,
after_try_statement_block_ix,
if cfg.basic_block(after_try_block_graph_ix).unreachable {
if cfg.basic_block(after_try_block_graph_ix).is_unreachable() {
EdgeType::Unreachable
} else {
EdgeType::Join
Expand Down
2 changes: 1 addition & 1 deletion crates/oxc_semantic/src/dot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ impl DebugDot for ControlFlowGraph {
}
let mut attrs = Attrs::from_iter([("label", format!("{weight:?}"))]);
if matches!(weight, EdgeType::Unreachable)
|| self.basic_block(edge.source()).unreachable
|| self.basic_block(edge.source()).is_unreachable()
{
attrs += ("style", "dotted");
}
Expand Down

0 comments on commit 95e018f

Please sign in to comment.