Fixed: #2270 AS3 decompilation - unnnecessary local registers assignments as part of expressions when using optimization like dup, setlocal N instead of setlocal N, getlocal N

This commit is contained in:
Jindra Petřík
2024-08-12 19:51:40 +02:00
parent 02baf4baa6
commit 16ff10a890
31 changed files with 487 additions and 58 deletions
@@ -0,0 +1,44 @@
/*
* Copyright (C) 2010-2024 JPEXS, All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
*/
package com.jpexs.decompiler.graph;
import java.util.Collection;
import java.util.Stack;
/**
* Abstract graph target recursive visitor.
*
* @author JPEXS
*/
public abstract class AbstractGraphTargetRecursiveVisitor implements GraphTargetRecursiveVisitorInterface {
/**
* Constructs new AbstractGraphTargetVisitor
*/
public AbstractGraphTargetRecursiveVisitor() {
}
@Override
public abstract void visit(GraphTargetItem item, Stack<GraphTargetItem> parentStack);
@Override
public final void visitAll(Collection<GraphTargetItem> items, Stack<GraphTargetItem> parentStack) {
for (GraphTargetItem item : items) {
visit(item, parentStack);
}
}
}
@@ -2715,6 +2715,18 @@ public class Graph {
return printGraph(foundGotos, partCodes, partCodePos, visited, localData, stack, allParts, parent, part, stopPart, stopPartKind, loops, throwStates, null, staticOperation, path, 0);
}
/**
* Gets if expression from stack.
* Can be overriden for custom handling
* @param localData Local data
* @param stack Stack
* @param output Output
* @return Expression
*/
protected GraphTargetItem getIfExpression(BaseLocalData localData, TranslateStack stack, List<GraphTargetItem> output) {
return stack.pop();
}
/**
* Walks graph parts and converts them to target items.
*
@@ -3254,7 +3266,7 @@ public class Graph {
} //else
GraphPart nextOnePart = null;
if (getNextParts(localData, part).size() == 2 && !partIsSwitch(part)) {
GraphTargetItem expr = stack.pop();
GraphTargetItem expr = getIfExpression(localData, stack, currentRet);
if (nextOnePart == null) {
@@ -48,6 +48,7 @@ import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.Stack;
/**
* Graph target item - an item in high level representation of the code.
@@ -963,15 +964,19 @@ public abstract class GraphTargetItem implements Serializable, Cloneable {
*
* @param visitor Visitor
*/
public final void visitRecursivelyNoBlock(GraphTargetVisitorInterface visitor) {
public final void visitRecursivelyNoBlock(GraphTargetRecursiveVisitorInterface visitor) {
Set<GraphTargetItem> visitedItems = new HashSet<>();
Stack<GraphTargetItem> parentStack = new Stack<>();
parentStack.add(this);
visitNoBlock(new AbstractGraphTargetVisitor() {
@Override
public void visit(GraphTargetItem item) {
if (item != null && !visitedItems.contains(item)) {
visitedItems.add(item);
visitor.visit(item);
visitor.visit(item, parentStack);
parentStack.push(item);
item.visitNoBlock(this);
parentStack.pop();
}
}
});
@@ -0,0 +1,44 @@
/*
* Copyright (C) 2010-2024 JPEXS, All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
*/
package com.jpexs.decompiler.graph;
import java.util.Collection;
import java.util.Stack;
/**
* Recursive graph target visitor interface.
*
* @author JPEXS
*/
public interface GraphTargetRecursiveVisitorInterface {
/**
* Visits a graph target item.
*
* @param item Graph target item
* @param parentStack Stack of parents
*/
public void visit(GraphTargetItem item, Stack<GraphTargetItem> parentStack);
/**
* Visits all graph target items.
*
* @param items Collection of graph target items
* @param parentStack Stack of parents
*/
public void visitAll(Collection<GraphTargetItem> items, Stack<GraphTargetItem> parentStack);
}
@@ -19,7 +19,7 @@ package com.jpexs.decompiler.graph;
import java.util.Collection;
/**
* Graph source visitor interface.
* Graph target visitor interface.
*
* @author JPEXS
*/
@@ -17,6 +17,10 @@
package com.jpexs.decompiler.graph;
import com.jpexs.decompiler.graph.model.PopItem;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -38,6 +42,27 @@ public class TranslateStack extends Stack<GraphTargetItem> {
*/
private final String path;
private Map<String, GraphTargetItem> marks = new HashMap<>();
/**
* Sets mark.
* @param name Name
* @param value Value
*/
public void setMark(String name, GraphTargetItem value) {
marks.put(name, value);
}
/**
* Gets mark.
* @param name Name
* @return Value
*/
public GraphTargetItem getMark(String name) {
return marks.get(name);
}
/**
* Simplifies all items in the stack.
*/