mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-05-30 04:35:10 +00:00
Fix swaps
This commit is contained in:
@@ -19,6 +19,7 @@ package com.jpexs.decompiler.flash;
|
||||
import com.jpexs.decompiler.graph.GraphPart;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
import com.jpexs.decompiler.graph.SecondPassData;
|
||||
import com.jpexs.helpers.Reference;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
@@ -55,6 +56,11 @@ public abstract class BaseLocalData {
|
||||
*/
|
||||
public Set<String> usedDeobfuscations = new LinkedHashSet<>();
|
||||
|
||||
/**
|
||||
* Max temp index
|
||||
*/
|
||||
public Reference<Integer> maxTempIndex = new Reference<>(0);
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
|
||||
@@ -3823,7 +3823,7 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
|
||||
break;
|
||||
}
|
||||
|
||||
stack.setConnectedOutput(0, output);
|
||||
stack.setConnectedOutput(0, output, localData);
|
||||
ins.translate(localData, stack, output, staticOperation, path);
|
||||
if (ins.isExit()) {
|
||||
break;
|
||||
|
||||
@@ -298,6 +298,7 @@ public class AVM2LocalData extends BaseLocalData {
|
||||
bottomSetLocals = localData.bottomSetLocals;
|
||||
swfVersion = localData.swfVersion;
|
||||
usedDeobfuscations = localData.usedDeobfuscations;
|
||||
maxTempIndex = localData.maxTempIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1826,6 +1826,7 @@ public class AVM2Code implements Cloneable {
|
||||
/**
|
||||
* Converts to source output.
|
||||
*
|
||||
* @param maxTempIndex Max temp index
|
||||
* @param output Output
|
||||
* @param swfVersion SWF version
|
||||
* @param switchParts Switch parts
|
||||
@@ -1857,7 +1858,7 @@ public class AVM2Code implements Cloneable {
|
||||
* @throws ConvertException On convert error
|
||||
* @throws InterruptedException On interrupt
|
||||
*/
|
||||
public void toSourceOutput(List<GraphTargetItem> output, int swfVersion, Set<GraphPart> switchParts, List<MethodBody> callStack, AbcIndexing abcIndex, Map<Integer, Set<Integer>> setLocalPosToGetLocalPos, boolean thisHasDefaultToPrimitive, Reference<GraphSourceItem> lineStartItem, String path, GraphPart part, boolean processJumps, boolean isStatic, int scriptIndex, int classIndex, HashMap<Integer, GraphTargetItem> localRegs, TranslateStack stack, ScopeStack scopeStack, ScopeStack localScopeStack, ABC abc, MethodBody body, int start, int end, HashMap<Integer, String> localRegNames, HashMap<Integer, GraphTargetItem> localRegTypes, List<DottedChain> fullyQualifiedNames, boolean[] visited, HashMap<Integer, Integer> localRegAssignmentIps, LinkedIdentityHashSet<SetLocalAVM2Item> bottomStackSetLocals, Set<String> usedDeobfuscations) throws ConvertException, InterruptedException {
|
||||
public void toSourceOutput(Reference<Integer> maxTempIndex, List<GraphTargetItem> output, int swfVersion, Set<GraphPart> switchParts, List<MethodBody> callStack, AbcIndexing abcIndex, Map<Integer, Set<Integer>> setLocalPosToGetLocalPos, boolean thisHasDefaultToPrimitive, Reference<GraphSourceItem> lineStartItem, String path, GraphPart part, boolean processJumps, boolean isStatic, int scriptIndex, int classIndex, HashMap<Integer, GraphTargetItem> localRegs, TranslateStack stack, ScopeStack scopeStack, ScopeStack localScopeStack, ABC abc, MethodBody body, int start, int end, HashMap<Integer, String> localRegNames, HashMap<Integer, GraphTargetItem> localRegTypes, List<DottedChain> fullyQualifiedNames, boolean[] visited, HashMap<Integer, Integer> localRegAssignmentIps, LinkedIdentityHashSet<SetLocalAVM2Item> bottomStackSetLocals, Set<String> usedDeobfuscations) throws ConvertException, InterruptedException {
|
||||
boolean debugMode = DEBUG_MODE;
|
||||
if (debugMode) {
|
||||
System.err.println("OPEN SubSource:" + start + "-" + end + " " + code.get(start).toString() + " to " + code.get(end).toString());
|
||||
@@ -1976,7 +1977,7 @@ public class AVM2Code implements Cloneable {
|
||||
} else
|
||||
*/
|
||||
if ((ins.definition instanceof ReturnValueIns) || (ins.definition instanceof ReturnVoidIns) || (ins.definition instanceof ThrowIns)) {
|
||||
ins.definition.translate(usedDeobfuscations, swfVersion, switchParts, callStack, abcIndex, setLocalPosToGetLocalPos, lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, localScopeStack, ins, output, body, abc, localRegNames, localRegTypes, fullyQualifiedNames, path, localRegAssignmentIps, ip, this, thisHasDefaultToPrimitive, bottomStackSetLocals);
|
||||
ins.definition.translate(maxTempIndex, usedDeobfuscations, swfVersion, switchParts, callStack, abcIndex, setLocalPosToGetLocalPos, lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, localScopeStack, ins, output, body, abc, localRegNames, localRegTypes, fullyQualifiedNames, path, localRegAssignmentIps, ip, this, thisHasDefaultToPrimitive, bottomStackSetLocals);
|
||||
//ip = end + 1;
|
||||
break;
|
||||
} else if (ins.definition instanceof NewFunctionIns) {
|
||||
@@ -2012,13 +2013,13 @@ public class AVM2Code implements Cloneable {
|
||||
}
|
||||
}
|
||||
// What to do when hasDup is false?
|
||||
ins.definition.translate(usedDeobfuscations, swfVersion, switchParts, callStack, abcIndex, setLocalPosToGetLocalPos, lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, localScopeStack, ins, output, body, abc, localRegNames, localRegTypes, fullyQualifiedNames, path, localRegAssignmentIps, ip, this, thisHasDefaultToPrimitive, bottomStackSetLocals);
|
||||
ins.definition.translate(maxTempIndex, usedDeobfuscations, swfVersion, switchParts, callStack, abcIndex, setLocalPosToGetLocalPos, lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, localScopeStack, ins, output, body, abc, localRegNames, localRegTypes, fullyQualifiedNames, path, localRegAssignmentIps, ip, this, thisHasDefaultToPrimitive, bottomStackSetLocals);
|
||||
NewFunctionAVM2Item nft = (NewFunctionAVM2Item) stack.peek();
|
||||
nft.functionName = functionName;
|
||||
ip++;
|
||||
} else {
|
||||
try {
|
||||
ins.definition.translate(usedDeobfuscations, swfVersion, switchParts, callStack, abcIndex, setLocalPosToGetLocalPos, lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, localScopeStack, ins, output, body, abc, localRegNames, localRegTypes, fullyQualifiedNames, path, localRegAssignmentIps, ip, this, thisHasDefaultToPrimitive, bottomStackSetLocals);
|
||||
ins.definition.translate(maxTempIndex, usedDeobfuscations, swfVersion, switchParts, callStack, abcIndex, setLocalPosToGetLocalPos, lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, localScopeStack, ins, output, body, abc, localRegNames, localRegTypes, fullyQualifiedNames, path, localRegAssignmentIps, ip, this, thisHasDefaultToPrimitive, bottomStackSetLocals);
|
||||
|
||||
if (stack.size() == 1 && (stack.peek() instanceof SetLocalAVM2Item)) {
|
||||
bottomStackSetLocals.add((SetLocalAVM2Item) stack.peek());
|
||||
|
||||
@@ -236,7 +236,7 @@ public class AVM2DeobfuscatorGetSet extends SWFDecompilerAdapter {
|
||||
return;
|
||||
}
|
||||
|
||||
stack.setConnectedOutput(0, output);
|
||||
stack.setConnectedOutput(0, output, localData);
|
||||
ins.translate(localData, stack, output, 0, "");
|
||||
}
|
||||
|
||||
|
||||
@@ -326,7 +326,7 @@ public class AVM2DeobfuscatorRegistersOld extends AVM2DeobfuscatorSimpleOld {
|
||||
continue outer;
|
||||
}
|
||||
|
||||
stack.setConnectedOutput(0, output);
|
||||
stack.setConnectedOutput(0, output, localData);
|
||||
ins.translate(localData, stack, output, 0, "");
|
||||
if (def instanceof SetLocalTypeIns) {
|
||||
int regId = ((SetLocalTypeIns) def).getRegisterId(ins);
|
||||
|
||||
@@ -370,7 +370,7 @@ public class AVM2DeobfuscatorSimpleOld extends AVM2DeobfuscatorZeroJumpsNullPush
|
||||
}
|
||||
}
|
||||
|
||||
stack.setConnectedOutput(0, output);
|
||||
stack.setConnectedOutput(0, output, localData);
|
||||
ins.translate(localData, stack, output, 0, "");
|
||||
}
|
||||
|
||||
|
||||
@@ -339,7 +339,7 @@ public class AVM2Graph extends Graph {
|
||||
localData2.localScopeStack = new ScopeStack();
|
||||
|
||||
List<GraphTargetItem> targetOutput = new GraphPartMarkedArrayList<>();
|
||||
finallyTryTargetStack.setConnectedOutput(0, targetOutput);
|
||||
finallyTryTargetStack.setConnectedOutput(0, targetOutput, localData);
|
||||
try {
|
||||
translatePart(targetOutput, localData2, finallyTryTargetPart, finallyTryTargetStack, 0 /*??*/, "try_target");
|
||||
} catch (GraphPartChangeException ex1) { //should not happen
|
||||
|
||||
@@ -200,7 +200,7 @@ public class AVM2GraphSource extends GraphSource {
|
||||
@Override
|
||||
public void translatePart(List<GraphTargetItem> output, Graph graph, GraphPart part, BaseLocalData localData, TranslateStack stack, int start, int end, int staticOperation, String path) throws InterruptedException {
|
||||
Reference<GraphSourceItem> lineStartItem = new Reference<>(localData.lineStartInstruction);
|
||||
code.toSourceOutput(output, localData.swfVersion, localData.allSwitchParts, ((AVM2LocalData) localData).callStack, ((AVM2LocalData) localData).abcIndex, ((AVM2LocalData) localData).setLocalPosToGetLocalPos, ((AVM2LocalData) localData).thisHasDefaultToPrimitive, lineStartItem, path, part, false, isStatic, scriptIndex, classIndex, localRegs, stack, ((AVM2LocalData) localData).scopeStack, ((AVM2LocalData) localData).localScopeStack, abc, body, start, end, localRegNames, ((AVM2LocalData) localData).localRegTypes, fullyQualifiedNames, new boolean[size()], localRegAssignmentIps, ((AVM2LocalData) localData).bottomSetLocals, localData.usedDeobfuscations);
|
||||
code.toSourceOutput(localData.maxTempIndex, output, localData.swfVersion, localData.allSwitchParts, ((AVM2LocalData) localData).callStack, ((AVM2LocalData) localData).abcIndex, ((AVM2LocalData) localData).setLocalPosToGetLocalPos, ((AVM2LocalData) localData).thisHasDefaultToPrimitive, lineStartItem, path, part, false, isStatic, scriptIndex, classIndex, localRegs, stack, ((AVM2LocalData) localData).scopeStack, ((AVM2LocalData) localData).localScopeStack, abc, body, start, end, localRegNames, ((AVM2LocalData) localData).localRegTypes, fullyQualifiedNames, new boolean[size()], localRegAssignmentIps, ((AVM2LocalData) localData).bottomSetLocals, localData.usedDeobfuscations);
|
||||
localData.lineStartInstruction = lineStartItem.getVal();
|
||||
}
|
||||
|
||||
|
||||
@@ -271,6 +271,7 @@ public abstract class InstructionDefinition implements Serializable {
|
||||
/**
|
||||
* Translates instruction to high level code.
|
||||
*
|
||||
* @param maxTempIndex Max temp index
|
||||
* @param usedDeobfuscations Used deobfuscations
|
||||
* @param swfVersion SWF version
|
||||
* @param switchParts Switch parts
|
||||
@@ -300,7 +301,7 @@ public abstract class InstructionDefinition implements Serializable {
|
||||
* @param bottomSetLocals Bottom set locals
|
||||
* @throws InterruptedException On interrupt
|
||||
*/
|
||||
public void translate(Set<String> usedDeobfuscations, int swfVersion, Set<GraphPart> switchParts, List<MethodBody> callStack, AbcIndexing abcIndex, Map<Integer, Set<Integer>> setLocalPosToGetLocalPos, Reference<GraphSourceItem> lineStartItem, boolean isStatic, int scriptIndex, int classIndex, HashMap<Integer, GraphTargetItem> localRegs, TranslateStack stack, ScopeStack scopeStack, ScopeStack localScopeStack, AVM2Instruction ins, List<GraphTargetItem> output, MethodBody body, ABC abc, HashMap<Integer, String> localRegNames, HashMap<Integer, GraphTargetItem> localRegTypes, List<DottedChain> fullyQualifiedNames, String path, HashMap<Integer, Integer> localRegsAssignmentIps, int ip, AVM2Code code, boolean thisHasDefaultToPrimitive, LinkedIdentityHashSet<SetLocalAVM2Item> bottomSetLocals) throws InterruptedException {
|
||||
public void translate(Reference<Integer> maxTempIndex, Set<String> usedDeobfuscations, int swfVersion, Set<GraphPart> switchParts, List<MethodBody> callStack, AbcIndexing abcIndex, Map<Integer, Set<Integer>> setLocalPosToGetLocalPos, Reference<GraphSourceItem> lineStartItem, boolean isStatic, int scriptIndex, int classIndex, HashMap<Integer, GraphTargetItem> localRegs, TranslateStack stack, ScopeStack scopeStack, ScopeStack localScopeStack, AVM2Instruction ins, List<GraphTargetItem> output, MethodBody body, ABC abc, HashMap<Integer, String> localRegNames, HashMap<Integer, GraphTargetItem> localRegTypes, List<DottedChain> fullyQualifiedNames, String path, HashMap<Integer, Integer> localRegsAssignmentIps, int ip, AVM2Code code, boolean thisHasDefaultToPrimitive, LinkedIdentityHashSet<SetLocalAVM2Item> bottomSetLocals) throws InterruptedException {
|
||||
AVM2LocalData localData = new AVM2LocalData();
|
||||
localData.allSwitchParts = switchParts;
|
||||
localData.isStatic = isStatic;
|
||||
@@ -325,6 +326,7 @@ public abstract class InstructionDefinition implements Serializable {
|
||||
localData.bottomSetLocals = bottomSetLocals;
|
||||
localData.swfVersion = swfVersion;
|
||||
localData.usedDeobfuscations = usedDeobfuscations;
|
||||
localData.maxTempIndex = maxTempIndex;
|
||||
translate(localData, stack, ins, output, path);
|
||||
lineStartItem.setVal(localData.lineStartInstruction);
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ 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 com.jpexs.decompiler.graph.model.HasTempIndex;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -56,14 +57,23 @@ public class DupIns extends InstructionDefinition {
|
||||
@Override
|
||||
public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List<GraphTargetItem> output, String path) {
|
||||
GraphTargetItem v = stack.pop();
|
||||
int temp = 0;
|
||||
|
||||
if (v instanceof NewActivationAVM2Item
|
||||
|| v instanceof ExceptionAVM2Item) {
|
||||
stack.push(v);
|
||||
} else {
|
||||
stack.push(new DuplicateSourceItem(AVM2GraphTargetDialect.INSTANCE, ins, localData.lineStartInstruction, v));
|
||||
if (v instanceof HasTempIndex) {
|
||||
temp = ((HasTempIndex) v).getTempIndex();
|
||||
stack.push(v);
|
||||
} else {
|
||||
temp = localData.maxTempIndex.getVal() + 1;
|
||||
localData.maxTempIndex.setVal(temp);
|
||||
stack.push(new DuplicateSourceItem(AVM2GraphTargetDialect.INSTANCE, ins, localData.lineStartInstruction, v, temp));
|
||||
}
|
||||
}
|
||||
//stack.push(v);
|
||||
stack.push(new DuplicateItem(AVM2GraphTargetDialect.INSTANCE, ins, localData.lineStartInstruction, v));
|
||||
stack.push(new DuplicateItem(AVM2GraphTargetDialect.INSTANCE, ins, localData.lineStartInstruction, v, temp));
|
||||
//v.moreSrc.add(new GraphSourceItemPos(ins, 0));
|
||||
|
||||
}
|
||||
|
||||
@@ -30,9 +30,13 @@ import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.SimpleValue;
|
||||
import com.jpexs.decompiler.graph.TranslateStack;
|
||||
import com.jpexs.decompiler.graph.model.DuplicateItem;
|
||||
import com.jpexs.decompiler.graph.model.DuplicateSourceItem;
|
||||
import com.jpexs.decompiler.graph.model.HasTempIndex;
|
||||
import com.jpexs.decompiler.graph.model.PopItem;
|
||||
import com.jpexs.decompiler.graph.model.PushItem;
|
||||
import com.jpexs.decompiler.graph.model.SetTemporaryItem;
|
||||
import com.jpexs.decompiler.graph.model.SwapItem;
|
||||
import com.jpexs.decompiler.graph.model.TemporaryItem;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -65,11 +69,13 @@ public class SwapIns extends InstructionDefinition {
|
||||
GraphTargetItem o2 = stack.pop();
|
||||
|
||||
|
||||
/*stack.push(o1);
|
||||
stack.push(o2);
|
||||
o1.getMoreSrc().add(new GraphSourceItemPos(ins, 0));
|
||||
o2.getMoreSrc().add(new GraphSourceItemPos(ins, 0));
|
||||
*/
|
||||
/*if (true) {
|
||||
stack.push(o1);
|
||||
stack.push(o2);
|
||||
o1.getMoreSrc().add(new GraphSourceItemPos(ins, 0));
|
||||
o2.getMoreSrc().add(new GraphSourceItemPos(ins, 0));
|
||||
return;
|
||||
}*/
|
||||
if (((o1 instanceof ExceptionAVM2Item) && (o2 instanceof ExceptionAVM2Item))
|
||||
||
|
||||
(
|
||||
@@ -94,6 +100,7 @@ public class SwapIns extends InstructionDefinition {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
stack.finishBlock(output);
|
||||
if (!(o2 instanceof PopItem)) {
|
||||
output.add(new PushItem(o2));
|
||||
@@ -101,7 +108,35 @@ public class SwapIns extends InstructionDefinition {
|
||||
if (!(o2 instanceof PopItem && o1 instanceof PopItem)) {
|
||||
output.add(new PushItem(o1));
|
||||
}
|
||||
output.add(new SwapItem(AVM2GraphTargetDialect.INSTANCE, ins, localData.lineStartInstruction));
|
||||
output.add(new SwapItem(AVM2GraphTargetDialect.INSTANCE, ins, localData.lineStartInstruction));
|
||||
*/
|
||||
/*if (o2 instanceof HasTempIndex) {
|
||||
stack.push(o1);
|
||||
stack.push(o2);
|
||||
return;
|
||||
}*/
|
||||
/*
|
||||
if (o2 instanceof SetTemporaryItem || o2 instanceof DuplicateSourceItem) {
|
||||
HasTempIndex ti = (HasTempIndex) o2;
|
||||
stack.addToOutput(new SetTemporaryItem(AVM2GraphTargetDialect.INSTANCE, ins, localData.lineStartInstruction, o2.value, ti.getTempIndex(), "swap"));
|
||||
stack.push(o1);
|
||||
stack.push(new TemporaryItem(AVM2GraphTargetDialect.INSTANCE, ins, localData.lineStartInstruction, o2, ti.getTempIndex()));
|
||||
return;
|
||||
}
|
||||
|
||||
if (o2 instanceof TemporaryItem || o2 instanceof DuplicateItem) {
|
||||
stack.push(o1);
|
||||
stack.push(o2);
|
||||
return;
|
||||
}
|
||||
*/
|
||||
int temp = localData.maxTempIndex.getVal() + 1;
|
||||
localData.maxTempIndex.setVal(temp);
|
||||
stack.finishBlock(output);
|
||||
stack.addToOutput(new SetTemporaryItem(AVM2GraphTargetDialect.INSTANCE, ins, localData.lineStartInstruction, o2, temp, "swap"));
|
||||
stack.push(o1);
|
||||
stack.push(new TemporaryItem(AVM2GraphTargetDialect.INSTANCE, ins, localData.lineStartInstruction, o2, temp));
|
||||
stack.finishBlock(output);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -2451,7 +2451,7 @@ public class ActionScript3Parser {
|
||||
break;
|
||||
//Both ASs
|
||||
case "dup":
|
||||
ret = new DuplicateItem(DIALECT, null, null, expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables, false, abc));
|
||||
ret = new DuplicateItem(DIALECT, null, null, expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables, false, abc), 0);
|
||||
allowMemberOrCall = true;
|
||||
break;
|
||||
case "push":
|
||||
|
||||
@@ -76,7 +76,9 @@ import com.jpexs.decompiler.graph.model.LabelItem;
|
||||
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.SetTemporaryItem;
|
||||
import com.jpexs.decompiler.graph.model.SwitchItem;
|
||||
import com.jpexs.decompiler.graph.model.TemporaryItem;
|
||||
import com.jpexs.decompiler.graph.model.TrueItem;
|
||||
import com.jpexs.decompiler.graph.model.WhileItem;
|
||||
import com.jpexs.helpers.Helper;
|
||||
@@ -342,6 +344,17 @@ public class ActionGraph extends Graph {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (it instanceof SetTemporaryItem) {
|
||||
SetTemporaryItem st = (SetTemporaryItem) it;
|
||||
if (st.value instanceof GetPropertyActionItem) {
|
||||
GetPropertyActionItem gp = (GetPropertyActionItem) st.value;
|
||||
if (gp.propertyIndex == 11 /*_target*/) {
|
||||
list.remove(t);
|
||||
t--;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (it instanceof SetTargetActionItem) {
|
||||
SetTargetActionItem st = (SetTargetActionItem) it;
|
||||
if (st.target.isEmpty()) {
|
||||
@@ -362,6 +375,11 @@ public class ActionGraph extends Graph {
|
||||
t--;
|
||||
continue;
|
||||
}
|
||||
if (st.target instanceof TemporaryItem) {
|
||||
list.remove(t);
|
||||
t--;
|
||||
continue;
|
||||
}
|
||||
if ((st.target instanceof DirectValueActionItem) && st.target.getResult().equals("")) {
|
||||
if (targetStart > -1) {
|
||||
targetEnd = t;
|
||||
|
||||
@@ -1869,7 +1869,7 @@ public class ActionScript2Parser {
|
||||
break;
|
||||
//Both ASs
|
||||
case "dup":
|
||||
ret = new DuplicateItem(DIALECT, null, null, expression(inFunction, inMethod, inTellTarget, allowRemainder, variables, functions, false, hasEval));
|
||||
ret = new DuplicateItem(DIALECT, null, null, expression(inFunction, inMethod, inTellTarget, allowRemainder, variables, functions, false, hasEval), 0);
|
||||
allowMemberOrCall = true;
|
||||
break;
|
||||
case "push":
|
||||
|
||||
@@ -68,7 +68,8 @@ public class ActionPushDuplicate extends Action {
|
||||
@Override
|
||||
public void translate(Set<String> usedDeobfuscations, Map<String, Map<String, Trait>> uninitializedClassTraits, SecondPassData secondPassData, boolean insideDoInitAction, GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
GraphTargetItem value = stack.peek();
|
||||
stack.push(new DuplicateItem(ActionGraphTargetDialect.INSTANCE, this, lineStartAction, value));
|
||||
//TODO: implement logic similar to Avm2
|
||||
stack.push(new DuplicateItem(ActionGraphTargetDialect.INSTANCE, this, lineStartAction, value, 0));
|
||||
value.getMoreSrc().add(new GraphSourceItemPos(this, 0));
|
||||
}
|
||||
|
||||
|
||||
@@ -2390,7 +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);
|
||||
stack.setConnectedOutput(0, output, localData);
|
||||
int end;
|
||||
for (GraphPart p : sub) {
|
||||
if (p.end == -1) {
|
||||
@@ -3370,7 +3370,7 @@ public class Graph {
|
||||
|
||||
if (code.size() <= part.start) {
|
||||
if (!(!ret.isEmpty() && ret.get(ret.size() - 1) instanceof ExitItem)) {
|
||||
stack.setConnectedOutput(0, ret);
|
||||
stack.setConnectedOutput(0, ret, localData);
|
||||
stack.addToOutput(new ScriptEndItem(dialect));
|
||||
}
|
||||
return ret;
|
||||
@@ -3503,7 +3503,7 @@ public class Graph {
|
||||
if (currentRet instanceof GraphPartMarkedArrayList) {
|
||||
((GraphPartMarkedArrayList) currentRet).startPart(part);
|
||||
}
|
||||
stack.setConnectedOutput(0, currentRet);
|
||||
stack.setConnectedOutput(0, currentRet, localData);
|
||||
if (checkPartOutput(currentRet, foundGotos, partCodes, partCodePos, visited, code, localData, allParts, stack, parent, part, stopPart, stopPartKind, loops, throwStates, currentLoop, staticOperation, path, recursionLevel)) {
|
||||
parseNext = false;
|
||||
} else {
|
||||
@@ -3512,7 +3512,7 @@ public class Graph {
|
||||
do {
|
||||
exHappened = false;
|
||||
try {
|
||||
stack.setConnectedOutput(currentRet.size(), output);
|
||||
stack.setConnectedOutput(currentRet.size(), output, localData);
|
||||
code.translatePart(output, this, part, localData, stack, ipStart, part.end, staticOperation, path);
|
||||
} catch (GraphPartChangeException ex) { //Special case for ifFrameLoaded when it's over multiple parts
|
||||
//output.addAll(ex.getOutput());
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
*/
|
||||
package com.jpexs.decompiler.graph;
|
||||
|
||||
import com.jpexs.decompiler.flash.BaseLocalData;
|
||||
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;
|
||||
@@ -23,11 +24,16 @@ 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.DuplicateItem;
|
||||
import com.jpexs.decompiler.graph.model.DuplicateSourceItem;
|
||||
import com.jpexs.decompiler.graph.model.ExitItem;
|
||||
import com.jpexs.decompiler.graph.model.HasTempIndex;
|
||||
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.SetTemporaryItem;
|
||||
import com.jpexs.decompiler.graph.model.SwapItem;
|
||||
import com.jpexs.decompiler.graph.model.TemporaryItem;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@@ -60,6 +66,8 @@ public class TranslateStack extends Stack<GraphTargetItem> {
|
||||
private Map<String, GraphTargetItem> marks = new HashMap<>();
|
||||
|
||||
public List<GraphTargetItem> outputQueue = new ArrayList<>();
|
||||
|
||||
public BaseLocalData localData = null;
|
||||
|
||||
@Override
|
||||
public synchronized Object clone() {
|
||||
@@ -75,9 +83,10 @@ public class TranslateStack extends Stack<GraphTargetItem> {
|
||||
}
|
||||
|
||||
|
||||
public void setConnectedOutput(int prevOutputSize, List<GraphTargetItem> connectedOutput) {
|
||||
public void setConnectedOutput(int prevOutputSize, List<GraphTargetItem> connectedOutput, BaseLocalData localData) {
|
||||
this.prevOutputSize = prevOutputSize;
|
||||
this.connectedOutput = connectedOutput;
|
||||
this.localData = localData;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -86,7 +95,7 @@ public class TranslateStack extends Stack<GraphTargetItem> {
|
||||
if (item instanceof FindPropertyAVM2Item) {
|
||||
finishBlock(connectedOutput);
|
||||
} else {
|
||||
outputQueue.add(item);
|
||||
outputQueue.add(item);
|
||||
item = new CommaExpressionItem(item.dialect, null, item.lineStartItem, outputQueue);
|
||||
outputQueue = new ArrayList<>();
|
||||
}
|
||||
@@ -226,6 +235,39 @@ public class TranslateStack extends Stack<GraphTargetItem> {
|
||||
connectedOutput.addAll(oldQueue);
|
||||
}
|
||||
|
||||
if (isEmpty() && connectedOutput != null) {
|
||||
for (int i = connectedOutput.size() - 1; i >= 0; i--) {
|
||||
GraphTargetItem item = connectedOutput.get(i);
|
||||
if (item instanceof Block) {
|
||||
break;
|
||||
}
|
||||
if (item instanceof PushItem) {
|
||||
PushItem pi = (PushItem) item;
|
||||
if (pi.value instanceof SetTemporaryItem) {
|
||||
SetTemporaryItem st = (SetTemporaryItem) pi.value;
|
||||
connectedOutput.set(i, st);
|
||||
return new TemporaryItem(pi.dialect, pi.value.getSrc(), pi.value.getLineStartItem(), pi.value, st.tempIndex);
|
||||
} else if (pi.value instanceof DuplicateSourceItem) {
|
||||
DuplicateSourceItem ds = (DuplicateSourceItem) pi.value;
|
||||
connectedOutput.set(i, new SetTemporaryItem(pi.dialect, ds.getSrc(), ds.getLineStartItem(), ds.value, ds.tempIndex,"push"));
|
||||
return new TemporaryItem(pi.dialect, pi.value.getSrc(), pi.value.getLineStartItem(), ds.value, ds.tempIndex);
|
||||
} /*else if (pi.value instanceof DuplicateItem) {
|
||||
DuplicateItem d = (DuplicateItem) pi.value;
|
||||
//connectedOutput.remove(i);
|
||||
connectedOutput.set(i, new SetTemporaryItem(pi.dialect, d.getSrc(), d.getLineStartItem(), d.value, d.tempIndex));
|
||||
return new TemporaryItem(pi.dialect, pi.value.getSrc(), pi.value.getLineStartItem(), pi.value, d.tempIndex);
|
||||
} */else if (pi.value instanceof TemporaryItem) {
|
||||
connectedOutput.remove(i);
|
||||
return pi.value;
|
||||
} else {
|
||||
int temp = localData.maxTempIndex.getVal() + 1;
|
||||
localData.maxTempIndex.setVal(temp);
|
||||
connectedOutput.set(i, new SetTemporaryItem(pi.dialect, pi.value.getSrc(), pi.value.getLineStartItem(), pi.value, temp, "push"));
|
||||
return new TemporaryItem(pi.dialect, pi.value.getSrc(), pi.value.getLineStartItem(), pi.value, temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (path != null) {
|
||||
if (this.isEmpty()) {
|
||||
@@ -260,10 +302,25 @@ public class TranslateStack extends Stack<GraphTargetItem> {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isAllTemp() {
|
||||
for (int i = 0; i < size(); i++) {
|
||||
GraphTargetItem item = get(i);
|
||||
if (item instanceof TemporaryItem) {
|
||||
continue;
|
||||
}
|
||||
if (item instanceof DuplicateItem) {
|
||||
continue;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void addToOutput(GraphTargetItem item) {
|
||||
if (isEmpty()
|
||||
|| peek() instanceof ExceptionAVM2Item
|
||||
|| peek() instanceof NewActivationAVM2Item
|
||||
//|| isAllTemp()
|
||||
) {
|
||||
connectedOutput.add(item);
|
||||
return;
|
||||
@@ -356,7 +413,7 @@ public class TranslateStack extends Stack<GraphTargetItem> {
|
||||
if (output.size() < 3) {
|
||||
return;
|
||||
}
|
||||
if (!(output.get(output.size() - 1) instanceof SwapItem)) {
|
||||
if (!(output.get(output.size() - 1) instanceof PushItem)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -364,13 +421,34 @@ public class TranslateStack extends Stack<GraphTargetItem> {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(output.get(output.size() - 3) instanceof PushItem)) {
|
||||
if (!(output.get(output.size() - 3) instanceof SetTemporaryItem)) {
|
||||
return;
|
||||
}
|
||||
|
||||
PushItem pi1 = (PushItem) output.get(output.size() - 1);
|
||||
if (!(pi1.value instanceof TemporaryItem)) {
|
||||
return;
|
||||
}
|
||||
|
||||
TemporaryItem ti = (TemporaryItem) pi1.value;
|
||||
|
||||
SetTemporaryItem st = (SetTemporaryItem) output.get(output.size() - 3);
|
||||
|
||||
if (!"swap".equals(st.getSuffix())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (st.getTempIndex() != ti.getTempIndex()) {
|
||||
return;
|
||||
}
|
||||
|
||||
PushItem pi2 = (PushItem) output.get(output.size() - 2);
|
||||
|
||||
output.remove(output.size() - 1);
|
||||
push(((PushItem)output.remove(output.size() - 1)).value);
|
||||
push(((PushItem)output.remove(output.size() - 1)).value);
|
||||
output.remove(output.size() - 1);
|
||||
output.remove(output.size() - 1);
|
||||
push(pi2.value);
|
||||
push(ti.value);
|
||||
//moveToStack(output);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,8 +33,9 @@ import java.util.Set;
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DuplicateItem extends GraphTargetItem implements SimpleValue {
|
||||
public class DuplicateItem extends GraphTargetItem implements SimpleValue, HasTempIndex {
|
||||
|
||||
public int tempIndex;
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
@@ -43,8 +44,9 @@ public class DuplicateItem extends GraphTargetItem implements SimpleValue {
|
||||
* @param lineStartIns Line start item
|
||||
* @param value Value
|
||||
*/
|
||||
public DuplicateItem(GraphTargetDialect dialect, GraphSourceItem src, GraphSourceItem lineStartIns, GraphTargetItem value) {
|
||||
public DuplicateItem(GraphTargetDialect dialect, GraphSourceItem src, GraphSourceItem lineStartIns, GraphTargetItem value, int tempIndex) {
|
||||
super(dialect, src, lineStartIns, value.getPrecedence(), value);
|
||||
this.tempIndex = tempIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -62,9 +64,12 @@ public class DuplicateItem extends GraphTargetItem implements SimpleValue {
|
||||
/*if (!value.hasSideEffect() || !Configuration.displayDupInstructions.get()) {
|
||||
return value.appendTry(writer, localData);
|
||||
}*/
|
||||
writer.append("§§dup(");
|
||||
value.appendTry(writer, localData);
|
||||
return writer.append(")");
|
||||
if (tempIndex == 0) {
|
||||
writer.append("§§dup(");
|
||||
value.appendTry(writer, localData);
|
||||
return writer.append(")");
|
||||
}
|
||||
return writer.append("_temp_").append(tempIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -137,4 +142,8 @@ public class DuplicateItem extends GraphTargetItem implements SimpleValue {
|
||||
return value.hasSideEffect();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTempIndex() {
|
||||
return tempIndex;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,9 @@ import java.util.Set;
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DuplicateSourceItem extends GraphTargetItem implements SimpleValue {
|
||||
public class DuplicateSourceItem extends GraphTargetItem implements SimpleValue, HasTempIndex {
|
||||
|
||||
public int tempIndex;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
@@ -44,10 +46,11 @@ public class DuplicateSourceItem extends GraphTargetItem implements SimpleValue
|
||||
* @param lineStartIns Line start item
|
||||
* @param value Value
|
||||
*/
|
||||
public DuplicateSourceItem(GraphTargetDialect dialect, GraphSourceItem src, GraphSourceItem lineStartIns, GraphTargetItem value) {
|
||||
public DuplicateSourceItem(GraphTargetDialect dialect, GraphSourceItem src, GraphSourceItem lineStartIns, GraphTargetItem value, int tempIndex) {
|
||||
super(dialect, src, lineStartIns, value.getPrecedence(), value);
|
||||
this.tempIndex = tempIndex;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object getResult() {
|
||||
return value.getResult();
|
||||
@@ -63,9 +66,18 @@ public class DuplicateSourceItem extends GraphTargetItem implements SimpleValue
|
||||
/*if (!value.hasSideEffect() || !Configuration.displayDupInstructions.get()) {
|
||||
return value.appendTry(writer, localData);
|
||||
}*/
|
||||
writer.append("§§dupsrc(");
|
||||
value.appendTry(writer, localData);
|
||||
return writer.append(")");
|
||||
if (tempIndex == 0) {
|
||||
writer.append("§§dupsrc(");
|
||||
value.appendTry(writer, localData);
|
||||
return writer.append(")");
|
||||
}
|
||||
GraphTargetItem val = value;
|
||||
while ((val instanceof HasTempIndex) && ((HasTempIndex) val).getTempIndex() == tempIndex) {
|
||||
val = val.value;
|
||||
}
|
||||
writer.append("_tempdup_").append(tempIndex).append(" = ");
|
||||
val.appendTry(writer, localData);
|
||||
return writer;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -138,4 +150,8 @@ public class DuplicateSourceItem extends GraphTargetItem implements SimpleValue
|
||||
return value.hasSideEffect();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTempIndex() {
|
||||
return tempIndex;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public interface HasTempIndex {
|
||||
public int getTempIndex();
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* 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.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 SetTemporaryItem extends GraphTargetItem implements SimpleValue, HasTempIndex {
|
||||
|
||||
private static final boolean SHOW_SUFFIX = false;
|
||||
|
||||
public int tempIndex;
|
||||
private final String suffix;
|
||||
|
||||
public String getSuffix() {
|
||||
return suffix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param dialect Dialect
|
||||
* @param src Source
|
||||
* @param lineStartIns Line start item
|
||||
* @param value Value
|
||||
*/
|
||||
public SetTemporaryItem(GraphTargetDialect dialect, GraphSourceItem src, GraphSourceItem lineStartIns, GraphTargetItem value, int tempIndex, String suffix) {
|
||||
super(dialect, src, lineStartIns, value.getPrecedence(), value);
|
||||
this.tempIndex = tempIndex;
|
||||
this.suffix = suffix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getResult() {
|
||||
return value.getResult();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getResultAsNumber() {
|
||||
return value.getResultAsNumber();
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException {
|
||||
GraphTargetItem val = value;
|
||||
while ((val instanceof HasTempIndex) && ((HasTempIndex) val).getTempIndex() == tempIndex) {
|
||||
val = val.value;
|
||||
}
|
||||
writer.append("_temp");
|
||||
if (SHOW_SUFFIX) {
|
||||
writer.append(suffix);
|
||||
}
|
||||
writer.append("_").append(tempIndex).append(" = ");
|
||||
val.appendTry(writer, localData);
|
||||
return writer;
|
||||
}
|
||||
|
||||
@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 boolean isSimpleValue() {
|
||||
return ((value instanceof SimpleValue) && ((SimpleValue) value).isSimpleValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasSideEffect() {
|
||||
return value.hasSideEffect();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTempIndex() {
|
||||
return tempIndex;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* 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 TemporaryItem extends GraphTargetItem implements SimpleValue, HasTempIndex {
|
||||
|
||||
public int tempIndex;
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param dialect Dialect
|
||||
* @param src Source
|
||||
* @param lineStartIns Line start item
|
||||
* @param value Value
|
||||
*/
|
||||
public TemporaryItem(GraphTargetDialect dialect, GraphSourceItem src, GraphSourceItem lineStartIns, GraphTargetItem value, int tempIndex) {
|
||||
super(dialect, src, lineStartIns, value.getPrecedence(), value);
|
||||
this.tempIndex = tempIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getResult() {
|
||||
return value.getResult();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getResultAsNumber() {
|
||||
return value.getResultAsNumber();
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException {
|
||||
return writer.append("_temp_").append(tempIndex);
|
||||
}
|
||||
|
||||
@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 boolean isSimpleValue() {
|
||||
return ((value instanceof SimpleValue) && ((SimpleValue) value).isSimpleValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasSideEffect() {
|
||||
return value.hasSideEffect();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTempIndex() {
|
||||
return tempIndex;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user