§§dupsrc introduced

This commit is contained in:
Jindra Petřík
2025-08-03 21:42:25 +02:00
parent 922cd45084
commit b449db946f
14 changed files with 213 additions and 40 deletions

View File

@@ -63,6 +63,7 @@ import com.jpexs.decompiler.graph.ScopeStack;
import com.jpexs.decompiler.graph.TranslateStack;
import com.jpexs.decompiler.graph.model.CommaExpressionItem;
import com.jpexs.decompiler.graph.model.DuplicateItem;
import com.jpexs.decompiler.graph.model.DuplicateSourceItem;
import com.jpexs.decompiler.graph.model.PopItem;
import com.jpexs.decompiler.graph.model.PushItem;
import com.jpexs.helpers.LinkedIdentityHashSet;
@@ -562,10 +563,10 @@ public abstract class InstructionDefinition implements Serializable {
if ((value instanceof IncrementAVM2Item) || (value instanceof DecrementAVM2Item)) {
boolean isIncrement = (value instanceof IncrementAVM2Item);
if (value.value instanceof DuplicateItem) {
GraphTargetItem duplicated = value.value.value;
GraphTargetItem duplicated = value.value.value.getThroughDuplicate();
stack.moveToStack(output);
if (!stack.isEmpty()) {
if (stack.peek() == duplicated) {
if (stack.peek().getThroughDuplicate() == duplicated) {
GraphTargetItem notCoerced = duplicated.getNotCoerced();
if (notCoerced instanceof GetLexAVM2Item) {
GetLexAVM2Item getLex = (GetLexAVM2Item) notCoerced;
@@ -584,9 +585,9 @@ public abstract class InstructionDefinition implements Serializable {
GetPropertyAVM2Item getProp = (GetPropertyAVM2Item) notCoerced;
if (((FullMultinameAVM2Item) getProp.propertyName).compareSame(multiname)) {
if (getProp.object instanceof DuplicateItem) { //assembled/TestIncrement3
if (getProp.object.value == obj) {
getProp.object = obj;
if ((getProp.object instanceof DuplicateItem) || (getProp.object instanceof DuplicateSourceItem)) { //assembled/TestIncrement3
if (getProp.object.value == obj.getThroughDuplicate()) {
getProp.object = obj.getThroughDuplicate();
}
}
@@ -635,12 +636,12 @@ public abstract class InstructionDefinition implements Serializable {
GetPropertyAVM2Item getProp = (GetPropertyAVM2Item) value.value.getNotCoercedNoDup();
if (((FullMultinameAVM2Item) getProp.propertyName).compareSame(multiname)) {
if (getProp.object instanceof DuplicateItem) {
if (getProp.object.value == obj) {
getProp.object = obj;
if ((getProp.object instanceof DuplicateItem) || (getProp.object instanceof DuplicateSourceItem)) {
if (getProp.object.value == obj.getThroughDuplicate()) {
getProp.object = obj.getThroughDuplicate();
}
}
if (Objects.equals(getProp.object, obj)) {
if (Objects.equals(getProp.object.getThroughDuplicate(), obj.getThroughDuplicate())) {
if (hasConvert) {
if (isIncrement) {
stack.addToOutput(new PostIncrementAVM2Item(ins, localData.lineStartInstruction, getProp));
@@ -666,7 +667,7 @@ public abstract class InstructionDefinition implements Serializable {
boolean isIncrement = (duplicated instanceof IncrementAVM2Item);
stack.moveToStack(output);
if (!stack.isEmpty()) {
if (stack.peek() == duplicated) {
if (stack.peek().getThroughDuplicate() == duplicated.getThroughDuplicate()) {
GraphTargetItem incrementedProp = duplicated.value;
if (incrementedProp instanceof GetLexAVM2Item) {
GetLexAVM2Item getLex = (GetLexAVM2Item) incrementedProp;
@@ -716,7 +717,7 @@ public abstract class InstructionDefinition implements Serializable {
if (valueSetLocalReg.value.value instanceof DuplicateItem) {
GraphTargetItem duplicated = valueSetLocalReg.value.value.value;
//if (!output.isEmpty() && output.get(output.size() - 1) instanceof PushItem && ((PushItem) output.get(output.size() - 1)).value == duplicated) {
if (!stack.isEmpty() && stack.peek() == duplicated) {
if (!stack.isEmpty() && stack.peek().getThroughDuplicate() == duplicated) {
GraphTargetItem notCoerced = duplicated.getNotCoerced();
if (notCoerced instanceof GetPropertyAVM2Item) {
GetPropertyAVM2Item getProperty = (GetPropertyAVM2Item) notCoerced;
@@ -797,7 +798,7 @@ public abstract class InstructionDefinition implements Serializable {
}
}
if (obj.getThroughDuplicate() instanceof ConstructAVM2Item) {
if (obj.getThroughDuplicate() instanceof ConstructAVM2Item) {
ConstructAVM2Item c = (ConstructAVM2Item) obj.getThroughDuplicate();
if (c.object instanceof ApplyTypeAVM2Item) {
ApplyTypeAVM2Item at = (ApplyTypeAVM2Item) c.object;
@@ -805,10 +806,24 @@ public abstract class InstructionDefinition implements Serializable {
List<GraphTargetItem> vals = new ArrayList<>();
vals.add(value);
c.object = new InitVectorAVM2Item(c.getInstruction(), c.getLineStartIns(), at.params.get(0), vals);
if (obj instanceof DuplicateItem) {
if (!stack.isEmpty()
&& stack.peek() instanceof DuplicateSourceItem
&& stack.peek().getThroughDuplicate() == obj.getThroughDuplicate()) {
stack.push(stack.pop().value);
}
}
return;
} else if (c.object instanceof InitVectorAVM2Item) {
InitVectorAVM2Item iv = (InitVectorAVM2Item) c.object;
iv.arguments.add(value);
if (obj instanceof DuplicateItem) {
if (!stack.isEmpty()
&& stack.peek() instanceof DuplicateSourceItem
&& stack.peek().getThroughDuplicate() == obj.getThroughDuplicate()) {
stack.push(stack.pop().value);
}
}
return;
}
}

View File

@@ -74,12 +74,12 @@ public interface SetTypeIns {
GraphTargetItem insideDup = notCoercedValue.value;
if (!AVM2Item.mustStayIntact1(insideDup.getNotCoercedNoDup())) {
stack.moveToStack(output);
if (!stack.isEmpty() && stack.peek() == insideDup) {
if (!stack.isEmpty() && stack.peek().getThroughDuplicate() == insideDup.getThroughDuplicate()) {
stack.pop();
if ((insideDup instanceof DuplicateItem) && regId > -1) {
int numDups = 1;
while ((insideDup instanceof DuplicateItem) && !stack.isEmpty() && stack.peek() == insideDup.value) {
while ((insideDup instanceof DuplicateItem) && !stack.isEmpty() && stack.peek().getThroughDuplicate() == insideDup.getThroughDuplicate()) {
insideDup = insideDup.value;
stack.pop();
numDups++;

View File

@@ -87,8 +87,8 @@ public class CallIns extends InstructionDefinition {
if (function instanceof GetPropertyAVM2Item) {
GetPropertyAVM2Item getProperty = (GetPropertyAVM2Item) function;
if (getProperty.object instanceof DuplicateItem) {
if (getProperty.object.value == receiver) {
getProperty.object = receiver;
if (getProperty.object.value == receiver.getThroughDuplicate()) {
getProperty.object = receiver.getThroughDuplicate();
}
} else if (getProperty.object instanceof SetLocalAVM2Item) {
SetLocalAVM2Item setLocal = (SetLocalAVM2Item) getProperty.object;

View File

@@ -47,6 +47,7 @@ import com.jpexs.decompiler.graph.TranslateStack;
import com.jpexs.decompiler.graph.TypeItem;
import com.jpexs.decompiler.graph.model.CommaExpressionItem;
import com.jpexs.decompiler.graph.model.DuplicateItem;
import com.jpexs.decompiler.graph.model.DuplicateSourceItem;
import java.util.List;
/**
@@ -133,9 +134,9 @@ public abstract class GetLocalTypeIns extends InstructionDefinition {
if (setLocal.value.getNotCoerced() instanceof GetPropertyAVM2Item) {
SetPropertyAVM2Item setProp = (SetPropertyAVM2Item) setItem;
GetPropertyAVM2Item getProp = (GetPropertyAVM2Item) setLocal.value.getNotCoerced();
if (getProp.object.getThroughDuplicate() == setProp.object) {
if (getProp.object.getThroughDuplicate() == setProp.object.getThroughDuplicate()) {
if (((FullMultinameAVM2Item) setProp.propertyName).compareSame((FullMultinameAVM2Item) getProp.propertyName)) {
if (getProp.object instanceof DuplicateItem) {
if ((getProp.object instanceof DuplicateItem) || (getProp.object instanceof DuplicateSourceItem)) {
getProp.object = getProp.object.value;
}
GraphTargetItem result;
@@ -175,9 +176,10 @@ public abstract class GetLocalTypeIns extends InstructionDefinition {
if (setItem.value.value instanceof GetPropertyAVM2Item) {
SetPropertyAVM2Item setProp = (SetPropertyAVM2Item) setItem;
GetPropertyAVM2Item getProp = (GetPropertyAVM2Item) setItem.value.value;
if (getProp.object.getThroughDuplicate() == setProp.object) {
if (getProp.object.getThroughDuplicate() == setProp.object.getThroughDuplicate()) {
if (((FullMultinameAVM2Item) setProp.propertyName).compareSame((FullMultinameAVM2Item) getProp.propertyName)) {
if (getProp.object instanceof DuplicateItem) {
if (getProp.object instanceof DuplicateItem
|| getProp.object instanceof DuplicateSourceItem) {
getProp.object = getProp.object.value;
}
if (isIncrement) {
@@ -223,7 +225,8 @@ public abstract class GetLocalTypeIns extends InstructionDefinition {
GetPropertyAVM2Item getProp = (GetPropertyAVM2Item) setItem.value.value;
if (getProp.object.getThroughDuplicate() == setProp.object) {
if (((FullMultinameAVM2Item) setProp.propertyName).compareSame((FullMultinameAVM2Item) getProp.propertyName)) {
if (getProp.object instanceof DuplicateItem) {
if (getProp.object instanceof DuplicateItem
|| getProp.object instanceof DuplicateSourceItem) {
getProp.object = getProp.object.value;
}
if (isIncrement) {
@@ -243,9 +246,7 @@ public abstract class GetLocalTypeIns extends InstructionDefinition {
}
}
}
}
}
}
@Override

View File

@@ -155,7 +155,7 @@ public abstract class SetLocalTypeIns extends InstructionDefinition implements S
if (value instanceof DuplicateItem) {
result.directlyCausedByDup = true;
}
}
SetTypeIns.handleResult(value, stack, output, localData, result, regId, value.returnType());
}

View File

@@ -114,7 +114,7 @@ public class GetPropertyIns extends InstructionDefinition {
}
}
if (findPropName.name instanceof DuplicateItem) {
if (findPropName.name.value == multiname.name) {
if (findPropName.name.getThroughDuplicate() == multiname.name.getThroughDuplicate()) {
findPropName.name = findPropName.name.value;
}
}
@@ -131,7 +131,7 @@ public class GetPropertyIns extends InstructionDefinition {
}
}
if (findPropName.namespace instanceof DuplicateItem) {
if (findPropName.namespace.value == multiname.namespace) {
if (findPropName.namespace.getThroughDuplicate() == multiname.namespace.getThroughDuplicate()) {
findPropName.namespace = findPropName.namespace.value;
}
}

View File

@@ -92,13 +92,13 @@ public class SetPropertyIns extends InstructionDefinition implements SetTypeIns
CompoundableBinaryOp binaryOp = (CompoundableBinaryOp) value.getNotCoerced();
if (binaryOp.getLeftSide() instanceof GetLexAVM2Item) {
GetLexAVM2Item getLex = (GetLexAVM2Item) binaryOp.getLeftSide();
if ((obj instanceof FindPropertyAVM2Item) && localData.abc.constants.getMultiname(multiname.multinameIndex).equals(getLex.propertyName)) {
if ((obj.getThroughDuplicate() instanceof FindPropertyAVM2Item) && localData.abc.constants.getMultiname(multiname.multinameIndex).equals(getLex.propertyName)) {
result.setCompoundValue(binaryOp.getRightSide());
result.setCompoundOperator(binaryOp.getOperator());
}
} else if (binaryOp.getLeftSide() instanceof GetPropertyAVM2Item) {
GetPropertyAVM2Item propItem = (GetPropertyAVM2Item) binaryOp.getLeftSide();
if (Objects.equals(obj, propItem.object.getThroughDuplicate()) && Objects.equals(multiname, propItem.propertyName)) {
if (Objects.equals(obj.getThroughDuplicate(), propItem.object.getThroughDuplicate()) && Objects.equals(multiname, propItem.propertyName)) {
result.setCompoundValue(binaryOp.getRightSide());
result.setCompoundOperator(binaryOp.getOperator());
}

View File

@@ -23,9 +23,12 @@ import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea;
import com.jpexs.decompiler.flash.abc.avm2.graph.AVM2GraphTargetDialect;
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.NewActivationAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.clauses.ExceptionAVM2Item;
import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.TranslateStack;
import com.jpexs.decompiler.graph.model.DuplicateItem;
import com.jpexs.decompiler.graph.model.DuplicateSourceItem;
import java.util.List;
/**
@@ -52,8 +55,14 @@ public class DupIns extends InstructionDefinition {
@Override
public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List<GraphTargetItem> output, String path) {
GraphTargetItem v = stack.pop();
stack.push(v);
GraphTargetItem v = stack.pop();
if (v instanceof NewActivationAVM2Item
|| v instanceof ExceptionAVM2Item) {
stack.push(v);
} else {
stack.push(new DuplicateSourceItem(AVM2GraphTargetDialect.INSTANCE, ins, localData.lineStartInstruction, v));
}
//stack.push(v);
stack.push(new DuplicateItem(AVM2GraphTargetDialect.INSTANCE, ins, localData.lineStartInstruction, v));
//v.moreSrc.add(new GraphSourceItemPos(ins, 0));

View File

@@ -3860,6 +3860,8 @@ public class Graph {
GraphTargetItem rightSide = ((PushItem) filteredOnTrue.get(filteredOnTrue.size() - 1)).value;
GraphTargetItem prevExpr = stack.pop();
GraphTargetItem leftSide = expr.getNotCoercedNoDup();
prevExpr = prevExpr.getThroughDuplicate();
boolean hideEmptyTrueFalse = true;

View File

@@ -0,0 +1,141 @@
/*
* Copyright (C) 2010-2025 JPEXS, All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
*/
package com.jpexs.decompiler.graph.model;
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
import com.jpexs.decompiler.graph.CompilationException;
import com.jpexs.decompiler.graph.GraphSourceItem;
import com.jpexs.decompiler.graph.GraphTargetDialect;
import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.SimpleValue;
import com.jpexs.decompiler.graph.SourceGenerator;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
/**
* Duplicate item.
*
* @author JPEXS
*/
public class DuplicateSourceItem extends GraphTargetItem implements SimpleValue {
/**
* Constructor.
*
* @param dialect Dialect
* @param src Source
* @param lineStartIns Line start item
* @param value Value
*/
public DuplicateSourceItem(GraphTargetDialect dialect, GraphSourceItem src, GraphSourceItem lineStartIns, GraphTargetItem value) {
super(dialect, src, lineStartIns, value.getPrecedence(), value);
}
@Override
public Object getResult() {
return value.getResult();
}
@Override
public Double getResultAsNumber() {
return value.getResultAsNumber();
}
@Override
public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException {
/*if (!value.hasSideEffect() || !Configuration.displayDupInstructions.get()) {
return value.appendTry(writer, localData);
}*/
writer.append("§§dupsrc(");
value.appendTry(writer, localData);
return writer.append(")");
}
@Override
public GraphTargetItem getNotCoerced() {
return value.getNotCoerced();
}
@Override
public GraphTargetItem getNotCoercedNoDup() {
return this;
}
@Override
public GraphTargetItem getThroughRegister() {
return value.getThroughRegister();
}
@Override
public GraphTargetItem getThroughDuplicate() {
return value.getThroughDuplicate();
}
@Override
public boolean isCompileTime(Set<GraphTargetItem> dependencies) {
if (dependencies.contains(value)) {
return false;
}
if (!((value instanceof SimpleValue) && ((SimpleValue) value).isSimpleValue())) {
dependencies.add(value);
}
return value.isCompileTime(dependencies);
}
@Override
public boolean isVariableComputed() {
return value.isVariableComputed();
}
@Override
public List<GraphSourceItem> toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException {
return new ArrayList<>();
}
@Override
public boolean hasReturnValue() {
return true;
}
@Override
public GraphTargetItem simplify(String implicitCoerce) {
return this;
}
@Override
public GraphTargetItem returnType() {
return value.returnType();
}
/*@Override
public GraphTargetItem invert(GraphSourceItem src) {
return //new DuplicateItem(src, value instanceof NotItem ? (value.value) : new NotItem(src, value));
}*/
@Override
public boolean isSimpleValue() {
return ((value instanceof SimpleValue) && ((SimpleValue) value).isSimpleValue());
}
@Override
public boolean hasSideEffect() {
return value.hasSideEffect();
}
}