Better Comma operator detection WIP

This commit is contained in:
Jindra Petřík
2025-08-02 09:35:03 +02:00
parent b3a693e4e3
commit 9a9811f170
36 changed files with 166 additions and 135 deletions

View File

@@ -3823,6 +3823,7 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
break;
}
stack.setConnectedOutput(0, output);
ins.translate(localData, stack, output, staticOperation, path);
if (ins.isExit()) {
break;

View File

@@ -236,6 +236,7 @@ public class AVM2DeobfuscatorGetSet extends SWFDecompilerAdapter {
return;
}
stack.setConnectedOutput(0, output);
ins.translate(localData, stack, output, 0, "");
}

View File

@@ -326,6 +326,7 @@ public class AVM2DeobfuscatorRegistersOld extends AVM2DeobfuscatorSimpleOld {
continue outer;
}
stack.setConnectedOutput(0, output);
ins.translate(localData, stack, output, 0, "");
if (def instanceof SetLocalTypeIns) {
int regId = ((SetLocalTypeIns) def).getRegisterId(ins);

View File

@@ -370,6 +370,7 @@ public class AVM2DeobfuscatorSimpleOld extends AVM2DeobfuscatorZeroJumpsNullPush
}
}
stack.setConnectedOutput(0, output);
ins.translate(localData, stack, output, 0, "");
}

View File

@@ -339,6 +339,7 @@ public class AVM2Graph extends Graph {
localData2.localScopeStack = new ScopeStack();
List<GraphTargetItem> targetOutput = new GraphPartMarkedArrayList<>();
finallyTryTargetStack.setConnectedOutput(0, targetOutput);
try {
translatePart(targetOutput, localData2, finallyTryTargetPart, finallyTryTargetStack, 0 /*??*/, "try_target");
} catch (GraphPartChangeException ex1) { //should not happen
@@ -1249,6 +1250,7 @@ public class AVM2Graph extends Graph {
el.phase = 4; //Special case: try inside loop. 4 is immediately switched back to 1 inside printGraph
}
}
stack = (TranslateStack) stack.clone();
tryCommands = printGraph(foundGotos, partCodes, partCodePos, visited, localData, stack, allParts, null, part, stopPart2, stopPartKind2, loops, throwStates, staticOperation, path);
}
@@ -1427,6 +1429,7 @@ public class AVM2Graph extends Graph {
}
List<GraphTargetItem> currentCatchCommands = printGraph(foundGotos, partCodes, partCodePos, visited, localData2, st2, allParts, null, catchPart, stopPart2, stopPartKind2, loops, throwStates, staticOperation, path);
st2.finishBlock(currentCatchCommands);
/*if (!currentCatchCommands.isEmpty() && (currentCatchCommands.get(0) instanceof SetLocalAVM2Item)) {
if (currentCatchCommands.get(0).value.getNotCoerced() instanceof ExceptionAVM2Item) {
currentCatchCommands.remove(0);

View File

@@ -606,19 +606,18 @@ public abstract class InstructionDefinition implements Serializable {
if (value.value.getNotCoercedNoDup() instanceof GetLexAVM2Item) {
GetLexAVM2Item getLex = (GetLexAVM2Item) value.value.getNotCoercedNoDup();
if (localData.abc.constants.getMultiname(multinameIndex).equals(getLex.propertyName)
&& (obj instanceof FindPropertyAVM2Item)) {
stack.moveToOutput(output, false);
&& (obj instanceof FindPropertyAVM2Item)) {
if (hasConvert) {
if (isIncrement) {
output.add(new PostIncrementAVM2Item(ins, localData.lineStartInstruction, getLex));
stack.addToOutput(new PostIncrementAVM2Item(ins, localData.lineStartInstruction, getLex));
} else {
output.add(new PostDecrementAVM2Item(ins, localData.lineStartInstruction, getLex));
stack.addToOutput(new PostDecrementAVM2Item(ins, localData.lineStartInstruction, getLex));
}
} else {
if (isIncrement) {
output.add(new PreIncrementAVM2Item(ins, localData.lineStartInstruction, getLex));
stack.addToOutput(new PreIncrementAVM2Item(ins, localData.lineStartInstruction, getLex));
} else {
output.add(new PreDecrementAVM2Item(ins, localData.lineStartInstruction, getLex));
stack.addToOutput(new PreDecrementAVM2Item(ins, localData.lineStartInstruction, getLex));
}
}
return;
@@ -635,18 +634,17 @@ public abstract class InstructionDefinition implements Serializable {
}
}
if (Objects.equals(getProp.object, obj)) {
stack.moveToOutput(output, false);
if (hasConvert) {
if (isIncrement) {
output.add(new PostIncrementAVM2Item(ins, localData.lineStartInstruction, getProp));
stack.addToOutput(new PostIncrementAVM2Item(ins, localData.lineStartInstruction, getProp));
} else {
output.add(new PostDecrementAVM2Item(ins, localData.lineStartInstruction, getProp));
stack.addToOutput(new PostDecrementAVM2Item(ins, localData.lineStartInstruction, getProp));
}
} else {
if (isIncrement) {
output.add(new PreIncrementAVM2Item(ins, localData.lineStartInstruction, getProp));
stack.addToOutput(new PreIncrementAVM2Item(ins, localData.lineStartInstruction, getProp));
} else {
output.add(new PreDecrementAVM2Item(ins, localData.lineStartInstruction, getProp));
stack.addToOutput(new PreDecrementAVM2Item(ins, localData.lineStartInstruction, getProp));
}
}
return;

View File

@@ -90,8 +90,7 @@ public interface SetTypeIns {
value = insideDup;
}
result.value = value;
stack.moveToOutput(output, false);
output.add(result);
stack.addToOutput(result);
for (int i = 0; i < numDups; i++) {
stack.push(new LocalRegAVM2Item(null, localData.lineStartInstruction, regId, value, localData.localRegTypes.containsKey(regId) ? localData.localRegTypes.get(regId) : value.returnType()));
}
@@ -111,8 +110,7 @@ public interface SetTypeIns {
}
if (regId > -1 && AVM2Item.mustStayIntact2(insideDup.getNotCoerced())) { //hack
stack.moveToOutput(output, false);
output.add(result);
stack.addToOutput(result);
stack.push(new LocalRegAVM2Item(null, localData.lineStartInstruction, regId, value, localData.localRegTypes.containsKey(regId) ? localData.localRegTypes.get(regId) : TypeItem.UNBOUNDED));
return;
}
@@ -123,7 +121,6 @@ public interface SetTypeIns {
}
}
}
stack.moveToOutput(output, false);
output.add(result);
stack.addToOutput(result);
}
}

View File

@@ -62,8 +62,7 @@ public class Sf32Ins extends InstructionDefinition implements AlchemyTypeIns {
public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List<GraphTargetItem> output, String path) {
GraphTargetItem ofs = stack.pop();
GraphTargetItem value = stack.pop();
stack.moveToOutput(output, false);
output.add(new AlchemyStoreAVM2Item(ins, localData.lineStartInstruction, value, ofs, "f", 32));
stack.addToOutput(new AlchemyStoreAVM2Item(ins, localData.lineStartInstruction, value, ofs, "f", 32));
}
@Override

View File

@@ -62,8 +62,7 @@ public class Sf64Ins extends InstructionDefinition implements AlchemyTypeIns {
public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List<GraphTargetItem> output, String path) {
GraphTargetItem ofs = stack.pop();
GraphTargetItem value = stack.pop();
stack.moveToOutput(output, false);
output.add(new AlchemyStoreAVM2Item(ins, localData.lineStartInstruction, value, ofs, "f", 64));
stack.addToOutput(new AlchemyStoreAVM2Item(ins, localData.lineStartInstruction, value, ofs, "f", 64));
}
@Override

View File

@@ -62,8 +62,7 @@ public class Si16Ins extends InstructionDefinition implements AlchemyTypeIns {
public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List<GraphTargetItem> output, String path) {
GraphTargetItem ofs = stack.pop();
GraphTargetItem value = stack.pop();
stack.moveToOutput(output, false);
output.add(new AlchemyStoreAVM2Item(ins, localData.lineStartInstruction, value, ofs, "i", 16));
stack.addToOutput(new AlchemyStoreAVM2Item(ins, localData.lineStartInstruction, value, ofs, "i", 16));
}
@Override

View File

@@ -62,8 +62,7 @@ public class Si32Ins extends InstructionDefinition implements AlchemyTypeIns {
public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List<GraphTargetItem> output, String path) {
GraphTargetItem ofs = stack.pop();
GraphTargetItem value = stack.pop();
stack.moveToOutput(output, false);
output.add(new AlchemyStoreAVM2Item(ins, localData.lineStartInstruction, value, ofs, "i", 32));
stack.addToOutput(new AlchemyStoreAVM2Item(ins, localData.lineStartInstruction, value, ofs, "i", 32));
}
@Override

View File

@@ -62,8 +62,7 @@ public class Si8Ins extends InstructionDefinition implements AlchemyTypeIns {
public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List<GraphTargetItem> output, String path) {
GraphTargetItem ofs = stack.pop();
GraphTargetItem value = stack.pop();
stack.moveToOutput(output, false);
output.add(new AlchemyStoreAVM2Item(ins, localData.lineStartInstruction, value, ofs, "i", 8));
stack.addToOutput(new AlchemyStoreAVM2Item(ins, localData.lineStartInstruction, value, ofs, "i", 8));
}
@Override

View File

@@ -72,8 +72,7 @@ public class ConstructSuperIns extends InstructionDefinition {
args.add(0, stack.pop());
}
GraphTargetItem obj = stack.pop();
stack.moveToOutput(output, false);
output.add(new ConstructSuperAVM2Item(ins, localData.lineStartInstruction, obj, args));
stack.addToOutput(new ConstructSuperAVM2Item(ins, localData.lineStartInstruction, obj, args));
}
@Override

View File

@@ -89,8 +89,7 @@ public class CallPropVoidIns extends InstructionDefinition {
Reference<GraphTargetItem> type = new Reference<>(null);
Reference<GraphTargetItem> callType = new Reference<>(null);
GetPropertyIns.resolvePropertyType(localData, obj, multiname, isStatic, type, callType);
stack.moveToOutput(output, false);
output.add(new CallPropertyAVM2Item(ins, localData.lineStartInstruction, true, obj, multiname, args, callType.getVal(), isStatic.getVal()));
stack.addToOutput(new CallPropertyAVM2Item(ins, localData.lineStartInstruction, true, obj, multiname, args, callType.getVal(), isStatic.getVal()));
}
@Override

View File

@@ -82,8 +82,7 @@ public class CallSuperVoidIns extends InstructionDefinition {
FullMultinameAVM2Item multiname = resolveMultiname(localData, true, stack, localData.getConstants(), multinameIndex, ins, output);
GraphTargetItem receiver = stack.pop();
stack.moveToOutput(output, false);
output.add(new CallSuperAVM2Item(ins, localData.lineStartInstruction, true, receiver, multiname, args));
stack.addToOutput(new CallSuperAVM2Item(ins, localData.lineStartInstruction, true, receiver, multiname, args));
}
@Override

View File

@@ -73,8 +73,7 @@ public class DecLocalIIns extends InstructionDefinition {
}
}
if (!isPostDec) {
stack.moveToOutput(output, false);
output.add(new DecLocalAVM2Item(ins, localData.lineStartInstruction, regId));
stack.addToOutput(new DecLocalAVM2Item(ins, localData.lineStartInstruction, regId));
}
if (localData.localRegs.containsKey(regId)) {
localData.localRegs.put(regId, new SubtractAVM2Item(ins, localData.lineStartInstruction, localData.localRegs.get(regId), new IntegerValueAVM2Item(ins, localData.lineStartInstruction, 1)));

View File

@@ -74,8 +74,7 @@ public class DecLocalIns extends InstructionDefinition {
}
}
if (!isPostDec) {
stack.moveToOutput(output, false);
output.add(new DecLocalAVM2Item(ins, localData.lineStartInstruction, regId));
stack.addToOutput(new DecLocalAVM2Item(ins, localData.lineStartInstruction, regId));
}
if (localData.localRegs.containsKey(regId)) {
localData.localRegs.put(regId, new SubtractAVM2Item(ins, localData.lineStartInstruction, localData.localRegs.get(regId), new IntegerValueAVM2Item(ins, localData.lineStartInstruction, 1)));

View File

@@ -73,8 +73,7 @@ public class IncLocalIIns extends InstructionDefinition {
}
}
if (!isPostInc) {
stack.moveToOutput(output, false);
output.add(new IncLocalAVM2Item(ins, localData.lineStartInstruction, regId));
stack.addToOutput(new IncLocalAVM2Item(ins, localData.lineStartInstruction, regId));
}
if (localData.localRegs.containsKey(regId)) {
localData.localRegs.put(regId, new AddAVM2Item(ins, localData.lineStartInstruction, localData.localRegs.get(regId), new IntegerValueAVM2Item(ins, localData.lineStartInstruction, 1)));

View File

@@ -74,8 +74,7 @@ public class IncLocalIns extends InstructionDefinition {
}
}
if (!isPostInc) {
stack.moveToOutput(output, false);
output.add(new IncLocalAVM2Item(ins, localData.lineStartInstruction, regId));
stack.addToOutput(new IncLocalAVM2Item(ins, localData.lineStartInstruction, regId));
}
if (localData.localRegs.containsKey(regId)) {
localData.localRegs.put(regId, new AddAVM2Item(ins, localData.lineStartInstruction, localData.localRegs.get(regId), new IntegerValueAVM2Item(ins, localData.lineStartInstruction, 1)));

View File

@@ -83,8 +83,7 @@ public abstract class SetLocalTypeIns extends InstructionDefinition implements S
localData.localRegAssignmentIps.put(regId, localData.localRegAssignmentIps.get(regId) + 1);
//localRegsAssignmentIps.put(regId, ip);
if (value.getThroughDuplicate() instanceof NewActivationAVM2Item) {
stack.moveToOutput(output, false);
output.add(new StoreNewActivationAVM2Item(ins, localData.lineStartInstruction, regId));
stack.addToOutput(new StoreNewActivationAVM2Item(ins, localData.lineStartInstruction, regId));
return;
}
if (value instanceof FindPropertyAVM2Item) {
@@ -103,12 +102,10 @@ public abstract class SetLocalTypeIns extends InstructionDefinition implements S
stack.pop();
stack.push(new PreIncrementAVM2Item(ins, localData.lineStartInstruction, inside));
} else {
stack.moveToOutput(output, false);
output.add(new PostIncrementAVM2Item(ins, localData.lineStartInstruction, inside));
stack.addToOutput(new PostIncrementAVM2Item(ins, localData.lineStartInstruction, inside));
}
} else {
stack.moveToOutput(output, false);
output.add(new PostIncrementAVM2Item(ins, localData.lineStartInstruction, inside));
stack.addToOutput(new PostIncrementAVM2Item(ins, localData.lineStartInstruction, inside));
}
return;
}
@@ -128,12 +125,10 @@ public abstract class SetLocalTypeIns extends InstructionDefinition implements S
stack.pop();
stack.push(new PreDecrementAVM2Item(ins, localData.lineStartInstruction, inside));
} else {
stack.moveToOutput(output, false);
output.add(new PostDecrementAVM2Item(ins, localData.lineStartInstruction, inside));
stack.addToOutput(new PostDecrementAVM2Item(ins, localData.lineStartInstruction, inside));
}
} else {
stack.moveToOutput(output, false);
output.add(new PostDecrementAVM2Item(ins, localData.lineStartInstruction, inside));
stack.addToOutput(new PostDecrementAVM2Item(ins, localData.lineStartInstruction, inside));
}
return;
}

View File

@@ -55,8 +55,7 @@ public class ReturnValueIns extends InstructionDefinition {
if (value instanceof SetLocalAVM2Item) {
value = value.value;
}
stack.moveToOutput(output, true);
output.add(new ReturnValueAVM2Item(ins, localData.lineStartInstruction, value));
stack.addToOutput(new ReturnValueAVM2Item(ins, localData.lineStartInstruction, value));
}
@Override

View File

@@ -49,8 +49,7 @@ public class ReturnVoidIns extends InstructionDefinition {
@Override
public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List<GraphTargetItem> output, String path) {
stack.moveToOutput(output, true);
output.add(new ReturnVoidAVM2Item(ins, localData.lineStartInstruction));
stack.addToOutput(new ReturnVoidAVM2Item(ins, localData.lineStartInstruction));
}
@Override

View File

@@ -111,12 +111,10 @@ public class SetSlotIns extends InstructionDefinition implements SetTypeIns {
stack.pop();
stack.push(new PreIncrementAVM2Item(ins, localData.lineStartInstruction, inside));
} else {
stack.moveToOutput(output, false);
output.add(new PostIncrementAVM2Item(ins, localData.lineStartInstruction, inside));
stack.addToOutput(new PostIncrementAVM2Item(ins, localData.lineStartInstruction, inside));
}
} else {
stack.moveToOutput(output, false);
output.add(new PostIncrementAVM2Item(ins, localData.lineStartInstruction, inside));
stack.addToOutput(new PostIncrementAVM2Item(ins, localData.lineStartInstruction, inside));
}
return;
}
@@ -139,12 +137,10 @@ public class SetSlotIns extends InstructionDefinition implements SetTypeIns {
stack.pop();
stack.push(new PreDecrementAVM2Item(ins, localData.lineStartInstruction, inside));
} else {
stack.moveToOutput(output, false);
output.add(new PostDecrementAVM2Item(ins, localData.lineStartInstruction, inside));
stack.addToOutput(new PostDecrementAVM2Item(ins, localData.lineStartInstruction, inside));
}
} else {
stack.moveToOutput(output, false);
output.add(new PostDecrementAVM2Item(ins, localData.lineStartInstruction, inside));
stack.addToOutput(new PostDecrementAVM2Item(ins, localData.lineStartInstruction, inside));
}
return;
}

View File

@@ -52,8 +52,7 @@ public class ThrowIns extends InstructionDefinition {
@Override
public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List<GraphTargetItem> output, String path) {
GraphTargetItem value = stack.pop();
stack.moveToOutput(output, true);
output.add(new ThrowAVM2Item(ins, localData.lineStartInstruction, value));
stack.addToOutput(new ThrowAVM2Item(ins, localData.lineStartInstruction, value));
}
@Override

View File

@@ -84,8 +84,7 @@ public class DecLocalPIns extends InstructionDefinition {
}
}
if (!isPostDec) {
stack.moveToOutput(output, false);
output.add(new DecLocalAVM2Item(ins, localData.lineStartInstruction, regId));
stack.addToOutput(new DecLocalAVM2Item(ins, localData.lineStartInstruction, regId));
}
if (localData.localRegs.containsKey(regId)) {
localData.localRegs.put(regId, new SubtractAVM2Item(ins, localData.lineStartInstruction, localData.localRegs.get(regId), new IntegerValueAVM2Item(ins, localData.lineStartInstruction, 1)));

View File

@@ -84,8 +84,7 @@ public class IncLocalPIns extends InstructionDefinition {
}
}
if (!isPostInc) {
stack.moveToOutput(output, false);
output.add(new IncLocalAVM2Item(ins, localData.lineStartInstruction, regId));
stack.addToOutput(new IncLocalAVM2Item(ins, localData.lineStartInstruction, regId));
}
if (localData.localRegs.containsKey(regId)) {
localData.localRegs.put(regId, new AddAVM2Item(ins, localData.lineStartInstruction, localData.localRegs.get(regId), new IntegerValueAVM2Item(ins, localData.lineStartInstruction, 1)));

View File

@@ -52,7 +52,7 @@ public class DupIns extends InstructionDefinition {
@Override
public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List<GraphTargetItem> output, String path) {
GraphTargetItem v = stack.pop();
GraphTargetItem v = stack.pop();
stack.push(v);
stack.push(new DuplicateItem(AVM2GraphTargetDialect.INSTANCE, ins, localData.lineStartInstruction, v));
//v.moreSrc.add(new GraphSourceItemPos(ins, 0));

View File

@@ -63,8 +63,7 @@ public class PopIns extends InstructionDefinition {
return;
}
stack.moveToOutput(output, false);
output.add(top);
stack.addToOutput(top);
}
@Override

View File

@@ -53,8 +53,7 @@ public class PopScopeIns extends InstructionDefinition {
GraphTargetItem scope = localData.localScopeStack.pop();
if (scope instanceof WithObjectAVM2Item) {
scope = ((WithObjectAVM2Item) scope).scope;
stack.moveToOutput(output, false);
output.add(new WithEndAVM2Item(ins, localData.lineStartInstruction, scope));
stack.addToOutput(new WithEndAVM2Item(ins, localData.lineStartInstruction, scope));
}
}

View File

@@ -45,8 +45,7 @@ public class PushWithIns extends InstructionDefinition {
GraphTargetItem w = stack.pop();
WithObjectAVM2Item wot = new WithObjectAVM2Item(ins, localData.lineStartInstruction, w);
localData.localScopeStack.push(wot);
stack.moveToOutput(output, false);
output.add(new WithAVM2Item(ins, localData.lineStartInstruction, w));
stack.addToOutput(new WithAVM2Item(ins, localData.lineStartInstruction, w));
}
@Override

View File

@@ -63,7 +63,13 @@ public class SwapIns extends InstructionDefinition {
GraphTargetItem o1 = stack.pop();
GraphTargetItem o2 = stack.pop();
if (((o1 instanceof ExceptionAVM2Item) && (o2 instanceof ExceptionAVM2Item))
stack.push(o1);
stack.push(o2);
o1.getMoreSrc().add(new GraphSourceItemPos(ins, 0));
o2.getMoreSrc().add(new GraphSourceItemPos(ins, 0));
/*if (((o1 instanceof ExceptionAVM2Item) && (o2 instanceof ExceptionAVM2Item))
||
(
(
@@ -90,7 +96,8 @@ public class SwapIns extends InstructionDefinition {
stack.moveToOutput(output, false);
output.add(new PushItem(o2));
output.add(new PushItem(o1));
output.add(new SwapItem(AVM2GraphTargetDialect.INSTANCE, ins, localData.lineStartInstruction));
output.add(new SwapItem(AVM2GraphTargetDialect.INSTANCE, ins, localData.lineStartInstruction));
*/
}
@Override

View File

@@ -52,8 +52,7 @@ public class DXNSIns extends InstructionDefinition {
@Override
public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List<GraphTargetItem> output, String path) {
stack.moveToOutput(output, false);
//FIXME!!! - search namespace
output.add(new DefaultXMLNamespace(ins, localData.lineStartInstruction, new StringAVM2Item(ins, localData.lineStartInstruction, localData.getConstants().getString(ins.operands[0]))));
stack.addToOutput(new DefaultXMLNamespace(ins, localData.lineStartInstruction, new StringAVM2Item(ins, localData.lineStartInstruction, localData.getConstants().getString(ins.operands[0]))));
}
}

View File

@@ -52,8 +52,7 @@ public class DXNSLateIns extends InstructionDefinition {
@Override
public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List<GraphTargetItem> output, String path) {
GraphTargetItem xmlns = stack.pop();
stack.moveToOutput(output, false);
output.add(new DefaultXMLNamespace(ins, localData.lineStartInstruction, xmlns));
stack.addToOutput(new DefaultXMLNamespace(ins, localData.lineStartInstruction, xmlns));
}

View File

@@ -1382,7 +1382,7 @@ public abstract class Action implements GraphSourceItem {
store.setStore(actions.subList(ip + 1, ip + 1 + store.getStoreSize()));
ip = ip + 1 + store.getStoreSize() - 1/*ip++ will be next*/;
}
action.translate(localData, stack, output, staticOperation, path);
if (((action instanceof ActionSetTarget) || (action instanceof ActionSetTarget2)) && (!stack.isEmpty())) {

View File

@@ -3369,8 +3369,7 @@ public class Graph {
if (code.size() <= part.start) {
if (!(!ret.isEmpty() && ret.get(ret.size() - 1) instanceof ExitItem)) {
stack.moveToOutput(ret, true);
ret.add(new ScriptEndItem(dialect));
stack.addToOutput(new ScriptEndItem(dialect));
}
return ret;
}
@@ -3534,8 +3533,7 @@ public class Graph {
} while (exHappened);
if ((part.end >= code.size() - 1) && getNextParts(localData, part).isEmpty()) {
if (!(!output.isEmpty() && output.get(output.size() - 1) instanceof ExitItem)) {
stack.moveToOutput(output, true);
output.add(new ScriptEndItem(dialect));
stack.addToOutput(new ScriptEndItem(dialect));
}
}
}
@@ -4541,50 +4539,7 @@ public class Graph {
* @param stack Stack
*/
public void makeAllCommands(List<GraphTargetItem> commands, TranslateStack stack) {
int clen = commands.size();
boolean isExit = false;
if (clen > 0) {
if (commands.get(clen - 1) instanceof ScriptEndItem) {
clen--;
isExit = true;
}
}
if (clen > 0) {
if (commands.get(clen - 1) instanceof ExitItem) {
isExit = true;
clen--;
}
}
if (clen > 0) {
if (commands.get(clen - 1) instanceof BreakItem) {
clen--;
}
}
if (clen > 0) {
if (commands.get(clen - 1) instanceof ContinueItem) {
clen--;
}
}
for (int i = stack.size() - 1; i >= 0; i--) {
GraphTargetItem p = stack.get(i);
if (p instanceof BranchStackResistant) {
continue;
}
stack.remove(i);
if (!(p instanceof PopItem)) {
if (isExit) {
//ASC2 leaves some function calls unpopped on stack before returning from a method
commands.add(clen, p);
} else {
int pos = 0;
if (p.outputPos < commands.size()) {
commands.add(p.outputPos, new PushItem(p));
} else {
commands.add(clen + pos, new PushItem(p));
}
}
}
}
stack.finishBlock(commands);
}
/**

View File

@@ -19,9 +19,15 @@ package com.jpexs.decompiler.graph;
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;
import com.jpexs.decompiler.graph.model.BreakItem;
import com.jpexs.decompiler.graph.model.CommaExpressionItem;
import com.jpexs.decompiler.graph.model.ContinueItem;
import com.jpexs.decompiler.graph.model.ExitItem;
import com.jpexs.decompiler.graph.model.PopItem;
import com.jpexs.decompiler.graph.model.PushItem;
import com.jpexs.decompiler.graph.model.ScriptEndItem;
import com.jpexs.decompiler.graph.model.SwapItem;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -51,7 +57,23 @@ public class TranslateStack extends Stack<GraphTargetItem> {
private int prevOutputSize = 0;
private Map<String, GraphTargetItem> marks = new HashMap<>();
public List<GraphTargetItem> outputQueue = new ArrayList<>();
@Override
public synchronized Object clone() {
TranslateStack st = (TranslateStack) super.clone();
st.outputQueue = new ArrayList<>(outputQueue);
return st;
}
@Override
public void clear() {
super.clear();
outputQueue.clear();
}
public void setConnectedOutput(int prevOutputSize, List<GraphTargetItem> connectedOutput) {
this.prevOutputSize = prevOutputSize;
this.connectedOutput = connectedOutput;
@@ -59,6 +81,11 @@ 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 (connectedOutput != null && item != null) {
item.outputPos = prevOutputSize + connectedOutput.size();
}
@@ -187,6 +214,14 @@ public class TranslateStack extends Stack<GraphTargetItem> {
*/
@Override
public synchronized GraphTargetItem pop() {
if (!outputQueue.isEmpty()) {
List<GraphTargetItem> oldQueue = outputQueue;
outputQueue = new ArrayList<>();
finishBlock(connectedOutput);
connectedOutput.addAll(oldQueue);
}
if (path != null) {
if (this.isEmpty()) {
/*if (connectedOutput != null && !connectedOutput.isEmpty() && connectedOutput.get(connectedOutput.size() - 1) instanceof PushItem) {
@@ -220,11 +255,22 @@ public class TranslateStack extends Stack<GraphTargetItem> {
}
}
public void moveToOutput(List<GraphTargetItem> output, boolean beforeExit) {
if (true) {
//return;
public void addToOutput(GraphTargetItem item) {
if (isEmpty()
|| peek() instanceof ExceptionAVM2Item
|| peek() instanceof NewActivationAVM2Item
) {
connectedOutput.add(item);
return;
}
int pos = output.size();
outputQueue.add(item);
if (item instanceof ExitItem) {
finishBlock(connectedOutput);
}
}
public void finishBlock(List<GraphTargetItem> output) {
/*int pos = output.size();
for (int i = size() - 1; i >= 0; i--) {
GraphTargetItem item = get(i);
@@ -238,7 +284,59 @@ public class TranslateStack extends Stack<GraphTargetItem> {
break;
}
remove(i);
if (item instanceof PopItem) {
continue;
}
output.add(pos, beforeExit ? item : new PushItem(item));
}*/
output.addAll(outputQueue);
outputQueue.clear();
int clen = output.size();
boolean isExit = false;
if (clen > 0) {
if (output.get(clen - 1) instanceof ScriptEndItem) {
clen--;
isExit = true;
}
}
if (clen > 0) {
if (output.get(clen - 1) instanceof ExitItem) {
isExit = true;
clen--;
}
}
if (clen > 0) {
if (output.get(clen - 1) instanceof BreakItem) {
clen--;
}
}
if (clen > 0) {
if (output.get(clen - 1) instanceof ContinueItem) {
clen--;
}
}
for (int i = size() - 1; i >= 0; i--) {
GraphTargetItem p = get(i);
if (p instanceof BranchStackResistant) {
continue;
}
remove(i);
if (!(p instanceof PopItem)) {
if (isExit) {
//ASC2 leaves some function calls unpopped on stack before returning from a method
output.add(clen, p);
} else {
/*int pos = 0;
if (p.outputPos < output.size()) {
output.add(p.outputPos, new PushItem(p));
} else {
output.add(clen + pos, new PushItem(p));
}*/
output.add(clen, new PushItem(p));
}
}
}
}