Skip to content

Commit 060e45b

Browse files
committed
Working on sequencer logic
1 parent 0c22bc0 commit 060e45b

2 files changed

Lines changed: 74 additions & 78 deletions

File tree

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

Lines changed: 56 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -115,42 +115,44 @@ public MethodAnalyzer(final ClassDesc owner, final MethodModel method) {
115115

116116
private void step0PrepareTryCatchBlocks(final CodeModel code) {
117117
for (final ExceptionCatch exceptionHandler : code.exceptionHandlers()) {
118-
final List<TryCatchBlock> blocks = tryCatchBlocks.computeIfAbsent(exceptionHandler.tryStart(), key -> new ArrayList<>());
119-
120-
// Ad if not already where
121-
TryCatchBlock blockToModify = null;
122-
for (final TryCatchBlock block : blocks) {
123-
if (block.start.equals(exceptionHandler.tryStart()) && block.end.equals(exceptionHandler.tryEnd())) {
124-
blockToModify = block;
125-
break;
118+
if (exceptionHandler.tryStart() != exceptionHandler.handler()) {
119+
final List<TryCatchBlock> blocks = tryCatchBlocks.computeIfAbsent(exceptionHandler.tryStart(), key -> new ArrayList<>());
120+
121+
// Ad if not already where
122+
TryCatchBlock blockToModify = null;
123+
for (final TryCatchBlock block : blocks) {
124+
if (block.start.equals(exceptionHandler.tryStart()) && block.end.equals(exceptionHandler.tryEnd())) {
125+
blockToModify = block;
126+
break;
127+
}
126128
}
127-
}
128129

129-
if (blockToModify == null) {
130-
blockToModify = new TryCatchBlock(exceptionHandler.tryStart(), exceptionHandler.tryEnd());
131-
blocks.add(blockToModify);
132-
if (blocks.size() > 1) {
133-
illegalState("Multiple try-catch blocks for the same try-catch block range!");
130+
if (blockToModify == null) {
131+
blockToModify = new TryCatchBlock(exceptionHandler.tryStart(), exceptionHandler.tryEnd());
132+
blocks.add(blockToModify);
133+
if (blocks.size() > 1) {
134+
illegalState("Multiple try-catch blocks for the same try-catch block range!");
135+
}
134136
}
135-
}
136137

137-
// We try to find the right catch handler
138-
CatchHandler handler = null;
139-
for (final CatchHandler k : blockToModify.handlers) {
140-
if (k.handler.equals(exceptionHandler.handler())) {
141-
handler = k;
142-
break;
138+
// We try to find the right catch handler
139+
CatchHandler handler = null;
140+
for (final CatchHandler k : blockToModify.handlers) {
141+
if (k.handler.equals(exceptionHandler.handler())) {
142+
handler = k;
143+
break;
144+
}
145+
}
146+
if (handler == null) {
147+
handler = new CatchHandler(exceptionHandler.handler());
148+
blockToModify.handlers.add(handler);
143149
}
144-
}
145-
if (handler == null) {
146-
handler = new CatchHandler(exceptionHandler.handler());
147-
blockToModify.handlers.add(handler);
148-
}
149150

150-
if (exceptionHandler.catchType().isPresent()) {
151-
handler.addCaughtException(exceptionHandler.catchType().get().asSymbol());
152-
} else {
153-
handler.markAsFinally();
151+
if (exceptionHandler.catchType().isPresent()) {
152+
handler.addCaughtException(exceptionHandler.catchType().get().asSymbol());
153+
} else {
154+
handler.markAsFinally();
155+
}
154156
}
155157
}
156158
}
@@ -239,21 +241,19 @@ private void step1AnalyzeCFG(final CodeModel code) {
239241
for (final TryCatchBlock block : blocksFromHere) {
240242
for (int k = 0; k < block.handlers.size(); k++) {
241243
final CatchHandler handler = block.handlers.get(k);
242-
if (!handler.finallyHandler && !handler.handler.equals(block.start)) {
243-
if (labelToIndex.containsKey(handler.handler)) {
244-
final int newIndex = labelToIndex.get(handler.handler);
245-
if (!visited.contains(newIndex)) {
246-
jobs.add(new CFGAnalysisJob(newIndex, newPath));
247-
}
248-
Frame frame = frames[newIndex];
249-
if (frame == null) {
250-
frame = new Frame(newIndex, codeElements.get(newIndex));
251-
frames[newIndex] = frame;
252-
}
253-
frame.predecessors.add(new FrameCFGEdge(i, new FrameNamedProjection(CatchProjection.nameFor(k, handler.exceptionTypes)), FlowType.FORWARD));
254-
} else {
255-
illegalState("Exception handler target " + handler.handler + " is not mapped to an index");
244+
if (labelToIndex.containsKey(handler.handler)) {
245+
final int newIndex = labelToIndex.get(handler.handler);
246+
if (!visited.contains(newIndex)) {
247+
jobs.add(new CFGAnalysisJob(newIndex, newPath));
256248
}
249+
Frame frame = frames[newIndex];
250+
if (frame == null) {
251+
frame = new Frame(newIndex, codeElements.get(newIndex));
252+
frames[newIndex] = frame;
253+
}
254+
frame.predecessors.add(new FrameCFGEdge(i, new FrameNamedProjection(CatchProjection.nameFor(k, handler.exceptionTypes)), FlowType.FORWARD));
255+
} else {
256+
illegalState("Exception handler target " + handler.handler + " is not mapped to an index");
257257
}
258258
}
259259
}
@@ -854,9 +854,7 @@ private void step4FollowCFGAndInterpret(final CodeModel code) {
854854
final List<ExceptionGuard.Catches> catches = new ArrayList<>();
855855
for (int i = 0; i < catchBlock.handlers.size(); i++) {
856856
final CatchHandler handler = catchBlock.handlers.get(i);
857-
if (!handler.finallyHandler) {
858-
catches.add(new ExceptionGuard.Catches(i, handler.exceptionTypes));
859-
}
857+
catches.add(new ExceptionGuard.Catches(i, handler.exceptionTypes));
860858
}
861859
final ExceptionGuard n = new ExceptionGuard("Guard_" + frame.elementIndex, catches);
862860

@@ -872,7 +870,7 @@ private void step4FollowCFGAndInterpret(final CodeModel code) {
872870
// This is the thing we need to interpret
873871

874872
// Interpret the node
875-
visitNode(code, frameElement, frame);
873+
visitNode(frameElement, frame);
876874

877875
if (frame.out == null || frame.out == incomingStatus) {
878876
illegalState("No outgoing or same same as incoming status for " + frameElement);
@@ -888,12 +886,12 @@ private void step4FollowCFGAndInterpret(final CodeModel code) {
888886
private void step5PeepholeOptimizations() {
889887
}
890888

891-
private void visitNode(final CodeModel codeModel, final CodeElement node, final Frame frame) {
889+
private void visitNode(final CodeElement node, final Frame frame) {
892890

893891
if (node instanceof final PseudoInstruction psi) {
894892
// Pseudo Instructions
895893
switch (psi) {
896-
case final LabelTarget labelTarget -> visitLabelTarget(codeModel, labelTarget, frame);
894+
case final LabelTarget labelTarget -> visitLabelTarget(labelTarget, frame);
897895
case final LineNumber lineNumber -> visitLineNumberNode(lineNumber, frame);
898896
case final LocalVariable localVariable -> visitLocalVariable(localVariable, frame);
899897
case final LocalVariableType localVariableType -> visitLocalVariableType(localVariableType, frame);
@@ -1015,7 +1013,7 @@ private ExceptionGuard exceptionGuardsFromHere(final Node node, final String lab
10151013
}
10161014
10171015
@Testbacklog
1018-
protected void visitLabelTarget(final CodeModel codeModel, final LabelTarget node, final Frame frame) {
1016+
protected void visitLabelTarget(final LabelTarget node, final Frame frame) {
10191017
10201018
final Label label = node.label();
10211019
@@ -1024,7 +1022,7 @@ protected void visitLabelTarget(final CodeModel codeModel, final LabelTarget nod
10241022
}
10251023
10261024
final List<TryCatchBlock> catchesFromHere = tryCatchBlocks.get(label);
1027-
final Map<Label, List<ExceptionCatch>> catchesEndingHere = codeModel.exceptionHandlers().stream().filter(t -> t.tryEnd().equals(label)).collect(Collectors.groupingBy(ExceptionCatch::tryStart));
1025+
final List<TryCatchBlock> catchesEndingHere = tryCatchBlocks.values().stream().flatMap(Collection::stream).filter(t -> t.end.equals(label)).toList();
10281026
10291027
if (!catchesEndingHere.isEmpty()) {
10301028
if (catchesFromHere != null && !catchesFromHere.isEmpty()) {
@@ -1035,7 +1033,7 @@ protected void visitLabelTarget(final CodeModel codeModel, final LabelTarget nod
10351033
}
10361034
final Status outgoing = frame.copyIncomingToOutgoing();
10371035

1038-
final String searchLabel = "Guard_" + labelToIndex.get(catchesEndingHere.keySet().iterator().next());
1036+
final String searchLabel = "Guard_" + labelToIndex.get(catchesEndingHere.getFirst().start);
10391037
final ExceptionGuard activeGuard = exceptionGuardsFromHere(outgoing.control, searchLabel);
10401038
if (activeGuard == null) {
10411039
illegalState("No exception guard found for " + outgoing.control + " with label " + searchLabel);
@@ -1065,9 +1063,7 @@ protected void visitLabelTarget(final CodeModel codeModel, final LabelTarget nod
10651063
final List<ExceptionGuard.Catches> catches = new ArrayList<>();
10661064
for (int i = 0; i < catchBlock.handlers.size(); i++) {
10671065
final CatchHandler handler = catchBlock.handlers.get(i);
1068-
if (!handler.finallyHandler) {
1069-
catches.add(new ExceptionGuard.Catches(i, handler.exceptionTypes));
1070-
}
1066+
catches.add(new ExceptionGuard.Catches(i, handler.exceptionTypes));
10711067
}
10721068
final ExceptionGuard n = new ExceptionGuard("Guard_" + frame.elementIndex, catches);
10731069

@@ -1933,7 +1929,7 @@ private void parse_PUTFIELD(final ClassDesc owner, final ClassDesc fieldType, fi
19331929
final PutField put = new PutField(owner, fieldType, fieldName, target, v);
19341930

19351931
outgoing.memory = outgoing.memory.memoryFlowsTo(put);
1936-
//outgoing.control = outgoing.control.controlFlowsTo(put, FlowType.FORWARD);
1932+
outgoing.control = outgoing.control.controlFlowsTo(put, FlowType.FORWARD);
19371933
}
19381934

19391935
private void parse_GETSTATIC(final ClassDesc owner, final ClassDesc fieldType, final String fieldName, final Frame frame) {
@@ -2310,7 +2306,7 @@ private void parse_ARRAYSTORE_X_TRUNCATED(final Opcode opcode, final Frame frame
23102306
final ArrayStore store = new ArrayStore(array, index, new Truncate(arrayType.componentType(), value));
23112307

23122308
outgoing.memory = outgoing.memory.memoryFlowsTo(store);
2313-
//outgoing.control = outgoing.control.controlFlowsTo(store, FlowType.FORWARD);
2309+
outgoing.control = outgoing.control.controlFlowsTo(store, FlowType.FORWARD);
23142310
}
23152311

23162312
private void parse_ASTORE_X(final Frame frame, final ClassDesc arrayType) {
@@ -2324,7 +2320,7 @@ private void parse_ASTORE_X(final Frame frame, final ClassDesc arrayType) {
23242320
final ArrayStore store = new ArrayStore(array, index, value);
23252321

23262322
outgoing.memory = outgoing.memory.memoryFlowsTo(store);
2327-
//outgoing.control = outgoing.control.controlFlowsTo(store, FlowType.FORWARD);
2323+
outgoing.control = outgoing.control.controlFlowsTo(store, FlowType.FORWARD);
23282324
}
23292325

23302326
private void parse_AASTORE(final Frame frame) {
@@ -2338,7 +2334,7 @@ private void parse_AASTORE(final Frame frame) {
23382334
final ArrayStore store = new ArrayStore(array, index, value);
23392335

23402336
outgoing.memory = outgoing.memory.memoryFlowsTo(store);
2341-
//outgoing.control = outgoing.control.controlFlowsTo(store, FlowType.FORWARD);
2337+
outgoing.control = outgoing.control.controlFlowsTo(store, FlowType.FORWARD);
23422338
}
23432339

23442340
private void parse_ALOAD_X_INTEXTENDED(final Frame frame, final Extend.ExtendType type) {

src/test/java/de/mirkosertic/metair/ir/MethodAnalyzerTest.java

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -465,11 +465,11 @@ public void aastore() {
465465

466466
assertThat(frame.out).isNotNull().isNotSameAs(frame.in);
467467
assertThat(frame.out.stack).isEmpty();
468-
assertThat(frame.out.control).isInstanceOf(LabelNode.class);
468+
assertThat(frame.out.control).isInstanceOf(ArrayStore.class);
469469
assertThat(frame.out.memory).isInstanceOf(ArrayStore.class);
470470

471471
final ArrayStore as = (ArrayStore) frame.out.memory;
472-
assertThat(as.uses).hasSize(4);
472+
assertThat(as.uses).hasSize(5);
473473
assertThat(as.uses.get(0).node()).isSameAs(array);
474474
assertThat(as.uses.get(1).node()).isSameAs(index);
475475
assertThat(as.uses.get(2).node()).isSameAs(value);
@@ -507,11 +507,11 @@ public void castore() {
507507

508508
assertThat(frame.out).isNotNull().isNotSameAs(frame.in);
509509
assertThat(frame.out.stack).isEmpty();
510-
assertThat(frame.out.control).isInstanceOf(LabelNode.class);
510+
assertThat(frame.out.control).isInstanceOf(ArrayStore.class);
511511
assertThat(frame.out.memory).isInstanceOf(ArrayStore.class);
512512

513513
final ArrayStore as = (ArrayStore) frame.out.memory;
514-
assertThat(as.uses).hasSize(4);
514+
assertThat(as.uses).hasSize(5);
515515
assertThat(as.uses.get(0).node()).isSameAs(array);
516516
assertThat(as.uses.get(1).node()).isSameAs(index);
517517
assertThat(as.uses.get(2).node()).isInstanceOf(Truncate.class);
@@ -557,11 +557,11 @@ public void bastore() {
557557

558558
assertThat(frame.out).isNotNull().isNotSameAs(frame.in);
559559
assertThat(frame.out.stack).isEmpty();
560-
assertThat(frame.out.control).isInstanceOf(LabelNode.class);
560+
assertThat(frame.out.control).isInstanceOf(ArrayStore.class);
561561
assertThat(frame.out.memory).isInstanceOf(ArrayStore.class);
562562

563563
final ArrayStore as = (ArrayStore) frame.out.memory;
564-
assertThat(as.uses).hasSize(4);
564+
assertThat(as.uses).hasSize(5);
565565
assertThat(as.uses.get(0).node()).isSameAs(array);
566566
assertThat(as.uses.get(1).node()).isSameAs(index);
567567
assertThat(as.uses.get(2).node()).isInstanceOf(Truncate.class);
@@ -586,11 +586,11 @@ public void sastore() {
586586

587587
assertThat(frame.out).isNotNull().isNotSameAs(frame.in);
588588
assertThat(frame.out.stack).isEmpty();
589-
assertThat(frame.out.control).isInstanceOf(LabelNode.class);
589+
assertThat(frame.out.control).isInstanceOf(ArrayStore.class);
590590
assertThat(frame.out.memory).isInstanceOf(ArrayStore.class);
591591

592592
final ArrayStore as = (ArrayStore) frame.out.memory;
593-
assertThat(as.uses).hasSize(4);
593+
assertThat(as.uses).hasSize(5);
594594
assertThat(as.uses.get(0).node()).isSameAs(array);
595595
assertThat(as.uses.get(1).node()).isSameAs(index);
596596
assertThat(as.uses.get(2).node()).isInstanceOf(Truncate.class);
@@ -615,11 +615,11 @@ public void iastore() {
615615

616616
assertThat(frame.out).isNotNull().isNotSameAs(frame.in);
617617
assertThat(frame.out.stack).isEmpty();
618-
assertThat(frame.out.control).isInstanceOf(LabelNode.class);
618+
assertThat(frame.out.control).isInstanceOf(ArrayStore.class);
619619
assertThat(frame.out.memory).isInstanceOf(ArrayStore.class);
620620

621621
final ArrayStore as = (ArrayStore) frame.out.memory;
622-
assertThat(as.uses).hasSize(4);
622+
assertThat(as.uses).hasSize(5);
623623
assertThat(as.uses.get(0).node()).isSameAs(array);
624624
assertThat(as.uses.get(1).node()).isSameAs(index);
625625
assertThat(as.uses.get(2).node()).isSameAs(value);
@@ -657,11 +657,11 @@ public void lastore() {
657657

658658
assertThat(frame.out).isNotNull().isNotSameAs(frame.in);
659659
assertThat(frame.out.stack).isEmpty();
660-
assertThat(frame.out.control).isInstanceOf(LabelNode.class);
660+
assertThat(frame.out.control).isInstanceOf(ArrayStore.class);
661661
assertThat(frame.out.memory).isInstanceOf(ArrayStore.class);
662662

663663
final ArrayStore as = (ArrayStore) frame.out.memory;
664-
assertThat(as.uses).hasSize(4);
664+
assertThat(as.uses).hasSize(5);
665665
assertThat(as.uses.get(0).node()).isSameAs(array);
666666
assertThat(as.uses.get(1).node()).isSameAs(index);
667667
assertThat(as.uses.get(2).node()).isSameAs(value);
@@ -686,11 +686,11 @@ public void fastore() {
686686

687687
assertThat(frame.out).isNotNull().isNotSameAs(frame.in);
688688
assertThat(frame.out.stack).isEmpty();
689-
assertThat(frame.out.control).isInstanceOf(LabelNode.class);
689+
assertThat(frame.out.control).isInstanceOf(ArrayStore.class);
690690
assertThat(frame.out.memory).isInstanceOf(ArrayStore.class);
691691

692692
final ArrayStore as = (ArrayStore) frame.out.memory;
693-
assertThat(as.uses).hasSize(4);
693+
assertThat(as.uses).hasSize(5);
694694
assertThat(as.uses.get(0).node()).isSameAs(array);
695695
assertThat(as.uses.get(1).node()).isSameAs(index);
696696
assertThat(as.uses.get(2).node()).isSameAs(value);
@@ -715,11 +715,11 @@ public void dastore() {
715715

716716
assertThat(frame.out).isNotNull().isNotSameAs(frame.in);
717717
assertThat(frame.out.stack).isEmpty();
718-
assertThat(frame.out.control).isInstanceOf(LabelNode.class);
718+
assertThat(frame.out.control).isInstanceOf(ArrayStore.class);
719719
assertThat(frame.out.memory).isInstanceOf(ArrayStore.class);
720720

721721
final ArrayStore as = (ArrayStore) frame.out.memory;
722-
assertThat(as.uses).hasSize(4);
722+
assertThat(as.uses).hasSize(5);
723723
assertThat(as.uses.get(0).node()).isSameAs(array);
724724
assertThat(as.uses.get(1).node()).isSameAs(index);
725725
assertThat(as.uses.get(2).node()).isSameAs(value);
@@ -958,11 +958,11 @@ public void putfield() {
958958

959959
assertThat(frame.out).isNotNull().isNotSameAs(frame.in);
960960
assertThat(frame.out.stack).isEmpty();
961-
assertThat(frame.out.control).isInstanceOf(LabelNode.class);
961+
assertThat(frame.out.control).isInstanceOf(PutField.class);
962962
assertThat(frame.out.memory).isInstanceOf(PutField.class);
963963

964964
final PutField put = (PutField) frame.out.memory;
965-
assertThat(put.uses).hasSize(3);
965+
assertThat(put.uses).hasSize(4);
966966
assertThat(put.uses.get(0).node()).isSameAs(target);
967967
assertThat(put.uses.get(0).use()).isEqualTo(new ArgumentUse(0));
968968
assertThat(put.uses.get(1).node()).isSameAs(value);

0 commit comments

Comments
 (0)