mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-07-18 16:28:07 +00:00
Adding goto §§ instruction for unresolved jumps (FlashCC etc.)
AS3: Add/remove instruction improvement
This commit is contained in:
@@ -1770,193 +1770,191 @@ public class AVM2Code implements Cloneable {
|
||||
return list;
|
||||
}
|
||||
|
||||
public void updateOffsets(OffsetUpdater updater, MethodBody body) {
|
||||
for (AVM2Instruction ins : code) {
|
||||
if (ins.definition instanceof LookupSwitchIns) {
|
||||
long target = ins.offset + ins.operands[0];
|
||||
ins.operands[0] = updater.updateOperandOffset(target, ins.operands[0]);
|
||||
for (int k = 2; k < ins.operands.length; k++) {
|
||||
target = ins.offset + ins.operands[k];
|
||||
ins.operands[k] = updater.updateOperandOffset(target, ins.operands[k]);
|
||||
}
|
||||
} else {
|
||||
/*for (int j = 0; j < ins.definition.operands.length; j++) {
|
||||
if (ins.definition.operands[j] == AVM2Code.DAT_OFFSET) {
|
||||
long target = ins.offset + ins.getBytes().length + ins.operands[j];
|
||||
ins.operands[j] = updater.updateOperandOffset(target, ins.operands[j]);
|
||||
}
|
||||
}*/
|
||||
//Faster, but not so universal
|
||||
if ((ins.definition instanceof JumpIns) || (ins.definition instanceof IfTypeIns)) {
|
||||
long target = ins.offset + ins.getBytes().length + ins.operands[0];
|
||||
ins.operands[0] = updater.updateOperandOffset(target, ins.operands[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (ABCException ex : body.exceptions) {
|
||||
ex.start = updater.updateOperandOffset(ex.start, ex.start);
|
||||
ex.end = updater.updateOperandOffset(ex.end, ex.end);
|
||||
ex.target = updater.updateOperandOffset(ex.target, ex.target);
|
||||
}
|
||||
for (AVM2Instruction ins : code) {
|
||||
ins.offset = updater.updateInstructionOffset(ins.offset);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkValidOffsets(MethodBody body) {
|
||||
updateOffsets(new OffsetUpdater() {
|
||||
|
||||
@Override
|
||||
public long updateInstructionOffset(long offset) {
|
||||
adr2pos(offset);
|
||||
return offset;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int updateOperandOffset(long targetAddress, int offset) {
|
||||
adr2pos(targetAddress);
|
||||
return offset;
|
||||
}
|
||||
|
||||
}, body);
|
||||
}
|
||||
|
||||
public void removeInstruction(int pos, MethodBody body) {
|
||||
if ((pos < 0) || (pos >= code.size())) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
int byteCount = code.get(pos).getBytes().length;
|
||||
long remOffset = code.get(pos).offset;
|
||||
for (int i = pos + 1; i < code.size(); i++) {
|
||||
code.get(i).offset -= byteCount;
|
||||
}
|
||||
//checkValidOffsets(body);
|
||||
final long remOffset = code.get(pos).offset;
|
||||
final int byteCount = code.get(pos).getBytes().length;
|
||||
updateOffsets(new OffsetUpdater() {
|
||||
@Override
|
||||
public long updateInstructionOffset(long address) {
|
||||
if (address > remOffset) {
|
||||
return address - byteCount;
|
||||
}
|
||||
return address;
|
||||
}
|
||||
|
||||
for (ABCException ex : body.exceptions) {
|
||||
if (ex.start > remOffset) {
|
||||
ex.start -= byteCount;
|
||||
@Override
|
||||
public int updateOperandOffset(long targetAddress, int offset) {
|
||||
if (targetAddress > remOffset) {
|
||||
return offset - byteCount;
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
if (ex.end > remOffset) {
|
||||
ex.end -= byteCount;
|
||||
}
|
||||
if (ex.target > remOffset) {
|
||||
ex.target -= byteCount;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < pos; i++) {
|
||||
if (code.get(i).definition instanceof LookupSwitchIns) {
|
||||
long target = code.get(i).offset + code.get(i).operands[0];
|
||||
if (target > remOffset) {
|
||||
code.get(i).operands[0] -= byteCount;
|
||||
}
|
||||
for (int k = 2; k < code.get(i).operands.length; k++) {
|
||||
target = code.get(i).offset + code.get(i).operands[k];
|
||||
if (target > remOffset) {
|
||||
code.get(i).operands[k] -= byteCount;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int j = 0; j < code.get(i).definition.operands.length; j++) {
|
||||
if (code.get(i).definition.operands[j] == AVM2Code.DAT_OFFSET) {
|
||||
long target = code.get(i).offset + code.get(i).getBytes().length + code.get(i).operands[j];
|
||||
if (target > remOffset) {
|
||||
code.get(i).operands[j] -= byteCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = pos + 1; i < code.size(); i++) {
|
||||
if (code.get(i).definition instanceof LookupSwitchIns) {
|
||||
long target = code.get(i).offset + code.get(i).operands[0];
|
||||
if (target < remOffset) {
|
||||
code.get(i).operands[0] += byteCount;
|
||||
}
|
||||
for (int k = 2; k < code.get(i).operands.length; k++) {
|
||||
target = code.get(i).offset + code.get(i).operands[k];
|
||||
if (target < remOffset) {
|
||||
code.get(i).operands[k] += byteCount;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int j = 0; j < code.get(i).definition.operands.length; j++) {
|
||||
if (code.get(i).definition.operands[j] == AVM2Code.DAT_OFFSET) {
|
||||
long target = code.get(i).offset + code.get(i).getBytes().length + code.get(i).operands[j];
|
||||
if (target < remOffset) {
|
||||
code.get(i).operands[j] += byteCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}, body);
|
||||
code.remove(pos);
|
||||
invalidateCache();
|
||||
//checkValidOffsets(body);
|
||||
//System.exit(0);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param pos
|
||||
* @param instruction
|
||||
* Inserts instuction at specified point. Handles offsets properly. Note: If
|
||||
* newinstruction is jump, the offset operand must be handled properly by
|
||||
* caller. All old jump offsets to pos are targeted before new instruction.
|
||||
*
|
||||
* @param pos Position in the list
|
||||
* @param instruction Instruction False means before new instruction
|
||||
* @param body Method body (used for try handling)
|
||||
*/
|
||||
public void insertInstruction(int pos, AVM2Instruction instruction, MethodBody body) {
|
||||
insertInstruction(pos, instruction, true, false, body);
|
||||
insertInstruction(pos, instruction, false, body);
|
||||
}
|
||||
|
||||
public void replaceInstruction(int idx, AVM2Instruction ins, MethodBody body) {
|
||||
insertInstruction(idx, ins, true, true, body);
|
||||
removeInstruction(idx + 1, body);
|
||||
}
|
||||
|
||||
public void insertInstruction(int pos, AVM2Instruction instruction, boolean preRefsToThis, boolean postRefsToThis, MethodBody body) {
|
||||
/**
|
||||
* Replaces instrunction by another. Properly handles offsets. Note: If
|
||||
* newinstruction is jump, the offset operand must be handled properly by
|
||||
* caller.
|
||||
*
|
||||
* @param pos
|
||||
* @param instruction
|
||||
* @param body
|
||||
*/
|
||||
public void replaceInstruction(int pos, AVM2Instruction instruction, MethodBody body) {
|
||||
if (pos < 0) {
|
||||
pos = 0;
|
||||
}
|
||||
if (pos > code.size()) {
|
||||
pos = code.size();
|
||||
}
|
||||
int byteCount = instruction.getBytes().length;
|
||||
instruction.offset = code.get(pos).offset;
|
||||
int oldByteCount = code.get(pos).getBytes().length;
|
||||
int newByteCount = instruction.getBytes().length;
|
||||
int byteDelta = newByteCount - oldByteCount;
|
||||
|
||||
if (byteDelta != 0) {
|
||||
updateOffsets(new OffsetUpdater() {
|
||||
|
||||
@Override
|
||||
public long updateInstructionOffset(long offset) {
|
||||
if (offset > instruction.offset) {
|
||||
return offset + byteDelta;
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int updateOperandOffset(long targetAddress, int offset) {
|
||||
if (targetAddress > instruction.offset) {
|
||||
return offset + byteDelta;
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
}, body);
|
||||
}
|
||||
code.set(pos, instruction);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts instuction at specified point. Handles offsets properly. Note: If
|
||||
* newinstruction is jump, the offset operand must be handled properly by
|
||||
* caller.
|
||||
*
|
||||
* @param pos Position in the list
|
||||
* @param instruction Instruction
|
||||
* @param mapOffsetsAfterIns Map all jumps to the pos after new instruction?
|
||||
* False means before new instruction
|
||||
* @param body Method body (used for try handling)
|
||||
*/
|
||||
public void insertInstruction(int pos, AVM2Instruction instruction, boolean mapOffsetsAfterIns, MethodBody body) {
|
||||
if (pos < 0) {
|
||||
pos = 0;
|
||||
}
|
||||
if (pos > code.size()) {
|
||||
pos = code.size();
|
||||
}
|
||||
final int byteCount = instruction.getBytes().length;
|
||||
if (pos == code.size()) {
|
||||
instruction.offset = code.get(pos - 1).offset + code.get(pos - 1).getBytes().length;
|
||||
} else {
|
||||
instruction.offset = code.get(pos).offset;
|
||||
}
|
||||
updateOffsets(new OffsetUpdater() {
|
||||
|
||||
for (ABCException ex : body.exceptions) {
|
||||
if (ex.start > instruction.offset) {
|
||||
ex.start += byteCount;
|
||||
}
|
||||
if (ex.end > instruction.offset) {
|
||||
ex.end += byteCount;
|
||||
}
|
||||
if (ex.target > instruction.offset) {
|
||||
ex.target += byteCount;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
for (int i = 0; i < pos; i++) {
|
||||
if (code.get(i).definition instanceof LookupSwitchIns) {
|
||||
long target = code.get(i).offset + code.get(i).operands[0];
|
||||
if (target > instruction.offset) {
|
||||
code.get(i).operands[0] += byteCount;
|
||||
}
|
||||
if (target == instruction.offset && !preRefsToThis) {
|
||||
code.get(i).operands[0] += byteCount;
|
||||
}
|
||||
for (int k = 2; k < code.get(i).operands.length; k++) {
|
||||
target = code.get(i).offset + code.get(i).operands[k];
|
||||
if (target > instruction.offset) {
|
||||
code.get(i).operands[k] += byteCount;
|
||||
}
|
||||
if (target == instruction.offset && !preRefsToThis) {
|
||||
code.get(i).operands[k] += byteCount;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int j = 0; j < code.get(i).definition.operands.length; j++) {
|
||||
if (code.get(i).definition.operands[j] == AVM2Code.DAT_OFFSET) {
|
||||
long target = code.get(i).offset + code.get(i).getBytes().length + code.get(i).operands[j];
|
||||
if (target > instruction.offset) {
|
||||
code.get(i).operands[j] += byteCount;
|
||||
}
|
||||
if (target == instruction.offset && !preRefsToThis) {
|
||||
code.get(i).operands[j] += byteCount;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public long updateInstructionOffset(long offset) {
|
||||
if (offset >= instruction.offset) {
|
||||
return offset + byteCount;
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
}
|
||||
{
|
||||
for (int i = pos; i < code.size(); i++) {
|
||||
if (code.get(i).definition instanceof LookupSwitchIns) {
|
||||
long target = code.get(i).offset + code.get(i).operands[0];
|
||||
if (target < instruction.offset) {
|
||||
code.get(i).operands[0] -= byteCount;
|
||||
}
|
||||
if (target == instruction.offset && postRefsToThis) {
|
||||
code.get(i).operands[0] -= byteCount;
|
||||
}
|
||||
for (int k = 2; k < code.get(i).operands.length; k++) {
|
||||
target = code.get(i).offset + code.get(i).operands[k];
|
||||
if (target < instruction.offset) {
|
||||
code.get(i).operands[k] -= byteCount;
|
||||
}
|
||||
if (target == instruction.offset && postRefsToThis) {
|
||||
code.get(i).operands[k] -= byteCount;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int j = 0; j < code.get(i).definition.operands.length; j++) {
|
||||
if (code.get(i).definition.operands[j] == AVM2Code.DAT_OFFSET) {
|
||||
long target = code.get(i).offset + code.get(i).getBytes().length + code.get(i).operands[j];
|
||||
if (target < instruction.offset) {
|
||||
code.get(i).operands[j] -= byteCount;
|
||||
}
|
||||
if (target == instruction.offset && postRefsToThis) {
|
||||
code.get(i).operands[j] -= byteCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = pos; i < code.size(); i++) {
|
||||
code.get(i).offset += byteCount;
|
||||
}
|
||||
@Override
|
||||
public int updateOperandOffset(long targetAddress, int offset) {
|
||||
if ((targetAddress > instruction.offset) || (mapOffsetsAfterIns && (targetAddress == instruction.offset))) {
|
||||
return offset + byteCount;
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
}, body);
|
||||
code.add(pos, instruction);
|
||||
invalidateCache();
|
||||
checkValidOffsets(body);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -2524,6 +2522,30 @@ public class AVM2Code implements Cloneable {
|
||||
restoreControlFlowPass(constants, trait, info, body, false);
|
||||
//restoreControlFlowPass(constants, body, true);
|
||||
}
|
||||
/*
|
||||
public void removeIgnored(AVM2ConstantPool constants, Trait trait, MethodInfo info, MethodBody body) throws InterruptedException {
|
||||
try {
|
||||
List<Integer> outputMap = new ArrayList<>();
|
||||
HighlightedTextWriter writer = new HighlightedTextWriter(Configuration.getCodeFormatting(), false);
|
||||
toASMSource(constants, trait, info, body, outputMap, ScriptExportMode.PCODE, writer);
|
||||
String src = writer.toString();
|
||||
AVM2Code acode = ASM3Parser.parse(new StringReader(src), constants, trait, body, info);
|
||||
for (int i = 0; i < acode.code.size(); i++) {
|
||||
if (outputMap.size() > i) {
|
||||
int tpos = outputMap.get(i);
|
||||
if (tpos == -1) {
|
||||
} else if (code.get(tpos).mappedOffset >= 0) {
|
||||
acode.code.get(i).mappedOffset = code.get(tpos).mappedOffset;
|
||||
} else {
|
||||
acode.code.get(i).mappedOffset = pos2adr(tpos);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.code = acode.code;
|
||||
} catch (IOException | AVM2ParseException ex) {
|
||||
}
|
||||
invalidateCache();
|
||||
}*/
|
||||
|
||||
public void removeIgnored(AVM2ConstantPool constants, Trait trait, MethodInfo info, MethodBody body) throws InterruptedException {
|
||||
for (int i = 0; i < code.size(); i++) {
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 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.flash.abc.avm2;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public interface OffsetUpdater {
|
||||
|
||||
public long updateInstructionOffset(long offset);
|
||||
|
||||
public int updateOperandOffset(long targetAddress, int offset);
|
||||
}
|
||||
@@ -164,67 +164,50 @@ public class AVM2DeobfuscatorSimple implements SWFDecompilerListener {
|
||||
ExecutionResult result = new ExecutionResult();
|
||||
executeActions(classIndex, isStatic, body, scriptIndex, abc, code, i, code.code.size() - 1, result);
|
||||
|
||||
if (result.idx != -1) {
|
||||
int newIstructionCount = 1; // jump
|
||||
if (!result.stack.isEmpty()) {
|
||||
newIstructionCount += result.stack.size();
|
||||
}
|
||||
/*if (result.idx != -1) {
|
||||
int newIstructionCount = 1; // jump
|
||||
if (!result.stack.isEmpty()) {
|
||||
newIstructionCount += result.stack.size();
|
||||
}
|
||||
|
||||
if (newIstructionCount < result.instructionsProcessed) //if (result.isIf)
|
||||
{
|
||||
AVM2Instruction target = code.code.get(result.idx);
|
||||
AVM2Instruction prevAction = code.code.get(i);
|
||||
int idelta = 0;
|
||||
if (newIstructionCount < result.instructionsProcessed) //if (result.isIf)
|
||||
{
|
||||
AVM2Instruction target = code.code.get(result.idx);
|
||||
AVM2Instruction prevAction = code.code.get(i);
|
||||
int idelta = 0;
|
||||
|
||||
if (result.stack.isEmpty() && prevAction.definition instanceof JumpIns) {
|
||||
prevAction.operands[0] = ((int) (target.offset - prevAction.offset - prevAction.getBytes().length));
|
||||
} else {
|
||||
if (!result.stack.isEmpty()) {
|
||||
for (GraphTargetItem graphTargetItem : result.stack) {
|
||||
if (graphTargetItem instanceof PopItem) {
|
||||
continue;
|
||||
}
|
||||
AVM2Instruction ins = makePush(graphTargetItem.getResult(), cpool);
|
||||
if (ins != null) {
|
||||
code.insertInstruction(i + (idelta++), ins, body);
|
||||
//prevAction = ins;
|
||||
} else {
|
||||
throw new TranslateException("Cannot push: " + graphTargetItem);
|
||||
}
|
||||
if (result.stack.isEmpty() && prevAction.definition instanceof JumpIns) {
|
||||
prevAction.operands[0] = ((int) (target.offset - prevAction.offset - prevAction.getBytes().length));
|
||||
} else {
|
||||
if (!result.stack.isEmpty()) {
|
||||
for (GraphTargetItem graphTargetItem : result.stack) {
|
||||
if (graphTargetItem instanceof PopItem) {
|
||||
continue;
|
||||
}
|
||||
AVM2Instruction ins = makePush(graphTargetItem.getResult(), cpool);
|
||||
if (ins != null) {
|
||||
code.insertInstruction(i + (idelta++), ins, body);
|
||||
//prevAction = ins;
|
||||
} else {
|
||||
throw new TranslateException("Cannot push: " + graphTargetItem);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AVM2Instruction jump = new AVM2Instruction(0, new JumpIns(), new int[]{0});
|
||||
code.insertInstruction(i + (idelta++), jump, body);
|
||||
AVM2Instruction jump = new AVM2Instruction(0, new JumpIns(), new int[]{0});
|
||||
code.insertInstruction(i + (idelta++), jump, body);
|
||||
|
||||
jump.operands[0] = ((int) (target.offset - jump.offset - jump.getBytes().length));
|
||||
jump.operands[0] = ((int) (target.offset - jump.offset - jump.getBytes().length));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
removeUnreachableActions(code, cpool, trait, minfo, body);
|
||||
removeZeroJumps(code, body);
|
||||
removeUnreachableActions(code, cpool, trait, minfo, body);
|
||||
removeZeroJumps(code, body);
|
||||
|
||||
i = -1;
|
||||
/*if (nextAction != null) {
|
||||
long mapped = nextAction.mappedOffset;
|
||||
int nextIdx = -1;
|
||||
for (int p = 0; p < code.code.size(); p++) {
|
||||
if (code.code.get(p).mappedOffset == mapped) {
|
||||
nextIdx = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (nextIdx == -1) {
|
||||
//?
|
||||
break;
|
||||
} else {
|
||||
i = nextIdx - 1;
|
||||
}
|
||||
|
||||
}*/
|
||||
}
|
||||
}
|
||||
i = -1;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -340,7 +323,7 @@ public class AVM2DeobfuscatorSimple implements SWFDecompilerListener {
|
||||
break;
|
||||
}
|
||||
|
||||
//boolean ifed = false;
|
||||
boolean ifed = false;
|
||||
if (def instanceof JumpIns) {
|
||||
//ActionJump jump = (ActionJump) action;
|
||||
long address = action.offset + action.getBytes().length + action.operands[0];
|
||||
@@ -353,18 +336,29 @@ public class AVM2DeobfuscatorSimple implements SWFDecompilerListener {
|
||||
//ActionIf aif = (ActionIf) action;
|
||||
GraphTargetItem top = stack.pop();
|
||||
Object res = top.getResult();
|
||||
long address = action.offset + action.getBytes().length + action.operands[0];
|
||||
int nidx = code.adr2pos(address);//code.indexOf(code.getByAddress(address));
|
||||
AVM2Instruction tarIns = code.code.get(nidx);
|
||||
|
||||
if (EcmaScript.toBoolean(res)) {
|
||||
long address = action.offset + action.getBytes().length + action.operands[0];
|
||||
idx = code.adr2pos(address);//code.indexOf(code.getByAddress(address));
|
||||
if (idx == -1) {
|
||||
throw new TranslateException("If target not found: " + address);
|
||||
}
|
||||
//ifed = true;
|
||||
/*if (nidx == -1) {
|
||||
throw new TranslateException("If target not found: " + address);
|
||||
}*/
|
||||
AVM2Instruction jumpIns = new AVM2Instruction(0, new JumpIns(), new int[]{0});
|
||||
//jumpIns.operands[0] = action.operands[0] /*- action.getBytes().length*/ + jumpIns.getBytes().length;
|
||||
code.replaceInstruction(idx, jumpIns, body);
|
||||
jumpIns.operands[0] = (int) (tarIns.offset - jumpIns.offset - jumpIns.getBytes().length);
|
||||
|
||||
code.insertInstruction(idx, new AVM2Instruction(action.offset, new DeobfuscatePopIns(), new int[]{}), true, body);
|
||||
|
||||
idx = code.adr2pos(jumpIns.offset + jumpIns.getBytes().length + jumpIns.operands[0]);
|
||||
} else {
|
||||
//action.definition = new DeobfuscatePopIns();
|
||||
code.replaceInstruction(idx, new AVM2Instruction(action.offset, new DeobfuscatePopIns(), new int[]{}), body);
|
||||
//action.definition = new DeobfuscatePopIns();
|
||||
idx++;
|
||||
}
|
||||
ifed = true;
|
||||
//break;
|
||||
} else {
|
||||
idx++;
|
||||
}
|
||||
@@ -377,7 +371,9 @@ public class AVM2DeobfuscatorSimple implements SWFDecompilerListener {
|
||||
result.stack.clear();
|
||||
result.stack.addAll(stack);
|
||||
}
|
||||
|
||||
if (ifed) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (EmptyStackException | TranslateException | InterruptedException ex) {
|
||||
//result.idx = -1;
|
||||
|
||||
@@ -167,7 +167,7 @@ public class AVM2Graph extends Graph {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<GraphTargetItem> check(GraphSource code, BaseLocalData localData, List<GraphPart> allParts, TranslateStack stack, GraphPart parent, GraphPart part, List<GraphPart> stopPart, List<Loop> loops, List<GraphTargetItem> output, Loop currentLoop, int staticOperation, String path) throws InterruptedException {
|
||||
protected List<GraphTargetItem> check(Map<GraphPart, List<GraphTargetItem>> partCodes, Map<GraphPart, Integer> partCodePos, GraphSource code, BaseLocalData localData, List<GraphPart> allParts, TranslateStack stack, GraphPart parent, GraphPart part, List<GraphPart> stopPart, List<Loop> loops, List<GraphTargetItem> output, Loop currentLoop, int staticOperation, String path) throws InterruptedException {
|
||||
List<GraphTargetItem> ret = null;
|
||||
|
||||
AVM2LocalData aLocalData = (AVM2LocalData) localData;
|
||||
@@ -277,7 +277,7 @@ public class AVM2Graph extends Graph {
|
||||
finallyJumps.clear();
|
||||
ignoredSwitches.put(e, swPos);
|
||||
st.push(new PopItem(null));
|
||||
finallyCommands = printGraph(localData, st, allParts, parent, fpart, null, loops, staticOperation, path);
|
||||
finallyCommands = printGraph(partCodes, partCodePos, localData, st, allParts, parent, fpart, null, loops, staticOperation, path);
|
||||
//ignoredSwitches.remove(igs_size-1);
|
||||
finallyJumps.putAll(oldFinallyJumps);
|
||||
if (!finallyJumps.containsKey(e)) {
|
||||
@@ -336,7 +336,7 @@ public class AVM2Graph extends Graph {
|
||||
stopPart2.add(retPart);
|
||||
}
|
||||
|
||||
List<GraphTargetItem> ncatchedCommands = printGraph(localData2, st2, allParts, parent, npart, stopPart2, loops, staticOperation, path);
|
||||
List<GraphTargetItem> ncatchedCommands = printGraph(partCodes, partCodePos, localData2, st2, allParts, parent, npart, stopPart2, loops, staticOperation, path);
|
||||
if (catchedExceptions.get(e).isFinally() && (catchedExceptions.size() > 1 || hasFinally)) {
|
||||
catchedExceptions.remove(e);
|
||||
e--;
|
||||
@@ -376,7 +376,7 @@ public class AVM2Graph extends Graph {
|
||||
}
|
||||
TranslateStack st = (TranslateStack) stack.clone();
|
||||
st.clear();
|
||||
List<GraphTargetItem> tryCommands = printGraph(localData, st, allParts, parent, part, stopPart2, loops, staticOperation, path);
|
||||
List<GraphTargetItem> tryCommands = printGraph(partCodes, partCodePos, localData, st, allParts, parent, part, stopPart2, loops, staticOperation, path);
|
||||
if (retPart != null && avm2code.code.get(retPart.start).isExit() && !(!tryCommands.isEmpty() && (tryCommands.get(tryCommands.size() - 1) instanceof ExitItem))) {
|
||||
avm2code.code.get(retPart.start).translate(localData, st, tryCommands, staticOperation, path);
|
||||
}
|
||||
@@ -413,7 +413,7 @@ public class AVM2Graph extends Graph {
|
||||
TranslateStack st = (TranslateStack) stack.clone();
|
||||
st.clear();
|
||||
|
||||
ret.addAll(printGraph(localData, st, allParts, null, part, stopPart, loops, staticOperation, path));
|
||||
ret.addAll(printGraph(partCodes, partCodePos, localData, st, allParts, null, part, stopPart, loops, staticOperation, path));
|
||||
} else {
|
||||
ret.add(lop);
|
||||
}
|
||||
@@ -603,7 +603,7 @@ public class AVM2Graph extends Graph {
|
||||
defaultPart = switchLoc.nextParts.get(switchLoc.nextParts.size() - 1);
|
||||
List<GraphPart> stopPart2 = new ArrayList<>(stopPart);
|
||||
stopPart2.add(next);
|
||||
defaultCommands = printGraph(localData, stack, allParts, switchLoc, defaultPart, stopPart2, loops, staticOperation, path);
|
||||
defaultCommands = printGraph(partCodes, partCodePos, localData, stack, allParts, switchLoc, defaultPart, stopPart2, loops, staticOperation, path);
|
||||
if (!defaultCommands.isEmpty()) {
|
||||
if (defaultCommands.get(defaultCommands.size() - 1) instanceof BreakItem) {
|
||||
if (((BreakItem) defaultCommands.get(defaultCommands.size() - 1)).loopId == currentLoop.id) {
|
||||
@@ -630,7 +630,7 @@ public class AVM2Graph extends Graph {
|
||||
stopPart2.add(defaultPart);
|
||||
}
|
||||
|
||||
cc.addAll(0, printGraph(localData, stack, allParts, switchLoc, caseBodies.get(i), stopPart2, loops, staticOperation, path));
|
||||
cc.addAll(0, printGraph(partCodes, partCodePos, localData, stack, allParts, switchLoc, caseBodies.get(i), stopPart2, loops, staticOperation, path));
|
||||
caseCommands.add(cc);
|
||||
}
|
||||
|
||||
@@ -642,7 +642,7 @@ public class AVM2Graph extends Graph {
|
||||
ret.add(ti);
|
||||
} else {*/
|
||||
currentLoop.phase = 2;
|
||||
ret.addAll(printGraph(localData, stack, allParts, null, next, stopPart, loops, staticOperation, path));
|
||||
ret.addAll(printGraph(partCodes, partCodePos, localData, stack, allParts, null, next, stopPart, loops, staticOperation, path));
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -204,7 +204,7 @@ public final class MethodBody implements Cloneable {
|
||||
if (exportMode != ScriptExportMode.AS) {
|
||||
getCode().toASMSource(constants, trait, method_info.get(this.method_info), this, exportMode, writer);
|
||||
} else {
|
||||
//if (!path.contains("RemoveAllPopup")) {
|
||||
//if (!path.contains("_addGarbageLineMulti")) {
|
||||
if (!Configuration.decompile.get()) {
|
||||
writer.appendNoHilight(Helper.getDecompilationSkippedComment()).newLine();
|
||||
return;
|
||||
@@ -248,7 +248,7 @@ public final class MethodBody implements Cloneable {
|
||||
if (exportMode != ScriptExportMode.AS) {
|
||||
getCode().toASMSource(constants, trait, method_info.get(this.method_info), this, exportMode, writer);
|
||||
} else {
|
||||
//if (!path.contains("RemoveAllPopup")) {
|
||||
//if (!path.contains("_addGarbageLineMulti")) {
|
||||
if (!Configuration.decompile.get()) {
|
||||
//writer.startMethod(this.method_info);
|
||||
writer.appendNoHilight(Helper.getDecompilationSkippedComment()).newLine();
|
||||
|
||||
@@ -53,6 +53,7 @@ import com.jpexs.decompiler.graph.model.WhileItem;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -247,7 +248,7 @@ public class ActionGraph extends Graph {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<GraphTargetItem> check(GraphSource code, BaseLocalData localData, List<GraphPart> allParts, TranslateStack stack, GraphPart parent, GraphPart part, List<GraphPart> stopPart, List<Loop> loops, List<GraphTargetItem> output, Loop currentLoop, int staticOperation, String path) throws InterruptedException {
|
||||
protected List<GraphTargetItem> check(Map<GraphPart, List<GraphTargetItem>> partCodes, Map<GraphPart, Integer> partCodePos, GraphSource code, BaseLocalData localData, List<GraphPart> allParts, TranslateStack stack, GraphPart parent, GraphPart part, List<GraphPart> stopPart, List<Loop> loops, List<GraphTargetItem> output, Loop currentLoop, int staticOperation, String path) throws InterruptedException {
|
||||
if (!output.isEmpty()) {
|
||||
if (output.get(output.size() - 1) instanceof StoreRegisterActionItem) {
|
||||
StoreRegisterActionItem str = (StoreRegisterActionItem) output.get(output.size() - 1);
|
||||
@@ -310,7 +311,7 @@ public class ActionGraph extends Graph {
|
||||
List<GraphTargetItem> defaultCommands = new ArrayList<>();
|
||||
List<GraphPart> stopPart2 = new ArrayList<>(stopPart);
|
||||
stopPart2.add(defaultPart2);
|
||||
defaultCommands = printGraph(localData, stack, allParts, null, defaultPart, stopPart2, loops, staticOperation, path);
|
||||
defaultCommands = printGraph(partCodes, partCodePos, localData, stack, allParts, null, defaultPart, stopPart2, loops, staticOperation, path);
|
||||
|
||||
List<GraphPart> loopContinues = new ArrayList<>();
|
||||
for (Loop l : loops) {
|
||||
@@ -384,7 +385,7 @@ public class ActionGraph extends Graph {
|
||||
if ((defaultPart != null) && (defaultCommands.isEmpty())) {
|
||||
List<GraphPart> stopPart2x = new ArrayList<>(stopPart);
|
||||
stopPart2x.add(next);
|
||||
defaultCommands = printGraph(localData, stack, allParts, null, defaultPart, stopPart2x, loops, staticOperation, path);
|
||||
defaultCommands = printGraph(partCodes, partCodePos, localData, stack, allParts, null, defaultPart, stopPart2x, loops, staticOperation, path);
|
||||
}
|
||||
|
||||
if (!defaultCommands.isEmpty()) {
|
||||
@@ -433,7 +434,7 @@ public class ActionGraph extends Graph {
|
||||
if (breakPart != null) {
|
||||
stopPart2x.add(breakPart);
|
||||
}
|
||||
cc.addAll(0, printGraph(localData, stack, allParts, null, caseBodies.get(i), stopPart2x, loops, staticOperation, path));
|
||||
cc.addAll(0, printGraph(partCodes, partCodePos, localData, stack, allParts, null, caseBodies.get(i), stopPart2x, loops, staticOperation, path));
|
||||
if (cc.size() >= 2) {
|
||||
if (cc.get(cc.size() - 1) instanceof BreakItem) {
|
||||
if ((cc.get(cc.size() - 2) instanceof ContinueItem) || (cc.get(cc.size() - 2) instanceof BreakItem)) {
|
||||
@@ -452,7 +453,7 @@ public class ActionGraph extends Graph {
|
||||
if (ti != null) {
|
||||
ret.add(ti);
|
||||
} else {
|
||||
ret.addAll(printGraph(localData, stack, allParts, null, next, stopPart, loops, staticOperation, path));
|
||||
ret.addAll(printGraph(partCodes, partCodePos, localData, stack, allParts, null, next, stopPart, loops, staticOperation, path));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,8 +31,10 @@ import com.jpexs.decompiler.graph.model.DuplicateItem;
|
||||
import com.jpexs.decompiler.graph.model.ExitItem;
|
||||
import com.jpexs.decompiler.graph.model.FalseItem;
|
||||
import com.jpexs.decompiler.graph.model.ForItem;
|
||||
import com.jpexs.decompiler.graph.model.GotoItem;
|
||||
import com.jpexs.decompiler.graph.model.IfItem;
|
||||
import com.jpexs.decompiler.graph.model.IntegerValueItem;
|
||||
import com.jpexs.decompiler.graph.model.LabelItem;
|
||||
import com.jpexs.decompiler.graph.model.LocalData;
|
||||
import com.jpexs.decompiler.graph.model.LogicalOpItem;
|
||||
import com.jpexs.decompiler.graph.model.LoopItem;
|
||||
@@ -434,7 +436,7 @@ public class Graph {
|
||||
/*1
|
||||
System.err.println("<loops>");
|
||||
for (Loop el : loops) {
|
||||
System..println(el);
|
||||
System.err.println(el);
|
||||
}
|
||||
System.err.println("</loops>");*/
|
||||
getPrecontinues(path, localData, null, heads.get(0), allParts, loops, null);
|
||||
@@ -444,7 +446,7 @@ public class Graph {
|
||||
}
|
||||
System.err.println("</loopspre>");//*/
|
||||
|
||||
List<GraphTargetItem> ret = printGraph(localData, stack, allParts, null, heads.get(0), null, loops, staticOperation, path);
|
||||
List<GraphTargetItem> ret = printGraph(new HashMap<>(), new HashMap<>(), localData, stack, allParts, null, heads.get(0), null, loops, staticOperation, path);
|
||||
processIfs(ret);
|
||||
finalProcessStack(stack, ret);
|
||||
finalProcessAll(ret, 0, new FinalProcessLocalData());
|
||||
@@ -731,7 +733,7 @@ public class Graph {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected List<GraphTargetItem> check(GraphSource code, BaseLocalData localData, List<GraphPart> allParts, TranslateStack stack, GraphPart parent, GraphPart part, List<GraphPart> stopPart, List<Loop> loops, List<GraphTargetItem> output, Loop currentLoop, int staticOperation, String path) throws InterruptedException {
|
||||
protected List<GraphTargetItem> check(Map<GraphPart, List<GraphTargetItem>> partCodes, Map<GraphPart, Integer> partCodePos, GraphSource code, BaseLocalData localData, List<GraphPart> allParts, TranslateStack stack, GraphPart parent, GraphPart part, List<GraphPart> stopPart, List<Loop> loops, List<GraphTargetItem> output, Loop currentLoop, int staticOperation, String path) throws InterruptedException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -807,9 +809,9 @@ public class Graph {
|
||||
list.remove(list.size() - 1);
|
||||
}
|
||||
|
||||
protected List<GraphTargetItem> printGraph(BaseLocalData localData, TranslateStack stack, List<GraphPart> allParts, GraphPart parent, GraphPart part, List<GraphPart> stopPart, List<Loop> loops, int staticOperation, String path) throws InterruptedException {
|
||||
protected List<GraphTargetItem> printGraph(Map<GraphPart, List<GraphTargetItem>> partCodes, Map<GraphPart, Integer> partCodePos, BaseLocalData localData, TranslateStack stack, List<GraphPart> allParts, GraphPart parent, GraphPart part, List<GraphPart> stopPart, List<Loop> loops, int staticOperation, String path) throws InterruptedException {
|
||||
List<GraphPart> visited = new ArrayList<>();
|
||||
return printGraph(visited, localData, stack, allParts, parent, part, stopPart, loops, null, staticOperation, path, 0);
|
||||
return printGraph(partCodes, partCodePos, visited, localData, stack, allParts, parent, part, stopPart, loops, null, staticOperation, path, 0);
|
||||
}
|
||||
|
||||
protected GraphTargetItem checkLoop(LoopItem loopItem, BaseLocalData localData, List<Loop> loops) {
|
||||
@@ -1305,7 +1307,7 @@ public class Graph {
|
||||
}
|
||||
}
|
||||
|
||||
protected List<GraphTargetItem> printGraph(List<GraphPart> visited, BaseLocalData localData, TranslateStack stack, List<GraphPart> allParts, GraphPart parent, GraphPart part, List<GraphPart> stopPart, List<Loop> loops, List<GraphTargetItem> ret, int staticOperation, String path, int recursionLevel) throws InterruptedException {
|
||||
protected List<GraphTargetItem> printGraph(Map<GraphPart, List<GraphTargetItem>> partCodes, Map<GraphPart, Integer> partCodePos, List<GraphPart> visited, BaseLocalData localData, TranslateStack stack, List<GraphPart> allParts, GraphPart parent, GraphPart part, List<GraphPart> stopPart, List<Loop> loops, List<GraphTargetItem> ret, int staticOperation, String path, int recursionLevel) throws InterruptedException {
|
||||
if (Thread.currentThread().isInterrupted()) {
|
||||
throw new InterruptedException();
|
||||
}
|
||||
@@ -1315,11 +1317,7 @@ public class Graph {
|
||||
if (recursionLevel > allParts.size() + 1) {
|
||||
throw new TranslateException("printGraph max recursion level reached.");
|
||||
}
|
||||
if (visited.contains(part)) {
|
||||
//return new ArrayList<GraphTargetItem>();
|
||||
} else {
|
||||
visited.add(part);
|
||||
}
|
||||
|
||||
if (ret == null) {
|
||||
ret = new ArrayList<>();
|
||||
}
|
||||
@@ -1429,6 +1427,23 @@ public class Graph {
|
||||
ret.add(new ScriptEndItem());
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (visited.contains(part)) {
|
||||
String labelName = "addr" + part.start;
|
||||
List<GraphTargetItem> firstCode = partCodes.get(part);
|
||||
int firstCodePos = partCodePos.get(part);
|
||||
if (firstCode.size() > firstCodePos && (firstCode.get(firstCodePos) instanceof LabelItem)) {
|
||||
labelName = ((LabelItem) firstCode.get(firstCodePos)).labelName;
|
||||
} else {
|
||||
firstCode.add(firstCodePos, new LabelItem(null, labelName));
|
||||
}
|
||||
ret.add(new GotoItem(null, labelName));
|
||||
return ret;
|
||||
} else {
|
||||
visited.add(part);
|
||||
partCodes.put(part, ret);
|
||||
partCodePos.put(part, ret.size());
|
||||
}
|
||||
List<GraphTargetItem> currentRet = ret;
|
||||
UniversalLoopItem loopItem = null;
|
||||
TranslateStack sPreLoop = stack;
|
||||
@@ -1466,7 +1481,7 @@ public class Graph {
|
||||
}
|
||||
|
||||
if (parseNext) {
|
||||
List<GraphTargetItem> retCheck = check(code, localData, allParts, stack, parent, part, stopPart, loops, output, currentLoop, staticOperation, path);
|
||||
List<GraphTargetItem> retCheck = check(partCodes, partCodePos, code, localData, allParts, stack, parent, part, stopPart, loops, output, currentLoop, staticOperation, path);
|
||||
if (retCheck != null) {
|
||||
if (!retCheck.isEmpty()) {
|
||||
currentRet.addAll(retCheck);
|
||||
@@ -1524,7 +1539,7 @@ public class Graph {
|
||||
//int stackLenBefore = stack.size();
|
||||
TranslateStack s2 = (TranslateStack) stack.clone();
|
||||
s2.clear();
|
||||
List<GraphTargetItem> nextCommands = printGraph(visited, prepareBranchLocalData(localData), s2, allParts, part, p, stopPart2, loops, null, staticOperation, path, recursionLevel + 1);
|
||||
List<GraphTargetItem> nextCommands = printGraph(partCodes, partCodePos, visited, prepareBranchLocalData(localData), s2, allParts, part, p, stopPart2, loops, null, staticOperation, path, recursionLevel + 1);
|
||||
makeAllCommands(nextCommands, s2);
|
||||
if (first) {
|
||||
defaultCommands = nextCommands;
|
||||
@@ -1539,7 +1554,7 @@ public class Graph {
|
||||
currentRet.add(sw);
|
||||
swLoop.phase = 2;
|
||||
if (next != null) {
|
||||
currentRet.addAll(printGraph(visited, localData, stack, allParts, part, next, stopPart, loops, null, staticOperation, path, recursionLevel + 1));
|
||||
currentRet.addAll(printGraph(partCodes, partCodePos, visited, localData, stack, allParts, part, next, stopPart, loops, null, staticOperation, path, recursionLevel + 1));
|
||||
}
|
||||
} //else
|
||||
GraphPart nextOnePart = null;
|
||||
@@ -1576,12 +1591,12 @@ public class Graph {
|
||||
|
||||
List<GraphTargetItem> onTrue = new ArrayList<>();
|
||||
if (!isEmpty && hasOntrue) {
|
||||
onTrue = printGraph(visited, prepareBranchLocalData(localData), trueStack, allParts, part, nps.get(1), stopPart2, loops, null, staticOperation, path, recursionLevel + 1);
|
||||
onTrue = printGraph(partCodes, partCodePos, visited, prepareBranchLocalData(localData), trueStack, allParts, part, nps.get(1), stopPart2, loops, null, staticOperation, path, recursionLevel + 1);
|
||||
}
|
||||
List<GraphTargetItem> onFalse = new ArrayList<>();
|
||||
|
||||
if (!isEmpty && hasOnFalse) {
|
||||
onFalse = printGraph(visited, prepareBranchLocalData(localData), falseStack, allParts, part, nps.get(0), stopPart2, loops, null, staticOperation, path, recursionLevel + 1);
|
||||
onFalse = printGraph(partCodes, partCodePos, visited, prepareBranchLocalData(localData), falseStack, allParts, part, nps.get(0), stopPart2, loops, null, staticOperation, path, recursionLevel + 1);
|
||||
}
|
||||
//List<GraphTargetItem> out2 = new ArrayList<>();
|
||||
//makeAllCommands(out2, stack);
|
||||
@@ -1625,7 +1640,7 @@ public class Graph {
|
||||
}
|
||||
//currentRet.addAll(out2);
|
||||
if (next != null) {
|
||||
printGraph(visited, localData, stack, allParts, part, next, stopPart, loops, currentRet, staticOperation, path, recursionLevel + 1);
|
||||
printGraph(partCodes, partCodePos, visited, localData, stack, allParts, part, next, stopPart, loops, currentRet, staticOperation, path, recursionLevel + 1);
|
||||
//currentRet.addAll();
|
||||
}
|
||||
}
|
||||
@@ -1634,7 +1649,7 @@ public class Graph {
|
||||
nextOnePart = part.nextParts.get(0);
|
||||
}
|
||||
if (nextOnePart != null) {
|
||||
printGraph(visited, localData, stack, allParts, part, part.nextParts.get(0), stopPart, loops, currentRet, staticOperation, path, recursionLevel + 1);
|
||||
printGraph(partCodes, partCodePos, visited, localData, stack, allParts, part, part.nextParts.get(0), stopPart, loops, currentRet, staticOperation, path, recursionLevel + 1);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1659,7 +1674,7 @@ public class Graph {
|
||||
stopContPart.add(currentLoop.loopContinue);
|
||||
GraphPart precoBackup = currentLoop.loopPreContinue;
|
||||
currentLoop.loopPreContinue = null;
|
||||
loopItem.commands.addAll(printGraph(visited, localData, new TranslateStack(path), allParts, null, precoBackup, stopContPart, loops, null, staticOperation, path, recursionLevel + 1));
|
||||
loopItem.commands.addAll(printGraph(partCodes, partCodePos, visited, localData, new TranslateStack(path), allParts, null, precoBackup, stopContPart, loops, null, staticOperation, path, recursionLevel + 1));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1716,7 +1731,7 @@ public class Graph {
|
||||
currentLoop.loopPreContinue = null;
|
||||
List<GraphPart> stopPart2 = new ArrayList<>(stopPart);
|
||||
stopPart2.add(currentLoop.loopContinue);
|
||||
finalComm = printGraph(visited, localData, new TranslateStack(path), allParts, null, backup, stopPart2, loops, null, staticOperation, path, recursionLevel + 1);
|
||||
finalComm = printGraph(partCodes, partCodePos, visited, localData, new TranslateStack(path), allParts, null, backup, stopPart2, loops, null, staticOperation, path, recursionLevel + 1);
|
||||
currentLoop.loopPreContinue = backup;
|
||||
checkContinueAtTheEnd(finalComm, currentLoop);
|
||||
}
|
||||
@@ -1793,7 +1808,7 @@ public class Graph {
|
||||
currentLoop.loopPreContinue = null;
|
||||
List<GraphPart> stopPart2 = new ArrayList<>(stopPart);
|
||||
stopPart2.add(currentLoop.loopContinue);
|
||||
List<GraphTargetItem> finalComm = printGraph(visited, localData, new TranslateStack(path), allParts, null, backup, stopPart2, loops, null, staticOperation, path, recursionLevel + 1);
|
||||
List<GraphTargetItem> finalComm = printGraph(partCodes, partCodePos, visited, localData, new TranslateStack(path), allParts, null, backup, stopPart2, loops, null, staticOperation, path, recursionLevel + 1);
|
||||
currentLoop.loopPreContinue = backup;
|
||||
checkContinueAtTheEnd(finalComm, currentLoop);
|
||||
|
||||
@@ -1843,7 +1858,7 @@ public class Graph {
|
||||
}
|
||||
|
||||
if (currentLoop.loopBreak != null) {
|
||||
ret.addAll(printGraph(visited, localData, sPreLoop, allParts, part, currentLoop.loopBreak, stopPart, loops, null, staticOperation, path, recursionLevel + 1));
|
||||
ret.addAll(printGraph(partCodes, partCodePos, visited, localData, sPreLoop, allParts, part, currentLoop.loopBreak, stopPart, loops, null, staticOperation, path, recursionLevel + 1));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 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.ecma.Null;
|
||||
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.TypeItem;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class GotoItem extends GraphTargetItem {
|
||||
|
||||
public String labelName;
|
||||
|
||||
public GotoItem(GraphSourceItem src, String labelName) {
|
||||
super(src, PRECEDENCE_PRIMARY);
|
||||
this.labelName = labelName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException {
|
||||
writer.append("§§goto(" + labelName + ")");
|
||||
return writer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasReturnValue() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTargetItem returnType() {
|
||||
return TypeItem.UNBOUNDED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getResult() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 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.ecma.Null;
|
||||
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.TypeItem;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class LabelItem extends GraphTargetItem {
|
||||
|
||||
public String labelName;
|
||||
|
||||
public LabelItem(GraphSourceItem src, String labelName) {
|
||||
super(src, PRECEDENCE_PRIMARY);
|
||||
this.labelName = labelName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException {
|
||||
writer.append(labelName + ":");
|
||||
return writer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean needsNewLine() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean needsSemicolon() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasReturnValue() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTargetItem returnType() {
|
||||
return TypeItem.UNBOUNDED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getResult() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user