mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-09-24 23:21:21 +00:00
Better Pre/Post increments/decrements.
Temporary registers hidden.
This commit is contained in:
@@ -527,6 +527,8 @@ public class AVM2Code {
|
||||
};
|
||||
//endoflist
|
||||
public static InstructionDefinition instructionSetByCode[] = buildInstructionSetByCode();
|
||||
|
||||
public boolean hideTemporaryRegisters=true;
|
||||
|
||||
private static InstructionDefinition[] buildInstructionSetByCode() {
|
||||
InstructionDefinition result[] = new InstructionDefinition[256];
|
||||
@@ -948,7 +950,7 @@ public class AVM2Code {
|
||||
return localRegNames;
|
||||
}
|
||||
|
||||
private void clearKilledAssigments(List<TreeItem> output) {
|
||||
private void clearTemporaryRegisters(List<TreeItem> output) {
|
||||
for (int i = 0; i < output.size(); i++) {
|
||||
if (output.get(i) instanceof SetLocalTreeItem) {
|
||||
if (isKilled(((SetLocalTreeItem) output.get(i)).regIndex, 0, code.size() - 1)) {
|
||||
@@ -1471,148 +1473,6 @@ public class AVM2Code {
|
||||
} else if (insAfter.definition instanceof IfTrueIns) {
|
||||
//stack.add("(" + stack.pop() + ")||");
|
||||
isAnd = false;
|
||||
} else if ((insAfter.definition instanceof IncrementIIns) || ((insAfter.definition instanceof IncrementIns))) {
|
||||
int np = -1;
|
||||
if (((np = ipOfType(ip + 2, false, SetLocalTypeIns.class, CoerceOrConvertTypeIns.class, start, end)) > -1)
|
||||
&& (ipOfType(ip - 1, true, GetLocalTypeIns.class, CoerceOrConvertTypeIns.class, start, end) > -1)) {
|
||||
stack.add(new PostIncrementTreeItem(insAfter, stack.pop()));
|
||||
ip = np + 1;
|
||||
addr = pos2adr(ip);
|
||||
break;
|
||||
}
|
||||
if (((ip - 1 >= start) && (ip + 2 <= end))
|
||||
&& (code.get(ip + 2).definition instanceof SetLocalTypeIns)
|
||||
&& (isKilled(((SetLocalTypeIns) code.get(ip + 2).definition).getRegisterId(code.get(ip + 2)), ip + 3, end))) {
|
||||
int pos = -1;
|
||||
for (int d = ip + 3; d <= end; d++) {
|
||||
if (!((code.get(d).definition instanceof GetLocalTypeIns)
|
||||
&& (isKilled(((GetLocalTypeIns) code.get(d).definition).getRegisterId(code.get(d)), d + 1, end)))) {
|
||||
pos = d;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (pos > -1) {
|
||||
if (code.get(pos).definition instanceof SetTypeIns) {
|
||||
stack.push(new PostIncrementTreeItem(insAfter, stack.pop()));
|
||||
ip = pos + 1;
|
||||
addr = pos2adr(ip);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
ins.definition.translate(isStatic, classIndex, localRegs, stack, scopeStack, constants, ins, method_info, output, body, abc, localRegNames);
|
||||
ip++;
|
||||
addr = pos2adr(ip);
|
||||
break;
|
||||
} else if ((insAfter.definition instanceof DecrementIIns) || ((insAfter.definition instanceof DecrementIns))) {
|
||||
int np = -1;
|
||||
if (((np = ipOfType(ip + 2, false, SetLocalTypeIns.class, CoerceOrConvertTypeIns.class, start, end)) > -1)
|
||||
&& (ipOfType(ip - 1, true, GetLocalTypeIns.class, CoerceOrConvertTypeIns.class, start, end) > -1)) {
|
||||
stack.add(new PostDecrementTreeItem(insAfter, stack.pop()));
|
||||
ip = np + 1;
|
||||
addr = pos2adr(ip);
|
||||
break;
|
||||
}
|
||||
if (((ip - 1 >= start) && (ip + 2 <= end))
|
||||
&& (code.get(ip + 2).definition instanceof SetLocalTypeIns)
|
||||
&& (isKilled(((SetLocalTypeIns) code.get(ip + 2).definition).getRegisterId(code.get(ip + 2)), ip + 3, end))) {
|
||||
int pos = -1;
|
||||
for (int d = ip + 3; d <= end; d++) {
|
||||
if (!((code.get(d).definition instanceof GetLocalTypeIns)
|
||||
&& (isKilled(((GetLocalTypeIns) code.get(d).definition).getRegisterId(code.get(d)), d + 1, end)))) {
|
||||
pos = d;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (pos > -1) {
|
||||
if (code.get(pos).definition instanceof SetTypeIns) {
|
||||
stack.push(new PostDecrementTreeItem(insAfter, stack.pop()));
|
||||
ip = pos + 1;
|
||||
addr = pos2adr(ip);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
ins.definition.translate(isStatic, classIndex, localRegs, stack, scopeStack, constants, ins, method_info, output, body, abc, localRegNames);
|
||||
ip++;
|
||||
addr = pos2adr(ip);
|
||||
break;
|
||||
} else if ((insBefore.definition instanceof IncrementIIns) || ((insBefore.definition instanceof IncrementIns))) {
|
||||
if (((ip - 2 >= start) && (ip + 2 <= end)) && (code.get(ip + 1).definition instanceof CoerceOrConvertTypeIns) && (code.get(ip + 2).definition instanceof SetLocalTypeIns) && (code.get(ip - 2).definition instanceof GetLocalTypeIns)) {
|
||||
stack.pop();
|
||||
int regId = ((SetLocalTypeIns) code.get(ip + 2).definition).getRegisterId(code.get(ip + 2));
|
||||
stack.add(new PreIncrementTreeItem(insBefore, new LocalRegTreeItem(code.get(ip + 2), regId, localRegs.get(regId))));
|
||||
ip += 3;
|
||||
addr = pos2adr(ip);
|
||||
break;
|
||||
}
|
||||
if (((ip - 1 >= start) && (ip + 2 <= end))
|
||||
&& (code.get(ip + 1).definition instanceof SetLocalTypeIns)
|
||||
&& (isKilled(((SetLocalTypeIns) code.get(ip + 1).definition).getRegisterId(code.get(ip + 1)), ip + 2, end))) {
|
||||
int pos = -1;
|
||||
for (int d = ip + 2; d <= end; d++) {
|
||||
if (!((code.get(d).definition instanceof GetLocalTypeIns)
|
||||
&& (isKilled(((GetLocalTypeIns) code.get(d).definition).getRegisterId(code.get(d)), d + 1, end)))) {
|
||||
pos = d;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (pos > -1) {
|
||||
if (code.get(pos).definition instanceof SetTypeIns) {
|
||||
TreeItem s = stack.pop();
|
||||
if (s instanceof IncrementTreeItem) {
|
||||
stack.push(new PreIncrementTreeItem(insBefore, ((IncrementTreeItem) s).object));
|
||||
}
|
||||
ip = pos + 1;
|
||||
addr = pos2adr(ip);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
ins.definition.translate(isStatic, classIndex, localRegs, stack, scopeStack, constants, ins, method_info, output, body, abc, localRegNames);
|
||||
ip++;
|
||||
addr = pos2adr(ip);
|
||||
break;
|
||||
} else if ((insBefore.definition instanceof DecrementIIns) || ((insBefore.definition instanceof DecrementIns))) {
|
||||
if (((ip - 2 >= start) && (ip + 2 <= end)) && (code.get(ip + 1).definition instanceof CoerceOrConvertTypeIns) && (code.get(ip + 2).definition instanceof SetLocalTypeIns) && (code.get(ip - 2).definition instanceof GetLocalTypeIns)) {
|
||||
stack.pop();
|
||||
int regId = ((SetLocalTypeIns) code.get(ip + 2).definition).getRegisterId(code.get(ip + 2));
|
||||
stack.add(new PreDecrementTreeItem(insBefore, new LocalRegTreeItem(code.get(ip + 2), regId, localRegs.get(regId))));
|
||||
ip += 3;
|
||||
addr = pos2adr(ip);
|
||||
break;
|
||||
}
|
||||
if (((ip - 1 >= start) && (ip + 2 <= end))
|
||||
&& (code.get(ip + 1).definition instanceof SetLocalTypeIns)
|
||||
&& (isKilled(((SetLocalTypeIns) code.get(ip + 1).definition).getRegisterId(code.get(ip + 1)), ip + 2, end))) {
|
||||
int pos = -1;
|
||||
for (int d = ip + 2; d <= end; d++) {
|
||||
if (!((code.get(d).definition instanceof GetLocalTypeIns)
|
||||
&& (isKilled(((GetLocalTypeIns) code.get(d).definition).getRegisterId(code.get(d)), d + 1, end)))) {
|
||||
pos = d;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (pos > -1) {
|
||||
if (code.get(pos).definition instanceof SetTypeIns) {
|
||||
TreeItem s = stack.pop();
|
||||
if (s instanceof DecrementTreeItem) {
|
||||
stack.push(new PreDecrementTreeItem(insBefore, ((DecrementTreeItem) s).object));
|
||||
}
|
||||
ip = pos + 1;
|
||||
addr = pos2adr(ip);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
ins.definition.translate(isStatic, classIndex, localRegs, stack, scopeStack, constants, ins, method_info, output, body, abc, localRegNames);
|
||||
ip++;
|
||||
addr = pos2adr(ip);
|
||||
break;
|
||||
} else if (insAfter.definition instanceof SetLocalTypeIns) {
|
||||
//chained assignments
|
||||
int reg = (((SetLocalTypeIns) insAfter.definition).getRegisterId(insAfter));
|
||||
@@ -1728,7 +1588,10 @@ public class AVM2Code {
|
||||
if (debugMode) {
|
||||
System.out.println("CLOSE SubSource:" + start + "-" + end + " " + code.get(start).toString() + " to " + code.get(end).toString());
|
||||
}
|
||||
//clearKilledAssigments(output);
|
||||
if(hideTemporaryRegisters)
|
||||
{
|
||||
clearTemporaryRegisters(output);
|
||||
}
|
||||
return new ConvertOutput(stack, output);
|
||||
} catch (ConvertException cex) {
|
||||
throw cex;
|
||||
@@ -1736,6 +1599,7 @@ public class AVM2Code {
|
||||
if (ex instanceof UnknownJumpException) {
|
||||
throw (UnknownJumpException) ex;
|
||||
}
|
||||
ex.printStackTrace();
|
||||
throw new ConvertException(ex.getClass().getSimpleName(), ip);
|
||||
}
|
||||
}
|
||||
@@ -1813,6 +1677,7 @@ public class AVM2Code {
|
||||
list = toSource(isStatic, classIndex, localRegs, new Stack<TreeItem>(), new Stack<TreeItem>(), abc, constants, method_info, body, 0, code.size() - 1, localRegNames).output;
|
||||
s = listToString(list, constants, localRegNames);
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
s = "/*\r\n * Decompilation error\r\n * Code may be obfuscated\r\n * Error Message: " + ex.getMessage() + "\r\n */";
|
||||
return s;
|
||||
}
|
||||
@@ -1842,7 +1707,7 @@ public class AVM2Code {
|
||||
}
|
||||
HashMap<Integer, String> localRegTypes = getLocalRegTypes(constants);
|
||||
for (int i = paramCount + 1; i < regCount; i++) {
|
||||
if ((!(localRegs.get(i) instanceof NewActivationTreeItem))/*&&(!isKilled(i, 0, code.size()-1))*/) {
|
||||
if ((!(localRegs.get(i) instanceof NewActivationTreeItem)&&((!hideTemporaryRegisters)||(!isKilled(i, 0, code.size()-1))))) {
|
||||
sub += "var " + TreeItem.localRegName(localRegNames, i);
|
||||
if (localRegTypes.containsKey(i)) {
|
||||
sub += ":" + localRegTypes.get(i);
|
||||
|
||||
@@ -31,42 +31,13 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class SetLocal0Ins extends InstructionDefinition implements SetTypeIns, SetLocalTypeIns {
|
||||
public class SetLocal0Ins extends SetLocalTypeIns {
|
||||
|
||||
public SetLocal0Ins() {
|
||||
super(0xd4, "setlocal_0", new int[]{});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(LocalDataArea lda, ConstantPool constants, List arguments) {
|
||||
lda.localRegisters.put(0, lda.operandStack.pop());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.asdec.abc.types.MethodBody body, com.jpexs.asdec.abc.ABC abc, HashMap<Integer, String> localRegNames) {
|
||||
TreeItem val = (TreeItem) stack.pop();
|
||||
localRegs.put(0, val);
|
||||
if (val instanceof NewActivationTreeItem) {
|
||||
return;
|
||||
}
|
||||
if (val instanceof FindPropertyTreeItem) {
|
||||
return;
|
||||
}
|
||||
//if(val.startsWith("catchscope ")) return;
|
||||
//if(val.startsWith("newactivation()")) return;
|
||||
output.add(new SetLocalTreeItem(ins, 0, val));
|
||||
}
|
||||
|
||||
public String getObject(Stack<TreeItem> stack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.asdec.abc.types.MethodBody body, HashMap<Integer, String> localRegNames) {
|
||||
return TreeItem.localRegName(localRegNames, 0);
|
||||
}
|
||||
|
||||
|
||||
public int getRegisterId(AVM2Instruction ins) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,42 +31,14 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class SetLocal1Ins extends InstructionDefinition implements SetTypeIns, SetLocalTypeIns {
|
||||
public class SetLocal1Ins extends SetLocalTypeIns {
|
||||
|
||||
public SetLocal1Ins() {
|
||||
super(0xd5, "setlocal_1", new int[]{});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(LocalDataArea lda, ConstantPool constants, List arguments) {
|
||||
lda.localRegisters.put(1, lda.operandStack.pop());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.asdec.abc.types.MethodBody body, com.jpexs.asdec.abc.ABC abc, HashMap<Integer, String> localRegNames) {
|
||||
TreeItem val = (TreeItem) stack.pop();
|
||||
localRegs.put(1, val);
|
||||
if (val instanceof NewActivationTreeItem) {
|
||||
return;
|
||||
}
|
||||
if (val instanceof FindPropertyTreeItem) {
|
||||
return;
|
||||
}
|
||||
//if(val.startsWith("catchscope ")) return;
|
||||
//if(val.startsWith("newactivation()")) return;
|
||||
output.add(new SetLocalTreeItem(ins, 1, val));
|
||||
}
|
||||
|
||||
public String getObject(Stack<TreeItem> stack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.asdec.abc.types.MethodBody body, HashMap<Integer, String> localRegNames) {
|
||||
return TreeItem.localRegName(localRegNames, 1);
|
||||
}
|
||||
|
||||
public int getRegisterId(AVM2Instruction ins) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,42 +31,13 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class SetLocal2Ins extends InstructionDefinition implements SetTypeIns, SetLocalTypeIns {
|
||||
public class SetLocal2Ins extends SetLocalTypeIns {
|
||||
|
||||
public SetLocal2Ins() {
|
||||
super(0xd6, "setlocal_2", new int[]{});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(LocalDataArea lda, ConstantPool constants, List arguments) {
|
||||
lda.localRegisters.put(2, lda.operandStack.pop());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.asdec.abc.types.MethodBody body, com.jpexs.asdec.abc.ABC abc, HashMap<Integer, String> localRegNames) {
|
||||
TreeItem val = (TreeItem) stack.pop();
|
||||
localRegs.put(2, val);
|
||||
if (val instanceof NewActivationTreeItem) {
|
||||
return;
|
||||
}
|
||||
if (val instanceof FindPropertyTreeItem) {
|
||||
return;
|
||||
}
|
||||
//if(val.startsWith("catchscope ")) return;
|
||||
//if(val.startsWith("newactivation()")) return;
|
||||
output.add(new SetLocalTreeItem(ins, 2, val));
|
||||
}
|
||||
|
||||
public String getObject(Stack<TreeItem> stack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.asdec.abc.types.MethodBody body, HashMap<Integer, String> localRegNames) {
|
||||
return TreeItem.localRegName(localRegNames, 2);
|
||||
}
|
||||
|
||||
public int getRegisterId(AVM2Instruction ins) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,42 +31,13 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class SetLocal3Ins extends InstructionDefinition implements SetTypeIns, SetLocalTypeIns {
|
||||
public class SetLocal3Ins extends SetLocalTypeIns {
|
||||
|
||||
public SetLocal3Ins() {
|
||||
super(0xd7, "setlocal_3", new int[]{});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(LocalDataArea lda, ConstantPool constants, List arguments) {
|
||||
lda.localRegisters.put(3, lda.operandStack.pop());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.asdec.abc.types.MethodBody body, com.jpexs.asdec.abc.ABC abc, HashMap<Integer, String> localRegNames) {
|
||||
TreeItem val = (TreeItem) stack.pop();
|
||||
localRegs.put(3, val);
|
||||
if (val instanceof NewActivationTreeItem) {
|
||||
return;
|
||||
}
|
||||
if (val instanceof FindPropertyTreeItem) {
|
||||
return;
|
||||
}
|
||||
//if(val.startsWith("catchscope ")) return;
|
||||
//if(val.startsWith("newactivation()")) return;
|
||||
output.add(new SetLocalTreeItem(ins, 3, val));
|
||||
}
|
||||
|
||||
public String getObject(Stack<TreeItem> stack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.asdec.abc.types.MethodBody body, HashMap<Integer, String> localRegNames) {
|
||||
return TreeItem.localRegName(localRegNames, 3);
|
||||
}
|
||||
|
||||
public int getRegisterId(AVM2Instruction ins) {
|
||||
return 3;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,42 +32,13 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class SetLocalIns extends InstructionDefinition implements SetTypeIns, SetLocalTypeIns {
|
||||
public class SetLocalIns extends SetLocalTypeIns {
|
||||
|
||||
public SetLocalIns() {
|
||||
super(0x63, "setlocal", new int[]{AVM2Code.DAT_LOCAL_REG_INDEX});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(LocalDataArea lda, ConstantPool constants, List arguments) {
|
||||
lda.localRegisters.put((int) (long) (Long) arguments.get(0), lda.operandStack.pop());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.asdec.abc.types.MethodBody body, com.jpexs.asdec.abc.ABC abc, HashMap<Integer, String> localRegNames) {
|
||||
TreeItem val = (TreeItem) stack.pop();
|
||||
localRegs.put(ins.operands[0], val);
|
||||
if (val instanceof NewActivationTreeItem) {
|
||||
return;
|
||||
}
|
||||
if (val instanceof FindPropertyTreeItem) {
|
||||
return;
|
||||
}
|
||||
//if(val.startsWith("catchscope ")) return;
|
||||
//if(val.startsWith("newactivation()")) return;
|
||||
output.add(new SetLocalTreeItem(ins, ins.operands[0], val));
|
||||
}
|
||||
|
||||
public String getObject(Stack<TreeItem> stack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.asdec.abc.types.MethodBody body, HashMap<Integer, String> localRegNames) {
|
||||
return TreeItem.localRegName(localRegNames, ins.operands[0]);
|
||||
}
|
||||
|
||||
public int getRegisterId(AVM2Instruction ins) {
|
||||
return ins.operands[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,9 +16,104 @@
|
||||
*/
|
||||
package com.jpexs.asdec.abc.avm2.instructions.localregs;
|
||||
|
||||
import com.jpexs.asdec.abc.ABC;
|
||||
import com.jpexs.asdec.abc.avm2.ConstantPool;
|
||||
import com.jpexs.asdec.abc.avm2.instructions.AVM2Instruction;
|
||||
import com.jpexs.asdec.abc.avm2.instructions.InstructionDefinition;
|
||||
import com.jpexs.asdec.abc.avm2.instructions.SetTypeIns;
|
||||
import com.jpexs.asdec.abc.avm2.treemodel.DecrementTreeItem;
|
||||
import com.jpexs.asdec.abc.avm2.treemodel.FindPropertyTreeItem;
|
||||
import com.jpexs.asdec.abc.avm2.treemodel.GetPropertyTreeItem;
|
||||
import com.jpexs.asdec.abc.avm2.treemodel.IncrementTreeItem;
|
||||
import com.jpexs.asdec.abc.avm2.treemodel.LocalRegTreeItem;
|
||||
import com.jpexs.asdec.abc.avm2.treemodel.NewActivationTreeItem;
|
||||
import com.jpexs.asdec.abc.avm2.treemodel.PostDecrementTreeItem;
|
||||
import com.jpexs.asdec.abc.avm2.treemodel.PostIncrementTreeItem;
|
||||
import com.jpexs.asdec.abc.avm2.treemodel.SetLocalTreeItem;
|
||||
import com.jpexs.asdec.abc.avm2.treemodel.TreeItem;
|
||||
import com.jpexs.asdec.abc.avm2.treemodel.operations.PreDecrementTreeItem;
|
||||
import com.jpexs.asdec.abc.avm2.treemodel.operations.PreIncrementTreeItem;
|
||||
import com.jpexs.asdec.abc.types.MethodInfo;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public interface SetLocalTypeIns {
|
||||
public abstract class SetLocalTypeIns extends InstructionDefinition implements SetTypeIns {
|
||||
|
||||
public SetLocalTypeIns(int instructionCode, String instructionName, int[] operands) {
|
||||
super(instructionCode, instructionName, operands);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.asdec.abc.types.MethodBody body, com.jpexs.asdec.abc.ABC abc, HashMap<Integer, String> localRegNames) {
|
||||
int regId = getRegisterId(ins);
|
||||
TreeItem value = (TreeItem) stack.pop();
|
||||
localRegs.put(regId, value);
|
||||
if (value instanceof NewActivationTreeItem) {
|
||||
return;
|
||||
}
|
||||
if (value instanceof FindPropertyTreeItem) {
|
||||
return;
|
||||
}
|
||||
if (value.getNotCoerced() instanceof IncrementTreeItem) {
|
||||
TreeItem inside = ((IncrementTreeItem) value.getNotCoerced()).object.getNotCoerced();
|
||||
if (inside instanceof LocalRegTreeItem) {
|
||||
if (((LocalRegTreeItem) inside).regIndex == regId) {
|
||||
if (stack.size() > 0) {
|
||||
TreeItem top = stack.peek().getNotCoerced();
|
||||
if (top == inside) {
|
||||
stack.pop();
|
||||
stack.push(new PostIncrementTreeItem(ins, inside));
|
||||
} else if ((top instanceof IncrementTreeItem) && (((IncrementTreeItem) top).object == inside)) {
|
||||
stack.pop();
|
||||
stack.push(new PreIncrementTreeItem(ins, inside));
|
||||
} else {
|
||||
output.add(new PostIncrementTreeItem(ins, inside));
|
||||
}
|
||||
} else {
|
||||
output.add(new PostIncrementTreeItem(ins, inside));
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (value.getNotCoerced() instanceof DecrementTreeItem) {
|
||||
TreeItem inside = ((DecrementTreeItem) value.getNotCoerced()).object.getNotCoerced();
|
||||
if (inside instanceof LocalRegTreeItem) {
|
||||
if (((LocalRegTreeItem) inside).regIndex == regId) {
|
||||
if (stack.size() > 0) {
|
||||
TreeItem top = stack.peek().getNotCoerced();
|
||||
if (top == inside) {
|
||||
stack.pop();
|
||||
stack.push(new PostDecrementTreeItem(ins, inside));
|
||||
} else if ((top instanceof DecrementTreeItem) && (((DecrementTreeItem) top).object == inside)) {
|
||||
stack.pop();
|
||||
stack.push(new PreDecrementTreeItem(ins, inside));
|
||||
} else {
|
||||
output.add(new PostDecrementTreeItem(ins, inside));
|
||||
}
|
||||
} else {
|
||||
output.add(new PostDecrementTreeItem(ins, inside));
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//if(val.startsWith("catchscope ")) return;
|
||||
//if(val.startsWith("newactivation()")) return;
|
||||
output.add(new SetLocalTreeItem(ins, regId, value));
|
||||
}
|
||||
|
||||
public String getObject(Stack<TreeItem> stack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.asdec.abc.types.MethodBody body, HashMap<Integer, String> localRegNames) {
|
||||
return TreeItem.localRegName(localRegNames, getRegisterId(ins));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
public abstract int getRegisterId(AVM2Instruction ins);
|
||||
}
|
||||
|
||||
@@ -22,9 +22,17 @@ import com.jpexs.asdec.abc.avm2.ConstantPool;
|
||||
import com.jpexs.asdec.abc.avm2.instructions.AVM2Instruction;
|
||||
import com.jpexs.asdec.abc.avm2.instructions.InstructionDefinition;
|
||||
import com.jpexs.asdec.abc.avm2.instructions.SetTypeIns;
|
||||
import com.jpexs.asdec.abc.avm2.treemodel.DecrementTreeItem;
|
||||
import com.jpexs.asdec.abc.avm2.treemodel.FullMultinameTreeItem;
|
||||
import com.jpexs.asdec.abc.avm2.treemodel.GetPropertyTreeItem;
|
||||
import com.jpexs.asdec.abc.avm2.treemodel.IncrementTreeItem;
|
||||
import com.jpexs.asdec.abc.avm2.treemodel.LocalRegTreeItem;
|
||||
import com.jpexs.asdec.abc.avm2.treemodel.PostDecrementTreeItem;
|
||||
import com.jpexs.asdec.abc.avm2.treemodel.PostIncrementTreeItem;
|
||||
import com.jpexs.asdec.abc.avm2.treemodel.SetPropertyTreeItem;
|
||||
import com.jpexs.asdec.abc.avm2.treemodel.TreeItem;
|
||||
import com.jpexs.asdec.abc.avm2.treemodel.operations.PreDecrementTreeItem;
|
||||
import com.jpexs.asdec.abc.avm2.treemodel.operations.PreIncrementTreeItem;
|
||||
import com.jpexs.asdec.abc.types.MethodInfo;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@@ -42,6 +50,65 @@ public class SetPropertyIns extends InstructionDefinition implements SetTypeIns
|
||||
TreeItem value = (TreeItem) stack.pop();
|
||||
FullMultinameTreeItem multiname = resolveMultiname(stack, constants, multinameIndex, ins);
|
||||
TreeItem obj = (TreeItem) stack.pop();
|
||||
if (value.getThroughRegister() instanceof IncrementTreeItem) {
|
||||
TreeItem inside = ((IncrementTreeItem) value.getThroughRegister()).object.getThroughRegister().getNotCoerced();
|
||||
if (inside instanceof GetPropertyTreeItem) {
|
||||
GetPropertyTreeItem insideProp = ((GetPropertyTreeItem) inside);
|
||||
if (insideProp.propertyName.compareSame(multiname)) {
|
||||
TreeItem insideObj = obj;
|
||||
if (insideObj instanceof LocalRegTreeItem) {
|
||||
insideObj = ((LocalRegTreeItem) insideObj).computedValue;
|
||||
}
|
||||
if (insideProp.object == insideObj) {
|
||||
if (stack.size() > 0) {
|
||||
TreeItem top = stack.peek().getNotCoerced();
|
||||
if (top == insideProp) {
|
||||
stack.pop();
|
||||
stack.push(new PostIncrementTreeItem(ins, insideProp));
|
||||
} else if ((top instanceof IncrementTreeItem) && (((IncrementTreeItem) top).object == inside)) {
|
||||
stack.pop();
|
||||
stack.push(new PreIncrementTreeItem(ins, insideProp));
|
||||
} else {
|
||||
output.add(new PostIncrementTreeItem(ins, insideProp));
|
||||
}
|
||||
} else {
|
||||
output.add(new PostIncrementTreeItem(ins, insideProp));
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (value.getThroughRegister() instanceof DecrementTreeItem) {
|
||||
TreeItem inside = ((DecrementTreeItem) value.getThroughRegister()).object.getThroughRegister().getNotCoerced();
|
||||
if (inside instanceof GetPropertyTreeItem) {
|
||||
GetPropertyTreeItem insideProp = ((GetPropertyTreeItem) inside);
|
||||
if (insideProp.propertyName.compareSame(multiname)) {
|
||||
TreeItem insideObj = obj;
|
||||
if (insideObj instanceof LocalRegTreeItem) {
|
||||
insideObj = ((LocalRegTreeItem) insideObj).computedValue;
|
||||
}
|
||||
if (insideProp.object == insideObj) {
|
||||
if (stack.size() > 0) {
|
||||
TreeItem top = stack.peek().getNotCoerced();
|
||||
if (top == insideProp) {
|
||||
stack.pop();
|
||||
stack.push(new PostDecrementTreeItem(ins, insideProp));
|
||||
} else if ((top instanceof DecrementTreeItem) && (((DecrementTreeItem) top).object == inside)) {
|
||||
stack.pop();
|
||||
stack.push(new PreDecrementTreeItem(ins, insideProp));
|
||||
} else {
|
||||
output.add(new PostDecrementTreeItem(ins, insideProp));
|
||||
}
|
||||
} else {
|
||||
output.add(new PostDecrementTreeItem(ins, insideProp));
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
output.add(new SetPropertyTreeItem(ins, obj, multiname, value));
|
||||
}
|
||||
|
||||
|
||||
@@ -22,10 +22,18 @@ import com.jpexs.asdec.abc.avm2.ConstantPool;
|
||||
import com.jpexs.asdec.abc.avm2.instructions.AVM2Instruction;
|
||||
import com.jpexs.asdec.abc.avm2.instructions.InstructionDefinition;
|
||||
import com.jpexs.asdec.abc.avm2.instructions.SetTypeIns;
|
||||
import com.jpexs.asdec.abc.avm2.treemodel.DecrementTreeItem;
|
||||
import com.jpexs.asdec.abc.avm2.treemodel.GetSlotTreeItem;
|
||||
import com.jpexs.asdec.abc.avm2.treemodel.IncrementTreeItem;
|
||||
import com.jpexs.asdec.abc.avm2.treemodel.LocalRegTreeItem;
|
||||
import com.jpexs.asdec.abc.avm2.treemodel.NewActivationTreeItem;
|
||||
import com.jpexs.asdec.abc.avm2.treemodel.PostDecrementTreeItem;
|
||||
import com.jpexs.asdec.abc.avm2.treemodel.PostIncrementTreeItem;
|
||||
import com.jpexs.asdec.abc.avm2.treemodel.SetSlotTreeItem;
|
||||
import com.jpexs.asdec.abc.avm2.treemodel.TreeItem;
|
||||
import com.jpexs.asdec.abc.avm2.treemodel.clauses.ExceptionTreeItem;
|
||||
import com.jpexs.asdec.abc.avm2.treemodel.operations.PreDecrementTreeItem;
|
||||
import com.jpexs.asdec.abc.avm2.treemodel.operations.PreIncrementTreeItem;
|
||||
import com.jpexs.asdec.abc.types.MethodInfo;
|
||||
import com.jpexs.asdec.abc.types.Multiname;
|
||||
import com.jpexs.asdec.abc.types.traits.TraitSlotConst;
|
||||
@@ -65,7 +73,59 @@ public class SetSlotIns extends InstructionDefinition implements SetTypeIns {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (value.getNotCoerced() instanceof IncrementTreeItem) {
|
||||
TreeItem inside = ((IncrementTreeItem) value.getNotCoerced()).object.getThroughRegister().getNotCoerced();
|
||||
if (inside instanceof GetSlotTreeItem) {
|
||||
GetSlotTreeItem slotItem=(GetSlotTreeItem)inside;
|
||||
if ((slotItem.scope.getThroughRegister()==obj.getThroughRegister())
|
||||
&&(slotItem.slotName==slotname))
|
||||
{
|
||||
if (stack.size() > 0) {
|
||||
TreeItem top = stack.peek().getNotCoerced();
|
||||
if (top == inside) {
|
||||
stack.pop();
|
||||
stack.push(new PostIncrementTreeItem(ins, inside));
|
||||
} else if ((top instanceof IncrementTreeItem) && (((IncrementTreeItem) top).object == inside)) {
|
||||
stack.pop();
|
||||
stack.push(new PreIncrementTreeItem(ins, inside));
|
||||
} else {
|
||||
output.add(new PostIncrementTreeItem(ins, inside));
|
||||
}
|
||||
} else {
|
||||
output.add(new PostIncrementTreeItem(ins, inside));
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (value.getNotCoerced() instanceof DecrementTreeItem) {
|
||||
TreeItem inside = ((DecrementTreeItem) value.getNotCoerced()).object.getThroughRegister().getNotCoerced();
|
||||
if (inside instanceof GetSlotTreeItem) {
|
||||
GetSlotTreeItem slotItem=(GetSlotTreeItem)inside;
|
||||
if ((slotItem.scope.getThroughRegister()==obj.getThroughRegister())
|
||||
&&(slotItem.slotName==slotname))
|
||||
{
|
||||
if (stack.size() > 0) {
|
||||
TreeItem top = stack.peek().getNotCoerced();
|
||||
if (top == inside) {
|
||||
stack.pop();
|
||||
stack.push(new PostDecrementTreeItem(ins, inside));
|
||||
} else if ((top instanceof DecrementTreeItem) && (((DecrementTreeItem) top).object == inside)) {
|
||||
stack.pop();
|
||||
stack.push(new PreDecrementTreeItem(ins, inside));
|
||||
} else {
|
||||
output.add(new PostDecrementTreeItem(ins, inside));
|
||||
}
|
||||
} else {
|
||||
output.add(new PostDecrementTreeItem(ins, inside));
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
output.add(new SetSlotTreeItem(ins, obj, slotname, value));
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ public class DupIns extends InstructionDefinition {
|
||||
@Override
|
||||
public void translate(boolean isStatic, int classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.asdec.abc.types.MethodBody body, com.jpexs.asdec.abc.ABC abc, HashMap<Integer, String> localRegNames) {
|
||||
TreeItem v = (TreeItem) stack.pop();
|
||||
stack.push(v);
|
||||
stack.push(v);
|
||||
stack.push(v);
|
||||
|
||||
}
|
||||
|
||||
@@ -36,4 +36,9 @@ public class ConvertTreeItem extends TreeItem {
|
||||
//return hilight("("+type+")")+
|
||||
return value.toString(constants, localRegNames);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TreeItem getNotCoerced() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,8 +24,8 @@ public class FullMultinameTreeItem extends TreeItem {
|
||||
|
||||
public int multinameIndex;
|
||||
public TreeItem name;
|
||||
public TreeItem namespace;
|
||||
|
||||
public TreeItem namespace;
|
||||
|
||||
public FullMultinameTreeItem(AVM2Instruction instruction, int multinameIndex, TreeItem name) {
|
||||
super(instruction, PRECEDENCE_PRIMARY);
|
||||
this.multinameIndex = multinameIndex;
|
||||
@@ -69,4 +69,37 @@ public class FullMultinameTreeItem extends TreeItem {
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public boolean compareSame(FullMultinameTreeItem other)
|
||||
{
|
||||
if(multinameIndex!=other.multinameIndex){
|
||||
return false;
|
||||
}
|
||||
TreeItem tiName=name;
|
||||
while(tiName instanceof LocalRegTreeItem){
|
||||
tiName=((LocalRegTreeItem)tiName).computedValue;
|
||||
}
|
||||
|
||||
TreeItem tiName2=other.name;
|
||||
while(tiName2 instanceof LocalRegTreeItem){
|
||||
tiName2=((LocalRegTreeItem)tiName2).computedValue;
|
||||
}
|
||||
if(tiName!=tiName2){
|
||||
return false;
|
||||
}
|
||||
|
||||
TreeItem tiNameSpace=namespace;
|
||||
while(tiNameSpace instanceof LocalRegTreeItem){
|
||||
tiNameSpace=((LocalRegTreeItem)tiNameSpace).computedValue;
|
||||
}
|
||||
|
||||
TreeItem tiNameSpace2=other.namespace;
|
||||
while(tiNameSpace2 instanceof LocalRegTreeItem){
|
||||
tiNameSpace2=((LocalRegTreeItem)tiNameSpace2).computedValue;
|
||||
}
|
||||
if(tiNameSpace!=tiNameSpace2){
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,4 +48,11 @@ public class LocalRegTreeItem extends TreeItem {
|
||||
public boolean isTrue() {
|
||||
return computedValue.isTrue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TreeItem getThroughRegister() {
|
||||
return computedValue.getThroughRegister();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -42,13 +42,17 @@ public abstract class TreeItem {
|
||||
public static final int NOPRECEDENCE = 16;
|
||||
public int precedence = NOPRECEDENCE;
|
||||
public AVM2Instruction instruction;
|
||||
|
||||
|
||||
public TreeItem(AVM2Instruction instruction, int precedence) {
|
||||
this.instruction = instruction;
|
||||
this.precedence = precedence;
|
||||
}
|
||||
|
||||
public abstract String toString(ConstantPool constants, HashMap<Integer, String> localRegNames);
|
||||
|
||||
public String toStringNoH(ConstantPool constants, HashMap<Integer, String> localRegNames){
|
||||
return Highlighting.stripHilights(toString(constants,localRegNames));
|
||||
}
|
||||
|
||||
public String toStringSemicoloned(ConstantPool constants, HashMap<Integer, String> localRegNames) {
|
||||
return toString(constants, localRegNames) + (needsSemicolon() ? ";" : "");
|
||||
@@ -104,6 +108,10 @@ public abstract class TreeItem {
|
||||
public TreeItem getNotCoerced() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public TreeItem getThroughRegister() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public static String localRegName(HashMap<Integer, String> localRegNames, int reg) {
|
||||
if (localRegNames.containsKey(reg)) {
|
||||
|
||||
Reference in New Issue
Block a user