AS3 p-code more RAbcDasm like

- get/setlocal_x renamed to get/setlocalx
- QName casing changed from Qname

Better increment/decrement detection, chained assignments.
This commit is contained in:
Jindra Petřík
2021-01-26 21:12:34 +01:00
parent 5cc22a1b4c
commit 0da0e41cc6
53 changed files with 1245 additions and 376 deletions

View File

@@ -24,9 +24,12 @@ All notable changes to this project will be documented in this file.
### Changed
- AS3 test methods separated to classes
- AS3 p-code more RAbcDasm like: parenthesis after True/False/Undefined/Null trait kinds
- AS3 p-code more RAbcDasm like: commas in parameters list (WARNING: Breaks backward compatibility)
- AS3 p-code more RAbcDasm like: lookupswitch caseoffsets in brackets
- AS3 p-code more RAbcDasm like (WARNING: Breaks backward compatibility):
- parenthesis after True/False/Undefined/Null trait kinds
- commas in parameters list
- lookupswitch caseoffsets in brackets
- get/setlocal_x renamed to get/setlocalx
- QName casing changed from Qname
### Removed
- Code structure detection in Graphviz graphs as it was usually wrong

View File

@@ -320,24 +320,4 @@ public abstract class InstructionDefinition implements Serializable {
}
return localData.code.adr2pos(src.getAddress());
}
public void cleanTempRegisters(AVM2LocalData localData, List<GraphTargetItem> output, List<LocalRegAVM2Item> usedLocalRegs) {
for (LocalRegAVM2Item reg : usedLocalRegs) {
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 = getItemIp(localData, setLocal);
Set<Integer> usages = localData.getSetLocalUsages(setLocalIp);
int usageIp = getItemIp(localData, reg);
if (usages.size() == 1 && usages.iterator().next().equals(usageIp)) {
output.remove(i);
}
}
} else {
break;
}
}
}
}
}

View File

@@ -24,7 +24,9 @@ import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
import com.jpexs.decompiler.flash.abc.avm2.model.CallAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.GetPropertyAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.LocalRegAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.SetLocalAVM2Item;
import com.jpexs.decompiler.flash.ecma.NotCompileTime;
import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.TranslateStack;
@@ -74,12 +76,21 @@ public class CallIns extends InstructionDefinition {
args.add(0, stack.pop());
}
GraphTargetItem receiver = stack.pop();
if (receiver instanceof LocalRegAVM2Item) {
List<LocalRegAVM2Item> localRegs = new ArrayList<>();
localRegs.add((LocalRegAVM2Item) receiver);
cleanTempRegisters(localData, output, localRegs);
}
GraphTargetItem function = stack.pop();
if (function instanceof GetPropertyAVM2Item) {
GetPropertyAVM2Item getProperty = (GetPropertyAVM2Item) function;
if (getProperty.object instanceof SetLocalAVM2Item) {
SetLocalAVM2Item setLocal = (SetLocalAVM2Item) getProperty.object;
if (receiver instanceof LocalRegAVM2Item) {
LocalRegAVM2Item getLocal = (LocalRegAVM2Item) receiver;
if (getLocal.regIndex == setLocal.regIndex) {
getProperty.object = getProperty.object.value;
receiver = getProperty.object;
}
}
}
}
stack.push(new CallAVM2Item(ins, localData.lineStartInstruction, receiver, function, args));
}

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.avm2.instructions.AVM2Instruction;
@@ -24,7 +25,7 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
public class GetLocal0Ins extends GetLocalTypeIns {
public GetLocal0Ins() {
public GetLocal0Ins() {
super(0xd0, "getlocal0", new int[]{}, false);
}
@Override

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.avm2.instructions.AVM2Instruction;
@@ -24,7 +25,7 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
public class GetLocal1Ins extends GetLocalTypeIns {
public GetLocal1Ins() {
public GetLocal1Ins() {
super(0xd1, "getlocal1", new int[]{}, false);
}
@Override

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.avm2.instructions.AVM2Instruction;
@@ -24,7 +25,7 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
public class GetLocal2Ins extends GetLocalTypeIns {
public GetLocal2Ins() {
public GetLocal2Ins() {
super(0xd2, "getlocal2", new int[]{}, false);
}
@Override

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.avm2.instructions.AVM2Instruction;
@@ -24,7 +25,7 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
public class GetLocal3Ins extends GetLocalTypeIns {
public GetLocal3Ins() {
public GetLocal3Ins() {
super(0xd3, "getlocal3", new int[]{}, false);
}
@Override

View File

@@ -23,6 +23,8 @@ import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
import com.jpexs.decompiler.flash.abc.avm2.model.ClassAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.CoerceAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.ConvertAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.LocalRegAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.ScriptAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.SetLocalAVM2Item;
@@ -86,7 +88,27 @@ public abstract class GetLocalTypeIns extends InstructionDefinition {
//computedValue = new NotCompileTimeItem(ins, localData.lineStartInstruction, computedValue);
}
if (output.size() >= 2) {
//chained assignments
if (!output.isEmpty()) {
if ((output.get(output.size() - 1) instanceof SetTypeAVM2Item)) {
GraphTargetItem setItem = output.get(output.size() - 1);
if (setItem.value.getNotCoerced() instanceof SetLocalAVM2Item) {
SetLocalAVM2Item setLocal = (SetLocalAVM2Item) setItem.value.getNotCoerced();
if (setLocal.regIndex == regId) {
if ((setItem.value instanceof CoerceAVM2Item) || (setItem.value instanceof ConvertAVM2Item)) {
setItem.value.value = setLocal.value;
} else {
setItem.value = setLocal.value;
}
output.remove(output.size() - 1);
stack.add(setItem);
return;
}
}
}
}
/*if (output.size() >= 2) {
if ((output.get(output.size() - 1) instanceof SetTypeAVM2Item) && (output.get(output.size() - 2) instanceof SetLocalAVM2Item)) {
SetLocalAVM2Item setLocal = (SetLocalAVM2Item) output.get(output.size() - 2);
GraphTargetItem setItem = output.get(output.size() - 1);
@@ -105,7 +127,7 @@ public abstract class GetLocalTypeIns extends InstructionDefinition {
}
}
}
}
}*/
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.localregs;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
@@ -24,7 +25,7 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
public class SetLocal0Ins extends SetLocalTypeIns {
public SetLocal0Ins() {
public SetLocal0Ins() {
super(0xd4, "setlocal0", new int[]{}, false);
}
@Override

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.avm2.instructions.AVM2Instruction;
@@ -24,7 +25,7 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
public class SetLocal1Ins extends SetLocalTypeIns {
public SetLocal1Ins() {
public SetLocal1Ins() {
super(0xd5, "setlocal1", new int[]{}, false);
}
@Override

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.avm2.instructions.AVM2Instruction;
@@ -24,7 +25,7 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
public class SetLocal2Ins extends SetLocalTypeIns {
public SetLocal2Ins() {
public SetLocal2Ins() {
super(0xd6, "setlocal2", new int[]{}, false);
}
@Override

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.avm2.instructions.AVM2Instruction;
@@ -24,7 +25,7 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
public class SetLocal3Ins extends SetLocalTypeIns {
public SetLocal3Ins() {
public SetLocal3Ins() {
super(0xd7, "setlocal3", new int[]{}, false);
}
@Override

View File

@@ -21,8 +21,11 @@ import com.jpexs.decompiler.flash.abc.AVM2LocalData;
import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
import static com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition.getItemIp;
import com.jpexs.decompiler.flash.abc.avm2.instructions.SetTypeIns;
import com.jpexs.decompiler.flash.abc.avm2.model.AVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.CoerceAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.ConvertAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.DecrementAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.FindPropertyAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.IncrementAVM2Item;
@@ -31,6 +34,7 @@ import com.jpexs.decompiler.flash.abc.avm2.model.NewActivationAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.PostDecrementAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.PostIncrementAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.SetLocalAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.SetTypeAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.operations.PreDecrementAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.operations.PreIncrementAVM2Item;
import com.jpexs.decompiler.flash.abc.types.MethodBody;
@@ -41,6 +45,7 @@ import com.jpexs.decompiler.graph.model.DuplicateItem;
import com.jpexs.decompiler.graph.model.PopItem;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import java.util.Stack;
/**
@@ -132,6 +137,27 @@ public abstract class SetLocalTypeIns extends InstructionDefinition implements S
if (localData.getSetLocalUsages(localData.code.adr2pos(ins.getAddress())).isEmpty() && (value instanceof DuplicateItem)) {
return;
}
GraphTargetItem notCoercedValue = value;
if ((value instanceof CoerceAVM2Item) || (value instanceof ConvertAVM2Item)) {
notCoercedValue = value.value;
}
if (notCoercedValue instanceof DuplicateItem) {
GraphTargetItem insideDup = notCoercedValue.value;
if (!stack.isEmpty() && stack.peek() == insideDup) {
stack.pop();
if ((value instanceof CoerceAVM2Item) || (value instanceof ConvertAVM2Item)) {
value.value = insideDup;
} else {
value = insideDup;
}
GraphTargetItem result = new SetLocalAVM2Item(ins, localData.lineStartInstruction, regId, value);
stack.push(result);
return;
}
}
GraphTargetItem result = new SetLocalAVM2Item(ins, localData.lineStartInstruction, regId, value);
output.add(result);
}

View File

@@ -27,12 +27,14 @@ import com.jpexs.decompiler.flash.abc.avm2.model.ApplyTypeAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.ConstructAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.DecrementAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.FullMultinameAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.GetLexAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.GetPropertyAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.IncrementAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.InitVectorAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.LocalRegAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.PostDecrementAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.PostIncrementAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.SetLocalAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.SetPropertyAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.operations.PreDecrementAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.operations.PreIncrementAVM2Item;
@@ -40,6 +42,7 @@ import com.jpexs.decompiler.flash.abc.types.MethodBody;
import com.jpexs.decompiler.graph.DottedChain;
import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.TranslateStack;
import com.jpexs.decompiler.graph.model.DuplicateItem;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -55,98 +58,156 @@ public class SetPropertyIns extends InstructionDefinition implements SetTypeIns
super(0x61, "setproperty", new int[]{AVM2Code.DAT_MULTINAME_INDEX}, true);
}
private GraphTargetItem checkIncDec(boolean standalone, int multinameIndex, AVM2Instruction ins, AVM2LocalData localData, GraphTargetItem item,
LocalRegAVM2Item valueLocalReg, LocalRegAVM2Item nameLocalReg, LocalRegAVM2Item objLocalReg) {
if (item instanceof SetLocalAVM2Item) {
SetLocalAVM2Item valueSetLocalReg = (SetLocalAVM2Item) item;
if ((valueSetLocalReg.value instanceof IncrementAVM2Item) || (valueSetLocalReg.value instanceof DecrementAVM2Item)) {
boolean isIncrement = (valueSetLocalReg.value instanceof IncrementAVM2Item);
if (valueSetLocalReg.value.value instanceof GetPropertyAVM2Item) {
GetPropertyAVM2Item getProperty = (GetPropertyAVM2Item) valueSetLocalReg.value.value;
FullMultinameAVM2Item propertyName = ((FullMultinameAVM2Item) getProperty.propertyName);
SetLocalAVM2Item nameSetLocalReg = null;
if (propertyName.name instanceof SetLocalAVM2Item) {
nameSetLocalReg = (SetLocalAVM2Item) propertyName.name;
}
if (getProperty.object instanceof SetLocalAVM2Item) {
SetLocalAVM2Item objSetLocalReg = (SetLocalAVM2Item) getProperty.object;
if ((valueLocalReg.regIndex == valueSetLocalReg.regIndex)
&& (propertyName.multinameIndex == multinameIndex)
&& ((nameLocalReg == null && nameSetLocalReg == null) || (nameLocalReg.regIndex == nameSetLocalReg.regIndex))
&& (objLocalReg.regIndex == objSetLocalReg.regIndex)) {
if (nameSetLocalReg != null) {
propertyName.name = nameSetLocalReg.value;
}
getProperty.object = objSetLocalReg.value;
if (standalone) {
if (isIncrement) {
return new PostIncrementAVM2Item(ins, localData.lineStartInstruction, getProperty);
} else {
return new PostDecrementAVM2Item(ins, localData.lineStartInstruction, getProperty);
}
} else {
if (isIncrement) {
return new PreIncrementAVM2Item(ins, localData.lineStartInstruction, getProperty);
} else {
return new PreDecrementAVM2Item(ins, localData.lineStartInstruction, getProperty);
}
}
}
}
}
}
}
return null;
}
@Override
public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List<GraphTargetItem> output, String path) {
int multinameIndex = ins.operands[0];
GraphTargetItem value = stack.pop();
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) {
if ((value instanceof IncrementAVM2Item) || (value instanceof DecrementAVM2Item)) {
boolean isIncrement = (value instanceof IncrementAVM2Item);
if (value.value instanceof DuplicateItem) {
GraphTargetItem duplicated = value.value.value;
if (!stack.isEmpty()) {
if (stack.peek() == duplicated) {
GraphTargetItem notCoerced = duplicated.getNotCoerced();
if (notCoerced instanceof GetLexAVM2Item) {
GetLexAVM2Item getLex = (GetLexAVM2Item) notCoerced;
if (localData.abc.constants.getMultiname(multinameIndex).equals(getLex.propertyName)) {
stack.pop();
stack.push(new PostIncrementAVM2Item(ins, localData.lineStartInstruction, insideProp));
} else if ((top instanceof IncrementAVM2Item) && (((IncrementAVM2Item) top).value == inside)) {
stack.pop();
stack.push(new PreIncrementAVM2Item(ins, localData.lineStartInstruction, insideProp));
} else {
output.add(new PostIncrementAVM2Item(ins, localData.lineStartInstruction, insideProp));
if (isIncrement) {
stack.push(new PostIncrementAVM2Item(ins, localData.lineStartInstruction, getLex));
} else {
stack.push(new PostDecrementAVM2Item(ins, localData.lineStartInstruction, getLex));
}
return;
}
} else {
output.add(new PostIncrementAVM2Item(ins, localData.lineStartInstruction, insideProp));
}
return;
}
}
}
}
if (value.getThroughDuplicate().getThroughRegister().getThroughDuplicate() instanceof DecrementAVM2Item) {
List<LocalRegAVM2Item> localRegs = new ArrayList<>();
if (value.getThroughDuplicate() instanceof LocalRegAVM2Item) {
localRegs.add((LocalRegAVM2Item) value.getThroughDuplicate());
if (value instanceof LocalRegAVM2Item) {
LocalRegAVM2Item valueLocalReg = (LocalRegAVM2Item) value;
LocalRegAVM2Item nameLocalReg = null;
if (multiname.name instanceof LocalRegAVM2Item) {
nameLocalReg = (LocalRegAVM2Item) multiname.name;;
}
if (obj instanceof LocalRegAVM2Item) {
LocalRegAVM2Item objLocalReg = (LocalRegAVM2Item) obj;
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) {
stack.pop();
stack.push(new PostDecrementAVM2Item(ins, localData.lineStartInstruction, insideProp));
} else if ((top instanceof DecrementAVM2Item) && (((DecrementAVM2Item) top).value == inside)) {
stack.pop();
stack.push(new PreDecrementAVM2Item(ins, localData.lineStartInstruction, insideProp));
} else {
output.add(new PostDecrementAVM2Item(ins, localData.lineStartInstruction, insideProp));
if (!output.isEmpty() && !stack.isEmpty()) {
if (output.get(output.size() - 1) instanceof SetLocalAVM2Item) {
SetLocalAVM2Item valueSetLocalReg = (SetLocalAVM2Item) output.get(output.size() - 1);
if ((valueSetLocalReg.value instanceof IncrementAVM2Item)
|| (valueSetLocalReg.value instanceof DecrementAVM2Item)) {
boolean isIncrement = (valueSetLocalReg.value instanceof IncrementAVM2Item);
if (valueSetLocalReg.value.value instanceof DuplicateItem) {
GraphTargetItem duplicated = valueSetLocalReg.value.value.value;
if (stack.peek() == duplicated) {
GraphTargetItem notCoerced = duplicated.getNotCoerced();
if (notCoerced instanceof GetPropertyAVM2Item) {
GetPropertyAVM2Item getProperty = (GetPropertyAVM2Item) notCoerced;
FullMultinameAVM2Item propertyName = ((FullMultinameAVM2Item) getProperty.propertyName);
SetLocalAVM2Item nameSetLocalReg = null;
if (propertyName.name instanceof SetLocalAVM2Item) {
nameSetLocalReg = (SetLocalAVM2Item) propertyName.name;
}
if (getProperty.object instanceof SetLocalAVM2Item) {
SetLocalAVM2Item objSetLocalReg = (SetLocalAVM2Item) getProperty.object;
if ((valueLocalReg.regIndex == valueSetLocalReg.regIndex)
&& (propertyName.multinameIndex == multinameIndex)
&& ((nameLocalReg == null && nameSetLocalReg == null) || (nameLocalReg.regIndex == nameSetLocalReg.regIndex))
&& (objLocalReg.regIndex == objSetLocalReg.regIndex)) {
if (nameSetLocalReg != null) {
propertyName.name = nameSetLocalReg.value;
}
getProperty.object = objSetLocalReg.value;
output.remove(output.size() - 1);
stack.pop();
if (isIncrement) {
stack.push(new PostIncrementAVM2Item(ins, localData.lineStartInstruction, getProperty));
} else {
stack.push(new PostDecrementAVM2Item(ins, localData.lineStartInstruction, getProperty));
}
return;
}
}
}
}
}
} else {
output.add(new PostDecrementAVM2Item(ins, localData.lineStartInstruction, insideProp));
}
}
}
if (!stack.isEmpty()) {
GraphTargetItem checked = checkIncDec(false, multinameIndex, ins, localData, stack.peek(), valueLocalReg, nameLocalReg, objLocalReg);
if (checked != null) {
stack.pop();
stack.push(checked);
return;
}
}
if (!output.isEmpty()) {
GraphTargetItem checked = checkIncDec(true, multinameIndex, ins, localData, output.get(output.size() - 1), valueLocalReg, nameLocalReg, objLocalReg);
if (checked != null) {
output.remove(output.size() - 1);
output.add(checked);
return;
}
}
}
}

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.model;
import com.jpexs.decompiler.flash.IdentifiersDeobfuscation;
@@ -172,4 +173,33 @@ public abstract class AVM2Item extends GraphTargetItem {
AVM2SourceGenerator g = (AVM2SourceGenerator) generator;
g.killRegister(localData, regNumber);
}
@Override
public boolean isIdentical(GraphTargetItem other) {
GraphTargetItem tiName = this;
while (tiName instanceof LocalRegAVM2Item) {
if (((LocalRegAVM2Item) tiName).computedValue != null) {
tiName = ((LocalRegAVM2Item) tiName).computedValue.getThroughNotCompilable().getThroughDuplicate();
} else {
break;
}
}
GraphTargetItem tiName2 = other;
if (tiName2 != null) {
tiName2 = tiName2.getThroughDuplicate();
}
while (tiName2 instanceof LocalRegAVM2Item) {
if (((LocalRegAVM2Item) tiName2).computedValue != null) {
tiName2 = ((LocalRegAVM2Item) tiName2).computedValue.getThroughNotCompilable().getThroughDuplicate();
} else {
break;
}
}
if (tiName != tiName2) {
return false;
}
return true;
}
}

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.model;
import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool;
@@ -21,6 +22,7 @@ import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
import com.jpexs.decompiler.graph.DottedChain;
import com.jpexs.decompiler.graph.GraphSourceItem;
import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.SimpleValue;
import com.jpexs.decompiler.graph.TypeItem;
import com.jpexs.decompiler.graph.model.LocalData;
@@ -28,7 +30,7 @@ import com.jpexs.decompiler.graph.model.LocalData;
*
* @author JPEXS
*/
*/
public class GetLexAVM2Item extends AVM2Item implements SimpleValue {
public Multiname propertyName;
@@ -60,4 +62,9 @@ public class GetLexAVM2Item extends AVM2Item {
public boolean hasReturnValue() {
return true;
}
@Override
public boolean isSimpleValue() {
return true;
}
}

View File

@@ -319,7 +319,7 @@ public final class MethodBody implements Cloneable {
} catch (InterruptedException ex) {
throw ex;
} catch (Exception | OutOfMemoryError | StackOverflowError ex) {
ex.printStackTrace();
convertException = ex;
Throwable cause = ex.getCause();
if (ex instanceof ExecutionException && cause instanceof Exception) {
@@ -384,6 +384,7 @@ public final class MethodBody implements Cloneable {
} catch (ThreadDeath | InterruptedException ex) {
throw ex;
} catch (Throwable ex) {
ex.printStackTrace();
//ignore
logger.log(Level.SEVERE, "Deobfuscation failed in: " + path, ex);
body = clone();

View File

@@ -56,7 +56,7 @@ public class Multiname {
private static final int[] multinameKinds = new int[]{QNAME, QNAMEA, MULTINAME, MULTINAMEA, RTQNAME, RTQNAMEA, MULTINAMEL, RTQNAMEL, RTQNAMELA, MULTINAMELA, TYPENAME};
private static final String[] multinameKindNames = new String[]{"Qname", "QnameA", "Multiname", "MultinameA", "RTQname", "RTQnameA", "MultinameL", "RTQnameL", "RTQnameLA", "MultinameLA", "TypeName"};
private static final String[] multinameKindNames = new String[]{"QName", "QNameA", "Multiname", "MultinameA", "RTQName", "RTQNameA", "MultinameL", "RTQNameL", "RTQNameLA", "MultinameLA", "TypeName"};
public int kind;

View File

@@ -1278,53 +1278,53 @@ instruction.multiply_i.stackBefore = value1, value2
instruction.multiply_i.stackAfter = value3
instruction.multiply_i.operands =
instruction.getlocal_0.shortDescription = Get local register 0
instruction.getlocal_0.description =
instruction.getlocal_0.stackBefore =
instruction.getlocal_0.stackAfter = value
instruction.getlocal_0.operands =
instruction.getlocal0.shortDescription = Get local register 0
instruction.getlocal0.description =
instruction.getlocal0.stackBefore =
instruction.getlocal0.stackAfter = value
instruction.getlocal0.operands =
instruction.getlocal_1.shortDescription = Get local register 1
instruction.getlocal_1.description =
instruction.getlocal_1.stackBefore =
instruction.getlocal_1.stackAfter = value
instruction.getlocal_1.operands =
instruction.getlocal1.shortDescription = Get local register 1
instruction.getlocal1.description =
instruction.getlocal1.stackBefore =
instruction.getlocal1.stackAfter = value
instruction.getlocal1.operands =
instruction.getlocal_2.shortDescription = Get local register 2
instruction.getlocal_2.description =
instruction.getlocal_2.stackBefore =
instruction.getlocal_2.stackAfter = value
instruction.getlocal_2.operands =
instruction.getlocal2.shortDescription = Get local register 2
instruction.getlocal2.description =
instruction.getlocal2.stackBefore =
instruction.getlocal2.stackAfter = value
instruction.getlocal2.operands =
instruction.getlocal_3.shortDescription = Get local register 3
instruction.getlocal_3.description =
instruction.getlocal_3.stackBefore =
instruction.getlocal_3.stackAfter = value
instruction.getlocal_3.operands =
instruction.getlocal3.shortDescription = Get local register 3
instruction.getlocal3.description =
instruction.getlocal3.stackBefore =
instruction.getlocal3.stackAfter = value
instruction.getlocal3.operands =
instruction.setlocal_0.shortDescription = Set local register 0
instruction.setlocal_0.description =
instruction.setlocal_0.stackBefore = value
instruction.setlocal_0.stackAfter =
instruction.setlocal_0.operands =
instruction.setlocal0.shortDescription = Set local register 0
instruction.setlocal0.description =
instruction.setlocal0.stackBefore = value
instruction.setlocal0.stackAfter =
instruction.setlocal0.operands =
instruction.setlocal_1.shortDescription = Set local register 1
instruction.setlocal_1.description =
instruction.setlocal_1.stackBefore = value
instruction.setlocal_1.stackAfter =
instruction.setlocal_1.operands =
instruction.setlocal1.shortDescription = Set local register 1
instruction.setlocal1.description =
instruction.setlocal1.stackBefore = value
instruction.setlocal1.stackAfter =
instruction.setlocal1.operands =
instruction.setlocal_2.shortDescription = Set local register 2
instruction.setlocal_2.description =
instruction.setlocal_2.stackBefore = value
instruction.setlocal_2.stackAfter =
instruction.setlocal_2.operands =
instruction.setlocal2.shortDescription = Set local register 2
instruction.setlocal2.description =
instruction.setlocal2.stackBefore = value
instruction.setlocal2.stackAfter =
instruction.setlocal2.operands =
instruction.setlocal_3.shortDescription = Set local register 3
instruction.setlocal_3.description =
instruction.setlocal_3.stackBefore = value
instruction.setlocal_3.stackAfter =
instruction.setlocal_3.operands =
instruction.setlocal3.shortDescription = Set local register 3
instruction.setlocal3.description =
instruction.setlocal3.stackBefore = value
instruction.setlocal3.stackAfter =
instruction.setlocal3.operands =
#Undocumented:
instruction.invalid.shortDescription = Invalid

View File

@@ -1278,53 +1278,53 @@ instruction.multiply_i.stackBefore = value1, value2
instruction.multiply_i.stackAfter = value3
instruction.multiply_i.operands =
instruction.getlocal_0.shortDescription = Obt\u00e9 el registre local 0
instruction.getlocal_0.description =
instruction.getlocal_0.stackBefore =
instruction.getlocal_0.stackAfter = value
instruction.getlocal_0.operands =
instruction.getlocal0.shortDescription = Obt\u00e9 el registre local 0
instruction.getlocal0.description =
instruction.getlocal0.stackBefore =
instruction.getlocal0.stackAfter = value
instruction.getlocal0.operands =
instruction.getlocal_1.shortDescription = Obt\u00e9 el registre local 1
instruction.getlocal_1.description =
instruction.getlocal_1.stackBefore =
instruction.getlocal_1.stackAfter = value
instruction.getlocal_1.operands =
instruction.getlocal1.shortDescription = Obt\u00e9 el registre local 1
instruction.getlocal1.description =
instruction.getlocal1.stackBefore =
instruction.getlocal1.stackAfter = value
instruction.getlocal1.operands =
instruction.getlocal_2.shortDescription = Obt\u00e9 el registre local 2
instruction.getlocal_2.description =
instruction.getlocal_2.stackBefore =
instruction.getlocal_2.stackAfter = value
instruction.getlocal_2.operands =
instruction.getlocal2.shortDescription = Obt\u00e9 el registre local 2
instruction.getlocal2.description =
instruction.getlocal2.stackBefore =
instruction.getlocal2.stackAfter = value
instruction.getlocal2.operands =
instruction.getlocal_3.shortDescription = Obt\u00e9 el registre local 3
instruction.getlocal_3.description =
instruction.getlocal_3.stackBefore =
instruction.getlocal_3.stackAfter = value
instruction.getlocal_3.operands =
instruction.getlocal3.shortDescription = Obt\u00e9 el registre local 3
instruction.getlocal3.description =
instruction.getlocal3.stackBefore =
instruction.getlocal3.stackAfter = value
instruction.getlocal3.operands =
instruction.setlocal_0.shortDescription = Estableix el registre local 0
instruction.setlocal_0.description =
instruction.setlocal_0.stackBefore = value
instruction.setlocal_0.stackAfter =
instruction.setlocal_0.operands =
instruction.setlocal0.shortDescription = Estableix el registre local 0
instruction.setlocal0.description =
instruction.setlocal0.stackBefore = value
instruction.setlocal0.stackAfter =
instruction.setlocal0.operands =
instruction.setlocal_1.shortDescription = Estableix el registre local 1
instruction.setlocal_1.description =
instruction.setlocal_1.stackBefore = value
instruction.setlocal_1.stackAfter =
instruction.setlocal_1.operands =
instruction.setlocal1.shortDescription = Estableix el registre local 1
instruction.setlocal1.description =
instruction.setlocal1.stackBefore = value
instruction.setlocal1.stackAfter =
instruction.setlocal1.operands =
instruction.setlocal_2.shortDescription = Estableix el registre local 2
instruction.setlocal_2.description =
instruction.setlocal_2.stackBefore = value
instruction.setlocal_2.stackAfter =
instruction.setlocal_2.operands =
instruction.setlocal2.shortDescription = Estableix el registre local 2
instruction.setlocal2.description =
instruction.setlocal2.stackBefore = value
instruction.setlocal2.stackAfter =
instruction.setlocal2.operands =
instruction.setlocal_3.shortDescription = Estableix el registre local 3
instruction.setlocal_3.description =
instruction.setlocal_3.stackBefore = value
instruction.setlocal_3.stackAfter =
instruction.setlocal_3.operands =
instruction.setlocal3.shortDescription = Estableix el registre local 3
instruction.setlocal3.description =
instruction.setlocal3.stackBefore = value
instruction.setlocal3.stackAfter =
instruction.setlocal3.operands =
#Undocumented:
instruction.invalid.shortDescription = Inv\u00e0lid

View File

@@ -1698,67 +1698,67 @@ instruction.multiply_i.operands =
instruction.getlocal_0.shortDescription = Yerel kay\u0131t al 0
instruction.getlocal_0.description =
instruction.getlocal_0.stackBefore =
instruction.getlocal_0.stackAfter = de\u011fer
instruction.getlocal_0.operands =
instruction.getlocal0.shortDescription = Yerel kay\u0131t al 0
instruction.getlocal0.description =
instruction.getlocal0.stackBefore =
instruction.getlocal0.stackAfter = de\u011fer
instruction.getlocal0.operands =
instruction.getlocal_1.shortDescription = Yerel kay\u0131t al 1
instruction.getlocal_1.description =
instruction.getlocal_1.stackBefore =
instruction.getlocal_1.stackAfter = de\u011fer
instruction.getlocal_1.operands =
instruction.getlocal1.shortDescription = Yerel kay\u0131t al 1
instruction.getlocal1.description =
instruction.getlocal1.stackBefore =
instruction.getlocal1.stackAfter = de\u011fer
instruction.getlocal1.operands =
instruction.getlocal_2.shortDescription = Yerel kay\u0131t al 2
instruction.getlocal_2.description =
instruction.getlocal_2.stackBefore =
instruction.getlocal_2.stackAfter = de\u011fer
instruction.getlocal_2.operands =
instruction.getlocal2.shortDescription = Yerel kay\u0131t al 2
instruction.getlocal2.description =
instruction.getlocal2.stackBefore =
instruction.getlocal2.stackAfter = de\u011fer
instruction.getlocal2.operands =
instruction.getlocal_3.shortDescription = Yerel kay\u0131t al 3
instruction.getlocal_3.description =
instruction.getlocal_3.stackBefore =
instruction.getlocal_3.stackAfter = de\u011fer
instruction.getlocal_3.operands =
instruction.getlocal3.shortDescription = Yerel kay\u0131t al 3
instruction.getlocal3.description =
instruction.getlocal3.stackBefore =
instruction.getlocal3.stackAfter = de\u011fer
instruction.getlocal3.operands =
instruction.setlocal_0.shortDescription = Yerel kay\u0131t ayarla 0
instruction.setlocal_0.description =
instruction.setlocal_0.stackBefore = de\u011fer
instruction.setlocal_0.stackAfter =
instruction.setlocal_0.operands =
instruction.setlocal0.shortDescription = Yerel kay\u0131t ayarla 0
instruction.setlocal0.description =
instruction.setlocal0.stackBefore = de\u011fer
instruction.setlocal0.stackAfter =
instruction.setlocal0.operands =
instruction.setlocal_1.shortDescription = Yerel kay\u0131t ayarla 1
instruction.setlocal_1.description =
instruction.setlocal_1.stackBefore = de\u011fer
instruction.setlocal_1.stackAfter =
instruction.setlocal_1.operands =
instruction.setlocal1.shortDescription = Yerel kay\u0131t ayarla 1
instruction.setlocal1.description =
instruction.setlocal1.stackBefore = de\u011fer
instruction.setlocal1.stackAfter =
instruction.setlocal1.operands =
instruction.setlocal_2.shortDescription = Yerel kay\u0131t ayarla 2
instruction.setlocal_2.description =
instruction.setlocal_2.stackBefore = de\u011fer
instruction.setlocal_2.stackAfter =
instruction.setlocal_2.operands =
instruction.setlocal2.shortDescription = Yerel kay\u0131t ayarla 2
instruction.setlocal2.description =
instruction.setlocal2.stackBefore = de\u011fer
instruction.setlocal2.stackAfter =
instruction.setlocal2.operands =
instruction.setlocal_3.shortDescription = Yerel kay\u0131t ayarla 3
instruction.setlocal_3.description =
instruction.setlocal_3.stackBefore = de\u011fer
instruction.setlocal_3.stackAfter =
instruction.setlocal_3.operands =
instruction.setlocal3.shortDescription = Yerel kay\u0131t ayarla 3
instruction.setlocal3.description =
instruction.setlocal3.stackBefore = de\u011fer
instruction.setlocal3.stackAfter =
instruction.setlocal3.operands =
#Undocumented:

View File

@@ -1278,53 +1278,53 @@ instruction.multiply_i.stackBefore = value1, value2
instruction.multiply_i.stackAfter = value3
instruction.multiply_i.operands =
instruction.getlocal_0.shortDescription = Get local register 0
instruction.getlocal_0.description =
instruction.getlocal_0.stackBefore =
instruction.getlocal_0.stackAfter = value
instruction.getlocal_0.operands =
instruction.getlocal0.shortDescription = Get local register 0
instruction.getlocal0.description =
instruction.getlocal0.stackBefore =
instruction.getlocal0.stackAfter = value
instruction.getlocal0.operands =
instruction.getlocal_1.shortDescription = Get local register 1
instruction.getlocal_1.description =
instruction.getlocal_1.stackBefore =
instruction.getlocal_1.stackAfter = value
instruction.getlocal_1.operands =
instruction.getlocal1.shortDescription = Get local register 1
instruction.getlocal1.description =
instruction.getlocal1.stackBefore =
instruction.getlocal1.stackAfter = value
instruction.getlocal1.operands =
instruction.getlocal_2.shortDescription = Get local register 2
instruction.getlocal_2.description =
instruction.getlocal_2.stackBefore =
instruction.getlocal_2.stackAfter = value
instruction.getlocal_2.operands =
instruction.getlocal2.shortDescription = Get local register 2
instruction.getlocal2.description =
instruction.getlocal2.stackBefore =
instruction.getlocal2.stackAfter = value
instruction.getlocal2.operands =
instruction.getlocal_3.shortDescription = Get local register 3
instruction.getlocal_3.description =
instruction.getlocal_3.stackBefore =
instruction.getlocal_3.stackAfter = value
instruction.getlocal_3.operands =
instruction.getlocal3.shortDescription = Get local register 3
instruction.getlocal3.description =
instruction.getlocal3.stackBefore =
instruction.getlocal3.stackAfter = value
instruction.getlocal3.operands =
instruction.setlocal_0.shortDescription = Set local register 0
instruction.setlocal_0.description =
instruction.setlocal_0.stackBefore = value
instruction.setlocal_0.stackAfter =
instruction.setlocal_0.operands =
instruction.setlocal0.shortDescription = Set local register 0
instruction.setlocal0.description =
instruction.setlocal0.stackBefore = value
instruction.setlocal0.stackAfter =
instruction.setlocal0.operands =
instruction.setlocal_1.shortDescription = Set local register 1
instruction.setlocal_1.description =
instruction.setlocal_1.stackBefore = value
instruction.setlocal_1.stackAfter =
instruction.setlocal_1.operands =
instruction.setlocal1.shortDescription = Set local register 1
instruction.setlocal1.description =
instruction.setlocal1.stackBefore = value
instruction.setlocal1.stackAfter =
instruction.setlocal1.operands =
instruction.setlocal_2.shortDescription = Set local register 2
instruction.setlocal_2.description =
instruction.setlocal_2.stackBefore = value
instruction.setlocal_2.stackAfter =
instruction.setlocal_2.operands =
instruction.setlocal2.shortDescription = Set local register 2
instruction.setlocal2.description =
instruction.setlocal2.stackBefore = value
instruction.setlocal2.stackAfter =
instruction.setlocal2.operands =
instruction.setlocal_3.shortDescription = Set local register 3
instruction.setlocal_3.description =
instruction.setlocal_3.stackBefore = value
instruction.setlocal_3.stackAfter =
instruction.setlocal_3.operands =
instruction.setlocal3.shortDescription = Set local register 3
instruction.setlocal3.description =
instruction.setlocal3.stackBefore = value
instruction.setlocal3.stackAfter =
instruction.setlocal3.operands =
#Undocumented:
instruction.invalid.shortDescription = Invalid

View File

@@ -601,4 +601,8 @@ public abstract class GraphTargetItem implements Serializable, Cloneable {
return 0;
}
public boolean isIdentical(GraphTargetItem other) {
return this == other;
}
}

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;
import com.jpexs.decompiler.flash.abc.ABC;
@@ -56,7 +57,7 @@ public class ActionScript3AssemblerTest extends ActionScriptTestBase {
}
private int getBaseAddr() {
private int getBaseAddr() {
return 2; //getlocal0 + pushscope
}
private ABC getABC() {
@@ -81,7 +82,7 @@ public class ActionScript3AssemblerTest extends ActionScriptTestBase {
private MethodBody compilePCode(String str) throws IOException, AVM2ParseException, InterruptedException {
str = "code\r\n"
str = "code\r\n"
+ "getlocal0\r\n"
+ "pushscope\r\n"
+ str
+ "returnvoid\r\n";
@@ -101,7 +102,7 @@ public class ActionScript3AssemblerTest extends ActionScriptTestBase {
@Test
public void removeInstruction() throws Exception {
MethodBody b = compilePCode("pushbyte 1\r\n"
MethodBody b = compilePCode("pushbyte 1\r\n"
+ "setlocal1\r\n" //remove this
+ "jump label1\r\n"
+ "pushtrue\r\n"
+ "pop\r\n"
@@ -112,7 +113,7 @@ public class ActionScript3AssemblerTest extends ActionScriptTestBase {
@Test
public void removeInstruction2() throws Exception {
MethodBody b = compilePCode("pushbyte 1\r\n"
MethodBody b = compilePCode("pushbyte 1\r\n"
+ "setlocal1\r\n"
+ "jump label1\r\n"
+ "pushtrue\r\n"
+ "pop\r\n" //remove this
@@ -123,7 +124,7 @@ public class ActionScript3AssemblerTest extends ActionScriptTestBase {
@Test
public void replaceInstruction() throws Exception {
MethodBody b = compilePCode("pushbyte 1\r\n"
MethodBody b = compilePCode("pushbyte 1\r\n"
+ "setlocal1\r\n"
+ "jump label1\r\n" //remove this
+ "jump label1\r\n"
+ "pushtrue\r\n"
@@ -135,7 +136,7 @@ public class ActionScript3AssemblerTest extends ActionScriptTestBase {
@Test
public void replaceInstruction2() throws Exception {
MethodBody b = compilePCode("pushbyte 1\r\n"
MethodBody b = compilePCode("pushbyte 1\r\n"
+ "setlocal1\r\n"
+ "jump label1\r\n"
+ "pushtrue\r\n"
+ "jump label1\r\n" //remove this

View File

@@ -64,7 +64,7 @@ public class ActionScript3DeobfuscatorTest extends ActionScriptTestBase {
private String recompilePCode(String str) throws IOException, AVM2ParseException, InterruptedException {
str = "code\r\n"
+ "getlocal_0\r\n"
+ "getlocal0\r\n"
+ "pushscope\r\n"
+ str
+ "returnvoid\r\n";
@@ -238,7 +238,7 @@ public class ActionScript3DeobfuscatorTest extends ActionScriptTestBase {
+ "a:jump c\r\n"
+ "c:pushbyte 4\r\n"
+ "b:pushbyte 3\r\n");
Assert.assertEquals(res, "getlocal_0\r\n"
Assert.assertEquals(res, "getlocal0\r\n"
+ "pushscope\r\n"
+ "pushbyte 3\r\n"
+ "pushbyte 4\r\n"

View File

@@ -35,7 +35,9 @@ import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
@@ -49,13 +51,13 @@ import org.testng.annotations.Test;
*/
public class ActionScript3Test extends ActionScriptTestBase {
private SWF swf;
private Map<String, SWF> swfMap = new HashMap<>();
@BeforeClass
public void init() throws IOException, InterruptedException {
//Main.initLogging(false);
swf = new SWF(new BufferedInputStream(new FileInputStream("testdata/flashdevelop/bin/flashdevelop.swf")), false);
swfMap.put("standard", new SWF(new BufferedInputStream(new FileInputStream("testdata/flashdevelop/bin/flashdevelop.swf")), false));
swfMap.put("assembled", new SWF(new BufferedInputStream(new FileInputStream("testdata/custom/bin/custom.swf")), false));
Configuration.autoDeobfuscate.set(false);
Configuration.simplifyExpressions.set(false);
@@ -64,13 +66,14 @@ public class ActionScript3Test extends ActionScriptTestBase {
Configuration.showMethodBodyId.set(false);
}
private void decompileMethod(String methodName, String expectedResult, boolean isStatic) {
private void decompileMethod(String swfIdentifier, String methodName, String expectedResult, boolean isStatic) {
String className = methodName.substring(0, 1).toUpperCase() + methodName.substring(1);
int clsIndex = -1;
int scriptIndex = -1;
ABC abc = null;
SWF swf = swfMap.get(swfIdentifier);
List<ABC> abcs = new ArrayList<>();
for (ABCContainerTag abcTag : swf.getAbcList()) {
abcs.add(abcTag.getABC());
@@ -115,7 +118,7 @@ public class ActionScript3Test extends ActionScriptTestBase {
DoABC2Tag tag = null;
ABC abc = null;
ScriptPack scriptPack = null;
for (Tag t : swf.getTags()) {
for (Tag t : swfMap.get("standard").getTags()) {
if (t instanceof DoABC2Tag) {
tag = (DoABC2Tag) t;
abc = tag.getABC();
@@ -141,13 +144,13 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testArguments() {
decompileMethod("testArguments", "return arguments[0];\r\n",
decompileMethod("standard", "testArguments", "return arguments[0];\r\n",
false);
}
@Test
public void testCatchFinally() {
decompileMethod("testCatchFinally", "var a:* = 5;\r\n"
decompileMethod("standard", "testCatchFinally", "var a:* = 5;\r\n"
+ "try\r\n"
+ "{\r\n"
+ "a = 9;\r\n"
@@ -166,7 +169,7 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testChain2() {
decompileMethod("testChain2", "var g:Array = null;\r\n"
decompileMethod("standard", "testChain2", "var g:Array = null;\r\n"
+ "var h:Boolean = false;\r\n"
+ "var extraLine:Boolean = false;\r\n"
+ "var r:int = 7;\r\n"
@@ -186,7 +189,7 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testChainedAssignments() {
decompileMethod("testChainedAssignments", "var a:int = 0;\r\n"
decompileMethod("standard", "testChainedAssignments", "var a:int = 0;\r\n"
+ "var b:int = 0;\r\n"
+ "var c:int = 0;\r\n"
+ "var d:int = 0;\r\n"
@@ -199,7 +202,7 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testComplexExpressions() {
decompileMethod("testComplexExpressions", "var i:int = 0;\r\n"
decompileMethod("standard", "testComplexExpressions", "var i:int = 0;\r\n"
+ "var j:int = 0;\r\n"
+ "j = i = i + (i = i + i++);\r\n",
false);
@@ -207,7 +210,7 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testContinueLevels() {
decompileMethod("testContinueLevels", "var b:* = undefined;\r\n"
decompileMethod("standard", "testContinueLevels", "var b:* = undefined;\r\n"
+ "var c:* = undefined;\r\n"
+ "var d:* = undefined;\r\n"
+ "var e:* = undefined;\r\n"
@@ -273,7 +276,7 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testDecl2() {
decompileMethod("testDecl2", "var k:int = 0;\r\n"
decompileMethod("standard", "testDecl2", "var k:int = 0;\r\n"
+ "var i:int = 5;\r\n"
+ "i = i + 7;\r\n"
+ "if(i == 5)\r\n"
@@ -289,7 +292,7 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testDeclarations() {
decompileMethod("testDeclarations", "var vall:* = undefined;\r\n"
decompileMethod("standard", "testDeclarations", "var vall:* = undefined;\r\n"
+ "var vstr:String = null;\r\n"
+ "var vint:int = 0;\r\n"
+ "var vuint:uint = 0;\r\n"
@@ -309,7 +312,7 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testDefaultNotLastGrouped() {
decompileMethod("testDefaultNotLastGrouped", "var k:* = 10;\r\n"
decompileMethod("standard", "testDefaultNotLastGrouped", "var k:* = 10;\r\n"
+ "switch(k)\r\n"
+ "{\r\n"
+ "default:\r\n"
@@ -327,7 +330,7 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testDoWhile() {
decompileMethod("testDoWhile", "var a:* = 8;\r\n"
decompileMethod("standard", "testDoWhile", "var a:* = 8;\r\n"
+ "do\r\n"
+ "{\r\n"
+ "trace(\"a=\" + a);\r\n"
@@ -339,7 +342,7 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testDoWhile2() {
decompileMethod("testDoWhile2", "var k:int = 5;\r\n"
decompileMethod("standard", "testDoWhile2", "var k:int = 5;\r\n"
+ "do\r\n"
+ "{\r\n"
+ "k++;\r\n"
@@ -358,9 +361,20 @@ public class ActionScript3Test extends ActionScriptTestBase {
false);
}
@Test
public void testDup() {
decompileMethod("standard", "testDup", "var a:Boolean = false;\r\n"
+ "var b:Boolean = false;\r\n"
+ "if(a = b)\r\n"
+ "{\r\n"
+ "trace(a);\r\n"
+ "}\r\n",
false);
}
@Test
public void testExpressions() {
decompileMethod("testExpressions", "var arr:Array = null;\r\n"
decompileMethod("standard", "testExpressions", "var arr:Array = null;\r\n"
+ "var i:int = 5;\r\n"
+ "var j:int = 5;\r\n"
+ "if((i = i = i / 2) == 1 || i == 2)\r\n"
@@ -381,7 +395,7 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testFinallyZeroJump() {
decompileMethod("testFinallyZeroJump", "var str:String = param1;\r\n"
decompileMethod("standard", "testFinallyZeroJump", "var str:String = param1;\r\n"
+ "try\r\n"
+ "{\r\n"
+ "}\r\n"
@@ -403,7 +417,7 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testFor() {
decompileMethod("testFor", "for(var a:* = 0; a < 10; a++)\r\n"
decompileMethod("standard", "testFor", "for(var a:* = 0; a < 10; a++)\r\n"
+ "{\r\n"
+ "trace(\"a=\" + a);\r\n"
+ "}\r\n",
@@ -412,7 +426,7 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testForAnd() {
decompileMethod("testForAnd", "var x:Boolean = false;\r\n"
decompileMethod("standard", "testForAnd", "var x:Boolean = false;\r\n"
+ "var len:int = 5;\r\n"
+ "var a:int = 4;\r\n"
+ "var b:int = 7;\r\n"
@@ -437,7 +451,7 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testForBreak() {
decompileMethod("testForBreak", "for(var a:* = 0; a < 10; a++)\r\n"
decompileMethod("standard", "testForBreak", "for(var a:* = 0; a < 10; a++)\r\n"
+ "{\r\n"
+ "if(a == 5)\r\n"
+ "{\r\n"
@@ -450,7 +464,7 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testForContinue() {
decompileMethod("testForContinue", "for(var a:* = 0; a < 10; a = a + 1)\r\n"
decompileMethod("standard", "testForContinue", "for(var a:* = 0; a < 10; a = a + 1)\r\n"
+ "{\r\n"
+ "if(a == 9)\r\n"
+ "{\r\n"
@@ -478,7 +492,7 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testForEach() {
decompileMethod("testForEach", "var list:Array = null;\r\n"
decompileMethod("standard", "testForEach", "var list:Array = null;\r\n"
+ "var item:* = undefined;\r\n"
+ "list = new Array();\r\n"
+ "list[0] = \"first\";\r\n"
@@ -493,7 +507,7 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testForEachObjectArray() {
decompileMethod("testForEachObjectArray", "var list:Array = null;\r\n"
decompileMethod("standard", "testForEachObjectArray", "var list:Array = null;\r\n"
+ "var test:Array = null;\r\n"
+ "list = new Array();\r\n"
+ "list[0] = \"first\";\r\n"
@@ -510,7 +524,7 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testForEachObjectAttribute() {
decompileMethod("testForEachObjectAttribute", "var list:Array = null;\r\n"
decompileMethod("standard", "testForEachObjectAttribute", "var list:Array = null;\r\n"
+ "list = new Array();\r\n"
+ "list[0] = \"first\";\r\n"
+ "list[1] = \"second\";\r\n"
@@ -524,7 +538,7 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testForGoto() {
decompileMethod("testForGoto", "var c:int = 0;\r\n"
decompileMethod("standard", "testForGoto", "var c:int = 0;\r\n"
+ "var len:int = 5;\r\n"
+ "for(var i:uint = 0; i < len; i++)\r\n"
+ "{\r\n"
@@ -549,7 +563,7 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testForIn() {
decompileMethod("testForIn", "var dic:Dictionary = null;\r\n"
decompileMethod("standard", "testForIn", "var dic:Dictionary = null;\r\n"
+ "var item:* = null;\r\n"
+ "for(item in dic)\r\n"
+ "{\r\n"
@@ -564,7 +578,7 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testForXml() {
decompileMethod("testForXml", "var c:int = 0;\r\n"
decompileMethod("standard", "testForXml", "var c:int = 0;\r\n"
+ "var name:String = \"ahoj\";\r\n"
+ "var myXML:XML = <order id=\"604\">\r\n"
+ "<book isbn=\"12345\">\r\n"
@@ -597,7 +611,7 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testGotos() {
decompileMethod("testGotos", "var a:Boolean = true;\r\n"
decompileMethod("standard", "testGotos", "var a:Boolean = true;\r\n"
+ "var b:Boolean = false;\r\n"
+ "if(a)\r\n"
+ "{\r\n"
@@ -629,7 +643,7 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testGotos2() {
decompileMethod("testGotos2", "var a:Boolean = true;\r\n"
decompileMethod("standard", "testGotos2", "var a:Boolean = true;\r\n"
+ "var b:Boolean = false;\r\n"
+ "var c:Boolean = true;\r\n"
+ "if(a)\r\n"
@@ -653,7 +667,7 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testGotos3() {
decompileMethod("testGotos3", "var i:int = 0;\r\n"
decompileMethod("standard", "testGotos3", "var i:int = 0;\r\n"
+ "var a:int = 5;\r\n"
+ "if(a > 5)\r\n"
+ "{\r\n"
@@ -680,7 +694,7 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testGotos4() {
decompileMethod("testGotos4", "var a:int = 5;\r\n"
decompileMethod("standard", "testGotos4", "var a:int = 5;\r\n"
+ "if(a > 3)\r\n"
+ "{\r\n"
+ "if(a < 7)\r\n"
@@ -701,7 +715,7 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testGotos5() {
decompileMethod("testGotos5", "var j:int = 0;\r\n"
decompileMethod("standard", "testGotos5", "var j:int = 0;\r\n"
+ "var s:String = \"A\";\r\n"
+ "for(var i:int = 0; i < 10; i++)\r\n"
+ "{\r\n"
@@ -725,7 +739,7 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testGotos6() {
decompileMethod("testGotos6", "var a:Boolean = true;\r\n"
decompileMethod("standard", "testGotos6", "var a:Boolean = true;\r\n"
+ "var s:String = \"a\";\r\n"
+ "if(a)\r\n"
+ "{\r\n"
@@ -750,7 +764,7 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testGotos7() {
decompileMethod("testGotos7", "for(var i:int = 0; i < 10; i++)\r\n"
decompileMethod("standard", "testGotos7", "for(var i:int = 0; i < 10; i++)\r\n"
+ "{\r\n"
+ "switch(i)\r\n"
+ "{\r\n"
@@ -779,13 +793,13 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testHello() {
decompileMethod("testHello", "trace(\"hello\");\r\n",
decompileMethod("standard", "testHello", "trace(\"hello\");\r\n",
false);
}
@Test
public void testIf() {
decompileMethod("testIf", "var a:* = 5;\r\n"
decompileMethod("standard", "testIf", "var a:* = 5;\r\n"
+ "if(a == 7)\r\n"
+ "{\r\n"
+ "trace(\"onTrue\");\r\n"
@@ -795,7 +809,7 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testIfElse() {
decompileMethod("testIfElse", "var a:* = 5;\r\n"
decompileMethod("standard", "testIfElse", "var a:* = 5;\r\n"
+ "if(a == 7)\r\n"
+ "{\r\n"
+ "trace(\"onTrue\");\r\n"
@@ -809,7 +823,7 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testIfInIf() {
decompileMethod("testIfInIf", "var k:int = 5;\r\n"
decompileMethod("standard", "testIfInIf", "var k:int = 5;\r\n"
+ "if(k > 5 && k < 20)\r\n"
+ "{\r\n"
+ "trace(\"A\");\r\n"
@@ -833,7 +847,7 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testInc2() {
decompileMethod("testInc2", "var a:* = [1];\r\n"
decompileMethod("standard", "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"
@@ -846,7 +860,7 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testIncDec() {
decompileMethod("testIncDec", "var a:* = 5;\r\n"
decompileMethod("standard", "testIncDec", "var a:* = 5;\r\n"
+ "var b:* = 0;\r\n"
+ "trace(\"++var\");\r\n"
+ "b = ++a;\r\n"
@@ -885,7 +899,7 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testInlineFunctions() {
decompileMethod("testInlineFunctions", "var first:String = null;\r\n"
decompileMethod("standard", "testInlineFunctions", "var first:String = null;\r\n"
+ "first = \"value1\";\r\n"
+ "var traceParameter:Function = function(aParam:String):String\r\n"
+ "{\r\n"
@@ -907,7 +921,7 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testInnerFunctions() {
decompileMethod("testInnerFunctions", "var s:int = 0;\r\n"
decompileMethod("standard", "testInnerFunctions", "var s:int = 0;\r\n"
+ "var innerFunc:Function = function(b:String):*\r\n"
+ "{\r\n"
+ "trace(b);\r\n"
@@ -923,7 +937,7 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testInnerIf() {
decompileMethod("testInnerIf", "var a:* = 5;\r\n"
decompileMethod("standard", "testInnerIf", "var a:* = 5;\r\n"
+ "var b:* = 4;\r\n"
+ "if(a == 5)\r\n"
+ "{\r\n"
@@ -950,7 +964,7 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testInnerTry() {
decompileMethod("testInnerTry", "try\r\n"
decompileMethod("standard", "testInnerTry", "try\r\n"
+ "{\r\n"
+ "try\r\n"
+ "{\r\n"
@@ -975,7 +989,7 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testLogicalComputing() {
decompileMethod("testLogicalComputing", "var b:Boolean = false;\r\n"
decompileMethod("standard", "testLogicalComputing", "var b:Boolean = false;\r\n"
+ "var i:* = 5;\r\n"
+ "var j:* = 7;\r\n"
+ "if(i > j)\r\n"
@@ -989,14 +1003,14 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testManualConvert() {
decompileMethod("testManualConvert", "trace(\"String(this).length\");\r\n"
decompileMethod("standard", "testManualConvert", "trace(\"String(this).length\");\r\n"
+ "trace(String(this).length);\r\n",
false);
}
@Test
public void testMissingDefault() {
decompileMethod("testMissingDefault", "var jj:int = 1;\r\n"
decompileMethod("standard", "testMissingDefault", "var jj:int = 1;\r\n"
+ "switch(jj)\r\n"
+ "{\r\n"
+ "case 1:\r\n"
@@ -1013,7 +1027,7 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testMultipleCondition() {
decompileMethod("testMultipleCondition", "var a:* = 5;\r\n"
decompileMethod("standard", "testMultipleCondition", "var a:* = 5;\r\n"
+ "var b:* = 8;\r\n"
+ "var c:* = 9;\r\n"
+ "if((a <= 4 || b <= 8) && c == 7)\r\n"
@@ -1029,7 +1043,7 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testNamedAnonFunctions() {
decompileMethod("testNamedAnonFunctions", "var test:* = new function testFunc(param1:*, param2:int, param3:Array):Boolean\r\n"
decompileMethod("standard", "testNamedAnonFunctions", "var test:* = new function testFunc(param1:*, param2:int, param3:Array):Boolean\r\n"
+ "{\r\n"
+ "return (param1 as TestClass2).attrib1 == 5;\r\n"
+ "};\r\n",
@@ -1038,7 +1052,7 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testNames() {
decompileMethod("testNames", "var ns:* = this.getNamespace();\r\n"
decompileMethod("standard", "testNames", "var ns:* = this.getNamespace();\r\n"
+ "var name:* = this.getName();\r\n"
+ "var a:* = ns::unnamespacedFunc();\r\n"
+ "var b:* = ns::[name];\r\n"
@@ -1049,19 +1063,19 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testParamNames() {
decompileMethod("testParamNames", "return firstp + secondp + thirdp;\r\n",
decompileMethod("standard", "testParamNames", "return firstp + secondp + thirdp;\r\n",
false);
}
@Test
public void testParamsCount() {
decompileMethod("testParamsCount", "return firstp;\r\n",
decompileMethod("standard", "testParamsCount", "return firstp;\r\n",
false);
}
@Test
public void testPrecedence() {
decompileMethod("testPrecedence", "var a:* = 0;\r\n"
decompileMethod("standard", "testPrecedence", "var a:* = 0;\r\n"
+ "a = (5 + 6) * 7;\r\n"
+ "a = 5 * (2 + 3);\r\n"
+ "a = 5 + 6 * 7;\r\n"
@@ -1078,7 +1092,7 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testPrecedenceX() {
decompileMethod("testPrecedenceX", "var a:* = 5;\r\n"
decompileMethod("standard", "testPrecedenceX", "var a:* = 5;\r\n"
+ "var b:* = 2;\r\n"
+ "var c:* = 3;\r\n"
+ "var d:* = a << (b >>> c);\r\n"
@@ -1088,7 +1102,7 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testProperty() {
decompileMethod("testProperty", "var d:* = new TestClass1();\r\n"
decompileMethod("standard", "testProperty", "var d:* = new TestClass1();\r\n"
+ "var k:* = 7 + 8;\r\n"
+ "if(k == 15)\r\n"
+ "{\r\n"
@@ -1099,7 +1113,7 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testRegExp() {
decompileMethod("testRegExp", "var a1:* = /[a-z\\r\\n0-9\\\\]+/i;\r\n"
decompileMethod("standard", "testRegExp", "var a1:* = /[a-z\\r\\n0-9\\\\]+/i;\r\n"
+ "var a2:* = /[a-z\\r\\n0-9\\\\]+/i;\r\n"
+ "var b1:* = /[0-9AB]+/;\r\n"
+ "var b2:* = /[0-9AB]+/;\r\n",
@@ -1108,14 +1122,14 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testRest() {
decompileMethod("testRest", "trace(\"firstRest:\" + restval[0]);\r\n"
decompileMethod("standard", "testRest", "trace(\"firstRest:\" + restval[0]);\r\n"
+ "return firstp;\r\n",
false);
}
@Test
public void testStrictEquals() {
decompileMethod("testStrictEquals", "var k:int = 6;\r\n"
decompileMethod("standard", "testStrictEquals", "var k:int = 6;\r\n"
+ "if(this.f() !== this.f())\r\n"
+ "{\r\n"
+ "trace(\"is eight\");\r\n"
@@ -1125,7 +1139,7 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testStringConcat() {
decompileMethod("testStringConcat", "var k:int = 8;\r\n"
decompileMethod("standard", "testStringConcat", "var k:int = 8;\r\n"
+ "this.traceIt(\"hello\" + 5 * 6);\r\n"
+ "this.traceIt(\"hello\" + (k - 1));\r\n"
+ "this.traceIt(\"hello\" + 5 + 6);\r\n",
@@ -1134,7 +1148,7 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testStrings() {
decompileMethod("testStrings", "trace(\"hello\");\r\n"
decompileMethod("standard", "testStrings", "trace(\"hello\");\r\n"
+ "trace(\"quotes:\\\"hello!\\\"\");\r\n"
+ "trace(\"backslash: \\\\ \");\r\n"
+ "trace(\"single quotes: \\'hello!\\'\");\r\n"
@@ -1144,7 +1158,7 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testSwitch() {
decompileMethod("testSwitch", "var a:* = 5;\r\n"
decompileMethod("standard", "testSwitch", "var a:* = 5;\r\n"
+ "switch(a)\r\n"
+ "{\r\n"
+ "case 57 * a:\r\n"
@@ -1163,7 +1177,7 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testSwitchComma() {
decompileMethod("testSwitchComma", "var b:int = 5;\r\n"
decompileMethod("standard", "testSwitchComma", "var b:int = 5;\r\n"
+ "var a:String = \"A\";\r\n"
+ "switch(a)\r\n"
+ "{\r\n"
@@ -1180,7 +1194,7 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testSwitchDefault() {
decompileMethod("testSwitchDefault", "var a:* = 5;\r\n"
decompileMethod("standard", "testSwitchDefault", "var a:* = 5;\r\n"
+ "switch(a)\r\n"
+ "{\r\n"
+ "case 57 * a:\r\n"
@@ -1202,7 +1216,7 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testTernarOperator() {
decompileMethod("testTernarOperator", "var a:* = 5;\r\n"
decompileMethod("standard", "testTernarOperator", "var a:* = 5;\r\n"
+ "var b:* = 4;\r\n"
+ "var c:* = 4;\r\n"
+ "var d:* = 78;\r\n"
@@ -1213,7 +1227,7 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testTry() {
decompileMethod("testTry", "var i:int = 0;\r\n"
decompileMethod("standard", "testTry", "var i:int = 0;\r\n"
+ "i = 7;\r\n"
+ "try\r\n"
+ "{\r\n"
@@ -1238,7 +1252,7 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testTryReturn() {
decompileMethod("testTryReturn", "var i:int = 0;\r\n"
decompileMethod("standard", "testTryReturn", "var i:int = 0;\r\n"
+ "var b:Boolean = false;\r\n"
+ "try\r\n"
+ "{\r\n"
@@ -1266,7 +1280,7 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testTryReturn2() {
decompileMethod("testTryReturn2", "var c:Boolean = false;\r\n"
decompileMethod("standard", "testTryReturn2", "var c:Boolean = false;\r\n"
+ "trace(\"before\");\r\n"
+ "var a:Boolean = true;\r\n"
+ "var b:Boolean = false;\r\n"
@@ -1309,7 +1323,7 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testUsagesTry() {
decompileMethod("testUsagesTry", "var k:int = 5;\r\n"
decompileMethod("standard", "testUsagesTry", "var k:int = 5;\r\n"
+ "switch(k)\r\n"
+ "{\r\n"
+ "case 0:\r\n"
@@ -1343,7 +1357,7 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testVector() {
decompileMethod("testVector", "var v:Vector.<String> = new Vector.<String>();\r\n"
decompileMethod("standard", "testVector", "var v:Vector.<String> = new Vector.<String>();\r\n"
+ "v.push(\"hello\");\r\n"
+ "v[0] = \"hi\";\r\n"
+ "v[5 * 8 - 39] = \"hi2\";\r\n"
@@ -1353,14 +1367,14 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testVector2() {
decompileMethod("testVector2", "var a:Vector.<Vector.<int>> = new Vector.<Vector.<int>>();\r\n"
decompileMethod("standard", "testVector2", "var a:Vector.<Vector.<int>> = new Vector.<Vector.<int>>();\r\n"
+ "var b:Vector.<int> = new <int>[10,20,30];\r\n",
false);
}
@Test
public void testWhileAnd() {
decompileMethod("testWhileAnd", "var a:int = 5;\r\n"
decompileMethod("standard", "testWhileAnd", "var a:int = 5;\r\n"
+ "var b:int = 10;\r\n"
+ "while(a < 10 && b > 1)\r\n"
+ "{\r\n"
@@ -1374,7 +1388,7 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testWhileContinue() {
decompileMethod("testWhileContinue", "var a:* = 5;\r\n"
decompileMethod("standard", "testWhileContinue", "var a:* = 5;\r\n"
+ "while(true)\r\n"
+ "{\r\n"
+ "if(a == 9)\r\n"
@@ -1396,7 +1410,7 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testWhileTry() {
decompileMethod("testWhileTry", "while(true)\r\n"
decompileMethod("standard", "testWhileTry", "while(true)\r\n"
+ "{\r\n"
+ "try\r\n"
+ "{\r\n"
@@ -1419,7 +1433,7 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testWhileTry2() {
decompileMethod("testWhileTry2", "var j:* = undefined;\r\n"
decompileMethod("standard", "testWhileTry2", "var j:* = undefined;\r\n"
+ "for(var i:* = 0; i < 100; i++)\r\n"
+ "{\r\n"
+ "try\r\n"
@@ -1445,7 +1459,7 @@ public class ActionScript3Test extends ActionScriptTestBase {
@Test
public void testXml() {
decompileMethod("testXml", "var g:XML = null;\r\n"
decompileMethod("standard", "testXml", "var g:XML = null;\r\n"
+ "var name:String = \"ahoj\";\r\n"
+ "var myXML:XML = <order id=\"604\">\r\n"
+ "<book isbn=\"12345\">\r\n"
@@ -1559,6 +1573,24 @@ public class ActionScript3Test extends ActionScriptTestBase {
false);
}
@Test
public void testDupAssignment() {
decompileMethod("assembled", "testDupAssignment", "var _loc1_:int = 0;\r\n"
+ "var _loc2_:int = 10;\r\n"
+ "if(_loc1_ = _loc2_)\r\n"
+ "{\r\n"
+ "trace(_loc2_);\r\n"
+ "}\r\n",
false);
}
@Test
public void testIncrement() {
decompileMethod("assembled", "testIncrement", "super();\r\n"
+ "b = a++;\r\n",
false);
}
@Test
public void testOptionalParameters() {
String methodName = "testOptionalParameters";
@@ -1567,7 +1599,7 @@ public class ActionScript3Test extends ActionScriptTestBase {
int clsIndex = -1;
DoABC2Tag tag = null;
ABC abc = null;
for (Tag t : swf.getTags()) {
for (Tag t : swfMap.get("standard").getTags()) {
if (t instanceof DoABC2Tag) {
tag = (DoABC2Tag) t;
abc = tag.getABC();

View File

@@ -33,7 +33,10 @@ import com.jpexs.decompiler.flash.tags.DoABC2Tag;
import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.decompiler.graph.ScopeStack;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
@@ -48,13 +51,10 @@ import java.util.TreeMap;
*/
public class AS3Generator {
public static void main(String[] args) throws Exception {
Configuration.autoDeobfuscate.set(false);
SWF swf = new SWF(new BufferedInputStream(new FileInputStream("testdata/flashdevelop/bin/flashdevelop.swf")), false);
private static void useFile(StringBuilder s, File f, String identifier) throws FileNotFoundException, IOException, InterruptedException {
SWF swf = new SWF(new BufferedInputStream(new FileInputStream(f)), false);
DoABC2Tag tag = null;
List<ScriptPack> scriptPacks = swf.getAS3Packs();
StringBuilder s = new StringBuilder();
Map<String, ScriptPack> sortedPacks = new TreeMap<>();
for (ScriptPack pack : scriptPacks) {
sortedPacks.put(pack.getClassPath().toRawString(), pack);
@@ -72,10 +72,15 @@ public class AS3Generator {
String name = t.getName(abc).getName(abc.constants, null, true, true);
String clsName = pack.getClassPath().className;
String lower = clsName.substring(0, 1).toLowerCase() + clsName.substring(1);
if (lower.equals("testOptionalParameters")) { //SPECIAL: ignored
continue;
}
if (name.equals("run")) {
s.append("@Test\r\npublic void ");
s.append(lower);
s.append("(){\r\ndecompileMethod(\"");
s.append(identifier);
s.append("\",\"");
s.append(lower);
s.append("\", ");
HighlightedTextWriter src = new HighlightedTextWriter(new CodeFormatting(), false);
@@ -102,6 +107,16 @@ public class AS3Generator {
}
}
}
}
public static void main(String[] args) throws Exception {
Configuration.autoDeobfuscate.set(false);
StringBuilder s = new StringBuilder();
useFile(s, new File("testdata/flashdevelop/bin/flashdevelop.swf"), "standard");
useFile(s, new File("testdata/custom/bin/custom.swf"), "assembled");
try (PrintWriter pw = new PrintWriter("as3_teststub.java")) {
pw.println(s.toString());

Binary file not shown.

View File

@@ -0,0 +1,87 @@
class
refid "Main"
instance QName(PackageNamespace(""), "Main")
extends QName(PackageNamespace("flash.display"), "Sprite")
flag SEALED
flag PROTECTEDNS
protectedns ProtectedNamespace("Main")
iinit
refid "Main/instance/init"
body
maxstack 3
localcount 1
initscopedepth 9
maxscopedepth 10
code
getlocal0
pushscope
getlocal0
constructsuper 0
getlex Multiname("stage", [PrivateNamespace(null, "Main/instance"), PrivateNamespace(null, "Main"), PackageNamespace(""), PackageInternalNs(""), Namespace("http://adobe.com/AS3/2006/builtin"), PackageNamespace("tests"), ProtectedNamespace("Main"), StaticProtectedNs("Main"), StaticProtectedNs("flash.display:Sprite"), StaticProtectedNs("flash.display:DisplayObjectContainer"), StaticProtectedNs("flash.display:InteractiveObject"), StaticProtectedNs("flash.display:DisplayObject"), StaticProtectedNs("flash.events:EventDispatcher")])
iffalse L9
getlocal0
callpropvoid Multiname("init", [PrivateNamespace(null, "Main/instance"), PrivateNamespace(null, "Main"), PackageNamespace(""), PackageInternalNs(""), Namespace("http://adobe.com/AS3/2006/builtin"), PackageNamespace("tests"), ProtectedNamespace("Main"), StaticProtectedNs("Main"), StaticProtectedNs("flash.display:Sprite"), StaticProtectedNs("flash.display:DisplayObjectContainer"), StaticProtectedNs("flash.display:InteractiveObject"), StaticProtectedNs("flash.display:DisplayObject"), StaticProtectedNs("flash.events:EventDispatcher")]), 0
jump L15
L9:
findpropstrict Multiname("addEventListener", [PrivateNamespace(null, "Main/instance"), PrivateNamespace(null, "Main"), PackageNamespace(""), PackageInternalNs(""), Namespace("http://adobe.com/AS3/2006/builtin"), PackageNamespace("tests"), ProtectedNamespace("Main"), StaticProtectedNs("Main"), StaticProtectedNs("flash.display:Sprite"), StaticProtectedNs("flash.display:DisplayObjectContainer"), StaticProtectedNs("flash.display:InteractiveObject"), StaticProtectedNs("flash.display:DisplayObject"), StaticProtectedNs("flash.events:EventDispatcher")])
getlex Multiname("Event", [PrivateNamespace(null, "Main/instance"), PrivateNamespace(null, "Main"), PackageNamespace(""), PackageInternalNs(""), Namespace("http://adobe.com/AS3/2006/builtin"), PackageNamespace("tests"), ProtectedNamespace("Main"), StaticProtectedNs("Main"), StaticProtectedNs("flash.display:Sprite"), StaticProtectedNs("flash.display:DisplayObjectContainer"), StaticProtectedNs("flash.display:InteractiveObject"), StaticProtectedNs("flash.display:DisplayObject"), StaticProtectedNs("flash.events:EventDispatcher"), PackageNamespace("flash.events")])
getproperty Multiname("ADDED_TO_STAGE", [PrivateNamespace(null, "Main/instance"), PrivateNamespace(null, "Main"), PackageNamespace(""), PackageInternalNs(""), Namespace("http://adobe.com/AS3/2006/builtin"), PackageNamespace("tests"), ProtectedNamespace("Main"), StaticProtectedNs("Main"), StaticProtectedNs("flash.display:Sprite"), StaticProtectedNs("flash.display:DisplayObjectContainer"), StaticProtectedNs("flash.display:InteractiveObject"), StaticProtectedNs("flash.display:DisplayObject"), StaticProtectedNs("flash.events:EventDispatcher")])
getlocal0
getproperty Multiname("init", [PrivateNamespace(null, "Main/instance"), PrivateNamespace(null, "Main"), PackageNamespace(""), PackageInternalNs(""), Namespace("http://adobe.com/AS3/2006/builtin"), PackageNamespace("tests"), ProtectedNamespace("Main"), StaticProtectedNs("Main"), StaticProtectedNs("flash.display:Sprite"), StaticProtectedNs("flash.display:DisplayObjectContainer"), StaticProtectedNs("flash.display:InteractiveObject"), StaticProtectedNs("flash.display:DisplayObject"), StaticProtectedNs("flash.events:EventDispatcher")])
callpropvoid Multiname("addEventListener", [PrivateNamespace(null, "Main/instance"), PrivateNamespace(null, "Main"), PackageNamespace(""), PackageInternalNs(""), Namespace("http://adobe.com/AS3/2006/builtin"), PackageNamespace("tests"), ProtectedNamespace("Main"), StaticProtectedNs("Main"), StaticProtectedNs("flash.display:Sprite"), StaticProtectedNs("flash.display:DisplayObjectContainer"), StaticProtectedNs("flash.display:InteractiveObject"), StaticProtectedNs("flash.display:DisplayObject"), StaticProtectedNs("flash.events:EventDispatcher")]), 2
L15:
returnvoid
end ; code
end ; body
end ; method
trait method QName(PrivateNamespace(null, "Main/instance"), "init")
method
refid "Main/instance/Main/instance/init"
param QName(PackageNamespace("flash.events"), "Event")
returns QName(PackageNamespace(""), "void")
flag HAS_OPTIONAL
optional Null()
body
maxstack 3
localcount 2
initscopedepth 9
maxscopedepth 10
code
getlocal0
pushscope
findpropstrict Multiname("removeEventListener", [PrivateNamespace(null, "Main/instance"), PrivateNamespace(null, "Main"), PackageNamespace(""), PackageInternalNs(""), Namespace("http://adobe.com/AS3/2006/builtin"), PackageNamespace("tests"), ProtectedNamespace("Main"), StaticProtectedNs("Main"), StaticProtectedNs("flash.display:Sprite"), StaticProtectedNs("flash.display:DisplayObjectContainer"), StaticProtectedNs("flash.display:InteractiveObject"), StaticProtectedNs("flash.display:DisplayObject"), StaticProtectedNs("flash.events:EventDispatcher")])
getlex Multiname("Event", [PrivateNamespace(null, "Main/instance"), PrivateNamespace(null, "Main"), PackageNamespace(""), PackageInternalNs(""), Namespace("http://adobe.com/AS3/2006/builtin"), PackageNamespace("tests"), ProtectedNamespace("Main"), StaticProtectedNs("Main"), StaticProtectedNs("flash.display:Sprite"), StaticProtectedNs("flash.display:DisplayObjectContainer"), StaticProtectedNs("flash.display:InteractiveObject"), StaticProtectedNs("flash.display:DisplayObject"), StaticProtectedNs("flash.events:EventDispatcher"), PackageNamespace("flash.events")])
getproperty Multiname("ADDED_TO_STAGE", [PrivateNamespace(null, "Main/instance"), PrivateNamespace(null, "Main"), PackageNamespace(""), PackageInternalNs(""), Namespace("http://adobe.com/AS3/2006/builtin"), PackageNamespace("tests"), ProtectedNamespace("Main"), StaticProtectedNs("Main"), StaticProtectedNs("flash.display:Sprite"), StaticProtectedNs("flash.display:DisplayObjectContainer"), StaticProtectedNs("flash.display:InteractiveObject"), StaticProtectedNs("flash.display:DisplayObject"), StaticProtectedNs("flash.events:EventDispatcher")])
getlocal0
getproperty Multiname("init", [PrivateNamespace(null, "Main/instance"), PrivateNamespace(null, "Main"), PackageNamespace(""), PackageInternalNs(""), Namespace("http://adobe.com/AS3/2006/builtin"), PackageNamespace("tests"), ProtectedNamespace("Main"), StaticProtectedNs("Main"), StaticProtectedNs("flash.display:Sprite"), StaticProtectedNs("flash.display:DisplayObjectContainer"), StaticProtectedNs("flash.display:InteractiveObject"), StaticProtectedNs("flash.display:DisplayObject"), StaticProtectedNs("flash.events:EventDispatcher")])
callpropvoid Multiname("removeEventListener", [PrivateNamespace(null, "Main/instance"), PrivateNamespace(null, "Main"), PackageNamespace(""), PackageInternalNs(""), Namespace("http://adobe.com/AS3/2006/builtin"), PackageNamespace("tests"), ProtectedNamespace("Main"), StaticProtectedNs("Main"), StaticProtectedNs("flash.display:Sprite"), StaticProtectedNs("flash.display:DisplayObjectContainer"), StaticProtectedNs("flash.display:InteractiveObject"), StaticProtectedNs("flash.display:DisplayObject"), StaticProtectedNs("flash.events:EventDispatcher")]), 2
returnvoid
end ; code
end ; body
end ; method
end ; trait
end ; instance
cinit
refid "Main/class/init"
body
maxstack 1
localcount 1
initscopedepth 8
maxscopedepth 9
code
getlocal0
pushscope
returnvoid
end ; code
end ; body
end ; method
end ; class

View File

@@ -0,0 +1,49 @@
script
sinit
refid "Main/init"
body
maxstack 2
localcount 1
initscopedepth 1
maxscopedepth 8
code
getlocal0
pushscope
getscopeobject 0
getlex QName(PackageNamespace(""), "Object")
pushscope
getlex QName(PackageNamespace("flash.events"), "EventDispatcher")
pushscope
getlex QName(PackageNamespace("flash.display"), "DisplayObject")
pushscope
getlex QName(PackageNamespace("flash.display"), "InteractiveObject")
pushscope
getlex QName(PackageNamespace("flash.display"), "DisplayObjectContainer")
pushscope
getlex QName(PackageNamespace("flash.display"), "Sprite")
pushscope
getlex Multiname("Sprite", [PrivateNamespace(null, "Main"), PackageNamespace(""), PackageInternalNs(""), Namespace("http://adobe.com/AS3/2006/builtin"), PackageNamespace("tests"), PackageNamespace("flash.display")])
newclass "Main"
popscope
popscope
popscope
popscope
popscope
popscope
initproperty QName(PackageNamespace(""), "Main")
returnvoid
end ; code
end ; body
end ; method
trait class QName(PackageNamespace(""), "Main") slotid 1
#include "Main.class.asasm"
end ; trait
end ; script

Binary file not shown.

View File

@@ -0,0 +1,10 @@
#version 4
program
minorversion 16
majorversion 46
#include "Main.script.asasm"
#include "tests/TestDupAssignment.script.asasm"
#include "tests/TestIncrement.script.asasm"
end ; program

View File

@@ -0,0 +1,77 @@
class
refid "tests:TestDupAssignment"
instance QName(PackageNamespace("tests"), "TestDupAssignment")
extends QName(PackageNamespace(""), "Object")
flag SEALED
flag PROTECTEDNS
protectedns ProtectedNamespace("tests:TestDupAssignment")
iinit
refid "tests:TestDupAssignment/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:TestDupAssignment/instance/run"
returns QName(PackageNamespace(""), "void")
body
maxstack 2
localcount 4
initscopedepth 4
maxscopedepth 5
code
getlocal0
pushscope
pushbyte 0
setlocal1
pushbyte 10
setlocal2
getlocal2
dup
convert_i
setlocal1
iffalse L15
findpropstrict Multiname("trace", [PrivateNamespace(null, "tests:TestDupAssignment/instance/run"), PrivateNamespace(null, "tests:TestDupAssignment"), PackageNamespace(""), PackageNamespace("tests"), PackageInternalNs("tests"), Namespace("http://adobe.com/AS3/2006/builtin"), ProtectedNamespace("tests:TestDupAssignment"), StaticProtectedNs("tests:TestDupAssignment")])
getlocal2
callpropvoid Multiname("trace", [PrivateNamespace(null, "tests:TestDupAssignment/instance/run"), PrivateNamespace(null, "tests:TestDupAssignment"), PackageNamespace(""), PackageNamespace("tests"), PackageInternalNs("tests"), Namespace("http://adobe.com/AS3/2006/builtin"), ProtectedNamespace("tests:TestDupAssignment"), StaticProtectedNs("tests:TestDupAssignment")]), 1
L15:
returnvoid
end ; code
end ; body
end ; method
end ; trait
end ; instance
cinit
refid "tests:TestDupAssignment/class/init"
body
maxstack 1
localcount 1
initscopedepth 3
maxscopedepth 4
code
getlocal0
pushscope
returnvoid
end ; code
end ; body
end ; method
end ; class

View File

@@ -0,0 +1,29 @@
script
sinit
refid "tests:TestDupAssignment/init"
body
maxstack 2
localcount 1
initscopedepth 1
maxscopedepth 3
code
getlocal0
pushscope
findpropstrict Multiname("TestDupAssignment", [PackageNamespace("tests")])
getlex QName(PackageNamespace(""), "Object")
pushscope
getlex Multiname("Object", [PrivateNamespace(null, "tests:TestDupAssignment"), PackageNamespace(""), PackageNamespace("tests"), PackageInternalNs("tests"), Namespace("http://adobe.com/AS3/2006/builtin")])
newclass "tests:TestDupAssignment"
popscope
initproperty QName(PackageNamespace("tests"), "TestDupAssignment")
returnvoid
end ; code
end ; body
end ; method
trait class QName(PackageNamespace("tests"), "TestDupAssignment")
#include "TestDupAssignment.class.asasm"
end ; trait
end ; script

View File

@@ -0,0 +1,71 @@
class
refid "tests:TestIncrement"
instance QName(PackageNamespace("tests"), "TestIncrement")
extends QName(PackageNamespace(""), "Object")
flag SEALED
flag PROTECTEDNS
protectedns ProtectedNamespace("tests:TestIncrement")
iinit
refid "tests:TestIncrement/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:TestIncrement/instance/run"
returns QName(PackageNamespace(""), "void")
body
maxstack 2
localcount 4
initscopedepth 4
maxscopedepth 5
code
getlocal0
pushscope
getlocal0
constructsuper 0
getlex QName(PrivateNamespace("myns"),"a")
convert_d
dup
increment
findpropstrict QName(PrivateNamespace("myns"),"a")
swap
setproperty QName(PrivateNamespace("myns"),"a")
findproperty QName(PackageNamespace(""),"b")
swap
setproperty QName(PackageNamespace(""),"b")
returnvoid
end ; code
end ; body
end ; method
end ; trait
end ; instance
cinit
refid "tests:TestIncrement/class/init"
body
maxstack 1
localcount 1
initscopedepth 3
maxscopedepth 4
code
getlocal0
pushscope
returnvoid
end ; code
end ; body
end ; method
end ; class

View File

@@ -0,0 +1,29 @@
script
sinit
refid "tests:TestIncrement/init"
body
maxstack 2
localcount 1
initscopedepth 1
maxscopedepth 3
code
getlocal0
pushscope
findpropstrict Multiname("TestIncrement", [PackageNamespace("tests")])
getlex QName(PackageNamespace(""), "Object")
pushscope
getlex Multiname("Object", [PrivateNamespace(null, "tests:TestIncrement"), PackageNamespace(""), PackageNamespace("tests"), PackageInternalNs("tests"), Namespace("http://adobe.com/AS3/2006/builtin")])
newclass "tests:TestIncrement"
popscope
initproperty QName(PackageNamespace("tests"), "TestIncrement")
returnvoid
end ; code
end ; body
end ; method
trait class QName(PackageNamespace("tests"), "TestIncrement")
#include "TestIncrement.class.asasm"
end ; trait
end ; script

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,40 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<title>Custom</title>
<meta name="description" content="" />
<script src="js/swfobject.js"></script>
<script>
var flashvars = {
};
var params = {
menu: "false",
scale: "noScale",
allowFullscreen: "true",
allowScriptAccess: "always",
bgcolor: "",
wmode: "direct" // can cause issues with FP settings & webcam
};
var attributes = {
id:"Custom"
};
swfobject.embedSWF(
"Custom.swf",
"altContent", "100%", "100%", "10.0.0",
"expressInstall.swf",
flashvars, params, attributes);
</script>
<style>
html, body { height:100%; overflow:hidden; }
body { margin:0; }
</style>
</head>
<body>
<div id="altContent">
<h1>Custom</h1>
<p><a href="http://www.adobe.com/go/getflashplayer">Get Adobe Flash player</a></p>
</div>
</body>
</html>

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,93 @@
<?xml version="1.0" encoding="utf-8"?>
<project version="2">
<!-- Output SWF options -->
<output>
<movie outputType="Application" />
<movie input="" />
<movie path="bin\custom.swf" />
<movie fps="30" />
<movie width="800" />
<movie height="600" />
<movie version="25" />
<movie minorVersion="0" />
<movie platform="Flash Player" />
<movie background="#FFFFFF" />
</output>
<!-- Other classes to be compiled into your SWF -->
<classpaths>
<class path="src" />
</classpaths>
<!-- Build options -->
<build>
<option accessible="False" />
<option advancedTelemetry="False" />
<option allowSourcePathOverlap="False" />
<option benchmark="False" />
<option es="False" />
<option inline="False" />
<option locale="" />
<option loadConfig="" />
<option optimize="False" />
<option omitTraces="False" />
<option showActionScriptWarnings="True" />
<option showBindingWarnings="True" />
<option showInvalidCSS="True" />
<option showDeprecationWarnings="True" />
<option showUnusedTypeSelectorWarnings="True" />
<option strict="False" />
<option useNetwork="True" />
<option useResourceBundleMetadata="True" />
<option warnings="True" />
<option verboseStackTraces="False" />
<option linkReport="" />
<option loadExterns="" />
<option staticLinkRSL="True" />
<option additional="" />
<option compilerConstants="" />
<option minorVersion="" />
</build>
<!-- SWC Include Libraries -->
<includeLibraries>
<!-- example: <element path="..." /> -->
</includeLibraries>
<!-- SWC Libraries -->
<libraryPaths>
<!-- example: <element path="..." /> -->
</libraryPaths>
<!-- External Libraries -->
<externalLibraryPaths>
<!-- example: <element path="..." /> -->
</externalLibraryPaths>
<!-- Runtime Shared Libraries -->
<rslPaths>
<!-- example: <element path="..." /> -->
</rslPaths>
<!-- Intrinsic Libraries -->
<intrinsics>
<!-- example: <element path="..." /> -->
</intrinsics>
<!-- Assets to embed into the output SWF -->
<library>
<!-- example: <asset path="..." id="..." update="..." glyphs="..." mode="..." place="..." sharepoint="..." /> -->
</library>
<!-- Class files to compile (other referenced classes will automatically be included) -->
<compileTargets>
<compile path="src\Main.as" />
</compileTargets>
<!-- Paths to exclude from the Project Explorer tree -->
<hiddenPaths>
<hidden path="obj" />
</hiddenPaths>
<!-- Executed before build -->
<preBuildCommand />
<!-- Executed after build -->
<postBuildCommand alwaysRun="False" />
<!-- Other project options -->
<options>
<option showHiddenPaths="False" />
<option testMovie="Default" />
<option testMovieCommand="" />
</options>
<!-- Plugin storage -->
<storage />
</project>

View File

@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="utf-8"?>
<!--This Adobe Flex compiler configuration file was generated by a tool.-->
<!--Any modifications you make may be lost.-->
<flex-config>
<target-player>25.0</target-player>
<benchmark>false</benchmark>
<static-link-runtime-shared-libraries>true</static-link-runtime-shared-libraries>
<compiler>
<define append="true">
<name>CONFIG::debug</name>
<value>false</value>
</define>
<define append="true">
<name>CONFIG::release</name>
<value>true</value>
</define>
<define append="true">
<name>CONFIG::timeStamp</name>
<value>'26.01.2021'</value>
</define>
<define append="true">
<name>CONFIG::air</name>
<value>false</value>
</define>
<define append="true">
<name>CONFIG::mobile</name>
<value>false</value>
</define>
<define append="true">
<name>CONFIG::desktop</name>
<value>false</value>
</define>
<strict>false</strict>
<omit-trace-statements>true</omit-trace-statements>
<verbose-stacktraces>false</verbose-stacktraces>
<source-path append="true">
<path-element>C:\Dropbox\Programovani\JavaSE\FFDec\libsrc\ffdec_lib\testdata\custom\src</path-element>
<path-element>C:\Program Files (x86)\FlashDevelop\Library\AS3\classes</path-element>
</source-path>
</compiler>
<file-specs>
<path-element>C:\Dropbox\Programovani\JavaSE\FFDec\libsrc\ffdec_lib\testdata\custom\src\Main.as</path-element>
</file-specs>
<default-background-color>#FFFFFF</default-background-color>
<default-frame-rate>30</default-frame-rate>
<default-size>
<width>800</width>
<height>600</height>
</default-size>
</flex-config>

View File

@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="utf-8"?>
<!--This Adobe Flex compiler configuration file was generated by a tool.-->
<!--Any modifications you make may be lost.-->
<flex-config>
<target-player>25.0</target-player>
<benchmark>false</benchmark>
<static-link-runtime-shared-libraries>true</static-link-runtime-shared-libraries>
<compiler>
<define append="true">
<name>CONFIG::debug</name>
<value>false</value>
</define>
<define append="true">
<name>CONFIG::release</name>
<value>true</value>
</define>
<define append="true">
<name>CONFIG::timeStamp</name>
<value>'26.01.2021'</value>
</define>
<define append="true">
<name>CONFIG::air</name>
<value>false</value>
</define>
<define append="true">
<name>CONFIG::mobile</name>
<value>false</value>
</define>
<define append="true">
<name>CONFIG::desktop</name>
<value>false</value>
</define>
<strict>false</strict>
<omit-trace-statements>false</omit-trace-statements>
<verbose-stacktraces>false</verbose-stacktraces>
<source-path append="true">
<path-element>C:\Dropbox\Programovani\JavaSE\FFDec\libsrc\ffdec_lib\testdata\custom\src</path-element>
<path-element>C:\Program Files (x86)\FlashDevelop\Library\AS3\classes</path-element>
</source-path>
</compiler>
<file-specs>
<path-element>C:\Dropbox\Programovani\JavaSE\FFDec\libsrc\ffdec_lib\testdata\custom\src\Main.as</path-element>
</file-specs>
<default-background-color>#FFFFFF</default-background-color>
<default-frame-rate>30</default-frame-rate>
<default-size>
<width>800</width>
<height>600</height>
</default-size>
</flex-config>

View File

@@ -0,0 +1,13 @@
@echo off
set RABCDASM_PATH=c:\RABCDasm
rd /s /q .\abc
%RABCDASM_PATH%\abcexport.exe .\bin\custom.swf
mkdir .\abc
move .\bin\*.abc abc\>NUL
set ABC_DIR=.\abc
for /F %%x in ('dir /B/D %ABC_DIR%') do (
%RABCDASM_PATH%\rabcdasm.exe %ABC_DIR%\%%x
)
pause

View File

@@ -0,0 +1,5 @@
@echo off
set RABCDASM_PATH=c:\RABCDasm
%RABCDASM_PATH%\rabcasm.exe abc\custom-0\custom-0.main.asasm
%RABCDASM_PATH%\abcreplace.exe bin\custom.swf 0 abc\custom-0\custom-0.main.abc
pause

View File

@@ -0,0 +1,29 @@
package
{
import flash.display.Sprite;
import flash.events.Event;
import tests.*;
/**
* ...
* @author JPEXS
*/
public class Main extends Sprite
{
TestDupAssignment;
public function Main()
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
// entry point
}
}
}

View File

@@ -0,0 +1,13 @@
package tests
{
public class TestDupAssignment
{
public function run() : void
{
//TODO: replace this using RABCDasm
}
}
}

View File

@@ -16,7 +16,7 @@
</define>
<define append="true">
<name>CONFIG::timeStamp</name>
<value>'25.01.2021'</value>
<value>'26.01.2021'</value>
</define>
<define append="true">
<name>CONFIG::air</name>

View File

@@ -16,7 +16,7 @@
</define>
<define append="true">
<name>CONFIG::timeStamp</name>
<value>'25.01.2021'</value>
<value>'26.01.2021'</value>
</define>
<define append="true">
<name>CONFIG::air</name>

View File

@@ -24,6 +24,7 @@ package
TestDefaultNotLastGrouped;
TestDoWhile;
TestDoWhile2;
TestDup;
TestExpressions;
TestFinallyZeroJump;
TestFor;

View File

@@ -0,0 +1,18 @@
package tests
{
public class TestDup
{
public function run() : void
{
var a:Boolean;
var b:Boolean;
if (a = b)
{
trace(a);
}
}
}
}

View File

@@ -8,4 +8,4 @@ package tests
trace("hello");
}
}
}
}