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

@@ -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;
}
}