Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,13 @@ public enum KFunctionType implements Typed {
STR_TEMPLATE
}

public KFunctionExprent(KFunctionType funcType, List<Exprent> operands, BitSet bytecodeOffsets) {
public KFunctionExprent(KFunctionType funcType, List<Exprent> operands, BytecodeRange bytecodeOffsets) {
this(FunctionType.OTHER, operands, bytecodeOffsets);

this.kType = funcType;
}

public KFunctionExprent(FunctionType funcType, List<Exprent> operands, BitSet bytecodeOffsets) {
public KFunctionExprent(FunctionType funcType, List<Exprent> operands, BytecodeRange bytecodeOffsets) {
super(funcType, new ArrayList<>(KUtils.replaceExprents(operands)), bytecodeOffsets);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public enum DeclarationType {

private DeclarationType declarationType;

public KVarExprent(int index, VarType varType, VarProcessor processor, BitSet bytecode) {
public KVarExprent(int index, VarType varType, VarProcessor processor, BytecodeRange bytecode) {
super(index, varType, processor, bytecode);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,7 @@ else if (args.length > x+1) {
System.out.println("error: Failed to read config file '" + path + "'");
throw new RuntimeException(e);
}
}
else {
} else {
params.add(args[x]);
}
}
Expand Down
24 changes: 16 additions & 8 deletions src/org/jetbrains/java/decompiler/main/rels/MethodProcessor.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import org.jetbrains.java.decompiler.modules.decompiler.deobfuscator.ExceptionDeobfuscator;
import org.jetbrains.java.decompiler.modules.decompiler.flow.DirectGraph;
import org.jetbrains.java.decompiler.modules.decompiler.flow.FlattenStatementsHelper;
import org.jetbrains.java.decompiler.modules.decompiler.stats.BasicBlockStatement;
import org.jetbrains.java.decompiler.modules.decompiler.stats.RootStatement;
import org.jetbrains.java.decompiler.modules.decompiler.vars.VarProcessor;
import org.jetbrains.java.decompiler.struct.StructClass;
Expand Down Expand Up @@ -88,9 +89,9 @@ public void run() {
public static RootStatement codeToJava(StructClass cl, StructMethod mt, MethodDescriptor md, VarProcessor varProc, LanguageSpec spec) throws IOException {
CancelationManager.checkCanceled();

debugCurrentlyDecompiling.set(null);
debugCurrentCFG.set(null);
debugCurrentDecompileRecord.set(null);
debugCurrentlyDecompiling.remove();
debugCurrentCFG.remove();
debugCurrentDecompileRecord.remove();

boolean isInitializer = CodeConstants.CLINIT_NAME.equals(mt.getName()); // for now static initializer only
PluginContext pluginContext = PluginContext.getCurrentContext();
Expand Down Expand Up @@ -253,6 +254,12 @@ public static RootStatement codeToJava(StructClass cl, StructMethod mt, MethodDe

// Main loop
while (true) {
if (root.isSimple() && root.getFirst().getExprents().size() <= 1) {
LabelHelper.identifyLabels(root);
decompileRecord.add("IdentifyLabels", root);
break;
}

decompileRecord.incrementMainLoop();
decompileRecord.add("Start", root);

Expand Down Expand Up @@ -311,11 +318,6 @@ public static RootStatement codeToJava(StructClass cl, StructMethod mt, MethodDe
continue;
}

if (IntersectionCastProcessor.makeIntersectionCasts(root)) {
decompileRecord.add("intersectionCasts", root);
continue;
}

if (DecompilerContext.getOption(IFernflowerPreferences.PATTERN_MATCHING)) {
if (cl.getVersion().hasIfPatternMatching()) {
if (IfPatternMatchProcessor.matchInstanceof(root)) {
Expand Down Expand Up @@ -444,6 +446,10 @@ public static RootStatement codeToJava(StructClass cl, StructMethod mt, MethodDe
decompileRecord.add("HideEmptyDefault", root);
}

if (IntersectionCastProcessor.makeIntersectionCasts(root)) {
decompileRecord.add("intersectionCasts", root);
}

if (GenericsProcessor.qualifyChains(root)) {
decompileRecord.add("QualifyGenericChains", root);
}
Expand Down Expand Up @@ -476,6 +482,8 @@ public static RootStatement codeToJava(StructClass cl, StructMethod mt, MethodDe
// Debug print the decompile record
DotExporter.toDotFile(decompileRecord, mt, "decompileRecord", false);

// Delete unneeded data now that processing is complete
ExprProcessor.releaseResources(root, varProc);
mt.releaseResources();

return root;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ else if (found == 2) {
return createConcatExprent(lstOperands, expr.bytecode);
}

private static Exprent createConcatExprent(List<Exprent> lstOperands, BitSet bytecode) {
private static Exprent createConcatExprent(List<Exprent> lstOperands, Exprent.BytecodeRange bytecode) {
// build exprent to return
Exprent func = lstOperands.get(0);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,10 +212,10 @@ public void processBlock(BasicBlockStatement stat, PrimitiveExprsList data, Stru

Instruction instr = seq.getInstr(i);
Integer bytecode_offset = block.getOldOffset(i);
BitSet bytecode_offsets = null;
Exprent.BytecodeRange bytecode_offsets = null;
if (bytecode_offset >= 0) {
bytecode_offsets = new BitSet();
bytecode_offsets.set(bytecode_offset, bytecode_offset + instr.length);
bytecode_offsets = new Exprent.BytecodeRange(new Exprent.BytecodeSet.Range(bytecode_offset, bytecode_offset + instr.length - 1));
// bytecode_offsets.set();
}

switch (instr.opcode) {
Expand Down Expand Up @@ -308,7 +308,7 @@ else if (cn instanceof LinkConstant) {
Exprent expr = stack.pop();
int varindex = instr.operand(0);
if (bytecode_offsets != null) { //TODO: Figure out why this nulls in some cases
bytecode_offsets.set(bytecode_offset, bytecode_offset + instr.length);
bytecode_offsets.or(new Exprent.BytecodeRange(new Exprent.BytecodeSet.Range(bytecode_offset, bytecode_offset + instr.length - 1)));
}
varExprent = new VarExprent(varindex, varTypes[instr.opcode - opc_istore], varProcessor, bytecode_offsets);
varExprent.setBackingInstr(instr);
Expand Down Expand Up @@ -747,6 +747,23 @@ private static void markExprOddity(RootStatement root, Exprent ex) {
}
}

public static void releaseResources(RootStatement stat, VarProcessor varProc) {
releaseResources(stat);

varProc.getVarVersions().getTypeProcessor().getUpperBounds().clear();
}

private static void releaseResources(Statement stat) {
for (Statement st : stat.getStats()) {
releaseResources(st);
}

if (stat instanceof BasicBlockStatement block) {
((ArrayList<Integer>)block.getBlock().getInstrOldOffsets()).trimToSize();
((ArrayList<Exprent>) block.getExprents()).trimToSize();
}
}

public static String getTypeName(VarType type) {
return getTypeName(type, true);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,11 @@ public class FinallyProcessor {
private final StructMethod mt;
private final MethodDescriptor methodDescriptor;
private final VarProcessor varProcessor;

// Ephemeral variables
private VarVersionsGraph ssuversions;
private Map<Instruction, Integer> instrRewrites;
private RootStatement root;

public FinallyProcessor(StructMethod mt, MethodDescriptor md, VarProcessor varProc) {
this.mt = mt;
Expand All @@ -57,6 +60,8 @@ public FinallyProcessor(StructMethod mt, MethodDescriptor md, VarProcessor varPr

public boolean iterateGraph(StructClass cl, StructMethod mt, RootStatement root, ControlFlowGraph graph) {
this.ssuversions = null;
this.instrRewrites = null;
this.root = root;
BytecodeVersion bytecodeVersion = mt.getBytecodeVersion();

ListStack<Statement> stack = new ListStack<>();
Expand Down Expand Up @@ -130,26 +135,35 @@ private Record(int firstCode, Map<BasicBlock, Boolean> mapLast) {
}
}

private Record getFinallyInformation(StructClass cl, StructMethod mt, RootStatement root, CatchAllStatement fstat) {
ExprProcessor proc = new ExprProcessor(this.methodDescriptor, this.varProcessor);
proc.processStatement(root, cl);

if (this.ssuversions == null) {
// FIXME: don't split SSAU unless needed!
private Map<Instruction, Integer> getInstrRewrites() {
if (this.instrRewrites == null) {
SSAConstructorSparseEx ssa = new SSAConstructorSparseEx();
ssa.splitVariables(root, mt);

this.instrRewrites = SimpleSSAReassign.reassignSSAForm(ssa, root);

StackVarsProcessor.setVersionsToNull(root);
}

return this.instrRewrites;
}

private VarVersionsGraph getVarVersionsGraph() {
if (this.ssuversions == null) {
SSAUConstructorSparseEx ssau = new SSAUConstructorSparseEx();
ssau.splitVariables(root, mt);

this.ssuversions = ssau.getSsuVersions();
StackVarsProcessor.setVersionsToNull(root);
}

return this.ssuversions;
}

private Record getFinallyInformation(StructClass cl, StructMethod mt, RootStatement root, CatchAllStatement fstat) {
ExprProcessor proc = new ExprProcessor(this.methodDescriptor, this.varProcessor);
proc.processStatement(root, cl);

Map<BasicBlock, Boolean> mapLast = new LinkedHashMap<>();

BasicBlockStatement firstBlockStatement = fstat.getHandler().getBasichead();
Expand Down Expand Up @@ -921,14 +935,15 @@ public boolean equalInstructions(Instruction first, Instruction second, List<int
boolean ok = false;
if (isOpcVar(first.opcode)) {
// Find rewritten variables
if (this.instrRewrites.containsKey(first)) {
firstOp = this.instrRewrites.get(first);
Map<Instruction, Integer> rewrites = this.getInstrRewrites();
if (rewrites.containsKey(first)) {
firstOp = rewrites.get(first);
}
if (this.instrRewrites.containsKey(second)) {
secondOp = this.instrRewrites.get(second);
if (rewrites.containsKey(second)) {
secondOp = rewrites.get(second);
}

if (this.ssuversions.areVarsAnalogous(firstOp, secondOp)) {
if (this.getVarVersionsGraph().areVarsAnalogous(firstOp, secondOp)) {
ok = true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1044,7 +1044,7 @@ private static boolean buildIff(Statement stat, SSAConstructorSparseEx ssa) {
if (stat instanceof IfStatement && stat.getExprents() == null) {
IfStatement statement = (IfStatement) stat;
Exprent ifHeadExpr = statement.getHeadexprent();
BitSet ifHeadExprBytecode = (ifHeadExpr == null ? null : ifHeadExpr.bytecode);
Exprent.BytecodeRange ifHeadExprBytecode = (ifHeadExpr == null ? null : ifHeadExpr.bytecode);

if (statement.iftype == IfStatement.IFTYPE_IFELSE) {
Statement ifStatement = statement.getIfstat();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ public void setDidWriteAlready(boolean didWriteAlready) {
}

@Override
public void getBytecodeRange(BitSet values) {
public void getBytecodeRange(BytecodeRange values) {
measureBytecode(values, parValues);
measureBytecode(values);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public class ArrayExprent extends Exprent {
private Exprent index;
private final VarType hardType;

public ArrayExprent(Exprent array, Exprent index, VarType hardType, BitSet bytecodeOffsets) {
public ArrayExprent(Exprent array, Exprent index, VarType hardType, BytecodeRange bytecodeOffsets) {
super(Type.ARRAY);
this.array = array;
this.index = index;
Expand Down Expand Up @@ -130,7 +130,7 @@ public Exprent getIndex() {
}

@Override
public void getBytecodeRange(BitSet values) {
public void getBytecodeRange(BytecodeRange values) {
measureBytecode(values, array);
measureBytecode(values, index);
measureBytecode(values);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public TextBuffer toJava(int indent) {
}

@Override
public void getBytecodeRange(BitSet values) {
public void getBytecodeRange(BytecodeRange values) {
measureBytecode(values, parameters);
measureBytecode(values);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,15 @@ public class AssignmentExprent extends Exprent {
private Exprent right;
private FunctionExprent.FunctionType condType = null;

public AssignmentExprent(Exprent left, Exprent right, BitSet bytecodeOffsets) {
public AssignmentExprent(Exprent left, Exprent right, BytecodeRange bytecodeOffsets) {
super(Type.ASSIGNMENT);
this.left = left;
this.right = right;

addBytecodeOffsets(bytecodeOffsets);
}

public AssignmentExprent(Exprent left, Exprent right, FunctionExprent.FunctionType condType, BitSet bytecodeOffsets) {
public AssignmentExprent(Exprent left, Exprent right, FunctionExprent.FunctionType condType, BytecodeRange bytecodeOffsets) {
this(left, right, bytecodeOffsets);
this.condType = condType;
}
Expand Down Expand Up @@ -286,7 +286,7 @@ public boolean equals(Object o) {
}

@Override
public void getBytecodeRange(BitSet values) {
public void getBytecodeRange(BytecodeRange values) {
measureBytecode(values, left);
measureBytecode(values, right);
measureBytecode(values);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@

public class ConstExprent extends Exprent {
private static final Map<Integer, String> CHAR_ESCAPES = new HashMap<>();
private static final Map<Double, Function<BitSet, TextBuffer>> UNINLINED_DOUBLES = new HashMap<>();
private static final Map<Float, Function<BitSet, TextBuffer>> UNINLINED_FLOATS = new HashMap<>();
private static final Map<Double, Function<BytecodeRange, TextBuffer>> UNINLINED_DOUBLES = new HashMap<>();
private static final Map<Float, Function<BytecodeRange, TextBuffer>> UNINLINED_FLOATS = new HashMap<>();
private static final Set<Object> NO_PAREN_VALUES = new HashSet<>();

static {
Expand Down Expand Up @@ -134,20 +134,20 @@ public class ConstExprent extends Exprent {
private final boolean boolPermitted;
private boolean wasCondy = false;

public ConstExprent(int val, boolean boolPermitted, BitSet bytecodeOffsets) {
public ConstExprent(int val, boolean boolPermitted, BytecodeRange bytecodeOffsets) {
this(guessType(val, boolPermitted), val, boolPermitted, bytecodeOffsets);
}

public ConstExprent(VarType constType, Object value, BitSet bytecodeOffsets) {
public ConstExprent(VarType constType, Object value, BytecodeRange bytecodeOffsets) {
this(constType, value, false, bytecodeOffsets);
}

public ConstExprent(VarType constType, Object value, BitSet bytecodeOffsets, boolean wasCondy) {
public ConstExprent(VarType constType, Object value, BytecodeRange bytecodeOffsets, boolean wasCondy) {
this(constType, value, false, bytecodeOffsets);
this.wasCondy = wasCondy;
}

protected ConstExprent(VarType constType, Object value, boolean boolPermitted, BitSet bytecodeOffsets) {
protected ConstExprent(VarType constType, Object value, boolean boolPermitted, BytecodeRange bytecodeOffsets) {
super(Type.CONST);
this.constType = constType;
this.value = value;
Expand Down Expand Up @@ -386,15 +386,15 @@ public int getPrecedence() {
return super.getPrecedence();
}

private static TextBuffer getPiDouble(BitSet bytecode) {
private static TextBuffer getPiDouble(BytecodeRange bytecode) {
return getDouble(bytecode, "PI", "java/lang/Math");
}

private static TextBuffer getDouble(BitSet bytecode, String name, String className) {
private static TextBuffer getDouble(BytecodeRange bytecode, String name, String className) {
return new FieldExprent(name, className, true, null, FieldDescriptor.DOUBLE_DESCRIPTOR, bytecode).toJava(0);
}

private static TextBuffer getFloat(BitSet bytecode, String name, String className) {
private static TextBuffer getFloat(BytecodeRange bytecode, String name, String className) {
return new FieldExprent(name, className, true, null, FieldDescriptor.FLOAT_DESCRIPTOR, bytecode).toJava(0);
}

Expand Down Expand Up @@ -640,7 +640,7 @@ public boolean isBoolPermitted() {
}

@Override
public void getBytecodeRange(BitSet values) {
public void getBytecodeRange(BytecodeRange values) {
measureBytecode(values);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public enum Type {
private final VarType retType;
private final MethodDescriptor methodDescriptor;

public ExitExprent(Type exitType, Exprent value, VarType retType, BitSet bytecodeOffsets, MethodDescriptor methodDescriptor) {
public ExitExprent(Type exitType, Exprent value, VarType retType, BytecodeRange bytecodeOffsets, MethodDescriptor methodDescriptor) {
super(Exprent.Type.EXIT);
this.exitType = exitType;
this.value = value;
Expand Down Expand Up @@ -155,7 +155,7 @@ public MethodDescriptor getMethodDescriptor() {
}

@Override
public void getBytecodeRange(BitSet values) {
public void getBytecodeRange(BytecodeRange values) {
measureBytecode(values, value);
measureBytecode(values);
}
Expand Down
Loading
Loading