From 5ea2cc42a15774b41b0d724b41cc84eceffb5b4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=C5=99=C3=ADk?= Date: Thu, 25 Feb 2021 19:39:39 +0100 Subject: [PATCH] Fixed: #1101 AS3 direct editation - handling imported vars --- CHANGELOG.md | 1 + .../abc/avm2/model/FindPropertyAVM2Item.java | 16 ++- .../parser/script/TypeAssignableItem.java | 119 ++++++++++++++++++ .../parser/script/UnresolvedAVM2Item.java | 12 +- .../importers/FFDecAs3ScriptReplacer.java | 3 +- .../as3_new/src/tests_classes/myvar.as | 5 + 6 files changed, 152 insertions(+), 4 deletions(-) create mode 100644 libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/TypeAssignableItem.java create mode 100644 libsrc/ffdec_lib/testdata/as3_new/src/tests_classes/myvar.as diff --git a/CHANGELOG.md b/CHANGELOG.md index 5336a3f5e..cc13ed649 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ All notable changes to this project will be documented in this file. - #1615 Turning off Checking for modifications disables SWF loading - #1100, #1123, #1516 AS1/2/3 direct editation - comma operator - #1618 Export to PDF selectable text escaping and text size +- #1101 AS3 direct editation - handling imported vars ### Changed - #1616 Close SWF menuitem is last in the context menu diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/FindPropertyAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/FindPropertyAVM2Item.java index 583803b71..1dd929aa4 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/FindPropertyAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/FindPropertyAVM2Item.java @@ -12,15 +12,23 @@ * 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.abc.avm2.model; +import com.jpexs.decompiler.flash.SourceGeneratorLocalData; +import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instructions; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other.FindPropertyIns; +import com.jpexs.decompiler.flash.abc.avm2.parser.script.AVM2SourceGenerator; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; +import com.jpexs.decompiler.graph.CompilationException; import com.jpexs.decompiler.graph.GraphSourceItem; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.GraphTargetVisitorInterface; +import com.jpexs.decompiler.graph.SourceGenerator; import com.jpexs.decompiler.graph.TypeItem; import com.jpexs.decompiler.graph.model.LocalData; +import java.util.List; /** * @@ -57,4 +65,10 @@ public class FindPropertyAVM2Item extends AVM2Item { public boolean hasReturnValue() { return true; } + + @Override + public List toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException { + return toSourceMerge(localData, generator, ins(AVM2Instructions.FindProperty, ((AVM2SourceGenerator) generator).typeName(localData, propertyName))); + } + } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/TypeAssignableItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/TypeAssignableItem.java new file mode 100644 index 000000000..9932176e3 --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/TypeAssignableItem.java @@ -0,0 +1,119 @@ +package com.jpexs.decompiler.flash.abc.avm2.parser.script; + +import com.jpexs.decompiler.flash.SourceGeneratorLocalData; +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; +import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instructions; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other.FindPropertyStrictIns; +import com.jpexs.decompiler.flash.abc.avm2.model.AVM2Item; +import static com.jpexs.decompiler.flash.abc.avm2.model.AVM2Item.ins; +import com.jpexs.decompiler.flash.abc.avm2.model.FindPropertyAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.clauses.AssignmentAVM2Item; +import static com.jpexs.decompiler.flash.abc.avm2.parser.script.AssignableAVM2Item.dupSetTemp; +import static com.jpexs.decompiler.flash.abc.avm2.parser.script.AssignableAVM2Item.getTemp; +import static com.jpexs.decompiler.flash.abc.avm2.parser.script.AssignableAVM2Item.killTemp; +import static com.jpexs.decompiler.flash.abc.avm2.parser.script.AssignableAVM2Item.setTemp; +import com.jpexs.decompiler.flash.abc.types.ValueKind; +import com.jpexs.decompiler.flash.helpers.GraphTextWriter; +import com.jpexs.decompiler.graph.CompilationException; +import com.jpexs.decompiler.graph.GraphSourceItem; +import com.jpexs.decompiler.graph.GraphTargetItem; +import static com.jpexs.decompiler.graph.GraphTargetItem.toSourceMerge; +import com.jpexs.decompiler.graph.SourceGenerator; +import com.jpexs.decompiler.graph.TypeItem; +import com.jpexs.decompiler.graph.model.LocalData; +import com.jpexs.helpers.Reference; +import java.util.Arrays; +import java.util.List; + +/** + * + * @author JPEXS + */ +public class TypeAssignableItem extends AssignableAVM2Item { + + private final TypeItem type; + + public TypeAssignableItem(TypeItem type) { + this.type = type; + } + + @Override + public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException { + return writer; + } + + @Override + public boolean hasReturnValue() { + return true; + } + + @Override + public GraphTargetItem returnType() { + return TypeItem.UNBOUNDED; + } + + @Override + public AssignableAVM2Item copy() { + return new TypeAssignableItem(type); + } + + public List toSource(SourceGeneratorLocalData localData, SourceGenerator generator, boolean needsReturn) throws CompilationException { + int propertyId = ((AVM2SourceGenerator) generator).typeName(localData, type); + Object obj = new FindPropertyAVM2Item(null, null, type); + Reference ret_temp = new Reference<>(-1); + if (assignedValue != null) { + GraphTargetItem coerced = assignedValue; + return toSourceMerge(localData, generator, obj, coerced, + needsReturn ? dupSetTemp(localData, generator, ret_temp) : null, + ins(AVM2Instructions.SetProperty, propertyId), + needsReturn ? getTemp(localData, generator, ret_temp) : null, + killTemp(localData, generator, Arrays.asList(ret_temp))); + } else { + if (obj instanceof AVM2Instruction && (((AVM2Instruction) obj).definition instanceof FindPropertyStrictIns)) { + return toSourceMerge(localData, generator, ins(AVM2Instructions.GetLex, propertyId), + needsReturn ? null : ins(AVM2Instructions.Pop) + ); + } + return toSourceMerge(localData, generator, obj, ins(AVM2Instructions.GetProperty, propertyId), + needsReturn ? null : ins(AVM2Instructions.Pop) + ); + } + } + + @Override + public List toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException { + return toSource(localData, generator, true); + } + + @Override + public List toSourceIgnoreReturnValue(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException { + return toSource(localData, generator, false); + } + + @Override + public List toSourceChange(SourceGeneratorLocalData localData, SourceGenerator generator, boolean post, boolean decrement, boolean needsReturn) throws CompilationException { + + int propertyId = ((AVM2SourceGenerator) generator).typeName(localData, type); + Object obj = new FindPropertyAVM2Item(null, null, type); + + Reference ret_temp = new Reference<>(-1); + Reference obj_temp = new Reference<>(-1); + + boolean isInteger = false; + + List ret = toSourceMerge(localData, generator, obj, dupSetTemp(localData, generator, obj_temp), + ins(AVM2Instructions.GetProperty, propertyId), + (!isInteger && post) ? ins(AVM2Instructions.ConvertD) : null, + (!post) ? (decrement ? ins(isInteger ? AVM2Instructions.DecrementI : AVM2Instructions.Decrement) : ins(isInteger ? AVM2Instructions.IncrementI : AVM2Instructions.Increment)) : null, + needsReturn ? ins(AVM2Instructions.Dup) : null, + (post) ? (decrement ? ins(isInteger ? AVM2Instructions.DecrementI : AVM2Instructions.Decrement) : ins(isInteger ? AVM2Instructions.IncrementI : AVM2Instructions.Increment)) : null, + setTemp(localData, generator, ret_temp), + getTemp(localData, generator, obj_temp), + getTemp(localData, generator, ret_temp), + ins(AVM2Instructions.SetProperty, propertyId), + killTemp(localData, generator, Arrays.asList(ret_temp, obj_temp))); + return ret; + } + +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/UnresolvedAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/UnresolvedAVM2Item.java index ce6678e3a..52153d1e9 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/UnresolvedAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/UnresolvedAVM2Item.java @@ -22,6 +22,7 @@ import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instructions; import com.jpexs.decompiler.flash.abc.avm2.model.BooleanAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.FindPropertyAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.InitVectorAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.IntegerValueAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.NanAVM2Item; @@ -327,9 +328,16 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item { ((PropertyAVM2Item) resolved).assignedValue = assignedValue; } } - if (name.size() == 1 && assignedValue != null) { - throw new CompilationException("Cannot assign type", line); + + if (name.size() == 1) { + resolved = new TypeAssignableItem(ret); + //TODO: check whether it is really an assignable and not a Class + if (assignedValue != null) { + ((TypeAssignableItem) resolved).assignedValue = assignedValue; + //throw new CompilationException("Cannot assign type", line); + } } + return resolvedRoot = ret; } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/FFDecAs3ScriptReplacer.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/FFDecAs3ScriptReplacer.java index 08a6113ff..3ad0ce0ad 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/FFDecAs3ScriptReplacer.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/FFDecAs3ScriptReplacer.java @@ -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.importers; import com.jpexs.decompiler.flash.SWF; diff --git a/libsrc/ffdec_lib/testdata/as3_new/src/tests_classes/myvar.as b/libsrc/ffdec_lib/testdata/as3_new/src/tests_classes/myvar.as new file mode 100644 index 000000000..36c1763a6 --- /dev/null +++ b/libsrc/ffdec_lib/testdata/as3_new/src/tests_classes/myvar.as @@ -0,0 +1,5 @@ +package tests_classes +{ + public var myvar:int = 10; + +} \ No newline at end of file