From b8a63c8d5a1b7afe65228e16695cb2025ea6567b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=F8=EDk?= Date: Sat, 5 Apr 2014 12:31:11 +0200 Subject: [PATCH] AS3 parser: Fixed If, While, DoWhile,For --- .../flash/abc/avm2/model/NanAVM2Item.java | 2 +- .../abc/avm2/model/operations/EqAVM2Item.java | 18 +- .../abc/avm2/model/operations/GeAVM2Item.java | 18 +- .../abc/avm2/model/operations/GtAVM2Item.java | 18 +- .../avm2/model/operations/IfCondition.java | 30 ++++ .../abc/avm2/model/operations/LeAVM2Item.java | 18 +- .../abc/avm2/model/operations/LtAVM2Item.java | 18 +- .../avm2/model/operations/NeqAVM2Item.java | 16 +- .../model/operations/StrictEqAVM2Item.java | 18 +- .../model/operations/StrictNeqAVM2Item.java | 18 +- .../parser/script/AVM2SourceGenerator.java | 170 +++++++++++------- .../parser/script/ActionScriptParser.java | 5 +- .../abc/avm2/parser/script/NameAVM2Item.java | 32 +++- .../flash/abc/avm2/parser/script/todo.txt | 2 +- 14 files changed, 307 insertions(+), 76 deletions(-) create mode 100644 trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/IfCondition.java diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/NanAVM2Item.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/NanAVM2Item.java index 73272f176..97366c180 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/NanAVM2Item.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/NanAVM2Item.java @@ -47,7 +47,7 @@ public class NanAVM2Item extends AVM2Item { @Override public GraphTargetItem returnType() { - return TypeItem.UNBOUNDED; + return new TypeItem("Number"); } @Override diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/EqAVM2Item.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/EqAVM2Item.java index ebff0ce80..2ae2b0f91 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/EqAVM2Item.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/EqAVM2Item.java @@ -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()); diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/GeAVM2Item.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/GeAVM2Item.java index 70e7594cc..cd2d77002 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/GeAVM2Item.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/GeAVM2Item.java @@ -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); diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/GtAVM2Item.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/GtAVM2Item.java index f71f49b9e..ea6ea1901 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/GtAVM2Item.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/GtAVM2Item.java @@ -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() { diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/IfCondition.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/IfCondition.java new file mode 100644 index 000000000..9ef029308 --- /dev/null +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/IfCondition.java @@ -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 . + */ + +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(); +} diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/LeAVM2Item.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/LeAVM2Item.java index 1385bc3be..7fd8f693a 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/LeAVM2Item.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/LeAVM2Item.java @@ -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); diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/LtAVM2Item.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/LtAVM2Item.java index c1b979a0b..8ebbbe11e 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/LtAVM2Item.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/LtAVM2Item.java @@ -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); diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/NeqAVM2Item.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/NeqAVM2Item.java index e2eeda19d..06ca4d890 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/NeqAVM2Item.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/NeqAVM2Item.java @@ -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() { diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/StrictEqAVM2Item.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/StrictEqAVM2Item.java index d00f9fa50..cc884b423 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/StrictEqAVM2Item.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/StrictEqAVM2Item.java @@ -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(); diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/StrictNeqAVM2Item.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/StrictNeqAVM2Item.java index aa0b56450..783a7a6ae 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/StrictNeqAVM2Item.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/StrictNeqAVM2Item.java @@ -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() { diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AVM2SourceGenerator.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AVM2SourceGenerator.java index c3be4b07d..637858059 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AVM2SourceGenerator.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AVM2SourceGenerator.java @@ -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 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 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 generateIf(SourceGeneratorLocalData localData, GraphTargetItem expression, List onTrueCmds, List onFalseCmds, boolean ternar) { List 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 onTrue = null; List 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 whileExpr = new ArrayList<>(); List 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 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 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 generate(SourceGeneratorLocalData localData, DoWhileItem item) { List ret = new ArrayList<>(); - List doExpr = generateToActionList(localData, item.expression); - List doBody = generateToActionList(localData, item.commands); + List 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 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 dowhileBody = generateToActionList(localData, item.commands); + List 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 generate(SourceGeneratorLocalData localData, ForItem item) { List ret = new ArrayList<>(); - List forExpr = generateToActionList(localData, item.expression); - List forBody = generateToActionList(localData, item.commands); - List forFinalCommands = generateToActionList(localData, item.finalCommands); + List 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 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 forBody = generateToActionList(localData, item.commands); + List 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; diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScriptParser.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScriptParser.java index cd7ded474..bd3f5d49b 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScriptParser.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScriptParser.java @@ -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)) { diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/NameAVM2Item.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/NameAVM2Item.java index b9d784895..ff00475e1 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/NameAVM2Item.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/NameAVM2Item.java @@ -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 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 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), diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/todo.txt b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/todo.txt index 5bd2fa6f3..2b7664e0b 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/todo.txt +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/todo.txt @@ -9,4 +9,4 @@ TODO List for AS3 parser/compiler: - with - delete property - default xml namespace -- custom namespace modifiers \ No newline at end of file +- custom namespace modifiers