increments/decrements, chained assignments fixes

This commit is contained in:
Jindra Petřík
2021-01-27 10:09:11 +01:00
parent 9417978be4
commit 4dc28cdebe
24 changed files with 565 additions and 49 deletions

View File

@@ -247,6 +247,7 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.xml.DXNSIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.xml.DXNSLateIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.xml.EscXAttrIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.xml.EscXElemIns;
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.FullMultinameAVM2Item;
@@ -1609,10 +1610,11 @@ public class AVM2Code implements Cloneable {
}
}*/
if ((ins.definition instanceof SetLocalTypeIns) && (ip + 1 <= end)) { // set_local_x,get_local_x.. no other local_x get
AVM2Instruction insAfter = code.get(ip + 1);
Set<Integer> usages = setLocalPosToGetLocalPos.containsKey(ip) ? setLocalPosToGetLocalPos.get(ip) : new HashSet<>();
if (usages.size() == 1 && (usages.iterator().next().equals(ip + 1)) && (insAfter.definition instanceof GetLocalTypeIns) && (((GetLocalTypeIns) insAfter.definition).getRegisterId(insAfter) == ((SetLocalTypeIns) ins.definition).getRegisterId(ins))) {
if (!AVM2Item.mustStayIntact2(stack.peek()) && usages.size() == 1 && (usages.iterator().next().equals(ip + 1)) && (insAfter.definition instanceof GetLocalTypeIns) && (((GetLocalTypeIns) insAfter.definition).getRegisterId(insAfter) == ((SetLocalTypeIns) ins.definition).getRegisterId(ins))) {
ip += 2;
continue iploop;
} else {

View File

@@ -12,13 +12,22 @@
* 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;
import com.jpexs.decompiler.flash.abc.ABC;
import com.jpexs.decompiler.flash.abc.AVM2LocalData;
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.LocalRegAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.SetLocalAVM2Item;
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.HashMap;
import java.util.List;
import java.util.Stack;
@@ -30,4 +39,38 @@ import java.util.Stack;
public interface SetTypeIns {
public abstract String getObject(Stack<AVM2Item> stack, ABC abc, AVM2Instruction ins, List<AVM2Item> output, MethodBody body, HashMap<Integer, String> localRegNames, List<DottedChain> fullyQualifiedNames) throws InterruptedException;
public static void handleResult(GraphTargetItem value, TranslateStack stack, List<GraphTargetItem> output, AVM2LocalData localData, GraphTargetItem result, int regId) {
GraphTargetItem notCoercedValue = value;
if ((value instanceof CoerceAVM2Item) || (value instanceof ConvertAVM2Item)) {
notCoercedValue = value.value;
}
if (notCoercedValue instanceof DuplicateItem) {
GraphTargetItem insideDup = notCoercedValue.value;
if (!AVM2Item.mustStayIntact1(insideDup.getNotCoerced())) {
if (!stack.isEmpty() && stack.peek() == insideDup) {
stack.pop();
if ((value instanceof CoerceAVM2Item) || (value instanceof ConvertAVM2Item)) {
value.value = insideDup;
} else {
value = insideDup;
}
result.value = value;
//GraphTargetItem result = new SetLocalAVM2Item(ins, localData.lineStartInstruction, regId, value);
if (regId > -1 && AVM2Item.mustStayIntact2(insideDup.getNotCoerced())) { //hack
output.add(result);
stack.push(new LocalRegAVM2Item(null, localData.lineStartInstruction, regId, value));
return;
}
stack.push(result);
return;
}
}
}
output.add(result);
}
}

View File

@@ -31,10 +31,13 @@ import com.jpexs.decompiler.flash.abc.avm2.model.FindPropertyAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.IncrementAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.LocalRegAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.NewActivationAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.NextNameAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.NextValueAVM2Item;
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.clauses.ExceptionAVM2Item;
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;
@@ -134,41 +137,26 @@ public abstract class SetLocalTypeIns extends InstructionDefinition implements S
}
}
if (localData.getSetLocalUsages(localData.code.adr2pos(ins.getAddress())).isEmpty() && (value instanceof DuplicateItem)) {
/*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);
SetTypeIns.handleResult(value, stack, output, localData, result, regId);
}
@Override
public int getStackPopCount(AVM2Instruction ins, ABC abc) {
public int getStackPopCount(AVM2Instruction ins, ABC abc
) {
return 1;
}
@Override
public String getObject(Stack<AVM2Item> stack, ABC abc, AVM2Instruction ins, List<AVM2Item> output, MethodBody body, HashMap<Integer, String> localRegNames, List<DottedChain> fullyQualifiedNames) {
public String getObject(Stack<AVM2Item> stack, ABC abc,
AVM2Instruction ins, List<AVM2Item> output,
MethodBody body, HashMap<Integer, String> localRegNames,
List<DottedChain> fullyQualifiedNames
) {
return AVM2Item.localRegName(localRegNames, getRegisterId(ins));
}

View File

@@ -46,7 +46,7 @@ public class SetGlobalSlotIns extends InstructionDefinition implements SetTypeIn
public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List<GraphTargetItem> output, String path) {
GraphTargetItem value = stack.pop();
GraphTargetItem result = new SetGlobalSlotAVM2Item(ins, localData.lineStartInstruction, ins.operands[0], value);
output.add(result);
SetTypeIns.handleResult(value, stack, output, localData, result, -1);
}
@Override

View File

@@ -111,6 +111,7 @@ public class SetPropertyIns extends InstructionDefinition implements SetTypeIns
FullMultinameAVM2Item multiname = resolveMultiname(localData, true, stack, localData.getConstants(), multinameIndex, ins);
GraphTargetItem obj = stack.pop();
//assembled/TestIncrement
if ((value instanceof IncrementAVM2Item) || (value instanceof DecrementAVM2Item)) {
boolean isIncrement = (value instanceof IncrementAVM2Item);
if (value.value instanceof DuplicateItem) {
@@ -134,7 +135,31 @@ public class SetPropertyIns extends InstructionDefinition implements SetTypeIns
}
}
}
}
//assembled/TestIncrement2
if (value instanceof DuplicateItem) {
GraphTargetItem duplicated = value.value;
if ((duplicated instanceof IncrementAVM2Item) || (duplicated instanceof DecrementAVM2Item)) {
boolean isIncrement = (duplicated instanceof IncrementAVM2Item);
if (!stack.isEmpty()) {
if (stack.peek() == duplicated) {
GraphTargetItem incrementedProp = duplicated.value;
if (incrementedProp instanceof GetLexAVM2Item) {
GetLexAVM2Item getLex = (GetLexAVM2Item) incrementedProp;
if (localData.abc.constants.getMultiname(multinameIndex).equals(getLex.propertyName)) {
stack.pop();
if (isIncrement) {
stack.push(new PreIncrementAVM2Item(ins, localData.lineStartInstruction, getLex));
} else {
stack.push(new PreDecrementAVM2Item(ins, localData.lineStartInstruction, getLex));
}
return;
}
}
}
}
}
}
if (value instanceof LocalRegAVM2Item) {
@@ -228,7 +253,7 @@ public class SetPropertyIns extends InstructionDefinition implements SetTypeIns
}
GraphTargetItem result = new SetPropertyAVM2Item(ins, localData.lineStartInstruction, obj, multiname, value);
output.add(result);
SetTypeIns.handleResult(value, stack, output, localData, result, -1);
}
@Override

View File

@@ -160,7 +160,7 @@ public class SetSlotIns extends InstructionDefinition implements SetTypeIns {
}
GraphTargetItem result = new SetSlotAVM2Item(ins, localData.lineStartInstruction, obj, objnoreg, slotIndex, slotname, value);
output.add(result);
SetTypeIns.handleResult(value, stack, output, localData, result, -1);
}
@Override

View File

@@ -55,7 +55,7 @@ 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);
output.add(result);
SetTypeIns.handleResult(value, stack, output, localData, result, -1);
}
@Override

View File

@@ -22,6 +22,7 @@ import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instructions;
import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
import com.jpexs.decompiler.flash.abc.avm2.model.clauses.ExceptionAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.parser.script.AVM2SourceGenerator;
import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
@@ -72,7 +73,7 @@ public abstract class AVM2Item extends GraphTargetItem {
}
protected GraphTextWriter formatProperty(GraphTextWriter writer, GraphTargetItem object, GraphTargetItem propertyName, LocalData localData) throws InterruptedException {
boolean empty = object instanceof FindPropertyAVM2Item;
boolean empty = object.getThroughDuplicate() instanceof FindPropertyAVM2Item;
if (object instanceof LocalRegAVM2Item) {
if (((LocalRegAVM2Item) object).computedValue != null) {
if (((LocalRegAVM2Item) object).computedValue.getThroughNotCompilable() instanceof FindPropertyAVM2Item) {
@@ -81,8 +82,8 @@ public abstract class AVM2Item extends GraphTargetItem {
}
}
if (object instanceof FindPropertyAVM2Item) {
FindPropertyAVM2Item fp = (FindPropertyAVM2Item) object;
if (object.getThroughDuplicate() instanceof FindPropertyAVM2Item) {
FindPropertyAVM2Item fp = (FindPropertyAVM2Item) object.getThroughDuplicate();
if (fp.propertyName instanceof FullMultinameAVM2Item) {
propertyName = fp.propertyName;
}
@@ -202,4 +203,22 @@ public abstract class AVM2Item extends GraphTargetItem {
return true;
}
public static boolean mustStayIntact1(GraphTargetItem target) {
target = target.getNotCoerced();
if (target instanceof ExceptionAVM2Item) {
return true;
}
return false;
}
public static boolean mustStayIntact2(GraphTargetItem target) {
target = target.getNotCoerced();
if (target instanceof NextValueAVM2Item) {
return true;
}
if (target instanceof NextNameAVM2Item) {
return true;
}
return false;
}
}

View File

@@ -55,7 +55,7 @@ public class CallSuperAVM2Item extends AVM2Item {
@Override
public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException {
if (!receiver.toString().equals("this") && !(receiver instanceof FindPropertyAVM2Item)) {
if (!receiver.toString().equals("this") && !(receiver.getThroughDuplicate() instanceof FindPropertyAVM2Item)) {
receiver.toString(writer, localData);
writer.append(".");
}

View File

@@ -53,7 +53,7 @@ public class ConstructPropAVM2Item extends AVM2Item {
@Override
public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException {
writer.append("new ");
if (!(object instanceof FindPropertyAVM2Item)) {
if (!(object.getThroughDuplicate() instanceof FindPropertyAVM2Item)) {
object.toString(writer, localData);
writer.append(".");
}

View File

@@ -48,7 +48,7 @@ public class GetSuperAVM2Item extends AVM2Item {
@Override
public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException {
if (!object.toString().equals("this")) {
if (!(object instanceof FindPropertyAVM2Item)) {
if (!(object.getThroughDuplicate() instanceof FindPropertyAVM2Item)) {
object.toString(writer, localData);
writer.append(".");
}

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.SourceGeneratorLocalData;

View File

@@ -16,22 +16,14 @@
*/
package com.jpexs.decompiler.flash.abc.avm2.model;
import com.jpexs.decompiler.flash.abc.ABC;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
import com.jpexs.decompiler.flash.abc.avm2.instructions.SetTypeIns;
import com.jpexs.decompiler.flash.abc.avm2.model.clauses.DeclarationAVM2Item;
import com.jpexs.decompiler.flash.abc.types.MethodBody;
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
import com.jpexs.decompiler.graph.DottedChain;
import com.jpexs.decompiler.graph.GraphPart;
import com.jpexs.decompiler.graph.GraphSourceItem;
import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.GraphTargetVisitorInterface;
import com.jpexs.decompiler.graph.TypeItem;
import com.jpexs.decompiler.graph.model.LocalData;
import java.util.HashMap;
import java.util.List;
import java.util.Stack;
/**
*
@@ -78,8 +70,10 @@ public class SetSuperAVM2Item extends AVM2Item implements SetTypeAVM2Item {
@Override
public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException {
if (!object.toString().equals("this")) {
object.toString(writer, localData);
writer.append(".");
if (!(object.getThroughDuplicate() instanceof FindPropertyAVM2Item)) {
object.toString(writer, localData);
writer.append(".");
}
}
writer.append("super.");
propertyName.toString(writer, localData);