mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-06-28 09:26:16 +00:00
Calculate setLocal usages and use it in setProperty
This commit is contained in:
@@ -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() {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
Reference in New Issue
Block a user