mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-09-27 20:20:51 +00:00
Issue #842 For reconstruction if debug line info present
Spaces added between parts of for
This commit is contained in:
@@ -674,6 +674,75 @@ public class AVM2Code implements Cloneable {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void calculateDebugFileLine(ABC abc) {
|
||||
calculateDebugFileLine(null, 0, 0, abc, new HashSet<Integer>());
|
||||
}
|
||||
|
||||
private boolean calculateDebugFileLine(String debugFile, int debugLine, int pos, ABC abc, Set<Integer> seen) {
|
||||
while (pos < code.size()) {
|
||||
AVM2Instruction ins = code.get(pos);
|
||||
if (seen.contains(pos)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
seen.add(pos);
|
||||
|
||||
if (ins.definition instanceof DebugFileIns) {
|
||||
debugFile = abc.constants.getString(ins.operands[0]);
|
||||
}
|
||||
|
||||
if (ins.definition instanceof DebugLineIns) {
|
||||
debugLine = ins.operands[0];
|
||||
}
|
||||
|
||||
ins.setFileLine(debugFile, debugLine);
|
||||
|
||||
if (ins.definition instanceof NewFunctionIns) {
|
||||
MethodBody innerBody = abc.findBody(ins.operands[0]);
|
||||
innerBody.getCode().calculateDebugFileLine(debugFile, debugLine, 0, abc, new HashSet<Integer>());
|
||||
}
|
||||
|
||||
if (ins.definition instanceof ReturnValueIns) {
|
||||
return true;
|
||||
}
|
||||
if (ins.definition instanceof ReturnVoidIns) {
|
||||
return true;
|
||||
}
|
||||
if (ins.definition instanceof JumpIns) {
|
||||
try {
|
||||
pos = adr2pos(pos2adr(pos) + ins.getBytes().length + ins.operands[0]);
|
||||
continue;
|
||||
} catch (ConvertException ex) {
|
||||
return false;
|
||||
}
|
||||
} else if (ins.definition instanceof IfTypeIns) {
|
||||
try {
|
||||
int newpos = adr2pos(pos2adr(pos) + ins.getBytes().length + ins.operands[0]);
|
||||
calculateDebugFileLine(debugFile, debugLine, newpos, abc, seen);
|
||||
} catch (ConvertException ex) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (ins.definition instanceof LookupSwitchIns) {
|
||||
for (int i = 0; i < ins.operands.length; i++) {
|
||||
if (i == 1) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
int newpos = adr2pos(pos2adr(pos) + ins.operands[i]);
|
||||
if (!calculateDebugFileLine(debugFile, debugLine, newpos, abc, seen)) {
|
||||
return false;
|
||||
}
|
||||
} catch (ConvertException ex) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public AVM2Code(ABCInputStream ais) throws IOException {
|
||||
Map<Long, AVM2Instruction> codeMap = new TreeMap<>();
|
||||
Map<Long, Long> endOffsets = new HashMap<>();
|
||||
|
||||
@@ -726,6 +726,7 @@ public class AVM2Graph extends Graph {
|
||||
|
||||
@Override
|
||||
protected void finalProcess(List<GraphTargetItem> list, int level, FinalProcessLocalData localData) {
|
||||
super.finalProcess(list, level, localData);
|
||||
if (level == 0) {
|
||||
if (!list.isEmpty()) {
|
||||
if (list.get(list.size() - 1) instanceof ReturnVoidAVM2Item) {
|
||||
|
||||
@@ -79,6 +79,7 @@ public class AVM2GraphSource extends GraphSource {
|
||||
this.scriptIndex = scriptIndex;
|
||||
this.localRegAssigmentIps = localRegAssigmentIp;
|
||||
this.refs = refs;
|
||||
code.calculateDebugFileLine(abc);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+20
@@ -56,6 +56,15 @@ public class AVM2Instruction implements Cloneable, GraphSourceItem {
|
||||
|
||||
public int changeJumpTo = -1;
|
||||
|
||||
private int line;
|
||||
|
||||
private String file;
|
||||
|
||||
public void setFileLine(String file, int line) {
|
||||
this.file = file;
|
||||
this.line = line;
|
||||
}
|
||||
|
||||
public AVM2Instruction(long offset, InstructionDefinition definition, int[] operands) {
|
||||
this.definition = definition;
|
||||
this.operands = operands != null && operands.length > 0 ? operands : null;
|
||||
@@ -382,4 +391,15 @@ public class AVM2Instruction implements Cloneable, GraphSourceItem {
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLine() {
|
||||
return line;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1287,4 +1287,15 @@ public abstract class Action implements GraphSourceItem {
|
||||
public boolean isDeobfuscatePop() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLine() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFile() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.␍ */
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action;
|
||||
|
||||
import com.jpexs.decompiler.flash.BaseLocalData;
|
||||
@@ -93,7 +94,7 @@ public class ActionGraph extends Graph {
|
||||
|
||||
@Override
|
||||
protected void finalProcess(List<GraphTargetItem> list, int level, FinalProcessLocalData localData) {
|
||||
|
||||
super.finalProcess(list, level, localData);
|
||||
List<GraphTargetItem> ret = Action.checkClass(list);
|
||||
if (ret != list) {
|
||||
list.clear();
|
||||
|
||||
@@ -461,6 +461,64 @@ public class Graph {
|
||||
}
|
||||
|
||||
protected void finalProcess(List<GraphTargetItem> list, int level, FinalProcessLocalData localData) {
|
||||
|
||||
//For detection based on debug line information
|
||||
Set<Integer> removeFromList = new HashSet<>();
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
|
||||
if (list.get(i) instanceof ForItem) {
|
||||
ForItem fori = (ForItem) list.get(i);
|
||||
int exprLine = fori.getLine();
|
||||
if (exprLine > 0) {
|
||||
List<GraphTargetItem> forFirstCommands = new ArrayList<>();
|
||||
for (int j = i - 1; j >= 0; j--) {
|
||||
if (list.get(j).getLine() == exprLine) {
|
||||
forFirstCommands.add(0, list.get(j));
|
||||
removeFromList.add(j);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
fori.firstCommands.addAll(0, forFirstCommands);
|
||||
}
|
||||
}
|
||||
|
||||
if (list.get(i) instanceof WhileItem) {
|
||||
WhileItem whi = (WhileItem) list.get(i);
|
||||
int whileExprLine = whi.getLine();
|
||||
if (whileExprLine > 0) {
|
||||
List<GraphTargetItem> forFirstCommands = new ArrayList<>();
|
||||
List<GraphTargetItem> forFinalCommands = new ArrayList<>();
|
||||
|
||||
for (int j = i - 1; j >= 0; j--) {
|
||||
if (list.get(j).getLine() == whileExprLine) {
|
||||
forFirstCommands.add(0, list.get(j));
|
||||
removeFromList.add(j);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (int j = whi.commands.size() - 1; j >= 0; j--) {
|
||||
if (whi.commands.get(j).getLine() == whileExprLine) {
|
||||
forFinalCommands.add(0, whi.commands.remove(j));
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!forFirstCommands.isEmpty() || !forFinalCommands.isEmpty()) {
|
||||
GraphTargetItem lastExpr = whi.expression.remove(whi.expression.size() - 1);
|
||||
forFirstCommands.addAll(whi.expression);
|
||||
list.set(i, new ForItem(whi.src, whi.loop, forFirstCommands, lastExpr, forFinalCommands, whi.commands));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = list.size() - 1; i >= 0; i--) {
|
||||
if (removeFromList.contains(i)) {
|
||||
list.remove(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void processIfs(List<GraphTargetItem> list) {
|
||||
@@ -1752,9 +1810,9 @@ public class Graph {
|
||||
checkContinueAtTheEnd(finalComm, currentLoop);
|
||||
}
|
||||
if (!finalComm.isEmpty()) {
|
||||
ret.add(index, li = new ForItem(null, currentLoop, new ArrayList<GraphTargetItem>(), exprList.get(exprList.size() - 1), finalComm, commands));
|
||||
ret.add(index, li = new ForItem(expr.src, currentLoop, new ArrayList<GraphTargetItem>(), exprList.get(exprList.size() - 1), finalComm, commands));
|
||||
} else {
|
||||
ret.add(index, li = new WhileItem(null, currentLoop, exprList, commands));
|
||||
ret.add(index, li = new WhileItem(expr.src, currentLoop, exprList, commands));
|
||||
}
|
||||
|
||||
loopTypeFound = true;
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
*/
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.graph;
|
||||
|
||||
import com.jpexs.decompiler.flash.BaseLocalData;
|
||||
@@ -44,4 +45,8 @@ public interface GraphSourceItem extends Serializable {
|
||||
public void setIgnored(boolean ignored, int pos);
|
||||
|
||||
public boolean isDeobfuscatePop();
|
||||
|
||||
public int getLine();
|
||||
|
||||
public String getFile();
|
||||
}
|
||||
|
||||
@@ -83,6 +83,20 @@ public abstract class GraphTargetItem implements Serializable {
|
||||
|
||||
protected HighlightData srcData = new HighlightData();
|
||||
|
||||
public int getLine() {
|
||||
if (src != null) {
|
||||
return src.getLine();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public String getFile() {
|
||||
if (src != null) {
|
||||
return src.getFile();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public GraphPart getFirstPart() {
|
||||
if (value == null) {
|
||||
return firstPart;
|
||||
|
||||
@@ -90,9 +90,9 @@ public class ForItem extends LoopItem implements Block {
|
||||
firstCommands.get(i).toString(writer, localData);
|
||||
p++;
|
||||
}
|
||||
writer.append(";");
|
||||
writer.append("; ");
|
||||
expression.toString(writer, localData);
|
||||
writer.append(";");
|
||||
writer.append("; ");
|
||||
p = 0;
|
||||
for (int i = 0; i < finalCommands.size(); i++) {
|
||||
if (finalCommands.get(i).isEmpty()) {
|
||||
|
||||
Reference in New Issue
Block a user