Skip to content

Commit 876766c

Browse files
committed
fixup! Add ControlFlowGraph and implementation
1 parent 45e51a1 commit 876766c

File tree

5 files changed

+75
-104
lines changed

5 files changed

+75
-104
lines changed

delphi-frontend/src/main/java/au/com/integradev/delphi/cfg/ControlFlowGraphBuilder.java

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,11 @@
1818
*/
1919
package au.com.integradev.delphi.cfg;
2020

21-
import static au.com.integradev.delphi.cfg.block.ProtoBlockBuilder.newBlock;
22-
2321
import au.com.integradev.delphi.cfg.api.Block;
2422
import au.com.integradev.delphi.cfg.api.ControlFlowGraph;
2523
import au.com.integradev.delphi.cfg.block.BlockImpl;
2624
import au.com.integradev.delphi.cfg.block.ProtoBlock;
27-
import au.com.integradev.delphi.cfg.block.ProtoBlockBuilder;
25+
import au.com.integradev.delphi.cfg.block.ProtoBlockFactory;
2826
import com.google.common.collect.Lists;
2927
import java.util.ArrayDeque;
3028
import java.util.ArrayList;
@@ -57,7 +55,8 @@ public class ControlFlowGraphBuilder {
5755
private final Deque<TryContext> tryContexts = new ArrayDeque<>();
5856

5957
public ControlFlowGraphBuilder() {
60-
ProtoBlock exitBlock = addBlock(newBlock());
58+
ProtoBlock exitBlock = ProtoBlockFactory.exitBlock();
59+
addBlock(exitBlock);
6160
exitBlocks.add(exitBlock);
6261
addBlockBefore(exitBlock);
6362
}
@@ -145,15 +144,15 @@ public void addLabel(LabelStatementNode labelNode) {
145144
// When "resolving" label, all the previously unresolved targets must be updated
146145
for (UnresolvedLabel unresolvedLabel : unresolvedLabels.get(label)) {
147146
unresolvedLabel.block.update(
148-
newBlock().withJump(unresolvedLabel.node, currentBlock, unresolvedLabel.nextBlock));
147+
ProtoBlockFactory.jump(unresolvedLabel.node, currentBlock, unresolvedLabel.nextBlock));
149148
}
150149
}
151150

152151
public void addGoto(GotoStatementNode gotoNode) {
153152
NameReferenceNode labelNode = gotoNode.getNameReference();
154153
String label = labelNode.getImage();
155154
if (labelTargets.containsKey(label)) {
156-
addBlock(newBlock().withJump(gotoNode, labelTargets.get(label), currentBlock));
155+
addBlock(ProtoBlockFactory.jump(gotoNode, labelTargets.get(label), currentBlock));
157156
return;
158157
}
159158

@@ -236,17 +235,16 @@ public void addElement(DelphiNode element) {
236235
}
237236

238237
public ProtoBlock addBlockBeforeCurrent() {
239-
return addBlockBefore(currentBlock);
238+
addBlockBefore(currentBlock);
239+
return currentBlock;
240240
}
241241

242-
public ProtoBlock addBlockBefore(ProtoBlock successor) {
243-
return addBlock(newBlock().withSuccessor(successor));
242+
public void addBlockBefore(ProtoBlock successor) {
243+
addBlock(ProtoBlockFactory.succeedingTo(successor));
244244
}
245245

246-
public ProtoBlock addBlock(ProtoBlockBuilder builder) {
247-
ProtoBlock result = builder.build();
248-
blocks.add(result);
249-
currentBlock = result;
250-
return result;
246+
public void addBlock(ProtoBlock block) {
247+
blocks.add(block);
248+
currentBlock = block;
251249
}
252250
}

delphi-frontend/src/main/java/au/com/integradev/delphi/cfg/ControlFlowGraphImpl.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,6 @@ public void prune() {
7575

7676
blocks.forEach(inactiveBlocks::remove);
7777
} while (!inactiveBlocks.isEmpty());
78-
79-
return this;
8078
}
8179

8280
private boolean isInactive(Block block) {

delphi-frontend/src/main/java/au/com/integradev/delphi/cfg/ControlFlowGraphVisitor.java

Lines changed: 30 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,9 @@
1818
*/
1919
package au.com.integradev.delphi.cfg;
2020

21-
import static au.com.integradev.delphi.cfg.block.ProtoBlockBuilder.newBlock;
22-
2321
import au.com.integradev.delphi.antlr.ast.visitors.DelphiParserVisitor;
2422
import au.com.integradev.delphi.cfg.block.ProtoBlock;
23+
import au.com.integradev.delphi.cfg.block.ProtoBlockFactory;
2524
import java.util.AbstractMap.SimpleEntry;
2625
import java.util.ArrayList;
2726
import java.util.HashSet;
@@ -153,12 +152,12 @@ public ControlFlowGraphBuilder visit(NameReferenceNode node, ControlFlowGraphBui
153152
switch (routineName) {
154153
case "System.Exit":
155154
builder.addBlock(
156-
newBlock().withJump(node, builder.getExitBlock(), builder.getCurrentBlock()));
155+
ProtoBlockFactory.jump(node, builder.getExitBlock(), builder.getCurrentBlock()));
157156
return builder;
158157
case "System.Break":
159158
return buildControlFlowStatement(node, builder.getBreakTarget(), builder);
160159
case "System.Halt":
161-
builder.addBlock(newBlock().withProgramTerminator(node));
160+
builder.addBlock(ProtoBlockFactory.halt(node));
162161
return builder;
163162
case "System.Continue":
164163
return buildControlFlowStatement(node, builder.getContinueTarget(), builder);
@@ -177,7 +176,7 @@ private static ControlFlowGraphBuilder buildControlFlowStatement(
177176
throw new IllegalStateException(
178177
String.format("'%s' statement not in loop statement", node.getImage()));
179178
}
180-
builder.addBlock(newBlock().withJump(node, target, builder.getCurrentBlock()));
179+
builder.addBlock(ProtoBlockFactory.jump(node, target, builder.getCurrentBlock()));
181180
return builder;
182181
}
183182

@@ -188,7 +187,7 @@ private static void handleExceptionalPaths(ControlFlowGraphBuilder builder) {
188187
}
189188

190189
Set<ProtoBlock> exceptions = builder.getAllCatchTargets();
191-
builder.addBlock(newBlock().withExceptions(builder.getCurrentBlock(), exceptions));
190+
builder.addBlock(ProtoBlockFactory.withExceptions(builder.getCurrentBlock(), exceptions));
192191
}
193192

194193
/** Overridden to ensure {@code NodeDeclaration}s are added in the correct order */
@@ -247,23 +246,17 @@ public ControlFlowGraphBuilder visit(IfStatementNode node, ControlFlowGraphBuild
247246
ProtoBlock after = builder.getCurrentBlock();
248247

249248
// process `else`
250-
ProtoBlock elseBlock = after;
251-
if (node.getElseStatement() != null) {
252-
StatementNode elseStatement = node.getElseStatement();
253-
if (!(elseStatement instanceof IfStatementNode)) {
254-
builder.addBlockBefore(after);
255-
}
256-
elseStatement.accept(this, builder);
257-
elseBlock = builder.getCurrentBlock();
258-
}
249+
builder.addBlockBefore(after);
250+
build(node.getElseStatement(), builder);
251+
ProtoBlock elseBlock = builder.getCurrentBlock();
259252

260253
// process `then`
261254
builder.addBlockBefore(after);
262255
build(node.getThenStatement(), builder);
263256
ProtoBlock thenBlock = builder.getCurrentBlock();
264257

265258
// process condition
266-
builder.addBlock(newBlock().withBranch(node, thenBlock, elseBlock));
259+
builder.addBlock(ProtoBlockFactory.withBranch(node, thenBlock, elseBlock));
267260
return buildCondition(builder, node.getGuardExpression(), thenBlock, elseBlock);
268261
}
269262

@@ -295,7 +288,7 @@ private ControlFlowGraphBuilder buildConditionAnd(
295288
buildCondition(builder, node.getRight(), trueBlock, falseBlock);
296289
ProtoBlock newTrueBlock = builder.getCurrentBlock();
297290
// LHS
298-
builder.addBlock(newBlock().withBranch(node, newTrueBlock, falseBlock));
291+
builder.addBlock(ProtoBlockFactory.withBranch(node, newTrueBlock, falseBlock));
299292
return buildCondition(builder, node.getLeft(), newTrueBlock, falseBlock);
300293
}
301294

@@ -308,7 +301,7 @@ private ControlFlowGraphBuilder buildConditionOr(
308301
buildCondition(builder, node.getRight(), trueBlock, falseBlock);
309302
ProtoBlock newFalseBlock = builder.getCurrentBlock();
310303
// LHS
311-
builder.addBlock(newBlock().withBranch(node, trueBlock, newFalseBlock));
304+
builder.addBlock(ProtoBlockFactory.withBranch(node, trueBlock, newFalseBlock));
312305
return buildCondition(builder, node.getLeft(), trueBlock, newFalseBlock);
313306
}
314307

@@ -382,7 +375,7 @@ public ControlFlowGraphBuilder visit(CaseStatementNode node, ControlFlowGraphBui
382375
caseSuccessors.add(builder.getCurrentBlock());
383376
}
384377

385-
caseBlock.update(newBlock().withCases(node, caseSuccessors));
378+
caseBlock.update(ProtoBlockFactory.cases(node, caseSuccessors));
386379
builder.setCurrentBlock(conditionBlock);
387380
return builder;
388381
}
@@ -408,20 +401,20 @@ public ControlFlowGraphBuilder visit(CaseStatementNode node, ControlFlowGraphBui
408401
@Override
409402
public ControlFlowGraphBuilder visit(RepeatStatementNode node, ControlFlowGraphBuilder builder) {
410403
ProtoBlock after = builder.getCurrentBlock();
411-
// Create a placeholder for the conditional block
412-
ProtoBlock loopback = builder.addBlockBefore(after);
404+
// Create a placeholder for the body's starting block
405+
ProtoBlock body = builder.addBlockBeforeCurrent();
413406

414407
// Condition
415-
builder.addBlock(newBlock().withBranch(node, after, loopback));
416-
buildCondition(builder, node.getGuardExpression(), after, loopback);
408+
builder.addBlock(ProtoBlockFactory.withBranch(node, after, body));
409+
buildCondition(builder, node.getGuardExpression(), after, body);
417410

418411
// Body
419412
builder.pushLoopContext(builder.getCurrentBlock(), after);
420413
builder.addBlockBeforeCurrent();
421414
build(node.getStatementList(), builder);
422415
builder.popLoopContext();
423416

424-
loopback.update(newBlock().withSuccessor(builder.getCurrentBlock()));
417+
body.update(ProtoBlockFactory.succeedingTo(builder.getCurrentBlock()));
425418
builder.addBlockBeforeCurrent();
426419
return builder;
427420
}
@@ -446,21 +439,22 @@ public ControlFlowGraphBuilder visit(RepeatStatementNode node, ControlFlowGraphB
446439
@Override
447440
public ControlFlowGraphBuilder visit(WhileStatementNode node, ControlFlowGraphBuilder builder) {
448441
ProtoBlock after = builder.getCurrentBlock();
449-
// Create a placeholder for the conditional block
450-
ProtoBlock loopback = builder.addBlockBefore(after);
442+
// Create a placeholder for the condition's starting block
443+
ProtoBlock condition = builder.addBlockBeforeCurrent();
451444

452445
// Body
453-
builder.addBlockBefore(loopback);
454-
builder.pushLoopContext(loopback, after);
446+
builder.addBlockBefore(condition);
447+
builder.pushLoopContext(condition, after);
455448
build(node.getStatement(), builder);
456449
builder.popLoopContext();
457450
ProtoBlock body = builder.getCurrentBlock();
458451

459452
// Condition
460-
builder.addBlock(newBlock().withBranch(node, body, after));
453+
builder.setCurrentBlock(condition);
454+
builder.addBlock(ProtoBlockFactory.withBranch(node, body, after));
461455
buildCondition(builder, node.getGuardExpression(), body, after);
462456

463-
loopback.update(newBlock().withSuccessor(builder.getCurrentBlock()));
457+
condition.update(ProtoBlockFactory.succeedingTo(builder.getCurrentBlock()));
464458
builder.addBlockBeforeCurrent();
465459
return builder;
466460
}
@@ -522,7 +516,7 @@ private ControlFlowGraphBuilder buildForLoop(
522516
build(node.getStatement(), builder);
523517
builder.popLoopContext();
524518

525-
loopback.update(newBlock().withBranch(node, builder.getCurrentBlock(), after));
519+
loopback.update(ProtoBlockFactory.withBranch(node, builder.getCurrentBlock(), after));
526520

527521
builder.setCurrentBlock(loopback);
528522
parts.forEach(
@@ -563,7 +557,8 @@ private ControlFlowGraphBuilder buildTryFinally(
563557
builder.addBlockBeforeCurrent();
564558
// Finally
565559
FinallyBlockNode finallyNode = node.getFinallyBlock();
566-
builder.addBlock(newBlock().withFinallyPath(builder.getCurrentBlock(), builder.getExitBlock()));
560+
builder.addBlock(
561+
ProtoBlockFactory.finallyBlock(builder.getCurrentBlock(), builder.getExitBlock()));
567562
build(finallyNode.getStatementList(), builder);
568563
builder.pushLoopContext(builder.getCurrentBlock(), builder.getCurrentBlock());
569564
builder.pushExitBlock(builder.getCurrentBlock());
@@ -633,14 +628,14 @@ private ControlFlowGraphBuilder buildTryExcept(
633628
public ControlFlowGraphBuilder visit(RaiseStatementNode node, ControlFlowGraphBuilder builder) {
634629
if (node.getRaiseExpression() == null) {
635630
Set<ProtoBlock> exceptions = builder.getAllCatchTargets();
636-
builder.addBlock(newBlock().withExceptions(builder.getCurrentBlock(), exceptions));
631+
builder.addBlock(ProtoBlockFactory.withExceptions(builder.getCurrentBlock(), exceptions));
637632
builder.addElement(node);
638633
return builder;
639634
}
640635

641636
Type raiseType = node.getRaiseExpression().getType();
642637
ProtoBlock jumpTarget = builder.getCatchTarget(raiseType);
643-
builder.addBlock(newBlock().withJump(node, jumpTarget, builder.getCurrentBlock()));
638+
builder.addBlock(ProtoBlockFactory.jump(node, jumpTarget, builder.getCurrentBlock()));
644639
return build(node.getRaiseExpression(), builder);
645640
}
646641

@@ -735,7 +730,7 @@ private ControlFlowGraphBuilder buildBooleanLHS(
735730
BinaryExpressionNode node,
736731
ProtoBlock trueBlock,
737732
ProtoBlock falseBlock) {
738-
builder.addBlock(newBlock().withBranch(node, trueBlock, falseBlock));
733+
builder.addBlock(ProtoBlockFactory.withBranch(node, trueBlock, falseBlock));
739734
return build(node.getLeft(), builder);
740735
}
741736

delphi-frontend/src/main/java/au/com/integradev/delphi/cfg/block/ProtoBlock.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,7 @@ public void addElement(DelphiNode element) {
4545
this.elements.add(element);
4646
}
4747

48-
public void update(ProtoBlockBuilder blockBuilder) {
49-
ProtoBlock block = blockBuilder.build();
48+
public void update(ProtoBlock block) {
5049
this.blockSupplier = block.blockSupplier;
5150
this.dataSetter = block.dataSetter;
5251
}

0 commit comments

Comments
 (0)