Skip to content

Commit 7b479c4

Browse files
committed
Added JUnit Engine
1 parent 982c878 commit 7b479c4

21 files changed

Lines changed: 622 additions & 350 deletions

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,9 @@ Generated IR (raw and unoptimized):
5555

5656
![IRExample New Instance Creation](./docs/newinstance_1.png)
5757

58-
## Example constructor invocation
58+
## Example constructor implementation
5959

60-
A simple Java example with constructor invocation:
60+
A simple Java example with constructor implementation:
6161
```
6262
public class Test {
6363

src/main/java/de/mirkosertic/metair/ir/DOTExporter.java

Lines changed: 78 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
package de.mirkosertic.metair.ir;
22

3-
import java.io.OutputStream;
3+
44
import java.io.PrintStream;
5+
import java.lang.classfile.CodeElement;
6+
import java.lang.classfile.CodeModel;
7+
import java.lang.classfile.MethodModel;
8+
import java.lang.classfile.instruction.LabelTarget;
59
import java.util.ArrayDeque;
610
import java.util.ArrayList;
711
import java.util.Deque;
812
import java.util.HashMap;
913
import java.util.HashSet;
1014
import java.util.List;
1115
import java.util.Map;
16+
import java.util.Optional;
1217
import java.util.Set;
1318

1419
public final class DOTExporter {
@@ -139,7 +144,7 @@ public static void writeTo(final Method method, final PrintStream ps) {
139144
d7 [style = invis];
140145
}
141146
c0 -> c1 [label="Control flow", style=solid, color=red]
142-
c1 -> c2 [label="Control flow back edge", style=dashed, color=red]
147+
c2 -> c3 [label="Control flow back edge", style=dashed, color=red]
143148
d0 -> d1 [label="Data flow"]
144149
d2 -> d3 [label="Declaration", style=dotted]
145150
d4 -> d5 [label="PHI Data flow", color=blue]
@@ -166,9 +171,7 @@ private static void printNode(final int index, final Node node, final PrintStrea
166171
}
167172
}
168173

169-
public static void writeTo(final DominatorTree tree, final OutputStream fileOutputStream) {
170-
final PrintStream ps = new PrintStream(fileOutputStream);
171-
174+
public static void writeTo(final DominatorTree tree, final PrintStream ps) {
172175
ps.println("digraph debugoutput {");
173176
for (final Node n : tree.preOrder) {
174177
ps.print(" node" + tree.preOrder.indexOf(n) + "[");
@@ -236,7 +239,7 @@ public static void writeTo(final DominatorTree tree, final OutputStream fileOutp
236239
d7 [style = invis];
237240
}
238241
c0 -> c1 [label="Control flow", style=solid, color=red]
239-
c1 -> c2 [label="Control flow back edge", style=dashed, color=red]
242+
c2 -> c3 [label="Control flow back edge", style=dashed, color=red]
240243
d0 -> d1 [label="Data flow"]
241244
d2 -> d3 [label="Declaration", style=dotted]
242245
d4 -> d5 [label="PHI Data flow", color=blue]
@@ -246,4 +249,73 @@ public static void writeTo(final DominatorTree tree, final OutputStream fileOutp
246249
ps.println("}");
247250
ps.flush();
248251
}
252+
253+
public static void writeBytecodeCFGTo(final MethodAnalyzer analyzer, final PrintStream ps) {
254+
ps.println("digraph {");
255+
256+
final MethodModel method = analyzer.getMethod();
257+
final Optional<CodeModel> optCode = method.code();
258+
if (optCode.isPresent()) {
259+
final CodeModel code = optCode.get();
260+
261+
final MethodAnalyzer.Frame[] frames = analyzer.getFrames();
262+
final List<MethodAnalyzer.Frame> topologicalOrder = analyzer.getCodeModelTopologicalOrder();
263+
264+
final List<CodeElement> elements = code.elementList();
265+
for (int i = 0; i < elements.size(); i++) {
266+
if (i == elements.size() - 1 && elements.get(i) instanceof LabelTarget) {
267+
// Ignore last label
268+
continue;
269+
}
270+
ps.print(" node" + i);
271+
ps.print("[");
272+
ps.print("label=\"");
273+
ps.print("#");
274+
ps.print(i);
275+
ps.print(" ");
276+
ps.print(elements.get(i));
277+
if (topologicalOrder != null && topologicalOrder.size() > i) {
278+
ps.print(" Order: " + topologicalOrder.indexOf(frames[i]));
279+
}
280+
ps.print("\"");
281+
ps.println(", shape=box, fillcolor=lightgrey, style=filled];");
282+
}
283+
284+
for (int elementIndex = 0; elementIndex < frames.length - 1; elementIndex++) {
285+
final MethodAnalyzer.Frame frame = frames[elementIndex];
286+
if (frame != null) {
287+
for (final MethodAnalyzer.CFGEdge edge : frame.predecessors) {
288+
ps.print(" node");
289+
ps.print(edge.fromIndex());
290+
ps.print(" -> node");
291+
ps.print(elementIndex);
292+
ps.print("[color=red");
293+
if (edge.controlType() == ControlType.BACKWARD) {
294+
ps.print(", style=dotted");
295+
}
296+
ps.println("];");
297+
}
298+
}
299+
}
300+
}
301+
302+
ps.println("""
303+
subgraph cluster_000 {
304+
label = "Legend";
305+
node [shape=point]
306+
{
307+
rank=same;
308+
c0 [style = invis];
309+
c1 [style = invis];
310+
c2 [style = invis];
311+
c3 [style = invis];
312+
}
313+
c0 -> c1 [label="Control flow", style=solid, color=red]
314+
c2 -> c3 [label="Control flow back edge", style=dashed, color=red]
315+
}
316+
""");
317+
318+
ps.println("}");
319+
320+
}
249321
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package de.mirkosertic.metair.ir;
2+
3+
public class IllegalParsingStateException extends IllegalStateException {
4+
5+
private final MethodAnalyzer analyzer;
6+
7+
public IllegalParsingStateException(final MethodAnalyzer analyzer, final String s) {
8+
super(s);
9+
this.analyzer = analyzer;
10+
}
11+
12+
public MethodAnalyzer getAnalyzer() {
13+
return analyzer;
14+
}
15+
}

0 commit comments

Comments
 (0)