diff --git a/CHANGELOG.md b/CHANGELOG.md index 6899bb749..8f6c64132 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ All notable changes to this project will be documented in this file. ## [Unreleased] ### Added - Updated Flash player to SWF version map +- Harman AIR 51 float support compatibility ### Fixed - [#2266] StartSound/2 and VideoFrame tags, classNames not taken as dependencies (needed chars) diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ABC.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ABC.java index 622994b91..e91c0c713 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ABC.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ABC.java @@ -784,6 +784,14 @@ public class ABC implements Openable { public boolean hasFloatSupport() { return minVersionCheck(47, 16); } + + /** + * Checks whether the ABC has float4 support + * @return Whether the ABC has float4 support + */ + public boolean hasFloat4Support() { + return false; + } /** * Sets float support. @@ -927,6 +935,8 @@ public class ABC implements Openable { } ais.endDumpLevel(); } + } + if (hasFloat4Support()) { // constant float4 int constant_float4_pool_count = ais.readU30("float4_count"); if (constant_float4_pool_count > 1) { @@ -1125,6 +1135,8 @@ public class ABC implements Openable { for (int i = 1; i < constants.getFloatCount(); i++) { aos.writeFloat(constants.getFloat(i)); } + } + if (hasFloat4Support()) { aos.writeU30(constants.getFloat4Count()); for (int i = 1; i < constants.getFloat4Count(); i++) { aos.writeFloat4(constants.getFloat4(i)); @@ -2400,7 +2412,7 @@ public class ABC implements Openable { } break; case ValueKind.CONSTANT_Float4: - if (hasFloatSupport()) { + if (hasFloat4Support()) { valueMergeMap = mergeFloat4Map; } break; @@ -2675,7 +2687,7 @@ public class ABC implements Openable { } break; case ValueKind.CONSTANT_Float4: - if (hasFloatSupport()) { + if (hasFloat4Support()) { valueMergeMap = mergeFloat4Map; } break; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ABCInputStream.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ABCInputStream.java index c86a9a41d..d450acf9e 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ABCInputStream.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ABCInputStream.java @@ -700,7 +700,7 @@ public class ABCInputStream implements AutoCloseable { */ public Float readFloat(String name) throws IOException { newDumpLevel(name, "Float"); - int intBits = (readInternal()) + (readInternal() << 8); + int intBits = (readInternal()) + (readInternal() << 8) + (readInternal() << 16) + (readInternal() << 24); float ret = Float.intBitsToFloat(intBits); endDumpLevel(ret); return ret; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java index 26d4448d2..36c07e1d9 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java @@ -580,7 +580,7 @@ public class AVM2Code implements Cloneable { /*0x20*/ new PushNullIns(), /*0x21*/ new PushUndefinedIns(), /*0x22*/ new PushFloatIns(), //major 47+ - /*0x22*/ new PushConstantIns(), //before major 47 + /*0x22*/ //new PushConstantIns(), //before major 47 /*0x23*/ new NextValueIns(), /*0x24*/ new PushByteIns(), /*0x25*/ new PushShortIns(), diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/CoerceAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/CoerceAVM2Item.java index 1879b815a..686ff5c01 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/CoerceAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/CoerceAVM2Item.java @@ -87,6 +87,12 @@ public class CoerceAVM2Item extends AVM2Item { && !valueReturnType.equals(TypeItem.UINT) && !valueReturnType.equals(TypeItem.UNBOUNDED); break; + case "float": + displayCoerce = !valueReturnType.equals(TypeItem.INT) + && !valueReturnType.equals(new TypeItem("float")) + && !valueReturnType.equals(TypeItem.UINT) + && !valueReturnType.equals(TypeItem.UNBOUNDED); + break; case "int": displayCoerce = !valueReturnType.equals(TypeItem.INT) && !valueReturnType.equals(TypeItem.UNBOUNDED); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/ConvertAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/ConvertAVM2Item.java index bb37d2a0f..3bab0fab2 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/ConvertAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/ConvertAVM2Item.java @@ -75,6 +75,12 @@ public class ConvertAVM2Item extends AVM2Item { && !valueReturnType.equals(TypeItem.UINT) && !valueReturnType.equals(TypeItem.UNBOUNDED); break; + case "float": + displayConvert = !valueReturnType.equals(TypeItem.INT) + && !valueReturnType.equals(new TypeItem("float")) + && !valueReturnType.equals(TypeItem.UINT) + && !valueReturnType.equals(TypeItem.UNBOUNDED); + break; case "int": displayConvert = !valueReturnType.equals(TypeItem.INT) && !valueReturnType.equals(TypeItem.UNBOUNDED); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/FloatValueAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/FloatValueAVM2Item.java index 8682d8ac2..ed17f49a2 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/FloatValueAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/FloatValueAVM2Item.java @@ -84,7 +84,7 @@ public class FloatValueAVM2Item extends NumberValueAVM2Item { @Override public GraphTargetItem returnType() { - return TypeItem.NUMBER; + return new TypeItem("float"); } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3Parser.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3Parser.java index bb33e2ae4..4698e2aff 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3Parser.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3Parser.java @@ -2489,7 +2489,7 @@ public class ActionScript3Parser { allowMemberOrCall = true; break; case FLOAT4: - if (!abc.hasFloatSupport()) { + if (!abc.hasFloat4Support()) { //parse again as method call lexer.yypushbackstr(lexer.yytext().substring("float4".length())); lexer.pushback(new ParsedSymbol(SymbolGroup.IDENTIFIER, SymbolType.IDENTIFIER, "float4")); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/usages/simple/ABCCleaner.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/usages/simple/ABCCleaner.java index 01d4aaac3..48283bd99 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/usages/simple/ABCCleaner.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/usages/simple/ABCCleaner.java @@ -276,7 +276,8 @@ public class ABCCleaner { } newCpool.addFloat(abc.constants.getFloat(i)); } - + } + if (abc.hasFloat4Support()) { for (int i = 1; i < abc.constants.getFloat4Count(); i++) { if (notReferencedIndices.get(ABCSimpleUsageDetector.ItemKind.FLOAT4).contains(i)) { continue; diff --git a/libsrc/ffdec_lib/testdata/float/bin/float.air_harman.swf b/libsrc/ffdec_lib/testdata/float/bin/float.air_harman.swf new file mode 100644 index 000000000..962a4d210 Binary files /dev/null and b/libsrc/ffdec_lib/testdata/float/bin/float.air_harman.swf differ diff --git a/libsrc/ffdec_lib/testdata/float/build_air_harman_debug.bat b/libsrc/ffdec_lib/testdata/float/build_air_harman_debug.bat new file mode 100644 index 000000000..6786cbb36 --- /dev/null +++ b/libsrc/ffdec_lib/testdata/float/build_air_harman_debug.bat @@ -0,0 +1,10 @@ +@echo off +set COMPILERKIND=air_harman +set SWFNAME=float +rem call c:\air_harman\bin\mxmlc.bat -debug=true -output bin/%SWFNAME%.%COMPILERKIND%.swf src/Main.as 1> buildlog.%COMPILERKIND%.txt 2>&1 +set batdir=%~dp0 +echo %batdir%bin\%SWFNAME%.%COMPILERKIND%.xml +cd c:\air_harman\bin +adl.exe -nodebug %batdir%bin\%SWFNAME%.%COMPILERKIND%.xml +rem -cmd +pause diff --git a/libsrc/ffdec_lib/testdata/float/src/Main.as b/libsrc/ffdec_lib/testdata/float/src/Main.as new file mode 100644 index 000000000..66b60ef13 --- /dev/null +++ b/libsrc/ffdec_lib/testdata/float/src/Main.as @@ -0,0 +1,24 @@ +package +{ + import flash.display.Sprite; + import flash.events.Event; + + public class Main extends Sprite + { + + public function Main() + { + if (stage) init(); + else addEventListener(Event.ADDED_TO_STAGE, init); + } + + private function init(e:Event = null):void + { + removeEventListener(Event.ADDED_TO_STAGE, init); + + var a:float = 10f; + } + + } + +} diff --git a/src/com/jpexs/decompiler/flash/gui/abc/ABCExplorerDialog.java b/src/com/jpexs/decompiler/flash/gui/abc/ABCExplorerDialog.java index 2cb45d24b..8b7c30ca5 100644 --- a/src/com/jpexs/decompiler/flash/gui/abc/ABCExplorerDialog.java +++ b/src/com/jpexs/decompiler/flash/gui/abc/ABCExplorerDialog.java @@ -404,6 +404,8 @@ public class ABCExplorerDialog extends AppDialog { } if (abc.hasFloatSupport()) { cpTabbedPane.addTab("fl (" + Math.max(0, abc.constants.getFloatCount() - 1) + ")", View.getIcon(TreeType.CONSTANT_FLOAT.getIcon().getFile()), makeTreePanel(abc, TreeType.CONSTANT_FLOAT)); + } + if (abc.hasFloat4Support()) { cpTabbedPane.addTab("fl4 (" + Math.max(0, abc.constants.getFloat4Count() - 1) + ")", View.getIcon(TreeType.CONSTANT_FLOAT_4.getIcon().getFile()), makeTreePanel(abc, TreeType.CONSTANT_FLOAT_4)); } cpTabbedPane.addTab("str (" + Math.max(0, abc.constants.getStringCount() - 1) + ")", View.getIcon(TreeType.CONSTANT_STRING.getIcon().getFile()), makeTreePanel(abc, TreeType.CONSTANT_STRING)); @@ -424,7 +426,8 @@ public class ABCExplorerDialog extends AppDialog { + Math.max(0, abc.constants.getNamespaceSetCount() - 1) + Math.max(0, abc.constants.getMultinameCount() - 1) + (abc.hasDecimalSupport() ? Math.max(0, abc.constants.getDecimalCount() - 1) : 0) - + (abc.hasFloatSupport() ? (Math.max(0, abc.constants.getFloatCount() - 1) + Math.max(0, abc.constants.getFloat4Count() - 1)) : 0); + + (abc.hasFloatSupport() ? Math.max(0, abc.constants.getFloatCount() - 1) : 0) + + (abc.hasFloat4Support() ? Math.max(0, abc.constants.getFloat4Count() - 1) : 0); mainTabbedPane.addTab("cp (" + cpCount + ")", View.getIcon("abcconstantpool16"), cpPanel); mainTabbedPane.addTab("mi (" + abc.method_info.size() + ")", View.getIcon(TreeType.METHOD_INFO.getIcon().getFile()), makeTreePanel(abc, TreeType.METHOD_INFO)); mainTabbedPane.addTab("md (" + abc.metadata_info.size() + ")", View.getIcon(TreeType.METADATA_INFO.getIcon().getFile()), makeTreePanel(abc, TreeType.METADATA_INFO)); @@ -558,7 +561,10 @@ public class ABCExplorerDialog extends AppDialog { stringOffset = 1; } if (getSelectedAbc().hasFloatSupport()) { - stringOffset = 2; + stringOffset++; + } + if (getSelectedAbc().hasFloat4Support()) { + stringOffset++; } switch (selectedType) { case CONSTANT_INT: @@ -588,7 +594,7 @@ public class ABCExplorerDialog extends AppDialog { cpTabbedPane.setSelectedIndex(3); break; case CONSTANT_FLOAT_4: - if (!getSelectedAbc().hasFloatSupport()) { + if (!getSelectedAbc().hasFloat4Support()) { return; } mainTabbedPane.setSelectedIndex(0);