Calculate setLocal usages and use it in setProperty

This commit is contained in:
Jindra Petřík
2021-01-24 11:46:07 +01:00
parent d5db3dc5f2
commit 15664f86fd
8 changed files with 183 additions and 24 deletions

View File

@@ -12,7 +12,8 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
* License along with this library.
*/
package com.jpexs.decompiler.flash.abc;
import com.jpexs.decompiler.flash.BaseLocalData;
@@ -30,6 +31,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
*
@@ -73,6 +75,8 @@ public class AVM2LocalData extends BaseLocalData {
public boolean thisHasDefaultToPrimitive;
public Map<Integer, Set<Integer>> setLocalPosToGetLocalPos;
public AVM2LocalData() {
}
@@ -96,6 +100,7 @@ public class AVM2LocalData extends BaseLocalData {
refs = localData.refs;
code = localData.code;
thisHasDefaultToPrimitive = localData.thisHasDefaultToPrimitive;
setLocalPosToGetLocalPos = localData.setLocalPosToGetLocalPos;
}
public AVM2ConstantPool getConstants() {

View File

@@ -1532,7 +1532,7 @@ public class AVM2Code implements Cloneable {
return pos2adr(fixIPAfterDebugLine(adr2pos(addr, true)));
}
public ConvertOutput toSourceOutput(boolean thisHasDefaultToPrimitive, Reference<GraphSourceItem> lineStartItem, String path, GraphPart part, boolean processJumps, boolean isStatic, int scriptIndex, int classIndex, HashMap<Integer, GraphTargetItem> localRegs, TranslateStack stack, ScopeStack scopeStack, ABC abc, MethodBody body, int start, int end, HashMap<Integer, String> localRegNames, List<DottedChain> fullyQualifiedNames, boolean[] visited, HashMap<Integer, Integer> localRegAssigmentIps, HashMap<Integer, List<Integer>> refs) throws ConvertException, InterruptedException {
public ConvertOutput toSourceOutput(Map<Integer, Set<Integer>> setLocalPosToGetLocalPos, boolean thisHasDefaultToPrimitive, Reference<GraphSourceItem> lineStartItem, String path, GraphPart part, boolean processJumps, boolean isStatic, int scriptIndex, int classIndex, HashMap<Integer, GraphTargetItem> localRegs, TranslateStack stack, ScopeStack scopeStack, ABC abc, MethodBody body, int start, int end, HashMap<Integer, String> localRegNames, List<DottedChain> fullyQualifiedNames, boolean[] visited, HashMap<Integer, Integer> localRegAssigmentIps, HashMap<Integer, List<Integer>> refs) throws ConvertException, InterruptedException {
calcKilledStats(body);
boolean debugMode = DEBUG_MODE;
if (debugMode) {
@@ -1637,12 +1637,12 @@ public class AVM2Code implements Cloneable {
AVM2Instruction insAfter = code.get(ip + 1);
if ((insAfter.definition instanceof GetLocalTypeIns) && (((GetLocalTypeIns) insAfter.definition).getRegisterId(insAfter) == ((SetLocalTypeIns) ins.definition).getRegisterId(ins))) {
GraphTargetItem before = stack.peek();
ins.definition.translate(lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, ins, output, body, abc, localRegNames, fullyQualifiedNames, path, localRegAssigmentIps, ip, refs, this, thisHasDefaultToPrimitive);
ins.definition.translate(setLocalPosToGetLocalPos, lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, ins, output, body, abc, localRegNames, fullyQualifiedNames, path, localRegAssigmentIps, ip, refs, this, thisHasDefaultToPrimitive);
stack.push(before);
ip += 2;
continue iploop;
} else {
ins.definition.translate(lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, ins, output, body, abc, localRegNames, fullyQualifiedNames, path, localRegAssigmentIps, ip, refs, this, thisHasDefaultToPrimitive);
ins.definition.translate(setLocalPosToGetLocalPos, lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, ins, output, body, abc, localRegNames, fullyQualifiedNames, path, localRegAssigmentIps, ip, refs, this, thisHasDefaultToPrimitive);
ip++;
continue iploop;
}
@@ -1651,7 +1651,7 @@ public class AVM2Code implements Cloneable {
do {
AVM2Instruction insAfter = ip + 1 < code.size() ? code.get(ip + 1) : null;
if (insAfter == null) {
ins.definition.translate(lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, ins, output, body, abc, localRegNames, fullyQualifiedNames, path, localRegAssigmentIps, ip, refs, this, thisHasDefaultToPrimitive);
ins.definition.translate(setLocalPosToGetLocalPos, lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, ins, output, body, abc, localRegNames, fullyQualifiedNames, path, localRegAssigmentIps, ip, refs, this, thisHasDefaultToPrimitive);
ip++;
break;
}
@@ -1685,7 +1685,7 @@ public class AVM2Code implements Cloneable {
if (((GetLocalTypeIns) code.get(t).definition).getRegisterId(code.get(t)) == reg) {
if (code.get(t + 1).definition instanceof KillIns) {
if (code.get(t + 1).operands[0] == reg) {
ConvertOutput assignment = toSourceOutput(thisHasDefaultToPrimitive, lineStartItem, path, part, processJumps, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, abc, body, ip + 2, t - 1, localRegNames, fullyQualifiedNames, visited, localRegAssigmentIps, refs);
ConvertOutput assignment = toSourceOutput(setLocalPosToGetLocalPos, thisHasDefaultToPrimitive, lineStartItem, path, part, processJumps, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, abc, body, ip + 2, t - 1, localRegNames, fullyQualifiedNames, visited, localRegAssigmentIps, refs);
if (!assignment.output.isEmpty()) {
GraphTargetItem tar = assignment.output.remove(assignment.output.size() - 1);
tar.firstPart = part;
@@ -1719,21 +1719,21 @@ public class AVM2Code implements Cloneable {
}
stack.push(vx);
} else {
ins.definition.translate(lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, ins, output, body, abc, localRegNames, fullyQualifiedNames, path, localRegAssigmentIps, ip, refs, this, thisHasDefaultToPrimitive);
ins.definition.translate(setLocalPosToGetLocalPos, lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, ins, output, body, abc, localRegNames, fullyQualifiedNames, path, localRegAssigmentIps, ip, refs, this, thisHasDefaultToPrimitive);
}
ip++;
break;
//}
} else {
ins.definition.translate(lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, ins, output, body, abc, localRegNames, fullyQualifiedNames, path, localRegAssigmentIps, ip, refs, this, thisHasDefaultToPrimitive);
ins.definition.translate(setLocalPosToGetLocalPos, lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, ins, output, body, abc, localRegNames, fullyQualifiedNames, path, localRegAssigmentIps, ip, refs, this, thisHasDefaultToPrimitive);
ip++;
break;
//throw new ConvertException("Unknown pattern after DUP:" + insComparsion.toString());
}
} while (ins.definition instanceof DupIns);
} else if ((ins.definition instanceof ReturnValueIns) || (ins.definition instanceof ReturnVoidIns) || (ins.definition instanceof ThrowIns)) {
ins.definition.translate(lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, ins, output, body, abc, localRegNames, fullyQualifiedNames, path, localRegAssigmentIps, ip, refs, this, thisHasDefaultToPrimitive);
ins.definition.translate(setLocalPosToGetLocalPos, lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, ins, output, body, abc, localRegNames, fullyQualifiedNames, path, localRegAssigmentIps, ip, refs, this, thisHasDefaultToPrimitive);
//ip = end + 1;
break;
} else if (ins.definition instanceof NewFunctionIns) {
@@ -1769,13 +1769,13 @@ public class AVM2Code implements Cloneable {
}
}
// What to do when hasDup is false?
ins.definition.translate(lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, ins, output, body, abc, localRegNames, fullyQualifiedNames, path, localRegAssigmentIps, ip, refs, this, thisHasDefaultToPrimitive);
ins.definition.translate(setLocalPosToGetLocalPos, lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, ins, output, body, abc, localRegNames, fullyQualifiedNames, path, localRegAssigmentIps, ip, refs, this, thisHasDefaultToPrimitive);
NewFunctionAVM2Item nft = (NewFunctionAVM2Item) stack.peek();
nft.functionName = functionName;
ip++;
} else {
try {
ins.definition.translate(lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, ins, output, body, abc, localRegNames, fullyQualifiedNames, path, localRegAssigmentIps, ip, refs, this, thisHasDefaultToPrimitive);
ins.definition.translate(setLocalPosToGetLocalPos, lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, ins, output, body, abc, localRegNames, fullyQualifiedNames, path, localRegAssigmentIps, ip, refs, this, thisHasDefaultToPrimitive);
} catch (RuntimeException re) {
/*String last="";
int len=5;

View File

@@ -28,6 +28,7 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.JumpIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.LookupSwitchIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.GetLocalTypeIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.KillIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.SetLocalTypeIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.ReturnValueIns;
import com.jpexs.decompiler.flash.abc.avm2.model.AVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.FilteredCheckAVM2Item;
@@ -85,6 +86,9 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Stack;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.logging.Logger;
/**
@@ -99,6 +103,8 @@ public class AVM2Graph extends Graph {
private final MethodBody body;
private final Logger logger = Logger.getLogger(AVM2Graph.class.getName());
public AVM2Code getCode() {
return avm2code;
}
@@ -128,6 +134,104 @@ public class AVM2Graph extends Graph {
}
@Override
protected void beforePrintGraph(BaseLocalData localData, String path, Set<GraphPart> allParts, List<Loop> loops) {
Map<Integer, Set<Integer>> setLocalPosToGetLocalPos = calculateLocalRegsUsage(path, allParts);
AVM2LocalData avm2LocalData = ((AVM2LocalData) localData);
avm2LocalData.setLocalPosToGetLocalPos = setLocalPosToGetLocalPos;
}
public Map<Integer, Set<Integer>> calculateLocalRegsUsage(String path, Set<GraphPart> allParts) {
logger.fine("--- " + path + " ---");
Map<Integer, Set<Integer>> setLocalPosToGetLocalPos = new TreeMap<>();
Map<GraphPart, Map<Integer, List<Integer>>> partUnresolvedRegisterToGetLocalPos = new HashMap<>();
Map<GraphPart, Map<Integer, Integer>> partRegisterToLastSetLocalPos = new HashMap<>();
for (GraphPart p : allParts) {
if (p.start < 0) {
continue;
}
Map<Integer, Integer> registerToLastSetLocalPos = new HashMap<>();
for (int ip = p.start; ip <= p.end; ip++) {
AVM2Instruction ins = avm2code.code.get(ip);
if (ins.definition instanceof SetLocalTypeIns) {
int regId = ((SetLocalTypeIns) ins.definition).getRegisterId(ins);
registerToLastSetLocalPos.put(regId, ip);
setLocalPosToGetLocalPos.put(ip, new TreeSet<>());
}
if (ins.definition instanceof GetLocalTypeIns) {
int regId = ((GetLocalTypeIns) ins.definition).getRegisterId(ins);
if (registerToLastSetLocalPos.containsKey(regId)) {
int setLocalPos = registerToLastSetLocalPos.get(regId);
setLocalPosToGetLocalPos.get(setLocalPos).add(ip);
} else {
if (!partUnresolvedRegisterToGetLocalPos.containsKey(p)) {
partUnresolvedRegisterToGetLocalPos.put(p, new HashMap<>());
}
if (!partUnresolvedRegisterToGetLocalPos.get(p).containsKey(regId)) {
partUnresolvedRegisterToGetLocalPos.get(p).put(regId, new ArrayList<>());
}
partUnresolvedRegisterToGetLocalPos.get(p).get(regId).add(ip);
}
}
}
partRegisterToLastSetLocalPos.put(p, registerToLastSetLocalPos);
}
Set<GraphPart> pSet = new HashSet<>(partUnresolvedRegisterToGetLocalPos.keySet());
for (GraphPart p : pSet) {
Map<Integer, List<Integer>> unresolvedRegisterToGetLocalPos = partUnresolvedRegisterToGetLocalPos.get(p);
Set<GraphPart> visited = new HashSet<>();
visited.add(p);
for (GraphPart q : p.refs) {
calculateLocalRegsUsageWalk(q, unresolvedRegisterToGetLocalPos, visited, partRegisterToLastSetLocalPos, setLocalPosToGetLocalPos);
}
}
for (int setLocalPos : setLocalPosToGetLocalPos.keySet()) {
AVM2Instruction ins = avm2code.code.get(setLocalPos);
int regId = ((SetLocalTypeIns) ins.definition).getRegisterId(ins);
logger.fine("set local reg " + regId + " at pos " + (setLocalPos + 1));
for (int getLocalPos : setLocalPosToGetLocalPos.get(setLocalPos)) {
logger.fine("- usage at pos " + (getLocalPos + 1));
}
}
return setLocalPosToGetLocalPos;
}
public void calculateLocalRegsUsageWalk(GraphPart q,
Map<Integer, List<Integer>> unresolvedRegisterToGetLocalPos,
Set<GraphPart> visited,
Map<GraphPart, Map<Integer, Integer>> partRegisterToLastSetLocalPos,
Map<Integer, Set<Integer>> setLocalPosToGetLocalPos) {
if (visited.contains(q)) {
return;
}
Set<Integer> regIds = new HashSet<>(unresolvedRegisterToGetLocalPos.keySet());
for (int regId : regIds) {
if (partRegisterToLastSetLocalPos.containsKey(q)) {
if (partRegisterToLastSetLocalPos.get(q).containsKey(regId)) {
int lastSetLocalPos = partRegisterToLastSetLocalPos.get(q).get(regId);
setLocalPosToGetLocalPos.get(lastSetLocalPos).addAll(unresolvedRegisterToGetLocalPos.get(regId));
unresolvedRegisterToGetLocalPos = new HashMap<>(unresolvedRegisterToGetLocalPos);
unresolvedRegisterToGetLocalPos.remove(regId);
}
}
}
if (unresolvedRegisterToGetLocalPos.isEmpty()) {
return;
}
visited.add(q);
for (GraphPart r : q.refs) {
calculateLocalRegsUsageWalk(r, unresolvedRegisterToGetLocalPos, visited, partRegisterToLastSetLocalPos, setLocalPosToGetLocalPos);
}
}
public static List<GraphTargetItem> translateViaGraph(String path, AVM2Code code, ABC abc, MethodBody body, boolean isStatic, int scriptIndex, int classIndex, HashMap<Integer, GraphTargetItem> localRegs, ScopeStack scopeStack, HashMap<Integer, String> localRegNames, List<DottedChain> fullyQualifiedNames, int staticOperation, HashMap<Integer, Integer> localRegAssigmentIps, HashMap<Integer, List<Integer>> refs, boolean thisHasDefaultToPrimitive) throws InterruptedException {
AVM2Graph g = new AVM2Graph(code, abc, body, isStatic, scriptIndex, classIndex, localRegs, scopeStack, localRegNames, fullyQualifiedNames, localRegAssigmentIps, refs);

View File

@@ -120,7 +120,7 @@ public class AVM2GraphSource extends GraphSource {
List<GraphTargetItem> ret = new ArrayList<>();
ScopeStack newstack = ((AVM2LocalData) localData).scopeStack;
Reference<GraphSourceItem> lineStartItem = new Reference<>(localData.lineStartInstruction);
ConvertOutput co = code.toSourceOutput(((AVM2LocalData) localData).thisHasDefaultToPrimitive, lineStartItem, path, part, false, isStatic, scriptIndex, classIndex, localRegs, stack, newstack, abc, body, start, end, localRegNames, fullyQualifiedNames, new boolean[size()], localRegAssigmentIps, refs);
ConvertOutput co = code.toSourceOutput(((AVM2LocalData) localData).setLocalPosToGetLocalPos, ((AVM2LocalData) localData).thisHasDefaultToPrimitive, lineStartItem, path, part, false, isStatic, scriptIndex, classIndex, localRegs, stack, newstack, abc, body, start, end, localRegNames, fullyQualifiedNames, new boolean[size()], localRegAssigmentIps, refs);
localData.lineStartInstruction = lineStartItem.getVal();
ret.addAll(co.output);
return ret;

View File

@@ -30,6 +30,8 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.IncLocalIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.SetLocalTypeIns;
import com.jpexs.decompiler.flash.abc.avm2.model.AVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.FullMultinameAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.LocalRegAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.SetLocalAVM2Item;
import com.jpexs.helpers.Reference;
import com.jpexs.decompiler.flash.abc.types.MethodBody;
import com.jpexs.decompiler.flash.abc.types.Multiname;
@@ -44,6 +46,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Stack;
@@ -160,7 +163,7 @@ public abstract class InstructionDefinition implements Serializable {
public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List<GraphTargetItem> output, String path) throws InterruptedException {
}
public void translate(Reference<GraphSourceItem> lineStartItem, boolean isStatic, int scriptIndex, int classIndex, HashMap<Integer, GraphTargetItem> localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2Instruction ins, List<GraphTargetItem> output, MethodBody body, ABC abc, HashMap<Integer, String> localRegNames, List<DottedChain> fullyQualifiedNames, String path, HashMap<Integer, Integer> localRegsAssignmentIps, int ip, HashMap<Integer, List<Integer>> refs, AVM2Code code, boolean thisHasDefaultToPrimitive) throws InterruptedException {
public void translate(Map<Integer, Set<Integer>> setLocalPosToGetLocalPos, Reference<GraphSourceItem> lineStartItem, boolean isStatic, int scriptIndex, int classIndex, HashMap<Integer, GraphTargetItem> localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2Instruction ins, List<GraphTargetItem> output, MethodBody body, ABC abc, HashMap<Integer, String> localRegNames, List<DottedChain> fullyQualifiedNames, String path, HashMap<Integer, Integer> localRegsAssignmentIps, int ip, HashMap<Integer, List<Integer>> refs, AVM2Code code, boolean thisHasDefaultToPrimitive) throws InterruptedException {
AVM2LocalData localData = new AVM2LocalData();
localData.isStatic = isStatic;
localData.scriptIndex = scriptIndex;
@@ -177,6 +180,7 @@ public abstract class InstructionDefinition implements Serializable {
localData.refs = refs;
localData.code = code;
localData.thisHasDefaultToPrimitive = thisHasDefaultToPrimitive;
localData.setLocalPosToGetLocalPos = setLocalPosToGetLocalPos;
translate(localData, stack, ins, output, path);
lineStartItem.setVal(localData.lineStartInstruction);
}
@@ -307,4 +311,25 @@ public abstract class InstructionDefinition implements Serializable {
public boolean isExitInstruction() {
return false;
}
public void cleanTempRegisters(AVM2LocalData localData, List<GraphTargetItem> output, List<LocalRegAVM2Item> usedLocalRegs) {
for (LocalRegAVM2Item reg : usedLocalRegs) {
System.err.println(reg.regIndex);
for (int i = output.size() - 1; i >= 0; i--) {
if (output.get(i) instanceof SetLocalAVM2Item) {
SetLocalAVM2Item setLocal = (SetLocalAVM2Item) output.get(i);
if (setLocal.regIndex == reg.regIndex) {
int setLocalIp = localData.code.code.indexOf(setLocal.getSrc());
Set<Integer> usages = localData.setLocalPosToGetLocalPos.get(setLocalIp);
int usageIp = localData.code.code.indexOf(reg.getSrc());
if (usages.size() == 1 && usages.iterator().next().equals(usageIp)) {
output.remove(i);
}
}
} else {
break;
}
}
}
}
}

View File

@@ -12,7 +12,8 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
* License along with this library.
*/
package com.jpexs.decompiler.flash.abc.avm2.instructions.localregs;
import com.jpexs.decompiler.flash.abc.ABC;
@@ -78,16 +79,8 @@ public abstract class GetLocalTypeIns extends InstructionDefinition {
assignCount = localData.localRegAssignmentIps.get(regId);
}
if (assignCount > 5) { //Do not allow change register more than 5 - for deobfuscation
if (assignCount > 5) { //Do not allow change register more than 5 - for deobfuscation
//computedValue = new NotCompileTimeItem(ins, localData.lineStartInstruction, computedValue);
}
}
/*if (!isRegisterCompileTime(regId, ip, refs, code)) {
computedValue = new NotCompileTimeAVM2Item(ins, localData.lineStartInstruction, computedValue);
}
if (computedValue == null) {
if (!localRegNames.containsKey(regId)) {
computedValue = new UndefinedAVM2Item(null); //In some obfuscated code there seems to be reading of undefined registers
}
stack.push(new LocalRegAVM2Item(ins, localData.lineStartInstruction, regId, computedValue));
}

View File

@@ -12,7 +12,8 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
* License along with this library.
*/
package com.jpexs.decompiler.flash.abc.avm2.instructions.other;
import com.jpexs.decompiler.flash.abc.ABC;
@@ -61,17 +62,29 @@ public class SetPropertyIns extends InstructionDefinition implements SetTypeIns
FullMultinameAVM2Item multiname = resolveMultiname(localData, true, stack, localData.getConstants(), multinameIndex, ins);
GraphTargetItem obj = stack.pop();
if (value.getThroughDuplicate().getThroughRegister().getThroughDuplicate() instanceof IncrementAVM2Item) {
List<LocalRegAVM2Item> localRegs = new ArrayList<>();
if (value.getThroughDuplicate() instanceof LocalRegAVM2Item) {
localRegs.add((LocalRegAVM2Item) value.getThroughDuplicate());
}
GraphTargetItem inside = ((IncrementAVM2Item) value.getThroughDuplicate().getThroughRegister().getThroughDuplicate()).value.getThroughRegister().getNotCoerced().getThroughDuplicate();
if (inside instanceof GetPropertyAVM2Item) {
GetPropertyAVM2Item insideProp = ((GetPropertyAVM2Item) inside);
if (((FullMultinameAVM2Item) insideProp.propertyName).compareSame(multiname)) {
GraphTargetItem insideObj = obj.getThroughDuplicate();
if (insideObj instanceof LocalRegAVM2Item) {
localRegs.add((LocalRegAVM2Item) insideObj);
if (((LocalRegAVM2Item) insideObj).computedValue != null) {
insideObj = ((LocalRegAVM2Item) insideObj).computedValue.getThroughNotCompilable().getThroughDuplicate();
}
}
if (multiname.name instanceof LocalRegAVM2Item) {
localRegs.add((LocalRegAVM2Item) multiname.name);
}
if (multiname.namespace instanceof LocalRegAVM2Item) {
localRegs.add((LocalRegAVM2Item) multiname.namespace);
}
if (insideProp.object.getThroughDuplicate() == insideObj) {
cleanTempRegisters(localData, output, localRegs);
if (stack.size() > 0) {
GraphTargetItem top = stack.peek().getNotCoerced().getThroughDuplicate();
if (top == insideProp) {
@@ -93,17 +106,30 @@ public class SetPropertyIns extends InstructionDefinition implements SetTypeIns
}
if (value.getThroughDuplicate().getThroughRegister().getThroughDuplicate() instanceof DecrementAVM2Item) {
List<LocalRegAVM2Item> localRegs = new ArrayList<>();
if (value.getThroughDuplicate() instanceof LocalRegAVM2Item) {
localRegs.add((LocalRegAVM2Item) value.getThroughDuplicate());
}
GraphTargetItem inside = ((DecrementAVM2Item) value.getThroughDuplicate().getThroughRegister().getThroughDuplicate()).value.getThroughRegister().getNotCoerced().getThroughDuplicate();
if (inside instanceof GetPropertyAVM2Item) {
GetPropertyAVM2Item insideProp = ((GetPropertyAVM2Item) inside);
if (((FullMultinameAVM2Item) insideProp.propertyName).compareSame(multiname)) {
GraphTargetItem insideObj = obj.getThroughDuplicate();
if (insideObj instanceof LocalRegAVM2Item) {
localRegs.add((LocalRegAVM2Item) insideObj);
if (((LocalRegAVM2Item) insideObj).computedValue != null) {
insideObj = ((LocalRegAVM2Item) insideObj).computedValue.getThroughNotCompilable().getThroughDuplicate();
}
}
if (multiname.name instanceof LocalRegAVM2Item) {
localRegs.add((LocalRegAVM2Item) multiname.name);
}
if (multiname.namespace instanceof LocalRegAVM2Item) {
localRegs.add((LocalRegAVM2Item) multiname.namespace);
}
if (insideProp.object.getThroughDuplicate() == insideObj) {
cleanTempRegisters(localData, output, localRegs);
if (stack.size() > 0) {
GraphTargetItem top = stack.peek().getNotCoerced().getThroughDuplicate();
if (top == insideProp) {

View File

@@ -545,6 +545,8 @@ public class Graph {
}
System.err.println("</loopspre>");//*/
List<GotoItem> gotos = new ArrayList<>();
beforePrintGraph(localData, path, allParts, loops);
List<GraphTargetItem> ret = printGraph(gotos, gotoTargets, new HashMap<>(), new HashMap<>(), localData, stack, allParts, null, heads.get(0), null, loops, staticOperation, path);
processIfGotos(gotos, ret);
@@ -572,6 +574,10 @@ public class Graph {
return ret;
}
protected void beforePrintGraph(BaseLocalData localData, String path, Set<GraphPart> allParts, List<Loop> loops) {
}
private List<GraphPartDecision> getCommonPrefix(List<List<GraphPartDecision>> listOfLists) {
List<GraphPartDecision> result = new ArrayList<>();
if (listOfLists.isEmpty()) {