AS3 - Compound assignments detection

This commit is contained in:
Jindra Petřík
2021-03-07 22:08:59 +01:00
parent 16a03fe0f7
commit 23227caacd
7 changed files with 84 additions and 13 deletions

View File

@@ -125,7 +125,7 @@ public abstract class SetLocalTypeIns extends InstructionDefinition implements S
}
SetLocalAVM2Item result = new SetLocalAVM2Item(ins, localData.lineStartInstruction, regId, value);
/*if (value.getNotCoercedNoDup() instanceof CompoundableBinaryOp) {
if (value.getNotCoercedNoDup() instanceof CompoundableBinaryOp) {
CompoundableBinaryOp binaryOp = (CompoundableBinaryOp) value.getNotCoercedNoDup();
if (binaryOp.getLeftSide() instanceof LocalRegAVM2Item) {
LocalRegAVM2Item loc = (LocalRegAVM2Item) binaryOp.getLeftSide();
@@ -134,7 +134,7 @@ public abstract class SetLocalTypeIns extends InstructionDefinition implements S
result.setCompoundOperator(binaryOp.getOperator());
}
}
}*/
}
SetTypeIns.handleResult(value, stack, output, localData, result, regId);
}

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.other;
import com.jpexs.decompiler.flash.abc.ABC;
@@ -43,7 +44,9 @@ public class InitPropertyIns extends InstructionDefinition {
GraphTargetItem val = stack.pop();
FullMultinameAVM2Item multiname = resolveMultiname(localData, true, stack, localData.getConstants(), multinameIndex, ins);
GraphTargetItem obj = stack.pop();
GraphTargetItem obj = stack.pop();
InitPropertyAVM2Item result = new InitPropertyAVM2Item(ins, localData.lineStartInstruction, obj, multiname, val);
SetPropertyIns.handleCompound(obj, multiname, val, output, result);
output.add(result);
}
@Override

View File

@@ -37,6 +37,7 @@ 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.SetTypeAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.operations.AddAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.operations.PreDecrementAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.operations.PreIncrementAVM2Item;
@@ -337,8 +338,12 @@ public class SetPropertyIns extends InstructionDefinition implements SetTypeIns
}
SetPropertyAVM2Item result = new SetPropertyAVM2Item(ins, localData.lineStartInstruction, obj, multiname, value);
handleCompound(obj, multiname, value, output, result);
/*
SetTypeIns.handleResult(value, stack, output, localData, result, -1);
}
public static void handleCompound(GraphTargetItem obj, FullMultinameAVM2Item multiname, GraphTargetItem value, List<GraphTargetItem> output, SetTypeAVM2Item result) {
if (value instanceof LocalRegAVM2Item) {
LocalRegAVM2Item locVal = (LocalRegAVM2Item) value;
if (multiname.name instanceof LocalRegAVM2Item) {
@@ -356,8 +361,8 @@ public class SetPropertyIns extends InstructionDefinition implements SetTypeIns
GetPropertyAVM2Item getProp = (GetPropertyAVM2Item) binaryOp.getLeftSide();
if (((FullMultinameAVM2Item) getProp.propertyName).compareSame(multiname) && Objects.equals(getProp.object, obj)) {
multiname.name = setLocName.value;
result.compoundValue = binaryOp.getRightSide();
result.compoundOperator = binaryOp.getOperator();
result.setCompoundValue(binaryOp.getRightSide());
result.setCompoundOperator(binaryOp.getOperator());
output.remove(output.size() - 2);
output.remove(output.size() - 1);
}
@@ -369,8 +374,20 @@ public class SetPropertyIns extends InstructionDefinition implements SetTypeIns
}
}
}
}*/
SetTypeIns.handleResult(value, stack, output, localData, result, -1);
}
if (value.getNotCoercedNoDup() instanceof CompoundableBinaryOp) {
if (!obj.hasSideEffect() && !multiname.hasSideEffect()) {
CompoundableBinaryOp binaryOp = (CompoundableBinaryOp) value.getNotCoercedNoDup();
if (binaryOp.getLeftSide() instanceof GetPropertyAVM2Item) {
GetPropertyAVM2Item propItem = (GetPropertyAVM2Item) binaryOp.getLeftSide();
if (Objects.equals(obj, propItem.object.getThroughDuplicate()) && Objects.equals(multiname, propItem.propertyName)) {
result.setCompoundValue(binaryOp.getRightSide());
result.setCompoundOperator(binaryOp.getOperator());
}
}
}
}
}
@Override

View File

@@ -39,9 +39,11 @@ import com.jpexs.decompiler.flash.abc.types.traits.TraitSlotConst;
import com.jpexs.decompiler.graph.DottedChain;
import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.TranslateStack;
import com.jpexs.decompiler.graph.model.CompoundableBinaryOp;
import com.jpexs.helpers.Reference;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.Stack;
/**
@@ -140,7 +142,21 @@ public class SetSlotIns extends InstructionDefinition implements SetTypeIns {
}
}
GraphTargetItem result = new SetSlotAVM2Item(ins, localData.lineStartInstruction, obj, objnoreg, slotIndex, slotname, value);
SetSlotAVM2Item result = new SetSlotAVM2Item(ins, localData.lineStartInstruction, obj, objnoreg, slotIndex, slotname, value);
if (value.getNotCoercedNoDup() instanceof CompoundableBinaryOp) {
if (!obj.hasSideEffect()) {
CompoundableBinaryOp binaryOp = (CompoundableBinaryOp) value.getNotCoercedNoDup();
if (binaryOp.getLeftSide() instanceof GetSlotAVM2Item) {
GetSlotAVM2Item getSlot = (GetSlotAVM2Item) binaryOp.getLeftSide();
if (Objects.equals(obj, getSlot.scope.getThroughDuplicate()) && slotIndex == getSlot.slotIndex) {
result.compoundValue = binaryOp.getRightSide();
result.compoundOperator = binaryOp.getOperator();
}
}
}
}
SetTypeIns.handleResult(value, stack, output, localData, result, -1);
}

View File

@@ -24,6 +24,7 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
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.FullMultinameAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.GetSuperAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.SetSuperAVM2Item;
import com.jpexs.decompiler.flash.abc.types.MethodBody;
import com.jpexs.decompiler.flash.configuration.Configuration;
@@ -31,9 +32,11 @@ import com.jpexs.decompiler.flash.helpers.HighlightedTextWriter;
import com.jpexs.decompiler.graph.DottedChain;
import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.TranslateStack;
import com.jpexs.decompiler.graph.model.CompoundableBinaryOp;
import com.jpexs.decompiler.graph.model.LocalData;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.Stack;
/**
@@ -54,7 +57,21 @@ public class SetSuperIns extends InstructionDefinition implements SetTypeIns {
FullMultinameAVM2Item multiname = resolveMultiname(localData, true, stack, localData.getConstants(), multinameIndex, ins);
GraphTargetItem obj = stack.pop();
GraphTargetItem result = new SetSuperAVM2Item(ins, localData.lineStartInstruction, value, obj, multiname);
SetSuperAVM2Item result = new SetSuperAVM2Item(ins, localData.lineStartInstruction, value, obj, multiname);
if (value.getNotCoercedNoDup() instanceof CompoundableBinaryOp) {
if (!obj.hasSideEffect() && !multiname.hasSideEffect()) {
CompoundableBinaryOp binaryOp = (CompoundableBinaryOp) value.getNotCoercedNoDup();
if (binaryOp.getLeftSide() instanceof GetSuperAVM2Item) {
GetSuperAVM2Item getSuper = (GetSuperAVM2Item) binaryOp.getLeftSide();
if (Objects.equals(obj, getSuper.object.getThroughDuplicate()) && Objects.equals(multiname, getSuper.propertyName)) {
result.setCompoundValue(binaryOp.getRightSide());
result.setCompoundOperator(binaryOp.getOperator());
}
}
}
}
SetTypeIns.handleResult(value, stack, output, localData, result, -1);
}

View File

@@ -41,8 +41,10 @@ import com.jpexs.decompiler.graph.model.FalseItem;
import com.jpexs.decompiler.graph.model.LocalData;
import com.jpexs.decompiler.graph.model.NotItem;
import com.jpexs.decompiler.graph.model.TrueItem;
import com.jpexs.helpers.Reference;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -372,7 +374,16 @@ public abstract class GraphTargetItem implements Serializable, Cloneable {
}
public boolean hasSideEffect() {
return false;
Reference<Boolean> ref = new Reference<>(false);
visitRecursively(new AbstractGraphTargetVisitor() {
@Override
public void visit(GraphTargetItem item) {
if (item.hasSideEffect()) {
ref.setVal(Boolean.TRUE);
}
}
});
return ref.getVal();
}
public boolean isVariableComputed() {

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.graph.model;
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
@@ -118,4 +119,10 @@ public class DuplicateItem extends GraphTargetItem implements SimpleValue {
public boolean isSimpleValue() {
return ((value instanceof SimpleValue) && ((SimpleValue) value).isSimpleValue());
}
@Override
public boolean hasSideEffect() {
return value.hasSideEffect();
}
}