return in try

This commit is contained in:
Jindra Petřík
2021-01-25 11:01:30 +01:00
parent f4e4835f29
commit ddd2d5697b
11 changed files with 162 additions and 17 deletions

View File

@@ -33,6 +33,16 @@ public class FinalProcessLocalData {
public final List<Loop> loops;
public Map<Integer, Set<Integer>> registerUsage;
public Set<Integer> getRegisterUsage(int regIndex) {
if (registerUsage == null) {
return new HashSet<>();
}
if (!registerUsage.containsKey(regIndex)) {
return new HashSet<>();
}
return registerUsage.get(regIndex);
}
public FinalProcessLocalData(List<Loop> loops) {
temporaryRegisters = new HashSet<>();
registerUsage = new HashMap<>();

View File

@@ -76,7 +76,7 @@ public class AVM2LocalData extends BaseLocalData {
public boolean thisHasDefaultToPrimitive;
public Map<Integer, Set<Integer>> setLocalPosToGetLocalPos;
public Map<Integer, Set<Integer>> setLocalPosToGetLocalPos = new HashMap<>();
public AVM2LocalData() {

View File

@@ -284,7 +284,7 @@ public class AVM2Graph extends Graph {
return;
}
if (ignoredSwitches.contains(q.end)) {
if (!next.equals(q.nextParts.get(0))) { //first is after finally
if (q.nextParts.isEmpty() || !next.equals(q.nextParts.get(0))) { //first is after finally
return;
}
}
@@ -616,6 +616,7 @@ public class AVM2Graph extends Graph {
}
output.clear();
stack.clear();
makeAllCommands(tryCommands, st);
output.add(new TryAVM2Item(tryCommands, catchedExceptions, catchedCommands, finallyCommands, finCatchName));
for (int fin_e : catchedFinallys) {
if (finallyJumps.containsKey(fin_e)) {
@@ -940,7 +941,7 @@ public class AVM2Graph extends Graph {
if (next.start == fip) {
if (stack != null && swip != -1) {
AVM2Instruction swIns = avm2code.code.get(swip);
GraphTargetItem t = stack.pop();
GraphTargetItem t = stack.peek();
Double dval = t.getResultAsNumber();
int val = (int) (double) dval;
if (swIns.definition instanceof LookupSwitchIns) {
@@ -1194,7 +1195,7 @@ public class AVM2Graph extends Graph {
@Override
protected void finalProcessAfter(List<GraphTargetItem> list, int level, FinalProcessLocalData localData, String path) {
super.finalProcessAfter(list, level, localData, path);
for (int i = 0; i < list.size(); i++) {
/*for (int i = 0; i < list.size(); i++) {
if (list.get(i) instanceof SetLocalAVM2Item) {
SetLocalAVM2Item ri = (SetLocalAVM2Item) list.get(i);
if (localData.temporaryRegisters.contains(ri.regIndex)) {
@@ -1202,9 +1203,18 @@ public class AVM2Graph extends Graph {
i--;
}
}
}
}*/
}
private boolean isIntegerOrPopInteger(GraphTargetItem item) {
if (item instanceof IntegerValueAVM2Item) {
return true;
}
if ((item instanceof PushItem) && (item.value instanceof IntegerValueAVM2Item)) {
return true;
}
return false;
}
@Override
protected void finalProcess(List<GraphTargetItem> list, int level, FinalProcessLocalData localData, String path) throws InterruptedException {
@@ -1227,7 +1237,7 @@ public class AVM2Graph extends Graph {
if (list.get(i) instanceof SetLocalAVM2Item) {
SetLocalAVM2Item ri = (SetLocalAVM2Item) list.get(i);
int setLocalIp = avm2code.adr2pos(ri.getSrc().getAddress());
Set<Integer> usages = localData.registerUsage.get(setLocalIp);
Set<Integer> usages = localData.getRegisterUsage(setLocalIp);
if (ri.value.getNotCoerced() instanceof ExceptionAVM2Item) {
ExceptionAVM2Item ea = (ExceptionAVM2Item) ri.value.getNotCoerced();
if (ea.exception.isFinally()) {
@@ -1261,7 +1271,7 @@ public class AVM2Graph extends Graph {
}
if (i + 2 < list.size()) {
if ((list.get(i + 1) instanceof IntegerValueAVM2Item) && (list.get(i + 2) instanceof ReturnValueAVM2Item)
if (isIntegerOrPopInteger(list.get(i + 1)) && (list.get(i + 2) instanceof ReturnValueAVM2Item)
&& (list.get(i + 2).value instanceof LocalRegAVM2Item)
&& (((LocalRegAVM2Item) list.get(i + 2).value).regIndex == ri.regIndex)) {
ReturnValueAVM2Item r = (ReturnValueAVM2Item) list.get(i + 2);
@@ -1271,7 +1281,7 @@ public class AVM2Graph extends Graph {
i--;
continue;
}
if ((list.get(i + 1) instanceof IntegerValueAVM2Item) && (list.get(i + 2) instanceof ThrowAVM2Item)
if (isIntegerOrPopInteger(list.get(i + 1)) && (list.get(i + 2) instanceof ThrowAVM2Item)
&& (list.get(i + 2).value instanceof LocalRegAVM2Item)
&& (((LocalRegAVM2Item) list.get(i + 2).value).regIndex == ri.regIndex)) {
ThrowAVM2Item t = (ThrowAVM2Item) list.get(i + 2);
@@ -1282,8 +1292,11 @@ public class AVM2Graph extends Graph {
continue;
}
} else if (i + 1 < list.size() && usages.isEmpty()) {
if (list.get(i + 1) instanceof IntegerValueAVM2Item) {
if (isIntegerOrPopInteger(list.get(i + 1))) {
list.remove(i + 1);
list.remove(i);
i--;
continue;
}
}
}

View File

@@ -1264,6 +1264,83 @@ public class ActionScript3Test extends ActionScriptTestBase {
false);
}
@Test
public void testTryReturn2() {
decompileMethod("testTryReturn2", "var c:Boolean = false;\r\n"
+ "trace(\"before\");\r\n"
+ "var a:Boolean = true;\r\n"
+ "var b:Boolean = false;\r\n"
+ "c = true;\r\n"
+ "var d:Boolean = false;\r\n"
+ "var e:Boolean = true;\r\n"
+ "try\r\n"
+ "{\r\n"
+ "if(a)\r\n"
+ "{\r\n"
+ "return \"A\";\r\n"
+ "}\r\n"
+ "if(b)\r\n"
+ "{\r\n"
+ "return \"B\";\r\n"
+ "}\r\n"
+ "}\r\n"
+ "catch(e:Error)\r\n"
+ "{\r\n"
+ "if(c)\r\n"
+ "{\r\n"
+ "return \"C\";\r\n"
+ "}\r\n"
+ "}\r\n"
+ "finally\r\n"
+ "{\r\n"
+ "if(d)\r\n"
+ "{\r\n"
+ "return \"D\";\r\n"
+ "}\r\n"
+ "if(e)\r\n"
+ "{\r\n"
+ "return \"E\";\r\n"
+ "}\r\n"
+ "}\r\n"
+ "trace(\"after\");\r\n"
+ "return \"X\";\r\n",
false);
}
@Test
public void testUsagesTry() {
decompileMethod("testUsagesTry", "var k:int = 5;\r\n"
+ "switch(k)\r\n"
+ "{\r\n"
+ "case 0:\r\n"
+ "trace(\"1\");\r\n"
+ "break;\r\n"
+ "case 1:\r\n"
+ "trace(\"2\");\r\n"
+ "}\r\n"
+ "var a:Boolean = true;\r\n"
+ "var b:Boolean = true;\r\n"
+ "try\r\n"
+ "{\r\n"
+ "if(b)\r\n"
+ "{\r\n"
+ "return \"B\";\r\n"
+ "}\r\n"
+ "trace(\"A\");\r\n"
+ "}\r\n"
+ "catch(e:Error)\r\n"
+ "{\r\n"
+ "trace(\"E\");\r\n"
+ "}\r\n"
+ "finally\r\n"
+ "{\r\n"
+ "trace(\"finally\");\r\n"
+ "}\r\n"
+ "trace(\"after\");\r\n"
+ "return \"X\";\r\n",
false);
}
@Test
public void testVector() {
decompileMethod("testVector", "var v:Vector.<String> = new Vector.<String>();\r\n"

View File

@@ -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;
/**
@@ -22,6 +23,7 @@ package com.jpexs.decompiler.flash;
public class ActionScriptTestBase {
protected String cleanPCode(String pCode) {
pCode = pCode.replaceAll("\t", " ").trim();
pCode = pCode.replaceAll("( *[\r\n]+ *)+", "\n").trim();
pCode = pCode.replaceAll(" +", " ").trim();
return pCode;

View File

@@ -16,7 +16,7 @@
</define>
<define append="true">
<name>CONFIG::timeStamp</name>
<value>'24.01.2021'</value>
<value>'25.01.2021'</value>
</define>
<define append="true">
<name>CONFIG::air</name>

View File

@@ -16,7 +16,7 @@
</define>
<define append="true">
<name>CONFIG::timeStamp</name>
<value>'24.01.2021'</value>
<value>'25.01.2021'</value>
</define>
<define append="true">
<name>CONFIG::air</name>

View File

@@ -77,6 +77,7 @@ package
TestTry;
TestTryReturn;
TestTryReturn2;
TestUsagesTry;
TestVector;
TestVector2;
TestWhileAnd;

View File

@@ -6,10 +6,12 @@ package tests
public function run() : String
{
trace("before");
var a:Boolean = true;
var b:Boolean = false;
var c:Boolean = true;
var d:Boolean = false;
var e:Boolean = true;
try
{
if (a)
@@ -23,14 +25,17 @@ package tests
}
catch (e:Error)
{
if (d){
return "D";
if (c){
return "C";
}
}
finally
{
if (c) {
return "C";
{
if (d) {
return "D";
}
if (e) {
return "E";
}
}
trace("after");

View File

@@ -0,0 +1,37 @@
package tests
{
public class TestUsagesTry
{
public function run() : String
{
var k:int = 5;
switch(k){
case 0: trace("1"); break;
case 1: trace("2"); break;
}
var a:Boolean = true;
var b:Boolean = true;
try
{
if (b) {
return "B";
}
trace("A");
}
catch (e:Error)
{
trace("E");
}
finally
{
trace("finally");
}
trace("after");
return "X";
}
}
}