mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-06-12 16:31:55 +00:00
2497 Swap instruction handling. WIP
This commit is contained in:
@@ -1390,6 +1390,7 @@ public class AVM2Graph extends Graph {
|
||||
//should not happen
|
||||
finallyCommands.clear();
|
||||
}
|
||||
stack.pop(); //duplicated switched value
|
||||
stack.pop(); //value switched by lookupswitch
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,6 +62,8 @@ import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.ScopeStack;
|
||||
import com.jpexs.decompiler.graph.TranslateStack;
|
||||
import com.jpexs.decompiler.graph.model.DuplicateItem;
|
||||
import com.jpexs.decompiler.graph.model.PopItem;
|
||||
import com.jpexs.decompiler.graph.model.PushItem;
|
||||
import com.jpexs.helpers.LinkedIdentityHashSet;
|
||||
import com.jpexs.helpers.Reference;
|
||||
import java.io.Serializable;
|
||||
@@ -377,7 +379,8 @@ public abstract class InstructionDefinition implements Serializable {
|
||||
* @param ins Instruction
|
||||
* @return Resolved multiname
|
||||
*/
|
||||
protected FullMultinameAVM2Item resolveMultiname(AVM2LocalData localData, boolean property, TranslateStack stack, AVM2ConstantPool constants, int multinameIndex, AVM2Instruction ins) {
|
||||
protected FullMultinameAVM2Item resolveMultiname(AVM2LocalData localData, boolean property, TranslateStack stack, AVM2ConstantPool constants, int multinameIndex, AVM2Instruction ins, List<GraphTargetItem> output) {
|
||||
stack.allowSwap(output);
|
||||
GraphTargetItem ns = null;
|
||||
GraphTargetItem name = null;
|
||||
if (multinameIndex > 0 && multinameIndex < constants.getMultinameCount()) {
|
||||
@@ -543,15 +546,17 @@ public abstract class InstructionDefinition implements Serializable {
|
||||
* @param path Path
|
||||
*/
|
||||
public void handleSetProperty(boolean init, AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List<GraphTargetItem> output, String path) {
|
||||
stack.allowSwap(output);
|
||||
int multinameIndex = ins.operands[0];
|
||||
GraphTargetItem value = stack.pop();
|
||||
FullMultinameAVM2Item multiname = resolveMultiname(localData, true, stack, localData.getConstants(), multinameIndex, ins);
|
||||
FullMultinameAVM2Item multiname = resolveMultiname(localData, true, stack, localData.getConstants(), multinameIndex, ins, output);
|
||||
GraphTargetItem obj = stack.pop();
|
||||
//assembled/TestIncrement
|
||||
if ((value instanceof IncrementAVM2Item) || (value instanceof DecrementAVM2Item)) {
|
||||
boolean isIncrement = (value instanceof IncrementAVM2Item);
|
||||
if (value.value instanceof DuplicateItem) {
|
||||
GraphTargetItem duplicated = value.value.value;
|
||||
stack.moveToStack(output);
|
||||
if (!stack.isEmpty()) {
|
||||
if (stack.peek() == duplicated) {
|
||||
GraphTargetItem notCoerced = duplicated.getNotCoerced();
|
||||
@@ -602,6 +607,7 @@ public abstract class InstructionDefinition implements Serializable {
|
||||
GetLexAVM2Item getLex = (GetLexAVM2Item) value.value.getNotCoercedNoDup();
|
||||
if (localData.abc.constants.getMultiname(multinameIndex).equals(getLex.propertyName)
|
||||
&& (obj instanceof FindPropertyAVM2Item)) {
|
||||
stack.moveToOutput(output, false);
|
||||
if (hasConvert) {
|
||||
if (isIncrement) {
|
||||
output.add(new PostIncrementAVM2Item(ins, localData.lineStartInstruction, getLex));
|
||||
@@ -629,6 +635,7 @@ 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));
|
||||
@@ -652,6 +659,7 @@ public abstract class InstructionDefinition implements Serializable {
|
||||
GraphTargetItem duplicated = value.value;
|
||||
if ((duplicated instanceof IncrementAVM2Item) || (duplicated instanceof DecrementAVM2Item)) {
|
||||
boolean isIncrement = (duplicated instanceof IncrementAVM2Item);
|
||||
stack.moveToStack(output);
|
||||
if (!stack.isEmpty()) {
|
||||
if (stack.peek() == duplicated) {
|
||||
GraphTargetItem incrementedProp = duplicated.value;
|
||||
@@ -702,7 +710,8 @@ public abstract class InstructionDefinition implements Serializable {
|
||||
boolean isIncrement = (valueSetLocalReg.value instanceof IncrementAVM2Item);
|
||||
if (valueSetLocalReg.value.value instanceof DuplicateItem) {
|
||||
GraphTargetItem duplicated = valueSetLocalReg.value.value.value;
|
||||
if (!stack.isEmpty() && stack.peek() == duplicated) {
|
||||
if (output.size() >= 2 && output.get(output.size() - 2) instanceof PushItem && ((PushItem) output.get(output.size() - 2)).value == duplicated) {
|
||||
//if (!stack.isEmpty() && stack.peek() == duplicated) {
|
||||
GraphTargetItem notCoerced = duplicated.getNotCoerced();
|
||||
if (notCoerced instanceof GetPropertyAVM2Item) {
|
||||
GetPropertyAVM2Item getProperty = (GetPropertyAVM2Item) notCoerced;
|
||||
@@ -723,7 +732,9 @@ public abstract class InstructionDefinition implements Serializable {
|
||||
}
|
||||
getProperty.object = objSetLocalReg.value;
|
||||
output.remove(output.size() - 1);
|
||||
stack.pop();
|
||||
output.remove(output.size() - 1);
|
||||
stack.moveToStack(output);
|
||||
//stack.pop();
|
||||
if (isIncrement) {
|
||||
stack.push(new PostIncrementAVM2Item(ins, localData.lineStartInstruction, getProperty));
|
||||
} else {
|
||||
@@ -739,6 +750,7 @@ public abstract class InstructionDefinition implements Serializable {
|
||||
}
|
||||
}
|
||||
|
||||
stack.moveToStack(output);
|
||||
if (!stack.isEmpty()) {
|
||||
GraphTargetItem checked = checkIncDec(false, multinameIndex, ins, localData, stack.peek(), valueLocalReg, nameLocalReg, objLocalReg);
|
||||
if (checked != null) {
|
||||
@@ -758,6 +770,29 @@ public abstract class InstructionDefinition implements Serializable {
|
||||
}
|
||||
}
|
||||
|
||||
if (obj instanceof PopItem) {
|
||||
if (output.size() >= 2
|
||||
&& output.get(output.size() - 1) instanceof SetLocalAVM2Item
|
||||
&& output.get(output.size() - 2) instanceof PushItem
|
||||
&& multiname.name instanceof LocalRegAVM2Item) {
|
||||
SetLocalAVM2Item setLocal = (SetLocalAVM2Item) output.get(output.size() - 1);
|
||||
LocalRegAVM2Item localReg = (LocalRegAVM2Item) multiname.name;
|
||||
PushItem pi = (PushItem) output.get(output.size() - 2);
|
||||
if (setLocal.regIndex == localReg.regIndex) {
|
||||
GraphSourceItem src = setLocal.getSrc();
|
||||
if (src != null) {
|
||||
if (localData.getSetLocalUsages(localData.code.adr2pos(src.getAddress())).size() == 1) {
|
||||
output.remove(output.size() - 1);
|
||||
output.remove(output.size() - 1);
|
||||
stack.moveToStack(output);
|
||||
obj = pi.value;
|
||||
multiname.name = setLocal.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (obj.getThroughDuplicate() instanceof ConstructAVM2Item) {
|
||||
ConstructAVM2Item c = (ConstructAVM2Item) obj.getThroughDuplicate();
|
||||
if (c.object instanceof ApplyTypeAVM2Item) {
|
||||
|
||||
@@ -73,6 +73,7 @@ public interface SetTypeIns {
|
||||
if (notCoercedValue instanceof DuplicateItem) {
|
||||
GraphTargetItem insideDup = notCoercedValue.value;
|
||||
if (!AVM2Item.mustStayIntact1(insideDup.getNotCoercedNoDup())) {
|
||||
stack.moveToStack(output);
|
||||
if (!stack.isEmpty() && stack.peek() == insideDup) {
|
||||
stack.pop();
|
||||
|
||||
@@ -89,6 +90,7 @@ public interface SetTypeIns {
|
||||
value = insideDup;
|
||||
}
|
||||
result.value = value;
|
||||
stack.moveToOutput(output, false);
|
||||
output.add(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()));
|
||||
@@ -109,6 +111,7 @@ public interface SetTypeIns {
|
||||
}
|
||||
|
||||
if (regId > -1 && AVM2Item.mustStayIntact2(insideDup.getNotCoerced())) { //hack
|
||||
stack.moveToOutput(output, false);
|
||||
output.add(result);
|
||||
stack.push(new LocalRegAVM2Item(null, localData.lineStartInstruction, regId, value, localData.localRegTypes.containsKey(regId) ? localData.localRegTypes.get(regId) : TypeItem.UNBOUNDED));
|
||||
return;
|
||||
@@ -120,6 +123,7 @@ public interface SetTypeIns {
|
||||
}
|
||||
}
|
||||
}
|
||||
stack.moveToOutput(output, false);
|
||||
output.add(result);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,6 +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));
|
||||
}
|
||||
|
||||
|
||||
@@ -62,6 +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));
|
||||
}
|
||||
|
||||
|
||||
@@ -62,6 +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));
|
||||
}
|
||||
|
||||
|
||||
@@ -62,6 +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));
|
||||
}
|
||||
|
||||
|
||||
@@ -62,6 +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));
|
||||
}
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ public class ConstructPropIns extends InstructionDefinition {
|
||||
for (int a = 0; a < argCount; a++) {
|
||||
args.add(0, stack.pop());
|
||||
}
|
||||
FullMultinameAVM2Item multiname = resolveMultiname(localData, true, stack, localData.getConstants(), multinameIndex, ins);
|
||||
FullMultinameAVM2Item multiname = resolveMultiname(localData, true, stack, localData.getConstants(), multinameIndex, ins, output);
|
||||
GraphTargetItem obj = stack.pop();
|
||||
|
||||
if (multiname.isXML(localData.abc, localData.localRegNames, localData.fullyQualifiedNames, localData.seenMethods)) {
|
||||
|
||||
@@ -72,6 +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));
|
||||
}
|
||||
|
||||
|
||||
@@ -80,6 +80,7 @@ public class CallIns extends InstructionDefinition {
|
||||
for (int a = 0; a < argCount; a++) {
|
||||
args.add(0, stack.pop());
|
||||
}
|
||||
stack.allowSwap(output);
|
||||
GraphTargetItem receiver = stack.pop();
|
||||
GraphTargetItem function = stack.pop();
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ public class CallPropLexIns extends CallPropertyIns {
|
||||
args.add(0, stack.pop());
|
||||
}
|
||||
|
||||
FullMultinameAVM2Item multiname = resolveMultiname(localData, true, stack, localData.getConstants(), multinameIndex, ins);
|
||||
FullMultinameAVM2Item multiname = resolveMultiname(localData, true, stack, localData.getConstants(), multinameIndex, ins, output);
|
||||
GraphTargetItem obj = stack.pop();
|
||||
|
||||
Reference<Boolean> isStatic = new Reference<>(false);
|
||||
|
||||
@@ -82,13 +82,14 @@ public class CallPropVoidIns extends InstructionDefinition {
|
||||
for (int a = 0; a < argCount; a++) {
|
||||
args.add(0, stack.pop());
|
||||
}
|
||||
FullMultinameAVM2Item multiname = resolveMultiname(localData, true, stack, localData.getConstants(), multinameIndex, ins);
|
||||
FullMultinameAVM2Item multiname = resolveMultiname(localData, true, stack, localData.getConstants(), multinameIndex, ins, output);
|
||||
|
||||
GraphTargetItem obj = stack.pop();
|
||||
Reference<Boolean> isStatic = new Reference<>(false);
|
||||
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()));
|
||||
}
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@ public class CallPropertyIns extends InstructionDefinition {
|
||||
args.add(0, stack.pop());
|
||||
}
|
||||
|
||||
FullMultinameAVM2Item multiname = resolveMultiname(localData, true, stack, localData.getConstants(), multinameIndex, ins);
|
||||
FullMultinameAVM2Item multiname = resolveMultiname(localData, true, stack, localData.getConstants(), multinameIndex, ins, output);
|
||||
GraphTargetItem obj = stack.pop();
|
||||
Reference<Boolean> isStatic = new Reference<>(false);
|
||||
Reference<GraphTargetItem> type = new Reference<>(null);
|
||||
|
||||
@@ -80,7 +80,7 @@ public class CallSuperIns extends InstructionDefinition {
|
||||
for (int a = 0; a < argCount; a++) {
|
||||
args.add(0, stack.pop());
|
||||
}
|
||||
FullMultinameAVM2Item multiname = resolveMultiname(localData, true, stack, localData.getConstants(), multinameIndex, ins);
|
||||
FullMultinameAVM2Item multiname = resolveMultiname(localData, true, stack, localData.getConstants(), multinameIndex, ins, output);
|
||||
GraphTargetItem receiver = stack.pop();
|
||||
|
||||
stack.push(new CallSuperAVM2Item(ins, localData.lineStartInstruction, false, receiver, multiname, args));
|
||||
|
||||
@@ -79,9 +79,10 @@ public class CallSuperVoidIns extends InstructionDefinition {
|
||||
for (int a = 0; a < argCount; a++) {
|
||||
args.add(0, stack.pop());
|
||||
}
|
||||
FullMultinameAVM2Item multiname = resolveMultiname(localData, true, stack, localData.getConstants(), multinameIndex, ins);
|
||||
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));
|
||||
}
|
||||
|
||||
|
||||
@@ -73,6 +73,7 @@ public class DecLocalIIns extends InstructionDefinition {
|
||||
}
|
||||
}
|
||||
if (!isPostDec) {
|
||||
stack.moveToOutput(output, false);
|
||||
output.add(new DecLocalAVM2Item(ins, localData.lineStartInstruction, regId));
|
||||
}
|
||||
if (localData.localRegs.containsKey(regId)) {
|
||||
|
||||
@@ -74,6 +74,7 @@ public class DecLocalIns extends InstructionDefinition {
|
||||
}
|
||||
}
|
||||
if (!isPostDec) {
|
||||
stack.moveToOutput(output, false);
|
||||
output.add(new DecLocalAVM2Item(ins, localData.lineStartInstruction, regId));
|
||||
}
|
||||
if (localData.localRegs.containsKey(regId)) {
|
||||
|
||||
@@ -134,6 +134,7 @@ public abstract class GetLocalTypeIns extends InstructionDefinition {
|
||||
result = new PostDecrementAVM2Item(setProp.getSrc(), localData.lineStartInstruction, getProp);
|
||||
}
|
||||
output.remove(output.size() - 1);
|
||||
stack.moveToStack(output);
|
||||
stack.add(result);
|
||||
return;
|
||||
}
|
||||
@@ -153,6 +154,7 @@ public abstract class GetLocalTypeIns extends InstructionDefinition {
|
||||
}
|
||||
|
||||
output.remove(output.size() - 1);
|
||||
stack.moveToStack(output);
|
||||
|
||||
if (setItem instanceof SetPropertyAVM2Item) {
|
||||
if ((setItem.value instanceof IncrementAVM2Item) || (setItem.value instanceof DecrementAVM2Item)) {
|
||||
@@ -176,7 +178,7 @@ public abstract class GetLocalTypeIns extends InstructionDefinition {
|
||||
}
|
||||
}
|
||||
|
||||
stack.add(setItem);
|
||||
stack.push(setItem);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,6 +73,7 @@ public class IncLocalIIns extends InstructionDefinition {
|
||||
}
|
||||
}
|
||||
if (!isPostInc) {
|
||||
stack.moveToOutput(output, false);
|
||||
output.add(new IncLocalAVM2Item(ins, localData.lineStartInstruction, regId));
|
||||
}
|
||||
if (localData.localRegs.containsKey(regId)) {
|
||||
|
||||
@@ -74,6 +74,7 @@ public class IncLocalIns extends InstructionDefinition {
|
||||
}
|
||||
}
|
||||
if (!isPostInc) {
|
||||
stack.moveToOutput(output, false);
|
||||
output.add(new IncLocalAVM2Item(ins, localData.lineStartInstruction, regId));
|
||||
}
|
||||
if (localData.localRegs.containsKey(regId)) {
|
||||
|
||||
@@ -83,6 +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));
|
||||
return;
|
||||
}
|
||||
@@ -102,9 +103,11 @@ 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));
|
||||
}
|
||||
} else {
|
||||
stack.moveToOutput(output, false);
|
||||
output.add(new PostIncrementAVM2Item(ins, localData.lineStartInstruction, inside));
|
||||
}
|
||||
return;
|
||||
@@ -125,9 +128,11 @@ 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));
|
||||
}
|
||||
} else {
|
||||
stack.moveToOutput(output, false);
|
||||
output.add(new PostDecrementAVM2Item(ins, localData.lineStartInstruction, inside));
|
||||
}
|
||||
return;
|
||||
|
||||
@@ -58,7 +58,7 @@ public class DeletePropertyIns extends InstructionDefinition {
|
||||
@Override
|
||||
public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List<GraphTargetItem> output, String path) {
|
||||
int multinameIndex = ins.operands[0];
|
||||
FullMultinameAVM2Item multiname = resolveMultiname(localData, true, stack, localData.getConstants(), multinameIndex, ins);
|
||||
FullMultinameAVM2Item multiname = resolveMultiname(localData, true, stack, localData.getConstants(), multinameIndex, ins, output);
|
||||
GraphTargetItem obj = stack.pop();
|
||||
Reference<Boolean> isStatic = new Reference<>(false);
|
||||
Reference<GraphTargetItem> type = new Reference<>(null);
|
||||
|
||||
@@ -63,7 +63,7 @@ public class FindPropertyIns extends InstructionDefinition {
|
||||
@Override
|
||||
public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List<GraphTargetItem> output, String path) {
|
||||
int multinameIndex = ins.operands[0];
|
||||
FullMultinameAVM2Item multiname = resolveMultiname(localData, true, stack, localData.getConstants(), multinameIndex, ins);
|
||||
FullMultinameAVM2Item multiname = resolveMultiname(localData, true, stack, localData.getConstants(), multinameIndex, ins, output);
|
||||
stack.push(new FindPropertyAVM2Item(ins, localData.lineStartInstruction, multiname)); //resolve right object
|
||||
}
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ public class FindPropertyStrictIns extends InstructionDefinition {
|
||||
@Override
|
||||
public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List<GraphTargetItem> output, String path) {
|
||||
int multinameIndex = ins.operands[0];
|
||||
FullMultinameAVM2Item multiname = resolveMultiname(localData, true, stack, localData.getConstants(), multinameIndex, ins);
|
||||
FullMultinameAVM2Item multiname = resolveMultiname(localData, true, stack, localData.getConstants(), multinameIndex, ins, output);
|
||||
stack.push(new FindPropertyAVM2Item(ins, localData.lineStartInstruction, multiname));
|
||||
}
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ public class GetDescendantsIns extends InstructionDefinition {
|
||||
@Override
|
||||
public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List<GraphTargetItem> output, String path) {
|
||||
int multinameIndex = ins.operands[0];
|
||||
FullMultinameAVM2Item multiname = resolveMultiname(localData, true, stack, localData.getConstants(), multinameIndex, ins);
|
||||
FullMultinameAVM2Item multiname = resolveMultiname(localData, true, stack, localData.getConstants(), multinameIndex, ins, output);
|
||||
GraphTargetItem obj = stack.pop();
|
||||
stack.push(new GetDescendantsAVM2Item(ins, localData.lineStartInstruction, obj, multiname));
|
||||
}
|
||||
|
||||
@@ -91,8 +91,8 @@ public class GetPropertyIns extends InstructionDefinition {
|
||||
|
||||
@Override
|
||||
public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List<GraphTargetItem> output, String path) {
|
||||
int multinameIndex = ins.operands[0];
|
||||
FullMultinameAVM2Item multiname = resolveMultiname(localData, true, stack, localData.getConstants(), multinameIndex, ins);
|
||||
int multinameIndex = ins.operands[0];
|
||||
FullMultinameAVM2Item multiname = resolveMultiname(localData, true, stack, localData.getConstants(), multinameIndex, ins, output);
|
||||
GraphTargetItem obj = stack.pop();
|
||||
//remove dups
|
||||
if (obj instanceof FindPropertyAVM2Item) {
|
||||
|
||||
@@ -45,7 +45,7 @@ public class GetSuperIns extends InstructionDefinition {
|
||||
@Override
|
||||
public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List<GraphTargetItem> output, String path) {
|
||||
int multinameIndex = ins.operands[0];
|
||||
FullMultinameAVM2Item multiname = resolveMultiname(localData, true, stack, localData.getConstants(), multinameIndex, ins);
|
||||
FullMultinameAVM2Item multiname = resolveMultiname(localData, true, stack, localData.getConstants(), multinameIndex, ins, output);
|
||||
GraphTargetItem obj = stack.pop();
|
||||
|
||||
Reference<Boolean> isStatic = new Reference<>(false);
|
||||
|
||||
@@ -55,6 +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));
|
||||
}
|
||||
|
||||
|
||||
@@ -49,6 +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));
|
||||
}
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@ public class SetGlobalSlotIns extends InstructionDefinition implements SetTypeIn
|
||||
@Override
|
||||
public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List<GraphTargetItem> output, String path) {
|
||||
int slotIndex = ins.operands[0];
|
||||
stack.allowSwap(output);
|
||||
GraphTargetItem value = stack.pop();
|
||||
GraphTargetItem obj = new GlobalAVM2Item(ins, localData.lineStartInstruction);
|
||||
SetSlotIns.handleSetSlot(localData, stack, ins, output, slotIndex, obj, value);
|
||||
|
||||
@@ -61,6 +61,7 @@ public class SetSlotIns extends InstructionDefinition implements SetTypeIns {
|
||||
@Override
|
||||
public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List<GraphTargetItem> output, String path) {
|
||||
int slotIndex = ins.operands[0];
|
||||
stack.allowSwap(output);
|
||||
GraphTargetItem value = stack.pop();
|
||||
GraphTargetItem obj = stack.pop(); //scopeId
|
||||
if (obj.getThroughRegister() instanceof NewActivationAVM2Item) {
|
||||
@@ -100,7 +101,8 @@ public class SetSlotIns extends InstructionDefinition implements SetTypeIns {
|
||||
GetSlotAVM2Item slotItem = (GetSlotAVM2Item) inside;
|
||||
if ((slotItem.scope.getThroughRegister() == obj.getThroughRegister())
|
||||
&& (slotItem.slotName == slotname)) {
|
||||
if (stack.size() > 0) {
|
||||
stack.moveToStack(output);
|
||||
if (!stack.isEmpty()) {
|
||||
GraphTargetItem top = stack.peek().getNotCoerced().getThroughDuplicate();
|
||||
if (top == inside) {
|
||||
stack.pop();
|
||||
@@ -109,9 +111,11 @@ 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));
|
||||
}
|
||||
} else {
|
||||
stack.moveToOutput(output, false);
|
||||
output.add(new PostIncrementAVM2Item(ins, localData.lineStartInstruction, inside));
|
||||
}
|
||||
return;
|
||||
@@ -125,7 +129,8 @@ public class SetSlotIns extends InstructionDefinition implements SetTypeIns {
|
||||
GetSlotAVM2Item slotItem = (GetSlotAVM2Item) inside;
|
||||
if ((slotItem.scope.getThroughRegister() == obj.getThroughRegister())
|
||||
&& (slotItem.slotName == slotname)) {
|
||||
if (stack.size() > 0) {
|
||||
stack.moveToStack(output);
|
||||
if (!stack.isEmpty()) {
|
||||
GraphTargetItem top = stack.peek().getNotCoerced().getThroughDuplicate();
|
||||
if (top == inside) {
|
||||
stack.pop();
|
||||
@@ -134,9 +139,11 @@ 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));
|
||||
}
|
||||
} else {
|
||||
stack.moveToOutput(output, false);
|
||||
output.add(new PostDecrementAVM2Item(ins, localData.lineStartInstruction, inside));
|
||||
}
|
||||
return;
|
||||
|
||||
@@ -48,11 +48,13 @@ public class SetSuperIns extends InstructionDefinition implements SetTypeIns {
|
||||
|
||||
@Override
|
||||
public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List<GraphTargetItem> output, String path) {
|
||||
stack.allowSwap(output);
|
||||
|
||||
int multinameIndex = ins.operands[0];
|
||||
|
||||
GraphTargetItem value = stack.pop();
|
||||
|
||||
FullMultinameAVM2Item multiname = resolveMultiname(localData, true, stack, localData.getConstants(), multinameIndex, ins);
|
||||
FullMultinameAVM2Item multiname = resolveMultiname(localData, true, stack, localData.getConstants(), multinameIndex, ins, output);
|
||||
GraphTargetItem obj = stack.pop();
|
||||
|
||||
Reference<Boolean> isStatic = new Reference<>(false);
|
||||
|
||||
@@ -51,7 +51,9 @@ public class ThrowIns extends InstructionDefinition {
|
||||
|
||||
@Override
|
||||
public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List<GraphTargetItem> output, String path) {
|
||||
output.add(new ThrowAVM2Item(ins, localData.lineStartInstruction, stack.pop()));
|
||||
GraphTargetItem value = stack.pop();
|
||||
stack.moveToOutput(output, true);
|
||||
output.add(new ThrowAVM2Item(ins, localData.lineStartInstruction, value));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -84,6 +84,7 @@ public class DecLocalPIns extends InstructionDefinition {
|
||||
}
|
||||
}
|
||||
if (!isPostDec) {
|
||||
stack.moveToOutput(output, false);
|
||||
output.add(new DecLocalAVM2Item(ins, localData.lineStartInstruction, regId));
|
||||
}
|
||||
if (localData.localRegs.containsKey(regId)) {
|
||||
|
||||
@@ -84,6 +84,7 @@ public class IncLocalPIns extends InstructionDefinition {
|
||||
}
|
||||
}
|
||||
if (!isPostInc) {
|
||||
stack.moveToOutput(output, false);
|
||||
output.add(new IncLocalAVM2Item(ins, localData.lineStartInstruction, regId));
|
||||
}
|
||||
if (localData.localRegs.containsKey(regId)) {
|
||||
|
||||
@@ -63,6 +63,7 @@ public class PopIns extends InstructionDefinition {
|
||||
return;
|
||||
}
|
||||
|
||||
stack.moveToOutput(output, false);
|
||||
output.add(top);
|
||||
}
|
||||
|
||||
|
||||
@@ -53,6 +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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,6 +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));
|
||||
}
|
||||
|
||||
|
||||
@@ -20,11 +20,18 @@ import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.AVM2LocalData;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.graph.AVM2GraphTargetDialect;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.EscapeXAttrAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.clauses.ExceptionAVM2Item;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItemPos;
|
||||
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.PushItem;
|
||||
import com.jpexs.decompiler.graph.model.SwapItem;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -55,10 +62,35 @@ public class SwapIns extends InstructionDefinition {
|
||||
|
||||
GraphTargetItem o1 = stack.pop();
|
||||
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 (((o1 instanceof ExceptionAVM2Item) && (o2 instanceof ExceptionAVM2Item))
|
||||
||
|
||||
(
|
||||
(
|
||||
((o1 instanceof SimpleValue) && ((SimpleValue) o1).isSimpleValue() && !(o1 instanceof DuplicateItem))
|
||||
||
|
||||
(o1 instanceof EscapeXAttrAVM2Item)
|
||||
)
|
||||
&&
|
||||
(
|
||||
((o2 instanceof SimpleValue) && ((SimpleValue) o2).isSimpleValue() && !(o2 instanceof DuplicateItem))
|
||||
||
|
||||
(o2 instanceof EscapeXAttrAVM2Item)
|
||||
)
|
||||
|
||||
)
|
||||
) {
|
||||
stack.push(o1);
|
||||
stack.push(o2);
|
||||
o1.getMoreSrc().add(new GraphSourceItemPos(ins, 0));
|
||||
o2.getMoreSrc().add(new GraphSourceItemPos(ins, 0));
|
||||
return;
|
||||
}
|
||||
|
||||
stack.moveToOutput(output, false);
|
||||
output.add(new PushItem(o2));
|
||||
output.add(new PushItem(o1));
|
||||
output.add(new SwapItem(AVM2GraphTargetDialect.INSTANCE, ins, localData.lineStartInstruction));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -52,6 +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]))));
|
||||
}
|
||||
|
||||
@@ -52,6 +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));
|
||||
|
||||
}
|
||||
|
||||
@@ -104,6 +104,7 @@ import com.jpexs.decompiler.graph.model.NotItem;
|
||||
import com.jpexs.decompiler.graph.model.OrItem;
|
||||
import com.jpexs.decompiler.graph.model.PopItem;
|
||||
import com.jpexs.decompiler.graph.model.PushItem;
|
||||
import com.jpexs.decompiler.graph.model.SwapItem;
|
||||
import com.jpexs.decompiler.graph.model.SwitchItem;
|
||||
import com.jpexs.decompiler.graph.model.TernarOpItem;
|
||||
import com.jpexs.decompiler.graph.model.TrueItem;
|
||||
@@ -3580,6 +3581,13 @@ public class AVM2SourceGenerator implements SourceGenerator {
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GraphSourceItem> generate(SourceGeneratorLocalData localData, SwapItem item) throws CompilationException {
|
||||
List<GraphSourceItem> ret = new ArrayList<>();
|
||||
ret.add(ins(AVM2Instructions.Swap));
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* For some strange reasons, && and || operators must have coerced
|
||||
* both sides when there is specific type expected.
|
||||
|
||||
@@ -118,6 +118,7 @@ import com.jpexs.decompiler.graph.model.OrItem;
|
||||
import com.jpexs.decompiler.graph.model.ParenthesisItem;
|
||||
import com.jpexs.decompiler.graph.model.PopItem;
|
||||
import com.jpexs.decompiler.graph.model.PushItem;
|
||||
import com.jpexs.decompiler.graph.model.SwapItem;
|
||||
import com.jpexs.decompiler.graph.model.SwitchItem;
|
||||
import com.jpexs.decompiler.graph.model.TernarOpItem;
|
||||
import com.jpexs.decompiler.graph.model.TrueItem;
|
||||
@@ -2460,6 +2461,9 @@ public class ActionScript3Parser {
|
||||
ret = new PopItem(DIALECT, null, null);
|
||||
allowMemberOrCall = true;
|
||||
break;
|
||||
case "swap":
|
||||
ret = new SwapItem(DIALECT, null, null);
|
||||
break;
|
||||
case "goto": //TODO
|
||||
case "multiname":
|
||||
throw new AVM2ParseException("Compiling §§" + s.value + " is not available, sorry", lexer.yyline());
|
||||
|
||||
@@ -1886,6 +1886,9 @@ public class ActionScript3SimpleParser implements SimpleParser {
|
||||
ret = true;
|
||||
allowMemberOrCall = true;
|
||||
break;
|
||||
case "swap":
|
||||
ret = true;
|
||||
break;
|
||||
case "goto":
|
||||
expectedType(errors, SymbolGroup.IDENTIFIER);
|
||||
//errors.add(new SimpleParseException("Compiling §§" + s.value + " is not available, sorry", lexer.yyline(), s.position));
|
||||
|
||||
@@ -164,6 +164,7 @@ import com.jpexs.decompiler.graph.model.OrItem;
|
||||
import com.jpexs.decompiler.graph.model.ParenthesisItem;
|
||||
import com.jpexs.decompiler.graph.model.PopItem;
|
||||
import com.jpexs.decompiler.graph.model.PushItem;
|
||||
import com.jpexs.decompiler.graph.model.SwapItem;
|
||||
import com.jpexs.decompiler.graph.model.SwitchItem;
|
||||
import com.jpexs.decompiler.graph.model.TernarOpItem;
|
||||
import com.jpexs.decompiler.graph.model.TrueItem;
|
||||
@@ -1878,6 +1879,9 @@ public class ActionScript2Parser {
|
||||
ret = new PopItem(DIALECT, null, null);
|
||||
allowMemberOrCall = true;
|
||||
break;
|
||||
case "swap":
|
||||
ret = new SwapItem(DIALECT, null, null);
|
||||
break;
|
||||
case "strict":
|
||||
s = lex();
|
||||
expected(s, lexer.yyline(), SymbolType.INTEGER);
|
||||
|
||||
@@ -1342,6 +1342,9 @@ public class ActionScript2SimpleParser implements SimpleParser {
|
||||
ret = true;
|
||||
allowMemberOrCall = true;
|
||||
break;
|
||||
case "swap":
|
||||
ret = true;
|
||||
break;
|
||||
case "strict":
|
||||
s = lexer.lex();
|
||||
expected(errors, s, lexer.yyline(), SymbolType.INTEGER);
|
||||
|
||||
@@ -40,6 +40,7 @@ import com.jpexs.decompiler.flash.action.swf5.ActionGetMember;
|
||||
import com.jpexs.decompiler.flash.action.swf5.ActionNewObject;
|
||||
import com.jpexs.decompiler.flash.action.swf5.ActionPushDuplicate;
|
||||
import com.jpexs.decompiler.flash.action.swf5.ActionSetMember;
|
||||
import com.jpexs.decompiler.flash.action.swf5.ActionStackSwap;
|
||||
import com.jpexs.decompiler.flash.action.swf5.ActionStoreRegister;
|
||||
import com.jpexs.decompiler.flash.action.swf6.ActionStrictEquals;
|
||||
import com.jpexs.decompiler.flash.action.swf7.ActionExtends;
|
||||
@@ -65,6 +66,7 @@ import com.jpexs.decompiler.graph.model.NotItem;
|
||||
import com.jpexs.decompiler.graph.model.OrItem;
|
||||
import com.jpexs.decompiler.graph.model.PopItem;
|
||||
import com.jpexs.decompiler.graph.model.PushItem;
|
||||
import com.jpexs.decompiler.graph.model.SwapItem;
|
||||
import com.jpexs.decompiler.graph.model.SwitchItem;
|
||||
import com.jpexs.decompiler.graph.model.TernarOpItem;
|
||||
import com.jpexs.decompiler.graph.model.TrueItem;
|
||||
@@ -1191,7 +1193,6 @@ public class ActionSourceGenerator implements SourceGenerator {
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
private int checkOffsetBounds(int offset, String errorItem, int errorLine) throws CompilationException {
|
||||
if (offset < -32768) {
|
||||
throw new CompilationException("Generated offset for " + errorItem + " is lower than mininum allowed for SI16.", errorLine);
|
||||
@@ -1201,4 +1202,10 @@ public class ActionSourceGenerator implements SourceGenerator {
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
@Override
|
||||
public List<GraphSourceItem> generate(SourceGeneratorLocalData localData, SwapItem item) throws CompilationException {
|
||||
List<GraphSourceItem> ret = new ArrayList<>();
|
||||
ret.add(new ActionStackSwap());
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3369,6 +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));
|
||||
}
|
||||
return ret;
|
||||
@@ -3533,6 +3534,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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import com.jpexs.decompiler.graph.model.NotItem;
|
||||
import com.jpexs.decompiler.graph.model.OrItem;
|
||||
import com.jpexs.decompiler.graph.model.PopItem;
|
||||
import com.jpexs.decompiler.graph.model.PushItem;
|
||||
import com.jpexs.decompiler.graph.model.SwapItem;
|
||||
import com.jpexs.decompiler.graph.model.SwitchItem;
|
||||
import com.jpexs.decompiler.graph.model.TernarOpItem;
|
||||
import com.jpexs.decompiler.graph.model.TrueItem;
|
||||
@@ -243,4 +244,14 @@ public interface SourceGenerator {
|
||||
* @throws CompilationException On compilation error
|
||||
*/
|
||||
public List<GraphSourceItem> generateDiscardValue(SourceGeneratorLocalData localData, GraphTargetItem item) throws CompilationException;
|
||||
|
||||
/**
|
||||
* Generates source code for SwapItem.
|
||||
*
|
||||
* @param localData Local data
|
||||
* @param item SwapItem
|
||||
* @return List of GraphSourceItem
|
||||
* @throws CompilationException On compilation error
|
||||
*/
|
||||
public List<GraphSourceItem> generate(SourceGeneratorLocalData localData, SwapItem item) throws CompilationException;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,12 @@
|
||||
*/
|
||||
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.PopItem;
|
||||
import com.jpexs.decompiler.graph.model.PushItem;
|
||||
import com.jpexs.decompiler.graph.model.SwapItem;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -144,6 +149,10 @@ public class TranslateStack extends Stack<GraphTargetItem> {
|
||||
public synchronized GraphTargetItem peek() {
|
||||
if (path != null) {
|
||||
if (this.isEmpty()) {
|
||||
/*if (connectedOutput != null && !connectedOutput.isEmpty() && connectedOutput.get(connectedOutput.size() - 1) instanceof PushItem) {
|
||||
PushItem pi = (PushItem) connectedOutput.get(connectedOutput.size() - 1);
|
||||
return pi.value;
|
||||
}*/
|
||||
Logger.getLogger(TranslateStack.class.getName()).log(Level.FINE, "{0}: Attempt to Peek empty stack", path);
|
||||
return getPop();
|
||||
}
|
||||
@@ -160,6 +169,10 @@ public class TranslateStack extends Stack<GraphTargetItem> {
|
||||
public synchronized GraphTargetItem peek(int index) {
|
||||
if (path != null) {
|
||||
if (index > this.size()) {
|
||||
/*if (connectedOutput != null && connectedOutput.size() >= index - this.size() && connectedOutput.get(connectedOutput.size() - (index - this.size())) instanceof PushItem) {
|
||||
PushItem pi = (PushItem) connectedOutput.get(connectedOutput.size() - (index - this.size()));
|
||||
return pi.value;
|
||||
}*/
|
||||
Logger.getLogger(TranslateStack.class.getName()).log(Level.FINE, "{0}: Attempt to Peek item from stack", path);
|
||||
return getPop();
|
||||
}
|
||||
@@ -176,6 +189,11 @@ public class TranslateStack extends Stack<GraphTargetItem> {
|
||||
public synchronized GraphTargetItem pop() {
|
||||
if (path != null) {
|
||||
if (this.isEmpty()) {
|
||||
/*if (connectedOutput != null && !connectedOutput.isEmpty() && connectedOutput.get(connectedOutput.size() - 1) instanceof PushItem) {
|
||||
PushItem pi = (PushItem) connectedOutput.remove(connectedOutput.size() - 1);
|
||||
return pi.value;
|
||||
}*/
|
||||
|
||||
PopItem oldpop = getPop();
|
||||
pop = null;
|
||||
Logger.getLogger(TranslateStack.class.getName()).log(Level.FINE, "{0}: Attempt to Pop empty stack", path);
|
||||
@@ -184,4 +202,68 @@ public class TranslateStack extends Stack<GraphTargetItem> {
|
||||
}
|
||||
return super.pop();
|
||||
}
|
||||
|
||||
public void moveToStack(List<GraphTargetItem> output) {
|
||||
if (!isEmpty()) {
|
||||
return;
|
||||
}
|
||||
int i = output.size() - 1;
|
||||
for (; i >= 0; i--) {
|
||||
if (!(output.get(i) instanceof PushItem)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
while(i < output.size()) {
|
||||
PushItem pi = (PushItem) output.remove(i);
|
||||
push(pi.value);
|
||||
}
|
||||
}
|
||||
|
||||
public void moveToOutput(List<GraphTargetItem> output, boolean beforeExit) {
|
||||
if (true) {
|
||||
//return;
|
||||
}
|
||||
int pos = output.size();
|
||||
|
||||
for (int i = size() - 1; i >= 0; i--) {
|
||||
GraphTargetItem item = get(i);
|
||||
if (item instanceof BranchStackResistant) {
|
||||
continue;
|
||||
}
|
||||
if (item instanceof NewActivationAVM2Item) {
|
||||
break;
|
||||
}
|
||||
if (item instanceof ExceptionAVM2Item) {
|
||||
break;
|
||||
}
|
||||
remove(i);
|
||||
output.add(pos, beforeExit ? item : new PushItem(item));
|
||||
}
|
||||
}
|
||||
|
||||
public void allowSwap(List<GraphTargetItem> output) {
|
||||
if (!isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (output.size() < 3) {
|
||||
return;
|
||||
}
|
||||
if (!(output.get(output.size() - 1) instanceof SwapItem)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(output.get(output.size() - 2) instanceof PushItem)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(output.get(output.size() - 3) instanceof PushItem)) {
|
||||
return;
|
||||
}
|
||||
|
||||
output.remove(output.size() - 1);
|
||||
push(((PushItem)output.remove(output.size() - 1)).value);
|
||||
push(((PushItem)output.remove(output.size() - 1)).value);
|
||||
//moveToStack(output);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,9 +59,9 @@ public class DuplicateItem extends GraphTargetItem implements SimpleValue {
|
||||
|
||||
@Override
|
||||
public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException {
|
||||
if (!value.hasSideEffect() || !Configuration.displayDupInstructions.get()) {
|
||||
/*if (!value.hasSideEffect() || !Configuration.displayDupInstructions.get()) {
|
||||
return value.appendTry(writer, localData);
|
||||
}
|
||||
}*/
|
||||
writer.append("§§dup(");
|
||||
value.appendTry(writer, localData);
|
||||
return writer.append(")");
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* 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.ecma.Null;
|
||||
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.SourceGenerator;
|
||||
import com.jpexs.decompiler.graph.TypeItem;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Pop item from the stack.
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class SwapItem extends GraphTargetItem {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param dialect Dialect
|
||||
* @param src Source
|
||||
* @param lineStartIns Line start instruction
|
||||
*/
|
||||
public SwapItem(GraphTargetDialect dialect, GraphSourceItem src, GraphSourceItem lineStartIns) {
|
||||
super(dialect, src, lineStartIns, PRECEDENCE_PRIMARY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException {
|
||||
writer.append("§§swap()");
|
||||
return writer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasReturnValue() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTargetItem returnType() {
|
||||
return TypeItem.UNBOUNDED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getResult() {
|
||||
return Null.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GraphSourceItem> toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException {
|
||||
return generator.generate(localData, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasSideEffect() {
|
||||
return true; //?
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user