Fixed tests.

This commit is contained in:
Jindra Petřík
2025-08-02 19:19:28 +02:00
parent 95b7abb9bc
commit 922cd45084
27 changed files with 168 additions and 124 deletions

View File

@@ -45,6 +45,7 @@ import com.jpexs.decompiler.graph.DottedChain;
import com.jpexs.decompiler.graph.GraphTargetItem;
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 java.util.List;
@@ -107,10 +108,20 @@ public abstract class GetLocalTypeIns extends InstructionDefinition {
//computedValue = new NotCompileTimeItem(ins, localData.lineStartInstruction, computedValue);
}
GraphTargetItem type = TypeItem.UNBOUNDED;
if (localData.localRegTypes.containsKey(regId)) {
type = localData.localRegTypes.get(regId);
} else if (computedValue != null) {
type = computedValue.returnType();
}
stack.push(new LocalRegAVM2Item(ins, localData.lineStartInstruction, regId, computedValue, type));
//chained assignments and/or ASC post/pre increment
if (!output.isEmpty()) {
if ((output.get(output.size() - 1) instanceof SetTypeAVM2Item)) {
GraphTargetItem setItem = output.get(output.size() - 1);
if (stack.peek() instanceof CommaExpressionItem) {
CommaExpressionItem ce = (CommaExpressionItem) stack.peek();
if (ce.commands.size() == 2 && ce.commands.get(0) instanceof SetTypeAVM2Item) {
GraphTargetItem setItem = ce.commands.get(0);
if ((setItem instanceof SetPropertyAVM2Item)
&& ((setItem.value.getNotCoerced() instanceof DecrementAVM2Item)
|| (setItem.value.getNotCoerced() instanceof IncrementAVM2Item))) {
@@ -133,9 +144,10 @@ public abstract class GetLocalTypeIns extends InstructionDefinition {
} else {
result = new PostDecrementAVM2Item(setProp.getSrc(), localData.lineStartInstruction, getProp);
}
output.remove(output.size() - 1);
stack.moveToStack(output);
stack.add(result);
//output.remove(output.size() - 1);
//stack.moveToStack(output);
stack.pop();
stack.push(result);
return;
}
}
@@ -153,6 +165,53 @@ public abstract class GetLocalTypeIns extends InstructionDefinition {
setItem.value = setLocal.value;
}
//output.remove(output.size() - 1);
//stack.moveToStack(output);
stack.pop();
if (setItem instanceof SetPropertyAVM2Item) {
if ((setItem.value instanceof IncrementAVM2Item) || (setItem.value instanceof DecrementAVM2Item)) {
boolean isIncrement = (setItem.value instanceof IncrementAVM2Item);
if (setItem.value.value instanceof GetPropertyAVM2Item) {
SetPropertyAVM2Item setProp = (SetPropertyAVM2Item) setItem;
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) {
getProp.object = getProp.object.value;
}
if (isIncrement) {
setItem = new PreIncrementAVM2Item(setProp.getSrc(), localData.lineStartInstruction, getProp);
} else {
setItem = new PreDecrementAVM2Item(setProp.getSrc(), localData.lineStartInstruction, getProp);
}
}
}
}
}
}
stack.push(setItem);
return;
}
}
}
}
} else 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) {
int setLocalIp = localData.code.adr2pos(setLocal.getSrc().getAddress());
if (localData.getSetLocalUsages(setLocalIp).size() == 1) {
if ((setItem.value instanceof CoerceAVM2Item) || (setItem.value instanceof ConvertAVM2Item)) {
setItem.value.value = setLocal.value;
} else {
setItem.value = setLocal.value;
}
stack.pop();
output.remove(output.size() - 1);
stack.moveToStack(output);
@@ -185,14 +244,8 @@ public abstract class GetLocalTypeIns extends InstructionDefinition {
}
}
}
GraphTargetItem type = TypeItem.UNBOUNDED;
if (localData.localRegTypes.containsKey(regId)) {
type = localData.localRegTypes.get(regId);
} else if (computedValue != null) {
type = computedValue.returnType();
}
stack.push(new LocalRegAVM2Item(ins, localData.lineStartInstruction, regId, computedValue, type));
}
@Override

View File

@@ -238,13 +238,7 @@ public class CallAVM2Item extends AVM2Item {
if (a > 0) {
writer.allowWrapHere().append(",");
}
if (arguments.get(a).getPrecedence() >= PRECEDENCE_COMMA) {
writer.append("(");
}
arguments.get(a).toString(writer, localData);
if (arguments.get(a).getPrecedence() >= PRECEDENCE_COMMA) {
writer.append(")");
}
}
return writer.append(")");
}

View File

@@ -85,13 +85,7 @@ public class CallMethodAVM2Item extends AVM2Item {
if (a > 0) {
writer.allowWrapHere().append(",");
}
if (arguments.get(a).getPrecedence() >= PRECEDENCE_COMMA) {
writer.append("(");
}
arguments.get(a).toString(writer, localData);
if (arguments.get(a).getPrecedence() >= PRECEDENCE_COMMA) {
writer.append(")");
}
}
return writer.append(")");
}

View File

@@ -104,13 +104,7 @@ public class CallPropertyAVM2Item extends AVM2Item {
if (a > 0) {
writer.allowWrapHere().append(",");
}
if (arguments.get(a).getPrecedence() >= PRECEDENCE_COMMA) {
writer.append("(");
}
arguments.get(a).toString(writer, localData);
if (arguments.get(a).getPrecedence() >= PRECEDENCE_COMMA) {
writer.append(")");
}
}
return writer.append(")");
}

View File

@@ -86,13 +86,7 @@ public class CallStaticAVM2Item extends AVM2Item {
if (a > 0) {
writer.append(",");
}
if (arguments.get(a).getPrecedence() >= PRECEDENCE_COMMA) {
writer.append("(");
}
arguments.get(a).toString(writer, localData);
if (arguments.get(a).getPrecedence() >= PRECEDENCE_COMMA) {
writer.append(")");
}
}
return writer.append(")");
}

View File

@@ -91,13 +91,7 @@ public class CallSuperAVM2Item extends AVM2Item {
if (a > 0) {
writer.append(",");
}
if (arguments.get(a).getPrecedence() >= PRECEDENCE_COMMA) {
writer.append("(");
}
arguments.get(a).toString(writer, localData);
if (arguments.get(a).getPrecedence() >= PRECEDENCE_COMMA) {
writer.append(")");
}
}
return writer.append(")");
}

View File

@@ -127,13 +127,7 @@ public class ConstructAVM2Item extends AVM2Item {
if (a > 0) {
writer.allowWrapHere().append(",");
}
if (args.get(a).getPrecedence() >= PRECEDENCE_COMMA) {
writer.append("(");
}
args.get(a).toString(writer, localData);
if (args.get(a).getPrecedence() >= PRECEDENCE_COMMA) {
writer.append(")");
}
}
return writer.append(")");
}

View File

@@ -125,13 +125,7 @@ public class ConstructPropAVM2Item extends AVM2Item {
if (a > 0) {
writer.allowWrapHere().append(",");
}
if (args.get(a).getPrecedence() >= PRECEDENCE_COMMA) {
writer.append("(");
}
args.get(a).toString(writer, localData);
if (args.get(a).getPrecedence() >= PRECEDENCE_COMMA) {
writer.append(")");
}
}
return writer.append(")");
}

View File

@@ -79,13 +79,7 @@ public class ConstructSuperAVM2Item extends AVM2Item {
if (a > 0) {
writer.allowWrapHere().append(",");
}
if (args.get(a).getPrecedence() >= PRECEDENCE_COMMA) {
writer.append("(");
}
args.get(a).toString(writer, localData);
if (args.get(a).getPrecedence() >= PRECEDENCE_COMMA) {
writer.append(")");
}
}
return writer.append(")");
}

View File

@@ -65,7 +65,7 @@ public class FilterAVM2Item extends AVM2Item {
public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException {
collection.toString(writer, localData);
writer.append(".(");
expression.toStringBoolean(writer, localData);
expression.toString(writer, localData, "Boolean", true);
return writer.append(")");
}

View File

@@ -79,6 +79,6 @@ public class BitNotAVM2Item extends UnaryOpItem {
return;
}
}
operand.toString(writer, localData, "");
operand.toString(writer, localData, "", false);
}
}

View File

@@ -61,6 +61,6 @@ public abstract class BitwiseBinaryOpAVM2Item extends BinaryOpItem implements Co
return;
}
}
operand.toString(writer, localData, "");
operand.toString(writer, localData, "", false);
}
}

View File

@@ -61,6 +61,6 @@ public abstract class BitwiseBinaryOpActionItem extends BinaryOpItem implements
return;
}
}
operand.toString(writer, localData, "");
operand.toString(writer, localData, "", false);
}
}

View File

@@ -80,10 +80,10 @@ public class SubtractActionItem extends BinaryOpItem implements CompoundableBina
int rightPrecedence = rightSide.getPrecedence();
if (rightPrecedence >= precedence && rightPrecedence != GraphTargetItem.NOPRECEDENCE) {
writer.append("(");
rightSide.toString(writer, localData, coerceRight);
rightSide.toString(writer, localData, coerceRight, false);
writer.append(")");
} else {
rightSide.toString(writer, localData, coerceRight);
rightSide.toString(writer, localData, coerceRight, false);
}
return writer;
} else if (rightSide.getPrecedence() >= precedence) { // >= add or subtract too

View File

@@ -2390,6 +2390,7 @@ public class Graph {
*/
protected final void translatePart(List<GraphTargetItem> output, BaseLocalData localData, GraphPart part, TranslateStack stack, int staticOperation, String path) throws InterruptedException, GraphPartChangeException {
List<GraphPart> sub = part.getSubParts();
stack.setConnectedOutput(0, output);
int end;
for (GraphPart p : sub) {
if (p.end == -1) {

View File

@@ -384,8 +384,8 @@ public abstract class GraphTargetItem implements Serializable, Cloneable {
* @return Writer
* @throws InterruptedException On interrupt
*/
public GraphTextWriter toStringBoolean(GraphTextWriter writer, LocalData localData) throws InterruptedException {
return toString(writer, localData, "Boolean");
public final GraphTextWriter toStringBoolean(GraphTextWriter writer, LocalData localData) throws InterruptedException {
return toString(writer, localData, "Boolean", false);
}
/**
@@ -396,8 +396,8 @@ public abstract class GraphTargetItem implements Serializable, Cloneable {
* @return Writer
* @throws InterruptedException On interrupt
*/
public GraphTextWriter toStringString(GraphTextWriter writer, LocalData localData) throws InterruptedException {
return toString(writer, localData, "String");
public final GraphTextWriter toStringString(GraphTextWriter writer, LocalData localData) throws InterruptedException {
return toString(writer, localData, "String", false);
}
/**
@@ -408,8 +408,8 @@ public abstract class GraphTargetItem implements Serializable, Cloneable {
* @return Writer
* @throws InterruptedException On interrupt
*/
public GraphTextWriter toStringInt(GraphTextWriter writer, LocalData localData) throws InterruptedException {
return toString(writer, localData, "int");
public final GraphTextWriter toStringInt(GraphTextWriter writer, LocalData localData) throws InterruptedException {
return toString(writer, localData, "int", false);
}
/**
@@ -420,8 +420,8 @@ public abstract class GraphTargetItem implements Serializable, Cloneable {
* @return Writer
* @throws InterruptedException On interrupt
*/
public GraphTextWriter toStringNumber(GraphTextWriter writer, LocalData localData) throws InterruptedException {
return toString(writer, localData, "Number");
public final GraphTextWriter toStringNumber(GraphTextWriter writer, LocalData localData) throws InterruptedException {
return toString(writer, localData, "Number", false);
}
/**
@@ -440,16 +440,17 @@ public abstract class GraphTargetItem implements Serializable, Cloneable {
* @param writer Writer
* @param localData Local data
* @param implicitCoerce Implicit coerce
* @param noParenthesis Do not use parenthesis
* @return Writer
* @throws InterruptedException On interrupt
*/
public GraphTextWriter toString(GraphTextWriter writer, LocalData localData, String implicitCoerce) throws InterruptedException {
public GraphTextWriter toString(GraphTextWriter writer, LocalData localData, String implicitCoerce, boolean noParenthesis) throws InterruptedException {
if (CancellableWorker.isInterrupted()) {
throw new InterruptedException();
}
writer.startOffset(src, getLineStartItem(), getPos(), srcData);
appendTry(writer, localData, implicitCoerce);
appendTry(writer, localData, implicitCoerce, noParenthesis);
writer.endOffset();
return writer;
}
@@ -463,7 +464,7 @@ public abstract class GraphTargetItem implements Serializable, Cloneable {
* @throws InterruptedException On interrupt
*/
public GraphTextWriter toString(GraphTextWriter writer, LocalData localData) throws InterruptedException {
return toString(writer, localData, "");
return toString(writer, localData, "", false);
}
/**
@@ -489,6 +490,18 @@ public abstract class GraphTargetItem implements Serializable, Cloneable {
* @throws InterruptedException On interrupt
*/
public abstract GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException;
/**
* Append this to a writer, ignoring parenthesis (in CommaExpression and/or Parenthesis)
*
* @param writer Writer
* @param localData Local data
* @return Writer
* @throws InterruptedException On interrupt
*/
public GraphTextWriter appendNoParenthesis(GraphTextWriter writer, LocalData localData) throws InterruptedException {
return appendTo(writer, localData);
}
/**
* Append this to a writer.
@@ -499,7 +512,7 @@ public abstract class GraphTargetItem implements Serializable, Cloneable {
* @throws InterruptedException On interrupt
*/
public GraphTextWriter appendTry(GraphTextWriter writer, LocalData localData) throws InterruptedException {
return appendTry(writer, localData, "");
return appendTry(writer, localData, "", false);
}
/**
@@ -511,7 +524,7 @@ public abstract class GraphTargetItem implements Serializable, Cloneable {
* @return Writer
* @throws InterruptedException On interrupt
*/
public GraphTextWriter appendTry(GraphTextWriter writer, LocalData localData, String implicitCoerce) throws InterruptedException {
public GraphTextWriter appendTry(GraphTextWriter writer, LocalData localData, String implicitCoerce, boolean noParenthesis) throws InterruptedException {
GraphTargetItem t = this;
if (!implicitCoerce.isEmpty()) { //if implicit coerce equals explicit
/*if (t instanceof ConvertAVM2Item) {
@@ -535,6 +548,9 @@ public abstract class GraphTargetItem implements Serializable, Cloneable {
if (!implicitCoerce.isEmpty() && Configuration.simplifyExpressions.get()) {
t = t.simplify(implicitCoerce);
}
if (noParenthesis) {
return t.appendNoParenthesis(writer, localData);
}
return t.appendTo(writer, localData);
}
@@ -1124,5 +1140,5 @@ public abstract class GraphTargetItem implements Serializable, Cloneable {
}
}
return o1.equals(o2);
}
}
}

View File

@@ -16,6 +16,7 @@
*/
package com.jpexs.decompiler.graph;
import com.jpexs.decompiler.flash.abc.avm2.model.FindPropertyAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.NewActivationAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.clauses.ExceptionAVM2Item;
import com.jpexs.decompiler.graph.model.BranchStackResistant;
@@ -82,9 +83,13 @@ public class TranslateStack extends Stack<GraphTargetItem> {
@Override
public GraphTargetItem push(GraphTargetItem item) {
if (!outputQueue.isEmpty()) {
outputQueue.add(item);
item = new CommaExpressionItem(item.dialect, null, item.lineStartItem, outputQueue);
outputQueue = new ArrayList<>();
if (item instanceof FindPropertyAVM2Item) {
finishBlock(connectedOutput);
} else {
outputQueue.add(item);
item = new CommaExpressionItem(item.dialect, null, item.lineStartItem, outputQueue);
outputQueue = new ArrayList<>();
}
}
if (connectedOutput != null && item != null) {
item.outputPos = prevOutputSize + connectedOutput.size();
@@ -288,13 +293,14 @@ public class TranslateStack extends Stack<GraphTargetItem> {
continue;
}
output.add(pos, beforeExit ? item : new PushItem(item));
}*/
output.addAll(outputQueue);
outputQueue.clear();
}*/
int clen = output.size();
boolean isExit = false;
if (!outputQueue.isEmpty() && outputQueue.get(outputQueue.size() - 1) instanceof ExitItem) {
isExit = true;
}
if (clen > 0) {
if (output.get(clen - 1) instanceof ScriptEndItem) {
clen--;
@@ -337,7 +343,10 @@ public class TranslateStack extends Stack<GraphTargetItem> {
output.add(clen, new PushItem(p));
}
}
}
}
output.addAll(outputQueue);
outputQueue.clear();
}
public void allowSwap(List<GraphTargetItem> output) {

View File

@@ -140,7 +140,7 @@ public abstract class BinaryOpItem extends GraphTargetItem implements BinaryOp {
* @throws InterruptedException On interrupt
*/
protected void operandToString(GraphTargetItem operand, GraphTextWriter writer, LocalData localData) throws InterruptedException {
operand.toString(writer, localData, "");
operand.toString(writer, localData, "", false);
}
@Override

View File

@@ -59,6 +59,17 @@ public class CommaExpressionItem extends GraphTargetItem {
@Override
public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException {
if (commands.isEmpty()) {
return writer;
}
writer.append("(");
appendNoParenthesis(writer, localData);
writer.append(")");
return writer;
}
@Override
public GraphTextWriter appendNoParenthesis(GraphTextWriter writer, LocalData localData) throws InterruptedException {
boolean first = true;
for (GraphTargetItem t : commands) {
if (t.isEmpty()) {
@@ -72,6 +83,8 @@ public class CommaExpressionItem extends GraphTargetItem {
}
return writer;
}
@Override
public List<GraphSourceItem> toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException {

View File

@@ -98,13 +98,18 @@ public class NotItem extends UnaryOpItem implements LogicalOpItem, Inverted {
}
@Override
public GraphTextWriter toStringBoolean(GraphTextWriter writer, LocalData localData) throws InterruptedException {
//Skip explicit conversion to boolean, it is not needed, it is done implicitly
if (value instanceof NotItem) {
return value.value.toStringBoolean(writer, localData);
public GraphTextWriter toString(GraphTextWriter writer, LocalData localData, String implicitCoerce, boolean noParenthesis) throws InterruptedException {
if ("Boolean".equals(implicitCoerce)) {
//Skip explicit conversion to boolean, it is not needed, it is done implicitly
if (value instanceof NotItem) {
return value.value.toStringBoolean(writer, localData);
}
}
return super.toStringBoolean(writer, localData);
return super.toString(writer, localData, implicitCoerce, noParenthesis);
}
@Override
public GraphTargetItem invert(GraphSourceItem src) {

View File

@@ -47,10 +47,17 @@ public class ParenthesisItem extends GraphTargetItem {
@Override
public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException {
writer.append("(");
value.toString(writer, localData);
appendNoParenthesis(writer, localData);
return writer.append(")");
}
@Override
public GraphTextWriter appendNoParenthesis(GraphTextWriter writer, LocalData localData) throws InterruptedException {
value.toString(writer, localData);
return writer;
}
@Override
public List<GraphSourceItem> toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException {
return value.toSource(localData, generator);

View File

@@ -151,7 +151,7 @@ public class SwitchItem extends LoopItem implements Block {
if (!(caseValues.get(k) instanceof DefaultItem)) {
writer.append("case ");
}
caseValues.get(k).toString(writer, localData);
caseValues.get(k).toString(writer, localData, "", true);
writer.append(":").newLine();
}
}

View File

@@ -79,7 +79,7 @@ public class TernarOpItem extends GraphTargetItem {
if (expression.getPrecedence() >= precedence) {
writer.append("(");
}
expression.toStringBoolean(writer, localData);
expression.toString(writer, localData, "Boolean", true);
if (expression.getPrecedence() >= precedence) {
writer.append(")");
}
@@ -88,7 +88,7 @@ public class TernarOpItem extends GraphTargetItem {
if (onTrue.getPrecedence() >= precedence && onTrue.getPrecedence() != GraphTargetItem.NOPRECEDENCE) { // >= ternar in ternar better in parenthesis
writer.append("(");
}
onTrue.toString(writer, localData);
onTrue.toString(writer, localData, "", true);
if (onTrue.getPrecedence() >= precedence && onTrue.getPrecedence() != GraphTargetItem.NOPRECEDENCE) {
writer.append(")");
}
@@ -96,7 +96,7 @@ public class TernarOpItem extends GraphTargetItem {
if (onFalse.getPrecedence() >= precedence && onFalse.getPrecedence() != GraphTargetItem.NOPRECEDENCE) {
writer.append("(");
}
onFalse.toString(writer, localData);
onFalse.toString(writer, localData, "", true);
if (onFalse.getPrecedence() >= precedence && onFalse.getPrecedence() != GraphTargetItem.NOPRECEDENCE) {
writer.append(")");
}

View File

@@ -178,6 +178,6 @@ public abstract class UnaryOpItem extends GraphTargetItem implements UnaryOp {
* @throws InterruptedException On interrupt
*/
protected void operandToString(GraphTargetItem operand, GraphTextWriter writer, LocalData localData) throws InterruptedException {
operand.toString(writer, localData, "");
operand.toString(writer, localData, "", false);
}
}