|
|
@ -14,12 +14,14 @@ |
|
|
|
|
|
|
|
|
|
|
|
package de.fernflower.modules.decompiler.sforms; |
|
|
|
package de.fernflower.modules.decompiler.sforms; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import java.io.File; |
|
|
|
import java.util.ArrayList; |
|
|
|
import java.util.ArrayList; |
|
|
|
import java.util.HashMap; |
|
|
|
import java.util.HashMap; |
|
|
|
import java.util.HashSet; |
|
|
|
import java.util.HashSet; |
|
|
|
import java.util.List; |
|
|
|
import java.util.List; |
|
|
|
import java.util.Map.Entry; |
|
|
|
import java.util.Map.Entry; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import test.util.DotExporter; |
|
|
|
import de.fernflower.code.CodeConstants; |
|
|
|
import de.fernflower.code.CodeConstants; |
|
|
|
import de.fernflower.modules.decompiler.exps.AssignmentExprent; |
|
|
|
import de.fernflower.modules.decompiler.exps.AssignmentExprent; |
|
|
|
import de.fernflower.modules.decompiler.exps.Exprent; |
|
|
|
import de.fernflower.modules.decompiler.exps.Exprent; |
|
|
@ -34,9 +36,9 @@ import de.fernflower.modules.decompiler.vars.VarVersionPaar; |
|
|
|
import de.fernflower.struct.StructMethod; |
|
|
|
import de.fernflower.struct.StructMethod; |
|
|
|
import de.fernflower.struct.gen.MethodDescriptor; |
|
|
|
import de.fernflower.struct.gen.MethodDescriptor; |
|
|
|
import de.fernflower.util.FastSparseSetFactory; |
|
|
|
import de.fernflower.util.FastSparseSetFactory; |
|
|
|
|
|
|
|
import de.fernflower.util.FastSparseSetFactory.FastSparseSet; |
|
|
|
import de.fernflower.util.InterpreterUtil; |
|
|
|
import de.fernflower.util.InterpreterUtil; |
|
|
|
import de.fernflower.util.SFormsFastMapDirect; |
|
|
|
import de.fernflower.util.SFormsFastMapDirect; |
|
|
|
import de.fernflower.util.FastSparseSetFactory.FastSparseSet; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public class SSAConstructorSparseEx { |
|
|
|
public class SSAConstructorSparseEx { |
|
|
|
|
|
|
|
|
|
|
@ -68,12 +70,12 @@ public class SSAConstructorSparseEx { |
|
|
|
FlattenStatementsHelper flatthelper = new FlattenStatementsHelper(); |
|
|
|
FlattenStatementsHelper flatthelper = new FlattenStatementsHelper(); |
|
|
|
DirectGraph dgraph = flatthelper.buildDirectGraph(root); |
|
|
|
DirectGraph dgraph = flatthelper.buildDirectGraph(root); |
|
|
|
|
|
|
|
|
|
|
|
// try {
|
|
|
|
// try {
|
|
|
|
// DotExporter.toDotFile(dgraph, new File("c:\\Temp\\gr12_my.dot"));
|
|
|
|
// DotExporter.toDotFile(dgraph, new File("c:\\Temp\\gr12_my.dot"));
|
|
|
|
// } catch(Exception ex) {ex.printStackTrace();}
|
|
|
|
// } catch(Exception ex) {ex.printStackTrace();}
|
|
|
|
|
|
|
|
|
|
|
|
HashSet<Integer> setInit = new HashSet<Integer>(); |
|
|
|
HashSet<Integer> setInit = new HashSet<Integer>(); |
|
|
|
for(int i=0;i<64;i++) { |
|
|
|
for(int i = 0; i < 64; i++) { |
|
|
|
setInit.add(i); |
|
|
|
setInit.add(i); |
|
|
|
} |
|
|
|
} |
|
|
|
factory = new FastSparseSetFactory<Integer>(setInit); |
|
|
|
factory = new FastSparseSetFactory<Integer>(setInit); |
|
|
@ -85,19 +87,29 @@ public class SSAConstructorSparseEx { |
|
|
|
|
|
|
|
|
|
|
|
HashSet<String> updated = new HashSet<String>(); |
|
|
|
HashSet<String> updated = new HashSet<String>(); |
|
|
|
do { |
|
|
|
do { |
|
|
|
// System.out.println("~~~~~~~~~~~~~ \r\n"+root.toJava());
|
|
|
|
// System.out.println("~~~~~~~~~~~~~ \r\n"+root.toJava());
|
|
|
|
ssaStatements(dgraph, updated); |
|
|
|
ssaStatements(dgraph, updated); |
|
|
|
// System.out.println("~~~~~~~~~~~~~ \r\n"+root.toJava());
|
|
|
|
// System.out.println("~~~~~~~~~~~~~ \r\n"+root.toJava());
|
|
|
|
} while(!updated.isEmpty()); |
|
|
|
} while (!updated.isEmpty()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private void ssaStatements(DirectGraph dgraph, HashSet<String> updated) { |
|
|
|
private void ssaStatements(DirectGraph dgraph, HashSet<String> updated) { |
|
|
|
|
|
|
|
|
|
|
|
// try {
|
|
|
|
// try {
|
|
|
|
// DotExporter.toDotFile(dgraph, new File("c:\\Temp\\gr1_my.dot"));
|
|
|
|
// DotExporter.toDotFile(dgraph, new File("c:\\Temp\\gr1_my.dot"));
|
|
|
|
// } catch(Exception ex) {ex.printStackTrace();}
|
|
|
|
// } catch(Exception ex) {ex.printStackTrace();}
|
|
|
|
|
|
|
|
|
|
|
|
for(DirectNode node: dgraph.nodes) { |
|
|
|
for(DirectNode node : dgraph.nodes) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// if (node.id.endsWith("_inc")) {
|
|
|
|
|
|
|
|
// System.out.println();
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// try {
|
|
|
|
|
|
|
|
// DotExporter.toDotFile(dgraph, new File("c:\\Temp\\gr1_my.dot"));
|
|
|
|
|
|
|
|
// } catch (Exception ex) {
|
|
|
|
|
|
|
|
// ex.printStackTrace();
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
updated.remove(node.id); |
|
|
|
updated.remove(node.id); |
|
|
|
mergeInVarMaps(node, dgraph); |
|
|
|
mergeInVarMaps(node, dgraph); |
|
|
@ -105,28 +117,28 @@ public class SSAConstructorSparseEx { |
|
|
|
SFormsFastMapDirect varmap = inVarVersions.get(node.id); |
|
|
|
SFormsFastMapDirect varmap = inVarVersions.get(node.id); |
|
|
|
varmap = new SFormsFastMapDirect(varmap); |
|
|
|
varmap = new SFormsFastMapDirect(varmap); |
|
|
|
|
|
|
|
|
|
|
|
SFormsFastMapDirect[] varmaparr = new SFormsFastMapDirect[] {varmap, null}; |
|
|
|
SFormsFastMapDirect[] varmaparr = new SFormsFastMapDirect[] { varmap, null }; |
|
|
|
|
|
|
|
|
|
|
|
if(node.exprents != null) { |
|
|
|
if (node.exprents != null) { |
|
|
|
for(Exprent expr: node.exprents) { |
|
|
|
for(Exprent expr : node.exprents) { |
|
|
|
processExprent(expr, varmaparr); |
|
|
|
processExprent(expr, varmaparr); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if(varmaparr[1] == null) { |
|
|
|
if (varmaparr[1] == null) { |
|
|
|
varmaparr[1] = varmaparr[0]; |
|
|
|
varmaparr[1] = varmaparr[0]; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
boolean this_updated = !mapsEqual(varmaparr[0], outVarVersions.get(node.id)) |
|
|
|
boolean this_updated = !mapsEqual(varmaparr[0], outVarVersions.get(node.id)) |
|
|
|
|| (outNegVarVersions.containsKey(node.id) && !mapsEqual(varmaparr[1], outNegVarVersions.get(node.id))); |
|
|
|
|| (outNegVarVersions.containsKey(node.id) && !mapsEqual(varmaparr[1], outNegVarVersions.get(node.id))); |
|
|
|
|
|
|
|
|
|
|
|
if(this_updated) { |
|
|
|
if (this_updated) { |
|
|
|
outVarVersions.put(node.id, varmaparr[0]); |
|
|
|
outVarVersions.put(node.id, varmaparr[0]); |
|
|
|
if(dgraph.mapNegIfBranch.containsKey(node.id)) { |
|
|
|
if (dgraph.mapNegIfBranch.containsKey(node.id)) { |
|
|
|
outNegVarVersions.put(node.id, varmaparr[1]); |
|
|
|
outNegVarVersions.put(node.id, varmaparr[1]); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
for(DirectNode nd: node.succs) { |
|
|
|
for(DirectNode nd : node.succs) { |
|
|
|
updated.add(nd.id); |
|
|
|
updated.add(nd.id); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -136,32 +148,31 @@ public class SSAConstructorSparseEx { |
|
|
|
|
|
|
|
|
|
|
|
private void processExprent(Exprent expr, SFormsFastMapDirect[] varmaparr) { |
|
|
|
private void processExprent(Exprent expr, SFormsFastMapDirect[] varmaparr) { |
|
|
|
|
|
|
|
|
|
|
|
if(expr == null) { |
|
|
|
if (expr == null) { |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
VarExprent varassign = null; |
|
|
|
VarExprent varassign = null; |
|
|
|
boolean finished = false; |
|
|
|
boolean finished = false; |
|
|
|
|
|
|
|
|
|
|
|
switch(expr.type) { |
|
|
|
switch (expr.type) { |
|
|
|
case Exprent.EXPRENT_ASSIGNMENT: |
|
|
|
case Exprent.EXPRENT_ASSIGNMENT: |
|
|
|
AssignmentExprent assexpr = (AssignmentExprent)expr; |
|
|
|
AssignmentExprent assexpr = (AssignmentExprent) expr; |
|
|
|
if(assexpr.getCondtype() == AssignmentExprent.CONDITION_NONE) { |
|
|
|
if (assexpr.getCondtype() == AssignmentExprent.CONDITION_NONE) { |
|
|
|
Exprent dest = assexpr.getLeft(); |
|
|
|
Exprent dest = assexpr.getLeft(); |
|
|
|
if(dest.type == Exprent.EXPRENT_VAR) { |
|
|
|
if (dest.type == Exprent.EXPRENT_VAR) { |
|
|
|
varassign = (VarExprent)dest; |
|
|
|
varassign = (VarExprent) dest; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
break; |
|
|
|
break; |
|
|
|
case Exprent.EXPRENT_FUNCTION: |
|
|
|
case Exprent.EXPRENT_FUNCTION: |
|
|
|
FunctionExprent func = (FunctionExprent)expr; |
|
|
|
FunctionExprent func = (FunctionExprent) expr; |
|
|
|
switch(func.getFunctype()) { |
|
|
|
switch (func.getFunctype()) { |
|
|
|
case FunctionExprent.FUNCTION_IIF: |
|
|
|
case FunctionExprent.FUNCTION_IIF: |
|
|
|
processExprent(func.getLstOperands().get(0), varmaparr); |
|
|
|
processExprent(func.getLstOperands().get(0), varmaparr); |
|
|
|
|
|
|
|
|
|
|
|
SFormsFastMapDirect varmapFalse; |
|
|
|
SFormsFastMapDirect varmapFalse; |
|
|
|
if(varmaparr[1] == null) { |
|
|
|
if (varmaparr[1] == null) { |
|
|
|
varmapFalse = new SFormsFastMapDirect(varmaparr[0]); |
|
|
|
varmapFalse = new SFormsFastMapDirect(varmaparr[0]); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
varmapFalse = varmaparr[1]; |
|
|
|
varmapFalse = varmaparr[1]; |
|
|
@ -170,7 +181,7 @@ public class SSAConstructorSparseEx { |
|
|
|
|
|
|
|
|
|
|
|
processExprent(func.getLstOperands().get(1), varmaparr); |
|
|
|
processExprent(func.getLstOperands().get(1), varmaparr); |
|
|
|
|
|
|
|
|
|
|
|
SFormsFastMapDirect[] varmaparrNeg = new SFormsFastMapDirect[] {varmapFalse, null}; |
|
|
|
SFormsFastMapDirect[] varmaparrNeg = new SFormsFastMapDirect[] { varmapFalse, null }; |
|
|
|
processExprent(func.getLstOperands().get(2), varmaparrNeg); |
|
|
|
processExprent(func.getLstOperands().get(2), varmaparrNeg); |
|
|
|
|
|
|
|
|
|
|
|
mergeMaps(varmaparr[0], varmaparrNeg[0]); |
|
|
|
mergeMaps(varmaparr[0], varmaparrNeg[0]); |
|
|
@ -181,12 +192,12 @@ public class SSAConstructorSparseEx { |
|
|
|
case FunctionExprent.FUNCTION_CADD: |
|
|
|
case FunctionExprent.FUNCTION_CADD: |
|
|
|
processExprent(func.getLstOperands().get(0), varmaparr); |
|
|
|
processExprent(func.getLstOperands().get(0), varmaparr); |
|
|
|
|
|
|
|
|
|
|
|
SFormsFastMapDirect[] varmaparrAnd = new SFormsFastMapDirect[] {new SFormsFastMapDirect(varmaparr[0]), null}; |
|
|
|
SFormsFastMapDirect[] varmaparrAnd = new SFormsFastMapDirect[] { new SFormsFastMapDirect(varmaparr[0]), null }; |
|
|
|
|
|
|
|
|
|
|
|
processExprent(func.getLstOperands().get(1), varmaparrAnd); |
|
|
|
processExprent(func.getLstOperands().get(1), varmaparrAnd); |
|
|
|
|
|
|
|
|
|
|
|
// false map
|
|
|
|
// false map
|
|
|
|
varmaparr[1] = mergeMaps(varmaparr[varmaparr[1]==null?0:1], varmaparrAnd[varmaparrAnd[1]==null?0:1]); |
|
|
|
varmaparr[1] = mergeMaps(varmaparr[varmaparr[1] == null ? 0 : 1], varmaparrAnd[varmaparrAnd[1] == null ? 0 : 1]); |
|
|
|
// true map
|
|
|
|
// true map
|
|
|
|
varmaparr[0] = varmaparrAnd[0]; |
|
|
|
varmaparr[0] = varmaparrAnd[0]; |
|
|
|
|
|
|
|
|
|
|
@ -195,12 +206,12 @@ public class SSAConstructorSparseEx { |
|
|
|
case FunctionExprent.FUNCTION_COR: |
|
|
|
case FunctionExprent.FUNCTION_COR: |
|
|
|
processExprent(func.getLstOperands().get(0), varmaparr); |
|
|
|
processExprent(func.getLstOperands().get(0), varmaparr); |
|
|
|
|
|
|
|
|
|
|
|
SFormsFastMapDirect[] varmaparrOr = new SFormsFastMapDirect[] {new SFormsFastMapDirect(varmaparr[varmaparr[1]==null?0:1]), null}; |
|
|
|
SFormsFastMapDirect[] varmaparrOr = new SFormsFastMapDirect[] { new SFormsFastMapDirect(varmaparr[varmaparr[1] == null ? 0 : 1]), null }; |
|
|
|
|
|
|
|
|
|
|
|
processExprent(func.getLstOperands().get(1), varmaparrOr); |
|
|
|
processExprent(func.getLstOperands().get(1), varmaparrOr); |
|
|
|
|
|
|
|
|
|
|
|
// false map
|
|
|
|
// false map
|
|
|
|
varmaparr[1] = varmaparrOr[varmaparrOr[1]==null?0:1]; |
|
|
|
varmaparr[1] = varmaparrOr[varmaparrOr[1] == null ? 0 : 1]; |
|
|
|
// true map
|
|
|
|
// true map
|
|
|
|
varmaparr[0] = mergeMaps(varmaparr[0], varmaparrOr[0]); |
|
|
|
varmaparr[0] = mergeMaps(varmaparr[0], varmaparrOr[0]); |
|
|
|
|
|
|
|
|
|
|
@ -208,26 +219,24 @@ public class SSAConstructorSparseEx { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if(finished) { |
|
|
|
if (finished) { |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
List<Exprent> lst = expr.getAllExprents(); |
|
|
|
List<Exprent> lst = expr.getAllExprents(); |
|
|
|
lst.remove(varassign); |
|
|
|
lst.remove(varassign); |
|
|
|
|
|
|
|
|
|
|
|
for(Exprent ex: lst) { |
|
|
|
for(Exprent ex : lst) { |
|
|
|
processExprent(ex, varmaparr); |
|
|
|
processExprent(ex, varmaparr); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SFormsFastMapDirect varmap = varmaparr[0]; |
|
|
|
SFormsFastMapDirect varmap = varmaparr[0]; |
|
|
|
|
|
|
|
|
|
|
|
if(varassign != null) { |
|
|
|
if (varassign != null) { |
|
|
|
|
|
|
|
|
|
|
|
Integer varindex = varassign.getIndex(); |
|
|
|
Integer varindex = varassign.getIndex(); |
|
|
|
|
|
|
|
|
|
|
|
if(varassign.getVersion() == 0) { |
|
|
|
if (varassign.getVersion() == 0) { |
|
|
|
// get next version
|
|
|
|
// get next version
|
|
|
|
Integer nextver = getNextFreeVersion(varindex); |
|
|
|
Integer nextver = getNextFreeVersion(varindex); |
|
|
|
|
|
|
|
|
|
|
@ -239,22 +248,22 @@ public class SSAConstructorSparseEx { |
|
|
|
setCurrentVar(varmap, varindex, varassign.getVersion()); |
|
|
|
setCurrentVar(varmap, varindex, varassign.getVersion()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} else if(expr.type == Exprent.EXPRENT_VAR) { |
|
|
|
} else if (expr.type == Exprent.EXPRENT_VAR) { |
|
|
|
|
|
|
|
|
|
|
|
VarExprent vardest = (VarExprent)expr; |
|
|
|
VarExprent vardest = (VarExprent) expr; |
|
|
|
Integer varindex = vardest.getIndex(); |
|
|
|
Integer varindex = vardest.getIndex(); |
|
|
|
FastSparseSet<Integer> vers = varmap.get(varindex); |
|
|
|
FastSparseSet<Integer> vers = varmap.get(varindex); |
|
|
|
|
|
|
|
|
|
|
|
int cardinality = vers.getCardinality(); |
|
|
|
int cardinality = vers.getCardinality(); |
|
|
|
if(cardinality == 1) { // == 1
|
|
|
|
if (cardinality == 1) { // == 1
|
|
|
|
// set version
|
|
|
|
// set version
|
|
|
|
Integer it = vers.iterator().next(); |
|
|
|
Integer it = vers.iterator().next(); |
|
|
|
vardest.setVersion(it.intValue()); |
|
|
|
vardest.setVersion(it.intValue()); |
|
|
|
} else if(cardinality == 2) { // size > 1
|
|
|
|
} else if (cardinality == 2) { // size > 1
|
|
|
|
Integer current_vers = vardest.getVersion(); |
|
|
|
Integer current_vers = vardest.getVersion(); |
|
|
|
|
|
|
|
|
|
|
|
VarVersionPaar currpaar = new VarVersionPaar(varindex, current_vers); |
|
|
|
VarVersionPaar currpaar = new VarVersionPaar(varindex, current_vers); |
|
|
|
if(current_vers != 0 && phi.containsKey(currpaar)) { |
|
|
|
if (current_vers != 0 && phi.containsKey(currpaar)) { |
|
|
|
setCurrentVar(varmap, varindex, current_vers); |
|
|
|
setCurrentVar(varmap, varindex, current_vers); |
|
|
|
// update phi node
|
|
|
|
// update phi node
|
|
|
|
phi.get(currpaar).union(vers); |
|
|
|
phi.get(currpaar).union(vers); |
|
|
@ -275,10 +284,10 @@ public class SSAConstructorSparseEx { |
|
|
|
|
|
|
|
|
|
|
|
private Integer getNextFreeVersion(Integer var) { |
|
|
|
private Integer getNextFreeVersion(Integer var) { |
|
|
|
Integer nextver = lastversion.get(var); |
|
|
|
Integer nextver = lastversion.get(var); |
|
|
|
if(nextver==null) { |
|
|
|
if (nextver == null) { |
|
|
|
nextver = new Integer(1); |
|
|
|
nextver = new Integer(1); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
nextver = new Integer(nextver.intValue()+1); |
|
|
|
nextver = new Integer(nextver.intValue() + 1); |
|
|
|
} |
|
|
|
} |
|
|
|
lastversion.put(var, nextver); |
|
|
|
lastversion.put(var, nextver); |
|
|
|
return nextver; |
|
|
|
return nextver; |
|
|
@ -288,18 +297,18 @@ public class SSAConstructorSparseEx { |
|
|
|
|
|
|
|
|
|
|
|
SFormsFastMapDirect mapNew = new SFormsFastMapDirect(); |
|
|
|
SFormsFastMapDirect mapNew = new SFormsFastMapDirect(); |
|
|
|
|
|
|
|
|
|
|
|
for(DirectNode pred: node.preds) { |
|
|
|
for(DirectNode pred : node.preds) { |
|
|
|
SFormsFastMapDirect mapOut = getFilteredOutMap(node.id, pred.id, dgraph, node.id); |
|
|
|
SFormsFastMapDirect mapOut = getFilteredOutMap(node.id, pred.id, dgraph, node.id); |
|
|
|
if(mapNew.isEmpty()) { |
|
|
|
if (mapNew.isEmpty()) { |
|
|
|
mapNew = mapOut.getCopy(); |
|
|
|
mapNew = mapOut.getCopy(); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
mergeMaps(mapNew, mapOut); |
|
|
|
mergeMaps(mapNew, mapOut); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if(extraVarVersions.containsKey(node.id)) { |
|
|
|
if (extraVarVersions.containsKey(node.id)) { |
|
|
|
SFormsFastMapDirect mapExtra = extraVarVersions.get(node.id); |
|
|
|
SFormsFastMapDirect mapExtra = extraVarVersions.get(node.id); |
|
|
|
if(mapNew.isEmpty()) { |
|
|
|
if (mapNew.isEmpty()) { |
|
|
|
mapNew = mapExtra.getCopy(); |
|
|
|
mapNew = mapExtra.getCopy(); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
mergeMaps(mapNew, mapExtra); |
|
|
|
mergeMaps(mapNew, mapExtra); |
|
|
@ -309,22 +318,21 @@ public class SSAConstructorSparseEx { |
|
|
|
inVarVersions.put(node.id, mapNew); |
|
|
|
inVarVersions.put(node.id, mapNew); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private SFormsFastMapDirect getFilteredOutMap(String nodeid, String predid, DirectGraph dgraph, |
|
|
|
private SFormsFastMapDirect getFilteredOutMap(String nodeid, String predid, DirectGraph dgraph, String destid) { |
|
|
|
String destid) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SFormsFastMapDirect mapNew = new SFormsFastMapDirect(); |
|
|
|
SFormsFastMapDirect mapNew = new SFormsFastMapDirect(); |
|
|
|
|
|
|
|
|
|
|
|
if(nodeid.equals(dgraph.mapNegIfBranch.get(predid))) { |
|
|
|
if (nodeid.equals(dgraph.mapNegIfBranch.get(predid))) { |
|
|
|
if(outNegVarVersions.containsKey(predid)) { |
|
|
|
if (outNegVarVersions.containsKey(predid)) { |
|
|
|
mapNew = outNegVarVersions.get(predid).getCopy(); |
|
|
|
mapNew = outNegVarVersions.get(predid).getCopy(); |
|
|
|
} |
|
|
|
} |
|
|
|
} else if(outVarVersions.containsKey(predid)) { |
|
|
|
} else if (outVarVersions.containsKey(predid)) { |
|
|
|
mapNew = outVarVersions.get(predid).getCopy(); |
|
|
|
mapNew = outVarVersions.get(predid).getCopy(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
boolean isFinallyExit = dgraph.mapShortRangeFinallyPaths.containsKey(predid); |
|
|
|
boolean isFinallyExit = dgraph.mapShortRangeFinallyPaths.containsKey(predid); |
|
|
|
|
|
|
|
|
|
|
|
if(isFinallyExit && !mapNew.isEmpty()) { |
|
|
|
if (isFinallyExit && !mapNew.isEmpty()) { |
|
|
|
|
|
|
|
|
|
|
|
SFormsFastMapDirect mapNewTemp = mapNew.getCopy(); |
|
|
|
SFormsFastMapDirect mapNewTemp = mapNew.getCopy(); |
|
|
|
|
|
|
|
|
|
|
@ -335,7 +343,7 @@ public class SSAConstructorSparseEx { |
|
|
|
|
|
|
|
|
|
|
|
HashSet<String> setLongPathWrapper = new HashSet<String>(); |
|
|
|
HashSet<String> setLongPathWrapper = new HashSet<String>(); |
|
|
|
for(FinallyPathWrapper finwraplong : dgraph.mapLongRangeFinallyPaths.get(predid)) { |
|
|
|
for(FinallyPathWrapper finwraplong : dgraph.mapLongRangeFinallyPaths.get(predid)) { |
|
|
|
setLongPathWrapper.add(finwraplong.destination+"##"+finwraplong.source); |
|
|
|
setLongPathWrapper.add(finwraplong.destination + "##" + finwraplong.source); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
for(FinallyPathWrapper finwrap : dgraph.mapShortRangeFinallyPaths.get(predid)) { |
|
|
|
for(FinallyPathWrapper finwrap : dgraph.mapShortRangeFinallyPaths.get(predid)) { |
|
|
@ -343,11 +351,11 @@ public class SSAConstructorSparseEx { |
|
|
|
|
|
|
|
|
|
|
|
boolean recFinally = dgraph.mapShortRangeFinallyPaths.containsKey(finwrap.source); |
|
|
|
boolean recFinally = dgraph.mapShortRangeFinallyPaths.containsKey(finwrap.source); |
|
|
|
|
|
|
|
|
|
|
|
if(recFinally) { |
|
|
|
if (recFinally) { |
|
|
|
// recursion
|
|
|
|
// recursion
|
|
|
|
map = getFilteredOutMap(finwrap.entry, finwrap.source, dgraph, destid); |
|
|
|
map = getFilteredOutMap(finwrap.entry, finwrap.source, dgraph, destid); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
if(finwrap.entry.equals(dgraph.mapNegIfBranch.get(finwrap.source))) { |
|
|
|
if (finwrap.entry.equals(dgraph.mapNegIfBranch.get(finwrap.source))) { |
|
|
|
map = outNegVarVersions.get(finwrap.source); |
|
|
|
map = outNegVarVersions.get(finwrap.source); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
map = outVarVersions.get(finwrap.source); |
|
|
|
map = outVarVersions.get(finwrap.source); |
|
|
@ -357,17 +365,17 @@ public class SSAConstructorSparseEx { |
|
|
|
// false path?
|
|
|
|
// false path?
|
|
|
|
boolean isFalsePath = true; |
|
|
|
boolean isFalsePath = true; |
|
|
|
|
|
|
|
|
|
|
|
if(recFinally) { |
|
|
|
if (recFinally) { |
|
|
|
isFalsePath = !finwrap.destination.equals(nodeid); |
|
|
|
isFalsePath = !finwrap.destination.equals(nodeid); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
isFalsePath = !setLongPathWrapper.contains(destid+"##"+finwrap.source); |
|
|
|
isFalsePath = !setLongPathWrapper.contains(destid + "##" + finwrap.source); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if(isFalsePath) { |
|
|
|
if (isFalsePath) { |
|
|
|
mapNewTemp.complement(map); |
|
|
|
mapNewTemp.complement(map); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
if(mapTrueSource.isEmpty()) { |
|
|
|
if (mapTrueSource.isEmpty()) { |
|
|
|
if(map != null) { |
|
|
|
if (map != null) { |
|
|
|
mapTrueSource = map.getCopy(); |
|
|
|
mapTrueSource = map.getCopy(); |
|
|
|
} |
|
|
|
} |
|
|
|
} else { |
|
|
|
} else { |
|
|
@ -376,7 +384,7 @@ public class SSAConstructorSparseEx { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if(isExceptionMonitorExit) { |
|
|
|
if (isExceptionMonitorExit) { |
|
|
|
|
|
|
|
|
|
|
|
mapNew = mapTrueSource; |
|
|
|
mapNew = mapTrueSource; |
|
|
|
|
|
|
|
|
|
|
@ -385,7 +393,7 @@ public class SSAConstructorSparseEx { |
|
|
|
mapNewTemp.union(mapTrueSource); |
|
|
|
mapNewTemp.union(mapTrueSource); |
|
|
|
|
|
|
|
|
|
|
|
SFormsFastMapDirect oldInMap = inVarVersions.get(nodeid); |
|
|
|
SFormsFastMapDirect oldInMap = inVarVersions.get(nodeid); |
|
|
|
if(oldInMap != null) { |
|
|
|
if (oldInMap != null) { |
|
|
|
mapNewTemp.union(oldInMap); |
|
|
|
mapNewTemp.union(oldInMap); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -396,10 +404,9 @@ public class SSAConstructorSparseEx { |
|
|
|
return mapNew; |
|
|
|
return mapNew; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private SFormsFastMapDirect mergeMaps(SFormsFastMapDirect mapTo, SFormsFastMapDirect map2) { |
|
|
|
private SFormsFastMapDirect mergeMaps(SFormsFastMapDirect mapTo, SFormsFastMapDirect map2) { |
|
|
|
|
|
|
|
|
|
|
|
if(map2 != null && !map2.isEmpty()) { |
|
|
|
if (map2 != null && !map2.isEmpty()) { |
|
|
|
mapTo.union(map2); |
|
|
|
mapTo.union(map2); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -408,18 +415,18 @@ public class SSAConstructorSparseEx { |
|
|
|
|
|
|
|
|
|
|
|
private boolean mapsEqual(SFormsFastMapDirect map1, SFormsFastMapDirect map2) { |
|
|
|
private boolean mapsEqual(SFormsFastMapDirect map1, SFormsFastMapDirect map2) { |
|
|
|
|
|
|
|
|
|
|
|
if(map1 == null) { |
|
|
|
if (map1 == null) { |
|
|
|
return map2 == null; |
|
|
|
return map2 == null; |
|
|
|
} else if (map2 == null) { |
|
|
|
} else if (map2 == null) { |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if(map1.size() != map2.size()) { |
|
|
|
if (map1.size() != map2.size()) { |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
for(Entry<Integer, FastSparseSet<Integer>> ent2: map2.entryList()) { |
|
|
|
for(Entry<Integer, FastSparseSet<Integer>> ent2 : map2.entryList()) { |
|
|
|
if(!InterpreterUtil.equalObjects(map1.get(ent2.getKey()), ent2.getValue())) { |
|
|
|
if (!InterpreterUtil.equalObjects(map1.get(ent2.getKey()), ent2.getValue())) { |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -427,7 +434,6 @@ public class SSAConstructorSparseEx { |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void setCurrentVar(SFormsFastMapDirect varmap, Integer var, Integer vers) { |
|
|
|
private void setCurrentVar(SFormsFastMapDirect varmap, Integer var, Integer vers) { |
|
|
|
FastSparseSet<Integer> set = factory.spawnEmptySet(); |
|
|
|
FastSparseSet<Integer> set = factory.spawnEmptySet(); |
|
|
|
set.add(vers); |
|
|
|
set.add(vers); |
|
|
@ -438,19 +444,19 @@ public class SSAConstructorSparseEx { |
|
|
|
|
|
|
|
|
|
|
|
SFormsFastMapDirect map; |
|
|
|
SFormsFastMapDirect map; |
|
|
|
|
|
|
|
|
|
|
|
switch(stat.type) { |
|
|
|
switch (stat.type) { |
|
|
|
case Statement.TYPE_CATCHALL: |
|
|
|
case Statement.TYPE_CATCHALL: |
|
|
|
case Statement.TYPE_TRYCATCH: |
|
|
|
case Statement.TYPE_TRYCATCH: |
|
|
|
|
|
|
|
|
|
|
|
List<VarExprent> lstVars; |
|
|
|
List<VarExprent> lstVars; |
|
|
|
if(stat.type == Statement.TYPE_CATCHALL) { |
|
|
|
if (stat.type == Statement.TYPE_CATCHALL) { |
|
|
|
lstVars = ((CatchAllStatement)stat).getVars(); |
|
|
|
lstVars = ((CatchAllStatement) stat).getVars(); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
lstVars = ((CatchStatement)stat).getVars(); |
|
|
|
lstVars = ((CatchStatement) stat).getVars(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
for(int i=1;i<stat.getStats().size();i++) { |
|
|
|
for(int i = 1; i < stat.getStats().size(); i++) { |
|
|
|
int varindex = lstVars.get(i-1).getIndex(); |
|
|
|
int varindex = lstVars.get(i - 1).getIndex(); |
|
|
|
int version = getNextFreeVersion(varindex); // == 1
|
|
|
|
int version = getNextFreeVersion(varindex); // == 1
|
|
|
|
|
|
|
|
|
|
|
|
map = new SFormsFastMapDirect(); |
|
|
|
map = new SFormsFastMapDirect(); |
|
|
@ -461,7 +467,7 @@ public class SSAConstructorSparseEx { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
for(Statement st: stat.getStats()) { |
|
|
|
for(Statement st : stat.getStats()) { |
|
|
|
setCatchMaps(st, dgraph, flatthelper); |
|
|
|
setCatchMaps(st, dgraph, flatthelper); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -472,11 +478,11 @@ public class SSAConstructorSparseEx { |
|
|
|
|
|
|
|
|
|
|
|
MethodDescriptor md = MethodDescriptor.parseDescriptor(mt.getDescriptor()); |
|
|
|
MethodDescriptor md = MethodDescriptor.parseDescriptor(mt.getDescriptor()); |
|
|
|
|
|
|
|
|
|
|
|
int paramcount = md.params.length + (thisvar?1:0); |
|
|
|
int paramcount = md.params.length + (thisvar ? 1 : 0); |
|
|
|
|
|
|
|
|
|
|
|
int varindex = 0; |
|
|
|
int varindex = 0; |
|
|
|
SFormsFastMapDirect map = new SFormsFastMapDirect(); |
|
|
|
SFormsFastMapDirect map = new SFormsFastMapDirect(); |
|
|
|
for(int i=0;i<paramcount;i++) { |
|
|
|
for(int i = 0; i < paramcount; i++) { |
|
|
|
int version = getNextFreeVersion(varindex); // == 1
|
|
|
|
int version = getNextFreeVersion(varindex); // == 1
|
|
|
|
|
|
|
|
|
|
|
|
FastSparseSet<Integer> set = factory.spawnEmptySet(); |
|
|
|
FastSparseSet<Integer> set = factory.spawnEmptySet(); |
|
|
@ -484,14 +490,14 @@ public class SSAConstructorSparseEx { |
|
|
|
map.put(varindex, set); |
|
|
|
map.put(varindex, set); |
|
|
|
startVars.add(new VarVersionPaar(varindex, version)); |
|
|
|
startVars.add(new VarVersionPaar(varindex, version)); |
|
|
|
|
|
|
|
|
|
|
|
if(thisvar) { |
|
|
|
if (thisvar) { |
|
|
|
if(i==0) { |
|
|
|
if (i == 0) { |
|
|
|
varindex++; |
|
|
|
varindex++; |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
varindex+=md.params[i-1].stack_size; |
|
|
|
varindex += md.params[i - 1].stack_size; |
|
|
|
} |
|
|
|
} |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
varindex+=md.params[i].stack_size; |
|
|
|
varindex += md.params[i].stack_size; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|