fixed some dup problems

This commit is contained in:
Jindra Petřík
2021-01-27 19:11:31 +01:00
parent 97c325eb20
commit 2bebbfad0b
21 changed files with 644 additions and 76 deletions

View File

@@ -295,6 +295,7 @@ import com.jpexs.decompiler.graph.SimpleValue;
import com.jpexs.decompiler.graph.TranslateStack;
import com.jpexs.decompiler.graph.TypeItem;
import com.jpexs.decompiler.graph.model.BinaryOpItem;
import com.jpexs.decompiler.graph.model.DuplicateItem;
import com.jpexs.decompiler.graph.model.ExitItem;
import com.jpexs.decompiler.graph.model.IfItem;
import com.jpexs.decompiler.graph.model.ScriptEndItem;
@@ -1614,7 +1615,7 @@ public class AVM2Code implements Cloneable {
AVM2Instruction insAfter = code.get(ip + 1);
Set<Integer> usages = setLocalPosToGetLocalPos.containsKey(ip) ? setLocalPosToGetLocalPos.get(ip) : new HashSet<>();
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))) {
if (!(stack.peek().getNotCoercedNoDup() instanceof DuplicateItem) && !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 {
@@ -2097,14 +2098,14 @@ public class AVM2Code implements Cloneable {
ins.operands[j] = updater.updateOperandOffset(target, ins.operands[j]);
}
}*/ //Faster, but not so universal
if (ins.definition instanceof IfTypeIns) {
long target = ins.getTargetAddress();
try {
ins.operands[0] = updater.updateOperandOffset(ins.getAddress(), target, ins.operands[0]);
} catch (ConvertException cex) {
throw new ConvertException("Invalid offset (" + ins + ")", i);
}
if (ins.definition instanceof IfTypeIns) {
long target = ins.getTargetAddress();
try {
ins.operands[0] = updater.updateOperandOffset(ins.getAddress(), target, ins.operands[0]);
} catch (ConvertException cex) {
throw new ConvertException("Invalid offset (" + ins + ")", i);
}
}
ins.setAddress(updater.updateInstructionOffset(ins.getAddress()));
//Note: changing operands here does not change instruction byte length as offsets are always S24 (not variable length)
}

View File

@@ -29,12 +29,20 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.IncLocalIIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.IncLocalIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.SetLocalTypeIns;
import com.jpexs.decompiler.flash.abc.avm2.model.AVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.ClassAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.FindPropertyAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.FullMultinameAVM2Item;
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.ScriptAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.SetLocalAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.ThisAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.clauses.ExceptionAVM2Item;
import com.jpexs.helpers.Reference;
import com.jpexs.decompiler.flash.abc.types.MethodBody;
import com.jpexs.decompiler.flash.abc.types.Multiname;
import com.jpexs.decompiler.flash.abc.types.traits.Trait;
import com.jpexs.decompiler.flash.abc.types.traits.TraitWithSlot;
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
import com.jpexs.decompiler.graph.DottedChain;
import com.jpexs.decompiler.graph.GraphSourceItem;
@@ -320,4 +328,50 @@ public abstract class InstructionDefinition implements Serializable {
}
return localData.code.adr2pos(src.getAddress());
}
protected Multiname searchSlotName(int slotIndex, AVM2LocalData localData, GraphTargetItem obj) {
return searchSlotName(slotIndex, localData, obj, -1);
}
private Multiname searchSlotName(int slotIndex, AVM2LocalData localData, GraphTargetItem obj, int multiNameIndex) {
if ((obj instanceof ExceptionAVM2Item) && (multiNameIndex == -1 || ((ExceptionAVM2Item) obj).exception.name_index == multiNameIndex)) {
return localData.getConstants().getMultiname(((ExceptionAVM2Item) obj).exception.name_index);
} else if ((obj instanceof ThisAVM2Item) || (obj instanceof ClassAVM2Item) || (obj instanceof ScriptAVM2Item)) {
List<Trait> traits = localData.getScriptInfo().get(localData.scriptIndex).traits.traits;
for (int t = 0; t < traits.size(); t++) {
Trait trait = traits.get(t);
if (trait instanceof TraitWithSlot) {
if (multiNameIndex == -1 || trait.name_index == multiNameIndex) {
if (((TraitWithSlot) trait).getSlotIndex() == slotIndex) {
return trait.getName(localData.abc);
}
}
}
}
} else if (obj instanceof NewActivationAVM2Item) {
MethodBody body = localData.methodBody;
List<Trait> traits = body.traits.traits;
for (int t = 0; t < traits.size(); t++) {
Trait trait = traits.get(t);
if (trait instanceof TraitWithSlot) {
if (multiNameIndex == -1 || trait.name_index == multiNameIndex) {
if (((TraitWithSlot) trait).getSlotIndex() == slotIndex) {
return trait.getName(localData.abc);
}
}
}
}
} else if (obj instanceof FindPropertyAVM2Item) {
FindPropertyAVM2Item findProp = (FindPropertyAVM2Item) obj;
for (GraphTargetItem item : localData.scopeStack) {
Multiname ret = searchSlotName(slotIndex, localData, item, ((FullMultinameAVM2Item) findProp.propertyName).multinameIndex);
if (ret != null) {
return ret;
}
}
}
return null;
}
}

View File

@@ -48,26 +48,47 @@ public interface SetTypeIns {
if (notCoercedValue instanceof DuplicateItem) {
GraphTargetItem insideDup = notCoercedValue.value;
if (!AVM2Item.mustStayIntact1(insideDup.getNotCoerced())) {
if (!AVM2Item.mustStayIntact1(insideDup.getNotCoercedNoDup())) {
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
if ((insideDup instanceof DuplicateItem) && regId > -1) {
int numDups = 1;
while ((insideDup instanceof DuplicateItem) && !stack.isEmpty() && stack.peek() == insideDup.value) {
insideDup = insideDup.value;
stack.pop();
numDups++;
}
if ((value instanceof CoerceAVM2Item) || (value instanceof ConvertAVM2Item)) {
value.value = insideDup;
} else {
value = insideDup;
}
result.value = value;
output.add(result);
stack.push(new LocalRegAVM2Item(null, localData.lineStartInstruction, regId, value));
for (int i = 0; i < numDups; i++) {
stack.push(new LocalRegAVM2Item(null, localData.lineStartInstruction, regId, value));
}
return;
} else {
if ((value instanceof CoerceAVM2Item) || (value instanceof ConvertAVM2Item)) {
value.value = insideDup;
} else {
value = insideDup;
}
result.value = 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;
}
stack.push(result);
return;
}
}
}

View File

@@ -50,32 +50,7 @@ public class GetSlotIns extends InstructionDefinition {
int slotIndex = ins.operands[0];
GraphTargetItem objinreg = stack.pop(); //scope
GraphTargetItem obj = objinreg.getThroughRegister();
Multiname slotname = null;
if (obj instanceof ExceptionAVM2Item) {
slotname = localData.getConstants().getMultiname(((ExceptionAVM2Item) obj).exception.name_index);
} else if ((obj instanceof ThisAVM2Item) || (obj instanceof ClassAVM2Item) || (obj instanceof ScriptAVM2Item)) {
List<Trait> traits = localData.getScriptInfo().get(localData.scriptIndex).traits.traits;
for (int t = 0; t < traits.size(); t++) {
Trait tr = traits.get(t);
if (tr instanceof TraitWithSlot) {
if (((TraitWithSlot) tr).getSlotIndex() == slotIndex) {
slotname = tr.getName(localData.abc);
}
}
}
} else if (obj instanceof NewActivationAVM2Item) {
MethodBody body = localData.methodBody;
List<Trait> traits = body.traits.traits;
for (int t = 0; t < traits.size(); t++) {
Trait trait = traits.get(t);
if (trait instanceof TraitWithSlot) {
if (((TraitWithSlot) trait).getSlotIndex() == slotIndex) {
slotname = trait.getName(localData.abc);
}
}
}
}
Multiname slotname = searchSlotName(slotIndex, localData, obj);
stack.push(new GetSlotAVM2Item(ins, localData.lineStartInstruction, obj, objinreg, slotIndex, slotname));
}

View File

@@ -161,6 +161,24 @@ public class SetPropertyIns extends InstructionDefinition implements SetTypeIns
}
}
}
//assembled/TestIncrement3
if ((value instanceof IncrementAVM2Item) || (value instanceof DecrementAVM2Item)) {
boolean isIncrement = (value instanceof IncrementAVM2Item);
if (value.value.getNotCoerced() instanceof GetPropertyAVM2Item) {
GetPropertyAVM2Item getProp = (GetPropertyAVM2Item) value.value.getNotCoerced();
if (getProp.object instanceof DuplicateItem) {
if (getProp.object.value == obj) {
getProp.object = obj;
if (isIncrement) {
output.add(new PostIncrementAVM2Item(ins, localData.lineStartInstruction, getProp));
} else {
output.add(new PostDecrementAVM2Item(ins, localData.lineStartInstruction, getProp));
}
return;
}
}
}
}
if (value instanceof LocalRegAVM2Item) {
LocalRegAVM2Item valueLocalReg = (LocalRegAVM2Item) value;

View File

@@ -25,6 +25,8 @@ 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.ClassAVM2Item;
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.FullMultinameAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.GetSlotAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.IncrementAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.LocalRegAVM2Item;
@@ -66,36 +68,10 @@ public class SetSlotIns extends InstructionDefinition implements SetTypeIns {
GraphTargetItem obj = stack.pop(); //scopeId
GraphTargetItem objnoreg = obj;
obj = obj.getThroughRegister();
Multiname slotname = null;
if (obj instanceof NewActivationAVM2Item) {
((NewActivationAVM2Item) obj).slots.put(slotIndex, value);
}
if (obj instanceof ExceptionAVM2Item) {
slotname = localData.getConstants().getMultiname(((ExceptionAVM2Item) obj).exception.name_index);
} else if ((obj instanceof ThisAVM2Item) || (obj instanceof ClassAVM2Item) || (obj instanceof ScriptAVM2Item)) {
List<Trait> traits = localData.getScriptInfo().get(localData.scriptIndex).traits.traits;
for (int t = 0; t < traits.size(); t++) {
Trait tr = traits.get(t);
if (tr instanceof TraitWithSlot) {
if (((TraitWithSlot) tr).getSlotIndex() == slotIndex) {
slotname = tr.getName(localData.abc);
}
}
}
} else if (obj instanceof NewActivationAVM2Item) {
MethodBody body = localData.methodBody;
List<Trait> traits = body.traits.traits;
for (int t = 0; t < traits.size(); t++) {
Trait trait = traits.get(t);
if (trait instanceof TraitWithSlot) {
if (((TraitWithSlot) trait).getSlotIndex() == slotIndex) {
slotname = trait.getName(localData.abc);
}
}
}
}
Multiname slotname = searchSlotName(slotIndex, localData, obj);
if (slotname != null) {
if (value instanceof LocalRegAVM2Item) {