mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-06-12 14:11:54 +00:00
#349 AS3 - better handling of declarations
This commit is contained in:
@@ -31,6 +31,7 @@ All notable changes to this project will be documented in this file.
|
||||
- AS3 deobfuscator of registers parsing of exception targets
|
||||
- AS3 code with exception start/end not matching instruction boundary
|
||||
- AS3 deobfuscator in some cases
|
||||
- #349 AS3 - better handling of declarations
|
||||
|
||||
### Changed
|
||||
- AS3 test methods separated to classes
|
||||
|
||||
@@ -285,11 +285,13 @@ import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
|
||||
import com.jpexs.decompiler.flash.helpers.HighlightedTextWriter;
|
||||
import com.jpexs.decompiler.flash.helpers.SWFDecompilerPlugin;
|
||||
import com.jpexs.decompiler.flash.helpers.hilight.HighlightSpecialType;
|
||||
import com.jpexs.decompiler.graph.AbstractGraphTargetVisitor;
|
||||
import com.jpexs.decompiler.graph.Block;
|
||||
import com.jpexs.decompiler.graph.DottedChain;
|
||||
import com.jpexs.decompiler.graph.GraphPart;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.GraphTargetVisitorInterface;
|
||||
import com.jpexs.decompiler.graph.ScopeStack;
|
||||
import com.jpexs.decompiler.graph.SimpleValue;
|
||||
import com.jpexs.decompiler.graph.TranslateStack;
|
||||
@@ -306,6 +308,7 @@ import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
@@ -1804,93 +1807,89 @@ public class AVM2Code implements Cloneable {
|
||||
return assignment;
|
||||
}
|
||||
|
||||
private GraphTargetItem injectDeclarations(int minreg, GraphTargetItem ti, DeclarationAVM2Item[] declaredRegisters, List<Slot> declaredSlots, List<DeclarationAVM2Item> declaredSlotsDec, ABC abc, MethodBody body) {
|
||||
if (ti.value != null) {
|
||||
ti.value = injectDeclarations(minreg, ti.value, declaredRegisters, declaredSlots, declaredSlotsDec, abc, body);
|
||||
}
|
||||
//TODO: walk whole tree... some walker?
|
||||
if (ti instanceof IfItem) {
|
||||
((IfItem) ti).expression = injectDeclarations(minreg, ((IfItem) ti).expression, declaredRegisters, declaredSlots, declaredSlotsDec, abc, body);
|
||||
}
|
||||
if (ti instanceof BinaryOpItem) {
|
||||
((BinaryOpItem) ti).leftSide = injectDeclarations(minreg, ((BinaryOpItem) ti).leftSide, declaredRegisters, declaredSlots, declaredSlotsDec, abc, body);
|
||||
((BinaryOpItem) ti).rightSide = injectDeclarations(minreg, ((BinaryOpItem) ti).rightSide, declaredRegisters, declaredSlots, declaredSlotsDec, abc, body);
|
||||
}
|
||||
if (ti instanceof ForEachInAVM2Item) {
|
||||
ForEachInAVM2Item fei = (ForEachInAVM2Item) ti;
|
||||
if (fei.expression.object instanceof LocalRegAVM2Item) {
|
||||
int reg = ((LocalRegAVM2Item) fei.expression.object).regIndex;
|
||||
if (declaredRegisters[reg] == null) {
|
||||
fei.expression.object = handleDeclareReg(minreg, fei.expression.object, declaredRegisters, declaredSlots, reg);
|
||||
private void injectDeclarations(List<GraphTargetItem> items, int minreg, DeclarationAVM2Item[] declaredRegisters, List<Slot> declaredSlots, List<DeclarationAVM2Item> declaredSlotsDec, ABC abc, MethodBody body) {
|
||||
for (int i = 0; i < items.size(); i++) {
|
||||
GraphTargetItem currentItem = items.get(i);
|
||||
List<GraphTargetItem> itemsOnLine = new ArrayList<>();
|
||||
itemsOnLine.add(currentItem);
|
||||
currentItem.visitRecursivelyNoBlock(new AbstractGraphTargetVisitor() {
|
||||
@Override
|
||||
public void visit(GraphTargetItem item) {
|
||||
itemsOnLine.add(item);
|
||||
}
|
||||
});
|
||||
|
||||
if (currentItem instanceof ForEachInAVM2Item) {
|
||||
ForEachInAVM2Item fei = (ForEachInAVM2Item) currentItem;
|
||||
if (fei.expression.object instanceof LocalRegAVM2Item) {
|
||||
int reg = ((LocalRegAVM2Item) fei.expression.object).regIndex;
|
||||
if (declaredRegisters[reg] == null) {
|
||||
fei.expression.object = handleDeclareReg(minreg, fei.expression.object, declaredRegisters, declaredSlots, reg);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (currentItem instanceof ForInAVM2Item) {
|
||||
ForInAVM2Item fi = (ForInAVM2Item) currentItem;
|
||||
if (fi.expression.object instanceof LocalRegAVM2Item) {
|
||||
int reg = ((LocalRegAVM2Item) fi.expression.object).regIndex;
|
||||
fi.expression.object = handleDeclareReg(minreg, fi.expression.object, declaredRegisters, declaredSlots, reg);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ti instanceof ForInAVM2Item) {
|
||||
ForInAVM2Item fi = (ForInAVM2Item) ti;
|
||||
if (fi.expression.object instanceof LocalRegAVM2Item) {
|
||||
int reg = ((LocalRegAVM2Item) fi.expression.object).regIndex;
|
||||
fi.expression.object = handleDeclareReg(minreg, fi.expression.object, declaredRegisters, declaredSlots, reg);
|
||||
//nowdeclaredRegs.add(reg);
|
||||
|
||||
}
|
||||
}
|
||||
if (ti instanceof Block) {
|
||||
Block bl = (Block) ti;
|
||||
for (List<GraphTargetItem> s : bl.getSubs()) {
|
||||
injectDeclarations(minreg, s, declaredRegisters, declaredSlots, declaredSlotsDec, abc, body);
|
||||
}
|
||||
}
|
||||
if (ti instanceof SetLocalAVM2Item) {
|
||||
int reg = ((SetLocalAVM2Item) ti).regIndex;
|
||||
ti = handleDeclareReg(minreg, ti, declaredRegisters, declaredSlots, reg);
|
||||
return ti;
|
||||
}
|
||||
if (ti instanceof SetSlotAVM2Item) {
|
||||
SetSlotAVM2Item ssti = (SetSlotAVM2Item) ti;
|
||||
Slot sl = new Slot(ssti.scope, ssti.slotName);
|
||||
if (!declaredSlots.contains(sl)) {
|
||||
GraphTargetItem type = TypeItem.UNBOUNDED;
|
||||
for (int t = 0; t < body.traits.traits.size(); t++) {
|
||||
if (body.traits.traits.get(t).getName(abc) == sl.multiname) {
|
||||
if (body.traits.traits.get(t) instanceof TraitSlotConst) {
|
||||
type = PropertyAVM2Item.multinameToType(((TraitSlotConst) body.traits.traits.get(t)).type_index, abc.constants);
|
||||
for (GraphTargetItem subItem : itemsOnLine) {
|
||||
if (subItem instanceof SetLocalAVM2Item) {
|
||||
SetLocalAVM2Item setLocal = (SetLocalAVM2Item) subItem;
|
||||
int reg = setLocal.regIndex;
|
||||
GraphTargetItem dec = handleDeclareReg(minreg, subItem, declaredRegisters, declaredSlots, reg);
|
||||
if (dec != subItem) { //declared right now
|
||||
if (subItem == currentItem) {
|
||||
items.set(i, dec);
|
||||
} else {
|
||||
((DeclarationAVM2Item) dec).showValue = false;
|
||||
items.add(i, dec);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
DeclarationAVM2Item d = new DeclarationAVM2Item(ti, type);
|
||||
ssti.setDeclaration(d);
|
||||
declaredSlotsDec.add(d);
|
||||
declaredSlots.add(sl);
|
||||
return d;
|
||||
//nowdeclaredSlots.add(sl);
|
||||
} else {
|
||||
int idx = declaredSlots.indexOf(sl);
|
||||
ssti.setDeclaration(declaredSlotsDec.get(idx));
|
||||
if (subItem instanceof SetSlotAVM2Item) {
|
||||
SetSlotAVM2Item ssti = (SetSlotAVM2Item) subItem;
|
||||
Slot sl = new Slot(ssti.scope, ssti.slotName);
|
||||
if (!declaredSlots.contains(sl)) {
|
||||
GraphTargetItem type = TypeItem.UNBOUNDED;
|
||||
for (int t = 0; t < body.traits.traits.size(); t++) {
|
||||
if (body.traits.traits.get(t).getName(abc) == sl.multiname) {
|
||||
if (body.traits.traits.get(t) instanceof TraitSlotConst) {
|
||||
type = PropertyAVM2Item.multinameToType(((TraitSlotConst) body.traits.traits.get(t)).type_index, abc.constants);
|
||||
}
|
||||
}
|
||||
}
|
||||
DeclarationAVM2Item d = new DeclarationAVM2Item(subItem, type);
|
||||
ssti.setDeclaration(d);
|
||||
declaredSlotsDec.add(d);
|
||||
declaredSlots.add(sl);
|
||||
|
||||
if (subItem == currentItem) {
|
||||
items.set(i, d);
|
||||
} else {
|
||||
d.showValue = false;
|
||||
items.add(i, d);
|
||||
i++;
|
||||
}
|
||||
|
||||
} else {
|
||||
int idx = declaredSlots.indexOf(sl);
|
||||
ssti.setDeclaration(declaredSlotsDec.get(idx));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (currentItem instanceof Block) {
|
||||
Block blk = (Block) currentItem;
|
||||
for (List<GraphTargetItem> sub : blk.getSubs()) {
|
||||
injectDeclarations(sub, minreg, declaredRegisters, declaredSlots, declaredSlotsDec, abc, body);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ti;
|
||||
}
|
||||
|
||||
private void injectDeclarations(int minreg, List<GraphTargetItem> list, DeclarationAVM2Item[] declaredRegisters, List<Slot> declaredSlots, List<DeclarationAVM2Item> declaredSlotsDec, ABC abc, MethodBody body) {
|
||||
//List<Integer> nowdeclaredRegs=new ArrayList<>();
|
||||
//List<Slot> nowdeclaredSlots=new ArrayList<>();
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
GraphTargetItem ti = list.get(i);
|
||||
GraphTargetItem ti2 = injectDeclarations(minreg, ti, declaredRegisters, declaredSlots, declaredSlotsDec, abc, body);
|
||||
if (ti != ti2) {
|
||||
list.set(i, ti2);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
//undeclare registers at the end of the block?
|
||||
for(int reg:nowdeclaredRegs){
|
||||
declaredRegisters[reg] = false;
|
||||
}
|
||||
|
||||
for(Slot s:nowdeclaredSlots){
|
||||
declaredSlots.remove(s);
|
||||
}*/
|
||||
}
|
||||
|
||||
public List<GraphTargetItem> toGraphTargetItems(boolean thisHasDefaultToPrimitive, ConvertData convertData, String path, int methodIndex, boolean isStatic, int scriptIndex, int classIndex, ABC abc, MethodBody body, HashMap<Integer, String> localRegNames, ScopeStack scopeStack, int initializerType, List<DottedChain> fullyQualifiedNames, List<Traits> initTraits, int staticOperation, HashMap<Integer, Integer> localRegAssigmentIps, HashMap<Integer, List<Integer>> refs) throws InterruptedException {
|
||||
@@ -2000,7 +1999,7 @@ public class AVM2Code implements Cloneable {
|
||||
//
|
||||
|
||||
//int minreg = abc.method_info.get(body.method_info).getMaxReservedReg() + 1;
|
||||
injectDeclarations(1, list, d, new ArrayList<>(), new ArrayList<>(), abc, body);
|
||||
injectDeclarations(list, 1, d, new ArrayList<>(), new ArrayList<>(), abc, body);
|
||||
|
||||
int lastPos = list.size() - 1;
|
||||
if (lastPos < 0) {
|
||||
|
||||
@@ -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.model.clauses;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.AVM2Item;
|
||||
@@ -40,6 +41,8 @@ public class DeclarationAVM2Item extends AVM2Item {
|
||||
|
||||
public GraphTargetItem type;
|
||||
|
||||
public boolean showValue = true;
|
||||
|
||||
public DeclarationAVM2Item(GraphTargetItem assignment, GraphTargetItem type) {
|
||||
super(assignment.getSrc(), assignment.getLineStartItem(), assignment.getPrecedence());
|
||||
this.type = type;
|
||||
@@ -108,8 +111,11 @@ public class DeclarationAVM2Item extends AVM2Item {
|
||||
writer.append(localName);
|
||||
writer.append(":");
|
||||
type.appendTry(writer, localData);
|
||||
type.appendTry(writer, localData);
|
||||
writer.append(" = ");
|
||||
if (showValue) {
|
||||
writer.append(" = ");
|
||||
val.toString(writer, localData);
|
||||
}
|
||||
return writer;
|
||||
}
|
||||
if (assignment instanceof SetSlotAVM2Item) {
|
||||
SetSlotAVM2Item ssti = (SetSlotAVM2Item) assignment;
|
||||
@@ -136,8 +142,11 @@ public class DeclarationAVM2Item extends AVM2Item {
|
||||
writer.append(":");
|
||||
|
||||
type.appendTry(writer, localData);
|
||||
type.appendTry(writer, localData);
|
||||
writer.append(" = ");
|
||||
if (showValue) {
|
||||
writer.append(" = ");
|
||||
val.toString(writer, localData);
|
||||
}
|
||||
return writer;
|
||||
}
|
||||
writer.append("var ");
|
||||
return assignment.toString(writer, localData);
|
||||
|
||||
@@ -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.model.clauses;
|
||||
|
||||
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
|
||||
@@ -62,6 +63,12 @@ public class ForEachInAVM2Item extends LoopItem implements Block {
|
||||
visitor.visitAll(commands);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitNoBlock(GraphTargetVisitorInterface visitor) {
|
||||
visitor.visit(expression);
|
||||
}
|
||||
|
||||
|
||||
public ForEachInAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, Loop loop, InAVM2Item expression, List<GraphTargetItem> commands) {
|
||||
super(instruction, lineStartIns, loop);
|
||||
|
||||
|
||||
@@ -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.model.clauses;
|
||||
|
||||
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
|
||||
@@ -64,6 +65,12 @@ public class ForInAVM2Item extends LoopItem implements Block {
|
||||
visitor.visitAll(commands);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitNoBlock(GraphTargetVisitorInterface visitor) {
|
||||
visitor.visit(expression);
|
||||
}
|
||||
|
||||
|
||||
public ForInAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, Loop loop, InAVM2Item expression, List<GraphTargetItem> commands) {
|
||||
super(instruction, lineStartIns, loop);
|
||||
if (!commands.isEmpty()) {
|
||||
|
||||
@@ -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.model.clauses;
|
||||
|
||||
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
|
||||
@@ -88,6 +89,12 @@ public class TryAVM2Item extends AVM2Item implements Block {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitNoBlock(GraphTargetVisitorInterface visitor) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
public TryAVM2Item(List<GraphTargetItem> tryCommands, List<ABCException> catchExceptions, List<List<GraphTargetItem>> catchCommands, List<GraphTargetItem> finallyCommands, String finCatchName) {
|
||||
super(null, null, NOPRECEDENCE);
|
||||
this.tryCommands = tryCommands;
|
||||
|
||||
@@ -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.parser.script;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.AVM2Item;
|
||||
@@ -20,6 +21,7 @@ import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
|
||||
import com.jpexs.decompiler.graph.Block;
|
||||
import com.jpexs.decompiler.graph.DottedChain;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.GraphTargetVisitorInterface;
|
||||
import com.jpexs.decompiler.graph.model.ContinueItem;
|
||||
import com.jpexs.decompiler.graph.model.LocalData;
|
||||
import com.jpexs.decompiler.graph.model.UnboundedTypeItem;
|
||||
@@ -74,6 +76,12 @@ public class ClassAVM2Item extends AVM2Item implements Block {
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitNoBlock(GraphTargetVisitorInterface visitor) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
public ClassAVM2Item(List<Map.Entry<String, Map<String, String>>> metadata, List<DottedChain> importedClasses, NamespaceItem pkg, List<NamespaceItem> openedNamespaces, boolean isFinal, boolean isDynamic, String className, GraphTargetItem extendsOp, List<GraphTargetItem> implementsOp, List<GraphTargetItem> cinit, boolean staticInitActivation, List<AssignableAVM2Item> cinitVariables, GraphTargetItem iinit, List<AssignableAVM2Item> iinitVariables, List<GraphTargetItem> traits, boolean iinitActivation) {
|
||||
super(null, null, NOPRECEDENCE);
|
||||
this.metadata = metadata;
|
||||
|
||||
@@ -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.action.model.clauses;
|
||||
|
||||
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
|
||||
@@ -29,6 +30,7 @@ import com.jpexs.decompiler.graph.Block;
|
||||
import com.jpexs.decompiler.graph.CompilationException;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.GraphTargetVisitorInterface;
|
||||
import com.jpexs.decompiler.graph.SourceGenerator;
|
||||
import com.jpexs.decompiler.graph.model.ContinueItem;
|
||||
import com.jpexs.decompiler.graph.model.LocalData;
|
||||
@@ -63,6 +65,12 @@ public class ClassActionItem extends ActionItem implements Block {
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitNoBlock(GraphTargetVisitorInterface visitor) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
public ClassActionItem(GraphTargetItem className, GraphTargetItem extendsOp, List<GraphTargetItem> implementsOp, List<MyEntry<GraphTargetItem, GraphTargetItem>> traits, List<Boolean> traitsStatic) {
|
||||
super(null, null, NOPRECEDENCE);
|
||||
this.className = className;
|
||||
|
||||
@@ -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.action.model.clauses;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
@@ -35,6 +36,7 @@ import com.jpexs.decompiler.graph.Block;
|
||||
import com.jpexs.decompiler.graph.CompilationException;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.GraphTargetVisitorInterface;
|
||||
import com.jpexs.decompiler.graph.Loop;
|
||||
import com.jpexs.decompiler.graph.SourceGenerator;
|
||||
import com.jpexs.decompiler.graph.model.ContinueItem;
|
||||
@@ -66,6 +68,22 @@ public class ForInActionItem extends LoopActionItem implements Block {
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(GraphTargetVisitorInterface visitor) {
|
||||
visitor.visit(variableName);
|
||||
visitor.visit(enumVariable);
|
||||
visitor.visitAll(commands);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitNoBlock(GraphTargetVisitorInterface visitor) {
|
||||
visitor.visit(variableName);
|
||||
visitor.visit(enumVariable);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public ForInActionItem(GraphSourceItem instruction, GraphSourceItem lineStartIns, Loop loop, GraphTargetItem variableName, GraphTargetItem enumVariable, List<GraphTargetItem> commands) {
|
||||
super(instruction, lineStartIns, loop);
|
||||
this.variableName = variableName;
|
||||
|
||||
@@ -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.action.model.clauses;
|
||||
|
||||
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
|
||||
@@ -24,6 +25,7 @@ import com.jpexs.decompiler.graph.CompilationException;
|
||||
import com.jpexs.decompiler.graph.Graph;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.GraphTargetVisitorInterface;
|
||||
import com.jpexs.decompiler.graph.SourceGenerator;
|
||||
import com.jpexs.decompiler.graph.model.ContinueItem;
|
||||
import com.jpexs.decompiler.graph.model.LocalData;
|
||||
@@ -46,6 +48,19 @@ public class IfFrameLoadedActionItem extends ActionItem implements Block {
|
||||
this.frame = frame;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(GraphTargetVisitorInterface visitor) {
|
||||
visitor.visit(frame);
|
||||
visitor.visitAll(actions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitNoBlock(GraphTargetVisitorInterface visitor) {
|
||||
visitor.visit(frame);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException {
|
||||
writer.append("ifFrameLoaded");
|
||||
|
||||
@@ -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.action.model.clauses;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
@@ -39,6 +40,7 @@ import com.jpexs.decompiler.graph.Block;
|
||||
import com.jpexs.decompiler.graph.CompilationException;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.GraphTargetVisitorInterface;
|
||||
import com.jpexs.decompiler.graph.SourceGenerator;
|
||||
import com.jpexs.decompiler.graph.model.ContinueItem;
|
||||
import com.jpexs.decompiler.graph.model.LocalData;
|
||||
@@ -76,6 +78,26 @@ public class TryActionItem extends ActionItem implements Block {
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(GraphTargetVisitorInterface visitor) {
|
||||
if (tryCommands != null) {
|
||||
visitor.visitAll(tryCommands);
|
||||
}
|
||||
for (List<GraphTargetItem> cc : catchCommands) {
|
||||
visitor.visitAll(cc);
|
||||
}
|
||||
if (finallyCommands != null) {
|
||||
visitor.visitAll(finallyCommands);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitNoBlock(GraphTargetVisitorInterface visitor) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public TryActionItem(List<GraphTargetItem> tryCommands, List<GraphTargetItem> catchExceptionNames, List<GraphTargetItem> catchExceptionTypes, List<List<GraphTargetItem>> catchCommands, List<GraphTargetItem> finallyCommands) {
|
||||
super(null, null, NOPRECEDENCE);
|
||||
this.tryCommands = tryCommands;
|
||||
|
||||
@@ -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.graph;
|
||||
|
||||
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
|
||||
@@ -534,12 +535,30 @@ public abstract class GraphTargetItem implements Serializable, Cloneable {
|
||||
});
|
||||
}
|
||||
|
||||
public final void visitRecursivelyNoBlock(GraphTargetVisitorInterface visitor) {
|
||||
Set<GraphTargetItem> visitedItems = new HashSet<>();
|
||||
visitNoBlock(new AbstractGraphTargetVisitor() {
|
||||
@Override
|
||||
public void visit(GraphTargetItem item) {
|
||||
if (item != null && !visitedItems.contains(item)) {
|
||||
visitedItems.add(item);
|
||||
visitor.visit(item);
|
||||
item.visitNoBlock(this);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void visit(GraphTargetVisitorInterface visitor) {
|
||||
if (value != null) {
|
||||
visitor.visit(value);
|
||||
}
|
||||
}
|
||||
|
||||
public void visitNoBlock(GraphTargetVisitorInterface visitor) {
|
||||
visit(visitor);
|
||||
}
|
||||
|
||||
public abstract GraphTargetItem returnType();
|
||||
|
||||
@Override
|
||||
|
||||
@@ -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.graph.model;
|
||||
|
||||
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
|
||||
@@ -69,6 +70,14 @@ public class DoWhileItem extends LoopItem implements Block {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitNoBlock(GraphTargetVisitorInterface visitor) {
|
||||
if (expression != null) {
|
||||
visitor.visitAll(expression);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public DoWhileItem(GraphSourceItem src, GraphSourceItem lineStartIns, Loop loop, List<GraphTargetItem> commands, List<GraphTargetItem> expression) {
|
||||
super(src, lineStartIns, loop);
|
||||
this.expression = expression;
|
||||
|
||||
@@ -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.graph.model;
|
||||
|
||||
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
|
||||
@@ -75,6 +76,12 @@ public class ForItem extends LoopItem implements Block {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitNoBlock(GraphTargetVisitorInterface visitor) {
|
||||
visitor.visit(expression);
|
||||
}
|
||||
|
||||
|
||||
public ForItem(GraphSourceItem src, GraphSourceItem lineStartIns, Loop loop, List<GraphTargetItem> firstCommands, GraphTargetItem expression, List<GraphTargetItem> finalCommands, List<GraphTargetItem> commands) {
|
||||
super(src, lineStartIns, loop);
|
||||
this.firstCommands = firstCommands;
|
||||
|
||||
@@ -12,13 +12,15 @@
|
||||
* 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.graph.model;
|
||||
|
||||
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
|
||||
import com.jpexs.decompiler.graph.Block;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.GraphTargetVisitorInterface;
|
||||
import com.jpexs.decompiler.graph.TypeItem;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -106,4 +108,15 @@ public class GotoItem extends GraphTargetItem implements Block {
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(GraphTargetVisitorInterface visitor) {
|
||||
if (targetCommands != null) {
|
||||
visitor.visitAll(targetCommands);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitNoBlock(GraphTargetVisitorInterface visitor) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.graph.model;
|
||||
|
||||
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
|
||||
@@ -72,6 +73,12 @@ public class IfItem extends GraphTargetItem implements Block {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitNoBlock(GraphTargetVisitorInterface visitor) {
|
||||
visitor.visit(expression);
|
||||
}
|
||||
|
||||
|
||||
public IfItem(GraphSourceItem src, GraphSourceItem lineStartIns, GraphTargetItem expression, List<GraphTargetItem> onTrue, List<GraphTargetItem> onFalse) {
|
||||
super(src, lineStartIns, NOPRECEDENCE);
|
||||
this.expression = expression;
|
||||
|
||||
@@ -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.graph.model;
|
||||
|
||||
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
|
||||
@@ -62,6 +63,13 @@ public class SwitchItem extends LoopItem implements Block {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitNoBlock(GraphTargetVisitorInterface visitor) {
|
||||
visitor.visit(switchedObject);
|
||||
visitor.visitAll(caseValues);
|
||||
}
|
||||
|
||||
|
||||
public SwitchItem(GraphSourceItem instruction, GraphSourceItem lineStartIns, Loop loop, GraphTargetItem switchedObject, List<GraphTargetItem> caseValues, List<List<GraphTargetItem>> caseCommands, List<Integer> valuesMapping) {
|
||||
super(instruction, lineStartIns, loop);
|
||||
this.switchedObject = switchedObject;
|
||||
|
||||
@@ -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.graph.model;
|
||||
|
||||
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
|
||||
@@ -64,6 +65,14 @@ public class WhileItem extends LoopItem implements Block {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitNoBlock(GraphTargetVisitorInterface visitor) {
|
||||
if (expression != null) {
|
||||
visitor.visitAll(expression);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public WhileItem(GraphSourceItem src, GraphSourceItem lineStartIns, Loop loop, List<GraphTargetItem> expression, List<GraphTargetItem> commands) {
|
||||
super(src, lineStartIns, loop);
|
||||
this.expression = expression;
|
||||
|
||||
@@ -16,6 +16,17 @@ public class ActionScript3AssembledDecompileTest extends ActionScript3DecompileT
|
||||
addSwf("assembled", "testdata/as3_assembled/bin/as3_assembled.swf");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeclareReg() {
|
||||
decompileMethod("assembled", "testDeclareReg", "var _loc3_:*;\r\n"
|
||||
+ "with(_loc3_ = other)\r\n"
|
||||
+ "{\r\n"
|
||||
+ "\r\n"
|
||||
+ "trace(\"hey\");\r\n"
|
||||
+ "}\r\n",
|
||||
false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDoubleDup() {
|
||||
decompileMethod("assembled", "testDoubleDup", "var _loc10_:Rectangle = myprop(_loc5_);\r\n"
|
||||
@@ -25,7 +36,8 @@ public class ActionScript3AssembledDecompileTest extends ActionScript3DecompileT
|
||||
|
||||
@Test
|
||||
public void testDup() {
|
||||
decompileMethod("assembled", "testDup", "return 1 - (var _loc1_:Number = 1 - _loc1_ / _loc4_) * _loc1_;\r\n",
|
||||
decompileMethod("assembled", "testDup", "var _loc1_:Number;\r\n"
|
||||
+ "return 1 - (_loc1_ = 1 - _loc1_ / _loc4_) * _loc1_;\r\n",
|
||||
false);
|
||||
}
|
||||
|
||||
@@ -90,6 +102,7 @@ public class ActionScript3AssembledDecompileTest extends ActionScript3DecompileT
|
||||
@Test
|
||||
public void testSetSlotDup() {
|
||||
decompileMethod("assembled", "testSetSlotDup", "var _loc5_:int = 5;\r\n"
|
||||
+ "var myslot:int;\r\n"
|
||||
+ "myname.somemethod(\"okay\",myslot = _loc5_);\r\n"
|
||||
+ "myname.start();\r\n",
|
||||
false);
|
||||
@@ -97,7 +110,8 @@ public class ActionScript3AssembledDecompileTest extends ActionScript3DecompileT
|
||||
|
||||
@Test
|
||||
public void testSetSlotFindProperty() {
|
||||
decompileMethod("assembled", "testSetSlotFindProperty", "return var myprop:int = 50;\r\n",
|
||||
decompileMethod("assembled", "testSetSlotFindProperty", "var myprop:int;\r\n"
|
||||
+ "return myprop = 50;\r\n",
|
||||
false);
|
||||
}
|
||||
|
||||
|
||||
@@ -743,7 +743,6 @@ public class ActionScript3ClassicAirDecompileTest extends ActionScript3Decompile
|
||||
@Test
|
||||
public void testInc2() {
|
||||
decompileMethod("classic_air", "testInc2", "var a:* = [1];\r\n"
|
||||
+ "a[this.getInt()]++;\r\n"
|
||||
+ "var d:* = a[this.getInt()]++;\r\n"
|
||||
+ "var e:* = ++a[this.getInt()];\r\n"
|
||||
+ "a[this.getInt()]++;\r\n"
|
||||
@@ -942,7 +941,8 @@ public class ActionScript3ClassicAirDecompileTest extends ActionScript3Decompile
|
||||
public void testNamedAnonFunctions() {
|
||||
decompileMethod("classic_air", "testNamedAnonFunctions", "var test:* = new function():*\r\n"
|
||||
+ "{\r\n"
|
||||
+ "return var testFunc:Function = function(param1:*, param2:int, param3:Array):Boolean\r\n"
|
||||
+ "var testFunc:Function;\r\n"
|
||||
+ "return testFunc = function(param1:*, param2:int, param3:Array):Boolean\r\n"
|
||||
+ "{\r\n"
|
||||
+ "return (param1 as TestClass2).attrib1 == 5;\r\n"
|
||||
+ "};\r\n"
|
||||
|
||||
@@ -734,7 +734,6 @@ public class ActionScript3ClassicDecompileTest extends ActionScript3DecompileTes
|
||||
@Test
|
||||
public void testInc2() {
|
||||
decompileMethod("classic", "testInc2", "var a:* = [1];\r\n"
|
||||
+ "++a[this.getInt()];\r\n"
|
||||
+ "var d:* = a[this.getInt()]++;\r\n"
|
||||
+ "var e:* = ++a[this.getInt()];\r\n"
|
||||
+ "++a[this.getInt()];\r\n"
|
||||
|
||||
Binary file not shown.
@@ -16,5 +16,6 @@ program
|
||||
#include "tests/TestDup.script.asasm"
|
||||
#include "tests/TestSwitchDefault.script.asasm"
|
||||
#include "tests/TestSwitch.script.asasm"
|
||||
#include "tests/TestDeclareReg.script.asasm"
|
||||
; place to add next
|
||||
end ; program
|
||||
|
||||
76
libsrc/ffdec_lib/testdata/as3_assembled/abc/as3_assembled-0/tests/TestDeclareReg.class.asasm
vendored
Normal file
76
libsrc/ffdec_lib/testdata/as3_assembled/abc/as3_assembled-0/tests/TestDeclareReg.class.asasm
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
class
|
||||
refid "tests:TestDeclareReg"
|
||||
instance QName(PackageNamespace("tests"), "TestDeclareReg")
|
||||
extends QName(PackageNamespace(""), "Object")
|
||||
flag SEALED
|
||||
flag PROTECTEDNS
|
||||
protectedns ProtectedNamespace("tests:TestDeclareReg")
|
||||
iinit
|
||||
refid "tests:TestDeclareReg/instance/init"
|
||||
body
|
||||
maxstack 1
|
||||
localcount 1
|
||||
initscopedepth 4
|
||||
maxscopedepth 5
|
||||
code
|
||||
getlocal0
|
||||
pushscope
|
||||
|
||||
getlocal0
|
||||
constructsuper 0
|
||||
|
||||
returnvoid
|
||||
end ; code
|
||||
end ; body
|
||||
end ; method
|
||||
trait method QName(PackageNamespace(""), "run")
|
||||
method
|
||||
refid "tests:TestDeclareReg/instance/run"
|
||||
returns QName(PackageNamespace(""), "void")
|
||||
body
|
||||
maxstack 2
|
||||
localcount 4
|
||||
initscopedepth 4
|
||||
maxscopedepth 5
|
||||
code
|
||||
getlocal0
|
||||
pushscope
|
||||
newactivation
|
||||
dup
|
||||
setlocal2
|
||||
pushscope
|
||||
getscopeobject 1
|
||||
getslot 1
|
||||
dup
|
||||
setlocal3
|
||||
pushwith
|
||||
findpropstrict QName(PackageNamespace(""),"trace")
|
||||
pushstring "hey"
|
||||
callpropvoid QName(PackageNamespace(""),"trace"), 1
|
||||
popscope
|
||||
returnvoid
|
||||
end ; code
|
||||
trait slot QName(PackageInternalNs("something"),"other")
|
||||
slotid 1
|
||||
type QName(PackageNamespace(""),"XML")
|
||||
end ; trait
|
||||
end ; body
|
||||
end ; method
|
||||
end ; trait
|
||||
end ; instance
|
||||
cinit
|
||||
refid "tests:TestDeclareReg/class/init"
|
||||
body
|
||||
maxstack 1
|
||||
localcount 1
|
||||
initscopedepth 3
|
||||
maxscopedepth 4
|
||||
code
|
||||
getlocal0
|
||||
pushscope
|
||||
|
||||
returnvoid
|
||||
end ; code
|
||||
end ; body
|
||||
end ; method
|
||||
end ; class
|
||||
29
libsrc/ffdec_lib/testdata/as3_assembled/abc/as3_assembled-0/tests/TestDeclareReg.script.asasm
vendored
Normal file
29
libsrc/ffdec_lib/testdata/as3_assembled/abc/as3_assembled-0/tests/TestDeclareReg.script.asasm
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
script
|
||||
sinit
|
||||
refid "tests:TestDeclareReg/init"
|
||||
body
|
||||
maxstack 2
|
||||
localcount 1
|
||||
initscopedepth 1
|
||||
maxscopedepth 3
|
||||
code
|
||||
getlocal0
|
||||
pushscope
|
||||
|
||||
findpropstrict Multiname("TestDeclareReg", [PackageNamespace("tests")])
|
||||
getlex QName(PackageNamespace(""), "Object")
|
||||
pushscope
|
||||
|
||||
getlex Multiname("Object", [PrivateNamespace(null, "tests:TestDeclareReg"), PackageNamespace(""), PackageNamespace("tests"), PackageInternalNs("tests"), Namespace("http://adobe.com/AS3/2006/builtin")])
|
||||
newclass "tests:TestDeclareReg"
|
||||
popscope
|
||||
initproperty QName(PackageNamespace("tests"), "TestDeclareReg")
|
||||
|
||||
returnvoid
|
||||
end ; code
|
||||
end ; body
|
||||
end ; method
|
||||
trait class QName(PackageNamespace("tests"), "TestDeclareReg")
|
||||
#include "TestDeclareReg.class.asasm"
|
||||
end ; trait
|
||||
end ; script
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user