AS3 parser: Fixed If, While, DoWhile,For

This commit is contained in:
Jindra Petk
2014-04-05 12:31:11 +02:00
parent 57ac7aa7aa
commit b8a63c8d5a
14 changed files with 307 additions and 76 deletions

View File

@@ -47,7 +47,7 @@ public class NanAVM2Item extends AVM2Item {
@Override
public GraphTargetItem returnType() {
return TypeItem.UNBOUNDED;
return new TypeItem("Number");
}
@Override

View File

@@ -18,7 +18,10 @@ package com.jpexs.decompiler.flash.abc.avm2.model.operations;
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
import com.jpexs.decompiler.flash.abc.avm2.instructions.comparison.EqualsIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.IfEqIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.IfNeIns;
import com.jpexs.decompiler.flash.ecma.EcmaScript;
import com.jpexs.decompiler.graph.GraphSourceItem;
import com.jpexs.decompiler.graph.GraphTargetItem;
@@ -28,12 +31,25 @@ import com.jpexs.decompiler.graph.model.BinaryOpItem;
import com.jpexs.decompiler.graph.model.LogicalOpItem;
import java.util.List;
public class EqAVM2Item extends BinaryOpItem implements LogicalOpItem {
public class EqAVM2Item extends BinaryOpItem implements LogicalOpItem, IfCondition {
public EqAVM2Item(GraphSourceItem instruction, GraphTargetItem leftSide, GraphTargetItem rightSide) {
super(instruction, PRECEDENCE_EQUALITY, leftSide, rightSide, "==");
}
@Override
public InstructionDefinition getIfDefinition() {
return new IfEqIns();
}
@Override
public InstructionDefinition getIfNotDefinition() {
return new IfNeIns();
}
@Override
public Object getResult() {
return EcmaScript.equals(leftSide.getResult(), rightSide.getResult());

View File

@@ -18,7 +18,11 @@ package com.jpexs.decompiler.flash.abc.avm2.model.operations;
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
import com.jpexs.decompiler.flash.abc.avm2.instructions.comparison.GreaterEqualsIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.IfEqIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.IfGeIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.IfNGeIns;
import com.jpexs.decompiler.flash.ecma.EcmaScript;
import com.jpexs.decompiler.graph.GraphSourceItem;
import com.jpexs.decompiler.graph.GraphTargetItem;
@@ -28,12 +32,24 @@ import com.jpexs.decompiler.graph.model.BinaryOpItem;
import com.jpexs.decompiler.graph.model.LogicalOpItem;
import java.util.List;
public class GeAVM2Item extends BinaryOpItem implements LogicalOpItem {
public class GeAVM2Item extends BinaryOpItem implements LogicalOpItem, IfCondition {
public GeAVM2Item(GraphSourceItem instruction, GraphTargetItem leftSide, GraphTargetItem rightSide) {
super(instruction, PRECEDENCE_RELATIONAL, leftSide, rightSide, ">=");
}
@Override
public InstructionDefinition getIfDefinition() {
return new IfGeIns();
}
@Override
public InstructionDefinition getIfNotDefinition() {
return new IfNGeIns();
}
@Override
public GraphTargetItem invert() {
return new LtAVM2Item(src, leftSide, rightSide);

View File

@@ -18,7 +18,11 @@ package com.jpexs.decompiler.flash.abc.avm2.model.operations;
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
import com.jpexs.decompiler.flash.abc.avm2.instructions.comparison.GreaterThanIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.IfEqIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.IfGtIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.IfNGtIns;
import com.jpexs.decompiler.flash.ecma.EcmaScript;
import com.jpexs.decompiler.graph.GraphSourceItem;
import com.jpexs.decompiler.graph.GraphTargetItem;
@@ -28,11 +32,23 @@ import com.jpexs.decompiler.graph.model.BinaryOpItem;
import com.jpexs.decompiler.graph.model.LogicalOpItem;
import java.util.List;
public class GtAVM2Item extends BinaryOpItem implements LogicalOpItem {
public class GtAVM2Item extends BinaryOpItem implements LogicalOpItem,IfCondition {
public GtAVM2Item(GraphSourceItem instruction, GraphTargetItem leftSide, GraphTargetItem rightSide) {
super(instruction, PRECEDENCE_RELATIONAL, leftSide, rightSide, ">");
}
@Override
public InstructionDefinition getIfDefinition() {
return new IfGtIns();
}
@Override
public InstructionDefinition getIfNotDefinition() {
return new IfNGtIns();
}
@Override
public GraphTargetItem invert() {

View File

@@ -0,0 +1,30 @@
/*
* Copyright (C) 2014 JPEXS
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.jpexs.decompiler.flash.abc.avm2.model.operations;
import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
import com.jpexs.decompiler.graph.model.BinaryOp;
/**
*
* @author JPEXS
*/
public interface IfCondition extends BinaryOp{
public InstructionDefinition getIfDefinition();
public InstructionDefinition getIfNotDefinition();
}

View File

@@ -18,7 +18,11 @@ package com.jpexs.decompiler.flash.abc.avm2.model.operations;
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
import com.jpexs.decompiler.flash.abc.avm2.instructions.comparison.LessEqualsIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.IfEqIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.IfLeIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.IfNLeIns;
import com.jpexs.decompiler.flash.ecma.EcmaScript;
import com.jpexs.decompiler.graph.GraphSourceItem;
import com.jpexs.decompiler.graph.GraphTargetItem;
@@ -28,12 +32,24 @@ import com.jpexs.decompiler.graph.model.BinaryOpItem;
import com.jpexs.decompiler.graph.model.LogicalOpItem;
import java.util.List;
public class LeAVM2Item extends BinaryOpItem implements LogicalOpItem {
public class LeAVM2Item extends BinaryOpItem implements LogicalOpItem,IfCondition {
public LeAVM2Item(GraphSourceItem instruction, GraphTargetItem leftSide, GraphTargetItem rightSide) {
super(instruction, PRECEDENCE_RELATIONAL, leftSide, rightSide, "<=");
}
@Override
public InstructionDefinition getIfDefinition() {
return new IfLeIns();
}
@Override
public InstructionDefinition getIfNotDefinition() {
return new IfNLeIns();
}
@Override
public GraphTargetItem invert() {
return new GtAVM2Item(src, leftSide, rightSide);

View File

@@ -18,7 +18,11 @@ package com.jpexs.decompiler.flash.abc.avm2.model.operations;
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
import com.jpexs.decompiler.flash.abc.avm2.instructions.comparison.LessThanIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.IfEqIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.IfLtIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.IfNLtIns;
import com.jpexs.decompiler.flash.ecma.EcmaScript;
import com.jpexs.decompiler.graph.GraphSourceItem;
import com.jpexs.decompiler.graph.GraphTargetItem;
@@ -28,12 +32,24 @@ import com.jpexs.decompiler.graph.model.BinaryOpItem;
import com.jpexs.decompiler.graph.model.LogicalOpItem;
import java.util.List;
public class LtAVM2Item extends BinaryOpItem implements LogicalOpItem {
public class LtAVM2Item extends BinaryOpItem implements LogicalOpItem,IfCondition {
public LtAVM2Item(GraphSourceItem instruction, GraphTargetItem leftSide, GraphTargetItem rightSide) {
super(instruction, PRECEDENCE_RELATIONAL, leftSide, rightSide, "<");
}
@Override
public InstructionDefinition getIfDefinition() {
return new IfLtIns();
}
@Override
public InstructionDefinition getIfNotDefinition() {
return new IfNLtIns();
}
@Override
public GraphTargetItem invert() {
return new GeAVM2Item(src, leftSide, rightSide);

View File

@@ -18,8 +18,11 @@ package com.jpexs.decompiler.flash.abc.avm2.model.operations;
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
import com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic.NotIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.comparison.EqualsIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.IfEqIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.IfNeIns;
import com.jpexs.decompiler.flash.ecma.EcmaScript;
import com.jpexs.decompiler.graph.GraphSourceItem;
import com.jpexs.decompiler.graph.GraphTargetItem;
@@ -29,11 +32,22 @@ import com.jpexs.decompiler.graph.model.BinaryOpItem;
import com.jpexs.decompiler.graph.model.LogicalOpItem;
import java.util.List;
public class NeqAVM2Item extends BinaryOpItem implements LogicalOpItem {
public class NeqAVM2Item extends BinaryOpItem implements LogicalOpItem,IfCondition {
public NeqAVM2Item(GraphSourceItem instruction, GraphTargetItem leftSide, GraphTargetItem rightSide) {
super(instruction, PRECEDENCE_EQUALITY, leftSide, rightSide, "!=");
}
@Override
public InstructionDefinition getIfDefinition() {
return new IfNeIns();
}
@Override
public InstructionDefinition getIfNotDefinition() {
return new IfEqIns();
}
@Override
public Object getResult() {

View File

@@ -18,7 +18,11 @@ package com.jpexs.decompiler.flash.abc.avm2.model.operations;
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
import com.jpexs.decompiler.flash.abc.avm2.instructions.comparison.StrictEqualsIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.IfNeIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.IfStrictEqIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.IfStrictNeIns;
import com.jpexs.decompiler.flash.ecma.EcmaScript;
import com.jpexs.decompiler.graph.GraphSourceItem;
import com.jpexs.decompiler.graph.GraphTargetItem;
@@ -28,12 +32,24 @@ import com.jpexs.decompiler.graph.model.BinaryOpItem;
import com.jpexs.decompiler.graph.model.LogicalOpItem;
import java.util.List;
public class StrictEqAVM2Item extends BinaryOpItem implements LogicalOpItem {
public class StrictEqAVM2Item extends BinaryOpItem implements LogicalOpItem,IfCondition {
public StrictEqAVM2Item(GraphSourceItem instruction, GraphTargetItem leftSide, GraphTargetItem rightSide) {
super(instruction, PRECEDENCE_EQUALITY, leftSide, rightSide, "===");
}
@Override
public InstructionDefinition getIfDefinition() {
return new IfStrictEqIns();
}
@Override
public InstructionDefinition getIfNotDefinition() {
return new IfStrictNeIns();
}
@Override
public Object getResult() {
Object x = leftSide.getResult();

View File

@@ -18,8 +18,12 @@ package com.jpexs.decompiler.flash.abc.avm2.model.operations;
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
import com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic.NotIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.comparison.StrictEqualsIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.IfNeIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.IfStrictEqIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.IfStrictNeIns;
import com.jpexs.decompiler.flash.ecma.EcmaScript;
import com.jpexs.decompiler.graph.GraphSourceItem;
import com.jpexs.decompiler.graph.GraphTargetItem;
@@ -29,11 +33,23 @@ import com.jpexs.decompiler.graph.model.BinaryOpItem;
import com.jpexs.decompiler.graph.model.LogicalOpItem;
import java.util.List;
public class StrictNeqAVM2Item extends BinaryOpItem implements LogicalOpItem {
public class StrictNeqAVM2Item extends BinaryOpItem implements LogicalOpItem,IfCondition {
public StrictNeqAVM2Item(GraphSourceItem instruction, GraphTargetItem leftSide, GraphTargetItem rightSide) {
super(instruction, PRECEDENCE_EQUALITY, leftSide, rightSide, "!==");
}
@Override
public InstructionDefinition getIfDefinition() {
return new IfStrictNeIns();
}
@Override
public InstructionDefinition getIfNotDefinition() {
return new IfStrictEqIns();
}
@Override
public GraphTargetItem invert() {

View File

@@ -22,9 +22,12 @@ import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
import com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic.NotIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.comparison.EqualsIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.comparison.StrictEqualsIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.construction.ConstructSuperIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.construction.NewClassIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.IfEqIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.IfFalseIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.IfTrueIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.JumpIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.GetLocal0Ins;
@@ -34,6 +37,7 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.other.FindPropertyStrict
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetLexIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetScopeObjectIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.InitPropertyIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.LabelIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.ReturnValueIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.ReturnVoidIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.DupIns;
@@ -49,6 +53,7 @@ import com.jpexs.decompiler.flash.abc.avm2.model.NullAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.StringAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.UndefinedAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.clauses.TryAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.operations.IfCondition;
import com.jpexs.decompiler.flash.abc.avm2.parser.ParseException;
import com.jpexs.decompiler.flash.abc.types.ABCException;
import com.jpexs.decompiler.flash.abc.types.ClassInfo;
@@ -166,14 +171,25 @@ public class AVM2SourceGenerator implements SourceGenerator {
return list;
}
private List<GraphSourceItem> condition(SourceGeneratorLocalData localData, GraphTargetItem t, int offset){
if(t instanceof IfCondition){
IfCondition ic=(IfCondition)t;
return GraphTargetItem.toSourceMerge(localData, this, ic.getLeftSide(),ic.getRightSide(),ins(ic.getIfDefinition(),offset));
}
return GraphTargetItem.toSourceMerge(localData, this, t, ins(new IfTrueIns(),offset));
}
private List<GraphSourceItem> notCondition(SourceGeneratorLocalData localData, GraphTargetItem t, int offset){
if(t instanceof IfCondition){
IfCondition ic=(IfCondition)t;
return GraphTargetItem.toSourceMerge(localData, this, ic.getLeftSide(),ic.getRightSide(),ins(ic.getIfNotDefinition(),offset));
}
return GraphTargetItem.toSourceMerge(localData, this, t, ins(new IfFalseIns(),offset));
}
private List<GraphSourceItem> generateIf(SourceGeneratorLocalData localData, GraphTargetItem expression, List<GraphTargetItem> onTrueCmds, List<GraphTargetItem> onFalseCmds, boolean ternar) {
List<GraphSourceItem> ret = new ArrayList<>();
if (false) {//expression instanceof Inverted) {
//ret.addAll(((Inverted) expression).invert().toSource(localData, this));
} else {
ret.addAll(expression.toSource(localData, this));
ret.add(ins(new NotIns()));
}
//ret.addAll(notCondition(localData, expression));
List<AVM2Instruction> onTrue = null;
List<AVM2Instruction> onFalse = null;
if (ternar) {
@@ -189,23 +205,23 @@ public class AVM2SourceGenerator implements SourceGenerator {
onFalse = generateToActionList(localData, onFalseCmds);
}
}
byte[] onTrueBytes = insToBytes(onTrue);
int onTrueLen = onTrueBytes.length;
AVM2Instruction ifaif = ins(new IfTrueIns(), 0);
ret.add(ifaif);
ret.addAll(onTrue);
ifaif.operands[0] = (onTrueLen);
AVM2Instruction ajmp = null;
if (onFalse != null) {
if (!((!nonempty(onTrue).isEmpty())
&& ((onTrue.get(onTrue.size() - 1).definition instanceof ContinueJumpIns)
|| ((onTrue.get(onTrue.size() - 1).definition instanceof BreakJumpIns))))) {
ajmp = ins(new JumpIns(), 0);
ret.add(ajmp);
onTrueLen += ajmp.getBytes().length;
onTrue.add(ajmp);
}
ifaif.operands[0] = onTrueLen;
}
byte[] onTrueBytes = insToBytes(onTrue);
int onTrueLen = onTrueBytes.length;
ret.addAll(notCondition(localData, expression, onTrueLen));
ret.addAll(onTrue);
if (onFalse != null) {
byte[] onFalseBytes = insToBytes(onFalse);
int onFalseLen = onFalseBytes.length;
if (ajmp != null) {
@@ -260,70 +276,102 @@ public class AVM2SourceGenerator implements SourceGenerator {
List<AVM2Instruction> whileExpr = new ArrayList<>();
List<GraphTargetItem> ex = new ArrayList<>(item.expression);
if (!ex.isEmpty()) {
GraphTargetItem lastItem = ex.remove(ex.size() - 1);
GraphTargetItem lastItem = null;
if (!ex.isEmpty()) {
lastItem = ex.remove(ex.size() - 1);
while(lastItem instanceof CommaExpressionItem){
CommaExpressionItem cei=(CommaExpressionItem)lastItem;
ex.addAll(cei.commands);
lastItem = ex.remove(ex.size() - 1);
}
whileExpr.addAll(generateToActionList(localData, ex));
whileExpr.addAll(toInsList(lastItem.toSource(localData, this))); //Want result
}
List<AVM2Instruction> whileBody = generateToActionList(localData, item.commands);
whileExpr.add(ins(new NotIns()));
AVM2Instruction whileaif = ins(new IfTrueIns(), 0);
whileExpr.add(whileaif);
AVM2Instruction whileajmp = ins(new JumpIns(), 0);
whileBody.add(whileajmp);
int whileExprLen = insToBytes(whileExpr).length;
int whileBodyLen = insToBytes(whileBody).length;
whileajmp.operands[0] = (-(whileExprLen
+ whileBodyLen));
whileaif.operands[0] = (whileBodyLen);
ret.addAll(whileExpr);
fixLoop(whileBody, whileBodyLen, -whileExprLen, item.loop.id);
List<AVM2Instruction> whileBody = generateToActionList(localData, item.commands);
AVM2Instruction forwardJump = ins(new JumpIns(),0);
ret.add(forwardJump);
whileBody.add(0,ins(new LabelIns()));
ret.addAll(whileBody);
int whileBodyLen = insToBytes(whileBody).length;
forwardJump.operands[0] = whileBodyLen;
whileExpr.addAll(toInsList(condition(localData, lastItem, 0)));
int whileExprLen = insToBytes(whileExpr).length;
whileExpr.get(whileExpr.size()-1).operands[0] = -(whileExprLen+whileBodyLen); //Assuming last is if instruction
ret.addAll(whileExpr);
fixLoop(whileBody, whileBodyLen + whileExprLen, whileBodyLen, item.loop.id);
return ret;
}
@Override
public List<GraphSourceItem> generate(SourceGeneratorLocalData localData, DoWhileItem item) {
List<GraphSourceItem> ret = new ArrayList<>();
List<AVM2Instruction> doExpr = generateToActionList(localData, item.expression);
List<AVM2Instruction> doBody = generateToActionList(localData, item.commands);
List<AVM2Instruction> whileExpr = new ArrayList<>();
int doBodyLen = insToBytes(doBody).length;
int doExprLen = insToBytes(doExpr).length;
ret.addAll(doBody);
ret.addAll(doExpr);
AVM2Instruction doif = ins(new IfTrueIns(), 0);
ret.add(doif);
doif.operands[0] = (-doBodyLen - doExprLen - doif.getBytes().length);
fixLoop(doBody, doBodyLen + doExprLen + doif.getBytes().length, doBodyLen, item.loop.id);
List<GraphTargetItem> ex = new ArrayList<>(item.expression);
GraphTargetItem lastItem = null;
if (!ex.isEmpty()) {
lastItem = ex.remove(ex.size() - 1);
while(lastItem instanceof CommaExpressionItem){
CommaExpressionItem cei=(CommaExpressionItem)lastItem;
ex.addAll(cei.commands);
lastItem = ex.remove(ex.size() - 1);
}
whileExpr.addAll(generateToActionList(localData, ex));
}
List<AVM2Instruction> dowhileBody = generateToActionList(localData, item.commands);
List<AVM2Instruction> labelBody = new ArrayList<>();
labelBody.add(ins(new LabelIns()));
int labelBodyLen = insToBytes(labelBody).length;
AVM2Instruction forwardJump = ins(new JumpIns(),labelBodyLen);
ret.add(forwardJump);
ret.addAll(labelBody);
ret.addAll(dowhileBody);
int dowhileBodyLen = insToBytes(dowhileBody).length;
whileExpr.addAll(toInsList(condition(localData, lastItem, 0)));
int dowhileExprLen = insToBytes(whileExpr).length;
whileExpr.get(whileExpr.size()-1).operands[0] = -(dowhileExprLen+dowhileBodyLen+labelBodyLen); //Assuming last is if instruction
ret.addAll(whileExpr);
fixLoop(dowhileBody, dowhileBodyLen + dowhileExprLen, dowhileBodyLen, item.loop.id);
return ret;
}
@Override
public List<GraphSourceItem> generate(SourceGeneratorLocalData localData, ForItem item) {
List<GraphSourceItem> ret = new ArrayList<>();
List<AVM2Instruction> forExpr = generateToActionList(localData, item.expression);
List<AVM2Instruction> forBody = generateToActionList(localData, item.commands);
List<AVM2Instruction> forFinalCommands = generateToActionList(localData, item.finalCommands);
List<AVM2Instruction> forExpr = new ArrayList<>();
forExpr.add(ins(new NotIns()));
AVM2Instruction foraif = ins(new IfTrueIns(), 0);
forExpr.add(foraif);
AVM2Instruction forajmp = ins(new JumpIns(), 0);
int forajmpLen = forajmp.getBytes().length;
int forExprLen = insToBytes(forExpr).length;
int forBodyLen = insToBytes(forBody).length;
int forFinalLen = insToBytes(forFinalCommands).length;
forajmp.operands[0] = (-(forExprLen
+ forBodyLen + forFinalLen + forajmpLen));
foraif.operands[0] = (forBodyLen + forFinalLen + forajmpLen);
ret.addAll(forExpr);
List<GraphTargetItem> ex = new ArrayList<>();
ex.add(item.expression);
GraphTargetItem lastItem = null;
if (!ex.isEmpty()) {
lastItem = ex.remove(ex.size() - 1);
while(lastItem instanceof CommaExpressionItem){
CommaExpressionItem cei=(CommaExpressionItem)lastItem;
ex.addAll(cei.commands);
lastItem = ex.remove(ex.size() - 1);
}
forExpr.addAll(generateToActionList(localData, ex));
}
List<AVM2Instruction> forBody = generateToActionList(localData, item.commands);
List<AVM2Instruction> forFinalCommands = generateToActionList(localData, item.finalCommands);
ret.addAll(generateToActionList(localData, item.firstCommands));
AVM2Instruction forwardJump = ins(new JumpIns(),0);
ret.add(forwardJump);
forBody.add(0,ins(new LabelIns()));
ret.addAll(forBody);
ret.addAll(forFinalCommands);
ret.add(forajmp);
fixLoop(forBody, forBodyLen + forFinalLen + forajmpLen, forBodyLen, item.loop.id);
int forBodyLen = insToBytes(forBody).length;
int forFinalCLen = insToBytes(forFinalCommands).length;
forwardJump.operands[0] = forBodyLen+forFinalCLen;
forExpr.addAll(toInsList(condition(localData, lastItem, 0)));
int forExprLen = insToBytes(forExpr).length;
forExpr.get(forExpr.size()-1).operands[0] = -(forExprLen+forBodyLen+forFinalCLen); //Assuming last is if instruction
ret.addAll(forExpr);
fixLoop(forBody, forBodyLen + forFinalCLen + forExprLen, forBodyLen, item.loop.id);
return ret;
}
private long uniqLast = 0;

View File

@@ -1456,10 +1456,9 @@ public class ActionScriptParser {
}
as.setAssignedValue(assigned);
if (expr instanceof NameAVM2Item) {
((NameAVM2Item) expr).setDefinition(false);
ret = as;
((NameAVM2Item) expr).setDefinition(false);
}
ret = expr;
ret = as;
break;
case INCREMENT: //postincrement
if (!(expr instanceof AssignableAVM2Item)) {

View File

@@ -23,16 +23,25 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic.DecrementIIns
import com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic.DecrementIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic.IncrementIIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic.IncrementIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.IncLocalIIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.IncLocalIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.FindPropertyStrictIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetPropertyIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.SetPropertyIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.DupIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PopIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushByteIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushNanIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushNullIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.types.CoerceAIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.types.CoerceIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.types.CoerceSIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.types.ConvertDIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.types.ConvertIIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.types.ConvertSIns;
import com.jpexs.decompiler.flash.abc.avm2.model.IntegerValueAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.NanAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.NullAVM2Item;
import com.jpexs.decompiler.flash.abc.types.Multiname;
import com.jpexs.decompiler.flash.abc.types.NamespaceSet;
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
@@ -158,9 +167,23 @@ public class NameAVM2Item extends AssignableAVM2Item {
return abc.constants.getNamespaceSetId(new NamespaceSet(nssa), true);
}
private GraphTargetItem getDefaultValue(String type){
switch(type){
case "int":
return new IntegerValueAVM2Item(null, 0L);
case "Number":
return new NanAVM2Item(null);
default:
return new NullAVM2Item(null);
}
}
private AVM2Instruction generateCoerce(SourceGenerator generator, String type) {
AVM2Instruction ins;
switch (type) {
case "int":
ins = ins(new ConvertIIns());
break;
case "*":
ins = ins(new CoerceAIns());
break;
@@ -180,7 +203,7 @@ public class NameAVM2Item extends AssignableAVM2Item {
throw new RuntimeException("No register set for " + variableName);
}
if (definition && assignedValue == null) {
return new ArrayList<>();
assignedValue = getDefaultValue(type==null?"*":type.toString());
}
AVM2SourceGenerator g = (AVM2SourceGenerator) generator;
Reference<Integer> ns_temp = new Reference<>(-1);
@@ -245,7 +268,8 @@ public class NameAVM2Item extends AssignableAVM2Item {
}
if (assignedValue != null) {
return toSourceMerge(localData, generator, assignedValue, (!("int".equals("" + assignedValue.returnType()) && "int".equals("" + type))) ? generateCoerce(generator, "" + type) : null, needsReturn
List<String> basicTypes = Arrays.asList("int","Number");
return toSourceMerge(localData, generator, assignedValue, !((""+assignedValue.returnType()).equals(""+type)&&(basicTypes.contains(""+type))) ? generateCoerce(generator, "" + type) : null, needsReturn
? ins(new DupIns()) : null, generateSetLoc(regNumber));
} else {
return toSourceMerge(localData, generator, generateGetLoc(regNumber),
@@ -387,6 +411,10 @@ public class NameAVM2Item extends AssignableAVM2Item {
);
}
if(!needsReturn){
return toSourceMerge(localData, generator,
ins(isInteger?new IncLocalIIns():new IncLocalIns(),regNumber));
}
return toSourceMerge(localData, generator,
//Start get original
generateGetLoc(regNumber),

View File

@@ -9,4 +9,4 @@ TODO List for AS3 parser/compiler:
- with
- delete property
- default xml namespace
- custom namespace modifiers
- custom namespace modifiers