Default clause position in switch fixed

This commit is contained in:
Jindra Petřík
2016-01-17 21:59:20 +01:00
parent 33e433fa26
commit 4994c4a70c
10 changed files with 279 additions and 185 deletions
@@ -86,6 +86,7 @@ import com.jpexs.decompiler.graph.model.AndItem;
import com.jpexs.decompiler.graph.model.BreakItem;
import com.jpexs.decompiler.graph.model.CommaExpressionItem;
import com.jpexs.decompiler.graph.model.ContinueItem;
import com.jpexs.decompiler.graph.model.DefaultItem;
import com.jpexs.decompiler.graph.model.DoWhileItem;
import com.jpexs.decompiler.graph.model.DuplicateItem;
import com.jpexs.decompiler.graph.model.FalseItem;
@@ -606,12 +607,21 @@ public class AVM2SourceGenerator implements SourceGenerator {
AVM2Instruction forwardJump = ins(AVM2Instructions.Jump, 0);
ret.add(forwardJump);
int defIndex = -1;
for (int i = item.caseValues.size() - 1; i >= 0; i--) {
if (item.caseValues.get(i) instanceof DefaultItem) {
defIndex = i;
break;
}
}
List<AVM2Instruction> cases = new ArrayList<>();
cases.addAll(toInsList(new IntegerValueAVM2Item(null, null, (long) item.caseValues.size()).toSource(localData, this)));
cases.addAll(toInsList(new IntegerValueAVM2Item(null, null, (long) defIndex).toSource(localData, this)));
int cLen = insToBytes(cases).length;
List<AVM2Instruction> caseLast = new ArrayList<>();
caseLast.add(0, ins(AVM2Instructions.Jump, cLen));
caseLast.addAll(0, toInsList(new IntegerValueAVM2Item(null, null, (long) item.caseValues.size()).toSource(localData, this)));
caseLast.addAll(0, toInsList(new IntegerValueAVM2Item(null, null, (long) defIndex).toSource(localData, this)));
int cLastLen = insToBytes(caseLast).length;
caseLast.add(0, ins(AVM2Instructions.Jump, cLastLen));
cases.addAll(0, caseLast);
@@ -621,6 +631,9 @@ public class AVM2SourceGenerator implements SourceGenerator {
preCases.addAll(toInsList(AssignableAVM2Item.setTemp(localData, this, switchedReg)));
for (int i = item.caseValues.size() - 1; i >= 0; i--) {
if (item.caseValues.get(i) instanceof DefaultItem) {
continue;
}
List<AVM2Instruction> sub = new ArrayList<>();
sub.addAll(toInsList(new IntegerValueAVM2Item(null, null, (long) i).toSource(localData, this)));
sub.add(ins(AVM2Instructions.Jump, insToBytes(cases).length));
@@ -633,13 +646,12 @@ public class AVM2SourceGenerator implements SourceGenerator {
}
cases.addAll(0, preCases);
AVM2Instruction lookupOp = new AVM2Instruction(0, AVM2Instructions.LookupSwitch, new int[item.caseValues.size() + 1 + 1 + 1]);
AVM2Instruction lookupOp = new AVM2Instruction(0, AVM2Instructions.LookupSwitch, new int[item.caseValues.size() + 1 + 1]);
cases.addAll(toInsList(AssignableAVM2Item.killTemp(localData, this, Arrays.asList(switchedReg))));
List<AVM2Instruction> bodies = new ArrayList<>();
List<Integer> bodiesOffsets = new ArrayList<>();
int defOffset;
int casesLen = insToBytes(cases).length;
bodies.addAll(generateToInsList(localData, item.defaultCommands));
bodies.add(0, ins(AVM2Instructions.Label));
bodies.add(ins(new BreakJumpIns(item.loop.id), 0)); //There could be two breaks when default clause ends with break, but official compiler does this too, so who cares...
defOffset = -(insToBytes(bodies).length + casesLen);
@@ -650,7 +662,6 @@ public class AVM2SourceGenerator implements SourceGenerator {
}
lookupOp.operands[0] = defOffset;
lookupOp.operands[1] = item.valuesMapping.size();
lookupOp.operands[2 + item.caseValues.size()] = defOffset;
for (int i = 0; i < item.valuesMapping.size(); i++) {
lookupOp.operands[2 + i] = bodiesOffsets.get(item.valuesMapping.get(i));
}
@@ -98,6 +98,7 @@ import com.jpexs.decompiler.graph.model.BlockItem;
import com.jpexs.decompiler.graph.model.BreakItem;
import com.jpexs.decompiler.graph.model.CommaExpressionItem;
import com.jpexs.decompiler.graph.model.ContinueItem;
import com.jpexs.decompiler.graph.model.DefaultItem;
import com.jpexs.decompiler.graph.model.DoWhileItem;
import com.jpexs.decompiler.graph.model.DuplicateItem;
import com.jpexs.decompiler.graph.model.ForItem;
@@ -1627,9 +1628,9 @@ public class ActionScript3Parser {
List<GraphTargetItem> caseExprsAll = new ArrayList<>();
List<Integer> valueMapping = new ArrayList<>();
int pos = 0;
while (s.type == SymbolType.CASE) {
while (s.type == SymbolType.CASE) {
GraphTargetItem curCaseExpr = expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables);
while (s.type == SymbolType.CASE || s.type == SymbolType.DEFAULT) {
while (s.type == SymbolType.CASE || s.type == SymbolType.DEFAULT) {
GraphTargetItem curCaseExpr = s.type == SymbolType.DEFAULT ? new DefaultItem() : expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables);
expectedType(SymbolType.COLON);
s = lex();
caseExprsAll.add(curCaseExpr);
@@ -1641,14 +1642,8 @@ public class ActionScript3Parser {
caseCmds.add(caseCmd);
s = lex();
}
List<GraphTargetItem> defCmd = new ArrayList<>();
if (s.type == SymbolType.DEFAULT) {
expectedType(SymbolType.COLON);
defCmd = commands(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, variables);
s = lexer.lex();
}
expected(s, lexer.yyline(), SymbolType.CURLY_CLOSE);
ret = new SwitchItem(null, null, sloop, switchExpr, caseExprsAll, caseCmds, defCmd, valueMapping);
ret = new SwitchItem(null, null, sloop, switchExpr, caseExprsAll, caseCmds, valueMapping);
break;
case BREAK:
s = lex();