Skip to content

Commit

Permalink
fine tune foreach loop reconstruction and line number realignment
Browse files Browse the repository at this point in the history
  • Loading branch information
nbauma109 committed Jun 19, 2022
1 parent b56a2be commit b1aca7e
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,8 @@
import org.jd.core.v1.model.classfile.constant.ConstantMethodref;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;

import jd.core.model.classfile.ConstantPool;
import jd.core.model.classfile.LocalVariable;
Expand All @@ -38,7 +36,7 @@
import jd.core.model.instruction.bytecode.instruction.Invokevirtual;
import jd.core.model.instruction.bytecode.instruction.StoreInstruction;
import jd.core.model.instruction.fast.FastConstants;
import jd.core.process.layouter.visitor.MinLineNumberVisitor;
import jd.core.process.layouter.visitor.MinMaxLineNumberVisitor;

/**
* try-catch-finally
Expand Down Expand Up @@ -69,8 +67,7 @@ public boolean removeOutOfBounds(int firstLineNumber) {
}

public int minLineNumber() {
Optional<Instruction> minLineNoInstr = instructions.stream().min(Comparator.comparing(MinLineNumberVisitor::visit));
return minLineNoInstr.isPresent() ? minLineNoInstr.get().getLineNumber() : Integer.MAX_VALUE;
return MinMaxLineNumberVisitor.visit(instructions).minLineNumber();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,11 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
Expand Down Expand Up @@ -111,8 +109,8 @@
import jd.core.process.analyzer.instruction.fast.reconstructor.TernaryOpInReturnReconstructor;
import jd.core.process.analyzer.instruction.fast.reconstructor.TernaryOpReconstructor;
import jd.core.process.analyzer.util.InstructionUtil;
import jd.core.process.layouter.visitor.MaxLineNumberVisitor;
import jd.core.process.layouter.visitor.MinLineNumberVisitor;
import jd.core.process.layouter.visitor.MinMaxLineNumberVisitor;
import jd.core.process.layouter.visitor.MinMaxLineNumberVisitor.MinMaxLineNumber;
import jd.core.util.IntSet;
import jd.core.util.SignatureUtil;

Expand Down Expand Up @@ -1059,15 +1057,14 @@ private static void createFastTry(ReferenceMap referenceMap, ClassFile classFile

List<Instruction> instructionsToMove = new ArrayList<>();
if (fastTry.hasFinally()) {
Optional<Instruction> finallyMinLineNoInstr = finallyInstructions.stream().min(Comparator.comparing(MinLineNumberVisitor::visit));
Optional<Instruction> finallyMaxLineNoInstr = finallyInstructions.stream().max(Comparator.comparing(MaxLineNumberVisitor::visit));
if (finallyMinLineNoInstr.isPresent() && finallyMaxLineNoInstr.isPresent()) {
MinMaxLineNumber minMaxLineNumber = MinMaxLineNumberVisitor.visit(finallyInstructions);
if (minMaxLineNumber.isValid()) {
for (Instruction tryInstruction : fastTry.getInstructions()) {
if (tryInstruction.getLineNumber() > finallyMaxLineNoInstr.get().getLineNumber()) {
if (tryInstruction.getLineNumber() > minMaxLineNumber.maxLineNumber()) {
instructionsToMove.add(tryInstruction);
}
}
fastTry.removeOutOfBoundsInstructions(finallyMinLineNoInstr.get().getLineNumber());
fastTry.removeOutOfBoundsInstructions(minMaxLineNumber.minLineNumber());
}
}

Expand Down Expand Up @@ -2862,8 +2859,26 @@ private static int createForLoopCase3(ClassFile classFile, Method method, List<I
}
break;
default: {
list.set(beforeWhileLoopIndex, new FastFor(FastConstants.FOR, forLoopOffset, beforeWhileLoop.getLineNumber(),
branch, beforeWhileLoop, test, lastBodyWhileLoop, subList));
MinMaxLineNumber minMaxLineNumber = MinMaxLineNumberVisitor.visit(subList);
if (!subList.isEmpty() && lastBodyWhileLoop.getLineNumber() > minMaxLineNumber.maxLineNumber()) {
if (lastBodyWhileLoop.getOpcode() != Const.GOTO) {
subList.add(lastBodyWhileLoop);
}
Instruction variable = createForEachVariableInstruction(subList.remove(0));
InvokeNoStaticInstruction insi = (InvokeNoStaticInstruction) ((AStore) beforeWhileLoop).getValueref();
Instruction values = insi.getObjectref();

// Remove iterator local variable
removeLocalVariable(method, (StoreInstruction) beforeWhileLoop);

variable.setLineNumber(values.getLineNumber());

list.set(beforeWhileLoopIndex, new FastForEach(FastConstants.FOREACH, forLoopOffset,
values.getLineNumber(), branch, variable, values, subList));
} else {
list.set(beforeWhileLoopIndex, new FastFor(FastConstants.FOR, forLoopOffset, beforeWhileLoop.getLineNumber(),
branch, beforeWhileLoop, test, lastBodyWhileLoop, subList));
}
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*******************************************************************************
* Copyright (C) 2022 GPLv3
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
package jd.core.process.layouter.visitor;

import java.util.List;

import jd.core.model.instruction.bytecode.instruction.Instruction;

public final class MinMaxLineNumberVisitor {

private MinMaxLineNumberVisitor() {
}

public static MinMaxLineNumber visit(List<Instruction> instructions) {
int minLineNumber = Integer.MAX_VALUE;
int maxLineNumber = Integer.MIN_VALUE;
for (Instruction instruction : instructions) {
minLineNumber = Math.min(minLineNumber, MinLineNumberVisitor.visit(instruction));
maxLineNumber = Math.max(maxLineNumber, MaxLineNumberVisitor.visit(instruction));
}
return new MinMaxLineNumber(minLineNumber, maxLineNumber);
}

public record MinMaxLineNumber(int minLineNumber, int maxLineNumber) {

public boolean isValid() {
return minLineNumber != Integer.MAX_VALUE && maxLineNumber != Integer.MIN_VALUE;
}
}
}

0 comments on commit b1aca7e

Please sign in to comment.