mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-07-18 15:18:11 +00:00
Fixed AS1/2 switch with nontrivial expressions - secondpass for all strictequals
This commit is contained in:
@@ -86,6 +86,7 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@@ -930,9 +931,15 @@ public abstract class Action implements GraphSourceItem {
|
||||
* @throws java.lang.InterruptedException
|
||||
*/
|
||||
public static List<GraphTargetItem> actionsToTree(boolean insideDoInitAction, boolean insideFunction, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, List<Action> actions, int version, int staticOperation, String path) throws InterruptedException {
|
||||
HashMap<String, GraphTargetItem> variablesBackup = new LinkedHashMap<>(variables);
|
||||
HashMap<String, GraphTargetItem> functionsBackup = new LinkedHashMap<>(functions);
|
||||
try {
|
||||
return ActionGraph.translateViaGraph(null, insideDoInitAction, insideFunction, regNames, variables, functions, actions, version, staticOperation, path);
|
||||
} catch (SecondPassException spe) {
|
||||
variables.clear();
|
||||
variables.putAll(variablesBackup);
|
||||
functions.clear();
|
||||
functions.putAll(functionsBackup);
|
||||
return ActionGraph.translateViaGraph(spe.getData(), insideDoInitAction, insideFunction, regNames, variables, functions, actions, version, staticOperation, path);
|
||||
}
|
||||
}
|
||||
@@ -982,6 +989,18 @@ public abstract class Action implements GraphSourceItem {
|
||||
this.ignored = ignored;
|
||||
}
|
||||
|
||||
private static HashMap<String, GraphTargetItem> prepareVariables(GraphSourceItemContainer cnt, HashMap<String, GraphTargetItem> variables) {
|
||||
HashMap<String, GraphTargetItem> variables2 = Helper.deepCopy(variables);
|
||||
if (cnt instanceof ActionDefineFunction || cnt instanceof ActionDefineFunction2) {
|
||||
for (int r = 0; r < 256; r++) {
|
||||
if (variables2.containsKey("__register" + r)) {
|
||||
variables2.remove("__register" + r);
|
||||
}
|
||||
}
|
||||
}
|
||||
return variables2;
|
||||
}
|
||||
|
||||
public static List<GraphTargetItem> actionsPartToTree(SecondPassData secondPassData, boolean insideDoInitAction, Reference<GraphSourceItem> fi, HashMap<Integer, String> registerNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, TranslateStack stack, List<Action> actions, int start, int end, int version, int staticOperation, String path) throws InterruptedException, GraphPartChangeException {
|
||||
if (start < actions.size() && (end > 0) && (start > 0)) {
|
||||
logger.log(Level.FINE, "Entering {0}-{1}{2}", new Object[]{start, end, actions.size() > 0 ? (" (" + actions.get(start).toString() + " - " + actions.get(end == actions.size() ? end - 1 : end) + ")") : ""});
|
||||
@@ -1033,14 +1052,7 @@ public abstract class Action implements GraphSourceItem {
|
||||
long endAddr = action.getAddress() + cnt.getHeaderSize();
|
||||
String cntName = cnt.getName();
|
||||
List<List<GraphTargetItem>> outs = new ArrayList<>();
|
||||
HashMap<String, GraphTargetItem> variables2 = Helper.deepCopy(variables);
|
||||
if (cnt instanceof ActionDefineFunction || cnt instanceof ActionDefineFunction2) {
|
||||
for (int r = 0; r < 256; r++) {
|
||||
if (variables2.containsKey("__register" + r)) {
|
||||
variables2.remove("__register" + r);
|
||||
}
|
||||
}
|
||||
}
|
||||
HashMap<String, GraphTargetItem> variables2 = prepareVariables(cnt, variables);
|
||||
for (long size : cnt.getContainerSizes()) {
|
||||
if (size == 0) {
|
||||
outs.add(new ArrayList<>());
|
||||
@@ -1056,7 +1068,12 @@ public abstract class Action implements GraphSourceItem {
|
||||
}
|
||||
}
|
||||
}
|
||||
out = ActionGraph.translateViaGraph(secondPassData, insideDoInitAction, true, regNames, variables2, functions, actions.subList(adr2ip(actions, endAddr), adr2ip(actions, endAddr + size)), version, staticOperation, path + (cntName == null ? "" : "/" + cntName));
|
||||
try {
|
||||
out = ActionGraph.translateViaGraph(null, insideDoInitAction, true, regNames, variables2, functions, actions.subList(adr2ip(actions, endAddr), adr2ip(actions, endAddr + size)), version, staticOperation, path + (cntName == null ? "" : "/" + cntName));
|
||||
} catch (SecondPassException spe) {
|
||||
variables2 = prepareVariables(cnt, variables);
|
||||
out = ActionGraph.translateViaGraph(spe.getData(), insideDoInitAction, true, regNames, variables2, functions, actions.subList(adr2ip(actions, endAddr), adr2ip(actions, endAddr + size)), version, staticOperation, path + (cntName == null ? "" : "/" + cntName));
|
||||
}
|
||||
} catch (OutOfMemoryError | TranslateException | StackOverflowError ex) {
|
||||
logger.log(Level.SEVERE, "Decompilation error in: " + path, ex);
|
||||
if (ex instanceof OutOfMemoryError) {
|
||||
|
||||
@@ -398,6 +398,15 @@ public class ActionGraph extends Graph {
|
||||
}
|
||||
}
|
||||
|
||||
private GraphPart findPart(int ip, Set<GraphPart> allParts) {
|
||||
for (GraphPart p : allParts) {
|
||||
if (p.containsIP(ip)) {
|
||||
return p;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<GraphTargetItem> check(List<GraphTargetItem> currentRet, List<GotoItem> foundGotos, Map<GraphPart, List<GraphTargetItem>> partCodes, Map<GraphPart, Integer> partCodePos, Set<GraphPart> visited, GraphSource code, BaseLocalData localData, Set<GraphPart> allParts, TranslateStack stack, GraphPart parent, GraphPart part, List<GraphPart> stopPart, List<StopPartKind> stopPartKind, List<Loop> loops, List<ThrowState> throwStates, List<GraphTargetItem> output, Loop currentLoop, int staticOperation, String path) throws InterruptedException {
|
||||
if (!output.isEmpty()) {
|
||||
@@ -445,29 +454,31 @@ public class ActionGraph extends Graph {
|
||||
if (secondPassData != null) {
|
||||
for (int si = 0; si < secondPassData.switchParts.size(); si++) {
|
||||
if (secondPassData.switchParts.get(si).get(0).equals(part)) {
|
||||
part = secondPassData.switchParts.get(si).get(secondPassData.switchParts.get(si).size() - 1);
|
||||
//we need to use findpart as parts have changed between first and second pass
|
||||
part = findPart(secondPassData.switchParts.get(si).get(secondPassData.switchParts.get(si).size() - 1).start, allParts);
|
||||
caseBodyParts.clear();
|
||||
caseBodyParts.addAll(secondPassData.switchOnFalseParts.get(si));
|
||||
for (GraphPart p : secondPassData.switchOnFalseParts.get(si)) {
|
||||
caseBodyParts.add(findPart(p.start, allParts));
|
||||
}
|
||||
caseValuesMap.clear();
|
||||
caseValuesMap.addAll(secondPassData.switchCaseExpressions.get(si));
|
||||
secondSwitchFound = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int cnt = 1;
|
||||
if (!secondSwitchFound) {
|
||||
if (false) { //always do secondPass
|
||||
try {
|
||||
while (part.nextParts.size() > 1
|
||||
&& part.nextParts.get(1).getHeight() > 1
|
||||
&& code.get(part.nextParts.get(1).end >= code.size() ? code.size() - 1 : part.nextParts.get(1).end) instanceof ActionIf
|
||||
&& ((top = translatePartGetStack(localData, part.nextParts.get(1), stack, staticOperation)) instanceof StrictEqActionItem)) {
|
||||
cnt++;
|
||||
part = part.nextParts.get(1);
|
||||
caseBodyParts.add(part.nextParts.get(0));
|
||||
while (part.nextParts.size() > 1
|
||||
&& part.nextParts.get(1).getHeight() > 1
|
||||
&& code.get(part.nextParts.get(1).end >= code.size() ? code.size() - 1 : part.nextParts.get(1).end) instanceof ActionIf
|
||||
&& ((top = translatePartGetStack(localData, part.nextParts.get(1), stack, staticOperation)) instanceof StrictEqActionItem)) {
|
||||
cnt++;
|
||||
part = part.nextParts.get(1);
|
||||
caseBodyParts.add(part.nextParts.get(0));
|
||||
|
||||
set = (StrictEqActionItem) top;
|
||||
caseValuesMap.add(set.rightSide);
|
||||
set = (StrictEqActionItem) top;
|
||||
caseValuesMap.add(set.rightSide);
|
||||
}
|
||||
} catch (GraphPartChangeException gce) {
|
||||
//ignore
|
||||
@@ -555,9 +566,16 @@ public class ActionGraph extends Graph {
|
||||
List<GraphTargetItem> switchExpressions = new ArrayList<>();
|
||||
List<GraphPart> switchOnFalseParts = new ArrayList<>();
|
||||
BinaryOpItem sneq = (BinaryOpItem) ii.expression;
|
||||
if (sneq.leftSide instanceof StoreRegisterActionItem) {
|
||||
StoreRegisterActionItem sr = (StoreRegisterActionItem) sneq.leftSide;
|
||||
int regId = sr.register.number;
|
||||
if ((sneq.leftSide instanceof StoreRegisterActionItem) || (sneq.leftSide instanceof GetVariableActionItem)) {
|
||||
|
||||
int regId = -1;
|
||||
GetVariableActionItem svar = null;
|
||||
if (sneq.leftSide instanceof StoreRegisterActionItem) {
|
||||
StoreRegisterActionItem sr = (StoreRegisterActionItem) sneq.leftSide;
|
||||
regId = sr.register.number;
|
||||
} else {
|
||||
svar = (GetVariableActionItem) sneq.leftSide;
|
||||
}
|
||||
|
||||
switchParts.add(ii.decisionPart);
|
||||
switchExpressions.add(sneq.rightSide);
|
||||
@@ -586,6 +604,15 @@ public class ActionGraph extends Graph {
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else if (svar != null && sneq.leftSide instanceof GetVariableActionItem) {
|
||||
if (sneq.leftSide.valueEquals(svar)) {
|
||||
switchParts.add(ii2.decisionPart);
|
||||
switchOnFalseParts.add(ii2.onTruePart);
|
||||
switchExpressions.add(sneq.rightSide);
|
||||
walkNext.add(isNeq ? ii2.onFalse : ii2.onTrue);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@ import com.jpexs.decompiler.graph.TranslateStack;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -106,9 +107,16 @@ public class ActionWaitForFrame extends Action implements ActionStore {
|
||||
public void translate(SecondPassData secondPassData, boolean insideDoInitAction, GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) throws InterruptedException {
|
||||
GraphTargetItem frameTi = new DirectValueActionItem(null, null, 0, (Long) ((long) frame), new ArrayList<>());
|
||||
List<GraphTargetItem> body;
|
||||
HashMap<String, GraphTargetItem> variablesBackup = new LinkedHashMap<>(variables);
|
||||
HashMap<String, GraphTargetItem> functionsBackup = new LinkedHashMap<>(functions);
|
||||
|
||||
try {
|
||||
body = ActionGraph.translateViaGraph(null, insideDoInitAction, true, regNames, variables, functions, skipped, SWF.DEFAULT_VERSION, staticOperation, path);
|
||||
} catch (SecondPassException spe) {
|
||||
variables.clear();
|
||||
variables.putAll(variablesBackup);
|
||||
functions.clear();
|
||||
functions.putAll(functionsBackup);
|
||||
body = ActionGraph.translateViaGraph(spe.getData(), insideDoInitAction, true, regNames, variables, functions, skipped, SWF.DEFAULT_VERSION, staticOperation, path);
|
||||
}
|
||||
output.add(new IfFrameLoadedActionItem(frameTi, body, this, lineStartAction));
|
||||
|
||||
@@ -38,6 +38,7 @@ import com.jpexs.decompiler.graph.TranslateStack;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -151,9 +152,15 @@ public class ActionWaitForFrame2 extends Action implements ActionStore {
|
||||
public void translate(SecondPassData secondPassData, boolean insideDoInitAction, GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) throws InterruptedException {
|
||||
GraphTargetItem frame = stack.pop();
|
||||
List<GraphTargetItem> body;
|
||||
HashMap<String, GraphTargetItem> variablesBackup = new LinkedHashMap<>(variables);
|
||||
HashMap<String, GraphTargetItem> functionsBackup = new LinkedHashMap<>(functions);
|
||||
try {
|
||||
body = ActionGraph.translateViaGraph(null, insideDoInitAction, true, regNames, variables, functions, skipped, SWF.DEFAULT_VERSION, staticOperation, path);
|
||||
} catch (SecondPassException spe) {
|
||||
variables.clear();
|
||||
variables.putAll(variablesBackup);
|
||||
functions.clear();
|
||||
functions.putAll(functionsBackup);
|
||||
body = ActionGraph.translateViaGraph(spe.getData(), insideDoInitAction, true, regNames, variables, functions, skipped, SWF.DEFAULT_VERSION, staticOperation, path);
|
||||
}
|
||||
output.add(new IfFrameLoadedActionItem(frame, body, this, lineStartAction));
|
||||
|
||||
Reference in New Issue
Block a user