diff --git a/libsrc/ffdec_lib/lexers/actionscript_pcode.flex b/libsrc/ffdec_lib/lexers/actionscript_pcode.flex index 27119710d..6db5ef65f 100644 --- a/libsrc/ffdec_lib/lexers/actionscript_pcode.flex +++ b/libsrc/ffdec_lib/lexers/actionscript_pcode.flex @@ -1,190 +1,190 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -/* Flash assembler language lexer specification */ -package com.jpexs.decompiler.flash.action.parser.pcode; - -import com.jpexs.decompiler.flash.action.parser.ActionParseException; -import com.jpexs.decompiler.flash.action.swf4.ConstantIndex; -import com.jpexs.decompiler.flash.action.swf4.RegisterNumber; -import com.jpexs.decompiler.flash.ecma.Null; -import com.jpexs.decompiler.flash.ecma.Undefined; - -%% - -%public -%class FlasmLexer -%final -%unicode -%char -%line -%column -%type ASMParsedSymbol -%throws ActionParseException - -%{ - - StringBuffer string = new StringBuffer(); - - /** - * Create an empty lexer, yyrset will be called later to reset and assign - * the reader - */ - public FlasmLexer() { - - } - - public int yychar() { - return yychar; - } - - public int yyline() { - return yyline + 1; - } - -%} - -/* main character classes */ -LineTerminator = \r|\n|\r\n - -InputCharacter = [^\r\n] -Comment = ";" {InputCharacter}* - -WhiteSpace = [ \t\f]+ - - -/* identifiers */ - -Identifier = [:jletter:][:jletterdigit:]* - -InstructionName = [a-zA-Z][a-zA-Z0-9_]* - -Label = {Identifier}: - -StartOfBlock = "{" - -EndOfBlock = "}" - -True = "true" -False = "false" -False = "false" -Null = "null" -Undefined = "undefined" - -Infinity = -? "Infinity" - -/* integer literals */ -PositiveNumberLiteral = 0 | [1-9][0-9]* -NegativeNumberLiteral = - {PositiveNumberLiteral} - -NumberLiteral = {PositiveNumberLiteral}|{NegativeNumberLiteral} - -/* floating point literals */ -FloatLiteral = "NaN" | {Infinity} | -?(({FLit1}|{FLit2}|{FLit3}) {Exponent}?) - -FLit1 = [0-9]+ \. [0-9]* -FLit2 = \. [0-9]+ -FLit3 = [0-9]+ -Exponent = [eE] [+-]? [0-9]+ - -HexDigit = [0-9a-fA-F] - -/* string and character literals */ -StringCharacter = [^\r\n\"\\] - -Register= register{PositiveNumberLiteral} -Constant= constant{PositiveNumberLiteral} - -%state STRING,PARAMETERS - -%% - - { - - - /* whitespace */ - {WhiteSpace} { } - - {Label} { - String s=yytext(); - return new ASMParsedSymbol(ASMParsedSymbol.TYPE_LABEL, s.substring(0, s.length() - 1)); - } - - /* identifiers */ - {InstructionName} { yybegin(PARAMETERS); - return new ASMParsedSymbol(ASMParsedSymbol.TYPE_INSTRUCTION_NAME, yytext()); - } - {EndOfBlock} { return new ASMParsedSymbol(ASMParsedSymbol.TYPE_BLOCK_END); } -} - - { - /* string literal */ - \" { - yybegin(STRING); - string.setLength(0); - } - - /* numeric literals */ - - {NumberLiteral} { return new ASMParsedSymbol(ASMParsedSymbol.TYPE_INTEGER, Long.parseLong((yytext()))); } - {FloatLiteral} { return new ASMParsedSymbol(ASMParsedSymbol.TYPE_FLOAT, Double.parseDouble((yytext()))); } - {LineTerminator} {yybegin(YYINITIAL); return new ASMParsedSymbol(ASMParsedSymbol.TYPE_EOL); } - {Comment} {return new ASMParsedSymbol(ASMParsedSymbol.TYPE_COMMENT, yytext().substring(1));} - {StartOfBlock} { yybegin(YYINITIAL); return new ASMParsedSymbol(ASMParsedSymbol.TYPE_BLOCK_START); } - {True} {return new ASMParsedSymbol(ASMParsedSymbol.TYPE_BOOLEAN,Boolean.TRUE);} - {False} {return new ASMParsedSymbol(ASMParsedSymbol.TYPE_BOOLEAN,Boolean.FALSE);} - {Null} {return new ASMParsedSymbol(ASMParsedSymbol.TYPE_NULL, new Null());} - {Undefined} {return new ASMParsedSymbol(ASMParsedSymbol.TYPE_UNDEFINED, new Undefined());} - - {Register} { return new ASMParsedSymbol(ASMParsedSymbol.TYPE_REGISTER, new RegisterNumber(Integer.parseInt(yytext().substring(8)))); } - {Constant} { return new ASMParsedSymbol(ASMParsedSymbol.TYPE_CONSTANT, new ConstantIndex(Integer.parseInt(yytext().substring(8)))); } - - {Identifier} { return new ASMParsedSymbol(ASMParsedSymbol.TYPE_IDENTIFIER, yytext()); } - -} - - { - \" { - yybegin(PARAMETERS); - // length also includes the trailing quote - return new ASMParsedSymbol(ASMParsedSymbol.TYPE_STRING, string.toString()); - } - - {StringCharacter}+ { string.append(yytext()); } - - /* escape sequences */ - "\\b" { string.append('\b'); } - "\\t" { string.append('\t'); } - "\\n" { string.append('\n'); } - "\\f" { string.append('\f'); } - "\\r" { string.append('\r'); } - "\\\"" { string.append('\"'); } - "\\'" { string.append('\''); } - "\\\\" { string.append('\\'); } - \\x{HexDigit}{2} { char val = (char) Integer.parseInt(yytext().substring(2), 16); - string.append(val); } - \\u{HexDigit}{4} { char val = (char) Integer.parseInt(yytext().substring(2), 16); - string.append(val); } - - /* error cases */ - \\. { throw new ActionParseException("Illegal escape sequence \"" + yytext() + "\"", yyline + 1); } - {LineTerminator} { throw new ActionParseException("Unterminated string at end of line", yyline + 1); } - -} - -/* error fallback */ -[^] { } -<> { return new ASMParsedSymbol(ASMParsedSymbol.TYPE_EOF); } +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +/* Flash assembler language lexer specification */ +package com.jpexs.decompiler.flash.action.parser.pcode; + +import com.jpexs.decompiler.flash.action.parser.ActionParseException; +import com.jpexs.decompiler.flash.action.swf4.ConstantIndex; +import com.jpexs.decompiler.flash.action.swf4.RegisterNumber; +import com.jpexs.decompiler.flash.ecma.Null; +import com.jpexs.decompiler.flash.ecma.Undefined; + +%% + +%public +%class FlasmLexer +%final +%unicode +%char +%line +%column +%type ASMParsedSymbol +%throws ActionParseException + +%{ + + StringBuffer string = new StringBuffer(); + + /** + * Create an empty lexer, yyrset will be called later to reset and assign + * the reader + */ + public FlasmLexer() { + + } + + public int yychar() { + return yychar; + } + + public int yyline() { + return yyline + 1; + } + +%} + +/* main character classes */ +LineTerminator = \r|\n|\r\n + +InputCharacter = [^\r\n] +Comment = ";" {InputCharacter}* + +WhiteSpace = [ \t\f]+ + + +/* identifiers */ + +Identifier = [:jletter:][:jletterdigit:]* + +InstructionName = [a-zA-Z][a-zA-Z0-9_]* + +Label = {Identifier}: + +StartOfBlock = "{" + +EndOfBlock = "}" + +True = "true" +False = "false" +False = "false" +Null = "null" +Undefined = "undefined" + +Infinity = -? "Infinity" + +/* integer literals */ +PositiveNumberLiteral = 0 | [1-9][0-9]* +NegativeNumberLiteral = - {PositiveNumberLiteral} + +NumberLiteral = {PositiveNumberLiteral}|{NegativeNumberLiteral} + +/* floating point literals */ +FloatLiteral = "NaN" | {Infinity} | -?(({FLit1}|{FLit2}|{FLit3}) {Exponent}?) + +FLit1 = [0-9]+ \. [0-9]* +FLit2 = \. [0-9]+ +FLit3 = [0-9]+ +Exponent = [eE] [+-]? [0-9]+ + +HexDigit = [0-9a-fA-F] + +/* string and character literals */ +StringCharacter = [^\r\n\"\\] + +Register= register{PositiveNumberLiteral} +Constant= constant{PositiveNumberLiteral} + +%state STRING,PARAMETERS + +%% + + { + + + /* whitespace */ + {WhiteSpace} { } + + {Label} { + String s=yytext(); + return new ASMParsedSymbol(ASMParsedSymbol.TYPE_LABEL, s.substring(0, s.length() - 1)); + } + + /* identifiers */ + {InstructionName} { yybegin(PARAMETERS); + return new ASMParsedSymbol(ASMParsedSymbol.TYPE_INSTRUCTION_NAME, yytext()); + } + {EndOfBlock} { return new ASMParsedSymbol(ASMParsedSymbol.TYPE_BLOCK_END); } +} + + { + /* string literal */ + \" { + yybegin(STRING); + string.setLength(0); + } + + /* numeric literals */ + + {NumberLiteral} { return new ASMParsedSymbol(ASMParsedSymbol.TYPE_INTEGER, Long.parseLong((yytext()))); } + {FloatLiteral} { return new ASMParsedSymbol(ASMParsedSymbol.TYPE_FLOAT, Double.parseDouble((yytext()))); } + {LineTerminator} {yybegin(YYINITIAL); return new ASMParsedSymbol(ASMParsedSymbol.TYPE_EOL); } + {Comment} {return new ASMParsedSymbol(ASMParsedSymbol.TYPE_COMMENT, yytext().substring(1));} + {StartOfBlock} { yybegin(YYINITIAL); return new ASMParsedSymbol(ASMParsedSymbol.TYPE_BLOCK_START); } + {True} {return new ASMParsedSymbol(ASMParsedSymbol.TYPE_BOOLEAN,Boolean.TRUE);} + {False} {return new ASMParsedSymbol(ASMParsedSymbol.TYPE_BOOLEAN,Boolean.FALSE);} + {Null} {return new ASMParsedSymbol(ASMParsedSymbol.TYPE_NULL, new Null());} + {Undefined} {return new ASMParsedSymbol(ASMParsedSymbol.TYPE_UNDEFINED, new Undefined());} + + {Register} { return new ASMParsedSymbol(ASMParsedSymbol.TYPE_REGISTER, new RegisterNumber(Integer.parseInt(yytext().substring(8)))); } + {Constant} { return new ASMParsedSymbol(ASMParsedSymbol.TYPE_CONSTANT, new ConstantIndex(Integer.parseInt(yytext().substring(8)))); } + + {Identifier} { return new ASMParsedSymbol(ASMParsedSymbol.TYPE_IDENTIFIER, yytext()); } + +} + + { + \" { + yybegin(PARAMETERS); + // length also includes the trailing quote + return new ASMParsedSymbol(ASMParsedSymbol.TYPE_STRING, string.toString()); + } + + {StringCharacter}+ { string.append(yytext()); } + + /* escape sequences */ + "\\b" { string.append('\b'); } + "\\t" { string.append('\t'); } + "\\n" { string.append('\n'); } + "\\f" { string.append('\f'); } + "\\r" { string.append('\r'); } + "\\\"" { string.append('\"'); } + "\\'" { string.append('\''); } + "\\\\" { string.append('\\'); } + \\x{HexDigit}{2} { char val = (char) Integer.parseInt(yytext().substring(2), 16); + string.append(val); } + \\u{HexDigit}{4} { char val = (char) Integer.parseInt(yytext().substring(2), 16); + string.append(val); } + + /* error cases */ + \\. { throw new ActionParseException("Illegal escape sequence \"" + yytext() + "\"", yyline + 1); } + {LineTerminator} { throw new ActionParseException("Unterminated string at end of line", yyline + 1); } + +} + +/* error fallback */ +[^] { } +<> { return new ASMParsedSymbol(ASMParsedSymbol.TYPE_EOF); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/ApplicationInfo.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/ApplicationInfo.java index b2deb1961..368e73a1b 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/ApplicationInfo.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/ApplicationInfo.java @@ -1,105 +1,105 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash; - -import java.io.IOException; -import java.util.Properties; - -/** - * - * @author JPEXS - */ -public class ApplicationInfo { - - public static final String APPLICATION_NAME = "JPEXS Free Flash Decompiler"; - - public static final String SHORT_APPLICATION_NAME = "FFDec"; - - public static final String VENDOR = "JPEXS"; - - public static String version = ""; - - public static String revision = ""; - - public static int version_major = 4; - - public static int version_minor = 0; - - public static int version_release = 0; - - public static int version_build = 0; - - public static boolean nightly = false; - - public static String applicationVerName; - - public static String shortApplicationVerName; - - public static final String PROJECT_PAGE = "https://www.free-decompiler.com/flash"; - - /** - * URL for checking new updates - */ - public static String updateCheckUrl = "https://www.free-decompiler.com/flash/update/check/?currentVersion=¤tRevision=¤tVersionMajor=¤tVersionMinor=¤tVersionRelease=¤tVersionBuild=¤tNightly="; - - /** - * URL for doing update - */ - public static String updateUrl = "https://www.free-decompiler.com/flash/update/update/?currentVersion=¤tRevision=¤tVersionMajor=¤tVersionMinor=¤tVersionRelease=¤tVersionBuild=¤tNightly="; - - static { - loadProperties(); - } - - private static void loadProperties() { - Properties prop = new Properties(); - try { - prop.load(ApplicationInfo.class.getResourceAsStream("/project.properties")); - version = prop.getProperty("version"); - revision = prop.getProperty("build"); - version_major = Integer.parseInt(prop.getProperty("version.major")); - version_minor = Integer.parseInt(prop.getProperty("version.minor")); - version_release = Integer.parseInt(prop.getProperty("version.release")); - version_build = Integer.parseInt(prop.getProperty("version.build")); - nightly = prop.getProperty("nightly").equals("true"); - if (nightly) { - version = version + " nightly build " + version_build; - } - } catch (IOException | NullPointerException | NumberFormatException ex) { - // ignore - version = "unknown"; - } - updateCheckUrl = updateCheckUrl - .replace("", revision) - .replace("", version) - .replace("", "" + version_major) - .replace("", "" + version_minor) - .replace("", "" + version_release) - .replace("", "" + version_build) - .replace("", nightly ? "1" : "0"); - updateUrl = updateUrl - .replace("", revision) - .replace("", version) - .replace("", "" + version_major) - .replace("", "" + version_minor) - .replace("", "" + version_release) - .replace("", "" + version_build) - .replace("", nightly ? "1" : "0"); - applicationVerName = APPLICATION_NAME + " v." + version; - shortApplicationVerName = SHORT_APPLICATION_NAME + " v." + version; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash; + +import java.io.IOException; +import java.util.Properties; + +/** + * + * @author JPEXS + */ +public class ApplicationInfo { + + public static final String APPLICATION_NAME = "JPEXS Free Flash Decompiler"; + + public static final String SHORT_APPLICATION_NAME = "FFDec"; + + public static final String VENDOR = "JPEXS"; + + public static String version = ""; + + public static String revision = ""; + + public static int version_major = 4; + + public static int version_minor = 0; + + public static int version_release = 0; + + public static int version_build = 0; + + public static boolean nightly = false; + + public static String applicationVerName; + + public static String shortApplicationVerName; + + public static final String PROJECT_PAGE = "https://www.free-decompiler.com/flash"; + + /** + * URL for checking new updates + */ + public static String updateCheckUrl = "https://www.free-decompiler.com/flash/update/check/?currentVersion=¤tRevision=¤tVersionMajor=¤tVersionMinor=¤tVersionRelease=¤tVersionBuild=¤tNightly="; + + /** + * URL for doing update + */ + public static String updateUrl = "https://www.free-decompiler.com/flash/update/update/?currentVersion=¤tRevision=¤tVersionMajor=¤tVersionMinor=¤tVersionRelease=¤tVersionBuild=¤tNightly="; + + static { + loadProperties(); + } + + private static void loadProperties() { + Properties prop = new Properties(); + try { + prop.load(ApplicationInfo.class.getResourceAsStream("/project.properties")); + version = prop.getProperty("version"); + revision = prop.getProperty("build"); + version_major = Integer.parseInt(prop.getProperty("version.major")); + version_minor = Integer.parseInt(prop.getProperty("version.minor")); + version_release = Integer.parseInt(prop.getProperty("version.release")); + version_build = Integer.parseInt(prop.getProperty("version.build")); + nightly = prop.getProperty("nightly").equals("true"); + if (nightly) { + version = version + " nightly build " + version_build; + } + } catch (IOException | NullPointerException | NumberFormatException ex) { + // ignore + version = "unknown"; + } + updateCheckUrl = updateCheckUrl + .replace("", revision) + .replace("", version) + .replace("", "" + version_major) + .replace("", "" + version_minor) + .replace("", "" + version_release) + .replace("", "" + version_build) + .replace("", nightly ? "1" : "0"); + updateUrl = updateUrl + .replace("", revision) + .replace("", version) + .replace("", "" + version_major) + .replace("", "" + version_minor) + .replace("", "" + version_release) + .replace("", "" + version_build) + .replace("", nightly ? "1" : "0"); + applicationVerName = APPLICATION_NAME + " v." + version; + shortApplicationVerName = SHORT_APPLICATION_NAME + " v." + version; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/IdentifiersDeobfuscation.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/IdentifiersDeobfuscation.java index 8054cc621..c527037a9 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/IdentifiersDeobfuscation.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/IdentifiersDeobfuscation.java @@ -1,397 +1,397 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash; - -import com.jpexs.decompiler.flash.abc.RenameType; -import com.jpexs.decompiler.flash.tags.DefineSpriteTag; -import com.jpexs.decompiler.flash.tags.Tag; -import com.jpexs.decompiler.flash.tags.base.PlaceObjectTypeTag; -import com.jpexs.helpers.Cache; -import com.jpexs.helpers.Helper; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Random; -import java.util.regex.Pattern; - -/** - * - * @author JPEXS - */ -public class IdentifiersDeobfuscation { - - private final Random rnd = new Random(); - - private final int DEFAULT_FOO_SIZE = 10; - - public HashSet allVariableNamesStr = new HashSet<>(); - - private final HashMap typeCounts = new HashMap<>(); - - public static final String VALID_FIRST_CHARACTERS = "\\p{Lu}\\p{Ll}\\p{Lt}\\p{Lm}\\p{Lo}_$"; - - public static final String VALID_NEXT_CHARACTERS = VALID_FIRST_CHARACTERS + "\\p{Nl}\\p{Mn}\\p{Mc}\\p{Nd}\\p{Pc}"; - - private static final Pattern VALID_NAME_PATTERN = Pattern.compile("^[a-zA-Z_\\$][a-zA-Z0-9_\\$]*$"); - - private static final Pattern IDENTIFIER_PATTERN = Pattern.compile("^[" + VALID_FIRST_CHARACTERS + "][" + VALID_NEXT_CHARACTERS + "]*$"); - - public static final String FOO_CHARACTERS = "bcdfghjklmnpqrstvwz"; - - public static final String FOO_JOIN_CHARACTERS = "aeiouy"; - - // http://help.adobe.com/en_US/AS2LCR/Flash_10.0/help.html?content=00000477.html - public static final String[] reservedWordsAS2 = { - // is "add" really a keyword? documentation says yes, but I can create "add" variable in CS6... - // "add", - "and", "break", "case", "catch", "class", "continue", "default", "delete", "do", "dynamic", "else", - "eq", "extends", "false", "finally", "for", "function", "ge", "get", "gt", "if", "ifFrameLoaded", "implements", - "import", "in", "instanceof", "interface", "intrinsic", "le", - // is "it" really a keyword? documentation says yes, but I can create "it" variable in CS6... - // "it", - "ne", "new", "not", "null", "on", "onClipEvent", - "or", "private", "public", "return", "set", "static", "super", "switch", "tellTarget", "this", "throw", "try", - "typeof", "undefined", "var", "void", "while", "with" - }; - - // http://www.adobe.com/devnet/actionscript/learning/as3-fundamentals/syntax.html - public static final String[] reservedWordsAS3 = { - "as", "break", "case", "catch", "class", "const", "continue", "default", "delete", "do", "else", - "extends", "false", "finally", "for", "function", "if", "implements", "import", "in", "instanceof", - "interface", "internal", "is", "new", "null", "package", "private", "protected", "public", - "return", "super", "switch", "this", "throw", - // is "to" really a keyword? documentation says yes, but I can create "to" variable... - // "to", - "true", "try", "typeof", "use", "var", - "void", "while", "with" - }; - - //syntactic keywords - can be used as identifiers, but that have special meaning in certain contexts - public static final String[] syntacticKeywordsAS3 = {"each", "get", "set", "namespace", "include", "dynamic", "final", "native", "override", "static"}; - - public static boolean isReservedWord(String s, boolean as3) { - if (s == null) { - return false; - } - String[] reservedWords = as3 ? reservedWordsAS3 : reservedWordsAS2; - s = s.trim(); - for (String rw : reservedWords) { - if (rw.equals(s)) { - return true; - } - } - return false; - } - - private String fooString(boolean as3, HashMap deobfuscated, String orig, boolean firstUppercase, int rndSize) { - boolean exists; - String ret; - loopfoo: - do { - exists = false; - int len = 3 + rnd.nextInt(rndSize - 3); - ret = ""; - for (int i = 0; i < len; i++) { - String c = ""; - if ((i % 2) == 0) { - c = "" + FOO_CHARACTERS.charAt(rnd.nextInt(FOO_CHARACTERS.length())); - } else { - c = "" + FOO_JOIN_CHARACTERS.charAt(rnd.nextInt(FOO_JOIN_CHARACTERS.length())); - } - if (i == 0 && firstUppercase) { - c = c.toUpperCase(Locale.ENGLISH); - } - ret += c; - } - if (allVariableNamesStr.contains(ret)) { - exists = true; - rndSize += 1; - continue loopfoo; - } - if (isReservedWord(ret, as3)) { - exists = true; - rndSize += 1; - continue; - } - if (deobfuscated.containsValue(ret)) { - exists = true; - rndSize += 1; - continue; - } - } while (exists); - return ret; - } - - public void deobfuscateInstanceNames(boolean as3, HashMap namesMap, RenameType renameType, List tags, Map selected) { - for (Tag t : tags) { - if (t instanceof DefineSpriteTag) { - deobfuscateInstanceNames(as3, namesMap, renameType, ((DefineSpriteTag) t).subTags, selected); - } - if (t instanceof PlaceObjectTypeTag) { - PlaceObjectTypeTag po = (PlaceObjectTypeTag) t; - String name = po.getInstanceName(); - if (name != null) { - String changedName = deobfuscateName(as3, name, false, "instance", namesMap, renameType, selected); - if (changedName != null) { - po.setInstanceName(changedName); - ((Tag) po).setModified(true); - } - } - String className = po.getClassName(); - if (className != null) { - String changedClassName = deobfuscateNameWithPackage(as3, className, namesMap, renameType, selected); - if (changedClassName != null) { - po.setClassName(changedClassName); - ((Tag) po).setModified(true); - } - } - } - } - } - - public String deobfuscatePackage(boolean as3, String pkg, HashMap namesMap, RenameType renameType, Map selected) { - if (namesMap.containsKey(pkg)) { - return namesMap.get(pkg); - } - String[] parts = null; - if (pkg.contains(".")) { - parts = pkg.split("\\."); - } else { - parts = new String[]{pkg}; - } - StringBuilder ret = new StringBuilder(); - boolean isChanged = false; - for (int p = 0; p < parts.length; p++) { - if (p > 0) { - ret.append("."); - } - String partChanged = deobfuscateName(as3, parts[p], false, "package", namesMap, renameType, selected); - if (partChanged != null) { - ret.append(partChanged); - isChanged = true; - } else { - ret.append(parts[p]); - } - } - if (isChanged) { - String retStr = ret.toString(); - namesMap.put(pkg, retStr); - return retStr; - } - return null; - } - - public String deobfuscateNameWithPackage(boolean as3, String n, HashMap namesMap, RenameType renameType, Map selected) { - String pkg = null; - String name = ""; - if (n.contains(".")) { - pkg = n.substring(0, n.lastIndexOf('.')); - name = n.substring(n.lastIndexOf('.') + 1); - } else { - name = n; - } - boolean changed = false; - if ((pkg != null) && (!pkg.isEmpty())) { - String changedPkg = deobfuscatePackage(as3, pkg, namesMap, renameType, selected); - if (changedPkg != null) { - changed = true; - pkg = changedPkg; - } - } - String changedName = deobfuscateName(as3, name, true, "class", namesMap, renameType, selected); - if (changedName != null) { - changed = true; - name = changedName; - } - if (changed) { - String newClassName = ""; - if (pkg == null) { - newClassName = name; - } else { - newClassName = pkg + "." + name; - } - return newClassName; - } - return null; - } - - public static boolean isValidName(boolean as3, String s, String... exceptions) { - for (String e : exceptions) { - if (e.equals(s)) { - return true; - } - } - - if (isReservedWord(s, as3)) { - return false; - } - - // simple fast test - if (VALID_NAME_PATTERN.matcher(s).matches()) { - return true; - } - // unicode test - if (IDENTIFIER_PATTERN.matcher(s).matches()) { - return true; - } - return false; - } - - public String deobfuscateName(boolean as3, String s, boolean firstUppercase, String usageType, HashMap namesMap, RenameType renameType, Map selected) { - boolean isValid = true; - if (usageType == null) { - usageType = "name"; - } - - if (selected != null) { - if (selected.containsKey(s)) { - return selected.get(s); - } - } - - isValid = isValidName(as3, s); - if (!isValid) { - if (namesMap.containsKey(s)) { - return namesMap.get(s); - } else { - Integer cnt = typeCounts.get(usageType); - if (cnt == null) { - cnt = 0; - } - - String ret = null; - if (renameType == RenameType.TYPENUMBER) { - - boolean found; - do { - found = false; - cnt++; - ret = usageType + "_" + cnt; - found = allVariableNamesStr.contains(ret); - } while (found); - typeCounts.put(usageType, cnt); - } else if (renameType == RenameType.RANDOMWORD) { - ret = fooString(as3, namesMap, s, firstUppercase, DEFAULT_FOO_SIZE); - } - namesMap.put(s, ret); - return ret; - } - } - return null; - } - - public static String makeObfuscatedIdentifier(String s) { - return "\u00A7" + escapeOIdentifier(s) + "\u00A7"; - } - - private static final Cache as3NameCache = Cache.getInstance(false, true, "as3_ident"); - - private static final Cache as2NameCache = Cache.getInstance(false, true, "as2_ident"); - - /** - * Ensures identifier is valid and if not, uses paragraph syntax - * - * @param as3 Is ActionScript3 - * @param s Identifier - * @param validExceptions Exceptions which are valid (e.g. some reserved - * words) - * @return - */ - public static String printIdentifier(boolean as3, String s, String... validExceptions) { - if (s.startsWith("\u00A7") && s.endsWith("\u00A7")) { // Assuming already printed - TODO:detect better - return s; - } - - for (String e : validExceptions) { - if (e.equals(s)) { - return s; - } - } - Cache nameCache = as3 ? as3NameCache : as2NameCache; - - if (nameCache.contains(s)) { - return nameCache.get(s); - } - - if (isValidName(as3, s, validExceptions)) { - nameCache.put(s, s); - return s; - } - String ret = makeObfuscatedIdentifier(s); - nameCache.put(s, ret); - return ret; - } - - public static String printNamespace(boolean as3, String pkg, String... validNameExceptions) { - Cache nameCache = as3 ? as3NameCache : as2NameCache; - if (nameCache.contains(pkg)) { - return nameCache.get(pkg); - } - if (pkg.isEmpty()) { - nameCache.put(pkg, pkg); - return pkg; - } - String[] parts = null; - if (pkg.contains(".")) { - parts = pkg.split("\\."); - } else { - parts = new String[]{pkg}; - } - StringBuilder ret = new StringBuilder(); - for (int i = 0; i < parts.length; i++) { - if (i > 0) { - ret.append("."); - } - ret.append(printIdentifier(as3, parts[i], validNameExceptions)); - } - String retStr = ret.toString(); - nameCache.put(pkg, retStr); - return retStr; - } - - public static String escapeOIdentifier(String s) { - StringBuilder ret = new StringBuilder(s.length()); - for (int i = 0; i < s.length(); i++) { - char c = s.charAt(i); - if (c == '\n') { - ret.append("\\n"); - } else if (c == '\r') { - ret.append("\\r"); - } else if (c == '\t') { - ret.append("\\t"); - } else if (c == '\b') { - ret.append("\\b"); - } else if (c == '\t') { - ret.append("\\t"); - } else if (c == '\f') { - ret.append("\\f"); - } else if (c == '\\') { - ret.append("\\\\"); - } else if (c == '\u00A7') { - ret.append("\\\u00A7"); - } else if (c < 32) { - ret.append("\\x").append(Helper.padZeros(Integer.toHexString((int) c), 2)); - } else { - ret.append(c); - } - } - - return ret.toString(); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash; + +import com.jpexs.decompiler.flash.abc.RenameType; +import com.jpexs.decompiler.flash.tags.DefineSpriteTag; +import com.jpexs.decompiler.flash.tags.Tag; +import com.jpexs.decompiler.flash.tags.base.PlaceObjectTypeTag; +import com.jpexs.helpers.Cache; +import com.jpexs.helpers.Helper; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Random; +import java.util.regex.Pattern; + +/** + * + * @author JPEXS + */ +public class IdentifiersDeobfuscation { + + private final Random rnd = new Random(); + + private final int DEFAULT_FOO_SIZE = 10; + + public HashSet allVariableNamesStr = new HashSet<>(); + + private final HashMap typeCounts = new HashMap<>(); + + public static final String VALID_FIRST_CHARACTERS = "\\p{Lu}\\p{Ll}\\p{Lt}\\p{Lm}\\p{Lo}_$"; + + public static final String VALID_NEXT_CHARACTERS = VALID_FIRST_CHARACTERS + "\\p{Nl}\\p{Mn}\\p{Mc}\\p{Nd}\\p{Pc}"; + + private static final Pattern VALID_NAME_PATTERN = Pattern.compile("^[a-zA-Z_\\$][a-zA-Z0-9_\\$]*$"); + + private static final Pattern IDENTIFIER_PATTERN = Pattern.compile("^[" + VALID_FIRST_CHARACTERS + "][" + VALID_NEXT_CHARACTERS + "]*$"); + + public static final String FOO_CHARACTERS = "bcdfghjklmnpqrstvwz"; + + public static final String FOO_JOIN_CHARACTERS = "aeiouy"; + + // http://help.adobe.com/en_US/AS2LCR/Flash_10.0/help.html?content=00000477.html + public static final String[] reservedWordsAS2 = { + // is "add" really a keyword? documentation says yes, but I can create "add" variable in CS6... + // "add", + "and", "break", "case", "catch", "class", "continue", "default", "delete", "do", "dynamic", "else", + "eq", "extends", "false", "finally", "for", "function", "ge", "get", "gt", "if", "ifFrameLoaded", "implements", + "import", "in", "instanceof", "interface", "intrinsic", "le", + // is "it" really a keyword? documentation says yes, but I can create "it" variable in CS6... + // "it", + "ne", "new", "not", "null", "on", "onClipEvent", + "or", "private", "public", "return", "set", "static", "super", "switch", "tellTarget", "this", "throw", "try", + "typeof", "undefined", "var", "void", "while", "with" + }; + + // http://www.adobe.com/devnet/actionscript/learning/as3-fundamentals/syntax.html + public static final String[] reservedWordsAS3 = { + "as", "break", "case", "catch", "class", "const", "continue", "default", "delete", "do", "else", + "extends", "false", "finally", "for", "function", "if", "implements", "import", "in", "instanceof", + "interface", "internal", "is", "new", "null", "package", "private", "protected", "public", + "return", "super", "switch", "this", "throw", + // is "to" really a keyword? documentation says yes, but I can create "to" variable... + // "to", + "true", "try", "typeof", "use", "var", + "void", "while", "with" + }; + + //syntactic keywords - can be used as identifiers, but that have special meaning in certain contexts + public static final String[] syntacticKeywordsAS3 = {"each", "get", "set", "namespace", "include", "dynamic", "final", "native", "override", "static"}; + + public static boolean isReservedWord(String s, boolean as3) { + if (s == null) { + return false; + } + String[] reservedWords = as3 ? reservedWordsAS3 : reservedWordsAS2; + s = s.trim(); + for (String rw : reservedWords) { + if (rw.equals(s)) { + return true; + } + } + return false; + } + + private String fooString(boolean as3, HashMap deobfuscated, String orig, boolean firstUppercase, int rndSize) { + boolean exists; + String ret; + loopfoo: + do { + exists = false; + int len = 3 + rnd.nextInt(rndSize - 3); + ret = ""; + for (int i = 0; i < len; i++) { + String c = ""; + if ((i % 2) == 0) { + c = "" + FOO_CHARACTERS.charAt(rnd.nextInt(FOO_CHARACTERS.length())); + } else { + c = "" + FOO_JOIN_CHARACTERS.charAt(rnd.nextInt(FOO_JOIN_CHARACTERS.length())); + } + if (i == 0 && firstUppercase) { + c = c.toUpperCase(Locale.ENGLISH); + } + ret += c; + } + if (allVariableNamesStr.contains(ret)) { + exists = true; + rndSize += 1; + continue loopfoo; + } + if (isReservedWord(ret, as3)) { + exists = true; + rndSize += 1; + continue; + } + if (deobfuscated.containsValue(ret)) { + exists = true; + rndSize += 1; + continue; + } + } while (exists); + return ret; + } + + public void deobfuscateInstanceNames(boolean as3, HashMap namesMap, RenameType renameType, List tags, Map selected) { + for (Tag t : tags) { + if (t instanceof DefineSpriteTag) { + deobfuscateInstanceNames(as3, namesMap, renameType, ((DefineSpriteTag) t).subTags, selected); + } + if (t instanceof PlaceObjectTypeTag) { + PlaceObjectTypeTag po = (PlaceObjectTypeTag) t; + String name = po.getInstanceName(); + if (name != null) { + String changedName = deobfuscateName(as3, name, false, "instance", namesMap, renameType, selected); + if (changedName != null) { + po.setInstanceName(changedName); + ((Tag) po).setModified(true); + } + } + String className = po.getClassName(); + if (className != null) { + String changedClassName = deobfuscateNameWithPackage(as3, className, namesMap, renameType, selected); + if (changedClassName != null) { + po.setClassName(changedClassName); + ((Tag) po).setModified(true); + } + } + } + } + } + + public String deobfuscatePackage(boolean as3, String pkg, HashMap namesMap, RenameType renameType, Map selected) { + if (namesMap.containsKey(pkg)) { + return namesMap.get(pkg); + } + String[] parts = null; + if (pkg.contains(".")) { + parts = pkg.split("\\."); + } else { + parts = new String[]{pkg}; + } + StringBuilder ret = new StringBuilder(); + boolean isChanged = false; + for (int p = 0; p < parts.length; p++) { + if (p > 0) { + ret.append("."); + } + String partChanged = deobfuscateName(as3, parts[p], false, "package", namesMap, renameType, selected); + if (partChanged != null) { + ret.append(partChanged); + isChanged = true; + } else { + ret.append(parts[p]); + } + } + if (isChanged) { + String retStr = ret.toString(); + namesMap.put(pkg, retStr); + return retStr; + } + return null; + } + + public String deobfuscateNameWithPackage(boolean as3, String n, HashMap namesMap, RenameType renameType, Map selected) { + String pkg = null; + String name = ""; + if (n.contains(".")) { + pkg = n.substring(0, n.lastIndexOf('.')); + name = n.substring(n.lastIndexOf('.') + 1); + } else { + name = n; + } + boolean changed = false; + if ((pkg != null) && (!pkg.isEmpty())) { + String changedPkg = deobfuscatePackage(as3, pkg, namesMap, renameType, selected); + if (changedPkg != null) { + changed = true; + pkg = changedPkg; + } + } + String changedName = deobfuscateName(as3, name, true, "class", namesMap, renameType, selected); + if (changedName != null) { + changed = true; + name = changedName; + } + if (changed) { + String newClassName = ""; + if (pkg == null) { + newClassName = name; + } else { + newClassName = pkg + "." + name; + } + return newClassName; + } + return null; + } + + public static boolean isValidName(boolean as3, String s, String... exceptions) { + for (String e : exceptions) { + if (e.equals(s)) { + return true; + } + } + + if (isReservedWord(s, as3)) { + return false; + } + + // simple fast test + if (VALID_NAME_PATTERN.matcher(s).matches()) { + return true; + } + // unicode test + if (IDENTIFIER_PATTERN.matcher(s).matches()) { + return true; + } + return false; + } + + public String deobfuscateName(boolean as3, String s, boolean firstUppercase, String usageType, HashMap namesMap, RenameType renameType, Map selected) { + boolean isValid = true; + if (usageType == null) { + usageType = "name"; + } + + if (selected != null) { + if (selected.containsKey(s)) { + return selected.get(s); + } + } + + isValid = isValidName(as3, s); + if (!isValid) { + if (namesMap.containsKey(s)) { + return namesMap.get(s); + } else { + Integer cnt = typeCounts.get(usageType); + if (cnt == null) { + cnt = 0; + } + + String ret = null; + if (renameType == RenameType.TYPENUMBER) { + + boolean found; + do { + found = false; + cnt++; + ret = usageType + "_" + cnt; + found = allVariableNamesStr.contains(ret); + } while (found); + typeCounts.put(usageType, cnt); + } else if (renameType == RenameType.RANDOMWORD) { + ret = fooString(as3, namesMap, s, firstUppercase, DEFAULT_FOO_SIZE); + } + namesMap.put(s, ret); + return ret; + } + } + return null; + } + + public static String makeObfuscatedIdentifier(String s) { + return "\u00A7" + escapeOIdentifier(s) + "\u00A7"; + } + + private static final Cache as3NameCache = Cache.getInstance(false, true, "as3_ident"); + + private static final Cache as2NameCache = Cache.getInstance(false, true, "as2_ident"); + + /** + * Ensures identifier is valid and if not, uses paragraph syntax + * + * @param as3 Is ActionScript3 + * @param s Identifier + * @param validExceptions Exceptions which are valid (e.g. some reserved + * words) + * @return + */ + public static String printIdentifier(boolean as3, String s, String... validExceptions) { + if (s.startsWith("\u00A7") && s.endsWith("\u00A7")) { // Assuming already printed - TODO:detect better + return s; + } + + for (String e : validExceptions) { + if (e.equals(s)) { + return s; + } + } + Cache nameCache = as3 ? as3NameCache : as2NameCache; + + if (nameCache.contains(s)) { + return nameCache.get(s); + } + + if (isValidName(as3, s, validExceptions)) { + nameCache.put(s, s); + return s; + } + String ret = makeObfuscatedIdentifier(s); + nameCache.put(s, ret); + return ret; + } + + public static String printNamespace(boolean as3, String pkg, String... validNameExceptions) { + Cache nameCache = as3 ? as3NameCache : as2NameCache; + if (nameCache.contains(pkg)) { + return nameCache.get(pkg); + } + if (pkg.isEmpty()) { + nameCache.put(pkg, pkg); + return pkg; + } + String[] parts = null; + if (pkg.contains(".")) { + parts = pkg.split("\\."); + } else { + parts = new String[]{pkg}; + } + StringBuilder ret = new StringBuilder(); + for (int i = 0; i < parts.length; i++) { + if (i > 0) { + ret.append("."); + } + ret.append(printIdentifier(as3, parts[i], validNameExceptions)); + } + String retStr = ret.toString(); + nameCache.put(pkg, retStr); + return retStr; + } + + public static String escapeOIdentifier(String s) { + StringBuilder ret = new StringBuilder(s.length()); + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + if (c == '\n') { + ret.append("\\n"); + } else if (c == '\r') { + ret.append("\\r"); + } else if (c == '\t') { + ret.append("\\t"); + } else if (c == '\b') { + ret.append("\\b"); + } else if (c == '\t') { + ret.append("\\t"); + } else if (c == '\f') { + ret.append("\\f"); + } else if (c == '\\') { + ret.append("\\\\"); + } else if (c == '\u00A7') { + ret.append("\\\u00A7"); + } else if (c < 32) { + ret.append("\\x").append(Helper.padZeros(Integer.toHexString((int) c), 2)); + } else { + ret.append(c); + } + } + + return ret.toString(); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java index ad559c5ac..d8a88cce9 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java @@ -1,2765 +1,2765 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash; - -import SevenZip.Compression.LZMA.Decoder; -import SevenZip.Compression.LZMA.Encoder; -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.CachedDecompilation; -import com.jpexs.decompiler.flash.abc.ClassPath; -import com.jpexs.decompiler.flash.abc.RenameType; -import com.jpexs.decompiler.flash.abc.ScriptPack; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.ScriptInfo; -import com.jpexs.decompiler.flash.action.Action; -import com.jpexs.decompiler.flash.action.ActionGraphSource; -import com.jpexs.decompiler.flash.action.ActionList; -import com.jpexs.decompiler.flash.action.ActionLocalData; -import com.jpexs.decompiler.flash.action.CachedScript; -import com.jpexs.decompiler.flash.action.model.ConstantPool; -import com.jpexs.decompiler.flash.action.model.DirectValueActionItem; -import com.jpexs.decompiler.flash.action.model.FunctionActionItem; -import com.jpexs.decompiler.flash.action.model.GetMemberActionItem; -import com.jpexs.decompiler.flash.action.model.GetVariableActionItem; -import com.jpexs.decompiler.flash.action.model.clauses.ClassActionItem; -import com.jpexs.decompiler.flash.action.model.clauses.InterfaceActionItem; -import com.jpexs.decompiler.flash.action.swf4.ActionEquals; -import com.jpexs.decompiler.flash.action.swf4.ActionGetVariable; -import com.jpexs.decompiler.flash.action.swf4.ActionIf; -import com.jpexs.decompiler.flash.action.swf4.ActionPush; -import com.jpexs.decompiler.flash.action.swf4.ActionSetVariable; -import com.jpexs.decompiler.flash.action.swf4.ConstantIndex; -import com.jpexs.decompiler.flash.action.swf5.ActionCallFunction; -import com.jpexs.decompiler.flash.action.swf5.ActionCallMethod; -import com.jpexs.decompiler.flash.action.swf5.ActionConstantPool; -import com.jpexs.decompiler.flash.action.swf5.ActionDefineFunction; -import com.jpexs.decompiler.flash.action.swf5.ActionDefineLocal; -import com.jpexs.decompiler.flash.action.swf5.ActionDefineLocal2; -import com.jpexs.decompiler.flash.action.swf5.ActionEquals2; -import com.jpexs.decompiler.flash.action.swf5.ActionGetMember; -import com.jpexs.decompiler.flash.action.swf5.ActionNewMethod; -import com.jpexs.decompiler.flash.action.swf5.ActionNewObject; -import com.jpexs.decompiler.flash.action.swf5.ActionSetMember; -import com.jpexs.decompiler.flash.action.swf7.ActionDefineFunction2; -import com.jpexs.decompiler.flash.configuration.Configuration; -import com.jpexs.decompiler.flash.dumpview.DumpInfo; -import com.jpexs.decompiler.flash.dumpview.DumpInfoSwfNode; -import com.jpexs.decompiler.flash.ecma.Null; -import com.jpexs.decompiler.flash.exporters.commonshape.ExportRectangle; -import com.jpexs.decompiler.flash.exporters.commonshape.Matrix; -import com.jpexs.decompiler.flash.exporters.commonshape.SVGExporter; -import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; -import com.jpexs.decompiler.flash.exporters.script.AS2ScriptExporter; -import com.jpexs.decompiler.flash.exporters.script.AS3ScriptExporter; -import com.jpexs.decompiler.flash.exporters.settings.ScriptExportSettings; -import com.jpexs.decompiler.flash.helpers.HighlightedText; -import com.jpexs.decompiler.flash.helpers.HighlightedTextWriter; -import com.jpexs.decompiler.flash.helpers.ImageHelper; -import com.jpexs.decompiler.flash.helpers.SWFDecompilerPlugin; -import com.jpexs.decompiler.flash.helpers.collections.MyEntry; -import com.jpexs.decompiler.flash.helpers.hilight.Highlighting; -import com.jpexs.decompiler.flash.tags.ABCContainerTag; -import com.jpexs.decompiler.flash.tags.DefineBinaryDataTag; -import com.jpexs.decompiler.flash.tags.DefineButton2Tag; -import com.jpexs.decompiler.flash.tags.DefineButtonTag; -import com.jpexs.decompiler.flash.tags.DefineSpriteTag; -import com.jpexs.decompiler.flash.tags.DoInitActionTag; -import com.jpexs.decompiler.flash.tags.EndTag; -import com.jpexs.decompiler.flash.tags.ExportAssetsTag; -import com.jpexs.decompiler.flash.tags.FileAttributesTag; -import com.jpexs.decompiler.flash.tags.JPEGTablesTag; -import com.jpexs.decompiler.flash.tags.ShowFrameTag; -import com.jpexs.decompiler.flash.tags.SymbolClassTag; -import com.jpexs.decompiler.flash.tags.Tag; -import com.jpexs.decompiler.flash.tags.TagStub; -import com.jpexs.decompiler.flash.tags.VideoFrameTag; -import com.jpexs.decompiler.flash.tags.base.ASMSource; -import com.jpexs.decompiler.flash.tags.base.ASMSourceContainer; -import com.jpexs.decompiler.flash.tags.base.BoundedTag; -import com.jpexs.decompiler.flash.tags.base.ButtonTag; -import com.jpexs.decompiler.flash.tags.base.CharacterIdTag; -import com.jpexs.decompiler.flash.tags.base.CharacterTag; -import com.jpexs.decompiler.flash.tags.base.DrawableTag; -import com.jpexs.decompiler.flash.tags.base.Exportable; -import com.jpexs.decompiler.flash.tags.base.FontTag; -import com.jpexs.decompiler.flash.tags.base.ImageTag; -import com.jpexs.decompiler.flash.tags.base.MorphShapeTag; -import com.jpexs.decompiler.flash.tags.base.PlaceObjectTypeTag; -import com.jpexs.decompiler.flash.tags.base.RemoveTag; -import com.jpexs.decompiler.flash.tags.base.RenderContext; -import com.jpexs.decompiler.flash.tags.base.ShapeTag; -import com.jpexs.decompiler.flash.tags.base.TextTag; -import com.jpexs.decompiler.flash.timeline.AS2Package; -import com.jpexs.decompiler.flash.timeline.Clip; -import com.jpexs.decompiler.flash.timeline.DepthState; -import com.jpexs.decompiler.flash.timeline.Frame; -import com.jpexs.decompiler.flash.timeline.FrameScript; -import com.jpexs.decompiler.flash.timeline.SvgClip; -import com.jpexs.decompiler.flash.timeline.TagScript; -import com.jpexs.decompiler.flash.timeline.Timeline; -import com.jpexs.decompiler.flash.timeline.Timelined; -import com.jpexs.decompiler.flash.treeitems.SWFList; -import com.jpexs.decompiler.flash.treeitems.TreeItem; -import com.jpexs.decompiler.flash.types.ColorTransform; -import com.jpexs.decompiler.flash.types.MATRIX; -import com.jpexs.decompiler.flash.types.RECT; -import com.jpexs.decompiler.flash.types.annotations.Internal; -import com.jpexs.decompiler.flash.types.filters.BlendComposite; -import com.jpexs.decompiler.flash.types.filters.FILTER; -import com.jpexs.decompiler.flash.xfl.FLAVersion; -import com.jpexs.decompiler.flash.xfl.XFLConverter; -import com.jpexs.decompiler.graph.Graph; -import com.jpexs.decompiler.graph.GraphSourceItem; -import com.jpexs.decompiler.graph.GraphSourceItemContainer; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.TranslateStack; -import com.jpexs.decompiler.graph.model.LocalData; -import com.jpexs.helpers.ByteArrayRange; -import com.jpexs.helpers.Cache; -import com.jpexs.helpers.Helper; -import com.jpexs.helpers.NulStream; -import com.jpexs.helpers.ProgressListener; -import com.jpexs.helpers.SerializableImage; -import com.jpexs.helpers.utf8.Utf8Helper; -import java.awt.AlphaComposite; -import java.awt.Color; -import java.awt.Graphics2D; -import java.awt.Rectangle; -import java.awt.RenderingHints; -import java.awt.Shape; -import java.awt.geom.AffineTransform; -import java.awt.image.BufferedImage; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.EmptyStackException; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Set; -import java.util.Stack; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.util.zip.DeflaterOutputStream; -import java.util.zip.InflaterInputStream; - -/** - * Class representing SWF file - * - * @author JPEXS - */ -public final class SWF implements SWFContainerItem, Timelined { - - // big object for testing cleanup - //BigObject bigObj = new BigObject(); - /** - * Default version of SWF file format - */ - public static final int DEFAULT_VERSION = 10; - - /** - * Maximum SWF file format version - * Needs to be fixed when SWF versions reaches this value - */ - public static final int MAX_VERSION = 30; - - /** - * Tags inside of file - */ - public List tags = new ArrayList<>(); - - @Internal - public boolean hasEndTag = true; - - /** - * ExportRectangle for the display - */ - public RECT displayRect; - - /** - * Movie frame rate - */ - public int frameRate; - - /** - * Number of frames in movie - */ - public int frameCount; - - /** - * Version of SWF - */ - public int version; - - /** - * Uncompressed size of the file - */ - @Internal - public long fileSize; - - /** - * Used compression mode - */ - public SWFCompression compression = SWFCompression.NONE; - - /** - * Compressed size of the file (LZMA) - */ - @Internal - public long compressedSize; - - /** - * LZMA Properties - */ - public byte[] lzmaProperties; - - @Internal - public byte[] uncompressedData; - - @Internal - public byte[] originalUncompressedData; - - /** - * ScaleForm GFx - */ - public boolean gfx = false; - - @Internal - public SWFList swfList; - - @Internal - private String file; - - @Internal - private String fileTitle; - - @Internal - private Map characters; - - @Internal - private List abcList; - - @Internal - private JPEGTablesTag jtt; - - @Internal - public Map sourceFontNamesMap = new HashMap<>(); - - public static final double unitDivisor = 20; - - private static final Logger logger = Logger.getLogger(SWF.class.getName()); - - @Internal - private Timeline timeline; - - @Internal - public DumpInfoSwfNode dumpInfo; - - @Internal - public DefineBinaryDataTag binaryData; - - @Internal - private final HashMap deobfuscated = new HashMap<>(); - - @Internal - private final IdentifiersDeobfuscation deobfuscation = new IdentifiersDeobfuscation(); - - @Internal - private Cache frameCache = Cache.getInstance(false, false, "frame"); - - @Internal - private final Cache as2Cache = Cache.getInstance(true, false, "as2"); - - @Internal - private final Cache as3Cache = Cache.getInstance(true, false, "as3"); - - public void updateCharacters() { - characters = null; - } - - public void clearTagSwfs() { - resetTimelines(this); - updateCharacters(); - - for (Tag tag : tags) { - if (tag instanceof DefineSpriteTag) { - DefineSpriteTag spriteTag = (DefineSpriteTag) tag; - for (Tag tag1 : spriteTag.subTags) { - tag1.setSwf(null); - } - - spriteTag.subTags.clear(); - } - - if (tag instanceof DefineBinaryDataTag) { - DefineBinaryDataTag binaryTag = (DefineBinaryDataTag) tag; - if (binaryTag.innerSwf != null) { - binaryTag.innerSwf.clearTagSwfs(); - } - } - - tag.setSwf(null); - } - - tags.clear(); - if (abcList != null) { - abcList.clear(); - } - - if (swfList != null) { - swfList.swfs.clear(); - } - - as2Cache.clear(); - as3Cache.clear(); - frameCache.clear(); - - timeline = null; - clearDumpInfo(dumpInfo); - dumpInfo = null; - jtt = null; - binaryData = null; - } - - private void clearDumpInfo(DumpInfo di) { - for (DumpInfo childInfo : di.getChildInfos()) { - clearDumpInfo(childInfo); - } - - di.getChildInfos().clear(); - } - - public Map getCharacters() { - if (characters == null) { - synchronized (this) { - if (characters == null) { - Map chars = new HashMap<>(); - parseCharacters(tags, chars); - characters = Collections.unmodifiableMap(chars); - } - } - } - - return characters; - } - - public CharacterTag getCharacter(int characterId) { - return getCharacters().get(characterId); - } - - public String getExportName(int characterId) { - CharacterTag characterTag = getCharacters().get(characterId); - String exportName = characterTag != null ? characterTag.getExportName() : null; - return exportName; - } - - public FontTag getFont(int fontId) { - CharacterTag characterTag = getCharacters().get(fontId); - if (characterTag instanceof FontTag) { - return (FontTag) characterTag; - } - - if (characterTag != null) { - logger.log(Level.SEVERE, "CharacterTag should be a FontTag. characterId: {0}", fontId); - } - - return null; - } - - public List getAbcList() { - if (abcList == null) { - synchronized (this) { - if (abcList == null) { - ArrayList newAbcList = new ArrayList<>(); - getAbcTags(tags, newAbcList); - abcList = newAbcList; - } - } - } - - return abcList; - } - - public boolean isAS3() { - FileAttributesTag fileAttributes = getFileAttributes(); - return (fileAttributes != null && fileAttributes.actionScript3) || (fileAttributes == null && !getAbcList().isEmpty()); - } - - public FileAttributesTag getFileAttributes() { - for (Tag t : tags) { - if (t instanceof FileAttributesTag) { - return (FileAttributesTag) t; - } - } - - return null; - } - - public int getNextCharacterId() { - int max = -1; - for (int characterId : getCharacters().keySet()) { - if (characterId > max) { - max = characterId; - } - } - - return max + 1; - } - - public synchronized JPEGTablesTag getJtt() { - if (jtt == null) { - synchronized (this) { - if (jtt == null) { - for (Tag t : tags) { - if (t instanceof JPEGTablesTag) { - jtt = (JPEGTablesTag) t; - break; - } - } - } - } - } - - return jtt; - } - - public String getDocumentClass() { - for (Tag t : tags) { - if (t instanceof SymbolClassTag) { - SymbolClassTag sc = (SymbolClassTag) t; - for (int i = 0; i < sc.tags.size(); i++) { - if (sc.tags.get(i) == 0) { - return sc.names.get(i); - } - } - } - } - - return null; - } - - public void fixCharactersOrder(boolean checkAll) { - Set addedCharacterIds = new HashSet<>(); - Set movedTags = new HashSet<>(); - for (int i = 0; i < tags.size(); i++) { - Tag tag = tags.get(i); - if (checkAll || tag.isModified()) { - Set needed = new HashSet<>(); - tag.getNeededCharacters(needed); - if (tag instanceof CharacterTag) { - CharacterTag characterTag = (CharacterTag) tag; - needed.remove(characterTag.getCharacterId()); - } - boolean moved = false; - for (Integer id : needed) { - if (!addedCharacterIds.contains(id)) { - CharacterTag neededCharacter = getCharacter(id); - if (neededCharacter == null) { - continue; - } - - if (movedTags.contains(neededCharacter)) { - logger.log(Level.SEVERE, "Fixing characters order failed, recursion detected."); - return; - } - - // move the needed character to the current position - tags.remove(neededCharacter); - tags.add(i, neededCharacter); - movedTags.add(neededCharacter); - moved = true; - } - } - - if (moved) { - i--; - continue; - } - } - if (tag instanceof CharacterTag) { - addedCharacterIds.add(((CharacterTag) tag).getCharacterId()); - } - } - } - - public void resetTimelines(Timelined timelined) { - timelined.resetTimeline(); - if (timelined instanceof SWF) { - for (Tag t : ((SWF) timelined).tags) { - if (t instanceof Timelined) { - resetTimelines((Timelined) t); - } - } - } - } - - private void parseCharacters(List list, Map characters) { - for (Tag t : list) { - if (t instanceof CharacterTag) { - int characterId = ((CharacterTag) t).getCharacterId(); - if (characters.containsKey(characterId)) { - logger.log(Level.SEVERE, "SWF already contains characterId={0}", characterId); - } - - if (characterId != 0) { - characters.put(characterId, (CharacterTag) t); - } - } - if (t instanceof DefineSpriteTag) { - parseCharacters(((DefineSpriteTag) t).getSubTags(), characters); - } - } - } - - /** - * Unresolve recursive sprites - */ - private void checkInvalidSprites() { - for (int i = 0; i < tags.size(); i++) { - Tag t = tags.get(i); - if (t instanceof DefineSpriteTag) { - if (!isSpriteValid((DefineSpriteTag) t, new ArrayList())) { - tags.set(i, new TagStub(this, t.getId(), "InvalidSprite", t.getOriginalRange(), null)); - } - } - } - } - - private boolean isSpriteValid(DefineSpriteTag sprite, List path) { - if (path.contains(sprite.spriteId)) { - return false; - } - path.add(sprite.spriteId); - for (Tag t : sprite.subTags) { - if (t instanceof DefineSpriteTag) { - if (!isSpriteValid((DefineSpriteTag) t, path)) { - return false; - } - } - } - path.remove((Integer) sprite.spriteId); - return true; - } - - @Override - public Timeline getTimeline() { - if (timeline == null) { - timeline = new Timeline(this); - } - return timeline; - } - - @Override - public void resetTimeline() { - if (timeline != null) { - timeline.reset(this); - } - } - - /** - * Gets all tags with specified id - * - * @param tagId Identificator of tag type - * @return List of tags - */ - public List getTagData(int tagId) { - List ret = new ArrayList<>(); - for (Tag tag : tags) { - if (tag.getId() == tagId) { - ret.add(tag); - } - } - return ret; - } - - /** - * Saves this SWF into new file - * - * @param os OutputStream to save SWF in - * @throws IOException - */ - public void saveTo(OutputStream os) throws IOException { - saveTo(os, compression); - } - - public String getHeaderBytes() { - return getHeaderBytes(compression, gfx); - } - - private String getHeaderBytes(SWFCompression compression, boolean gfx) { - if (compression == SWFCompression.LZMA_ABC) { - return "ABC"; - } - - String ret = ""; - if (compression == SWFCompression.LZMA) { - ret += 'Z'; - } else if (compression == SWFCompression.ZLIB) { - ret += 'C'; - } else { - if (gfx) { - ret += 'G'; - } else { - ret += 'F'; - } - } - if (gfx) { - ret += 'F'; - ret += 'X'; - } else { - ret += 'W'; - ret += 'S'; - } - return ret; - } - - /** - * Saves this SWF into new file - * - * @param os OutputStream to save SWF in - * @param compression - * @throws IOException - */ - public void saveTo(OutputStream os, SWFCompression compression) throws IOException { - try { - fixCharactersOrder(false); - - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - SWFOutputStream sos = new SWFOutputStream(baos, version); - sos.writeRECT(displayRect); - sos.writeUI8(0); - sos.writeUI8(frameRate); - sos.writeUI16(frameCount); - - sos.writeTags(tags); - if (hasEndTag) { - sos.writeUI16(0); - } - - sos.close(); - os.write(Utf8Helper.getBytes(getHeaderBytes(compression, gfx))); - os.write(version); - byte[] data = baos.toByteArray(); - sos = new SWFOutputStream(os, version); - sos.writeUI32(data.length + 8); - - if (compression == SWFCompression.LZMA || compression == SWFCompression.LZMA_ABC) { - long uncompressedLength = data.length; - Encoder enc = new Encoder(); - int val = lzmaProperties[0] & 0xFF; - int lc = val % 9; - int remainder = val / 9; - int lp = remainder % 5; - int pb = remainder / 5; - int dictionarySize = 0; - for (int i = 0; i < 4; i++) { - dictionarySize += ((int) (lzmaProperties[1 + i]) & 0xFF) << (i * 8); - } - if (Configuration.lzmaFastBytes.get() > 0) { - enc.SetNumFastBytes(Configuration.lzmaFastBytes.get()); - } - enc.SetDictionarySize(dictionarySize); - enc.SetLcLpPb(lc, lp, pb); - baos = new ByteArrayOutputStream(); - enc.SetEndMarkerMode(true); - enc.Code(new ByteArrayInputStream(data), baos, -1, -1, null); - data = baos.toByteArray(); - if (compression == SWFCompression.LZMA) { - byte[] udata = new byte[4]; - udata[0] = (byte) (data.length & 0xFF); - udata[1] = (byte) ((data.length >> 8) & 0xFF); - udata[2] = (byte) ((data.length >> 16) & 0xFF); - udata[3] = (byte) ((data.length >> 24) & 0xFF); - os.write(udata); - } - enc.WriteCoderProperties(os); - if (compression == SWFCompression.LZMA_ABC) { - byte[] udata = new byte[8]; - udata[0] = (byte) (uncompressedLength & 0xFF); - udata[1] = (byte) ((uncompressedLength >> 8) & 0xFF); - udata[2] = (byte) ((uncompressedLength >> 16) & 0xFF); - udata[3] = (byte) ((uncompressedLength >> 24) & 0xFF); - udata[4] = (byte) ((uncompressedLength >> 32) & 0xFF); - udata[5] = (byte) ((uncompressedLength >> 40) & 0xFF); - udata[6] = (byte) ((uncompressedLength >> 48) & 0xFF); - udata[7] = (byte) ((uncompressedLength >> 56) & 0xFF); - os.write(udata); - } - } else if (compression == SWFCompression.ZLIB) { - os = new DeflaterOutputStream(os); - } - - os.write(data); - } finally { - if (os != null) { - os.close(); - } - } - } - - public boolean isModified() { - for (Tag tag : tags) { - if (tag.isModified()) { - return true; - } - } - return false; - } - - public void clearModified() { - for (Tag tag : tags) { - if (tag.isModified()) { - tag.createOriginalData(); - tag.setModified(false); - } - } - - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try { - saveTo(baos, SWFCompression.NONE); - byte[] swfData = baos.toByteArray(); - uncompressedData = swfData; - } catch (IOException ex) { - logger.log(Level.SEVERE, "Cannot save SWF", ex); - } - } - - /** - * Constructs an empty SWF - */ - public SWF() { - - } - - /** - * Construct SWF from stream - * - * @param is Stream to read SWF from - * @param parallelRead Use parallel threads? - * @throws IOException - * @throws java.lang.InterruptedException - */ - public SWF(InputStream is, boolean parallelRead) throws IOException, InterruptedException { - this(is, null, null, null, parallelRead, false, true); - } - - /** - * Construct SWF from stream - * - * @param is Stream to read SWF from - * @param parallelRead Use parallel threads? - * @param lazy - * @throws IOException - * @throws java.lang.InterruptedException - */ - public SWF(InputStream is, boolean parallelRead, boolean lazy) throws IOException, InterruptedException { - this(is, null, null, null, parallelRead, false, lazy); - } - - /** - * Construct SWF from stream - * - * @param is Stream to read SWF from - * @param file Path to the file - * @param fileTitle Title of the SWF - * @param parallelRead Use parallel threads? - * @throws IOException - * @throws java.lang.InterruptedException - */ - public SWF(InputStream is, String file, String fileTitle, boolean parallelRead) throws IOException, InterruptedException { - this(is, file, fileTitle, null, parallelRead, false, true); - } - - /** - * Construct SWF from stream - * - * @param is Stream to read SWF from - * @param listener - * @param parallelRead Use parallel threads? - * @throws IOException - * @throws java.lang.InterruptedException - */ - public SWF(InputStream is, ProgressListener listener, boolean parallelRead) throws IOException, InterruptedException { - this(is, null, null, listener, parallelRead, false, true); - } - - /** - * Construct SWF from stream - * - * @param is Stream to read SWF from - * @param file Path to the file - * @param fileTitle Title of the SWF - * @param listener - * @param parallelRead Use parallel threads? - * @throws IOException - * @throws java.lang.InterruptedException - */ - public SWF(InputStream is, String file, String fileTitle, ProgressListener listener, boolean parallelRead) throws IOException, InterruptedException { - this(is, file, fileTitle, listener, parallelRead, false, true); - } - - /** - * Faster constructor to check SWF only - * - * @param is - * @throws java.io.IOException - */ - public SWF(InputStream is) throws IOException { - decompress(is, new NulStream(), true); - } - - /** - * Construct SWF from stream - * - * @param is Stream to read SWF from - * @param file Path to the file - * @param fileTitle Title of the SWF - * @param listener - * @param parallelRead Use parallel threads? - * @param checkOnly Check only file validity - * @param lazy - * @throws IOException - * @throws java.lang.InterruptedException - */ - public SWF(InputStream is, String file, String fileTitle, ProgressListener listener, boolean parallelRead, boolean checkOnly, boolean lazy) throws IOException, InterruptedException { - this.file = file; - this.fileTitle = fileTitle; - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - SWFHeader header = decompress(is, baos, true); - gfx = header.gfx; - compression = header.compression; - lzmaProperties = header.lzmaProperties; - uncompressedData = baos.toByteArray(); - originalUncompressedData = uncompressedData; - - SWFInputStream sis = new SWFInputStream(this, uncompressedData); - dumpInfo = new DumpInfoSwfNode(this, "rootswf", "", null, 0, 0); - sis.dumpInfo = dumpInfo; - sis.readBytesEx(3, "signature"); // skip siganture - version = sis.readUI8("version"); - fileSize = sis.readUI32("fileSize"); - dumpInfo.lengthBytes = fileSize; - if (listener != null) { - sis.addPercentListener(listener); - } - sis.setPercentMax(fileSize); - displayRect = sis.readRECT("displayRect"); - // FIXED8 (16 bit fixed point) frameRate - sis.readUI8("tmpFirstByetOfFrameRate"); // tmpFirstByetOfFrameRate - frameRate = sis.readUI8("frameRate"); - frameCount = sis.readUI16("frameCount"); - List tags = sis.readTagList(this, 0, parallelRead, true, !checkOnly, lazy); - if (tags.size() > 0 && tags.get(tags.size() - 1).getId() == EndTag.ID) { - tags.remove(tags.size() - 1); - } else { - hasEndTag = false; - } - this.tags = tags; - if (!checkOnly) { - checkInvalidSprites(); - updateCharacters(); - assignExportNamesToSymbols(); - assignClassesToSymbols(); - SWFDecompilerPlugin.fireSwfParsed(this); - } else { - boolean hasNonUnknownTag = false; - for (Tag tag : tags) { - if (tag.getOriginalDataLength() > 0 && Tag.getRequiredTags().contains(tag.getId())) { - hasNonUnknownTag = true; - } - } - if (!hasNonUnknownTag) { - throw new IOException("Invalid SWF file. No known tag found."); - } - } - - /*preload shape tags - for (Tag tag : tags) { - if (tag instanceof ShapeTag) { - ((ShapeTag) tag).getShapes(); - } - }*/ - } - - @Override - public SWF getSwf() { - return this; - } - - public SWF getRootSwf() { - SWF result = this; - while (result.binaryData != null) { - result = result.binaryData.getSwf(); - } - - return result; - } - - public String getFile() { - return file; - } - - /** - * Get title of the file - * - * @return file title - */ - public String getFileTitle() { - if (fileTitle != null) { - return fileTitle; - } - return file; - } - - public String getShortFileName() { - String title = getFileTitle(); - if (title == null) { - return ""; - } - return new File(title).getName(); - } - - public void setFile(String file) { - this.file = file; - fileTitle = null; - } - - private static void getAbcTags(List list, List actionScripts) { - for (Tag t : list) { - if (t instanceof DefineSpriteTag) { - getAbcTags(((DefineSpriteTag) t).getSubTags(), actionScripts); - } - if (t instanceof ABCContainerTag) { - actionScripts.add((ABCContainerTag) t); - } - } - } - - public void assignExportNamesToSymbols() { - HashMap exportNames = new HashMap<>(); - for (Tag t : tags) { - if (t instanceof ExportAssetsTag) { - ExportAssetsTag eat = (ExportAssetsTag) t; - for (int i = 0; i < eat.tags.size(); i++) { - Integer tagId = eat.tags.get(i); - String name = eat.names.get(i); - if ((!exportNames.containsKey(tagId)) && (!exportNames.containsValue(name))) { - exportNames.put(tagId, name); - } - } - } - } - for (Tag t : tags) { - if (t instanceof CharacterTag) { - CharacterTag ct = (CharacterTag) t; - if (exportNames.containsKey(ct.getCharacterId())) { - ct.setExportName(exportNames.get(ct.getCharacterId())); - } - } - } - } - - public void assignClassesToSymbols() { - HashMap classes = new HashMap<>(); - for (Tag t : tags) { - if (t instanceof SymbolClassTag) { - SymbolClassTag sct = (SymbolClassTag) t; - for (int i = 0; i < sct.tags.size(); i++) { - if ((!classes.containsKey(sct.tags.get(i))) && (!classes.containsValue(sct.names.get(i)))) { - classes.put(sct.tags.get(i), sct.names.get(i)); - } - } - } - } - for (Tag t : tags) { - if (t instanceof CharacterTag) { - CharacterTag ct = (CharacterTag) t; - if (classes.containsKey(ct.getCharacterId())) { - ct.setClassName(classes.get(ct.getCharacterId())); - } - } - } - } - - /** - * Compress SWF file - * - * @param fis Input stream - * @param fos Output stream - * @return True on success - */ - public static boolean fws2cws(InputStream fis, OutputStream fos) { - try { - byte[] swfHead = new byte[8]; - fis.read(swfHead); - - if (swfHead[0] != 'F') { - fis.close(); - return false; - } - swfHead[0] = 'C'; - fos.write(swfHead); - fos = new DeflaterOutputStream(fos); - int i; - while ((i = fis.read()) != -1) { - fos.write(i); - } - - fis.close(); - fos.close(); - } catch (IOException ex) { - return false; - } - return true; - } - - public static boolean decompress(InputStream fis, OutputStream fos) { - try { - decompress(fis, fos, false); - return true; - } catch (IOException ex) { - return false; - } - } - - private static void decodeLZMAStream(InputStream is, OutputStream os, byte[] lzmaProperties, long fileSize) throws IOException { - Decoder decoder = new Decoder(); - if (!decoder.SetDecoderProperties(lzmaProperties)) { - throw new IOException("LZMA:Incorrect stream properties"); - } - if (!decoder.Code(is, os, fileSize - 8)) { - throw new IOException("LZMA:Error in data stream"); - } - } - - private static SWFHeader decompress(InputStream is, OutputStream os, boolean allowUncompressed) throws IOException { - byte[] hdr = new byte[8]; - - // SWFheader: signature, version and fileSize - if (is.read(hdr) != 8) { - throw new IOException("SWF header is too short"); - } - - String signature = new String(hdr, 0, 3, Utf8Helper.charset); - if (!Arrays.asList( - "FWS", // Uncompressed Flash - "CWS", // ZLib compressed Flash - "ZWS", // LZMA compressed Flash - "GFX", // Uncompressed ScaleForm GFx - "CFX", // Compressed ScaleForm GFx - "ABC" // Non-standard LZMA compressed Flash - ).contains(signature)) { - throw new IOException("Invalid SWF file"); - } - - int version = hdr[3]; - SWFInputStream sis = new SWFInputStream(null, Arrays.copyOfRange(hdr, 4, 8), 4, 4); - long fileSize = sis.readUI32("fileSize"); - SWFHeader header = new SWFHeader(); - header.version = version; - header.fileSize = fileSize; - - if (hdr[1] == 'F' && hdr[2] == 'X') { - header.gfx = true; - } - - try (SWFOutputStream sos = new SWFOutputStream(os, version)) { - sos.write(Utf8Helper.getBytes(header.gfx ? "GFX" : "FWS")); - sos.writeUI8(version); - sos.writeUI32(fileSize); - - switch (hdr[0]) { - case 'C': { // CWS, CFX - Helper.copyStream(new InflaterInputStream(is), os, fileSize - 8); - header.compression = SWFCompression.ZLIB; - break; - } - case 'Z': { // ZWS - byte[] lzmaprop = new byte[9]; - is.read(lzmaprop); - sis = new SWFInputStream(null, lzmaprop); - sis.readUI32("LZMAsize"); // compressed LZMA data size = compressed SWF - 17 byte, - // where 17 = 8 byte header + this 4 byte + 5 bytes decoder properties - int propertiesSize = 5; - byte[] lzmaProperties = sis.readBytes(propertiesSize, "lzmaproperties"); - if (lzmaProperties.length != propertiesSize) { - throw new IOException("LZMA:input .lzma file is too short"); - } - - decodeLZMAStream(is, os, lzmaProperties, fileSize); - - header.compression = SWFCompression.LZMA; - header.lzmaProperties = lzmaProperties; - break; - } - case 'A': { // ABC - byte[] lzmaProperties = new byte[5]; - is.read(lzmaProperties); - byte[] uncompressedLength = new byte[8]; - is.read(uncompressedLength); - - decodeLZMAStream(is, os, lzmaProperties, fileSize); - - header.compression = SWFCompression.LZMA_ABC; - header.lzmaProperties = lzmaProperties; - break; - } - default: { // FWS, GFX - if (allowUncompressed) { - Helper.copyStream(is, os, fileSize - 8); - } else { - throw new IOException("SWF is not compressed"); - } - } - } - - return header; - } - } - - public static boolean renameInvalidIdentifiers(RenameType renameType, InputStream fis, OutputStream fos) { - try { - SWF swf = new SWF(fis, Configuration.parallelSpeedUp.get()); - int cnt = swf.deobfuscateIdentifiers(renameType); - swf.assignClassesToSymbols(); - System.out.println(cnt + " identifiers renamed."); - swf.saveTo(fos); - } catch (InterruptedException ex) { - return false; - } catch (IOException ex) { - return false; - } - return true; - } - - public boolean exportAS3Class(String className, String outdir, ScriptExportSettings exportSettings, boolean parallel, EventListener evl) throws Exception { - boolean exported = false; - - List abcList = getAbcList(); - for (int i = 0; i < abcList.size(); i++) { - ABC abc = abcList.get(i).getABC(); - List scrs = abc.findScriptPacksByPath(className); - for (int j = 0; j < scrs.size(); j++) { - ScriptPack scr = scrs.get(j); - String cnt = ""; - if (scrs.size() > 1) { - cnt = "script " + (j + 1) + "/" + scrs.size() + " "; - } - String eventData = cnt + scr.getPath() + " ..."; - evl.handleExportingEvent("tag", i + 1, abcList.size(), eventData); - scr.export(outdir, exportSettings, parallel); - evl.handleExportedEvent("tag", i + 1, abcList.size(), eventData); - exported = true; - } - } - return exported; - } - - private List uniqueAS3Packs(List packs) { - List ret = new ArrayList<>(); - Set classPaths = new HashSet<>(); - for (ScriptPack item : packs) { - ClassPath key = item.getClassPath(); - if (classPaths.contains(key)) { - logger.log(Level.SEVERE, "Duplicate pack path found (" + key + ")!"); - } else { - classPaths.add(key); - ret.add(item); - } - } - return ret; - } - - public List getAS3Packs() { - List packs = new ArrayList<>(); - for (ABCContainerTag abcTag : getAbcList()) { - packs.addAll(abcTag.getABC().getScriptPacks(null)); - } - return uniqueAS3Packs(packs); - } - - @Override - public RECT getRect() { - return displayRect; - } - - @Override - public RECT getRect(Set added) { - return displayRect; - } - - public EventListener getExportEventListener() { - EventListener evl = new EventListener() { - @Override - public void handleExportingEvent(String type, int index, int count, Object data) { - for (EventListener listener : listeners) { - listener.handleExportingEvent(type, index, count, data); - } - } - - @Override - public void handleExportedEvent(String type, int index, int count, Object data) { - for (EventListener listener : listeners) { - listener.handleExportedEvent(type, index, count, data); - } - } - - @Override - public void handleEvent(String event, Object data) { - informListeners(event, data); - } - }; - - return evl; - } - - public List exportActionScript(AbortRetryIgnoreHandler handler, String outdir, ScriptExportSettings exportSettings, boolean parallel, EventListener evl) throws IOException { - List ret = new ArrayList<>(); - - if (isAS3()) { - ret.addAll(new AS3ScriptExporter().exportActionScript3(this, handler, outdir, exportSettings, parallel, evl)); - } else { - ret.addAll(new AS2ScriptExporter().exportAS2ScriptsTimeout(handler, outdir, getASMs(true), exportSettings, evl)); - } - return ret; - } - - public Map getASMs(boolean exportFileNames) { - return getASMs(exportFileNames, new ArrayList(), true); - } - - public Map getASMs(boolean exportFileNames, List nodesToExport, boolean exportAll) { - Map asmsToExport = new HashMap<>(); - for (TreeItem treeItem : getFirstLevelASMNodes(null)) { - getASMs(exportFileNames, treeItem, nodesToExport, exportAll, asmsToExport, File.separator + getASMPath(exportFileNames, treeItem)); - } - - return asmsToExport; - } - - private void getASMs(boolean exportFileNames, TreeItem treeItem, List nodesToExport, boolean exportAll, Map asmsToExport, String path) { - boolean exportNode = nodesToExport.contains(treeItem); - TreeItem realItem = treeItem instanceof TagScript ? ((TagScript) treeItem).getTag() : treeItem; - if (realItem instanceof ASMSource && (exportAll || exportNode)) { - String npath = path; - int ppos = 1; - while (asmsToExport.containsKey(npath)) { - ppos++; - npath = path + (exportFileNames ? "[" + ppos + "]" : "_" + ppos); - } - asmsToExport.put(npath, (ASMSource) realItem); - } - - if (treeItem instanceof TagScript) { - TagScript tagScript = (TagScript) treeItem; - for (TreeItem subItem : tagScript.getFrames()) { - getASMs(exportFileNames, subItem, nodesToExport, exportAll, asmsToExport, path + File.separator + getASMPath(exportFileNames, subItem)); - } - } else if (treeItem instanceof FrameScript) { - FrameScript frameScript = (FrameScript) treeItem; - Frame parentFrame = frameScript.getFrame(); - for (TreeItem subItem : parentFrame.actionContainers) { - getASMs(exportFileNames, getASMWrapToTagScript(subItem), nodesToExport, exportAll || exportNode, asmsToExport, path + File.separator + getASMPath(exportFileNames, subItem)); - } - for (TreeItem subItem : parentFrame.actions) { - getASMs(exportFileNames, getASMWrapToTagScript(subItem), nodesToExport, exportAll || exportNode, asmsToExport, path + File.separator + getASMPath(exportFileNames, subItem)); - } - } else if (treeItem instanceof AS2Package) { - AS2Package as2Package = (AS2Package) treeItem; - for (TreeItem subItem : as2Package.subPackages.values()) { - getASMs(exportFileNames, subItem, nodesToExport, exportAll, asmsToExport, path + File.separator + getASMPath(exportFileNames, subItem)); - } - for (TreeItem subItem : as2Package.scripts.values()) { - getASMs(exportFileNames, subItem, nodesToExport, exportAll, asmsToExport, path + File.separator + getASMPath(exportFileNames, subItem)); - } - } - } - - private String getASMPath(boolean exportFileName, TreeItem treeItem) { - if (!exportFileName) { - return treeItem.toString(); - } - - String result; - if (treeItem instanceof Exportable) { - result = ((Exportable) treeItem).getExportFileName(); - } else { - result = treeItem.toString(); - } - - return Helper.makeFileName(result); - } - - private TreeItem getASMWrapToTagScript(TreeItem treeItem) { - if (treeItem instanceof Tag) { - Tag resultTag = (Tag) treeItem; - List subNodes = new ArrayList<>(); - if (treeItem instanceof ASMSourceContainer) { - for (ASMSource item : ((ASMSourceContainer) treeItem).getSubItems()) { - subNodes.add(item); - } - } - - TagScript tagScript = new TagScript(treeItem.getSwf(), resultTag, subNodes); - return tagScript; - } - - return treeItem; - } - - public List getFirstLevelASMNodes(Map tagScriptCache) { - Timeline timeline = getTimeline(); - List subNodes = new ArrayList<>(); - List subFrames = new ArrayList<>(); - subNodes.addAll(timeline.getAS2RootPackage().subPackages.values()); - subNodes.addAll(timeline.getAS2RootPackage().scripts.values()); - - for (Tag tag : timeline.otherTags) { - boolean hasInnerFrames = false; - List tagSubNodes = new ArrayList<>(); - if (tag instanceof Timelined) { - Timeline timeline2 = ((Timelined) tag).getTimeline(); - for (Frame frame : timeline2.getFrames()) { - if (!frame.actions.isEmpty() || !frame.actionContainers.isEmpty()) { - FrameScript frameScript = new FrameScript(this, frame); - tagSubNodes.add(frameScript); - hasInnerFrames = true; - } - } - } - - if (tag instanceof ASMSourceContainer) { - for (ASMSource asm : ((ASMSourceContainer) tag).getSubItems()) { - tagSubNodes.add(asm); - } - } - - if (!tagSubNodes.isEmpty()) { - TagScript ts = new TagScript(this, tag, tagSubNodes); - if (tagScriptCache != null) { - tagScriptCache.put(tag, ts); - } - if (hasInnerFrames) { - subFrames.add(ts); - } else { - subNodes.add(ts); - } - } - } - - subNodes.addAll(subFrames); - for (Frame frame : timeline.getFrames()) { - if (!frame.actions.isEmpty() || !frame.actionContainers.isEmpty()) { - FrameScript frameScript = new FrameScript(this, frame); - subNodes.add(frameScript); - } - } - - return subNodes; - } - - private final HashSet listeners = new HashSet<>(); - - public final void addEventListener(EventListener listener) { - listeners.add(listener); - for (Tag t : tags) { - if (t instanceof ABCContainerTag) { - (((ABCContainerTag) t).getABC()).addEventListener(listener); - } - } - } - - public final void removeEventListener(EventListener listener) { - listeners.remove(listener); - for (Tag t : tags) { - if (t instanceof ABCContainerTag) { - (((ABCContainerTag) t).getABC()).removeEventListener(listener); - } - } - } - - protected void informListeners(String event, Object data) { - for (EventListener listener : listeners) { - listener.handleEvent(event, data); - } - } - - public static boolean hasErrorHeader(byte[] data) { - return hasErrorHeader(new ByteArrayRange(data)); - } - - public static boolean hasErrorHeader(ByteArrayRange data) { - if (data.getLength() > 4) { - if ((data.get(0) & 0xff) == 0xff && (data.get(1) & 0xff) == 0xd9 - && (data.get(2) & 0xff) == 0xff && (data.get(3) & 0xff) == 0xd8) { - return true; - } - } - return false; - } - - public static void populateVideoFrames(int streamId, List tags, HashMap output) { - for (Tag t : tags) { - if (t instanceof VideoFrameTag) { - output.put(((VideoFrameTag) t).frameNum, (VideoFrameTag) t); - } - if (t instanceof DefineSpriteTag) { - populateVideoFrames(streamId, ((DefineSpriteTag) t).getSubTags(), output); - } - } - } - - private static void writeLE(OutputStream os, long val, int size) throws IOException { - for (int i = 0; i < size; i++) { - os.write((int) (val & 0xff)); - val >>= 8; - } - } - - public static void createWavFromPcmData(OutputStream fos, int soundRateHz, boolean soundSize, boolean soundType, byte[] data) throws IOException { - ByteArrayOutputStream subChunk1Data = new ByteArrayOutputStream(); - int audioFormat = 1; // PCM - writeLE(subChunk1Data, audioFormat, 2); - int numChannels = soundType ? 2 : 1; - writeLE(subChunk1Data, numChannels, 2); - int[] rateMap = {5512, 11025, 22050, 44100}; - int sampleRate = soundRateHz; // rateMap[soundRate]; - writeLE(subChunk1Data, sampleRate, 4); - int bitsPerSample = soundSize ? 16 : 8; - int byteRate = sampleRate * numChannels * bitsPerSample / 8; - writeLE(subChunk1Data, byteRate, 4); - int blockAlign = numChannels * bitsPerSample / 8; - writeLE(subChunk1Data, blockAlign, 2); - writeLE(subChunk1Data, bitsPerSample, 2); - - ByteArrayOutputStream chunks = new ByteArrayOutputStream(); - chunks.write(Utf8Helper.getBytes("fmt ")); - byte[] subChunk1DataBytes = subChunk1Data.toByteArray(); - writeLE(chunks, subChunk1DataBytes.length, 4); - chunks.write(subChunk1DataBytes); - - chunks.write(Utf8Helper.getBytes("data")); - writeLE(chunks, data.length, 4); - chunks.write(data); - - fos.write(Utf8Helper.getBytes("RIFF")); - byte[] chunkBytes = chunks.toByteArray(); - writeLE(fos, 4 + chunkBytes.length, 4); - fos.write(Utf8Helper.getBytes("WAVE")); - fos.write(chunkBytes); - } - - public static String getTypePrefix(CharacterTag c) { - if (c instanceof ShapeTag) { - return "shape"; - } - if (c instanceof MorphShapeTag) { - return "morphshape"; - } - if (c instanceof DefineSpriteTag) { - return "sprite"; - } - if (c instanceof TextTag) { - return "text"; - } - if (c instanceof ButtonTag) { - return "button"; - } - if (c instanceof FontTag) { - return "font"; - } - if (c instanceof ImageTag) { - return "image"; - } - return "character"; - } - - public static void writeLibrary(SWF fswf, Set library, OutputStream fos) throws IOException { - for (int c : library) { - CharacterTag ch = fswf.getCharacter(c); - if (ch instanceof FontTag) { - fos.write(Utf8Helper.getBytes("function " + getTypePrefix(ch) + c + "(ctx,ch,textColor){\r\n")); - fos.write(Utf8Helper.getBytes(((FontTag) ch).toHtmlCanvas(1))); - fos.write(Utf8Helper.getBytes("}\r\n\r\n")); - } else { - if (ch instanceof ImageTag) { - ImageTag image = (ImageTag) ch; - String format = image.getImageFormat(); - InputStream imageStream = image.getImageData(); - byte[] imageData; - if (imageStream != null) { - imageData = Helper.readStream(image.getImageData()); - } else { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ImageHelper.write(image.getImage().getBufferedImage(), format.toUpperCase(Locale.ENGLISH), baos); - imageData = baos.toByteArray(); - } - String base64ImgData = Helper.byteArrayToBase64String(imageData); - fos.write(Utf8Helper.getBytes("var imageObj" + c + " = document.createElement(\"img\");\r\nimageObj" + c + ".src=\"data:image/" + format + ";base64," + base64ImgData + "\";\r\n")); - } - fos.write(Utf8Helper.getBytes("function " + getTypePrefix(ch) + c + "(ctx,ctrans,frame,ratio,time){\r\n")); - if (ch instanceof DrawableTag) { - fos.write(Utf8Helper.getBytes(((DrawableTag) ch).toHtmlCanvas(1))); - } - fos.write(Utf8Helper.getBytes("}\r\n\r\n")); - } - } - } - - private static void getVariables(ConstantPool constantPool, BaseLocalData localData, TranslateStack stack, List output, ActionGraphSource code, int ip, List> variables, List functions, HashMap strings, List visited, HashMap usageTypes, String path) throws InterruptedException { - boolean debugMode = false; - while ((ip > -1) && ip < code.size()) { - if (visited.contains(ip)) { - break; - } - GraphSourceItem ins = code.get(ip); - - if (debugMode) { - System.err.println("Visit " + ip + ": ofs" + Helper.formatAddress(((Action) ins).getAddress()) + ":" + ((Action) ins).getASMSource(new ActionList(), new HashSet(), ScriptExportMode.PCODE) + " stack:" + Helper.stackToString(stack, LocalData.create(new ConstantPool()))); - } - if (ins.isExit()) { - break; - } - if (ins.isIgnored()) { - ip++; - continue; - } - - String usageType = "name"; - GraphTargetItem name = null; - if ((ins instanceof ActionGetVariable) - || (ins instanceof ActionGetMember) - || (ins instanceof ActionDefineLocal2) - || (ins instanceof ActionNewMethod) - || (ins instanceof ActionNewObject) - || (ins instanceof ActionCallMethod) - || (ins instanceof ActionCallFunction)) { - if (stack.isEmpty()) { - break; - } - name = stack.peek(); - } - - if ((ins instanceof ActionGetVariable) || (ins instanceof ActionDefineLocal2)) { - usageType = "variable"; - } - if (ins instanceof ActionGetMember) { - usageType = "member"; - } - if ((ins instanceof ActionNewMethod) || (ins instanceof ActionNewObject)) { - usageType = "class"; - } - if (ins instanceof ActionCallMethod) { - usageType = "function"; // can there be method? - } - if (ins instanceof ActionCallFunction) { - usageType = "function"; - } - - if ((ins instanceof ActionDefineFunction) || (ins instanceof ActionDefineFunction2)) { - functions.add(ins); - } - - if (ins instanceof GraphSourceItemContainer) { - GraphSourceItemContainer cnt = (GraphSourceItemContainer) ins; - List cntSizes = cnt.getContainerSizes(); - long addr = code.pos2adr(ip + 1); - ip = code.adr2pos(addr); - String cntName = cnt.getName(); - for (Long size : cntSizes) { - if (size == 0) { - continue; - } - ip = code.adr2pos(addr); - addr += size; - int nextip = code.adr2pos(addr); - getVariables(variables, functions, strings, usageTypes, new ActionGraphSource(code.getActions().subList(ip, nextip), code.version, new HashMap(), new HashMap(), new HashMap()), 0, path + (cntName == null ? "" : "/" + cntName)); - ip = nextip; - } - List> r = new ArrayList<>(); - r.add(new ArrayList()); - r.add(new ArrayList()); - r.add(new ArrayList()); - try { - ((GraphSourceItemContainer) ins).translateContainer(r, stack, output, new HashMap(), new HashMap(), new HashMap()); - } catch (EmptyStackException ex) { - } - - continue; - } - - if ((ins instanceof ActionSetVariable) || (ins instanceof ActionSetMember) || (ins instanceof ActionDefineLocal)) { - if (stack.size() < 2) { - break; - } - name = stack.get(stack.size() - 2); - } - - if ((ins instanceof ActionSetVariable) || (ins instanceof ActionDefineLocal)) { - usageType = "variable"; - } - - if (ins instanceof ActionSetMember) { - usageType = "member"; - } - - if (name instanceof DirectValueActionItem) { - variables.add(new MyEntry<>((DirectValueActionItem) name, constantPool)); - usageTypes.put((DirectValueActionItem) name, usageType); - } - - // for..in return - if (((ins instanceof ActionEquals) || (ins instanceof ActionEquals2)) && (stack.size() == 1) && (stack.peek() instanceof DirectValueActionItem)) { - stack.push(new DirectValueActionItem(null, 0, new Null(), new ArrayList())); - } - - if (ins instanceof ActionConstantPool) { - constantPool = new ConstantPool(((ActionConstantPool) ins).constantPool); - } - int staticOperation = Graph.SOP_USE_STATIC; //(Boolean) Configuration.getConfig("autoDeobfuscate", true) ? Graph.SOP_SKIP_STATIC : Graph.SOP_USE_STATIC; - - try { - ins.translate(localData, stack, output, staticOperation, path); - } catch (EmptyStackException ex) { - // probably obfucated code, never executed branch - break; - } - if (ins.isExit()) { - break; - } - - if (ins instanceof ActionPush) { - if (!stack.isEmpty()) { - GraphTargetItem top = stack.peek(); - if (top instanceof DirectValueActionItem) { - DirectValueActionItem dvt = (DirectValueActionItem) top; - if ((dvt.value instanceof String) || (dvt.value instanceof ConstantIndex)) { - if (constantPool == null) { - constantPool = new ConstantPool(dvt.constants); - } - strings.put(dvt, constantPool); - } - } - } - } - - if (ins.isBranch() || ins.isJump()) { - if (ins instanceof ActionIf) { - if (stack.isEmpty()) { - break; - } - stack.pop(); - } - visited.add(ip); - List branches = ins.getBranches(code); - for (int b : branches) { - TranslateStack brStack = (TranslateStack) stack.clone(); - if (b >= 0) { - getVariables(constantPool, localData, brStack, output, code, b, variables, functions, strings, visited, usageTypes, path); - } else { - if (debugMode) { - System.out.println("Negative branch:" + b); - } - } - } - // } - break; - } - ip++; - }; - } - - private static void getVariables(List> variables, List functions, HashMap strings, HashMap usageTypes, ActionGraphSource code, int addr, String path) throws InterruptedException { - ActionLocalData localData = new ActionLocalData(); - getVariables(null, localData, new TranslateStack(), new ArrayList(), code, code.adr2pos(addr), variables, functions, strings, new ArrayList(), usageTypes, path); - } - - private List> getVariables(List> variables, HashMap actionsMap, List functions, HashMap strings, HashMap usageTypes, ASMSource src, String path) throws InterruptedException { - List> ret = new ArrayList<>(); - ActionList actions = src.getActions(); - actionsMap.put(src, actions); - getVariables(variables, functions, strings, usageTypes, new ActionGraphSource(actions, version, new HashMap(), new HashMap(), new HashMap()), 0, path); - return ret; - } - - private void getVariables(List tags, String path, List> variables, HashMap actionsMap, List functions, HashMap strings, HashMap usageTypes) throws InterruptedException { - List processed = new ArrayList<>(); - for (Tag t : tags) { - String subPath = path + "/" + t.toString(); - if (t instanceof ASMSource) { - addVariable((ASMSource) t, subPath, processed, variables, actionsMap, functions, strings, usageTypes); - } - if (t instanceof ASMSourceContainer) { - List processed2 = new ArrayList<>(); - for (ASMSource asm : ((ASMSourceContainer) t).getSubItems()) { - addVariable(asm, subPath + "/" + asm.toString(), processed2, variables, actionsMap, functions, strings, usageTypes); - } - } - if (t instanceof DefineSpriteTag) { - getVariables(((DefineSpriteTag) t).getSubTags(), path + "/" + t.toString(), variables, actionsMap, functions, strings, usageTypes); - } - } - } - - private void addVariable(ASMSource asm, String path, List processed, List> variables, HashMap actionsMap, List functions, HashMap strings, HashMap usageTypes) throws InterruptedException { - int pos = 1; - String infPath2 = path; - while (processed.contains(infPath2)) { - pos++; - infPath2 = path + "[" + pos + "]"; - } - processed.add(infPath2); - informListeners("getVariables", infPath2); - getVariables(variables, actionsMap, functions, strings, usageTypes, asm, path); - } - - public void fixAS3Code() { - for (ABCContainerTag abcTag : getAbcList()) { - ABC abc = abcTag.getABC(); - for (MethodBody body : abc.bodies) { - AVM2Code code = body.getCode(); - } - - ((Tag) abcTag).setModified(true); - } - } - - public int deobfuscateAS3Identifiers(RenameType renameType) { - for (Tag tag : tags) { - if (tag instanceof ABCContainerTag) { - ((ABCContainerTag) tag).getABC().deobfuscateIdentifiers(deobfuscated, renameType, true); - tag.setModified(true); - } - } - for (Tag tag : tags) { - if (tag instanceof ABCContainerTag) { - ((ABCContainerTag) tag).getABC().deobfuscateIdentifiers(deobfuscated, renameType, false); - tag.setModified(true); - } - } - for (Tag tag : tags) { - if (tag instanceof SymbolClassTag) { - SymbolClassTag sc = (SymbolClassTag) tag; - for (int i = 0; i < sc.names.size(); i++) { - String newname = deobfuscation.deobfuscateNameWithPackage(true, sc.names.get(i), deobfuscated, renameType, deobfuscated); - if (newname != null) { - sc.names.set(i, newname); - } - } - sc.setModified(true); - } - } - deobfuscation.deobfuscateInstanceNames(true, deobfuscated, renameType, tags, new HashMap()); - return deobfuscated.size(); - } - - public int deobfuscateIdentifiers(RenameType renameType) throws InterruptedException { - FileAttributesTag fileAttributes = getFileAttributes(); - if (fileAttributes == null) { - int cnt = 0; - cnt += deobfuscateAS2Identifiers(renameType); - cnt += deobfuscateAS3Identifiers(renameType); - return cnt; - } else { - if (fileAttributes.actionScript3) { - return deobfuscateAS3Identifiers(renameType); - } else { - return deobfuscateAS2Identifiers(renameType); - } - } - } - - public void renameAS2Identifier(String identifier, String newname) throws InterruptedException { - Map selected = new HashMap<>(); - selected.put(identifier, newname); - renameAS2Identifiers(null, selected); - } - - private int deobfuscateAS2Identifiers(RenameType renameType) throws InterruptedException { - return renameAS2Identifiers(renameType, null); - } - - private int renameAS2Identifiers(RenameType renameType, Map selected) throws InterruptedException { - HashMap actionsMap = new HashMap<>(); - List allFunctions = new ArrayList<>(); - List> allVariableNames = new ArrayList<>(); - HashMap allStrings = new HashMap<>(); - HashMap usageTypes = new HashMap<>(); - - int ret = 0; - getVariables(tags, "", allVariableNames, actionsMap, allFunctions, allStrings, usageTypes); - informListeners("rename", ""); - int fc = 0; - for (MyEntry it : allVariableNames) { - String name = it.getKey().toStringNoH(it.getValue()); - deobfuscation.allVariableNamesStr.add(name); - } - - informListeners("rename", "classes"); - int classCount = 0; - for (Tag t : tags) { - if (t instanceof DoInitActionTag) { - classCount++; - } - } - int cnt = 0; - for (Tag t : tags) { - if (t instanceof DoInitActionTag) { - cnt++; - informListeners("rename", "class " + cnt + "/" + classCount); - DoInitActionTag dia = (DoInitActionTag) t; - String exportName = getExportName(dia.spriteId); - exportName = exportName != null ? exportName : "_unk_"; - final String pkgPrefix = "__Packages."; - String[] classNameParts = null; - if (exportName.startsWith(pkgPrefix)) { - String className = exportName.substring(pkgPrefix.length()); - if (className.contains(".")) { - classNameParts = className.split("\\."); - } else { - classNameParts = new String[]{className}; - } - } - int staticOperation = Graph.SOP_USE_STATIC; //(Boolean) Configuration.getConfig("autoDeobfuscate", true) ? Graph.SOP_SKIP_STATIC : Graph.SOP_USE_STATIC; - List dec; - try { - dec = Action.actionsToTree(dia.getActions(), version, staticOperation, ""/*FIXME*/); - } catch (EmptyStackException ex) { - continue; - } - GraphTargetItem name = null; - for (GraphTargetItem it : dec) { - if (it instanceof ClassActionItem) { - ClassActionItem cti = (ClassActionItem) it; - List methods = new ArrayList<>(); - methods.addAll(cti.functions); - methods.addAll(cti.staticFunctions); - - for (GraphTargetItem gti : methods) { - if (gti instanceof FunctionActionItem) { - FunctionActionItem fun = (FunctionActionItem) gti; - if (fun.calculatedFunctionName instanceof DirectValueActionItem) { - DirectValueActionItem dvf = (DirectValueActionItem) fun.calculatedFunctionName; - String fname = dvf.toStringNoH(null); - String changed = deobfuscation.deobfuscateName(false, fname, false, "method", deobfuscated, renameType, selected); - if (changed != null) { - deobfuscated.put(fname, changed); - } - } - } - } - - List vars = new ArrayList<>(); - for (MyEntry item : cti.vars) { - vars.add(item.getKey()); - } - for (MyEntry item : cti.staticVars) { - vars.add(item.getKey()); - } - for (GraphTargetItem gti : vars) { - if (gti instanceof DirectValueActionItem) { - DirectValueActionItem dvf = (DirectValueActionItem) gti; - String vname = dvf.toStringNoH(null); - String changed = deobfuscation.deobfuscateName(false, vname, false, "attribute", deobfuscated, renameType, selected); - if (changed != null) { - deobfuscated.put(vname, changed); - } - } - } - - name = cti.className; - break; - } - if (it instanceof InterfaceActionItem) { - InterfaceActionItem ift = (InterfaceActionItem) it; - name = ift.name; - } - } - - if (name != null) { - int pos = 0; - while (name instanceof GetMemberActionItem) { - GetMemberActionItem mem = (GetMemberActionItem) name; - GraphTargetItem memberName = mem.memberName; - if (memberName instanceof DirectValueActionItem) { - DirectValueActionItem dvt = (DirectValueActionItem) memberName; - String nameStr = dvt.toStringNoH(null); - if (classNameParts != null) { - if (classNameParts.length - 1 - pos < 0) { - break; - } - } - String changedNameStr = nameStr; - if (classNameParts != null) { - changedNameStr = classNameParts[classNameParts.length - 1 - pos]; - } - String changedNameStr2 = deobfuscation.deobfuscateName(false, changedNameStr, pos == 0, pos == 0 ? "class" : "package", deobfuscated, renameType, selected); - if (changedNameStr2 != null) { - changedNameStr = changedNameStr2; - } - ret++; - deobfuscated.put(nameStr, changedNameStr); - pos++; - } - name = mem.object; - } - if (name instanceof GetVariableActionItem) { - GetVariableActionItem var = (GetVariableActionItem) name; - if (var.name instanceof DirectValueActionItem) { - DirectValueActionItem dvt = (DirectValueActionItem) var.name; - String nameStr = dvt.toStringNoH(null); - if (classNameParts != null) { - if (classNameParts.length - 1 - pos < 0) { - break; - } - } - String changedNameStr = nameStr; - if (classNameParts != null) { - changedNameStr = classNameParts[classNameParts.length - 1 - pos]; - } - String changedNameStr2 = deobfuscation.deobfuscateName(false, changedNameStr, pos == 0, pos == 0 ? "class" : "package", deobfuscated, renameType, selected); - if (changedNameStr2 != null) { - changedNameStr = changedNameStr2; - } - ret++; - deobfuscated.put(nameStr, changedNameStr); - pos++; - } - } - } - t.setModified(true); - } - } - - for (GraphSourceItem fun : allFunctions) { - fc++; - informListeners("rename", "function " + fc + "/" + allFunctions.size()); - if (fun instanceof ActionDefineFunction) { - ActionDefineFunction f = (ActionDefineFunction) fun; - if (f.functionName.isEmpty()) { // anonymous function, leave as is - continue; - } - String changed = deobfuscation.deobfuscateName(false, f.functionName, false, "function", deobfuscated, renameType, selected); - if (changed != null) { - f.replacedFunctionName = changed; - ret++; - } - } - if (fun instanceof ActionDefineFunction2) { - ActionDefineFunction2 f = (ActionDefineFunction2) fun; - if (f.functionName.isEmpty()) { // anonymous function, leave as is - continue; - } - String changed = deobfuscation.deobfuscateName(false, f.functionName, false, "function", deobfuscated, renameType, selected); - if (changed != null) { - f.replacedFunctionName = changed; - ret++; - } - } - } - - HashSet stringsNoVarH = new HashSet<>(); - List allVariableNamesDv = new ArrayList<>(); - for (MyEntry it : allVariableNames) { - allVariableNamesDv.add(it.getKey()); - } - for (DirectValueActionItem ti : allStrings.keySet()) { - if (!allVariableNamesDv.contains(ti)) { - stringsNoVarH.add(System.identityHashCode(allStrings.get(ti)) + "_" + ti.toStringNoH(allStrings.get(ti))); - } - } - - int vc = 0; - for (MyEntry it : allVariableNames) { - vc++; - String name = it.getKey().toStringNoH(it.getValue()); - String changed = deobfuscation.deobfuscateName(false, name, false, usageTypes.get(it.getKey()), deobfuscated, renameType, selected); - if (changed != null) { - boolean addNew = false; - String h = System.identityHashCode(it.getKey()) + "_" + name; - if (stringsNoVarH.contains(h)) { - addNew = true; - } - ActionPush pu = (ActionPush) it.getKey().src; - if (pu.replacement == null) { - pu.replacement = new ArrayList<>(); - pu.replacement.addAll(pu.values); - } - if (pu.replacement.get(it.getKey().pos) instanceof ConstantIndex) { - ConstantIndex ci = (ConstantIndex) pu.replacement.get(it.getKey().pos); - ConstantPool pool = it.getValue(); - if (pool == null) { - continue; - } - if (pool.constants == null) { - continue; - } - if (addNew) { - pool.constants.add(changed); - ci.index = pool.constants.size() - 1; - } else { - pool.constants.set(ci.index, changed); - } - } else { - pu.replacement.set(it.getKey().pos, changed); - } - ret++; - } - } - - for (ASMSource src : actionsMap.keySet()) { - actionsMap.get(src).removeNops(); - src.setActions(actionsMap.get(src)); - src.setModified(); - } - - deobfuscation.deobfuscateInstanceNames(false, deobfuscated, renameType, tags, selected); - return ret; - } - - public void exportFla(AbortRetryIgnoreHandler handler, String outfile, String swfName, String generator, String generatorVerName, String generatorVersion, boolean parallel, FLAVersion version) throws IOException { - XFLConverter.convertSWF(handler, this, swfName, outfile, true, generator, generatorVerName, generatorVersion, parallel, version); - clearAllCache(); - } - - public void exportXfl(AbortRetryIgnoreHandler handler, String outfile, String swfName, String generator, String generatorVerName, String generatorVersion, boolean parallel, FLAVersion version) throws IOException { - XFLConverter.convertSWF(handler, this, swfName, outfile, false, generator, generatorVerName, generatorVersion, parallel, version); - clearAllCache(); - } - - public static AffineTransform matrixToTransform(MATRIX mat) { - return new AffineTransform(mat.getScaleXFloat(), mat.getRotateSkew0Float(), - mat.getRotateSkew1Float(), mat.getScaleYFloat(), - mat.translateX, mat.translateY); - } - - public SerializableImage getFromCache(String key) { - if (frameCache.contains(key)) { - return frameCache.get(key); - } - return null; - } - - public void putToCache(String key, SerializableImage img) { - if (Configuration.useFrameCache.get()) { - frameCache.put(key, img); - } - } - - public void clearImageCache() { - frameCache.clear(); - DefineSpriteTag.clearCache(); - DefineButtonTag.clearCache(); - DefineButton2Tag.clearCache(); - for (Tag tag : tags) { - if (tag instanceof ImageTag) { - ((ImageTag) tag).clearCache(); - } - } - } - - public void clearScriptCache() { - as2Cache.clear(); - as3Cache.clear(); - } - - public void clearAllCache() { - characters = null; - abcList = null; - timeline = null; - clearImageCache(); - clearScriptCache(); - Cache.clearAll(); - Helper.clearShapeCache(); - System.gc(); - } - - public static void uncache(ASMSource src) { - if (src != null) { - src.getSwf().as2Cache.remove(src); - } - } - - public static void uncache(ScriptPack pack) { - if (pack != null) { - pack.getSwf().as3Cache.remove(pack); - } - } - - public static boolean isCached(ASMSource src) { - return src.getSwf().as2Cache.contains(src); - } - - public static boolean isCached(ScriptPack pack) { - return pack.getSwf().as3Cache.contains(pack); - } - - public static CachedScript getCached(ASMSource src, ActionList actions) throws InterruptedException { - SWF swf = src.getSwf(); - if (swf.as2Cache.contains(src)) { - return swf.as2Cache.get(src); - } - - if (actions == null) { - actions = src.getActions(); - } - - HighlightedTextWriter writer = new HighlightedTextWriter(Configuration.getCodeFormatting(), true); - Action.actionsToSource(src, actions, src.toString()/*FIXME?*/, writer); - List hilights = writer.instructionHilights; - String srcNoHex = writer.toString(); - CachedScript res = new CachedScript(srcNoHex, hilights); - swf.as2Cache.put(src, res); - return res; - } - - public static CachedDecompilation getCached(ScriptPack pack) throws InterruptedException { - SWF swf = pack.getSwf(); - if (swf.as3Cache.contains(pack)) { - return swf.as3Cache.get(pack); - } - - int scriptIndex = pack.scriptIndex; - ScriptInfo script = null; - if (scriptIndex > -1) { - script = pack.abc.script_info.get(scriptIndex); - } - boolean parallel = Configuration.parallelSpeedUp.get(); - HighlightedTextWriter writer = new HighlightedTextWriter(Configuration.getCodeFormatting(), true); - pack.toSource(writer, script.traits.traits, ScriptExportMode.AS, parallel); - HighlightedText hilightedCode = new HighlightedText(writer); - CachedDecompilation res = new CachedDecompilation(hilightedCode); - swf.as3Cache.put(pack, res); - - return res; - } - - public static RECT fixRect(RECT rect) { - RECT ret = new RECT(); - ret.Xmin = rect.Xmin; - ret.Xmax = rect.Xmax; - ret.Ymin = rect.Ymin; - ret.Ymax = rect.Ymax; - - if (ret.Xmax <= 0) { - ret.Xmax = ret.getWidth(); - ret.Xmin = 0; - } - if (ret.Ymax <= 0) { - ret.Ymax = ret.getHeight(); - ret.Ymin = 0; - } - if (ret.Xmin < 0) { - ret.Xmax += (-ret.Xmin); - ret.Xmin = 0; - } - if (ret.Ymin < 0) { - ret.Ymax += (-ret.Ymin); - ret.Ymin = 0; - } - - if (ret.getWidth() < 1 || ret.getHeight() < 1) { - ret.Xmin = 0; - ret.Ymin = 0; - ret.Xmax = 20; - ret.Ymax = 20; - } - return ret; - } - - public static void frameToSvg(Timeline timeline, int frame, int time, DepthState stateUnderCursor, int mouseButton, SVGExporter exporter, ColorTransform colorTransform, int level, double zoom) throws IOException { - if (timeline.getFrameCount() <= frame) { - return; - } - Frame frameObj = timeline.getFrame(frame); - List clips = new ArrayList<>(); - List prevClips = new ArrayList<>(); - - int maxDepth = timeline.getMaxDepth(); - for (int i = 1; i <= maxDepth; i++) { - for (int c = 0; c < clips.size(); c++) { - if (clips.get(c).depth == i) { - exporter.setClip(prevClips.get(c)); - prevClips.remove(c); - clips.remove(c); - } - } - if (!frameObj.layers.containsKey(i)) { - continue; - } - DepthState layer = frameObj.layers.get(i); - if (!timeline.swf.getCharacters().containsKey(layer.characterId)) { - continue; - } - if (!layer.isVisible) { - continue; - } - - CharacterTag character = timeline.swf.getCharacter(layer.characterId); - if (colorTransform == null) { - colorTransform = new ColorTransform(); - } - - ColorTransform clrTrans = colorTransform.clone(); - if (layer.colorTransForm != null && layer.blendMode <= 1) { // Normal blend mode - clrTrans = colorTransform.merge(layer.colorTransForm); - } - - if (character instanceof DrawableTag) { - DrawableTag drawable = (DrawableTag) character; - - String assetName; - Tag drawableTag = (Tag) drawable; - RECT boundRect = drawable.getRect(); - if (exporter.exportedTags.containsKey(drawableTag)) { - assetName = exporter.exportedTags.get(drawableTag); - } else { - assetName = getTagIdPrefix(drawableTag, exporter); - exporter.exportedTags.put(drawableTag, assetName); - exporter.createDefGroup(new ExportRectangle(boundRect), assetName); - drawable.toSVG(exporter, layer.ratio, clrTrans, level + 1, zoom); - exporter.endGroup(); - } - ExportRectangle rect = new ExportRectangle(boundRect); - - // TODO: if (layer.filters != null) - // TODO: if (layer.blendMode > 1) - if (layer.clipDepth > -1) { - String clipName = exporter.getUniqueId("clipPath"); - exporter.createClipPath(new Matrix(), clipName); - SvgClip clip = new SvgClip(clipName, layer.clipDepth); - clips.add(clip); - prevClips.add(exporter.getClip()); - Matrix mat = Matrix.getTranslateInstance(rect.xMin, rect.yMin).preConcatenate(new Matrix(layer.matrix)); - exporter.addUse(mat, boundRect, assetName); - exporter.setClip(clip.shape); - exporter.endGroup(); - } else { - Matrix mat = Matrix.getTranslateInstance(rect.xMin, rect.yMin).preConcatenate(new Matrix(layer.matrix)); - exporter.addUse(mat, boundRect, assetName); - } - } - } - } - - private static String getTagIdPrefix(Tag tag, SVGExporter exporter) { - if (tag instanceof ShapeTag) { - return exporter.getUniqueId("shape"); - } - if (tag instanceof MorphShapeTag) { - return exporter.getUniqueId("morphshape"); - } - if (tag instanceof DefineSpriteTag) { - return exporter.getUniqueId("sprite"); - } - if (tag instanceof TextTag) { - return exporter.getUniqueId("text"); - } - if (tag instanceof ButtonTag) { - return exporter.getUniqueId("button"); - } - return exporter.getUniqueId("tag"); - } - - public static SerializableImage frameToImageGet(Timeline timeline, int frame, int time, DepthState stateUnderCursor, int mouseButton, RECT displayRect, Matrix transformation, ColorTransform colorTransform, Color backGroundColor, boolean useCache, double zoom) { - SWF swf = timeline.swf; - String key = "frame_" + frame + "_" + timeline.id + "_" + swf.hashCode() + "_" + zoom; - SerializableImage image; - if (useCache) { - image = swf.getFromCache(key); - if (image != null) { - return image; - } - } - - if (timeline.getFrameCount() == 0) { - return new SerializableImage(1, 1, SerializableImage.TYPE_INT_ARGB); - } - - RECT rect = displayRect; - image = new SerializableImage((int) (rect.getWidth() * zoom / SWF.unitDivisor) + 1, - (int) (rect.getHeight() * zoom / SWF.unitDivisor) + 1, SerializableImage.TYPE_INT_ARGB); - if (backGroundColor == null) { - image.fillTransparent(); - } else { - Graphics2D g = (Graphics2D) image.getBufferedImage().getGraphics(); - g.setComposite(AlphaComposite.Src); - g.setColor(backGroundColor); - g.fill(new Rectangle(image.getWidth(), image.getHeight())); - } - - Matrix m = transformation.clone(); - m.translate(-rect.Xmin * zoom, -rect.Ymin * zoom); - m.scale(zoom); - RenderContext renderContext = new RenderContext(); - renderContext.stateUnderCursor = stateUnderCursor; - renderContext.mouseButton = mouseButton; - frameToImage(timeline, frame, time, renderContext, image, m, colorTransform); - if (useCache) { - swf.putToCache(key, image); - } - - return image; - } - - public static void framesToImage(Timeline timeline, List ret, int startFrame, int stopFrame, RenderContext renderContext, RECT displayRect, int totalFrameCount, Stack visited, Matrix transformation, ColorTransform colorTransform, double zoom) { - RECT rect = displayRect; - for (int f = 0; f < timeline.getFrameCount(); f++) { - SerializableImage image = new SerializableImage((int) (rect.getWidth() / SWF.unitDivisor) + 1, - (int) (rect.getHeight() / SWF.unitDivisor) + 1, SerializableImage.TYPE_INT_ARGB); - image.fillTransparent(); - Matrix m = new Matrix(); - m.translate(-rect.Xmin, -rect.Ymin); - frameToImage(timeline, f, 0, renderContext, image, m, colorTransform); - ret.add(image); - } - } - - public static void frameToImage(Timeline timeline, int frame, int time, RenderContext renderContext, SerializableImage image, Matrix transformation, ColorTransform colorTransform) { - double unzoom = SWF.unitDivisor; - if (timeline.getFrameCount() <= frame) { - return; - } - Frame frameObj = timeline.getFrame(frame); - Graphics2D g = (Graphics2D) image.getGraphics(); - g.setPaint(frameObj.backgroundColor.toColor()); - g.fill(new Rectangle(image.getWidth(), image.getHeight())); - g.setTransform(transformation.toTransform()); - List clips = new ArrayList<>(); - List prevClips = new ArrayList<>(); - - int maxDepth = timeline.getMaxDepth(); - for (int i = 1; i <= maxDepth; i++) { - for (int c = 0; c < clips.size(); c++) { - if (clips.get(c).depth == i) { - g.setClip(prevClips.get(c)); - prevClips.remove(c); - clips.remove(c); - } - } - if (!frameObj.layers.containsKey(i)) { - continue; - } - DepthState layer = frameObj.layers.get(i); - if (!timeline.swf.getCharacters().containsKey(layer.characterId)) { - continue; - } - if (!layer.isVisible) { - continue; - } - - CharacterTag character = timeline.swf.getCharacter(layer.characterId); - Matrix mat = new Matrix(layer.matrix); - mat = mat.preConcatenate(transformation); - - if (colorTransform == null) { - colorTransform = new ColorTransform(); - } - - ColorTransform clrTrans = colorTransform.clone(); - if (layer.colorTransForm != null && layer.blendMode <= 1) { // Normal blend mode - clrTrans = colorTransform.merge(layer.colorTransForm); - } - - boolean showPlaceholder = false; - if (character instanceof DrawableTag) { - DrawableTag drawable = (DrawableTag) character; - Matrix drawMatrix = new Matrix(); - int drawableFrameCount = drawable.getNumFrames(); - if (drawableFrameCount == 0) { - drawableFrameCount = 1; - } - - int dframe; - if (timeline.fontFrameNum != -1) { - dframe = timeline.fontFrameNum; - } else { - dframe = (time + layer.time) % drawableFrameCount; - } - - if (character instanceof ButtonTag) { - dframe = ButtonTag.FRAME_UP; - if (renderContext.stateUnderCursor == layer) { - if (renderContext.mouseButton > 0) { - dframe = ButtonTag.FRAME_DOWN; - } else { - dframe = ButtonTag.FRAME_OVER; - } - } - } - - RECT boundRect = drawable.getRect(); - ExportRectangle rect = new ExportRectangle(boundRect); - rect = mat.transform(rect); - Matrix m = mat.clone(); - if (layer.filters != null && layer.filters.size() > 0) { - // calculate size after applying the filters - double deltaXMax = 0; - double deltaYMax = 0; - for (FILTER filter : layer.filters) { - double x = filter.getDeltaX(); - double y = filter.getDeltaY(); - deltaXMax = Math.max(x, deltaXMax); - deltaYMax = Math.max(y, deltaYMax); - } - rect.xMin -= deltaXMax * unzoom; - rect.xMax += deltaXMax * unzoom; - rect.yMin -= deltaYMax * unzoom; - rect.yMax += deltaYMax * unzoom; - } - - rect.xMin -= 1 * unzoom; - rect.yMin -= 1 * unzoom; - rect.xMin = Math.max(0, rect.xMin); - rect.yMin = Math.max(0, rect.yMin); - - int newWidth = (int) (rect.getWidth() / unzoom); - int newHeight = (int) (rect.getHeight() / unzoom); - int deltaX = (int) (rect.xMin / unzoom); - int deltaY = (int) (rect.yMin / unzoom); - newWidth = Math.min(image.getWidth() - deltaX, newWidth) + 1; - newHeight = Math.min(image.getHeight() - deltaY, newHeight) + 1; - - if (newWidth <= 0 || newHeight <= 0) { - continue; - } - - m.translate(-rect.xMin, -rect.yMin); - drawMatrix.translate(rect.xMin, rect.yMin); - - SerializableImage img = null; - String cacheKey = null; - if (drawable instanceof ShapeTag) { - cacheKey = ((ShapeTag) drawable).getCharacterId() + m.toString() + clrTrans.toString(); - img = renderContext.shapeCache.get(cacheKey); - } - - if (img == null) { - img = new SerializableImage(newWidth, newHeight, SerializableImage.TYPE_INT_ARGB); - img.fillTransparent(); - - drawable.toImage(dframe, layer.time + time, layer.ratio, renderContext, img, m, clrTrans); - - if (cacheKey != null) { - renderContext.shapeCache.put(cacheKey, img); - } - } - - /*//if (renderContext.stateUnderCursor == layer) { - if (true) { - BufferedImage bi = img.getBufferedImage(); - ColorModel cm = bi.getColorModel(); - boolean isAlphaPremultiplied = cm.isAlphaPremultiplied(); - WritableRaster raster = bi.copyData(null); - img = new SerializableImage(new BufferedImage(cm, raster, isAlphaPremultiplied, null)); - Graphics2D gg = (Graphics2D) img.getGraphics(); - gg.setStroke(new BasicStroke(3)); - gg.setPaint(Color.red); - gg.setTransform(AffineTransform.getTranslateInstance(0, 0)); - gg.draw(SHAPERECORD.twipToPixelShape(drawable.getOutline(dframe, layer.time + time, layer.ratio, renderContext, m))); - }*/ - if (layer.filters != null) { - for (FILTER filter : layer.filters) { - img = filter.apply(img); - } - } - if (layer.blendMode > 1) { - if (layer.colorTransForm != null) { - img = layer.colorTransForm.apply(img); - } - } - - drawMatrix.translateX /= unzoom; - drawMatrix.translateY /= unzoom; - AffineTransform trans = drawMatrix.toTransform(); - - switch (layer.blendMode) { - case 0: - case 1: - g.setComposite(AlphaComposite.SrcOver); - break; - case 2: // Layer - g.setComposite(AlphaComposite.SrcOver); - break; - case 3: - g.setComposite(BlendComposite.Multiply); - break; - case 4: - g.setComposite(BlendComposite.Screen); - break; - case 5: - g.setComposite(BlendComposite.Lighten); - break; - case 6: - g.setComposite(BlendComposite.Darken); - break; - case 7: - g.setComposite(BlendComposite.Difference); - break; - case 8: - g.setComposite(BlendComposite.Add); - break; - case 9: - g.setComposite(BlendComposite.Subtract); - break; - case 10: - g.setComposite(BlendComposite.Invert); - break; - case 11: - g.setComposite(BlendComposite.Alpha); - break; - case 12: - g.setComposite(BlendComposite.Erase); - break; - case 13: - g.setComposite(BlendComposite.Overlay); - break; - case 14: - g.setComposite(BlendComposite.HardLight); - break; - default: // Not implemented - g.setComposite(AlphaComposite.SrcOver); - break; - } - - if (layer.clipDepth > -1) { - BufferedImage mask = new BufferedImage(image.getWidth(), image.getHeight(), image.getType()); - Graphics2D gm = (Graphics2D) mask.getGraphics(); - gm.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); - gm.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); - gm.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); - gm.setComposite(AlphaComposite.Src); - gm.setColor(new Color(0, 0, 0, 0f)); - gm.fillRect(0, 0, image.getWidth(), image.getHeight()); - gm.setTransform(trans); - gm.drawImage(img.getBufferedImage(), 0, 0, null); - Clip clip = new Clip(Helper.imageToShape(mask), layer.clipDepth); // Maybe we can get current outline instead converting from image (?) - clips.add(clip); - prevClips.add(g.getClip()); - g.setTransform(AffineTransform.getTranslateInstance(0, 0)); - g.setClip(clip.shape); - } else { - g.setTransform(trans); - g.drawImage(img.getBufferedImage(), 0, 0, null); - } - } else if (character instanceof BoundedTag) { - showPlaceholder = true; - } - - if (showPlaceholder) { - mat.translateX /= unzoom; - mat.translateY /= unzoom; - AffineTransform trans = mat.toTransform(); - g.setTransform(trans); - BoundedTag b = (BoundedTag) character; - g.setPaint(new Color(255, 255, 255, 128)); - g.setComposite(BlendComposite.Invert); - RECT r = b.getRect(); - int div = (int) unzoom; - g.drawString(character.toString(), r.Xmin / div + 3, r.Ymin / div + 15); - g.draw(new Rectangle(r.Xmin / div, r.Ymin / div, r.getWidth() / div, r.getHeight() / div)); - g.drawLine(r.Xmin / div, r.Ymin / div, r.Xmax / div, r.Ymax / div); - g.drawLine(r.Xmax / div, r.Ymin / div, r.Xmin / div, r.Ymax / div); - g.setComposite(AlphaComposite.Dst); - } - } - - g.setTransform(AffineTransform.getScaleInstance(1, 1)); - } - - private void removeTagWithDependenciesFromTimeline(Tag toRemove, Timeline timeline) { - int characterId = 0; - if (toRemove instanceof CharacterTag) { - characterId = ((CharacterTag) toRemove).getCharacterId(); - } - Map stage = new HashMap<>(); - - Set dependingChars = new HashSet<>(); - if (characterId != 0) { - dependingChars.add(characterId); - for (int i = 0; i < timeline.tags.size(); i++) { - Tag t = timeline.tags.get(i); - if (t instanceof CharacterIdTag) { - CharacterIdTag c = (CharacterIdTag) t; - Set needed = new HashSet<>(); - t.getNeededCharacters(needed); - if (needed.contains(characterId)) { - dependingChars.add(c.getCharacterId()); - } - } - } - } - - for (int i = 0; i < timeline.tags.size(); i++) { - Tag t = timeline.tags.get(i); - if (t instanceof RemoveTag) { - RemoveTag rt = (RemoveTag) t; - int depth = rt.getDepth(); - if (stage.containsKey(depth)) { - int currentCharId = stage.get(depth); - stage.remove(depth); - if (dependingChars.contains(currentCharId)) { - timeline.tags.remove(i); - i--; - continue; - } - } - } - if (t instanceof PlaceObjectTypeTag) { - PlaceObjectTypeTag po = (PlaceObjectTypeTag) t; - int placeCharId = po.getCharacterId(); - int depth = po.getDepth(); - if (placeCharId != 0) { - stage.put(depth, placeCharId); - if (dependingChars.contains(placeCharId)) { - timeline.tags.remove(i); - i--; - continue; - } - } - } - if (t instanceof CharacterIdTag) { - CharacterIdTag c = (CharacterIdTag) t; - if (dependingChars.contains(c.getCharacterId())) { - timeline.tags.remove(i); - i--; - continue; - } - } - Set needed = new HashSet<>(); - t.getNeededCharacters(needed); - for (int dep : dependingChars) { - if (needed.contains(dep)) { - timeline.tags.remove(i); - i--; - continue; - } - } - if (t == toRemove) { - timeline.tags.remove(i); - i--; - continue; - } - if (t instanceof Timelined) { - removeTagWithDependenciesFromTimeline(toRemove, ((Timelined) t).getTimeline()); - } - } - } - - private boolean removeTagFromTimeline(Tag toRemove, Timeline timeline) { - boolean modified = false; - int characterId = -1; - if (toRemove instanceof CharacterTag) { - characterId = ((CharacterTag) toRemove).getCharacterId(); - modified = timeline.removeCharacter(characterId); - } - for (int i = 0; i < timeline.tags.size(); i++) { - Tag t = timeline.tags.get(i); - if (t == toRemove) { - timeline.tags.remove(t); - i--; - continue; - } - - if (toRemove instanceof CharacterTag) { - if (t.removeCharacter(characterId)) { - modified = true; - i = -1; - continue; - } - } - - if (t instanceof DefineSpriteTag) { - DefineSpriteTag spr = (DefineSpriteTag) t; - boolean sprModified = removeTagFromTimeline(toRemove, spr.getTimeline()); - if (sprModified) { - spr.setModified(true); - } - modified |= sprModified; - } - } - return modified; - } - - public void removeTags(Collection tags, boolean removeDependencies) { - Set timelineds = new HashSet<>(); - for (Tag tag : tags) { - Timelined timelined = tag.getTimelined(); - timelineds.add(timelined); - removeTagInternal(timelined, tag, removeDependencies); - } - - for (Timelined timelined : timelineds) { - resetTimelines(timelined); - } - - updateCharacters(); - clearImageCache(); - } - - public void removeTag(Tag tag, boolean removeDependencies) { - Timelined timelined = tag.getTimelined(); - removeTagInternal(timelined, tag, removeDependencies); - resetTimelines(timelined); - updateCharacters(); - clearImageCache(); - } - - private void removeTagInternal(Timelined timelined, Tag tag, boolean removeDependencies) { - if (tag instanceof ShowFrameTag || ShowFrameTag.isNestedTagType(tag.getId())) { - List tags; - if (timelined instanceof DefineSpriteTag) { - DefineSpriteTag sprite = (DefineSpriteTag) timelined; - tags = sprite.getSubTags(); - } else { - tags = this.tags; - } - tags.remove(tag); - if (timelined instanceof DefineSpriteTag) { - DefineSpriteTag sprite = (DefineSpriteTag) timelined; - sprite.setModified(true); - } - timelined.resetTimeline(); - } else { - // timeline should be always the swf here - if (removeDependencies) { - removeTagWithDependenciesFromTimeline(tag, timelined.getTimeline()); - if (timelined instanceof DefineSpriteTag) { - DefineSpriteTag sprite = (DefineSpriteTag) timelined; - sprite.setModified(true); - } - } else { - removeTagFromTimeline(tag, timeline); - } - } - } - - @Override - public String toString() { - return getShortFileName(); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash; + +import SevenZip.Compression.LZMA.Decoder; +import SevenZip.Compression.LZMA.Encoder; +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.CachedDecompilation; +import com.jpexs.decompiler.flash.abc.ClassPath; +import com.jpexs.decompiler.flash.abc.RenameType; +import com.jpexs.decompiler.flash.abc.ScriptPack; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.ScriptInfo; +import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.ActionGraphSource; +import com.jpexs.decompiler.flash.action.ActionList; +import com.jpexs.decompiler.flash.action.ActionLocalData; +import com.jpexs.decompiler.flash.action.CachedScript; +import com.jpexs.decompiler.flash.action.model.ConstantPool; +import com.jpexs.decompiler.flash.action.model.DirectValueActionItem; +import com.jpexs.decompiler.flash.action.model.FunctionActionItem; +import com.jpexs.decompiler.flash.action.model.GetMemberActionItem; +import com.jpexs.decompiler.flash.action.model.GetVariableActionItem; +import com.jpexs.decompiler.flash.action.model.clauses.ClassActionItem; +import com.jpexs.decompiler.flash.action.model.clauses.InterfaceActionItem; +import com.jpexs.decompiler.flash.action.swf4.ActionEquals; +import com.jpexs.decompiler.flash.action.swf4.ActionGetVariable; +import com.jpexs.decompiler.flash.action.swf4.ActionIf; +import com.jpexs.decompiler.flash.action.swf4.ActionPush; +import com.jpexs.decompiler.flash.action.swf4.ActionSetVariable; +import com.jpexs.decompiler.flash.action.swf4.ConstantIndex; +import com.jpexs.decompiler.flash.action.swf5.ActionCallFunction; +import com.jpexs.decompiler.flash.action.swf5.ActionCallMethod; +import com.jpexs.decompiler.flash.action.swf5.ActionConstantPool; +import com.jpexs.decompiler.flash.action.swf5.ActionDefineFunction; +import com.jpexs.decompiler.flash.action.swf5.ActionDefineLocal; +import com.jpexs.decompiler.flash.action.swf5.ActionDefineLocal2; +import com.jpexs.decompiler.flash.action.swf5.ActionEquals2; +import com.jpexs.decompiler.flash.action.swf5.ActionGetMember; +import com.jpexs.decompiler.flash.action.swf5.ActionNewMethod; +import com.jpexs.decompiler.flash.action.swf5.ActionNewObject; +import com.jpexs.decompiler.flash.action.swf5.ActionSetMember; +import com.jpexs.decompiler.flash.action.swf7.ActionDefineFunction2; +import com.jpexs.decompiler.flash.configuration.Configuration; +import com.jpexs.decompiler.flash.dumpview.DumpInfo; +import com.jpexs.decompiler.flash.dumpview.DumpInfoSwfNode; +import com.jpexs.decompiler.flash.ecma.Null; +import com.jpexs.decompiler.flash.exporters.commonshape.ExportRectangle; +import com.jpexs.decompiler.flash.exporters.commonshape.Matrix; +import com.jpexs.decompiler.flash.exporters.commonshape.SVGExporter; +import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; +import com.jpexs.decompiler.flash.exporters.script.AS2ScriptExporter; +import com.jpexs.decompiler.flash.exporters.script.AS3ScriptExporter; +import com.jpexs.decompiler.flash.exporters.settings.ScriptExportSettings; +import com.jpexs.decompiler.flash.helpers.HighlightedText; +import com.jpexs.decompiler.flash.helpers.HighlightedTextWriter; +import com.jpexs.decompiler.flash.helpers.ImageHelper; +import com.jpexs.decompiler.flash.helpers.SWFDecompilerPlugin; +import com.jpexs.decompiler.flash.helpers.collections.MyEntry; +import com.jpexs.decompiler.flash.helpers.hilight.Highlighting; +import com.jpexs.decompiler.flash.tags.ABCContainerTag; +import com.jpexs.decompiler.flash.tags.DefineBinaryDataTag; +import com.jpexs.decompiler.flash.tags.DefineButton2Tag; +import com.jpexs.decompiler.flash.tags.DefineButtonTag; +import com.jpexs.decompiler.flash.tags.DefineSpriteTag; +import com.jpexs.decompiler.flash.tags.DoInitActionTag; +import com.jpexs.decompiler.flash.tags.EndTag; +import com.jpexs.decompiler.flash.tags.ExportAssetsTag; +import com.jpexs.decompiler.flash.tags.FileAttributesTag; +import com.jpexs.decompiler.flash.tags.JPEGTablesTag; +import com.jpexs.decompiler.flash.tags.ShowFrameTag; +import com.jpexs.decompiler.flash.tags.SymbolClassTag; +import com.jpexs.decompiler.flash.tags.Tag; +import com.jpexs.decompiler.flash.tags.TagStub; +import com.jpexs.decompiler.flash.tags.VideoFrameTag; +import com.jpexs.decompiler.flash.tags.base.ASMSource; +import com.jpexs.decompiler.flash.tags.base.ASMSourceContainer; +import com.jpexs.decompiler.flash.tags.base.BoundedTag; +import com.jpexs.decompiler.flash.tags.base.ButtonTag; +import com.jpexs.decompiler.flash.tags.base.CharacterIdTag; +import com.jpexs.decompiler.flash.tags.base.CharacterTag; +import com.jpexs.decompiler.flash.tags.base.DrawableTag; +import com.jpexs.decompiler.flash.tags.base.Exportable; +import com.jpexs.decompiler.flash.tags.base.FontTag; +import com.jpexs.decompiler.flash.tags.base.ImageTag; +import com.jpexs.decompiler.flash.tags.base.MorphShapeTag; +import com.jpexs.decompiler.flash.tags.base.PlaceObjectTypeTag; +import com.jpexs.decompiler.flash.tags.base.RemoveTag; +import com.jpexs.decompiler.flash.tags.base.RenderContext; +import com.jpexs.decompiler.flash.tags.base.ShapeTag; +import com.jpexs.decompiler.flash.tags.base.TextTag; +import com.jpexs.decompiler.flash.timeline.AS2Package; +import com.jpexs.decompiler.flash.timeline.Clip; +import com.jpexs.decompiler.flash.timeline.DepthState; +import com.jpexs.decompiler.flash.timeline.Frame; +import com.jpexs.decompiler.flash.timeline.FrameScript; +import com.jpexs.decompiler.flash.timeline.SvgClip; +import com.jpexs.decompiler.flash.timeline.TagScript; +import com.jpexs.decompiler.flash.timeline.Timeline; +import com.jpexs.decompiler.flash.timeline.Timelined; +import com.jpexs.decompiler.flash.treeitems.SWFList; +import com.jpexs.decompiler.flash.treeitems.TreeItem; +import com.jpexs.decompiler.flash.types.ColorTransform; +import com.jpexs.decompiler.flash.types.MATRIX; +import com.jpexs.decompiler.flash.types.RECT; +import com.jpexs.decompiler.flash.types.annotations.Internal; +import com.jpexs.decompiler.flash.types.filters.BlendComposite; +import com.jpexs.decompiler.flash.types.filters.FILTER; +import com.jpexs.decompiler.flash.xfl.FLAVersion; +import com.jpexs.decompiler.flash.xfl.XFLConverter; +import com.jpexs.decompiler.graph.Graph; +import com.jpexs.decompiler.graph.GraphSourceItem; +import com.jpexs.decompiler.graph.GraphSourceItemContainer; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.TranslateStack; +import com.jpexs.decompiler.graph.model.LocalData; +import com.jpexs.helpers.ByteArrayRange; +import com.jpexs.helpers.Cache; +import com.jpexs.helpers.Helper; +import com.jpexs.helpers.NulStream; +import com.jpexs.helpers.ProgressListener; +import com.jpexs.helpers.SerializableImage; +import com.jpexs.helpers.utf8.Utf8Helper; +import java.awt.AlphaComposite; +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.awt.RenderingHints; +import java.awt.Shape; +import java.awt.geom.AffineTransform; +import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.EmptyStackException; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Set; +import java.util.Stack; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.zip.DeflaterOutputStream; +import java.util.zip.InflaterInputStream; + +/** + * Class representing SWF file + * + * @author JPEXS + */ +public final class SWF implements SWFContainerItem, Timelined { + + // big object for testing cleanup + //BigObject bigObj = new BigObject(); + /** + * Default version of SWF file format + */ + public static final int DEFAULT_VERSION = 10; + + /** + * Maximum SWF file format version + * Needs to be fixed when SWF versions reaches this value + */ + public static final int MAX_VERSION = 30; + + /** + * Tags inside of file + */ + public List tags = new ArrayList<>(); + + @Internal + public boolean hasEndTag = true; + + /** + * ExportRectangle for the display + */ + public RECT displayRect; + + /** + * Movie frame rate + */ + public int frameRate; + + /** + * Number of frames in movie + */ + public int frameCount; + + /** + * Version of SWF + */ + public int version; + + /** + * Uncompressed size of the file + */ + @Internal + public long fileSize; + + /** + * Used compression mode + */ + public SWFCompression compression = SWFCompression.NONE; + + /** + * Compressed size of the file (LZMA) + */ + @Internal + public long compressedSize; + + /** + * LZMA Properties + */ + public byte[] lzmaProperties; + + @Internal + public byte[] uncompressedData; + + @Internal + public byte[] originalUncompressedData; + + /** + * ScaleForm GFx + */ + public boolean gfx = false; + + @Internal + public SWFList swfList; + + @Internal + private String file; + + @Internal + private String fileTitle; + + @Internal + private Map characters; + + @Internal + private List abcList; + + @Internal + private JPEGTablesTag jtt; + + @Internal + public Map sourceFontNamesMap = new HashMap<>(); + + public static final double unitDivisor = 20; + + private static final Logger logger = Logger.getLogger(SWF.class.getName()); + + @Internal + private Timeline timeline; + + @Internal + public DumpInfoSwfNode dumpInfo; + + @Internal + public DefineBinaryDataTag binaryData; + + @Internal + private final HashMap deobfuscated = new HashMap<>(); + + @Internal + private final IdentifiersDeobfuscation deobfuscation = new IdentifiersDeobfuscation(); + + @Internal + private Cache frameCache = Cache.getInstance(false, false, "frame"); + + @Internal + private final Cache as2Cache = Cache.getInstance(true, false, "as2"); + + @Internal + private final Cache as3Cache = Cache.getInstance(true, false, "as3"); + + public void updateCharacters() { + characters = null; + } + + public void clearTagSwfs() { + resetTimelines(this); + updateCharacters(); + + for (Tag tag : tags) { + if (tag instanceof DefineSpriteTag) { + DefineSpriteTag spriteTag = (DefineSpriteTag) tag; + for (Tag tag1 : spriteTag.subTags) { + tag1.setSwf(null); + } + + spriteTag.subTags.clear(); + } + + if (tag instanceof DefineBinaryDataTag) { + DefineBinaryDataTag binaryTag = (DefineBinaryDataTag) tag; + if (binaryTag.innerSwf != null) { + binaryTag.innerSwf.clearTagSwfs(); + } + } + + tag.setSwf(null); + } + + tags.clear(); + if (abcList != null) { + abcList.clear(); + } + + if (swfList != null) { + swfList.swfs.clear(); + } + + as2Cache.clear(); + as3Cache.clear(); + frameCache.clear(); + + timeline = null; + clearDumpInfo(dumpInfo); + dumpInfo = null; + jtt = null; + binaryData = null; + } + + private void clearDumpInfo(DumpInfo di) { + for (DumpInfo childInfo : di.getChildInfos()) { + clearDumpInfo(childInfo); + } + + di.getChildInfos().clear(); + } + + public Map getCharacters() { + if (characters == null) { + synchronized (this) { + if (characters == null) { + Map chars = new HashMap<>(); + parseCharacters(tags, chars); + characters = Collections.unmodifiableMap(chars); + } + } + } + + return characters; + } + + public CharacterTag getCharacter(int characterId) { + return getCharacters().get(characterId); + } + + public String getExportName(int characterId) { + CharacterTag characterTag = getCharacters().get(characterId); + String exportName = characterTag != null ? characterTag.getExportName() : null; + return exportName; + } + + public FontTag getFont(int fontId) { + CharacterTag characterTag = getCharacters().get(fontId); + if (characterTag instanceof FontTag) { + return (FontTag) characterTag; + } + + if (characterTag != null) { + logger.log(Level.SEVERE, "CharacterTag should be a FontTag. characterId: {0}", fontId); + } + + return null; + } + + public List getAbcList() { + if (abcList == null) { + synchronized (this) { + if (abcList == null) { + ArrayList newAbcList = new ArrayList<>(); + getAbcTags(tags, newAbcList); + abcList = newAbcList; + } + } + } + + return abcList; + } + + public boolean isAS3() { + FileAttributesTag fileAttributes = getFileAttributes(); + return (fileAttributes != null && fileAttributes.actionScript3) || (fileAttributes == null && !getAbcList().isEmpty()); + } + + public FileAttributesTag getFileAttributes() { + for (Tag t : tags) { + if (t instanceof FileAttributesTag) { + return (FileAttributesTag) t; + } + } + + return null; + } + + public int getNextCharacterId() { + int max = -1; + for (int characterId : getCharacters().keySet()) { + if (characterId > max) { + max = characterId; + } + } + + return max + 1; + } + + public synchronized JPEGTablesTag getJtt() { + if (jtt == null) { + synchronized (this) { + if (jtt == null) { + for (Tag t : tags) { + if (t instanceof JPEGTablesTag) { + jtt = (JPEGTablesTag) t; + break; + } + } + } + } + } + + return jtt; + } + + public String getDocumentClass() { + for (Tag t : tags) { + if (t instanceof SymbolClassTag) { + SymbolClassTag sc = (SymbolClassTag) t; + for (int i = 0; i < sc.tags.size(); i++) { + if (sc.tags.get(i) == 0) { + return sc.names.get(i); + } + } + } + } + + return null; + } + + public void fixCharactersOrder(boolean checkAll) { + Set addedCharacterIds = new HashSet<>(); + Set movedTags = new HashSet<>(); + for (int i = 0; i < tags.size(); i++) { + Tag tag = tags.get(i); + if (checkAll || tag.isModified()) { + Set needed = new HashSet<>(); + tag.getNeededCharacters(needed); + if (tag instanceof CharacterTag) { + CharacterTag characterTag = (CharacterTag) tag; + needed.remove(characterTag.getCharacterId()); + } + boolean moved = false; + for (Integer id : needed) { + if (!addedCharacterIds.contains(id)) { + CharacterTag neededCharacter = getCharacter(id); + if (neededCharacter == null) { + continue; + } + + if (movedTags.contains(neededCharacter)) { + logger.log(Level.SEVERE, "Fixing characters order failed, recursion detected."); + return; + } + + // move the needed character to the current position + tags.remove(neededCharacter); + tags.add(i, neededCharacter); + movedTags.add(neededCharacter); + moved = true; + } + } + + if (moved) { + i--; + continue; + } + } + if (tag instanceof CharacterTag) { + addedCharacterIds.add(((CharacterTag) tag).getCharacterId()); + } + } + } + + public void resetTimelines(Timelined timelined) { + timelined.resetTimeline(); + if (timelined instanceof SWF) { + for (Tag t : ((SWF) timelined).tags) { + if (t instanceof Timelined) { + resetTimelines((Timelined) t); + } + } + } + } + + private void parseCharacters(List list, Map characters) { + for (Tag t : list) { + if (t instanceof CharacterTag) { + int characterId = ((CharacterTag) t).getCharacterId(); + if (characters.containsKey(characterId)) { + logger.log(Level.SEVERE, "SWF already contains characterId={0}", characterId); + } + + if (characterId != 0) { + characters.put(characterId, (CharacterTag) t); + } + } + if (t instanceof DefineSpriteTag) { + parseCharacters(((DefineSpriteTag) t).getSubTags(), characters); + } + } + } + + /** + * Unresolve recursive sprites + */ + private void checkInvalidSprites() { + for (int i = 0; i < tags.size(); i++) { + Tag t = tags.get(i); + if (t instanceof DefineSpriteTag) { + if (!isSpriteValid((DefineSpriteTag) t, new ArrayList())) { + tags.set(i, new TagStub(this, t.getId(), "InvalidSprite", t.getOriginalRange(), null)); + } + } + } + } + + private boolean isSpriteValid(DefineSpriteTag sprite, List path) { + if (path.contains(sprite.spriteId)) { + return false; + } + path.add(sprite.spriteId); + for (Tag t : sprite.subTags) { + if (t instanceof DefineSpriteTag) { + if (!isSpriteValid((DefineSpriteTag) t, path)) { + return false; + } + } + } + path.remove((Integer) sprite.spriteId); + return true; + } + + @Override + public Timeline getTimeline() { + if (timeline == null) { + timeline = new Timeline(this); + } + return timeline; + } + + @Override + public void resetTimeline() { + if (timeline != null) { + timeline.reset(this); + } + } + + /** + * Gets all tags with specified id + * + * @param tagId Identificator of tag type + * @return List of tags + */ + public List getTagData(int tagId) { + List ret = new ArrayList<>(); + for (Tag tag : tags) { + if (tag.getId() == tagId) { + ret.add(tag); + } + } + return ret; + } + + /** + * Saves this SWF into new file + * + * @param os OutputStream to save SWF in + * @throws IOException + */ + public void saveTo(OutputStream os) throws IOException { + saveTo(os, compression); + } + + public String getHeaderBytes() { + return getHeaderBytes(compression, gfx); + } + + private String getHeaderBytes(SWFCompression compression, boolean gfx) { + if (compression == SWFCompression.LZMA_ABC) { + return "ABC"; + } + + String ret = ""; + if (compression == SWFCompression.LZMA) { + ret += 'Z'; + } else if (compression == SWFCompression.ZLIB) { + ret += 'C'; + } else { + if (gfx) { + ret += 'G'; + } else { + ret += 'F'; + } + } + if (gfx) { + ret += 'F'; + ret += 'X'; + } else { + ret += 'W'; + ret += 'S'; + } + return ret; + } + + /** + * Saves this SWF into new file + * + * @param os OutputStream to save SWF in + * @param compression + * @throws IOException + */ + public void saveTo(OutputStream os, SWFCompression compression) throws IOException { + try { + fixCharactersOrder(false); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + SWFOutputStream sos = new SWFOutputStream(baos, version); + sos.writeRECT(displayRect); + sos.writeUI8(0); + sos.writeUI8(frameRate); + sos.writeUI16(frameCount); + + sos.writeTags(tags); + if (hasEndTag) { + sos.writeUI16(0); + } + + sos.close(); + os.write(Utf8Helper.getBytes(getHeaderBytes(compression, gfx))); + os.write(version); + byte[] data = baos.toByteArray(); + sos = new SWFOutputStream(os, version); + sos.writeUI32(data.length + 8); + + if (compression == SWFCompression.LZMA || compression == SWFCompression.LZMA_ABC) { + long uncompressedLength = data.length; + Encoder enc = new Encoder(); + int val = lzmaProperties[0] & 0xFF; + int lc = val % 9; + int remainder = val / 9; + int lp = remainder % 5; + int pb = remainder / 5; + int dictionarySize = 0; + for (int i = 0; i < 4; i++) { + dictionarySize += ((int) (lzmaProperties[1 + i]) & 0xFF) << (i * 8); + } + if (Configuration.lzmaFastBytes.get() > 0) { + enc.SetNumFastBytes(Configuration.lzmaFastBytes.get()); + } + enc.SetDictionarySize(dictionarySize); + enc.SetLcLpPb(lc, lp, pb); + baos = new ByteArrayOutputStream(); + enc.SetEndMarkerMode(true); + enc.Code(new ByteArrayInputStream(data), baos, -1, -1, null); + data = baos.toByteArray(); + if (compression == SWFCompression.LZMA) { + byte[] udata = new byte[4]; + udata[0] = (byte) (data.length & 0xFF); + udata[1] = (byte) ((data.length >> 8) & 0xFF); + udata[2] = (byte) ((data.length >> 16) & 0xFF); + udata[3] = (byte) ((data.length >> 24) & 0xFF); + os.write(udata); + } + enc.WriteCoderProperties(os); + if (compression == SWFCompression.LZMA_ABC) { + byte[] udata = new byte[8]; + udata[0] = (byte) (uncompressedLength & 0xFF); + udata[1] = (byte) ((uncompressedLength >> 8) & 0xFF); + udata[2] = (byte) ((uncompressedLength >> 16) & 0xFF); + udata[3] = (byte) ((uncompressedLength >> 24) & 0xFF); + udata[4] = (byte) ((uncompressedLength >> 32) & 0xFF); + udata[5] = (byte) ((uncompressedLength >> 40) & 0xFF); + udata[6] = (byte) ((uncompressedLength >> 48) & 0xFF); + udata[7] = (byte) ((uncompressedLength >> 56) & 0xFF); + os.write(udata); + } + } else if (compression == SWFCompression.ZLIB) { + os = new DeflaterOutputStream(os); + } + + os.write(data); + } finally { + if (os != null) { + os.close(); + } + } + } + + public boolean isModified() { + for (Tag tag : tags) { + if (tag.isModified()) { + return true; + } + } + return false; + } + + public void clearModified() { + for (Tag tag : tags) { + if (tag.isModified()) { + tag.createOriginalData(); + tag.setModified(false); + } + } + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try { + saveTo(baos, SWFCompression.NONE); + byte[] swfData = baos.toByteArray(); + uncompressedData = swfData; + } catch (IOException ex) { + logger.log(Level.SEVERE, "Cannot save SWF", ex); + } + } + + /** + * Constructs an empty SWF + */ + public SWF() { + + } + + /** + * Construct SWF from stream + * + * @param is Stream to read SWF from + * @param parallelRead Use parallel threads? + * @throws IOException + * @throws java.lang.InterruptedException + */ + public SWF(InputStream is, boolean parallelRead) throws IOException, InterruptedException { + this(is, null, null, null, parallelRead, false, true); + } + + /** + * Construct SWF from stream + * + * @param is Stream to read SWF from + * @param parallelRead Use parallel threads? + * @param lazy + * @throws IOException + * @throws java.lang.InterruptedException + */ + public SWF(InputStream is, boolean parallelRead, boolean lazy) throws IOException, InterruptedException { + this(is, null, null, null, parallelRead, false, lazy); + } + + /** + * Construct SWF from stream + * + * @param is Stream to read SWF from + * @param file Path to the file + * @param fileTitle Title of the SWF + * @param parallelRead Use parallel threads? + * @throws IOException + * @throws java.lang.InterruptedException + */ + public SWF(InputStream is, String file, String fileTitle, boolean parallelRead) throws IOException, InterruptedException { + this(is, file, fileTitle, null, parallelRead, false, true); + } + + /** + * Construct SWF from stream + * + * @param is Stream to read SWF from + * @param listener + * @param parallelRead Use parallel threads? + * @throws IOException + * @throws java.lang.InterruptedException + */ + public SWF(InputStream is, ProgressListener listener, boolean parallelRead) throws IOException, InterruptedException { + this(is, null, null, listener, parallelRead, false, true); + } + + /** + * Construct SWF from stream + * + * @param is Stream to read SWF from + * @param file Path to the file + * @param fileTitle Title of the SWF + * @param listener + * @param parallelRead Use parallel threads? + * @throws IOException + * @throws java.lang.InterruptedException + */ + public SWF(InputStream is, String file, String fileTitle, ProgressListener listener, boolean parallelRead) throws IOException, InterruptedException { + this(is, file, fileTitle, listener, parallelRead, false, true); + } + + /** + * Faster constructor to check SWF only + * + * @param is + * @throws java.io.IOException + */ + public SWF(InputStream is) throws IOException { + decompress(is, new NulStream(), true); + } + + /** + * Construct SWF from stream + * + * @param is Stream to read SWF from + * @param file Path to the file + * @param fileTitle Title of the SWF + * @param listener + * @param parallelRead Use parallel threads? + * @param checkOnly Check only file validity + * @param lazy + * @throws IOException + * @throws java.lang.InterruptedException + */ + public SWF(InputStream is, String file, String fileTitle, ProgressListener listener, boolean parallelRead, boolean checkOnly, boolean lazy) throws IOException, InterruptedException { + this.file = file; + this.fileTitle = fileTitle; + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + SWFHeader header = decompress(is, baos, true); + gfx = header.gfx; + compression = header.compression; + lzmaProperties = header.lzmaProperties; + uncompressedData = baos.toByteArray(); + originalUncompressedData = uncompressedData; + + SWFInputStream sis = new SWFInputStream(this, uncompressedData); + dumpInfo = new DumpInfoSwfNode(this, "rootswf", "", null, 0, 0); + sis.dumpInfo = dumpInfo; + sis.readBytesEx(3, "signature"); // skip siganture + version = sis.readUI8("version"); + fileSize = sis.readUI32("fileSize"); + dumpInfo.lengthBytes = fileSize; + if (listener != null) { + sis.addPercentListener(listener); + } + sis.setPercentMax(fileSize); + displayRect = sis.readRECT("displayRect"); + // FIXED8 (16 bit fixed point) frameRate + sis.readUI8("tmpFirstByetOfFrameRate"); // tmpFirstByetOfFrameRate + frameRate = sis.readUI8("frameRate"); + frameCount = sis.readUI16("frameCount"); + List tags = sis.readTagList(this, 0, parallelRead, true, !checkOnly, lazy); + if (tags.size() > 0 && tags.get(tags.size() - 1).getId() == EndTag.ID) { + tags.remove(tags.size() - 1); + } else { + hasEndTag = false; + } + this.tags = tags; + if (!checkOnly) { + checkInvalidSprites(); + updateCharacters(); + assignExportNamesToSymbols(); + assignClassesToSymbols(); + SWFDecompilerPlugin.fireSwfParsed(this); + } else { + boolean hasNonUnknownTag = false; + for (Tag tag : tags) { + if (tag.getOriginalDataLength() > 0 && Tag.getRequiredTags().contains(tag.getId())) { + hasNonUnknownTag = true; + } + } + if (!hasNonUnknownTag) { + throw new IOException("Invalid SWF file. No known tag found."); + } + } + + /*preload shape tags + for (Tag tag : tags) { + if (tag instanceof ShapeTag) { + ((ShapeTag) tag).getShapes(); + } + }*/ + } + + @Override + public SWF getSwf() { + return this; + } + + public SWF getRootSwf() { + SWF result = this; + while (result.binaryData != null) { + result = result.binaryData.getSwf(); + } + + return result; + } + + public String getFile() { + return file; + } + + /** + * Get title of the file + * + * @return file title + */ + public String getFileTitle() { + if (fileTitle != null) { + return fileTitle; + } + return file; + } + + public String getShortFileName() { + String title = getFileTitle(); + if (title == null) { + return ""; + } + return new File(title).getName(); + } + + public void setFile(String file) { + this.file = file; + fileTitle = null; + } + + private static void getAbcTags(List list, List actionScripts) { + for (Tag t : list) { + if (t instanceof DefineSpriteTag) { + getAbcTags(((DefineSpriteTag) t).getSubTags(), actionScripts); + } + if (t instanceof ABCContainerTag) { + actionScripts.add((ABCContainerTag) t); + } + } + } + + public void assignExportNamesToSymbols() { + HashMap exportNames = new HashMap<>(); + for (Tag t : tags) { + if (t instanceof ExportAssetsTag) { + ExportAssetsTag eat = (ExportAssetsTag) t; + for (int i = 0; i < eat.tags.size(); i++) { + Integer tagId = eat.tags.get(i); + String name = eat.names.get(i); + if ((!exportNames.containsKey(tagId)) && (!exportNames.containsValue(name))) { + exportNames.put(tagId, name); + } + } + } + } + for (Tag t : tags) { + if (t instanceof CharacterTag) { + CharacterTag ct = (CharacterTag) t; + if (exportNames.containsKey(ct.getCharacterId())) { + ct.setExportName(exportNames.get(ct.getCharacterId())); + } + } + } + } + + public void assignClassesToSymbols() { + HashMap classes = new HashMap<>(); + for (Tag t : tags) { + if (t instanceof SymbolClassTag) { + SymbolClassTag sct = (SymbolClassTag) t; + for (int i = 0; i < sct.tags.size(); i++) { + if ((!classes.containsKey(sct.tags.get(i))) && (!classes.containsValue(sct.names.get(i)))) { + classes.put(sct.tags.get(i), sct.names.get(i)); + } + } + } + } + for (Tag t : tags) { + if (t instanceof CharacterTag) { + CharacterTag ct = (CharacterTag) t; + if (classes.containsKey(ct.getCharacterId())) { + ct.setClassName(classes.get(ct.getCharacterId())); + } + } + } + } + + /** + * Compress SWF file + * + * @param fis Input stream + * @param fos Output stream + * @return True on success + */ + public static boolean fws2cws(InputStream fis, OutputStream fos) { + try { + byte[] swfHead = new byte[8]; + fis.read(swfHead); + + if (swfHead[0] != 'F') { + fis.close(); + return false; + } + swfHead[0] = 'C'; + fos.write(swfHead); + fos = new DeflaterOutputStream(fos); + int i; + while ((i = fis.read()) != -1) { + fos.write(i); + } + + fis.close(); + fos.close(); + } catch (IOException ex) { + return false; + } + return true; + } + + public static boolean decompress(InputStream fis, OutputStream fos) { + try { + decompress(fis, fos, false); + return true; + } catch (IOException ex) { + return false; + } + } + + private static void decodeLZMAStream(InputStream is, OutputStream os, byte[] lzmaProperties, long fileSize) throws IOException { + Decoder decoder = new Decoder(); + if (!decoder.SetDecoderProperties(lzmaProperties)) { + throw new IOException("LZMA:Incorrect stream properties"); + } + if (!decoder.Code(is, os, fileSize - 8)) { + throw new IOException("LZMA:Error in data stream"); + } + } + + private static SWFHeader decompress(InputStream is, OutputStream os, boolean allowUncompressed) throws IOException { + byte[] hdr = new byte[8]; + + // SWFheader: signature, version and fileSize + if (is.read(hdr) != 8) { + throw new IOException("SWF header is too short"); + } + + String signature = new String(hdr, 0, 3, Utf8Helper.charset); + if (!Arrays.asList( + "FWS", // Uncompressed Flash + "CWS", // ZLib compressed Flash + "ZWS", // LZMA compressed Flash + "GFX", // Uncompressed ScaleForm GFx + "CFX", // Compressed ScaleForm GFx + "ABC" // Non-standard LZMA compressed Flash + ).contains(signature)) { + throw new IOException("Invalid SWF file"); + } + + int version = hdr[3]; + SWFInputStream sis = new SWFInputStream(null, Arrays.copyOfRange(hdr, 4, 8), 4, 4); + long fileSize = sis.readUI32("fileSize"); + SWFHeader header = new SWFHeader(); + header.version = version; + header.fileSize = fileSize; + + if (hdr[1] == 'F' && hdr[2] == 'X') { + header.gfx = true; + } + + try (SWFOutputStream sos = new SWFOutputStream(os, version)) { + sos.write(Utf8Helper.getBytes(header.gfx ? "GFX" : "FWS")); + sos.writeUI8(version); + sos.writeUI32(fileSize); + + switch (hdr[0]) { + case 'C': { // CWS, CFX + Helper.copyStream(new InflaterInputStream(is), os, fileSize - 8); + header.compression = SWFCompression.ZLIB; + break; + } + case 'Z': { // ZWS + byte[] lzmaprop = new byte[9]; + is.read(lzmaprop); + sis = new SWFInputStream(null, lzmaprop); + sis.readUI32("LZMAsize"); // compressed LZMA data size = compressed SWF - 17 byte, + // where 17 = 8 byte header + this 4 byte + 5 bytes decoder properties + int propertiesSize = 5; + byte[] lzmaProperties = sis.readBytes(propertiesSize, "lzmaproperties"); + if (lzmaProperties.length != propertiesSize) { + throw new IOException("LZMA:input .lzma file is too short"); + } + + decodeLZMAStream(is, os, lzmaProperties, fileSize); + + header.compression = SWFCompression.LZMA; + header.lzmaProperties = lzmaProperties; + break; + } + case 'A': { // ABC + byte[] lzmaProperties = new byte[5]; + is.read(lzmaProperties); + byte[] uncompressedLength = new byte[8]; + is.read(uncompressedLength); + + decodeLZMAStream(is, os, lzmaProperties, fileSize); + + header.compression = SWFCompression.LZMA_ABC; + header.lzmaProperties = lzmaProperties; + break; + } + default: { // FWS, GFX + if (allowUncompressed) { + Helper.copyStream(is, os, fileSize - 8); + } else { + throw new IOException("SWF is not compressed"); + } + } + } + + return header; + } + } + + public static boolean renameInvalidIdentifiers(RenameType renameType, InputStream fis, OutputStream fos) { + try { + SWF swf = new SWF(fis, Configuration.parallelSpeedUp.get()); + int cnt = swf.deobfuscateIdentifiers(renameType); + swf.assignClassesToSymbols(); + System.out.println(cnt + " identifiers renamed."); + swf.saveTo(fos); + } catch (InterruptedException ex) { + return false; + } catch (IOException ex) { + return false; + } + return true; + } + + public boolean exportAS3Class(String className, String outdir, ScriptExportSettings exportSettings, boolean parallel, EventListener evl) throws Exception { + boolean exported = false; + + List abcList = getAbcList(); + for (int i = 0; i < abcList.size(); i++) { + ABC abc = abcList.get(i).getABC(); + List scrs = abc.findScriptPacksByPath(className); + for (int j = 0; j < scrs.size(); j++) { + ScriptPack scr = scrs.get(j); + String cnt = ""; + if (scrs.size() > 1) { + cnt = "script " + (j + 1) + "/" + scrs.size() + " "; + } + String eventData = cnt + scr.getPath() + " ..."; + evl.handleExportingEvent("tag", i + 1, abcList.size(), eventData); + scr.export(outdir, exportSettings, parallel); + evl.handleExportedEvent("tag", i + 1, abcList.size(), eventData); + exported = true; + } + } + return exported; + } + + private List uniqueAS3Packs(List packs) { + List ret = new ArrayList<>(); + Set classPaths = new HashSet<>(); + for (ScriptPack item : packs) { + ClassPath key = item.getClassPath(); + if (classPaths.contains(key)) { + logger.log(Level.SEVERE, "Duplicate pack path found (" + key + ")!"); + } else { + classPaths.add(key); + ret.add(item); + } + } + return ret; + } + + public List getAS3Packs() { + List packs = new ArrayList<>(); + for (ABCContainerTag abcTag : getAbcList()) { + packs.addAll(abcTag.getABC().getScriptPacks(null)); + } + return uniqueAS3Packs(packs); + } + + @Override + public RECT getRect() { + return displayRect; + } + + @Override + public RECT getRect(Set added) { + return displayRect; + } + + public EventListener getExportEventListener() { + EventListener evl = new EventListener() { + @Override + public void handleExportingEvent(String type, int index, int count, Object data) { + for (EventListener listener : listeners) { + listener.handleExportingEvent(type, index, count, data); + } + } + + @Override + public void handleExportedEvent(String type, int index, int count, Object data) { + for (EventListener listener : listeners) { + listener.handleExportedEvent(type, index, count, data); + } + } + + @Override + public void handleEvent(String event, Object data) { + informListeners(event, data); + } + }; + + return evl; + } + + public List exportActionScript(AbortRetryIgnoreHandler handler, String outdir, ScriptExportSettings exportSettings, boolean parallel, EventListener evl) throws IOException { + List ret = new ArrayList<>(); + + if (isAS3()) { + ret.addAll(new AS3ScriptExporter().exportActionScript3(this, handler, outdir, exportSettings, parallel, evl)); + } else { + ret.addAll(new AS2ScriptExporter().exportAS2ScriptsTimeout(handler, outdir, getASMs(true), exportSettings, evl)); + } + return ret; + } + + public Map getASMs(boolean exportFileNames) { + return getASMs(exportFileNames, new ArrayList(), true); + } + + public Map getASMs(boolean exportFileNames, List nodesToExport, boolean exportAll) { + Map asmsToExport = new HashMap<>(); + for (TreeItem treeItem : getFirstLevelASMNodes(null)) { + getASMs(exportFileNames, treeItem, nodesToExport, exportAll, asmsToExport, File.separator + getASMPath(exportFileNames, treeItem)); + } + + return asmsToExport; + } + + private void getASMs(boolean exportFileNames, TreeItem treeItem, List nodesToExport, boolean exportAll, Map asmsToExport, String path) { + boolean exportNode = nodesToExport.contains(treeItem); + TreeItem realItem = treeItem instanceof TagScript ? ((TagScript) treeItem).getTag() : treeItem; + if (realItem instanceof ASMSource && (exportAll || exportNode)) { + String npath = path; + int ppos = 1; + while (asmsToExport.containsKey(npath)) { + ppos++; + npath = path + (exportFileNames ? "[" + ppos + "]" : "_" + ppos); + } + asmsToExport.put(npath, (ASMSource) realItem); + } + + if (treeItem instanceof TagScript) { + TagScript tagScript = (TagScript) treeItem; + for (TreeItem subItem : tagScript.getFrames()) { + getASMs(exportFileNames, subItem, nodesToExport, exportAll, asmsToExport, path + File.separator + getASMPath(exportFileNames, subItem)); + } + } else if (treeItem instanceof FrameScript) { + FrameScript frameScript = (FrameScript) treeItem; + Frame parentFrame = frameScript.getFrame(); + for (TreeItem subItem : parentFrame.actionContainers) { + getASMs(exportFileNames, getASMWrapToTagScript(subItem), nodesToExport, exportAll || exportNode, asmsToExport, path + File.separator + getASMPath(exportFileNames, subItem)); + } + for (TreeItem subItem : parentFrame.actions) { + getASMs(exportFileNames, getASMWrapToTagScript(subItem), nodesToExport, exportAll || exportNode, asmsToExport, path + File.separator + getASMPath(exportFileNames, subItem)); + } + } else if (treeItem instanceof AS2Package) { + AS2Package as2Package = (AS2Package) treeItem; + for (TreeItem subItem : as2Package.subPackages.values()) { + getASMs(exportFileNames, subItem, nodesToExport, exportAll, asmsToExport, path + File.separator + getASMPath(exportFileNames, subItem)); + } + for (TreeItem subItem : as2Package.scripts.values()) { + getASMs(exportFileNames, subItem, nodesToExport, exportAll, asmsToExport, path + File.separator + getASMPath(exportFileNames, subItem)); + } + } + } + + private String getASMPath(boolean exportFileName, TreeItem treeItem) { + if (!exportFileName) { + return treeItem.toString(); + } + + String result; + if (treeItem instanceof Exportable) { + result = ((Exportable) treeItem).getExportFileName(); + } else { + result = treeItem.toString(); + } + + return Helper.makeFileName(result); + } + + private TreeItem getASMWrapToTagScript(TreeItem treeItem) { + if (treeItem instanceof Tag) { + Tag resultTag = (Tag) treeItem; + List subNodes = new ArrayList<>(); + if (treeItem instanceof ASMSourceContainer) { + for (ASMSource item : ((ASMSourceContainer) treeItem).getSubItems()) { + subNodes.add(item); + } + } + + TagScript tagScript = new TagScript(treeItem.getSwf(), resultTag, subNodes); + return tagScript; + } + + return treeItem; + } + + public List getFirstLevelASMNodes(Map tagScriptCache) { + Timeline timeline = getTimeline(); + List subNodes = new ArrayList<>(); + List subFrames = new ArrayList<>(); + subNodes.addAll(timeline.getAS2RootPackage().subPackages.values()); + subNodes.addAll(timeline.getAS2RootPackage().scripts.values()); + + for (Tag tag : timeline.otherTags) { + boolean hasInnerFrames = false; + List tagSubNodes = new ArrayList<>(); + if (tag instanceof Timelined) { + Timeline timeline2 = ((Timelined) tag).getTimeline(); + for (Frame frame : timeline2.getFrames()) { + if (!frame.actions.isEmpty() || !frame.actionContainers.isEmpty()) { + FrameScript frameScript = new FrameScript(this, frame); + tagSubNodes.add(frameScript); + hasInnerFrames = true; + } + } + } + + if (tag instanceof ASMSourceContainer) { + for (ASMSource asm : ((ASMSourceContainer) tag).getSubItems()) { + tagSubNodes.add(asm); + } + } + + if (!tagSubNodes.isEmpty()) { + TagScript ts = new TagScript(this, tag, tagSubNodes); + if (tagScriptCache != null) { + tagScriptCache.put(tag, ts); + } + if (hasInnerFrames) { + subFrames.add(ts); + } else { + subNodes.add(ts); + } + } + } + + subNodes.addAll(subFrames); + for (Frame frame : timeline.getFrames()) { + if (!frame.actions.isEmpty() || !frame.actionContainers.isEmpty()) { + FrameScript frameScript = new FrameScript(this, frame); + subNodes.add(frameScript); + } + } + + return subNodes; + } + + private final HashSet listeners = new HashSet<>(); + + public final void addEventListener(EventListener listener) { + listeners.add(listener); + for (Tag t : tags) { + if (t instanceof ABCContainerTag) { + (((ABCContainerTag) t).getABC()).addEventListener(listener); + } + } + } + + public final void removeEventListener(EventListener listener) { + listeners.remove(listener); + for (Tag t : tags) { + if (t instanceof ABCContainerTag) { + (((ABCContainerTag) t).getABC()).removeEventListener(listener); + } + } + } + + protected void informListeners(String event, Object data) { + for (EventListener listener : listeners) { + listener.handleEvent(event, data); + } + } + + public static boolean hasErrorHeader(byte[] data) { + return hasErrorHeader(new ByteArrayRange(data)); + } + + public static boolean hasErrorHeader(ByteArrayRange data) { + if (data.getLength() > 4) { + if ((data.get(0) & 0xff) == 0xff && (data.get(1) & 0xff) == 0xd9 + && (data.get(2) & 0xff) == 0xff && (data.get(3) & 0xff) == 0xd8) { + return true; + } + } + return false; + } + + public static void populateVideoFrames(int streamId, List tags, HashMap output) { + for (Tag t : tags) { + if (t instanceof VideoFrameTag) { + output.put(((VideoFrameTag) t).frameNum, (VideoFrameTag) t); + } + if (t instanceof DefineSpriteTag) { + populateVideoFrames(streamId, ((DefineSpriteTag) t).getSubTags(), output); + } + } + } + + private static void writeLE(OutputStream os, long val, int size) throws IOException { + for (int i = 0; i < size; i++) { + os.write((int) (val & 0xff)); + val >>= 8; + } + } + + public static void createWavFromPcmData(OutputStream fos, int soundRateHz, boolean soundSize, boolean soundType, byte[] data) throws IOException { + ByteArrayOutputStream subChunk1Data = new ByteArrayOutputStream(); + int audioFormat = 1; // PCM + writeLE(subChunk1Data, audioFormat, 2); + int numChannels = soundType ? 2 : 1; + writeLE(subChunk1Data, numChannels, 2); + int[] rateMap = {5512, 11025, 22050, 44100}; + int sampleRate = soundRateHz; // rateMap[soundRate]; + writeLE(subChunk1Data, sampleRate, 4); + int bitsPerSample = soundSize ? 16 : 8; + int byteRate = sampleRate * numChannels * bitsPerSample / 8; + writeLE(subChunk1Data, byteRate, 4); + int blockAlign = numChannels * bitsPerSample / 8; + writeLE(subChunk1Data, blockAlign, 2); + writeLE(subChunk1Data, bitsPerSample, 2); + + ByteArrayOutputStream chunks = new ByteArrayOutputStream(); + chunks.write(Utf8Helper.getBytes("fmt ")); + byte[] subChunk1DataBytes = subChunk1Data.toByteArray(); + writeLE(chunks, subChunk1DataBytes.length, 4); + chunks.write(subChunk1DataBytes); + + chunks.write(Utf8Helper.getBytes("data")); + writeLE(chunks, data.length, 4); + chunks.write(data); + + fos.write(Utf8Helper.getBytes("RIFF")); + byte[] chunkBytes = chunks.toByteArray(); + writeLE(fos, 4 + chunkBytes.length, 4); + fos.write(Utf8Helper.getBytes("WAVE")); + fos.write(chunkBytes); + } + + public static String getTypePrefix(CharacterTag c) { + if (c instanceof ShapeTag) { + return "shape"; + } + if (c instanceof MorphShapeTag) { + return "morphshape"; + } + if (c instanceof DefineSpriteTag) { + return "sprite"; + } + if (c instanceof TextTag) { + return "text"; + } + if (c instanceof ButtonTag) { + return "button"; + } + if (c instanceof FontTag) { + return "font"; + } + if (c instanceof ImageTag) { + return "image"; + } + return "character"; + } + + public static void writeLibrary(SWF fswf, Set library, OutputStream fos) throws IOException { + for (int c : library) { + CharacterTag ch = fswf.getCharacter(c); + if (ch instanceof FontTag) { + fos.write(Utf8Helper.getBytes("function " + getTypePrefix(ch) + c + "(ctx,ch,textColor){\r\n")); + fos.write(Utf8Helper.getBytes(((FontTag) ch).toHtmlCanvas(1))); + fos.write(Utf8Helper.getBytes("}\r\n\r\n")); + } else { + if (ch instanceof ImageTag) { + ImageTag image = (ImageTag) ch; + String format = image.getImageFormat(); + InputStream imageStream = image.getImageData(); + byte[] imageData; + if (imageStream != null) { + imageData = Helper.readStream(image.getImageData()); + } else { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ImageHelper.write(image.getImage().getBufferedImage(), format.toUpperCase(Locale.ENGLISH), baos); + imageData = baos.toByteArray(); + } + String base64ImgData = Helper.byteArrayToBase64String(imageData); + fos.write(Utf8Helper.getBytes("var imageObj" + c + " = document.createElement(\"img\");\r\nimageObj" + c + ".src=\"data:image/" + format + ";base64," + base64ImgData + "\";\r\n")); + } + fos.write(Utf8Helper.getBytes("function " + getTypePrefix(ch) + c + "(ctx,ctrans,frame,ratio,time){\r\n")); + if (ch instanceof DrawableTag) { + fos.write(Utf8Helper.getBytes(((DrawableTag) ch).toHtmlCanvas(1))); + } + fos.write(Utf8Helper.getBytes("}\r\n\r\n")); + } + } + } + + private static void getVariables(ConstantPool constantPool, BaseLocalData localData, TranslateStack stack, List output, ActionGraphSource code, int ip, List> variables, List functions, HashMap strings, List visited, HashMap usageTypes, String path) throws InterruptedException { + boolean debugMode = false; + while ((ip > -1) && ip < code.size()) { + if (visited.contains(ip)) { + break; + } + GraphSourceItem ins = code.get(ip); + + if (debugMode) { + System.err.println("Visit " + ip + ": ofs" + Helper.formatAddress(((Action) ins).getAddress()) + ":" + ((Action) ins).getASMSource(new ActionList(), new HashSet(), ScriptExportMode.PCODE) + " stack:" + Helper.stackToString(stack, LocalData.create(new ConstantPool()))); + } + if (ins.isExit()) { + break; + } + if (ins.isIgnored()) { + ip++; + continue; + } + + String usageType = "name"; + GraphTargetItem name = null; + if ((ins instanceof ActionGetVariable) + || (ins instanceof ActionGetMember) + || (ins instanceof ActionDefineLocal2) + || (ins instanceof ActionNewMethod) + || (ins instanceof ActionNewObject) + || (ins instanceof ActionCallMethod) + || (ins instanceof ActionCallFunction)) { + if (stack.isEmpty()) { + break; + } + name = stack.peek(); + } + + if ((ins instanceof ActionGetVariable) || (ins instanceof ActionDefineLocal2)) { + usageType = "variable"; + } + if (ins instanceof ActionGetMember) { + usageType = "member"; + } + if ((ins instanceof ActionNewMethod) || (ins instanceof ActionNewObject)) { + usageType = "class"; + } + if (ins instanceof ActionCallMethod) { + usageType = "function"; // can there be method? + } + if (ins instanceof ActionCallFunction) { + usageType = "function"; + } + + if ((ins instanceof ActionDefineFunction) || (ins instanceof ActionDefineFunction2)) { + functions.add(ins); + } + + if (ins instanceof GraphSourceItemContainer) { + GraphSourceItemContainer cnt = (GraphSourceItemContainer) ins; + List cntSizes = cnt.getContainerSizes(); + long addr = code.pos2adr(ip + 1); + ip = code.adr2pos(addr); + String cntName = cnt.getName(); + for (Long size : cntSizes) { + if (size == 0) { + continue; + } + ip = code.adr2pos(addr); + addr += size; + int nextip = code.adr2pos(addr); + getVariables(variables, functions, strings, usageTypes, new ActionGraphSource(code.getActions().subList(ip, nextip), code.version, new HashMap(), new HashMap(), new HashMap()), 0, path + (cntName == null ? "" : "/" + cntName)); + ip = nextip; + } + List> r = new ArrayList<>(); + r.add(new ArrayList()); + r.add(new ArrayList()); + r.add(new ArrayList()); + try { + ((GraphSourceItemContainer) ins).translateContainer(r, stack, output, new HashMap(), new HashMap(), new HashMap()); + } catch (EmptyStackException ex) { + } + + continue; + } + + if ((ins instanceof ActionSetVariable) || (ins instanceof ActionSetMember) || (ins instanceof ActionDefineLocal)) { + if (stack.size() < 2) { + break; + } + name = stack.get(stack.size() - 2); + } + + if ((ins instanceof ActionSetVariable) || (ins instanceof ActionDefineLocal)) { + usageType = "variable"; + } + + if (ins instanceof ActionSetMember) { + usageType = "member"; + } + + if (name instanceof DirectValueActionItem) { + variables.add(new MyEntry<>((DirectValueActionItem) name, constantPool)); + usageTypes.put((DirectValueActionItem) name, usageType); + } + + // for..in return + if (((ins instanceof ActionEquals) || (ins instanceof ActionEquals2)) && (stack.size() == 1) && (stack.peek() instanceof DirectValueActionItem)) { + stack.push(new DirectValueActionItem(null, 0, new Null(), new ArrayList())); + } + + if (ins instanceof ActionConstantPool) { + constantPool = new ConstantPool(((ActionConstantPool) ins).constantPool); + } + int staticOperation = Graph.SOP_USE_STATIC; //(Boolean) Configuration.getConfig("autoDeobfuscate", true) ? Graph.SOP_SKIP_STATIC : Graph.SOP_USE_STATIC; + + try { + ins.translate(localData, stack, output, staticOperation, path); + } catch (EmptyStackException ex) { + // probably obfucated code, never executed branch + break; + } + if (ins.isExit()) { + break; + } + + if (ins instanceof ActionPush) { + if (!stack.isEmpty()) { + GraphTargetItem top = stack.peek(); + if (top instanceof DirectValueActionItem) { + DirectValueActionItem dvt = (DirectValueActionItem) top; + if ((dvt.value instanceof String) || (dvt.value instanceof ConstantIndex)) { + if (constantPool == null) { + constantPool = new ConstantPool(dvt.constants); + } + strings.put(dvt, constantPool); + } + } + } + } + + if (ins.isBranch() || ins.isJump()) { + if (ins instanceof ActionIf) { + if (stack.isEmpty()) { + break; + } + stack.pop(); + } + visited.add(ip); + List branches = ins.getBranches(code); + for (int b : branches) { + TranslateStack brStack = (TranslateStack) stack.clone(); + if (b >= 0) { + getVariables(constantPool, localData, brStack, output, code, b, variables, functions, strings, visited, usageTypes, path); + } else { + if (debugMode) { + System.out.println("Negative branch:" + b); + } + } + } + // } + break; + } + ip++; + }; + } + + private static void getVariables(List> variables, List functions, HashMap strings, HashMap usageTypes, ActionGraphSource code, int addr, String path) throws InterruptedException { + ActionLocalData localData = new ActionLocalData(); + getVariables(null, localData, new TranslateStack(), new ArrayList(), code, code.adr2pos(addr), variables, functions, strings, new ArrayList(), usageTypes, path); + } + + private List> getVariables(List> variables, HashMap actionsMap, List functions, HashMap strings, HashMap usageTypes, ASMSource src, String path) throws InterruptedException { + List> ret = new ArrayList<>(); + ActionList actions = src.getActions(); + actionsMap.put(src, actions); + getVariables(variables, functions, strings, usageTypes, new ActionGraphSource(actions, version, new HashMap(), new HashMap(), new HashMap()), 0, path); + return ret; + } + + private void getVariables(List tags, String path, List> variables, HashMap actionsMap, List functions, HashMap strings, HashMap usageTypes) throws InterruptedException { + List processed = new ArrayList<>(); + for (Tag t : tags) { + String subPath = path + "/" + t.toString(); + if (t instanceof ASMSource) { + addVariable((ASMSource) t, subPath, processed, variables, actionsMap, functions, strings, usageTypes); + } + if (t instanceof ASMSourceContainer) { + List processed2 = new ArrayList<>(); + for (ASMSource asm : ((ASMSourceContainer) t).getSubItems()) { + addVariable(asm, subPath + "/" + asm.toString(), processed2, variables, actionsMap, functions, strings, usageTypes); + } + } + if (t instanceof DefineSpriteTag) { + getVariables(((DefineSpriteTag) t).getSubTags(), path + "/" + t.toString(), variables, actionsMap, functions, strings, usageTypes); + } + } + } + + private void addVariable(ASMSource asm, String path, List processed, List> variables, HashMap actionsMap, List functions, HashMap strings, HashMap usageTypes) throws InterruptedException { + int pos = 1; + String infPath2 = path; + while (processed.contains(infPath2)) { + pos++; + infPath2 = path + "[" + pos + "]"; + } + processed.add(infPath2); + informListeners("getVariables", infPath2); + getVariables(variables, actionsMap, functions, strings, usageTypes, asm, path); + } + + public void fixAS3Code() { + for (ABCContainerTag abcTag : getAbcList()) { + ABC abc = abcTag.getABC(); + for (MethodBody body : abc.bodies) { + AVM2Code code = body.getCode(); + } + + ((Tag) abcTag).setModified(true); + } + } + + public int deobfuscateAS3Identifiers(RenameType renameType) { + for (Tag tag : tags) { + if (tag instanceof ABCContainerTag) { + ((ABCContainerTag) tag).getABC().deobfuscateIdentifiers(deobfuscated, renameType, true); + tag.setModified(true); + } + } + for (Tag tag : tags) { + if (tag instanceof ABCContainerTag) { + ((ABCContainerTag) tag).getABC().deobfuscateIdentifiers(deobfuscated, renameType, false); + tag.setModified(true); + } + } + for (Tag tag : tags) { + if (tag instanceof SymbolClassTag) { + SymbolClassTag sc = (SymbolClassTag) tag; + for (int i = 0; i < sc.names.size(); i++) { + String newname = deobfuscation.deobfuscateNameWithPackage(true, sc.names.get(i), deobfuscated, renameType, deobfuscated); + if (newname != null) { + sc.names.set(i, newname); + } + } + sc.setModified(true); + } + } + deobfuscation.deobfuscateInstanceNames(true, deobfuscated, renameType, tags, new HashMap()); + return deobfuscated.size(); + } + + public int deobfuscateIdentifiers(RenameType renameType) throws InterruptedException { + FileAttributesTag fileAttributes = getFileAttributes(); + if (fileAttributes == null) { + int cnt = 0; + cnt += deobfuscateAS2Identifiers(renameType); + cnt += deobfuscateAS3Identifiers(renameType); + return cnt; + } else { + if (fileAttributes.actionScript3) { + return deobfuscateAS3Identifiers(renameType); + } else { + return deobfuscateAS2Identifiers(renameType); + } + } + } + + public void renameAS2Identifier(String identifier, String newname) throws InterruptedException { + Map selected = new HashMap<>(); + selected.put(identifier, newname); + renameAS2Identifiers(null, selected); + } + + private int deobfuscateAS2Identifiers(RenameType renameType) throws InterruptedException { + return renameAS2Identifiers(renameType, null); + } + + private int renameAS2Identifiers(RenameType renameType, Map selected) throws InterruptedException { + HashMap actionsMap = new HashMap<>(); + List allFunctions = new ArrayList<>(); + List> allVariableNames = new ArrayList<>(); + HashMap allStrings = new HashMap<>(); + HashMap usageTypes = new HashMap<>(); + + int ret = 0; + getVariables(tags, "", allVariableNames, actionsMap, allFunctions, allStrings, usageTypes); + informListeners("rename", ""); + int fc = 0; + for (MyEntry it : allVariableNames) { + String name = it.getKey().toStringNoH(it.getValue()); + deobfuscation.allVariableNamesStr.add(name); + } + + informListeners("rename", "classes"); + int classCount = 0; + for (Tag t : tags) { + if (t instanceof DoInitActionTag) { + classCount++; + } + } + int cnt = 0; + for (Tag t : tags) { + if (t instanceof DoInitActionTag) { + cnt++; + informListeners("rename", "class " + cnt + "/" + classCount); + DoInitActionTag dia = (DoInitActionTag) t; + String exportName = getExportName(dia.spriteId); + exportName = exportName != null ? exportName : "_unk_"; + final String pkgPrefix = "__Packages."; + String[] classNameParts = null; + if (exportName.startsWith(pkgPrefix)) { + String className = exportName.substring(pkgPrefix.length()); + if (className.contains(".")) { + classNameParts = className.split("\\."); + } else { + classNameParts = new String[]{className}; + } + } + int staticOperation = Graph.SOP_USE_STATIC; //(Boolean) Configuration.getConfig("autoDeobfuscate", true) ? Graph.SOP_SKIP_STATIC : Graph.SOP_USE_STATIC; + List dec; + try { + dec = Action.actionsToTree(dia.getActions(), version, staticOperation, ""/*FIXME*/); + } catch (EmptyStackException ex) { + continue; + } + GraphTargetItem name = null; + for (GraphTargetItem it : dec) { + if (it instanceof ClassActionItem) { + ClassActionItem cti = (ClassActionItem) it; + List methods = new ArrayList<>(); + methods.addAll(cti.functions); + methods.addAll(cti.staticFunctions); + + for (GraphTargetItem gti : methods) { + if (gti instanceof FunctionActionItem) { + FunctionActionItem fun = (FunctionActionItem) gti; + if (fun.calculatedFunctionName instanceof DirectValueActionItem) { + DirectValueActionItem dvf = (DirectValueActionItem) fun.calculatedFunctionName; + String fname = dvf.toStringNoH(null); + String changed = deobfuscation.deobfuscateName(false, fname, false, "method", deobfuscated, renameType, selected); + if (changed != null) { + deobfuscated.put(fname, changed); + } + } + } + } + + List vars = new ArrayList<>(); + for (MyEntry item : cti.vars) { + vars.add(item.getKey()); + } + for (MyEntry item : cti.staticVars) { + vars.add(item.getKey()); + } + for (GraphTargetItem gti : vars) { + if (gti instanceof DirectValueActionItem) { + DirectValueActionItem dvf = (DirectValueActionItem) gti; + String vname = dvf.toStringNoH(null); + String changed = deobfuscation.deobfuscateName(false, vname, false, "attribute", deobfuscated, renameType, selected); + if (changed != null) { + deobfuscated.put(vname, changed); + } + } + } + + name = cti.className; + break; + } + if (it instanceof InterfaceActionItem) { + InterfaceActionItem ift = (InterfaceActionItem) it; + name = ift.name; + } + } + + if (name != null) { + int pos = 0; + while (name instanceof GetMemberActionItem) { + GetMemberActionItem mem = (GetMemberActionItem) name; + GraphTargetItem memberName = mem.memberName; + if (memberName instanceof DirectValueActionItem) { + DirectValueActionItem dvt = (DirectValueActionItem) memberName; + String nameStr = dvt.toStringNoH(null); + if (classNameParts != null) { + if (classNameParts.length - 1 - pos < 0) { + break; + } + } + String changedNameStr = nameStr; + if (classNameParts != null) { + changedNameStr = classNameParts[classNameParts.length - 1 - pos]; + } + String changedNameStr2 = deobfuscation.deobfuscateName(false, changedNameStr, pos == 0, pos == 0 ? "class" : "package", deobfuscated, renameType, selected); + if (changedNameStr2 != null) { + changedNameStr = changedNameStr2; + } + ret++; + deobfuscated.put(nameStr, changedNameStr); + pos++; + } + name = mem.object; + } + if (name instanceof GetVariableActionItem) { + GetVariableActionItem var = (GetVariableActionItem) name; + if (var.name instanceof DirectValueActionItem) { + DirectValueActionItem dvt = (DirectValueActionItem) var.name; + String nameStr = dvt.toStringNoH(null); + if (classNameParts != null) { + if (classNameParts.length - 1 - pos < 0) { + break; + } + } + String changedNameStr = nameStr; + if (classNameParts != null) { + changedNameStr = classNameParts[classNameParts.length - 1 - pos]; + } + String changedNameStr2 = deobfuscation.deobfuscateName(false, changedNameStr, pos == 0, pos == 0 ? "class" : "package", deobfuscated, renameType, selected); + if (changedNameStr2 != null) { + changedNameStr = changedNameStr2; + } + ret++; + deobfuscated.put(nameStr, changedNameStr); + pos++; + } + } + } + t.setModified(true); + } + } + + for (GraphSourceItem fun : allFunctions) { + fc++; + informListeners("rename", "function " + fc + "/" + allFunctions.size()); + if (fun instanceof ActionDefineFunction) { + ActionDefineFunction f = (ActionDefineFunction) fun; + if (f.functionName.isEmpty()) { // anonymous function, leave as is + continue; + } + String changed = deobfuscation.deobfuscateName(false, f.functionName, false, "function", deobfuscated, renameType, selected); + if (changed != null) { + f.replacedFunctionName = changed; + ret++; + } + } + if (fun instanceof ActionDefineFunction2) { + ActionDefineFunction2 f = (ActionDefineFunction2) fun; + if (f.functionName.isEmpty()) { // anonymous function, leave as is + continue; + } + String changed = deobfuscation.deobfuscateName(false, f.functionName, false, "function", deobfuscated, renameType, selected); + if (changed != null) { + f.replacedFunctionName = changed; + ret++; + } + } + } + + HashSet stringsNoVarH = new HashSet<>(); + List allVariableNamesDv = new ArrayList<>(); + for (MyEntry it : allVariableNames) { + allVariableNamesDv.add(it.getKey()); + } + for (DirectValueActionItem ti : allStrings.keySet()) { + if (!allVariableNamesDv.contains(ti)) { + stringsNoVarH.add(System.identityHashCode(allStrings.get(ti)) + "_" + ti.toStringNoH(allStrings.get(ti))); + } + } + + int vc = 0; + for (MyEntry it : allVariableNames) { + vc++; + String name = it.getKey().toStringNoH(it.getValue()); + String changed = deobfuscation.deobfuscateName(false, name, false, usageTypes.get(it.getKey()), deobfuscated, renameType, selected); + if (changed != null) { + boolean addNew = false; + String h = System.identityHashCode(it.getKey()) + "_" + name; + if (stringsNoVarH.contains(h)) { + addNew = true; + } + ActionPush pu = (ActionPush) it.getKey().src; + if (pu.replacement == null) { + pu.replacement = new ArrayList<>(); + pu.replacement.addAll(pu.values); + } + if (pu.replacement.get(it.getKey().pos) instanceof ConstantIndex) { + ConstantIndex ci = (ConstantIndex) pu.replacement.get(it.getKey().pos); + ConstantPool pool = it.getValue(); + if (pool == null) { + continue; + } + if (pool.constants == null) { + continue; + } + if (addNew) { + pool.constants.add(changed); + ci.index = pool.constants.size() - 1; + } else { + pool.constants.set(ci.index, changed); + } + } else { + pu.replacement.set(it.getKey().pos, changed); + } + ret++; + } + } + + for (ASMSource src : actionsMap.keySet()) { + actionsMap.get(src).removeNops(); + src.setActions(actionsMap.get(src)); + src.setModified(); + } + + deobfuscation.deobfuscateInstanceNames(false, deobfuscated, renameType, tags, selected); + return ret; + } + + public void exportFla(AbortRetryIgnoreHandler handler, String outfile, String swfName, String generator, String generatorVerName, String generatorVersion, boolean parallel, FLAVersion version) throws IOException { + XFLConverter.convertSWF(handler, this, swfName, outfile, true, generator, generatorVerName, generatorVersion, parallel, version); + clearAllCache(); + } + + public void exportXfl(AbortRetryIgnoreHandler handler, String outfile, String swfName, String generator, String generatorVerName, String generatorVersion, boolean parallel, FLAVersion version) throws IOException { + XFLConverter.convertSWF(handler, this, swfName, outfile, false, generator, generatorVerName, generatorVersion, parallel, version); + clearAllCache(); + } + + public static AffineTransform matrixToTransform(MATRIX mat) { + return new AffineTransform(mat.getScaleXFloat(), mat.getRotateSkew0Float(), + mat.getRotateSkew1Float(), mat.getScaleYFloat(), + mat.translateX, mat.translateY); + } + + public SerializableImage getFromCache(String key) { + if (frameCache.contains(key)) { + return frameCache.get(key); + } + return null; + } + + public void putToCache(String key, SerializableImage img) { + if (Configuration.useFrameCache.get()) { + frameCache.put(key, img); + } + } + + public void clearImageCache() { + frameCache.clear(); + DefineSpriteTag.clearCache(); + DefineButtonTag.clearCache(); + DefineButton2Tag.clearCache(); + for (Tag tag : tags) { + if (tag instanceof ImageTag) { + ((ImageTag) tag).clearCache(); + } + } + } + + public void clearScriptCache() { + as2Cache.clear(); + as3Cache.clear(); + } + + public void clearAllCache() { + characters = null; + abcList = null; + timeline = null; + clearImageCache(); + clearScriptCache(); + Cache.clearAll(); + Helper.clearShapeCache(); + System.gc(); + } + + public static void uncache(ASMSource src) { + if (src != null) { + src.getSwf().as2Cache.remove(src); + } + } + + public static void uncache(ScriptPack pack) { + if (pack != null) { + pack.getSwf().as3Cache.remove(pack); + } + } + + public static boolean isCached(ASMSource src) { + return src.getSwf().as2Cache.contains(src); + } + + public static boolean isCached(ScriptPack pack) { + return pack.getSwf().as3Cache.contains(pack); + } + + public static CachedScript getCached(ASMSource src, ActionList actions) throws InterruptedException { + SWF swf = src.getSwf(); + if (swf.as2Cache.contains(src)) { + return swf.as2Cache.get(src); + } + + if (actions == null) { + actions = src.getActions(); + } + + HighlightedTextWriter writer = new HighlightedTextWriter(Configuration.getCodeFormatting(), true); + Action.actionsToSource(src, actions, src.toString()/*FIXME?*/, writer); + List hilights = writer.instructionHilights; + String srcNoHex = writer.toString(); + CachedScript res = new CachedScript(srcNoHex, hilights); + swf.as2Cache.put(src, res); + return res; + } + + public static CachedDecompilation getCached(ScriptPack pack) throws InterruptedException { + SWF swf = pack.getSwf(); + if (swf.as3Cache.contains(pack)) { + return swf.as3Cache.get(pack); + } + + int scriptIndex = pack.scriptIndex; + ScriptInfo script = null; + if (scriptIndex > -1) { + script = pack.abc.script_info.get(scriptIndex); + } + boolean parallel = Configuration.parallelSpeedUp.get(); + HighlightedTextWriter writer = new HighlightedTextWriter(Configuration.getCodeFormatting(), true); + pack.toSource(writer, script.traits.traits, ScriptExportMode.AS, parallel); + HighlightedText hilightedCode = new HighlightedText(writer); + CachedDecompilation res = new CachedDecompilation(hilightedCode); + swf.as3Cache.put(pack, res); + + return res; + } + + public static RECT fixRect(RECT rect) { + RECT ret = new RECT(); + ret.Xmin = rect.Xmin; + ret.Xmax = rect.Xmax; + ret.Ymin = rect.Ymin; + ret.Ymax = rect.Ymax; + + if (ret.Xmax <= 0) { + ret.Xmax = ret.getWidth(); + ret.Xmin = 0; + } + if (ret.Ymax <= 0) { + ret.Ymax = ret.getHeight(); + ret.Ymin = 0; + } + if (ret.Xmin < 0) { + ret.Xmax += (-ret.Xmin); + ret.Xmin = 0; + } + if (ret.Ymin < 0) { + ret.Ymax += (-ret.Ymin); + ret.Ymin = 0; + } + + if (ret.getWidth() < 1 || ret.getHeight() < 1) { + ret.Xmin = 0; + ret.Ymin = 0; + ret.Xmax = 20; + ret.Ymax = 20; + } + return ret; + } + + public static void frameToSvg(Timeline timeline, int frame, int time, DepthState stateUnderCursor, int mouseButton, SVGExporter exporter, ColorTransform colorTransform, int level, double zoom) throws IOException { + if (timeline.getFrameCount() <= frame) { + return; + } + Frame frameObj = timeline.getFrame(frame); + List clips = new ArrayList<>(); + List prevClips = new ArrayList<>(); + + int maxDepth = timeline.getMaxDepth(); + for (int i = 1; i <= maxDepth; i++) { + for (int c = 0; c < clips.size(); c++) { + if (clips.get(c).depth == i) { + exporter.setClip(prevClips.get(c)); + prevClips.remove(c); + clips.remove(c); + } + } + if (!frameObj.layers.containsKey(i)) { + continue; + } + DepthState layer = frameObj.layers.get(i); + if (!timeline.swf.getCharacters().containsKey(layer.characterId)) { + continue; + } + if (!layer.isVisible) { + continue; + } + + CharacterTag character = timeline.swf.getCharacter(layer.characterId); + if (colorTransform == null) { + colorTransform = new ColorTransform(); + } + + ColorTransform clrTrans = colorTransform.clone(); + if (layer.colorTransForm != null && layer.blendMode <= 1) { // Normal blend mode + clrTrans = colorTransform.merge(layer.colorTransForm); + } + + if (character instanceof DrawableTag) { + DrawableTag drawable = (DrawableTag) character; + + String assetName; + Tag drawableTag = (Tag) drawable; + RECT boundRect = drawable.getRect(); + if (exporter.exportedTags.containsKey(drawableTag)) { + assetName = exporter.exportedTags.get(drawableTag); + } else { + assetName = getTagIdPrefix(drawableTag, exporter); + exporter.exportedTags.put(drawableTag, assetName); + exporter.createDefGroup(new ExportRectangle(boundRect), assetName); + drawable.toSVG(exporter, layer.ratio, clrTrans, level + 1, zoom); + exporter.endGroup(); + } + ExportRectangle rect = new ExportRectangle(boundRect); + + // TODO: if (layer.filters != null) + // TODO: if (layer.blendMode > 1) + if (layer.clipDepth > -1) { + String clipName = exporter.getUniqueId("clipPath"); + exporter.createClipPath(new Matrix(), clipName); + SvgClip clip = new SvgClip(clipName, layer.clipDepth); + clips.add(clip); + prevClips.add(exporter.getClip()); + Matrix mat = Matrix.getTranslateInstance(rect.xMin, rect.yMin).preConcatenate(new Matrix(layer.matrix)); + exporter.addUse(mat, boundRect, assetName); + exporter.setClip(clip.shape); + exporter.endGroup(); + } else { + Matrix mat = Matrix.getTranslateInstance(rect.xMin, rect.yMin).preConcatenate(new Matrix(layer.matrix)); + exporter.addUse(mat, boundRect, assetName); + } + } + } + } + + private static String getTagIdPrefix(Tag tag, SVGExporter exporter) { + if (tag instanceof ShapeTag) { + return exporter.getUniqueId("shape"); + } + if (tag instanceof MorphShapeTag) { + return exporter.getUniqueId("morphshape"); + } + if (tag instanceof DefineSpriteTag) { + return exporter.getUniqueId("sprite"); + } + if (tag instanceof TextTag) { + return exporter.getUniqueId("text"); + } + if (tag instanceof ButtonTag) { + return exporter.getUniqueId("button"); + } + return exporter.getUniqueId("tag"); + } + + public static SerializableImage frameToImageGet(Timeline timeline, int frame, int time, DepthState stateUnderCursor, int mouseButton, RECT displayRect, Matrix transformation, ColorTransform colorTransform, Color backGroundColor, boolean useCache, double zoom) { + SWF swf = timeline.swf; + String key = "frame_" + frame + "_" + timeline.id + "_" + swf.hashCode() + "_" + zoom; + SerializableImage image; + if (useCache) { + image = swf.getFromCache(key); + if (image != null) { + return image; + } + } + + if (timeline.getFrameCount() == 0) { + return new SerializableImage(1, 1, SerializableImage.TYPE_INT_ARGB); + } + + RECT rect = displayRect; + image = new SerializableImage((int) (rect.getWidth() * zoom / SWF.unitDivisor) + 1, + (int) (rect.getHeight() * zoom / SWF.unitDivisor) + 1, SerializableImage.TYPE_INT_ARGB); + if (backGroundColor == null) { + image.fillTransparent(); + } else { + Graphics2D g = (Graphics2D) image.getBufferedImage().getGraphics(); + g.setComposite(AlphaComposite.Src); + g.setColor(backGroundColor); + g.fill(new Rectangle(image.getWidth(), image.getHeight())); + } + + Matrix m = transformation.clone(); + m.translate(-rect.Xmin * zoom, -rect.Ymin * zoom); + m.scale(zoom); + RenderContext renderContext = new RenderContext(); + renderContext.stateUnderCursor = stateUnderCursor; + renderContext.mouseButton = mouseButton; + frameToImage(timeline, frame, time, renderContext, image, m, colorTransform); + if (useCache) { + swf.putToCache(key, image); + } + + return image; + } + + public static void framesToImage(Timeline timeline, List ret, int startFrame, int stopFrame, RenderContext renderContext, RECT displayRect, int totalFrameCount, Stack visited, Matrix transformation, ColorTransform colorTransform, double zoom) { + RECT rect = displayRect; + for (int f = 0; f < timeline.getFrameCount(); f++) { + SerializableImage image = new SerializableImage((int) (rect.getWidth() / SWF.unitDivisor) + 1, + (int) (rect.getHeight() / SWF.unitDivisor) + 1, SerializableImage.TYPE_INT_ARGB); + image.fillTransparent(); + Matrix m = new Matrix(); + m.translate(-rect.Xmin, -rect.Ymin); + frameToImage(timeline, f, 0, renderContext, image, m, colorTransform); + ret.add(image); + } + } + + public static void frameToImage(Timeline timeline, int frame, int time, RenderContext renderContext, SerializableImage image, Matrix transformation, ColorTransform colorTransform) { + double unzoom = SWF.unitDivisor; + if (timeline.getFrameCount() <= frame) { + return; + } + Frame frameObj = timeline.getFrame(frame); + Graphics2D g = (Graphics2D) image.getGraphics(); + g.setPaint(frameObj.backgroundColor.toColor()); + g.fill(new Rectangle(image.getWidth(), image.getHeight())); + g.setTransform(transformation.toTransform()); + List clips = new ArrayList<>(); + List prevClips = new ArrayList<>(); + + int maxDepth = timeline.getMaxDepth(); + for (int i = 1; i <= maxDepth; i++) { + for (int c = 0; c < clips.size(); c++) { + if (clips.get(c).depth == i) { + g.setClip(prevClips.get(c)); + prevClips.remove(c); + clips.remove(c); + } + } + if (!frameObj.layers.containsKey(i)) { + continue; + } + DepthState layer = frameObj.layers.get(i); + if (!timeline.swf.getCharacters().containsKey(layer.characterId)) { + continue; + } + if (!layer.isVisible) { + continue; + } + + CharacterTag character = timeline.swf.getCharacter(layer.characterId); + Matrix mat = new Matrix(layer.matrix); + mat = mat.preConcatenate(transformation); + + if (colorTransform == null) { + colorTransform = new ColorTransform(); + } + + ColorTransform clrTrans = colorTransform.clone(); + if (layer.colorTransForm != null && layer.blendMode <= 1) { // Normal blend mode + clrTrans = colorTransform.merge(layer.colorTransForm); + } + + boolean showPlaceholder = false; + if (character instanceof DrawableTag) { + DrawableTag drawable = (DrawableTag) character; + Matrix drawMatrix = new Matrix(); + int drawableFrameCount = drawable.getNumFrames(); + if (drawableFrameCount == 0) { + drawableFrameCount = 1; + } + + int dframe; + if (timeline.fontFrameNum != -1) { + dframe = timeline.fontFrameNum; + } else { + dframe = (time + layer.time) % drawableFrameCount; + } + + if (character instanceof ButtonTag) { + dframe = ButtonTag.FRAME_UP; + if (renderContext.stateUnderCursor == layer) { + if (renderContext.mouseButton > 0) { + dframe = ButtonTag.FRAME_DOWN; + } else { + dframe = ButtonTag.FRAME_OVER; + } + } + } + + RECT boundRect = drawable.getRect(); + ExportRectangle rect = new ExportRectangle(boundRect); + rect = mat.transform(rect); + Matrix m = mat.clone(); + if (layer.filters != null && layer.filters.size() > 0) { + // calculate size after applying the filters + double deltaXMax = 0; + double deltaYMax = 0; + for (FILTER filter : layer.filters) { + double x = filter.getDeltaX(); + double y = filter.getDeltaY(); + deltaXMax = Math.max(x, deltaXMax); + deltaYMax = Math.max(y, deltaYMax); + } + rect.xMin -= deltaXMax * unzoom; + rect.xMax += deltaXMax * unzoom; + rect.yMin -= deltaYMax * unzoom; + rect.yMax += deltaYMax * unzoom; + } + + rect.xMin -= 1 * unzoom; + rect.yMin -= 1 * unzoom; + rect.xMin = Math.max(0, rect.xMin); + rect.yMin = Math.max(0, rect.yMin); + + int newWidth = (int) (rect.getWidth() / unzoom); + int newHeight = (int) (rect.getHeight() / unzoom); + int deltaX = (int) (rect.xMin / unzoom); + int deltaY = (int) (rect.yMin / unzoom); + newWidth = Math.min(image.getWidth() - deltaX, newWidth) + 1; + newHeight = Math.min(image.getHeight() - deltaY, newHeight) + 1; + + if (newWidth <= 0 || newHeight <= 0) { + continue; + } + + m.translate(-rect.xMin, -rect.yMin); + drawMatrix.translate(rect.xMin, rect.yMin); + + SerializableImage img = null; + String cacheKey = null; + if (drawable instanceof ShapeTag) { + cacheKey = ((ShapeTag) drawable).getCharacterId() + m.toString() + clrTrans.toString(); + img = renderContext.shapeCache.get(cacheKey); + } + + if (img == null) { + img = new SerializableImage(newWidth, newHeight, SerializableImage.TYPE_INT_ARGB); + img.fillTransparent(); + + drawable.toImage(dframe, layer.time + time, layer.ratio, renderContext, img, m, clrTrans); + + if (cacheKey != null) { + renderContext.shapeCache.put(cacheKey, img); + } + } + + /*//if (renderContext.stateUnderCursor == layer) { + if (true) { + BufferedImage bi = img.getBufferedImage(); + ColorModel cm = bi.getColorModel(); + boolean isAlphaPremultiplied = cm.isAlphaPremultiplied(); + WritableRaster raster = bi.copyData(null); + img = new SerializableImage(new BufferedImage(cm, raster, isAlphaPremultiplied, null)); + Graphics2D gg = (Graphics2D) img.getGraphics(); + gg.setStroke(new BasicStroke(3)); + gg.setPaint(Color.red); + gg.setTransform(AffineTransform.getTranslateInstance(0, 0)); + gg.draw(SHAPERECORD.twipToPixelShape(drawable.getOutline(dframe, layer.time + time, layer.ratio, renderContext, m))); + }*/ + if (layer.filters != null) { + for (FILTER filter : layer.filters) { + img = filter.apply(img); + } + } + if (layer.blendMode > 1) { + if (layer.colorTransForm != null) { + img = layer.colorTransForm.apply(img); + } + } + + drawMatrix.translateX /= unzoom; + drawMatrix.translateY /= unzoom; + AffineTransform trans = drawMatrix.toTransform(); + + switch (layer.blendMode) { + case 0: + case 1: + g.setComposite(AlphaComposite.SrcOver); + break; + case 2: // Layer + g.setComposite(AlphaComposite.SrcOver); + break; + case 3: + g.setComposite(BlendComposite.Multiply); + break; + case 4: + g.setComposite(BlendComposite.Screen); + break; + case 5: + g.setComposite(BlendComposite.Lighten); + break; + case 6: + g.setComposite(BlendComposite.Darken); + break; + case 7: + g.setComposite(BlendComposite.Difference); + break; + case 8: + g.setComposite(BlendComposite.Add); + break; + case 9: + g.setComposite(BlendComposite.Subtract); + break; + case 10: + g.setComposite(BlendComposite.Invert); + break; + case 11: + g.setComposite(BlendComposite.Alpha); + break; + case 12: + g.setComposite(BlendComposite.Erase); + break; + case 13: + g.setComposite(BlendComposite.Overlay); + break; + case 14: + g.setComposite(BlendComposite.HardLight); + break; + default: // Not implemented + g.setComposite(AlphaComposite.SrcOver); + break; + } + + if (layer.clipDepth > -1) { + BufferedImage mask = new BufferedImage(image.getWidth(), image.getHeight(), image.getType()); + Graphics2D gm = (Graphics2D) mask.getGraphics(); + gm.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); + gm.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); + gm.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + gm.setComposite(AlphaComposite.Src); + gm.setColor(new Color(0, 0, 0, 0f)); + gm.fillRect(0, 0, image.getWidth(), image.getHeight()); + gm.setTransform(trans); + gm.drawImage(img.getBufferedImage(), 0, 0, null); + Clip clip = new Clip(Helper.imageToShape(mask), layer.clipDepth); // Maybe we can get current outline instead converting from image (?) + clips.add(clip); + prevClips.add(g.getClip()); + g.setTransform(AffineTransform.getTranslateInstance(0, 0)); + g.setClip(clip.shape); + } else { + g.setTransform(trans); + g.drawImage(img.getBufferedImage(), 0, 0, null); + } + } else if (character instanceof BoundedTag) { + showPlaceholder = true; + } + + if (showPlaceholder) { + mat.translateX /= unzoom; + mat.translateY /= unzoom; + AffineTransform trans = mat.toTransform(); + g.setTransform(trans); + BoundedTag b = (BoundedTag) character; + g.setPaint(new Color(255, 255, 255, 128)); + g.setComposite(BlendComposite.Invert); + RECT r = b.getRect(); + int div = (int) unzoom; + g.drawString(character.toString(), r.Xmin / div + 3, r.Ymin / div + 15); + g.draw(new Rectangle(r.Xmin / div, r.Ymin / div, r.getWidth() / div, r.getHeight() / div)); + g.drawLine(r.Xmin / div, r.Ymin / div, r.Xmax / div, r.Ymax / div); + g.drawLine(r.Xmax / div, r.Ymin / div, r.Xmin / div, r.Ymax / div); + g.setComposite(AlphaComposite.Dst); + } + } + + g.setTransform(AffineTransform.getScaleInstance(1, 1)); + } + + private void removeTagWithDependenciesFromTimeline(Tag toRemove, Timeline timeline) { + int characterId = 0; + if (toRemove instanceof CharacterTag) { + characterId = ((CharacterTag) toRemove).getCharacterId(); + } + Map stage = new HashMap<>(); + + Set dependingChars = new HashSet<>(); + if (characterId != 0) { + dependingChars.add(characterId); + for (int i = 0; i < timeline.tags.size(); i++) { + Tag t = timeline.tags.get(i); + if (t instanceof CharacterIdTag) { + CharacterIdTag c = (CharacterIdTag) t; + Set needed = new HashSet<>(); + t.getNeededCharacters(needed); + if (needed.contains(characterId)) { + dependingChars.add(c.getCharacterId()); + } + } + } + } + + for (int i = 0; i < timeline.tags.size(); i++) { + Tag t = timeline.tags.get(i); + if (t instanceof RemoveTag) { + RemoveTag rt = (RemoveTag) t; + int depth = rt.getDepth(); + if (stage.containsKey(depth)) { + int currentCharId = stage.get(depth); + stage.remove(depth); + if (dependingChars.contains(currentCharId)) { + timeline.tags.remove(i); + i--; + continue; + } + } + } + if (t instanceof PlaceObjectTypeTag) { + PlaceObjectTypeTag po = (PlaceObjectTypeTag) t; + int placeCharId = po.getCharacterId(); + int depth = po.getDepth(); + if (placeCharId != 0) { + stage.put(depth, placeCharId); + if (dependingChars.contains(placeCharId)) { + timeline.tags.remove(i); + i--; + continue; + } + } + } + if (t instanceof CharacterIdTag) { + CharacterIdTag c = (CharacterIdTag) t; + if (dependingChars.contains(c.getCharacterId())) { + timeline.tags.remove(i); + i--; + continue; + } + } + Set needed = new HashSet<>(); + t.getNeededCharacters(needed); + for (int dep : dependingChars) { + if (needed.contains(dep)) { + timeline.tags.remove(i); + i--; + continue; + } + } + if (t == toRemove) { + timeline.tags.remove(i); + i--; + continue; + } + if (t instanceof Timelined) { + removeTagWithDependenciesFromTimeline(toRemove, ((Timelined) t).getTimeline()); + } + } + } + + private boolean removeTagFromTimeline(Tag toRemove, Timeline timeline) { + boolean modified = false; + int characterId = -1; + if (toRemove instanceof CharacterTag) { + characterId = ((CharacterTag) toRemove).getCharacterId(); + modified = timeline.removeCharacter(characterId); + } + for (int i = 0; i < timeline.tags.size(); i++) { + Tag t = timeline.tags.get(i); + if (t == toRemove) { + timeline.tags.remove(t); + i--; + continue; + } + + if (toRemove instanceof CharacterTag) { + if (t.removeCharacter(characterId)) { + modified = true; + i = -1; + continue; + } + } + + if (t instanceof DefineSpriteTag) { + DefineSpriteTag spr = (DefineSpriteTag) t; + boolean sprModified = removeTagFromTimeline(toRemove, spr.getTimeline()); + if (sprModified) { + spr.setModified(true); + } + modified |= sprModified; + } + } + return modified; + } + + public void removeTags(Collection tags, boolean removeDependencies) { + Set timelineds = new HashSet<>(); + for (Tag tag : tags) { + Timelined timelined = tag.getTimelined(); + timelineds.add(timelined); + removeTagInternal(timelined, tag, removeDependencies); + } + + for (Timelined timelined : timelineds) { + resetTimelines(timelined); + } + + updateCharacters(); + clearImageCache(); + } + + public void removeTag(Tag tag, boolean removeDependencies) { + Timelined timelined = tag.getTimelined(); + removeTagInternal(timelined, tag, removeDependencies); + resetTimelines(timelined); + updateCharacters(); + clearImageCache(); + } + + private void removeTagInternal(Timelined timelined, Tag tag, boolean removeDependencies) { + if (tag instanceof ShowFrameTag || ShowFrameTag.isNestedTagType(tag.getId())) { + List tags; + if (timelined instanceof DefineSpriteTag) { + DefineSpriteTag sprite = (DefineSpriteTag) timelined; + tags = sprite.getSubTags(); + } else { + tags = this.tags; + } + tags.remove(tag); + if (timelined instanceof DefineSpriteTag) { + DefineSpriteTag sprite = (DefineSpriteTag) timelined; + sprite.setModified(true); + } + timelined.resetTimeline(); + } else { + // timeline should be always the swf here + if (removeDependencies) { + removeTagWithDependenciesFromTimeline(tag, timelined.getTimeline()); + if (timelined instanceof DefineSpriteTag) { + DefineSpriteTag sprite = (DefineSpriteTag) timelined; + sprite.setModified(true); + } + } else { + removeTagFromTimeline(tag, timeline); + } + } + } + + @Override + public String toString() { + return getShortFileName(); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWFInputStream.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWFInputStream.java index dd4f0c853..87b09bbae 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWFInputStream.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWFInputStream.java @@ -1,3372 +1,3372 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash; - -import com.jpexs.decompiler.flash.action.Action; -import com.jpexs.decompiler.flash.action.special.ActionEnd; -import com.jpexs.decompiler.flash.action.special.ActionNop; -import com.jpexs.decompiler.flash.action.swf3.ActionGetURL; -import com.jpexs.decompiler.flash.action.swf3.ActionGoToLabel; -import com.jpexs.decompiler.flash.action.swf3.ActionGotoFrame; -import com.jpexs.decompiler.flash.action.swf3.ActionNextFrame; -import com.jpexs.decompiler.flash.action.swf3.ActionPlay; -import com.jpexs.decompiler.flash.action.swf3.ActionPrevFrame; -import com.jpexs.decompiler.flash.action.swf3.ActionSetTarget; -import com.jpexs.decompiler.flash.action.swf3.ActionStop; -import com.jpexs.decompiler.flash.action.swf3.ActionStopSounds; -import com.jpexs.decompiler.flash.action.swf3.ActionToggleQuality; -import com.jpexs.decompiler.flash.action.swf3.ActionWaitForFrame; -import com.jpexs.decompiler.flash.action.swf4.ActionAdd; -import com.jpexs.decompiler.flash.action.swf4.ActionAnd; -import com.jpexs.decompiler.flash.action.swf4.ActionAsciiToChar; -import com.jpexs.decompiler.flash.action.swf4.ActionCall; -import com.jpexs.decompiler.flash.action.swf4.ActionCharToAscii; -import com.jpexs.decompiler.flash.action.swf4.ActionCloneSprite; -import com.jpexs.decompiler.flash.action.swf4.ActionDivide; -import com.jpexs.decompiler.flash.action.swf4.ActionEndDrag; -import com.jpexs.decompiler.flash.action.swf4.ActionEquals; -import com.jpexs.decompiler.flash.action.swf4.ActionGetProperty; -import com.jpexs.decompiler.flash.action.swf4.ActionGetTime; -import com.jpexs.decompiler.flash.action.swf4.ActionGetURL2; -import com.jpexs.decompiler.flash.action.swf4.ActionGetVariable; -import com.jpexs.decompiler.flash.action.swf4.ActionGotoFrame2; -import com.jpexs.decompiler.flash.action.swf4.ActionIf; -import com.jpexs.decompiler.flash.action.swf4.ActionJump; -import com.jpexs.decompiler.flash.action.swf4.ActionLess; -import com.jpexs.decompiler.flash.action.swf4.ActionMBAsciiToChar; -import com.jpexs.decompiler.flash.action.swf4.ActionMBCharToAscii; -import com.jpexs.decompiler.flash.action.swf4.ActionMBStringExtract; -import com.jpexs.decompiler.flash.action.swf4.ActionMBStringLength; -import com.jpexs.decompiler.flash.action.swf4.ActionMultiply; -import com.jpexs.decompiler.flash.action.swf4.ActionNot; -import com.jpexs.decompiler.flash.action.swf4.ActionOr; -import com.jpexs.decompiler.flash.action.swf4.ActionPop; -import com.jpexs.decompiler.flash.action.swf4.ActionPush; -import com.jpexs.decompiler.flash.action.swf4.ActionRandomNumber; -import com.jpexs.decompiler.flash.action.swf4.ActionRemoveSprite; -import com.jpexs.decompiler.flash.action.swf4.ActionSetProperty; -import com.jpexs.decompiler.flash.action.swf4.ActionSetTarget2; -import com.jpexs.decompiler.flash.action.swf4.ActionSetVariable; -import com.jpexs.decompiler.flash.action.swf4.ActionStartDrag; -import com.jpexs.decompiler.flash.action.swf4.ActionStringAdd; -import com.jpexs.decompiler.flash.action.swf4.ActionStringEquals; -import com.jpexs.decompiler.flash.action.swf4.ActionStringExtract; -import com.jpexs.decompiler.flash.action.swf4.ActionStringLength; -import com.jpexs.decompiler.flash.action.swf4.ActionStringLess; -import com.jpexs.decompiler.flash.action.swf4.ActionSubtract; -import com.jpexs.decompiler.flash.action.swf4.ActionToInteger; -import com.jpexs.decompiler.flash.action.swf4.ActionTrace; -import com.jpexs.decompiler.flash.action.swf4.ActionWaitForFrame2; -import com.jpexs.decompiler.flash.action.swf5.ActionAdd2; -import com.jpexs.decompiler.flash.action.swf5.ActionBitAnd; -import com.jpexs.decompiler.flash.action.swf5.ActionBitLShift; -import com.jpexs.decompiler.flash.action.swf5.ActionBitOr; -import com.jpexs.decompiler.flash.action.swf5.ActionBitRShift; -import com.jpexs.decompiler.flash.action.swf5.ActionBitURShift; -import com.jpexs.decompiler.flash.action.swf5.ActionBitXor; -import com.jpexs.decompiler.flash.action.swf5.ActionCallFunction; -import com.jpexs.decompiler.flash.action.swf5.ActionCallMethod; -import com.jpexs.decompiler.flash.action.swf5.ActionConstantPool; -import com.jpexs.decompiler.flash.action.swf5.ActionDecrement; -import com.jpexs.decompiler.flash.action.swf5.ActionDefineFunction; -import com.jpexs.decompiler.flash.action.swf5.ActionDefineLocal; -import com.jpexs.decompiler.flash.action.swf5.ActionDefineLocal2; -import com.jpexs.decompiler.flash.action.swf5.ActionDelete; -import com.jpexs.decompiler.flash.action.swf5.ActionDelete2; -import com.jpexs.decompiler.flash.action.swf5.ActionEnumerate; -import com.jpexs.decompiler.flash.action.swf5.ActionEquals2; -import com.jpexs.decompiler.flash.action.swf5.ActionGetMember; -import com.jpexs.decompiler.flash.action.swf5.ActionIncrement; -import com.jpexs.decompiler.flash.action.swf5.ActionInitArray; -import com.jpexs.decompiler.flash.action.swf5.ActionInitObject; -import com.jpexs.decompiler.flash.action.swf5.ActionLess2; -import com.jpexs.decompiler.flash.action.swf5.ActionModulo; -import com.jpexs.decompiler.flash.action.swf5.ActionNewMethod; -import com.jpexs.decompiler.flash.action.swf5.ActionNewObject; -import com.jpexs.decompiler.flash.action.swf5.ActionPushDuplicate; -import com.jpexs.decompiler.flash.action.swf5.ActionReturn; -import com.jpexs.decompiler.flash.action.swf5.ActionSetMember; -import com.jpexs.decompiler.flash.action.swf5.ActionStackSwap; -import com.jpexs.decompiler.flash.action.swf5.ActionStoreRegister; -import com.jpexs.decompiler.flash.action.swf5.ActionTargetPath; -import com.jpexs.decompiler.flash.action.swf5.ActionToNumber; -import com.jpexs.decompiler.flash.action.swf5.ActionToString; -import com.jpexs.decompiler.flash.action.swf5.ActionTypeOf; -import com.jpexs.decompiler.flash.action.swf5.ActionWith; -import com.jpexs.decompiler.flash.action.swf6.ActionEnumerate2; -import com.jpexs.decompiler.flash.action.swf6.ActionGreater; -import com.jpexs.decompiler.flash.action.swf6.ActionInstanceOf; -import com.jpexs.decompiler.flash.action.swf6.ActionStrictEquals; -import com.jpexs.decompiler.flash.action.swf6.ActionStringGreater; -import com.jpexs.decompiler.flash.action.swf7.ActionCastOp; -import com.jpexs.decompiler.flash.action.swf7.ActionDefineFunction2; -import com.jpexs.decompiler.flash.action.swf7.ActionExtends; -import com.jpexs.decompiler.flash.action.swf7.ActionImplementsOp; -import com.jpexs.decompiler.flash.action.swf7.ActionThrow; -import com.jpexs.decompiler.flash.action.swf7.ActionTry; -import com.jpexs.decompiler.flash.configuration.Configuration; -import com.jpexs.decompiler.flash.dumpview.DumpInfo; -import com.jpexs.decompiler.flash.tags.CSMTextSettingsTag; -import com.jpexs.decompiler.flash.tags.DebugIDTag; -import com.jpexs.decompiler.flash.tags.DefineBinaryDataTag; -import com.jpexs.decompiler.flash.tags.DefineBitsJPEG2Tag; -import com.jpexs.decompiler.flash.tags.DefineBitsJPEG3Tag; -import com.jpexs.decompiler.flash.tags.DefineBitsJPEG4Tag; -import com.jpexs.decompiler.flash.tags.DefineBitsLossless2Tag; -import com.jpexs.decompiler.flash.tags.DefineBitsLosslessTag; -import com.jpexs.decompiler.flash.tags.DefineBitsTag; -import com.jpexs.decompiler.flash.tags.DefineButton2Tag; -import com.jpexs.decompiler.flash.tags.DefineButtonCxformTag; -import com.jpexs.decompiler.flash.tags.DefineButtonSoundTag; -import com.jpexs.decompiler.flash.tags.DefineButtonTag; -import com.jpexs.decompiler.flash.tags.DefineEditTextTag; -import com.jpexs.decompiler.flash.tags.DefineFont2Tag; -import com.jpexs.decompiler.flash.tags.DefineFont3Tag; -import com.jpexs.decompiler.flash.tags.DefineFont4Tag; -import com.jpexs.decompiler.flash.tags.DefineFontAlignZonesTag; -import com.jpexs.decompiler.flash.tags.DefineFontInfo2Tag; -import com.jpexs.decompiler.flash.tags.DefineFontInfoTag; -import com.jpexs.decompiler.flash.tags.DefineFontNameTag; -import com.jpexs.decompiler.flash.tags.DefineFontTag; -import com.jpexs.decompiler.flash.tags.DefineMorphShape2Tag; -import com.jpexs.decompiler.flash.tags.DefineMorphShapeTag; -import com.jpexs.decompiler.flash.tags.DefineScalingGridTag; -import com.jpexs.decompiler.flash.tags.DefineSceneAndFrameLabelDataTag; -import com.jpexs.decompiler.flash.tags.DefineShape2Tag; -import com.jpexs.decompiler.flash.tags.DefineShape3Tag; -import com.jpexs.decompiler.flash.tags.DefineShape4Tag; -import com.jpexs.decompiler.flash.tags.DefineShapeTag; -import com.jpexs.decompiler.flash.tags.DefineSoundTag; -import com.jpexs.decompiler.flash.tags.DefineSpriteTag; -import com.jpexs.decompiler.flash.tags.DefineText2Tag; -import com.jpexs.decompiler.flash.tags.DefineTextTag; -import com.jpexs.decompiler.flash.tags.DefineVideoStreamTag; -import com.jpexs.decompiler.flash.tags.DoABCDefineTag; -import com.jpexs.decompiler.flash.tags.DoABCTag; -import com.jpexs.decompiler.flash.tags.DoActionTag; -import com.jpexs.decompiler.flash.tags.DoInitActionTag; -import com.jpexs.decompiler.flash.tags.EnableDebugger2Tag; -import com.jpexs.decompiler.flash.tags.EnableDebuggerTag; -import com.jpexs.decompiler.flash.tags.EnableTelemetryTag; -import com.jpexs.decompiler.flash.tags.EndTag; -import com.jpexs.decompiler.flash.tags.ExportAssetsTag; -import com.jpexs.decompiler.flash.tags.FileAttributesTag; -import com.jpexs.decompiler.flash.tags.FrameLabelTag; -import com.jpexs.decompiler.flash.tags.ImportAssets2Tag; -import com.jpexs.decompiler.flash.tags.ImportAssetsTag; -import com.jpexs.decompiler.flash.tags.JPEGTablesTag; -import com.jpexs.decompiler.flash.tags.MetadataTag; -import com.jpexs.decompiler.flash.tags.PlaceObject2Tag; -import com.jpexs.decompiler.flash.tags.PlaceObject3Tag; -import com.jpexs.decompiler.flash.tags.PlaceObject4Tag; -import com.jpexs.decompiler.flash.tags.PlaceObjectTag; -import com.jpexs.decompiler.flash.tags.ProductInfoTag; -import com.jpexs.decompiler.flash.tags.ProtectTag; -import com.jpexs.decompiler.flash.tags.RemoveObject2Tag; -import com.jpexs.decompiler.flash.tags.RemoveObjectTag; -import com.jpexs.decompiler.flash.tags.ScriptLimitsTag; -import com.jpexs.decompiler.flash.tags.SetBackgroundColorTag; -import com.jpexs.decompiler.flash.tags.SetTabIndexTag; -import com.jpexs.decompiler.flash.tags.ShowFrameTag; -import com.jpexs.decompiler.flash.tags.SoundStreamBlockTag; -import com.jpexs.decompiler.flash.tags.SoundStreamHead2Tag; -import com.jpexs.decompiler.flash.tags.SoundStreamHeadTag; -import com.jpexs.decompiler.flash.tags.StartSound2Tag; -import com.jpexs.decompiler.flash.tags.StartSoundTag; -import com.jpexs.decompiler.flash.tags.SymbolClassTag; -import com.jpexs.decompiler.flash.tags.Tag; -import com.jpexs.decompiler.flash.tags.TagStub; -import com.jpexs.decompiler.flash.tags.UnknownTag; -import com.jpexs.decompiler.flash.tags.VideoFrameTag; -import com.jpexs.decompiler.flash.tags.gfx.DefineCompactedFont; -import com.jpexs.decompiler.flash.tags.gfx.DefineExternalGradient; -import com.jpexs.decompiler.flash.tags.gfx.DefineExternalImage; -import com.jpexs.decompiler.flash.tags.gfx.DefineExternalImage2; -import com.jpexs.decompiler.flash.tags.gfx.DefineExternalSound; -import com.jpexs.decompiler.flash.tags.gfx.DefineExternalStreamSound; -import com.jpexs.decompiler.flash.tags.gfx.DefineGradientMap; -import com.jpexs.decompiler.flash.tags.gfx.DefineSubImage; -import com.jpexs.decompiler.flash.tags.gfx.ExporterInfo; -import com.jpexs.decompiler.flash.tags.gfx.FontTextureInfo; -import com.jpexs.decompiler.flash.timeline.Timelined; -import com.jpexs.decompiler.flash.types.ALPHABITMAPDATA; -import com.jpexs.decompiler.flash.types.ALPHACOLORMAPDATA; -import com.jpexs.decompiler.flash.types.ARGB; -import com.jpexs.decompiler.flash.types.BITMAPDATA; -import com.jpexs.decompiler.flash.types.BUTTONCONDACTION; -import com.jpexs.decompiler.flash.types.BUTTONRECORD; -import com.jpexs.decompiler.flash.types.CLIPACTIONRECORD; -import com.jpexs.decompiler.flash.types.CLIPACTIONS; -import com.jpexs.decompiler.flash.types.CLIPEVENTFLAGS; -import com.jpexs.decompiler.flash.types.COLORMAPDATA; -import com.jpexs.decompiler.flash.types.CXFORM; -import com.jpexs.decompiler.flash.types.CXFORMWITHALPHA; -import com.jpexs.decompiler.flash.types.FILLSTYLE; -import com.jpexs.decompiler.flash.types.FILLSTYLEARRAY; -import com.jpexs.decompiler.flash.types.FOCALGRADIENT; -import com.jpexs.decompiler.flash.types.GLYPHENTRY; -import com.jpexs.decompiler.flash.types.GRADIENT; -import com.jpexs.decompiler.flash.types.GRADRECORD; -import com.jpexs.decompiler.flash.types.KERNINGRECORD; -import com.jpexs.decompiler.flash.types.LANGCODE; -import com.jpexs.decompiler.flash.types.LINESTYLE; -import com.jpexs.decompiler.flash.types.LINESTYLE2; -import com.jpexs.decompiler.flash.types.LINESTYLEARRAY; -import com.jpexs.decompiler.flash.types.MATRIX; -import com.jpexs.decompiler.flash.types.MORPHFILLSTYLE; -import com.jpexs.decompiler.flash.types.MORPHFILLSTYLEARRAY; -import com.jpexs.decompiler.flash.types.MORPHFOCALGRADIENT; -import com.jpexs.decompiler.flash.types.MORPHGRADIENT; -import com.jpexs.decompiler.flash.types.MORPHGRADRECORD; -import com.jpexs.decompiler.flash.types.MORPHLINESTYLE; -import com.jpexs.decompiler.flash.types.MORPHLINESTYLE2; -import com.jpexs.decompiler.flash.types.MORPHLINESTYLEARRAY; -import com.jpexs.decompiler.flash.types.PIX15; -import com.jpexs.decompiler.flash.types.PIX24; -import com.jpexs.decompiler.flash.types.RECT; -import com.jpexs.decompiler.flash.types.RGB; -import com.jpexs.decompiler.flash.types.RGBA; -import com.jpexs.decompiler.flash.types.SHAPE; -import com.jpexs.decompiler.flash.types.SHAPEWITHSTYLE; -import com.jpexs.decompiler.flash.types.SOUNDENVELOPE; -import com.jpexs.decompiler.flash.types.SOUNDINFO; -import com.jpexs.decompiler.flash.types.TEXTRECORD; -import com.jpexs.decompiler.flash.types.ZONEDATA; -import com.jpexs.decompiler.flash.types.ZONERECORD; -import com.jpexs.decompiler.flash.types.filters.BEVELFILTER; -import com.jpexs.decompiler.flash.types.filters.BLURFILTER; -import com.jpexs.decompiler.flash.types.filters.COLORMATRIXFILTER; -import com.jpexs.decompiler.flash.types.filters.CONVOLUTIONFILTER; -import com.jpexs.decompiler.flash.types.filters.DROPSHADOWFILTER; -import com.jpexs.decompiler.flash.types.filters.FILTER; -import com.jpexs.decompiler.flash.types.filters.GLOWFILTER; -import com.jpexs.decompiler.flash.types.filters.GRADIENTBEVELFILTER; -import com.jpexs.decompiler.flash.types.filters.GRADIENTGLOWFILTER; -import com.jpexs.decompiler.flash.types.shaperecords.CurvedEdgeRecord; -import com.jpexs.decompiler.flash.types.shaperecords.EndShapeRecord; -import com.jpexs.decompiler.flash.types.shaperecords.SHAPERECORD; -import com.jpexs.decompiler.flash.types.shaperecords.StraightEdgeRecord; -import com.jpexs.decompiler.flash.types.shaperecords.StyleChangeRecord; -import com.jpexs.helpers.ByteArrayRange; -import com.jpexs.helpers.Helper; -import com.jpexs.helpers.ImmediateFuture; -import com.jpexs.helpers.MemoryInputStream; -import com.jpexs.helpers.ProgressListener; -import com.jpexs.helpers.utf8.Utf8Helper; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.EOFException; -import java.io.IOException; -import java.io.PrintStream; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.util.zip.InflaterInputStream; - -/** - * Class for reading data from SWF file - * - * @author JPEXS - */ -public class SWFInputStream implements AutoCloseable { - - private MemoryInputStream is; - - private long startingPos; - - private static final Logger logger = Logger.getLogger(SWFInputStream.class.getName()); - - private final List listeners = new ArrayList<>(); - - private long percentMax; - - private SWF swf; - - public DumpInfo dumpInfo; - - public void addPercentListener(ProgressListener listener) { - listeners.add(listener); - } - - public void removePercentListener(ProgressListener listener) { - int index = listeners.indexOf(listener); - if (index > -1) { - listeners.remove(index); - } - } - - private void informListeners() { - if (listeners.size() > 0 && percentMax > 0) { - int percent = (int) (getPos() * 100 / percentMax); - if (lastPercent != percent) { - for (ProgressListener pl : listeners) { - pl.progress(percent); - } - lastPercent = percent; - } - } - } - - public void setPercentMax(long percentMax) { - this.percentMax = percentMax; - } - - /** - * Constructor - * - * @param swf SWF to read - * @param data SWF data - * @param startingPos - * @param limit - * @throws java.io.IOException - */ - public SWFInputStream(SWF swf, byte[] data, long startingPos, int limit) throws IOException { - this.swf = swf; - this.startingPos = startingPos; - is = new MemoryInputStream(data, 0, limit); - } - - /** - * Constructor - * - * @param swf SWF to read - * @param data SWF data - * @throws java.io.IOException - */ - public SWFInputStream(SWF swf, byte[] data) throws IOException { - this(swf, data, 0L, data.length); - } - - public SWF getSwf() { - return swf; - } - - /** - * Gets position in bytes in the stream - * - * @return Number of bytes - */ - public long getPos() { - return startingPos + is.getPos(); - } - - /** - * Sets position in bytes in the stream - * - * @param pos Number of bytes - * @throws java.io.IOException - */ - public void seek(long pos) throws IOException { - is.seek(pos - startingPos); - } - - private void newDumpLevel(String name, String type) { - if (dumpInfo != null) { - long startByte = is.getPos(); - if (bitPos > 0) { - startByte--; - } - DumpInfo di = new DumpInfo(name, type, null, startByte, bitPos, 0, 0); - di.parent = dumpInfo; - dumpInfo.getChildInfos().add(di); - dumpInfo = di; - } - } - - private void endDumpLevel() { - endDumpLevel(null); - } - - private void endDumpLevel(Object value) { - if (dumpInfo != null) { - if (dumpInfo.startBit == 0 && bitPos == 0) { - dumpInfo.lengthBytes = is.getPos() - dumpInfo.startByte; - } else { - dumpInfo.lengthBits = (int) ((is.getPos() - dumpInfo.startByte - 1) * 8 - dumpInfo.startBit + (bitPos == 0 ? 8 : bitPos)); - } - dumpInfo.previewValue = value; - dumpInfo = dumpInfo.parent; - } - } - - private void endDumpLevelUntil(DumpInfo di) { - if (di != null) { - while (dumpInfo != null && dumpInfo != di) { - endDumpLevel(); - } - } - } - - /** - * Reads one byte from the stream - * - * @return byte - * @throws IOException - */ - private int readEx() throws IOException { - bitPos = 0; - return readNoBitReset(); - } - - private void alignByte() { - bitPos = 0; - } - - private int lastPercent = -1; - - private int readNoBitReset() throws IOException, EndOfStreamException { - int r = is.read(); - if (r == -1) { - throw new EndOfStreamException(); - } - - informListeners(); - return r; - } - - /** - * Reads one UI8 (Unsigned 8bit integer) value from the stream - * - * @param name - * @return UI8 value or -1 on error - * @throws IOException - */ - public int readUI8(String name) throws IOException { - newDumpLevel(name, "UI8"); - int ret = readEx(); - endDumpLevel(ret); - return ret; - } - - /** - * Reads one string value from the stream - * - * @param name - * @return String value - * @throws IOException - */ - public String readString(String name) throws IOException { - newDumpLevel(name, "string"); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - int r; - while (true) { - r = readEx(); - if (r == 0) { - endDumpLevel(); - return new String(baos.toByteArray(), Utf8Helper.charset); - } - baos.write(r); - } - } - - /** - * Reads one UI32 (Unsigned 32bit integer) value from the stream - * - * @param name - * @return UI32 value - * @throws IOException - */ - public long readUI32(String name) throws IOException { - newDumpLevel(name, "UI32"); - long ret = readUI32Internal(); - endDumpLevel(ret); - return ret; - } - - /** - * Reads one UI32 (Unsigned 32bit integer) value from the stream - * - * @return UI32 value - * @throws IOException - */ - private long readUI32Internal() throws IOException { - return (readEx() + (readEx() << 8) + (readEx() << 16) + (readEx() << 24)) & 0xffffffff; - } - - /** - * Reads one UI16 (Unsigned 16bit integer) value from the stream - * - * @param name - * @return UI16 value - * @throws IOException - */ - public int readUI16(String name) throws IOException { - newDumpLevel(name, "UI16"); - int ret = readUI16Internal(); - endDumpLevel(ret); - return ret; - } - - /** - * Reads one UI16 (Unsigned 16bit integer) value from the stream - * - * @return UI16 value - * @throws IOException - */ - private int readUI16Internal() throws IOException { - return readEx() + (readEx() << 8); - } - - public int readUI24(String name) throws IOException { - newDumpLevel(name, "UI24"); - int ret = readEx() + (readEx() << 8) + (readEx() << 16); - endDumpLevel(ret); - return ret; - } - - /** - * Reads one SI32 (Signed 32bit integer) value from the stream - * - * @param name - * @return SI32 value - * @throws IOException - */ - public long readSI32(String name) throws IOException { - newDumpLevel(name, "SI32"); - long uval = readEx() + (readEx() << 8) + (readEx() << 16) + (readEx() << 24); - if (uval >= 0x80000000) { - uval = -(((~uval) & 0xffffffff) + 1); - } - endDumpLevel(uval); - return uval; - } - - /** - * Reads one SI16 (Signed 16bit integer) value from the stream - * - * @param name - * @return SI16 value - * @throws IOException - */ - public int readSI16(String name) throws IOException { - newDumpLevel(name, "SI16"); - int uval = readEx() + (readEx() << 8); - if (uval >= 0x8000) { - uval = -(((~uval) & 0xffff) + 1); - } - endDumpLevel(uval); - return uval; - } - - /** - * Reads one SI8 (Signed 8bit integer) value from the stream - * - * @param name - * @return SI8 value - * @throws IOException - */ - public int readSI8(String name) throws IOException { - newDumpLevel(name, "SI8"); - int uval = readEx(); - if (uval >= 0x80) { - uval = -(((~uval) & 0xff) + 1); - } - endDumpLevel(uval); - return uval; - } - - /** - * Reads one FIXED (Fixed point 16.16) value from the stream - * - * @param name - * @return FIXED value - * @throws IOException - */ - public double readFIXED(String name) throws IOException { - newDumpLevel(name, "FIXED"); - int afterPoint = readUI16Internal(); - int beforePoint = readUI16Internal(); - double ret = ((double) ((beforePoint << 16) + afterPoint)) / 65536; - endDumpLevel(ret); - return ret; - } - - /** - * Reads one FIXED8 (Fixed point 8.8) value from the stream - * - * @param name - * @return FIXED8 value - * @throws IOException - */ - public float readFIXED8(String name) throws IOException { - newDumpLevel(name, "FIXED8"); - int afterPoint = readEx(); - int beforePoint = readEx(); - float ret = beforePoint + (((float) afterPoint) / 256); - endDumpLevel(ret); - return ret; - } - - private long readLong() throws IOException { - byte[] readBuffer = readBytesInternalEx(8); - return (((long) readBuffer[3] << 56) - + ((long) (readBuffer[2] & 255) << 48) - + ((long) (readBuffer[1] & 255) << 40) - + ((long) (readBuffer[0] & 255) << 32) - + ((long) (readBuffer[7] & 255) << 24) - + ((readBuffer[6] & 255) << 16) - + ((readBuffer[5] & 255) << 8) - + ((readBuffer[4] & 255))); - } - - /** - * Reads one DOUBLE (double precision floating point value) value from the - * stream - * - * @param name - * @return DOUBLE value - * @throws IOException - */ - public double readDOUBLE(String name) throws IOException { - newDumpLevel(name, "DOUBLE"); - long el = readLong(); - double ret = Double.longBitsToDouble(el); - endDumpLevel(ret); - return ret; - } - - /** - * Reads one FLOAT (single precision floating point value) value from the - * stream - * - * @param name - * @return FLOAT value - * @throws IOException - */ - public float readFLOAT(String name) throws IOException { - newDumpLevel(name, "FLOAT"); - int val = (int) readUI32Internal(); - float ret = Float.intBitsToFloat(val); - endDumpLevel(ret); - /*int sign = val >> 31; - int mantisa = val & 0x3FFFFF; - int exp = (val >> 22) & 0xFF; - float ret =(sign == 1 ? -1 : 1) * (float) Math.pow(2, exp)* (1+((mantisa)/ (float)(1<<23)));*/ - return ret; - } - - /** - * Reads one FLOAT16 (16bit floating point value) value from the stream - * - * @param name - * @return FLOAT16 value - * @throws IOException - */ - public float readFLOAT16(String name) throws IOException { - newDumpLevel(name, "FLOAT16"); - int val = readUI16Internal(); - int sign = val >> 15; - int mantisa = val & 0x3FF; - int exp = (val >> 10) & 0x1F; - float ret = (sign == 1 ? -1 : 1) * (float) Math.pow(2, exp) * (1 + ((mantisa) / (float) (1 << 10))); - endDumpLevel(ret); - return ret; - } - - /** - * Reads bytes from the stream - * - * @param count Number of bytes to read - * @param name - * @return Array of read bytes - * @throws IOException - */ - public byte[] readBytesEx(long count, String name) throws IOException { - if (count <= 0) { - return new byte[0]; - } - newDumpLevel(name, "bytes"); - byte[] ret = readBytesInternalEx(count); - endDumpLevel(); - return ret; - } - - /** - * Reads byte range from the stream - * - * @param count Number of bytes to read - * @param name - * @return ByteArrayRange object - * @throws IOException - */ - public ByteArrayRange readByteRangeEx(long count, String name) throws IOException { - if (count <= 0) { - return ByteArrayRange.EMPTY; - } - newDumpLevel(name, "bytes"); - int startPos = (int) getPos(); - skipBytesEx(count); - endDumpLevel(); - return new ByteArrayRange(swf.uncompressedData, startPos, (int) count); - } - - /** - * Reads bytes from the stream - * - * @param count Number of bytes to read - * @return Array of read bytes - * @throws IOException - */ - private byte[] readBytesInternalEx(long count) throws IOException { - if (count <= 0) { - return new byte[0]; - } - - bitPos = 0; - byte[] ret = new byte[(int) count]; - if (is.read(ret) != count) { - throw new EndOfStreamException(); - } - - informListeners(); - return ret; - } - - /** - * Skip bytes from the stream - * - * @param count Number of bytes to skip - * @throws IOException - */ - public void skipBytesEx(long count) throws IOException { - if (count <= 0) { - return; - } - - bitPos = 0; - is.seek(is.getPos() + count); - if (is.available() < 0) { - throw new EndOfStreamException(); - } - - informListeners(); - } - - /** - * Skip bytes from the stream - * - * @param count Number of bytes to skip - * @throws IOException - */ - public void skipBytes(long count) throws IOException { - try { - skipBytesEx(count); - } catch (EOFException | EndOfStreamException ex) { - logger.log(Level.SEVERE, null, ex); - } - } - - /** - * Reads bytes from the stream - * - * @param count Number of bytes to read - * @param name - * @return Array of read bytes - * @throws IOException - */ - public byte[] readBytes(int count, String name) throws IOException { - if (count <= 0) { - return new byte[0]; - } - newDumpLevel(name, "bytes"); - byte[] ret = new byte[count]; - int i = 0; - try { - for (i = 0; i < count; i++) { - ret[i] = (byte) readEx(); - } - } catch (EOFException | EndOfStreamException ex) { - ret = Arrays.copyOf(ret, i); // truncate array - logger.log(Level.SEVERE, null, ex); - } - endDumpLevel(); - return ret; - } - - public byte[] readBytesZlib(long count, String name) throws IOException { - newDumpLevel(name, "bytesZlib"); - byte[] data = readBytesInternalEx(count); - endDumpLevel(); - InflaterInputStream dis = new InflaterInputStream(new ByteArrayInputStream(data)); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - if (count > 0) { - byte[] buf = new byte[4096]; - int c = 0; - while ((c = dis.read(buf)) > 0) { - baos.write(buf, 0, c); - } - } - return baos.toByteArray(); - } - - /** - * Reads one EncodedU32 (Encoded unsigned 32bit value) value from the stream - * - * @param name - * @return U32 value - * @throws IOException - */ - public long readEncodedU32(String name) throws IOException { - newDumpLevel(name, "encodedU32"); - int result = readEx(); - if ((result & 0x00000080) == 0) { - endDumpLevel(result); - return result; - } - result = (result & 0x0000007f) | (readEx()) << 7; - if ((result & 0x00004000) == 0) { - endDumpLevel(result); - return result; - } - result = (result & 0x00003fff) | (readEx()) << 14; - if ((result & 0x00200000) == 0) { - endDumpLevel(result); - return result; - } - result = (result & 0x001fffff) | (readEx()) << 21; - if ((result & 0x10000000) == 0) { - endDumpLevel(result); - return result; - } - result = (result & 0x0fffffff) | (readEx()) << 28; - endDumpLevel(result); - return result; - } - - private int bitPos = 0; - - private int tempByte = 0; - - /** - * Reads UB[nBits] (Unsigned-bit value) value from the stream - * - * @param nBits Number of bits which represent value - * @param name - * @return Unsigned value - * @throws IOException - */ - public long readUB(int nBits, String name) throws IOException { - if (nBits == 0) { - return 0; - } - newDumpLevel(name, "UB"); - long ret = readUBInternal(nBits); - endDumpLevel(ret); - return ret; - } - - /** - * Reads UB[nBits] (Unsigned-bit value) value from the stream - * - * @param nBits Number of bits which represent value - * @return Unsigned value - * @throws IOException - */ - private long readUBInternal(int nBits) throws IOException { - if (nBits == 0) { - return 0; - } - long ret = 0; - if (bitPos == 0) { - tempByte = readNoBitReset(); - } - for (int bit = 0; bit < nBits; bit++) { - int nb = (tempByte >> (7 - bitPos)) & 1; - ret += (nb << (nBits - 1 - bit)); - bitPos++; - if (bitPos == 8) { - bitPos = 0; - if (bit != nBits - 1) { - tempByte = readNoBitReset(); - } - } - } - return ret; - } - - /** - * Reads SB[nBits] (Signed-bit value) value from the stream - * - * @param nBits Number of bits which represent value - * @param name - * @return Signed value - * @throws IOException - */ - public long readSB(int nBits, String name) throws IOException { - if (nBits == 0) { - return 0; - } - newDumpLevel(name, "SB"); - long ret = readSBInternal(nBits); - endDumpLevel(ret); - return ret; - } - - /** - * Reads SB[nBits] (Signed-bit value) value from the stream - * - * @param nBits Number of bits which represent value - * @return Signed value - * @throws IOException - */ - private long readSBInternal(int nBits) throws IOException { - int uval = (int) readUBInternal(nBits); - - int shift = 32 - nBits; - // sign extension - uval = (uval << shift) >> shift; - return uval; - } - - /** - * Reads FB[nBits] (Signed fixed-point bit value) value from the stream - * - * @param nBits Number of bits which represent value - * @param name - * @return Fixed-point value - * @throws IOException - */ - public float readFB(int nBits, String name) throws IOException { - if (nBits == 0) { - return 0; - } - newDumpLevel(name, "FB"); - float val = readSBInternal(nBits); - float ret = val / 0x10000; - endDumpLevel(ret); - return ret; - } - - /** - * Reads one RECT value from the stream - * - * @param name - * @return RECT value - * @throws IOException - */ - public RECT readRECT(String name) throws IOException { - RECT ret = new RECT(); - newDumpLevel(name, "RECT"); - int NBits = (int) readUB(5, "NBits"); - ret.Xmin = (int) readSB(NBits, "Xmin"); - ret.Xmax = (int) readSB(NBits, "Xmax"); - ret.Ymin = (int) readSB(NBits, "Ymin"); - ret.Ymax = (int) readSB(NBits, "Ymax"); - ret.nbits = NBits; - alignByte(); - endDumpLevel(); - return ret; - } - - private static void dumpTag(PrintStream out, int version, Tag tag, int level) { - StringBuilder sb = new StringBuilder(); - sb.append(Helper.formatHex((int) tag.getPos(), 8)); - sb.append(": "); - sb.append(Helper.indent(level, "", " ")); - sb.append(Helper.format(tag.toString(), 25 - 2 * level)); - sb.append(" tagId="); - sb.append(Helper.formatInt(tag.getId(), 3)); - sb.append(" len="); - sb.append(Helper.formatInt(tag.getOriginalDataLength(), 8)); - sb.append(" "); - sb.append(Helper.bytesToHexString(64, tag.getOriginalData(), 0)); - out.println(sb.toString()); - // out.println(Utils.formatHex((int)tag.getPos(), 8) + ": " + Utils.indent(level, "") + Utils.format(tag.toString(), 25 - 2*level) + " tagId="+tag.getId()+" len="+tag.getOrigDataLength()+": "+Utils.bytesToHexString(64, tag.getData(version), 0)); - if (tag instanceof DefineSpriteTag) { - for (Tag subTag : ((DefineSpriteTag) tag).getSubTags()) { - dumpTag(out, version, subTag, level + 1); - } - } - } - - @Override - public void close() { - } - - private class TagResolutionTask implements Callable { - - private final TagStub tag; - - private final DumpInfo dumpInfo; - - private final int level; - - private final boolean parallel; - - private final boolean skipUnusualTags; - - private final boolean lazy; - - public TagResolutionTask(TagStub tag, DumpInfo dumpInfo, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) { - this.tag = tag; - this.dumpInfo = dumpInfo; - this.level = level; - this.parallel = parallel; - this.skipUnusualTags = skipUnusualTags; - this.lazy = lazy; - } - - @Override - public Tag call() throws Exception { - DumpInfo di = dumpInfo; - try { - Tag t = resolveTag(tag, level, parallel, skipUnusualTags, lazy); - if (dumpInfo != null && t != null) { - dumpInfo.name = t.getName(); - } - return t; - } catch (Exception ex) { - tag.getDataStream().endDumpLevelUntil(di); - logger.log(Level.SEVERE, null, ex); - return tag; - } - } - } - - /** - * Reads list of tags from the stream. Reading ends with End tag(=0) or end - * of the stream. Optionally can skip AS1/2 tags when file is AS3 - * - * @param timelined - * @param level - * @param parallel - * @param skipUnusualTags - * @param parseTags - * @param lazy - * @return List of tags - * @throws IOException - * @throws java.lang.InterruptedException - */ - public List readTagList(Timelined timelined, int level, boolean parallel, boolean skipUnusualTags, boolean parseTags, boolean lazy) throws IOException, InterruptedException { - if (Thread.currentThread().interrupted()) { - throw new InterruptedException(); - } - - boolean parallel1 = level == 0 && parallel; - ExecutorService executor = null; - List> futureResults = new ArrayList<>(); - if (parallel1) { - executor = Executors.newFixedThreadPool(Configuration.getParallelThreadCount()); - futureResults = new ArrayList<>(); - } - List tags = new ArrayList<>(); - Tag tag; - boolean isAS3 = false; - while (available() > 0) { - long pos = getPos(); - newDumpLevel(null, "TAG"); - try { - tag = readTag(timelined, level, pos, parseTags && !parallel1, parallel1, skipUnusualTags, lazy); - } catch (EOFException | EndOfStreamException ex) { - tag = null; - } - DumpInfo di = dumpInfo; - if (di != null && tag != null) { - di.name = tag.getName(); - } - endDumpLevel(tag == null ? null : tag.getId()); - if (tag == null) { - break; - } - - tag.setTimelined(timelined); - if (!parallel1) { - tags.add(tag); - } - if (Configuration.dumpTags.get() && level == 0) { - dumpTag(System.out, swf.version, tag, level); - } - - boolean doParse; - if (!skipUnusualTags) { - doParse = true; - } else { - switch (tag.getId()) { - case FileAttributesTag.ID: // FileAttributes - if (tag instanceof TagStub) { - tag = resolveTag((TagStub) tag, level, parallel1, skipUnusualTags, lazy); - } - FileAttributesTag fileAttributes = (FileAttributesTag) tag; - if (fileAttributes.actionScript3) { - isAS3 = true; - } - doParse = true; - break; - case DoActionTag.ID: - case DoInitActionTag.ID: - if (isAS3) { - doParse = false; - } else { - doParse = true; - } - break; - case ShowFrameTag.ID: - case PlaceObjectTag.ID: - case PlaceObject2Tag.ID: - case RemoveObjectTag.ID: - case RemoveObject2Tag.ID: - case PlaceObject3Tag.ID: // ? - case StartSoundTag.ID: - case FrameLabelTag.ID: - case SoundStreamHeadTag.ID: - case SoundStreamHead2Tag.ID: - case SoundStreamBlockTag.ID: - case VideoFrameTag.ID: - case EndTag.ID: - doParse = true; - break; - default: - if (level > 0) { //No such tags in DefineSprite allowed - logger.log(Level.FINE, "Tag({0}) found in DefineSprite => Ignored", tag.getId()); - doParse = false; - } else { - doParse = true; - } - - } - } - if (parseTags && doParse && parallel1 && tag instanceof TagStub) { - Future future = executor.submit(new TagResolutionTask((TagStub) tag, di, level, parallel1, skipUnusualTags, lazy)); - futureResults.add(future); - } else { - Future future = new ImmediateFuture<>(tag); - futureResults.add(future); - if (!(tag instanceof TagStub)) { - if (di != null) { - di.name = tag.getName(); - } - } - } - - if (tag.getId() == EndTag.ID) { - break; - } - } - - if (parallel1) { - for (Future future : futureResults) { - try { - tags.add(future.get()); - } catch (InterruptedException ex) { - future.cancel(true); - } catch (ExecutionException e) { - logger.log(Level.SEVERE, "Error during tag reading", e); - } - } - - executor.shutdown(); - } - return tags; - } - - public static Tag resolveTag(TagStub tag, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws InterruptedException { - Tag ret; - - ByteArrayRange data = tag.getOriginalRange(); - SWF swf = tag.getSwf(); - SWFInputStream sis = tag.getDataStream(); - - try { - switch (tag.getId()) { - case 0: - ret = new EndTag(sis, data); - break; - case 1: - ret = new ShowFrameTag(sis, data); - break; - case 2: - ret = new DefineShapeTag(sis, data, lazy); - break; - //case 3: FreeCharacter - case 4: - ret = new PlaceObjectTag(sis, data); - break; - case 5: - ret = new RemoveObjectTag(sis, data); - break; - case 6: - ret = new DefineBitsTag(sis, data); - break; - case 7: - ret = new DefineButtonTag(sis, data); - break; - case 8: - ret = new JPEGTablesTag(sis, data); - break; - case 9: - ret = new SetBackgroundColorTag(sis, data); - break; - case 10: - ret = new DefineFontTag(sis, data); - break; - case 11: - ret = new DefineTextTag(sis, data); - break; - case 12: - ret = new DoActionTag(sis, data); - break; - case 13: - ret = new DefineFontInfoTag(sis, data); - break; - case 14: - ret = new DefineSoundTag(sis, data); - break; - case 15: - ret = new StartSoundTag(sis, data); - break; - //case 16: StopSound - case 17: - ret = new DefineButtonSoundTag(sis, data); - break; - case 18: - ret = new SoundStreamHeadTag(sis, data); - break; - case 19: - ret = new SoundStreamBlockTag(sis, data); - break; - case 20: - ret = new DefineBitsLosslessTag(sis, data); - break; - case 21: - ret = new DefineBitsJPEG2Tag(sis, data); - break; - case 22: - ret = new DefineShape2Tag(sis, data, lazy); - break; - case 23: - ret = new DefineButtonCxformTag(sis, data); - break; - case 24: - ret = new ProtectTag(sis, data); - break; - //case 25: PathsArePostscript - case 26: - ret = new PlaceObject2Tag(sis, data); - break; - //case 27: - case 28: - ret = new RemoveObject2Tag(sis, data); - break; - //case 29: SyncFrame - //case 30: - //case 31: FreeAll - case 32: - ret = new DefineShape3Tag(sis, data, lazy); - break; - case 33: - ret = new DefineText2Tag(sis, data); - break; - case 34: - ret = new DefineButton2Tag(sis, data); - break; - case 35: - ret = new DefineBitsJPEG3Tag(sis, data); - break; - case 36: - ret = new DefineBitsLossless2Tag(sis, data); - break; - case 37: - ret = new DefineEditTextTag(sis, data); - break; - //case 38: DefineVideo - case 39: - ret = new DefineSpriteTag(sis, level, data, parallel, skipUnusualTags); - break; - //case 40: NameCharacter - case 41: - ret = new ProductInfoTag(sis, data); - break; - //case 42: DefineTextFormat - case 43: - ret = new FrameLabelTag(sis, data); - break; - //case 44: DefineBehavior - case 45: - ret = new SoundStreamHead2Tag(sis, data); - break; - case 46: - ret = new DefineMorphShapeTag(sis, data); - break; - //case 47: GenerateFrame - case 48: - ret = new DefineFont2Tag(sis, data); - break; - //case 49: GeneratorCommand - //case 50: DefineCommandObject - //case 51: CharacterSet - //case 52: ExternalFont - //case 53: DefineFunction - //case 54: PlaceFunction - //case 55: GenTagObject - case 56: - ret = new ExportAssetsTag(sis, data); - break; - case 57: - ret = new ImportAssetsTag(sis, data); - break; - case 58: - ret = new EnableDebuggerTag(sis, data); - break; - case 59: - ret = new DoInitActionTag(sis, data); - break; - case 60: - ret = new DefineVideoStreamTag(sis, data); - break; - case 61: - ret = new VideoFrameTag(sis, data); - break; - case 62: - ret = new DefineFontInfo2Tag(sis, data); - break; - case 63: - ret = new DebugIDTag(sis, data); - break; - case 64: - ret = new EnableDebugger2Tag(sis, data); - break; - case 65: - ret = new ScriptLimitsTag(sis, data); - break; - case 66: - ret = new SetTabIndexTag(sis, data); - break; - //case 67: DefineShape4 ??? - //case 68: DefineMorphShape2 ??? - case 69: - ret = new FileAttributesTag(sis, data); - break; - case 70: - ret = new PlaceObject3Tag(sis, data); - break; - case 71: - ret = new ImportAssets2Tag(sis, data); - break; - case 72: - ret = new DoABCTag(sis, data); - break; - case 73: - ret = new DefineFontAlignZonesTag(sis, data); - break; - case 74: - ret = new CSMTextSettingsTag(sis, data); - break; - case 75: - ret = new DefineFont3Tag(sis, data); - break; - case 76: - ret = new SymbolClassTag(sis, data); - break; - case 77: - ret = new MetadataTag(sis, data); - break; - case 78: - ret = new DefineScalingGridTag(sis, data); - break; - //case 79-81: - case 82: - ret = new DoABCDefineTag(sis, data); - break; - case 83: - ret = new DefineShape4Tag(sis, data, lazy); - break; - case 84: - ret = new DefineMorphShape2Tag(sis, data); - break; - //case 85: - case 86: - ret = new DefineSceneAndFrameLabelDataTag(sis, data); - break; - case 87: - ret = new DefineBinaryDataTag(sis, data); - break; - case 88: - ret = new DefineFontNameTag(sis, data); - break; - case 89: - ret = new StartSound2Tag(sis, data); - break; - case 90: - ret = new DefineBitsJPEG4Tag(sis, data); - break; - case 91: - ret = new DefineFont4Tag(sis, data); - break; - //case 92: certificate - case 93: - ret = new EnableTelemetryTag(sis, data); - break; - case 94: - ret = new PlaceObject4Tag(sis, data); - break; - default: - if (swf.gfx) { // GFX tags only in GFX files. There may be incorrect GFX tags in non GFX files - switch (tag.getId()) { - case 1000: - ret = new ExporterInfo(sis, data); - break; - case 1001: - ret = new DefineExternalImage(sis, data); - break; - case 1002: - ret = new FontTextureInfo(sis, data); - break; - case 1003: - ret = new DefineExternalGradient(sis, data); - break; - case 1004: - ret = new DefineGradientMap(sis, data); - break; - case 1005: - ret = new DefineCompactedFont(sis, data); - break; - case 1006: - ret = new DefineExternalSound(sis, data); - break; - case 1007: - ret = new DefineExternalStreamSound(sis, data); - break; - case 1008: - ret = new DefineSubImage(sis, data); - break; - case 1009: - ret = new DefineExternalImage2(sis, data); - break; - default: - ret = new UnknownTag(swf, tag.getId(), data); - } - } else { - ret = new UnknownTag(swf, tag.getId(), data); - } - } - } catch (IOException ex) { - logger.log(Level.SEVERE, "Error during tag reading. SWF: " + swf.getShortFileName() + " ID: " + tag.getId() + " name: " + tag.getName() + " pos: " + data.getPos(), ex); - ret = new TagStub(swf, tag.getId(), "ErrorTag", data, null); - } - ret.forceWriteAsLong = tag.forceWriteAsLong; - ret.setTimelined(tag.getTimelined()); - return ret; - } - - /** - * Reads one Tag from the stream with optional resolving (= reading tag - * content) - * - * @param timelined - * @param level - * @param pos - * @param resolve - * @param parallel - * @param skipUnusualTags - * @param lazy - * @return Tag or null when End tag - * @throws IOException - * @throws java.lang.InterruptedException - */ - public Tag readTag(Timelined timelined, int level, long pos, boolean resolve, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException, InterruptedException { - int tagIDTagLength = readUI16("tagIDTagLength"); - int tagID = (tagIDTagLength) >> 6; - - logger.log(Level.FINE, "Reading tag. ID={0}, position: {1}", new Object[]{tagID, pos}); - - long tagLength = (tagIDTagLength & 0x003F); - boolean readLong = false; - if (tagLength == 0x3f) { - tagLength = readSI32("tagLength"); - readLong = true; - } - int headerLength = readLong ? 6 : 2; - SWFInputStream tagDataStream = getLimitedStream((int) tagLength); - int available = available(); - if (tagLength > available) { - tagLength = available; - } - - ByteArrayRange dataRange = new ByteArrayRange(swf.uncompressedData, (int) pos, (int) (tagLength + headerLength)); - skipBytes(tagLength); - - TagStub tagStub = new TagStub(swf, tagID, "Unresolved", dataRange, tagDataStream); - tagStub.forceWriteAsLong = readLong; - Tag ret = tagStub; - - if (tagDataStream.dumpInfo == null && dumpInfo != null) { - dumpInfo.tagToResolve = tagStub; - } - - if (resolve) { - DumpInfo di = dumpInfo; - try { - ret = resolveTag(tagStub, level, parallel, skipUnusualTags, lazy); - } catch (Exception ex) { - tagDataStream.endDumpLevelUntil(di); - logger.log(Level.SEVERE, "Problem in " + timelined.toString(), ex); - } - - if (Configuration.debugMode.get()) { - byte[] data = ret.getOriginalData(); - byte[] dataNew = ret.getData(); - int ignoreFirst = 0; - for (int i = 0; i < data.length; i++) { - if (i >= dataNew.length) { - break; - } - if (dataNew[i] != data[i]) { - if (ignoreFirst > 0) { - ignoreFirst--; - continue; - } - String e = "TAG " + ret.toString() + " WRONG, "; - for (int j = i - 10; j <= i + 5; j++) { - while (j < 0) { - j++; - } - if (j >= data.length) { - break; - } - if (j >= dataNew.length) { - break; - } - if (j >= i) { - e += (Long.toHexString(data[j] & 0xff) + " ( is " + Long.toHexString(dataNew[j] & 0xff) + ") "); - } else { - e += (Long.toHexString(data[j] & 0xff) + " "); - } - } - logger.fine(e); - } - } - } - } - return ret; - } - - /** - * Reads one Action from the stream - * - * @return Action or null when ActionEndFlag or end of the stream - * @throws IOException - */ - public Action readAction() throws IOException { - int actionCode = -1; - - try { - actionCode = readUI8("actionCode"); - if (actionCode == 0) { - return new ActionEnd(); - } - if (actionCode == -1) { - return null; - } - int actionLength = 0; - if (actionCode >= 0x80) { - actionLength = readUI16("actionLength"); - } - switch (actionCode) { - // SWF3 Actions - case 0x81: - return new ActionGotoFrame(actionLength, this); - case 0x83: - return new ActionGetURL(actionLength, this, swf.version); - case 0x04: - return new ActionNextFrame(); - case 0x05: - return new ActionPrevFrame(); - case 0x06: - return new ActionPlay(); - case 0x07: - return new ActionStop(); - case 0x08: - return new ActionToggleQuality(); - case 0x09: - return new ActionStopSounds(); - case 0x8A: - return new ActionWaitForFrame(actionLength, this); - case 0x8B: - return new ActionSetTarget(actionLength, this, swf.version); - case 0x8C: - return new ActionGoToLabel(actionLength, this, swf.version); - // SWF4 Actions - case 0x96: - return new ActionPush(actionLength, this, swf.version); - case 0x17: - return new ActionPop(); - case 0x0A: - return new ActionAdd(); - case 0x0B: - return new ActionSubtract(); - case 0x0C: - return new ActionMultiply(); - case 0x0D: - return new ActionDivide(); - case 0x0E: - return new ActionEquals(); - case 0x0F: - return new ActionLess(); - case 0x10: - return new ActionAnd(); - case 0x11: - return new ActionOr(); - case 0x12: - return new ActionNot(); - case 0x13: - return new ActionStringEquals(); - case 0x14: - return new ActionStringLength(); - case 0x21: - return new ActionStringAdd(); - case 0x15: - return new ActionStringExtract(); - case 0x29: - return new ActionStringLess(); - case 0x31: - return new ActionMBStringLength(); - case 0x35: - return new ActionMBStringExtract(); - case 0x18: - return new ActionToInteger(); - case 0x32: - return new ActionCharToAscii(); - case 0x33: - return new ActionAsciiToChar(); - case 0x36: - return new ActionMBCharToAscii(); - case 0x37: - return new ActionMBAsciiToChar(); - case 0x99: - return new ActionJump(actionLength, this); - case 0x9D: - return new ActionIf(actionLength, this); - case 0x9E: - return new ActionCall(actionLength); - case 0x1C: - return new ActionGetVariable(); - case 0x1D: - return new ActionSetVariable(); - case 0x9A: - return new ActionGetURL2(actionLength, this); - case 0x9F: - return new ActionGotoFrame2(actionLength, this); - case 0x20: - return new ActionSetTarget2(); - case 0x22: - return new ActionGetProperty(); - case 0x23: - return new ActionSetProperty(); - case 0x24: - return new ActionCloneSprite(); - case 0x25: - return new ActionRemoveSprite(); - case 0x27: - return new ActionStartDrag(); - case 0x28: - return new ActionEndDrag(); - case 0x8D: - return new ActionWaitForFrame2(actionLength, this); - case 0x26: - return new ActionTrace(); - case 0x34: - return new ActionGetTime(); - case 0x30: - return new ActionRandomNumber(); - // SWF5 Actions - case 0x3D: - return new ActionCallFunction(); - case 0x52: - return new ActionCallMethod(); - case 0x88: - return new ActionConstantPool(actionLength, this, swf.version); - case 0x9B: - return new ActionDefineFunction(actionLength, this, swf.version); - case 0x3C: - return new ActionDefineLocal(); - case 0x41: - return new ActionDefineLocal2(); - case 0x3A: - return new ActionDelete(); - case 0x3B: - return new ActionDelete2(); - case 0x46: - return new ActionEnumerate(); - case 0x49: - return new ActionEquals2(); - case 0x4E: - return new ActionGetMember(); - case 0x42: - return new ActionInitArray(); - case 0x43: - return new ActionInitObject(); - case 0x53: - return new ActionNewMethod(); - case 0x40: - return new ActionNewObject(); - case 0x4F: - return new ActionSetMember(); - case 0x45: - return new ActionTargetPath(); - case 0x94: - return new ActionWith(actionLength, this, swf.version); - case 0x4A: - return new ActionToNumber(); - case 0x4B: - return new ActionToString(); - case 0x44: - return new ActionTypeOf(); - case 0x47: - return new ActionAdd2(); - case 0x48: - return new ActionLess2(); - case 0x3F: - return new ActionModulo(); - case 0x60: - return new ActionBitAnd(); - case 0x63: - return new ActionBitLShift(); - case 0x61: - return new ActionBitOr(); - case 0x64: - return new ActionBitRShift(); - case 0x65: - return new ActionBitURShift(); - case 0x62: - return new ActionBitXor(); - case 0x51: - return new ActionDecrement(); - case 0x50: - return new ActionIncrement(); - case 0x4C: - return new ActionPushDuplicate(); - case 0x3E: - return new ActionReturn(); - case 0x4D: - return new ActionStackSwap(); - case 0x87: - return new ActionStoreRegister(actionLength, this); - // SWF6 Actions - case 0x54: - return new ActionInstanceOf(); - case 0x55: - return new ActionEnumerate2(); - case 0x66: - return new ActionStrictEquals(); - case 0x67: - return new ActionGreater(); - case 0x68: - return new ActionStringGreater(); - // SWF7 Actions - case 0x8E: - return new ActionDefineFunction2(actionLength, this, swf.version); - case 0x69: - return new ActionExtends(); - case 0x2B: - return new ActionCastOp(); - case 0x2C: - return new ActionImplementsOp(); - case 0x8F: - return new ActionTry(actionLength, this, swf.version); - case 0x2A: - return new ActionThrow(); - default: - /*if (actionLength > 0) { - //skip(actionLength); - }*/ - //throw new UnknownActionException(actionCode); - Action r = new ActionNop(); - r.actionCode = actionCode; - r.actionLength = actionLength; - if (Configuration.useDetailedLogging.get()) { - logger.log(Level.SEVERE, "Unknown action code: {0}", actionCode); - } - return r; - } - } catch (EndOfStreamException | ArrayIndexOutOfBoundsException eos) { - return null; - } - } - - /** - * Reads one MATRIX value from the stream - * - * @param name - * @return MATRIX value - * @throws IOException - */ - public MATRIX readMatrix(String name) throws IOException { - MATRIX ret = new MATRIX(); - newDumpLevel(name, "MATRIX"); - ret.hasScale = readUB(1, "hasScale") == 1; - if (ret.hasScale) { - int NScaleBits = (int) readUB(5, "NScaleBits"); - ret.scaleX = (int) readSB(NScaleBits, "scaleX"); - ret.scaleY = (int) readSB(NScaleBits, "scaleY"); - ret.nScaleBits = NScaleBits; - } - ret.hasRotate = readUB(1, "hasRotate") == 1; - if (ret.hasRotate) { - int NRotateBits = (int) readUB(5, "NRotateBits"); - ret.rotateSkew0 = (int) readSB(NRotateBits, "rotateSkew0"); - ret.rotateSkew1 = (int) readSB(NRotateBits, "rotateSkew1"); - ret.nRotateBits = NRotateBits; - } - int NTranslateBits = (int) readUB(5, "NTranslateBits"); - ret.translateX = (int) readSB(NTranslateBits, "translateX"); - ret.translateY = (int) readSB(NTranslateBits, "translateY"); - ret.nTranslateBits = NTranslateBits; - alignByte(); - endDumpLevel(); - return ret; - } - - /** - * Reads one CXFORMWITHALPHA value from the stream - * - * @param name - * @return CXFORMWITHALPHA value - * @throws IOException - */ - public CXFORMWITHALPHA readCXFORMWITHALPHA(String name) throws IOException { - CXFORMWITHALPHA ret = new CXFORMWITHALPHA(); - newDumpLevel(name, "CXFORMWITHALPHA"); - ret.hasAddTerms = readUB(1, "hasAddTerms") == 1; - ret.hasMultTerms = readUB(1, "hasMultTerms") == 1; - int Nbits = (int) readUB(4, "Nbits"); - ret.nbits = Nbits; - if (ret.hasMultTerms) { - ret.redMultTerm = (int) readSB(Nbits, "redMultTerm"); - ret.greenMultTerm = (int) readSB(Nbits, "greenMultTerm"); - ret.blueMultTerm = (int) readSB(Nbits, "blueMultTerm"); - ret.alphaMultTerm = (int) readSB(Nbits, "alphaMultTerm"); - } - if (ret.hasAddTerms) { - ret.redAddTerm = (int) readSB(Nbits, "redAddTerm"); - ret.greenAddTerm = (int) readSB(Nbits, "greenAddTerm"); - ret.blueAddTerm = (int) readSB(Nbits, "blueAddTerm"); - ret.alphaAddTerm = (int) readSB(Nbits, "alphaAddTerm"); - } - alignByte(); - endDumpLevel(); - return ret; - } - - /** - * Reads one CXFORM value from the stream - * - * @param name - * @return CXFORM value - * @throws IOException - */ - public CXFORM readCXFORM(String name) throws IOException { - CXFORM ret = new CXFORM(); - newDumpLevel(name, "CXFORM"); - ret.hasAddTerms = readUB(1, "hasAddTerms") == 1; - ret.hasMultTerms = readUB(1, "hasMultTerms") == 1; - int Nbits = (int) readUB(4, "Nbits"); - ret.nbits = Nbits; - if (ret.hasMultTerms) { - ret.redMultTerm = (int) readSB(Nbits, "redMultTerm"); - ret.greenMultTerm = (int) readSB(Nbits, "greenMultTerm"); - ret.blueMultTerm = (int) readSB(Nbits, "blueMultTerm"); - } - if (ret.hasAddTerms) { - ret.redAddTerm = (int) readSB(Nbits, "redAddTerm"); - ret.greenAddTerm = (int) readSB(Nbits, "greenAddTerm"); - ret.blueAddTerm = (int) readSB(Nbits, "blueAddTerm"); - } - alignByte(); - endDumpLevel(); - return ret; - } - - /** - * Reads one CLIPEVENTFLAGS value from the stream - * - * @param name - * @return CLIPEVENTFLAGS value - * @throws IOException - */ - public CLIPEVENTFLAGS readCLIPEVENTFLAGS(String name) throws IOException { - CLIPEVENTFLAGS ret = new CLIPEVENTFLAGS(); - newDumpLevel(name, "CLIPEVENTFLAGS"); - ret.clipEventKeyUp = readUB(1, "clipEventKeyUp") == 1; - ret.clipEventKeyDown = readUB(1, "clipEventKeyDown") == 1; - ret.clipEventMouseUp = readUB(1, "clipEventMouseUp") == 1; - ret.clipEventMouseDown = readUB(1, "clipEventMouseDown") == 1; - ret.clipEventMouseMove = readUB(1, "clipEventMouseMove") == 1; - ret.clipEventUnload = readUB(1, "clipEventUnload") == 1; - ret.clipEventEnterFrame = readUB(1, "clipEventEnterFrame") == 1; - ret.clipEventLoad = readUB(1, "clipEventLoad") == 1; - ret.clipEventDragOver = readUB(1, "clipEventDragOver") == 1; - ret.clipEventRollOut = readUB(1, "clipEventRollOut") == 1; - ret.clipEventRollOver = readUB(1, "clipEventRollOver") == 1; - ret.clipEventReleaseOutside = readUB(1, "clipEventReleaseOutside") == 1; - ret.clipEventRelease = readUB(1, "clipEventRelease") == 1; - ret.clipEventPress = readUB(1, "clipEventPress") == 1; - ret.clipEventInitialize = readUB(1, "clipEventInitialize") == 1; - ret.clipEventData = readUB(1, "clipEventData") == 1; - if (swf.version >= 6) { - ret.reserved = (int) readUB(5, "reserved"); - ret.clipEventConstruct = readUB(1, "clipEventConstruct") == 1; - ret.clipEventKeyPress = readUB(1, "clipEventKeyPress") == 1; - ret.clipEventDragOut = readUB(1, "clipEventDragOut") == 1; - ret.reserved2 = (int) readUB(8, "reserved2"); - } - endDumpLevel(); - return ret; - } - - /** - * Reads one CLIPACTIONRECORD value from the stream - * - * @param swf - * @param tag - * @param name - * @return CLIPACTIONRECORD value - * @throws IOException - */ - public CLIPACTIONRECORD readCLIPACTIONRECORD(SWF swf, Tag tag, String name) throws IOException { - newDumpLevel(name, "CLIPACTIONRECORD"); - CLIPACTIONRECORD ret = new CLIPACTIONRECORD(swf, this, tag); - endDumpLevel(); - if (ret.eventFlags.isClear()) { - return null; - } - return ret; - } - - /** - * Reads one CLIPACTIONS value from the stream - * - * @param swf - * @param tag - * @param name - * @return CLIPACTIONS value - * @throws IOException - */ - public CLIPACTIONS readCLIPACTIONS(SWF swf, Tag tag, String name) throws IOException { - CLIPACTIONS ret = new CLIPACTIONS(); - newDumpLevel(name, "CLIPACTIONS"); - ret.reserved = readUI16("reserved"); - ret.allEventFlags = readCLIPEVENTFLAGS("allEventFlags"); - CLIPACTIONRECORD cr; - ret.clipActionRecords = new ArrayList<>(); - while ((cr = readCLIPACTIONRECORD(swf, tag, "record")) != null) { - ret.clipActionRecords.add(cr); - } - endDumpLevel(); - return ret; - } - - /** - * Reads one COLORMATRIXFILTER value from the stream - * - * @param name - * @return COLORMATRIXFILTER value - * @throws IOException - */ - public COLORMATRIXFILTER readCOLORMATRIXFILTER(String name) throws IOException { - COLORMATRIXFILTER ret = new COLORMATRIXFILTER(); - newDumpLevel(name, "COLORMATRIXFILTER"); - ret.matrix = new float[20]; - for (int i = 0; i < 20; i++) { - ret.matrix[i] = readFLOAT("cell"); - } - endDumpLevel(); - return ret; - } - - /** - * Reads one RGBA value from the stream - * - * @param name - * @return RGBA value - * @throws IOException - */ - public RGBA readRGBA(String name) throws IOException { - RGBA ret = new RGBA(); - newDumpLevel(name, "RGBA"); - ret.red = readUI8("red"); - ret.green = readUI8("green"); - ret.blue = readUI8("blue"); - ret.alpha = readUI8("alpha"); - endDumpLevel(); - return ret; - } - - /** - * Reads one ARGB value from the stream - * - * @param name - * @return ARGB value - * @throws IOException - */ - public ARGB readARGB(String name) throws IOException { - ARGB ret = new ARGB(); - newDumpLevel(name, "ARGB"); - ret.alpha = readUI8("alpha"); - ret.red = readUI8("red"); - ret.green = readUI8("green"); - ret.blue = readUI8("blue"); - endDumpLevel(); - return ret; - } - - /** - * Reads one RGB value from the stream - * - * @param name - * @return RGB value - * @throws IOException - */ - public RGB readRGB(String name) throws IOException { - RGB ret = new RGB(); - newDumpLevel(name, "RGB"); - ret.red = readUI8("red"); - ret.green = readUI8("green"); - ret.blue = readUI8("blue"); - endDumpLevel(); - return ret; - } - - /** - * Reads one CONVOLUTIONFILTER value from the stream - * - * @param name - * @return CONVOLUTIONFILTER value - * @throws IOException - */ - public CONVOLUTIONFILTER readCONVOLUTIONFILTER(String name) throws IOException { - CONVOLUTIONFILTER ret = new CONVOLUTIONFILTER(); - newDumpLevel(name, "CONVOLUTIONFILTER"); - ret.matrixX = readUI8("matrixX"); - ret.matrixY = readUI8("matrixY"); - ret.divisor = readFLOAT("divisor"); - ret.bias = readFLOAT("bias"); - ret.matrix = new float[ret.matrixX][ret.matrixY]; - for (int x = 0; x < ret.matrixX; x++) { - for (int y = 0; y < ret.matrixY; y++) { - ret.matrix[x][y] = readFLOAT("cell"); - } - } - ret.defaultColor = readRGBA("defaultColor"); - ret.reserved = (int) readUB(6, "reserved"); - ret.clamp = readUB(1, "clamp") == 1; - ret.preserveAlpha = readUB(1, "preserveAlpha") == 1; - endDumpLevel(); - return ret; - } - - /** - * Reads one BLURFILTER value from the stream - * - * @param name - * @return BLURFILTER value - * @throws IOException - */ - public BLURFILTER readBLURFILTER(String name) throws IOException { - BLURFILTER ret = new BLURFILTER(); - newDumpLevel(name, "BLURFILTER"); - ret.blurX = readFIXED("blurX"); - ret.blurY = readFIXED("blurY"); - ret.passes = (int) readUB(5, "passes"); - ret.reserved = (int) readUB(3, "reserved"); - endDumpLevel(); - return ret; - } - - /** - * Reads one DROPSHADOWFILTER value from the stream - * - * @param name - * @return DROPSHADOWFILTER value - * @throws IOException - */ - public DROPSHADOWFILTER readDROPSHADOWFILTER(String name) throws IOException { - DROPSHADOWFILTER ret = new DROPSHADOWFILTER(); - newDumpLevel(name, "DROPSHADOWFILTER"); - ret.dropShadowColor = readRGBA("dropShadowColor"); - ret.blurX = readFIXED("blurX"); - ret.blurY = readFIXED("blurY"); - ret.angle = readFIXED("angle"); - ret.distance = readFIXED("distance"); - ret.strength = readFIXED8("strength"); - ret.innerShadow = readUB(1, "innerShadow") == 1; - ret.knockout = readUB(1, "knockout") == 1; - ret.compositeSource = readUB(1, "compositeSource") == 1; - ret.passes = (int) readUB(5, "passes"); - endDumpLevel(); - return ret; - } - - /** - * Reads one GLOWFILTER value from the stream - * - * @param name - * @return GLOWFILTER value - * @throws IOException - */ - public GLOWFILTER readGLOWFILTER(String name) throws IOException { - GLOWFILTER ret = new GLOWFILTER(); - newDumpLevel(name, "GLOWFILTER"); - ret.glowColor = readRGBA("glowColor"); - ret.blurX = readFIXED("blurX"); - ret.blurY = readFIXED("blurY"); - ret.strength = readFIXED8("strength"); - ret.innerGlow = readUB(1, "innerGlow") == 1; - ret.knockout = readUB(1, "knockout") == 1; - ret.compositeSource = readUB(1, "compositeSource") == 1; - ret.passes = (int) readUB(5, "passes"); - endDumpLevel(); - return ret; - } - - /** - * Reads one BEVELFILTER value from the stream - * - * @param name - * @return BEVELFILTER value - * @throws IOException - */ - public BEVELFILTER readBEVELFILTER(String name) throws IOException { - BEVELFILTER ret = new BEVELFILTER(); - newDumpLevel(name, "BEVELFILTER"); - ret.highlightColor = readRGBA("highlightColor"); // Highlight color first. It it opposite of the documentation - ret.shadowColor = readRGBA("shadowColor"); - ret.blurX = readFIXED("blurX"); - ret.blurY = readFIXED("blurY"); - ret.angle = readFIXED("angle"); - ret.distance = readFIXED("distance"); - ret.strength = readFIXED8("strength"); - ret.innerShadow = readUB(1, "innerShadow") == 1; - ret.knockout = readUB(1, "knockout") == 1; - ret.compositeSource = readUB(1, "compositeSource") == 1; - ret.onTop = readUB(1, "onTop") == 1; - ret.passes = (int) readUB(4, "passes"); - endDumpLevel(); - return ret; - } - - /** - * Reads one GRADIENTGLOWFILTER value from the stream - * - * @param name - * @return GRADIENTGLOWFILTER value - * @throws IOException - */ - public GRADIENTGLOWFILTER readGRADIENTGLOWFILTER(String name) throws IOException { - GRADIENTGLOWFILTER ret = new GRADIENTGLOWFILTER(); - newDumpLevel(name, "GRADIENTGLOWFILTER"); - int numColors = readUI8("numColors"); - ret.gradientColors = new RGBA[numColors]; - ret.gradientRatio = new int[numColors]; - for (int i = 0; i < numColors; i++) { - ret.gradientColors[i] = readRGBA("gradientColor"); - } - for (int i = 0; i < numColors; i++) { - ret.gradientRatio[i] = readUI8("gradientRatio"); - } - ret.blurX = readFIXED("blurX"); - ret.blurY = readFIXED("blurY"); - ret.angle = readFIXED("angle"); - ret.distance = readFIXED("distance"); - ret.strength = readFIXED8("strength"); - ret.innerShadow = readUB(1, "innerShadow") == 1; - ret.knockout = readUB(1, "knockout") == 1; - ret.compositeSource = readUB(1, "compositeSource") == 1; - ret.onTop = readUB(1, "onTop") == 1; - ret.passes = (int) readUB(4, "passes"); - endDumpLevel(); - return ret; - } - - /** - * Reads one GRADIENTBEVELFILTER value from the stream - * - * @param name - * @return GRADIENTBEVELFILTER value - * @throws IOException - */ - public GRADIENTBEVELFILTER readGRADIENTBEVELFILTER(String name) throws IOException { - GRADIENTBEVELFILTER ret = new GRADIENTBEVELFILTER(); - newDumpLevel(name, "GRADIENTBEVELFILTER"); - int numColors = readUI8("numColors"); - ret.gradientColors = new RGBA[numColors]; - ret.gradientRatio = new int[numColors]; - for (int i = 0; i < numColors; i++) { - ret.gradientColors[i] = readRGBA("gradientColor"); - } - for (int i = 0; i < numColors; i++) { - ret.gradientRatio[i] = readUI8("gradientRatio"); - } - ret.blurX = readFIXED("blurX"); - ret.blurY = readFIXED("blurY"); - ret.angle = readFIXED("angle"); - ret.distance = readFIXED("distance"); - ret.strength = readFIXED8("strength"); - ret.innerShadow = readUB(1, "innerShadow") == 1; - ret.knockout = readUB(1, "knockout") == 1; - ret.compositeSource = readUB(1, "compositeSource") == 1; - ret.onTop = readUB(1, "onTop") == 1; - ret.passes = (int) readUB(4, "passes"); - endDumpLevel(); - return ret; - } - - /** - * Reads list of FILTER values from the stream - * - * @param name - * @return List of FILTER values - * @throws IOException - */ - public List readFILTERLIST(String name) throws IOException { - newDumpLevel(name, "FILTERLIST"); - int numberOfFilters = readUI8("numberOfFilters"); - List ret = new ArrayList<>(numberOfFilters); - for (int i = 0; i < numberOfFilters; i++) { - ret.add(readFILTER("filter")); - } - endDumpLevel(); - return ret; - } - - /** - * Reads one FILTER value from the stream - * - * @param name - * @return FILTER value - * @throws IOException - */ - public FILTER readFILTER(String name) throws IOException { - newDumpLevel(name, "FILTER"); - int filterId = readUI8("filterId"); - FILTER ret = null; - switch (filterId) { - case 0: - ret = readDROPSHADOWFILTER("filter"); - break; - case 1: - ret = readBLURFILTER("filter"); - break; - case 2: - ret = readGLOWFILTER("filter"); - break; - case 3: - ret = readBEVELFILTER("filter"); - break; - case 4: - ret = readGRADIENTGLOWFILTER("filter"); - break; - case 5: - ret = readCONVOLUTIONFILTER("filter"); - break; - case 6: - ret = readCOLORMATRIXFILTER("filter"); - break; - case 7: - ret = readGRADIENTBEVELFILTER("filter"); - break; - } - endDumpLevel(); - return ret; - } - - /** - * Reads list of BUTTONRECORD values from the stream - * - * @param inDefineButton2 Whether read from inside of DefineButton2Tag or - * not - * @param name - * @return List of BUTTONRECORD values - * @throws IOException - */ - public List readBUTTONRECORDList(boolean inDefineButton2, String name) throws IOException { - List ret = new ArrayList<>(); - newDumpLevel(name, "BUTTONRECORDList"); - BUTTONRECORD br; - while ((br = readBUTTONRECORD(inDefineButton2, "record")) != null) { - ret.add(br); - } - endDumpLevel(); - return ret; - } - - /** - * Reads one BUTTONRECORD value from the stream - * - * @param inDefineButton2 True when in DefineButton2 - * @param name - * @return BUTTONRECORD value - * @throws IOException - */ - public BUTTONRECORD readBUTTONRECORD(boolean inDefineButton2, String name) throws IOException { - BUTTONRECORD ret = new BUTTONRECORD(); - newDumpLevel(name, "BUTTONRECORD"); - ret.reserved = (int) readUB(2, "reserved"); - ret.buttonHasBlendMode = readUB(1, "buttonHasBlendMode") == 1; - ret.buttonHasFilterList = readUB(1, "buttonHasFilterList") == 1; - ret.buttonStateHitTest = readUB(1, "buttonStateHitTest") == 1; - ret.buttonStateDown = readUB(1, "buttonStateDown") == 1; - ret.buttonStateOver = readUB(1, "buttonStateOver") == 1; - ret.buttonStateUp = readUB(1, "buttonStateUp") == 1; - - if (!ret.buttonHasBlendMode && !ret.buttonHasFilterList - && !ret.buttonStateHitTest && !ret.buttonStateDown - && !ret.buttonStateOver && !ret.buttonStateUp && ret.reserved == 0) { - endDumpLevel(); - return null; - } - - ret.characterId = readUI16("characterId"); - ret.placeDepth = readUI16("placeDepth"); - ret.placeMatrix = readMatrix("placeMatrix"); - if (inDefineButton2) { - ret.colorTransform = readCXFORMWITHALPHA("colorTransform"); - if (ret.buttonHasFilterList) { - ret.filterList = readFILTERLIST("filterList"); - } - if (ret.buttonHasBlendMode) { - ret.blendMode = readUI8("blendMode"); - } - } - endDumpLevel(); - return ret; - } - - /** - * Reads list of BUTTONCONDACTION values from the stream - * - * @param swf - * @param tag - * @param name - * @return List of BUTTONCONDACTION values - * @throws IOException - */ - public List readBUTTONCONDACTIONList(SWF swf, Tag tag, String name) throws IOException { - List ret = new ArrayList<>(); - newDumpLevel(name, "BUTTONCONDACTIONList"); - BUTTONCONDACTION bc; - while (!(bc = readBUTTONCONDACTION(swf, tag, "action")).isLast) { - ret.add(bc); - } - ret.add(bc); - endDumpLevel(); - return ret; - } - - /** - * Reads one BUTTONCONDACTION value from the stream - * - * @param swf - * @param tag - * @param name - * @return BUTTONCONDACTION value - * @throws IOException - */ - public BUTTONCONDACTION readBUTTONCONDACTION(SWF swf, Tag tag, String name) throws IOException { - newDumpLevel(name, "BUTTONCONDACTION"); - BUTTONCONDACTION ret = new BUTTONCONDACTION(swf, this, tag); - //ret.actions = readActionList(); - endDumpLevel(); - return ret; - } - - /** - * Reads one GRADRECORD value from the stream - * - * @param shapeNum 1 in DefineShape, 2 in DefineShape2... - * @param name - * @return GRADRECORD value - * @throws IOException - */ - public GRADRECORD readGRADRECORD(int shapeNum, String name) throws IOException { - GRADRECORD ret = new GRADRECORD(); - newDumpLevel(name, "GRADRECORD"); - ret.ratio = readUI8("ratio"); - if (shapeNum >= 3) { - ret.color = readRGBA("color"); - } else { - ret.color = readRGB("color"); - } - endDumpLevel(); - return ret; - } - - /** - * Reads one GRADIENT value from the stream - * - * @param shapeNum 1 in DefineShape, 2 in DefineShape2... - * @param name - * @return GRADIENT value - * @throws IOException - */ - public GRADIENT readGRADIENT(int shapeNum, String name) throws IOException { - GRADIENT ret = new GRADIENT(); - newDumpLevel(name, "GRADIENT"); - ret.spreadMode = (int) readUB(2, "spreadMode"); - ret.interpolationMode = (int) readUB(2, "interpolationMode"); - int numGradients = (int) readUB(4, "numGradients"); - ret.gradientRecords = new GRADRECORD[numGradients]; - for (int i = 0; i < numGradients; i++) { - ret.gradientRecords[i] = readGRADRECORD(shapeNum, "gradientRecord"); - - } - endDumpLevel(); - return ret; - } - - /** - * Reads one FOCALGRADIENT value from the stream - * - * @param shapeNum 1 in DefineShape, 2 in DefineShape2... - * @param name - * @return FOCALGRADIENT value - * @throws IOException - */ - public FOCALGRADIENT readFOCALGRADIENT(int shapeNum, String name) throws IOException { - FOCALGRADIENT ret = new FOCALGRADIENT(); - newDumpLevel(name, "FOCALGRADIENT"); - ret.spreadMode = (int) readUB(2, "spreadMode"); - ret.interpolationMode = (int) readUB(2, "interpolationMode"); - int numGradients = (int) readUB(4, "numGradients"); - ret.gradientRecords = new GRADRECORD[numGradients]; - for (int i = 0; i < numGradients; i++) { - ret.gradientRecords[i] = readGRADRECORD(shapeNum, "gradientRecord"); - } - ret.focalPoint = readFIXED8("focalPoint"); - endDumpLevel(); - return ret; - } - - /** - * Reads one FILLSTYLE value from the stream - * - * @param shapeNum 1 in DefineShape, 2 in DefineShape2... - * @param name - * @return FILLSTYLE value - * @throws IOException - */ - public FILLSTYLE readFILLSTYLE(int shapeNum, String name) throws IOException { - FILLSTYLE ret = new FILLSTYLE(); - newDumpLevel(name, "FILLSTYLE"); - ret.fillStyleType = readUI8("fillStyleType"); - if (ret.fillStyleType == FILLSTYLE.SOLID) { - if (shapeNum >= 3) { - ret.color = readRGBA("color"); - } else { - ret.color = readRGB("color"); - } - } - if ((ret.fillStyleType == FILLSTYLE.LINEAR_GRADIENT) - || (ret.fillStyleType == FILLSTYLE.RADIAL_GRADIENT) - || (ret.fillStyleType == FILLSTYLE.FOCAL_RADIAL_GRADIENT)) { - ret.gradientMatrix = readMatrix("gradientMatrix"); - } - if ((ret.fillStyleType == FILLSTYLE.LINEAR_GRADIENT) - || (ret.fillStyleType == FILLSTYLE.RADIAL_GRADIENT)) { - ret.gradient = readGRADIENT(shapeNum, "gradient"); - } - if (ret.fillStyleType == FILLSTYLE.FOCAL_RADIAL_GRADIENT) { - ret.gradient = readFOCALGRADIENT(shapeNum, "gradient"); - } - - if ((ret.fillStyleType == FILLSTYLE.REPEATING_BITMAP) - || (ret.fillStyleType == FILLSTYLE.CLIPPED_BITMAP) - || (ret.fillStyleType == FILLSTYLE.NON_SMOOTHED_REPEATING_BITMAP) - || (ret.fillStyleType == FILLSTYLE.NON_SMOOTHED_CLIPPED_BITMAP)) { - ret.bitmapId = readUI16("bitmapId"); - ret.bitmapMatrix = readMatrix("bitmapMatrix"); - } - endDumpLevel(); - return ret; - } - - /** - * Reads one FILLSTYLEARRAY value from the stream - * - * @param shapeNum 1 in DefineShape, 2 in DefineShape2... - * @param name - * @return FILLSTYLEARRAY value - * @throws IOException - */ - public FILLSTYLEARRAY readFILLSTYLEARRAY(int shapeNum, String name) throws IOException { - - FILLSTYLEARRAY ret = new FILLSTYLEARRAY(); - newDumpLevel(name, "FILLSTYLEARRAY"); - int fillStyleCount = readUI8("fillStyleCount"); - if (((shapeNum == 2) || (shapeNum == 3) || (shapeNum == 4/*?*/)) && (fillStyleCount == 0xff)) { - fillStyleCount = readUI16("fillStyleCount"); - } - ret.fillStyles = new FILLSTYLE[fillStyleCount]; - for (int i = 0; i < fillStyleCount; i++) { - ret.fillStyles[i] = readFILLSTYLE(shapeNum, "fillStyle"); - } - endDumpLevel(); - return ret; - } - - /** - * Reads one LINESTYLE value from the stream - * - * @param shapeNum 1 in DefineShape, 2 in DefineShape2... - * @param name - * @return LINESTYLE value - * @throws IOException - */ - public LINESTYLE readLINESTYLE(int shapeNum, String name) throws IOException { - LINESTYLE ret = new LINESTYLE(); - newDumpLevel(name, "LINESTYLE"); - ret.width = readUI16("width"); - if ((shapeNum == 1) || (shapeNum == 2)) { - ret.color = readRGB("color"); - } - if (shapeNum == 3) { - ret.color = readRGBA("color"); - } - endDumpLevel(); - return ret; - } - - /** - * Reads one LINESTYLE2 value from the stream - * - * @param shapeNum 1 in DefineShape, 2 in DefineShape2... - * @param name - * @return LINESTYLE2 value - * @throws IOException - */ - public LINESTYLE2 readLINESTYLE2(int shapeNum, String name) throws IOException { - LINESTYLE2 ret = new LINESTYLE2(); - newDumpLevel(name, "LINESTYLE2"); - ret.width = readUI16("width"); - ret.startCapStyle = (int) readUB(2, "startCapStyle"); - ret.joinStyle = (int) readUB(2, "joinStyle"); - ret.hasFillFlag = (int) readUB(1, "hasFillFlag") == 1; - ret.noHScaleFlag = (int) readUB(1, "noHScaleFlag") == 1; - ret.noVScaleFlag = (int) readUB(1, "noVScaleFlag") == 1; - ret.pixelHintingFlag = (int) readUB(1, "pixelHintingFlag") == 1; - ret.reserved = (int) readUB(5, "reserved"); - ret.noClose = (int) readUB(1, "noClose") == 1; - ret.endCapStyle = (int) readUB(2, "endCapStyle"); - if (ret.joinStyle == LINESTYLE2.MITER_JOIN) { - ret.miterLimitFactor = readUI16("miterLimitFactor"); - } - if (!ret.hasFillFlag) { - ret.color = readRGBA("color"); - } else { - ret.fillType = readFILLSTYLE(shapeNum, "fillType"); - } - endDumpLevel(); - return ret; - } - - /** - * Reads one LINESTYLEARRAY value from the stream - * - * @param shapeNum 1 in DefineShape, 2 in DefineShape2... - * @param name - * @return LINESTYLEARRAY value - * @throws IOException - */ - public LINESTYLEARRAY readLINESTYLEARRAY(int shapeNum, String name) throws IOException { - LINESTYLEARRAY ret = new LINESTYLEARRAY(); - newDumpLevel(name, "LINESTYLEARRAY"); - int lineStyleCount = readUI8("lineStyleCount"); - if (lineStyleCount == 0xff) { - lineStyleCount = readUI16("lineStyleCount"); - } - if ((shapeNum == 1 || shapeNum == 2 || shapeNum == 3)) { - ret.lineStyles = new LINESTYLE[lineStyleCount]; - for (int i = 0; i < lineStyleCount; i++) { - ret.lineStyles[i] = readLINESTYLE(shapeNum, "lineStyle"); - } - } else if (shapeNum == 4) { - ret.lineStyles = new LINESTYLE2[lineStyleCount]; - for (int i = 0; i < lineStyleCount; i++) { - ret.lineStyles[i] = readLINESTYLE2(shapeNum, "lineStyle"); - } - } - endDumpLevel(); - return ret; - } - - /** - * Reads one SHAPERECORD value from the stream - * - * @param fillBits - * @param lineBits - * @param shapeNum 1 in DefineShape, 2 in DefineShape2... - * @return SHAPERECORD value - * @throws IOException - */ - private SHAPERECORD readSHAPERECORD(int fillBits, int lineBits, int shapeNum, boolean morphShape, String name) throws IOException { - SHAPERECORD ret; - newDumpLevel(name, "SHAPERECORD"); - int typeFlag = (int) readUB(1, "typeFlag"); - if (typeFlag == 0) { - boolean stateNewStyles = readUB(1, "stateNewStyles") == 1; - boolean stateLineStyle = readUB(1, "stateLineStyle") == 1; - boolean stateFillStyle1 = readUB(1, "stateFillStyle1") == 1; - boolean stateFillStyle0 = readUB(1, "stateFillStyle0") == 1; - boolean stateMoveTo = readUB(1, "stateMoveTo") == 1; - if ((!stateNewStyles) && (!stateLineStyle) && (!stateFillStyle1) && (!stateFillStyle0) && (!stateMoveTo)) { - ret = new EndShapeRecord(); - } else { - StyleChangeRecord scr = new StyleChangeRecord(); - scr.stateNewStyles = stateNewStyles; - scr.stateLineStyle = stateLineStyle; - scr.stateFillStyle0 = stateFillStyle0; - scr.stateFillStyle1 = stateFillStyle1; - scr.stateMoveTo = stateMoveTo; - if (stateMoveTo) { - scr.moveBits = (int) readUB(5, "moveBits"); - scr.moveDeltaX = (int) readSB(scr.moveBits, "moveDeltaX"); - scr.moveDeltaY = (int) readSB(scr.moveBits, "moveDeltaY"); - } - if (stateFillStyle0) { - scr.fillStyle0 = (int) readUB(fillBits, "fillStyle0"); - } - if (stateFillStyle1) { - scr.fillStyle1 = (int) readUB(fillBits, "fillStyle1"); - } - if (stateLineStyle) { - scr.lineStyle = (int) readUB(lineBits, "lineStyle"); - } - if (stateNewStyles) { - if (morphShape) { - // This should never happen in a valid SWF - throw new IOException("MorphShape should not have new styles."); - } else { - scr.fillStyles = readFILLSTYLEARRAY(shapeNum, "fillStyles"); - scr.lineStyles = readLINESTYLEARRAY(shapeNum, "lineStyles"); - } - scr.numFillBits = (int) readUB(4, "numFillBits"); - scr.numLineBits = (int) readUB(4, "numLineBits"); - } - ret = scr; - } - } else { // typeFlag==1 - int straightFlag = (int) readUB(1, "straightFlag"); - if (straightFlag == 1) { - StraightEdgeRecord ser = new StraightEdgeRecord(); - ser.numBits = (int) readUB(4, "numBits"); - ser.generalLineFlag = readUB(1, "generalLineFlag") == 1; - if (!ser.generalLineFlag) { - ser.vertLineFlag = readUB(1, "vertLineFlag") == 1; - } - if (ser.generalLineFlag || (!ser.vertLineFlag)) { - ser.deltaX = (int) readSB(ser.numBits + 2, "deltaX"); - } - if (ser.generalLineFlag || (ser.vertLineFlag)) { - ser.deltaY = (int) readSB(ser.numBits + 2, "deltaY"); - } - ret = ser; - } else { - CurvedEdgeRecord cer = new CurvedEdgeRecord(); - cer.numBits = (int) readUB(4, "numBits"); - cer.controlDeltaX = (int) readSB(cer.numBits + 2, "controlDeltaX"); - cer.controlDeltaY = (int) readSB(cer.numBits + 2, "controlDeltaY"); - cer.anchorDeltaX = (int) readSB(cer.numBits + 2, "anchorDeltaX"); - cer.anchorDeltaY = (int) readSB(cer.numBits + 2, "anchorDeltaY"); - ret = cer; - } - } - endDumpLevel(); - return ret; - } - - /** - * Reads one SHAPE value from the stream - * - * @param shapeNum 1 in DefineShape, 2 in DefineShape2... - * @param morphShape - * @param name - * @return SHAPE value - * @throws IOException - */ - public SHAPE readSHAPE(int shapeNum, boolean morphShape, String name) throws IOException { - SHAPE ret = new SHAPE(); - newDumpLevel(name, "SHAPE"); - ret.numFillBits = (int) readUB(4, "numFillBits"); - ret.numLineBits = (int) readUB(4, "numLineBits"); - ret.shapeRecords = readSHAPERECORDS(shapeNum, ret.numFillBits, ret.numLineBits, morphShape, "shapeRecords"); - endDumpLevel(); - return ret; - } - - /** - * Reads one SHAPEWITHSTYLE value from the stream - * - * @param shapeNum 1 in DefineShape, 2 in DefineShape2... - * @param morphShape - * @param name - * @return SHAPEWITHSTYLE value - * @throws IOException - */ - public SHAPEWITHSTYLE readSHAPEWITHSTYLE(int shapeNum, boolean morphShape, String name) throws IOException { - SHAPEWITHSTYLE ret = new SHAPEWITHSTYLE(); - newDumpLevel(name, "SHAPEWITHSTYLE"); - ret.fillStyles = readFILLSTYLEARRAY(shapeNum, "fillStyles"); - ret.lineStyles = readLINESTYLEARRAY(shapeNum, "lineStyles"); - ret.numFillBits = (int) readUB(4, "numFillBits"); - ret.numLineBits = (int) readUB(4, "numLineBits"); - ret.shapeRecords = readSHAPERECORDS(shapeNum, ret.numFillBits, ret.numLineBits, morphShape, "shapeRecords"); - endDumpLevel(); - return ret; - } - - /** - * Reads list of SHAPERECORDs from the stream - * - * @param shapeNum 1 in DefineShape, 2 in DefineShape2... - * @param fillBits - * @param lineBits - * @return SHAPERECORDs array - * @throws IOException - */ - private List readSHAPERECORDS(int shapeNum, int fillBits, int lineBits, boolean morphShape, String name) throws IOException { - List ret = new ArrayList<>(); - newDumpLevel(name, "SHAPERECORDS"); - SHAPERECORD rec; - do { - rec = readSHAPERECORD(fillBits, lineBits, shapeNum, morphShape, "record"); - if (rec instanceof StyleChangeRecord) { - StyleChangeRecord scRec = (StyleChangeRecord) rec; - if (scRec.stateNewStyles) { - fillBits = scRec.numFillBits; - lineBits = scRec.numLineBits; - } - } - ret.add(rec); - } while (!(rec instanceof EndShapeRecord)); - alignByte(); - endDumpLevel(); - return ret; - } - - /** - * Reads one SOUNDINFO value from the stream - * - * @param name - * @return SOUNDINFO value - * @throws IOException - */ - public SOUNDINFO readSOUNDINFO(String name) throws IOException { - SOUNDINFO ret = new SOUNDINFO(); - newDumpLevel(name, "SOUNDINFO"); - ret.reserved = (int) readUB(2, "reserved"); - ret.syncStop = readUB(1, "syncStop") == 1; - ret.syncNoMultiple = readUB(1, "syncNoMultiple") == 1; - ret.hasEnvelope = readUB(1, "hasEnvelope") == 1; - ret.hasLoops = readUB(1, "hasLoops") == 1; - ret.hasOutPoint = readUB(1, "hasOutPoint") == 1; - ret.hasInPoint = readUB(1, "hasInPoint") == 1; - if (ret.hasInPoint) { - ret.inPoint = readUI32("inPoint"); - } - if (ret.hasOutPoint) { - ret.outPoint = readUI32("outPoint"); - } - if (ret.hasLoops) { - ret.loopCount = readUI16("loopCount"); - } - if (ret.hasEnvelope) { - int envPoints = readUI8("envPoints"); - ret.envelopeRecords = new SOUNDENVELOPE[envPoints]; - for (int i = 0; i < envPoints; i++) { - ret.envelopeRecords[i] = readSOUNDENVELOPE("envelopeRecord"); - } - } - endDumpLevel(); - return ret; - } - - /** - * Reads one SOUNDENVELOPE value from the stream - * - * @param name - * @return SOUNDENVELOPE value - * @throws IOException - */ - public SOUNDENVELOPE readSOUNDENVELOPE(String name) throws IOException { - SOUNDENVELOPE ret = new SOUNDENVELOPE(); - newDumpLevel(name, "SOUNDENVELOPE"); - ret.pos44 = readUI32("pos44"); - ret.leftLevel = readUI16("leftLevel"); - ret.rightLevel = readUI16("rightLevel"); - endDumpLevel(); - return ret; - } - - /** - * Reads one GLYPHENTRY value from the stream - * - * @param glyphBits - * @param advanceBits - * @param name - * @return GLYPHENTRY value - * @throws IOException - */ - public GLYPHENTRY readGLYPHENTRY(int glyphBits, int advanceBits, String name) throws IOException { - GLYPHENTRY ret = new GLYPHENTRY(); - newDumpLevel(name, "GLYPHENTRY"); - ret.glyphIndex = (int) readUB(glyphBits, "glyphIndex"); - ret.glyphAdvance = (int) readUB(advanceBits, "glyphAdvance"); - endDumpLevel(); - return ret; - } - - /** - * Reads one TEXTRECORD value from the stream - * - * @param inDefineText2 - * @param glyphBits - * @param advanceBits - * @param name - * @return TEXTRECORD value - * @throws IOException - */ - public TEXTRECORD readTEXTRECORD(boolean inDefineText2, int glyphBits, int advanceBits, String name) throws IOException { - TEXTRECORD ret = new TEXTRECORD(); - newDumpLevel(name, "TEXTRECORD"); - int first = (int) readUB(1, "first"); // always 1 - readUB(3, "styleFlagsHasReserved"); // always 0 - ret.styleFlagsHasFont = readUB(1, "styleFlagsHasFont") == 1; - ret.styleFlagsHasColor = readUB(1, "styleFlagsHasColor") == 1; - ret.styleFlagsHasYOffset = readUB(1, "styleFlagsHasYOffset") == 1; - ret.styleFlagsHasXOffset = readUB(1, "styleFlagsHasXOffset") == 1; - if ((!ret.styleFlagsHasFont) && (!ret.styleFlagsHasColor) && (!ret.styleFlagsHasYOffset) && (!ret.styleFlagsHasXOffset) && (first == 0)) { // final text record - endDumpLevel(); - return null; - } - if (ret.styleFlagsHasFont) { - ret.fontId = readUI16("fontId"); - } - if (ret.styleFlagsHasColor) { - if (inDefineText2) { - ret.textColorA = readRGBA("textColorA"); - } else { - ret.textColor = readRGB("textColor"); - } - } - if (ret.styleFlagsHasXOffset) { - ret.xOffset = readSI16("xOffset"); - } - if (ret.styleFlagsHasYOffset) { - ret.yOffset = readSI16("yOffset"); - } - if (ret.styleFlagsHasFont) { - ret.textHeight = readUI16("textHeight"); - } - int glyphCount = readUI8("glyphCount"); - ret.glyphEntries = new ArrayList<>(glyphCount); - for (int i = 0; i < glyphCount; i++) { - ret.glyphEntries.add(readGLYPHENTRY(glyphBits, advanceBits, "glyphEntry")); - } - alignByte(); - endDumpLevel(); - return ret; - } - - /** - * Reads one MORPHGRADRECORD value from the stream - * - * @param name - * @return MORPHGRADRECORD value - * @throws IOException - */ - public MORPHGRADRECORD readMORPHGRADRECORD(String name) throws IOException { - MORPHGRADRECORD ret = new MORPHGRADRECORD(); - newDumpLevel(name, "MORPHGRADRECORD"); - ret.startRatio = readUI8("startRatio"); - ret.startColor = readRGBA("startColor"); - ret.endRatio = readUI8("endRatio"); - ret.endColor = readRGBA("endColor"); - endDumpLevel(); - return ret; - } - - /** - * Reads one MORPHGRADIENT value from the stream - * - * @param name - * @return MORPHGRADIENT value - * @throws IOException - */ - public MORPHGRADIENT readMORPHGRADIENT(String name) throws IOException { - MORPHGRADIENT ret = new MORPHGRADIENT(); - newDumpLevel(name, "MORPHGRADIENT"); - // Despite of documentation (UI8 1-8), there are two fields - // spreadMode and interPolationMode which are same as in GRADIENT - ret.spreadMode = (int) readUB(2, "spreadMode"); - ret.interPolationMode = (int) readUB(2, "interPolationMode"); - int numGradients = (int) readUB(4, "numGradients"); - ret.gradientRecords = new MORPHGRADRECORD[numGradients]; - for (int i = 0; i < numGradients; i++) { - ret.gradientRecords[i] = readMORPHGRADRECORD("gradientRecord"); - } - endDumpLevel(); - return ret; - } - - /** - * Reads one MORPHFOCALGRADIENT value from the stream - * - * This is undocumented feature - * - * @param name - * @return MORPHGRADIENT value - * @throws IOException - */ - public MORPHFOCALGRADIENT readMORPHFOCALGRADIENT(String name) throws IOException { - MORPHFOCALGRADIENT ret = new MORPHFOCALGRADIENT(); - newDumpLevel(name, "MORPHFOCALGRADIENT"); - ret.spreadMode = (int) readUB(2, "spreadMode"); - ret.interPolationMode = (int) readUB(2, "interPolationMode"); - int numGradients = (int) readUB(4, "numGradients"); - ret.gradientRecords = new MORPHGRADRECORD[numGradients]; - for (int i = 0; i < numGradients; i++) { - ret.gradientRecords[i] = readMORPHGRADRECORD("gradientRecord"); - } - ret.startFocalPoint = readFIXED8("startFocalPoint"); - ret.endFocalPoint = readFIXED8("endFocalPoint"); - endDumpLevel(); - return ret; - } - - /** - * Reads one MORPHFILLSTYLE value from the stream - * - * @param name - * @return MORPHFILLSTYLE value - * @throws IOException - */ - public MORPHFILLSTYLE readMORPHFILLSTYLE(String name) throws IOException { - MORPHFILLSTYLE ret = new MORPHFILLSTYLE(); - newDumpLevel(name, "MORPHFILLSTYLE"); - ret.fillStyleType = readUI8("fillStyleType"); - if (ret.fillStyleType == MORPHFILLSTYLE.SOLID) { - ret.startColor = readRGBA("startColor"); - ret.endColor = readRGBA("endColor"); - } - if ((ret.fillStyleType == MORPHFILLSTYLE.LINEAR_GRADIENT) - || (ret.fillStyleType == MORPHFILLSTYLE.RADIAL_GRADIENT) - || (ret.fillStyleType == MORPHFILLSTYLE.FOCAL_RADIAL_GRADIENT)) { - ret.startGradientMatrix = readMatrix("startGradientMatrix"); - ret.endGradientMatrix = readMatrix("endGradientMatrix"); - } - if ((ret.fillStyleType == MORPHFILLSTYLE.LINEAR_GRADIENT) - || (ret.fillStyleType == MORPHFILLSTYLE.RADIAL_GRADIENT)) { - ret.gradient = readMORPHGRADIENT("gradient"); - } - if (ret.fillStyleType == MORPHFILLSTYLE.FOCAL_RADIAL_GRADIENT) { - ret.gradient = readMORPHFOCALGRADIENT("gradient"); - } - - if ((ret.fillStyleType == MORPHFILLSTYLE.REPEATING_BITMAP) - || (ret.fillStyleType == MORPHFILLSTYLE.CLIPPED_BITMAP) - || (ret.fillStyleType == MORPHFILLSTYLE.NON_SMOOTHED_REPEATING_BITMAP) - || (ret.fillStyleType == MORPHFILLSTYLE.NON_SMOOTHED_CLIPPED_BITMAP)) { - ret.bitmapId = readUI16("bitmapId"); - ret.startBitmapMatrix = readMatrix("startBitmapMatrix"); - ret.endBitmapMatrix = readMatrix("endBitmapMatrix"); - } - endDumpLevel(); - return ret; - } - - /** - * Reads one MORPHFILLSTYLEARRAY value from the stream - * - * @param name - * @return MORPHFILLSTYLEARRAY value - * @throws IOException - */ - public MORPHFILLSTYLEARRAY readMORPHFILLSTYLEARRAY(String name) throws IOException { - - MORPHFILLSTYLEARRAY ret = new MORPHFILLSTYLEARRAY(); - newDumpLevel(name, "MORPHFILLSTYLEARRAY"); - int fillStyleCount = readUI8("fillStyleCount"); - if (fillStyleCount == 0xff) { - fillStyleCount = readUI16("fillStyleCount"); - } - ret.fillStyles = new MORPHFILLSTYLE[fillStyleCount]; - for (int i = 0; i < fillStyleCount; i++) { - ret.fillStyles[i] = readMORPHFILLSTYLE("fillStyle"); - } - endDumpLevel(); - return ret; - } - - /** - * Reads one MORPHLINESTYLE value from the stream - * - * @param name - * @return MORPHLINESTYLE value - * @throws IOException - */ - public MORPHLINESTYLE readMORPHLINESTYLE(String name) throws IOException { - MORPHLINESTYLE ret = new MORPHLINESTYLE(); - newDumpLevel(name, "MORPHLINESTYLE"); - ret.startWidth = readUI16("startWidth"); - ret.endWidth = readUI16("endWidth"); - ret.startColor = readRGBA("startColor"); - ret.endColor = readRGBA("endColor"); - endDumpLevel(); - return ret; - } - - /** - * Reads one MORPHLINESTYLE2 value from the stream - * - * @param name - * @return MORPHLINESTYLE2 value - * @throws IOException - */ - public MORPHLINESTYLE2 readMORPHLINESTYLE2(String name) throws IOException { - MORPHLINESTYLE2 ret = new MORPHLINESTYLE2(); - newDumpLevel(name, "MORPHLINESTYLE2"); - ret.startWidth = readUI16("startWidth"); - ret.endWidth = readUI16("endWidth"); - ret.startCapStyle = (int) readUB(2, "startCapStyle"); - ret.joinStyle = (int) readUB(2, "joinStyle"); - ret.hasFillFlag = (int) readUB(1, "hasFillFlag") == 1; - ret.noHScaleFlag = (int) readUB(1, "noHScaleFlag") == 1; - ret.noVScaleFlag = (int) readUB(1, "noVScaleFlag") == 1; - ret.pixelHintingFlag = (int) readUB(1, "pixelHintingFlag") == 1; - ret.reserved = (int) readUB(5, "reserved"); - ret.noClose = (int) readUB(1, "noClose") == 1; - ret.endCapStyle = (int) readUB(2, "endCapStyle"); - if (ret.joinStyle == LINESTYLE2.MITER_JOIN) { - ret.miterLimitFactor = readUI16("miterLimitFactor"); - } - if (!ret.hasFillFlag) { - ret.startColor = readRGBA("startColor"); - ret.endColor = readRGBA("endColor"); - } else { - ret.fillType = readMORPHFILLSTYLE("fillType"); - } - endDumpLevel(); - return ret; - } - - /** - * Reads one MORPHLINESTYLEARRAY value from the stream - * - * @param morphShapeNum 1 on DefineMorphShape, 2 on DefineMorphShape2 - * @param name - * @return MORPHLINESTYLEARRAY value - * @throws IOException - */ - public MORPHLINESTYLEARRAY readMORPHLINESTYLEARRAY(int morphShapeNum, String name) throws IOException { - MORPHLINESTYLEARRAY ret = new MORPHLINESTYLEARRAY(); - newDumpLevel(name, "MORPHLINESTYLEARRAY"); - int lineStyleCount = readUI8("lineStyleCount"); - if (lineStyleCount == 0xff) { - lineStyleCount = readUI16("lineStyleCount"); - } - if (morphShapeNum == 1) { - ret.lineStyles = new MORPHLINESTYLE[lineStyleCount]; - for (int i = 0; i < lineStyleCount; i++) { - ret.lineStyles[i] = readMORPHLINESTYLE("lineStyle"); - } - } else if (morphShapeNum == 2) { - ret.lineStyles2 = new MORPHLINESTYLE2[lineStyleCount]; - for (int i = 0; i < lineStyleCount; i++) { - ret.lineStyles2[i] = readMORPHLINESTYLE2("lineStyle2"); - } - } - endDumpLevel(); - return ret; - } - - /** - * Reads one KERNINGRECORD value from the stream - * - * @param fontFlagsWideCodes - * @param name - * @return KERNINGRECORD value - * @throws IOException - */ - public KERNINGRECORD readKERNINGRECORD(boolean fontFlagsWideCodes, String name) throws IOException { - KERNINGRECORD ret = new KERNINGRECORD(); - newDumpLevel(name, "KERNINGRECORD"); - if (fontFlagsWideCodes) { - ret.fontKerningCode1 = readUI16("fontKerningCode1"); - ret.fontKerningCode2 = readUI16("fontKerningCode2"); - } else { - ret.fontKerningCode1 = readUI8("fontKerningCode1"); - ret.fontKerningCode2 = readUI8("fontKerningCode2"); - } - ret.fontKerningAdjustment = readSI16("fontKerningAdjustment"); - endDumpLevel(); - return ret; - } - - /** - * Reads one LANGCODE value from the stream - * - * @param name - * @return LANGCODE value - * @throws IOException - */ - public LANGCODE readLANGCODE(String name) throws IOException { - LANGCODE ret = new LANGCODE(); - newDumpLevel(name, "LANGCODE"); - ret.languageCode = readUI8("languageCode"); - endDumpLevel(); - return ret; - } - - /** - * Reads one ZONERECORD value from the stream - * - * @param name - * @return ZONERECORD value - * @throws IOException - */ - public ZONERECORD readZONERECORD(String name) throws IOException { - ZONERECORD ret = new ZONERECORD(); - newDumpLevel(name, "ZONERECORD"); - int numZoneData = readUI8("numZoneData"); - ret.zonedata = new ZONEDATA[numZoneData]; - for (int i = 0; i < numZoneData; i++) { - ret.zonedata[i] = readZONEDATA("zonedata"); - } - readUB(6, "reserved"); - ret.zoneMaskY = readUB(1, "zoneMaskY") == 1; - ret.zoneMaskX = readUB(1, "zoneMaskX") == 1; - endDumpLevel(); - return ret; - } - - /** - * Reads one ZONEDATA value from the stream - * - * @param name - * @return ZONEDATA value - * @throws IOException - */ - public ZONEDATA readZONEDATA(String name) throws IOException { - ZONEDATA ret = new ZONEDATA(); - newDumpLevel(name, "ZONEDATA"); - ret.alignmentCoordinate = readUI16("alignmentCoordinate"); - ret.range = readUI16("range"); - endDumpLevel(); - return ret; - } - - /** - * Reads one PIX15 value from the stream - * - * @param name - * @return PIX15 value - * @throws IOException - */ - public PIX15 readPIX15(String name) throws IOException { - PIX15 ret = new PIX15(); - newDumpLevel(name, "PIX15"); - readUB(1, "reserved"); - ret.red = (int) readUB(5, "red"); - ret.green = (int) readUB(5, "green"); - ret.blue = (int) readUB(5, "blue"); - endDumpLevel(); - return ret; - } - - /** - * Reads one PIX24 value from the stream - * - * @param name - * @return PIX24 value - * @throws IOException - */ - public PIX24 readPIX24(String name) throws IOException { - PIX24 ret = new PIX24(); - newDumpLevel(name, "PIX24"); - ret.reserved = readUI8("reserved"); - ret.red = readUI8("red"); - ret.green = readUI8("green"); - ret.blue = readUI8("blue"); - endDumpLevel(); - return ret; - } - - /** - * Reads one COLORMAPDATA value from the stream - * - * @param colorTableSize - * @param bitmapWidth - * @param bitmapHeight - * @param name - * @return COLORMAPDATA value - * @throws IOException - */ - public COLORMAPDATA readCOLORMAPDATA(int colorTableSize, int bitmapWidth, int bitmapHeight, String name) throws IOException { - COLORMAPDATA ret = new COLORMAPDATA(); - newDumpLevel(name, "COLORMAPDATA"); - ret.colorTableRGB = new RGB[colorTableSize + 1]; - for (int i = 0; i < colorTableSize + 1; i++) { - ret.colorTableRGB[i] = readRGB("colorTableRGB"); - } - int dataLen = 0; - for (int y = 0; y < bitmapHeight; y++) { - int x = 0; - for (; x < bitmapWidth; x++) { - dataLen++; - } - while ((x % 4) != 0) { - dataLen++; - x++; - } - } - ret.colorMapPixelData = readBytesEx(dataLen, "colorMapPixelData"); - endDumpLevel(); - return ret; - } - - /** - * Reads one BITMAPDATA value from the stream - * - * @param bitmapFormat - * @param bitmapWidth - * @param bitmapHeight - * @param name - * @return COLORMAPDATA value - * @throws IOException - */ - public BITMAPDATA readBITMAPDATA(int bitmapFormat, int bitmapWidth, int bitmapHeight, String name) throws IOException { - BITMAPDATA ret = new BITMAPDATA(); - newDumpLevel(name, "BITMAPDATA"); - int pixelCount = bitmapWidth * bitmapHeight; - PIX15[] pix15 = bitmapFormat == DefineBitsLosslessTag.FORMAT_15BIT_RGB ? new PIX15[pixelCount] : null; - PIX24[] pix24 = bitmapFormat == DefineBitsLosslessTag.FORMAT_24BIT_RGB ? new PIX24[pixelCount] : null; - int dataLen = 0; - int pos = 0; - for (int y = 0; y < bitmapHeight; y++) { - for (int x = 0; x < bitmapWidth; x++) { - if (bitmapFormat == DefineBitsLosslessTag.FORMAT_15BIT_RGB) { - dataLen += 2; - pix15[pos++] = readPIX15("pix15"); - } - if (bitmapFormat == DefineBitsLosslessTag.FORMAT_24BIT_RGB) { - dataLen += 4; - pix24[pos++] = readPIX24("pix24"); - } - } - while ((dataLen % 4) != 0) { - dataLen++; - readUI8("padding"); - } - } - if (bitmapFormat == DefineBitsLosslessTag.FORMAT_15BIT_RGB) { - ret.bitmapPixelDataPix15 = pix15; - } else if (bitmapFormat == DefineBitsLosslessTag.FORMAT_24BIT_RGB) { - ret.bitmapPixelDataPix24 = pix24; - } - endDumpLevel(); - return ret; - } - - /** - * Reads one BITMAPDATA value from the stream - * - * @param bitmapFormat - * @param bitmapWidth - * @param bitmapHeight - * @param name - * @return COLORMAPDATA value - * @throws IOException - */ - public ALPHABITMAPDATA readALPHABITMAPDATA(int bitmapFormat, int bitmapWidth, int bitmapHeight, String name) throws IOException { - ALPHABITMAPDATA ret = new ALPHABITMAPDATA(); - newDumpLevel(name, "ALPHABITMAPDATA"); - ret.bitmapPixelData = new ARGB[bitmapWidth * bitmapHeight]; - for (int y = 0; y < bitmapHeight; y++) { - for (int x = 0; x < bitmapWidth; x++) { - ret.bitmapPixelData[y * bitmapWidth + x] = readARGB("bitmapPixelData"); - } - } - endDumpLevel(); - return ret; - } - - /** - * Reads one ALPHACOLORMAPDATA value from the stream - * - * @param colorTableSize - * @param bitmapWidth - * @param bitmapHeight - * @param name - * @return ALPHACOLORMAPDATA value - * @throws IOException - */ - public ALPHACOLORMAPDATA readALPHACOLORMAPDATA(int colorTableSize, int bitmapWidth, int bitmapHeight, String name) throws IOException { - ALPHACOLORMAPDATA ret = new ALPHACOLORMAPDATA(); - newDumpLevel(name, "ALPHACOLORMAPDATA"); - ret.colorTableRGB = new RGBA[colorTableSize + 1]; - for (int i = 0; i < colorTableSize + 1; i++) { - ret.colorTableRGB[i] = readRGBA("colorTableRGB"); - } - int dataLen = 0; - for (int y = 0; y < bitmapHeight; y++) { - int x = 0; - for (; x < bitmapWidth; x++) { - dataLen++; - } - while ((x % 4) != 0) { - dataLen++; - x++; - } - } - ret.colorMapPixelData = readBytesEx(dataLen, ""); - endDumpLevel(); - return ret; - } - - public int available() throws IOException { - return is.available(); - } - - public long availableBits() throws IOException { - if (bitPos > 0) { - return available() * 8 + (8 - bitPos); - } - return available() * 8; - } - - public MemoryInputStream getBaseStream() throws IOException { - int pos = (int) is.getPos(); - MemoryInputStream mis = new MemoryInputStream(is.getAllRead(), 0, pos + is.available()); - mis.seek(pos); - return mis; - } - - public SWFInputStream getLimitedStream(int limit) throws IOException { - SWFInputStream sis = new SWFInputStream(swf, is.getAllRead(), startingPos, (int) (is.getPos() + limit)); - - // uncomment the following line to turn off lazy dump info collecting - //sis.dumpInfo = dumpInfo; - sis.seek(is.getPos() + startingPos); - return sis; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash; + +import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.special.ActionEnd; +import com.jpexs.decompiler.flash.action.special.ActionNop; +import com.jpexs.decompiler.flash.action.swf3.ActionGetURL; +import com.jpexs.decompiler.flash.action.swf3.ActionGoToLabel; +import com.jpexs.decompiler.flash.action.swf3.ActionGotoFrame; +import com.jpexs.decompiler.flash.action.swf3.ActionNextFrame; +import com.jpexs.decompiler.flash.action.swf3.ActionPlay; +import com.jpexs.decompiler.flash.action.swf3.ActionPrevFrame; +import com.jpexs.decompiler.flash.action.swf3.ActionSetTarget; +import com.jpexs.decompiler.flash.action.swf3.ActionStop; +import com.jpexs.decompiler.flash.action.swf3.ActionStopSounds; +import com.jpexs.decompiler.flash.action.swf3.ActionToggleQuality; +import com.jpexs.decompiler.flash.action.swf3.ActionWaitForFrame; +import com.jpexs.decompiler.flash.action.swf4.ActionAdd; +import com.jpexs.decompiler.flash.action.swf4.ActionAnd; +import com.jpexs.decompiler.flash.action.swf4.ActionAsciiToChar; +import com.jpexs.decompiler.flash.action.swf4.ActionCall; +import com.jpexs.decompiler.flash.action.swf4.ActionCharToAscii; +import com.jpexs.decompiler.flash.action.swf4.ActionCloneSprite; +import com.jpexs.decompiler.flash.action.swf4.ActionDivide; +import com.jpexs.decompiler.flash.action.swf4.ActionEndDrag; +import com.jpexs.decompiler.flash.action.swf4.ActionEquals; +import com.jpexs.decompiler.flash.action.swf4.ActionGetProperty; +import com.jpexs.decompiler.flash.action.swf4.ActionGetTime; +import com.jpexs.decompiler.flash.action.swf4.ActionGetURL2; +import com.jpexs.decompiler.flash.action.swf4.ActionGetVariable; +import com.jpexs.decompiler.flash.action.swf4.ActionGotoFrame2; +import com.jpexs.decompiler.flash.action.swf4.ActionIf; +import com.jpexs.decompiler.flash.action.swf4.ActionJump; +import com.jpexs.decompiler.flash.action.swf4.ActionLess; +import com.jpexs.decompiler.flash.action.swf4.ActionMBAsciiToChar; +import com.jpexs.decompiler.flash.action.swf4.ActionMBCharToAscii; +import com.jpexs.decompiler.flash.action.swf4.ActionMBStringExtract; +import com.jpexs.decompiler.flash.action.swf4.ActionMBStringLength; +import com.jpexs.decompiler.flash.action.swf4.ActionMultiply; +import com.jpexs.decompiler.flash.action.swf4.ActionNot; +import com.jpexs.decompiler.flash.action.swf4.ActionOr; +import com.jpexs.decompiler.flash.action.swf4.ActionPop; +import com.jpexs.decompiler.flash.action.swf4.ActionPush; +import com.jpexs.decompiler.flash.action.swf4.ActionRandomNumber; +import com.jpexs.decompiler.flash.action.swf4.ActionRemoveSprite; +import com.jpexs.decompiler.flash.action.swf4.ActionSetProperty; +import com.jpexs.decompiler.flash.action.swf4.ActionSetTarget2; +import com.jpexs.decompiler.flash.action.swf4.ActionSetVariable; +import com.jpexs.decompiler.flash.action.swf4.ActionStartDrag; +import com.jpexs.decompiler.flash.action.swf4.ActionStringAdd; +import com.jpexs.decompiler.flash.action.swf4.ActionStringEquals; +import com.jpexs.decompiler.flash.action.swf4.ActionStringExtract; +import com.jpexs.decompiler.flash.action.swf4.ActionStringLength; +import com.jpexs.decompiler.flash.action.swf4.ActionStringLess; +import com.jpexs.decompiler.flash.action.swf4.ActionSubtract; +import com.jpexs.decompiler.flash.action.swf4.ActionToInteger; +import com.jpexs.decompiler.flash.action.swf4.ActionTrace; +import com.jpexs.decompiler.flash.action.swf4.ActionWaitForFrame2; +import com.jpexs.decompiler.flash.action.swf5.ActionAdd2; +import com.jpexs.decompiler.flash.action.swf5.ActionBitAnd; +import com.jpexs.decompiler.flash.action.swf5.ActionBitLShift; +import com.jpexs.decompiler.flash.action.swf5.ActionBitOr; +import com.jpexs.decompiler.flash.action.swf5.ActionBitRShift; +import com.jpexs.decompiler.flash.action.swf5.ActionBitURShift; +import com.jpexs.decompiler.flash.action.swf5.ActionBitXor; +import com.jpexs.decompiler.flash.action.swf5.ActionCallFunction; +import com.jpexs.decompiler.flash.action.swf5.ActionCallMethod; +import com.jpexs.decompiler.flash.action.swf5.ActionConstantPool; +import com.jpexs.decompiler.flash.action.swf5.ActionDecrement; +import com.jpexs.decompiler.flash.action.swf5.ActionDefineFunction; +import com.jpexs.decompiler.flash.action.swf5.ActionDefineLocal; +import com.jpexs.decompiler.flash.action.swf5.ActionDefineLocal2; +import com.jpexs.decompiler.flash.action.swf5.ActionDelete; +import com.jpexs.decompiler.flash.action.swf5.ActionDelete2; +import com.jpexs.decompiler.flash.action.swf5.ActionEnumerate; +import com.jpexs.decompiler.flash.action.swf5.ActionEquals2; +import com.jpexs.decompiler.flash.action.swf5.ActionGetMember; +import com.jpexs.decompiler.flash.action.swf5.ActionIncrement; +import com.jpexs.decompiler.flash.action.swf5.ActionInitArray; +import com.jpexs.decompiler.flash.action.swf5.ActionInitObject; +import com.jpexs.decompiler.flash.action.swf5.ActionLess2; +import com.jpexs.decompiler.flash.action.swf5.ActionModulo; +import com.jpexs.decompiler.flash.action.swf5.ActionNewMethod; +import com.jpexs.decompiler.flash.action.swf5.ActionNewObject; +import com.jpexs.decompiler.flash.action.swf5.ActionPushDuplicate; +import com.jpexs.decompiler.flash.action.swf5.ActionReturn; +import com.jpexs.decompiler.flash.action.swf5.ActionSetMember; +import com.jpexs.decompiler.flash.action.swf5.ActionStackSwap; +import com.jpexs.decompiler.flash.action.swf5.ActionStoreRegister; +import com.jpexs.decompiler.flash.action.swf5.ActionTargetPath; +import com.jpexs.decompiler.flash.action.swf5.ActionToNumber; +import com.jpexs.decompiler.flash.action.swf5.ActionToString; +import com.jpexs.decompiler.flash.action.swf5.ActionTypeOf; +import com.jpexs.decompiler.flash.action.swf5.ActionWith; +import com.jpexs.decompiler.flash.action.swf6.ActionEnumerate2; +import com.jpexs.decompiler.flash.action.swf6.ActionGreater; +import com.jpexs.decompiler.flash.action.swf6.ActionInstanceOf; +import com.jpexs.decompiler.flash.action.swf6.ActionStrictEquals; +import com.jpexs.decompiler.flash.action.swf6.ActionStringGreater; +import com.jpexs.decompiler.flash.action.swf7.ActionCastOp; +import com.jpexs.decompiler.flash.action.swf7.ActionDefineFunction2; +import com.jpexs.decompiler.flash.action.swf7.ActionExtends; +import com.jpexs.decompiler.flash.action.swf7.ActionImplementsOp; +import com.jpexs.decompiler.flash.action.swf7.ActionThrow; +import com.jpexs.decompiler.flash.action.swf7.ActionTry; +import com.jpexs.decompiler.flash.configuration.Configuration; +import com.jpexs.decompiler.flash.dumpview.DumpInfo; +import com.jpexs.decompiler.flash.tags.CSMTextSettingsTag; +import com.jpexs.decompiler.flash.tags.DebugIDTag; +import com.jpexs.decompiler.flash.tags.DefineBinaryDataTag; +import com.jpexs.decompiler.flash.tags.DefineBitsJPEG2Tag; +import com.jpexs.decompiler.flash.tags.DefineBitsJPEG3Tag; +import com.jpexs.decompiler.flash.tags.DefineBitsJPEG4Tag; +import com.jpexs.decompiler.flash.tags.DefineBitsLossless2Tag; +import com.jpexs.decompiler.flash.tags.DefineBitsLosslessTag; +import com.jpexs.decompiler.flash.tags.DefineBitsTag; +import com.jpexs.decompiler.flash.tags.DefineButton2Tag; +import com.jpexs.decompiler.flash.tags.DefineButtonCxformTag; +import com.jpexs.decompiler.flash.tags.DefineButtonSoundTag; +import com.jpexs.decompiler.flash.tags.DefineButtonTag; +import com.jpexs.decompiler.flash.tags.DefineEditTextTag; +import com.jpexs.decompiler.flash.tags.DefineFont2Tag; +import com.jpexs.decompiler.flash.tags.DefineFont3Tag; +import com.jpexs.decompiler.flash.tags.DefineFont4Tag; +import com.jpexs.decompiler.flash.tags.DefineFontAlignZonesTag; +import com.jpexs.decompiler.flash.tags.DefineFontInfo2Tag; +import com.jpexs.decompiler.flash.tags.DefineFontInfoTag; +import com.jpexs.decompiler.flash.tags.DefineFontNameTag; +import com.jpexs.decompiler.flash.tags.DefineFontTag; +import com.jpexs.decompiler.flash.tags.DefineMorphShape2Tag; +import com.jpexs.decompiler.flash.tags.DefineMorphShapeTag; +import com.jpexs.decompiler.flash.tags.DefineScalingGridTag; +import com.jpexs.decompiler.flash.tags.DefineSceneAndFrameLabelDataTag; +import com.jpexs.decompiler.flash.tags.DefineShape2Tag; +import com.jpexs.decompiler.flash.tags.DefineShape3Tag; +import com.jpexs.decompiler.flash.tags.DefineShape4Tag; +import com.jpexs.decompiler.flash.tags.DefineShapeTag; +import com.jpexs.decompiler.flash.tags.DefineSoundTag; +import com.jpexs.decompiler.flash.tags.DefineSpriteTag; +import com.jpexs.decompiler.flash.tags.DefineText2Tag; +import com.jpexs.decompiler.flash.tags.DefineTextTag; +import com.jpexs.decompiler.flash.tags.DefineVideoStreamTag; +import com.jpexs.decompiler.flash.tags.DoABCDefineTag; +import com.jpexs.decompiler.flash.tags.DoABCTag; +import com.jpexs.decompiler.flash.tags.DoActionTag; +import com.jpexs.decompiler.flash.tags.DoInitActionTag; +import com.jpexs.decompiler.flash.tags.EnableDebugger2Tag; +import com.jpexs.decompiler.flash.tags.EnableDebuggerTag; +import com.jpexs.decompiler.flash.tags.EnableTelemetryTag; +import com.jpexs.decompiler.flash.tags.EndTag; +import com.jpexs.decompiler.flash.tags.ExportAssetsTag; +import com.jpexs.decompiler.flash.tags.FileAttributesTag; +import com.jpexs.decompiler.flash.tags.FrameLabelTag; +import com.jpexs.decompiler.flash.tags.ImportAssets2Tag; +import com.jpexs.decompiler.flash.tags.ImportAssetsTag; +import com.jpexs.decompiler.flash.tags.JPEGTablesTag; +import com.jpexs.decompiler.flash.tags.MetadataTag; +import com.jpexs.decompiler.flash.tags.PlaceObject2Tag; +import com.jpexs.decompiler.flash.tags.PlaceObject3Tag; +import com.jpexs.decompiler.flash.tags.PlaceObject4Tag; +import com.jpexs.decompiler.flash.tags.PlaceObjectTag; +import com.jpexs.decompiler.flash.tags.ProductInfoTag; +import com.jpexs.decompiler.flash.tags.ProtectTag; +import com.jpexs.decompiler.flash.tags.RemoveObject2Tag; +import com.jpexs.decompiler.flash.tags.RemoveObjectTag; +import com.jpexs.decompiler.flash.tags.ScriptLimitsTag; +import com.jpexs.decompiler.flash.tags.SetBackgroundColorTag; +import com.jpexs.decompiler.flash.tags.SetTabIndexTag; +import com.jpexs.decompiler.flash.tags.ShowFrameTag; +import com.jpexs.decompiler.flash.tags.SoundStreamBlockTag; +import com.jpexs.decompiler.flash.tags.SoundStreamHead2Tag; +import com.jpexs.decompiler.flash.tags.SoundStreamHeadTag; +import com.jpexs.decompiler.flash.tags.StartSound2Tag; +import com.jpexs.decompiler.flash.tags.StartSoundTag; +import com.jpexs.decompiler.flash.tags.SymbolClassTag; +import com.jpexs.decompiler.flash.tags.Tag; +import com.jpexs.decompiler.flash.tags.TagStub; +import com.jpexs.decompiler.flash.tags.UnknownTag; +import com.jpexs.decompiler.flash.tags.VideoFrameTag; +import com.jpexs.decompiler.flash.tags.gfx.DefineCompactedFont; +import com.jpexs.decompiler.flash.tags.gfx.DefineExternalGradient; +import com.jpexs.decompiler.flash.tags.gfx.DefineExternalImage; +import com.jpexs.decompiler.flash.tags.gfx.DefineExternalImage2; +import com.jpexs.decompiler.flash.tags.gfx.DefineExternalSound; +import com.jpexs.decompiler.flash.tags.gfx.DefineExternalStreamSound; +import com.jpexs.decompiler.flash.tags.gfx.DefineGradientMap; +import com.jpexs.decompiler.flash.tags.gfx.DefineSubImage; +import com.jpexs.decompiler.flash.tags.gfx.ExporterInfo; +import com.jpexs.decompiler.flash.tags.gfx.FontTextureInfo; +import com.jpexs.decompiler.flash.timeline.Timelined; +import com.jpexs.decompiler.flash.types.ALPHABITMAPDATA; +import com.jpexs.decompiler.flash.types.ALPHACOLORMAPDATA; +import com.jpexs.decompiler.flash.types.ARGB; +import com.jpexs.decompiler.flash.types.BITMAPDATA; +import com.jpexs.decompiler.flash.types.BUTTONCONDACTION; +import com.jpexs.decompiler.flash.types.BUTTONRECORD; +import com.jpexs.decompiler.flash.types.CLIPACTIONRECORD; +import com.jpexs.decompiler.flash.types.CLIPACTIONS; +import com.jpexs.decompiler.flash.types.CLIPEVENTFLAGS; +import com.jpexs.decompiler.flash.types.COLORMAPDATA; +import com.jpexs.decompiler.flash.types.CXFORM; +import com.jpexs.decompiler.flash.types.CXFORMWITHALPHA; +import com.jpexs.decompiler.flash.types.FILLSTYLE; +import com.jpexs.decompiler.flash.types.FILLSTYLEARRAY; +import com.jpexs.decompiler.flash.types.FOCALGRADIENT; +import com.jpexs.decompiler.flash.types.GLYPHENTRY; +import com.jpexs.decompiler.flash.types.GRADIENT; +import com.jpexs.decompiler.flash.types.GRADRECORD; +import com.jpexs.decompiler.flash.types.KERNINGRECORD; +import com.jpexs.decompiler.flash.types.LANGCODE; +import com.jpexs.decompiler.flash.types.LINESTYLE; +import com.jpexs.decompiler.flash.types.LINESTYLE2; +import com.jpexs.decompiler.flash.types.LINESTYLEARRAY; +import com.jpexs.decompiler.flash.types.MATRIX; +import com.jpexs.decompiler.flash.types.MORPHFILLSTYLE; +import com.jpexs.decompiler.flash.types.MORPHFILLSTYLEARRAY; +import com.jpexs.decompiler.flash.types.MORPHFOCALGRADIENT; +import com.jpexs.decompiler.flash.types.MORPHGRADIENT; +import com.jpexs.decompiler.flash.types.MORPHGRADRECORD; +import com.jpexs.decompiler.flash.types.MORPHLINESTYLE; +import com.jpexs.decompiler.flash.types.MORPHLINESTYLE2; +import com.jpexs.decompiler.flash.types.MORPHLINESTYLEARRAY; +import com.jpexs.decompiler.flash.types.PIX15; +import com.jpexs.decompiler.flash.types.PIX24; +import com.jpexs.decompiler.flash.types.RECT; +import com.jpexs.decompiler.flash.types.RGB; +import com.jpexs.decompiler.flash.types.RGBA; +import com.jpexs.decompiler.flash.types.SHAPE; +import com.jpexs.decompiler.flash.types.SHAPEWITHSTYLE; +import com.jpexs.decompiler.flash.types.SOUNDENVELOPE; +import com.jpexs.decompiler.flash.types.SOUNDINFO; +import com.jpexs.decompiler.flash.types.TEXTRECORD; +import com.jpexs.decompiler.flash.types.ZONEDATA; +import com.jpexs.decompiler.flash.types.ZONERECORD; +import com.jpexs.decompiler.flash.types.filters.BEVELFILTER; +import com.jpexs.decompiler.flash.types.filters.BLURFILTER; +import com.jpexs.decompiler.flash.types.filters.COLORMATRIXFILTER; +import com.jpexs.decompiler.flash.types.filters.CONVOLUTIONFILTER; +import com.jpexs.decompiler.flash.types.filters.DROPSHADOWFILTER; +import com.jpexs.decompiler.flash.types.filters.FILTER; +import com.jpexs.decompiler.flash.types.filters.GLOWFILTER; +import com.jpexs.decompiler.flash.types.filters.GRADIENTBEVELFILTER; +import com.jpexs.decompiler.flash.types.filters.GRADIENTGLOWFILTER; +import com.jpexs.decompiler.flash.types.shaperecords.CurvedEdgeRecord; +import com.jpexs.decompiler.flash.types.shaperecords.EndShapeRecord; +import com.jpexs.decompiler.flash.types.shaperecords.SHAPERECORD; +import com.jpexs.decompiler.flash.types.shaperecords.StraightEdgeRecord; +import com.jpexs.decompiler.flash.types.shaperecords.StyleChangeRecord; +import com.jpexs.helpers.ByteArrayRange; +import com.jpexs.helpers.Helper; +import com.jpexs.helpers.ImmediateFuture; +import com.jpexs.helpers.MemoryInputStream; +import com.jpexs.helpers.ProgressListener; +import com.jpexs.helpers.utf8.Utf8Helper; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.EOFException; +import java.io.IOException; +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.zip.InflaterInputStream; + +/** + * Class for reading data from SWF file + * + * @author JPEXS + */ +public class SWFInputStream implements AutoCloseable { + + private MemoryInputStream is; + + private long startingPos; + + private static final Logger logger = Logger.getLogger(SWFInputStream.class.getName()); + + private final List listeners = new ArrayList<>(); + + private long percentMax; + + private SWF swf; + + public DumpInfo dumpInfo; + + public void addPercentListener(ProgressListener listener) { + listeners.add(listener); + } + + public void removePercentListener(ProgressListener listener) { + int index = listeners.indexOf(listener); + if (index > -1) { + listeners.remove(index); + } + } + + private void informListeners() { + if (listeners.size() > 0 && percentMax > 0) { + int percent = (int) (getPos() * 100 / percentMax); + if (lastPercent != percent) { + for (ProgressListener pl : listeners) { + pl.progress(percent); + } + lastPercent = percent; + } + } + } + + public void setPercentMax(long percentMax) { + this.percentMax = percentMax; + } + + /** + * Constructor + * + * @param swf SWF to read + * @param data SWF data + * @param startingPos + * @param limit + * @throws java.io.IOException + */ + public SWFInputStream(SWF swf, byte[] data, long startingPos, int limit) throws IOException { + this.swf = swf; + this.startingPos = startingPos; + is = new MemoryInputStream(data, 0, limit); + } + + /** + * Constructor + * + * @param swf SWF to read + * @param data SWF data + * @throws java.io.IOException + */ + public SWFInputStream(SWF swf, byte[] data) throws IOException { + this(swf, data, 0L, data.length); + } + + public SWF getSwf() { + return swf; + } + + /** + * Gets position in bytes in the stream + * + * @return Number of bytes + */ + public long getPos() { + return startingPos + is.getPos(); + } + + /** + * Sets position in bytes in the stream + * + * @param pos Number of bytes + * @throws java.io.IOException + */ + public void seek(long pos) throws IOException { + is.seek(pos - startingPos); + } + + private void newDumpLevel(String name, String type) { + if (dumpInfo != null) { + long startByte = is.getPos(); + if (bitPos > 0) { + startByte--; + } + DumpInfo di = new DumpInfo(name, type, null, startByte, bitPos, 0, 0); + di.parent = dumpInfo; + dumpInfo.getChildInfos().add(di); + dumpInfo = di; + } + } + + private void endDumpLevel() { + endDumpLevel(null); + } + + private void endDumpLevel(Object value) { + if (dumpInfo != null) { + if (dumpInfo.startBit == 0 && bitPos == 0) { + dumpInfo.lengthBytes = is.getPos() - dumpInfo.startByte; + } else { + dumpInfo.lengthBits = (int) ((is.getPos() - dumpInfo.startByte - 1) * 8 - dumpInfo.startBit + (bitPos == 0 ? 8 : bitPos)); + } + dumpInfo.previewValue = value; + dumpInfo = dumpInfo.parent; + } + } + + private void endDumpLevelUntil(DumpInfo di) { + if (di != null) { + while (dumpInfo != null && dumpInfo != di) { + endDumpLevel(); + } + } + } + + /** + * Reads one byte from the stream + * + * @return byte + * @throws IOException + */ + private int readEx() throws IOException { + bitPos = 0; + return readNoBitReset(); + } + + private void alignByte() { + bitPos = 0; + } + + private int lastPercent = -1; + + private int readNoBitReset() throws IOException, EndOfStreamException { + int r = is.read(); + if (r == -1) { + throw new EndOfStreamException(); + } + + informListeners(); + return r; + } + + /** + * Reads one UI8 (Unsigned 8bit integer) value from the stream + * + * @param name + * @return UI8 value or -1 on error + * @throws IOException + */ + public int readUI8(String name) throws IOException { + newDumpLevel(name, "UI8"); + int ret = readEx(); + endDumpLevel(ret); + return ret; + } + + /** + * Reads one string value from the stream + * + * @param name + * @return String value + * @throws IOException + */ + public String readString(String name) throws IOException { + newDumpLevel(name, "string"); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + int r; + while (true) { + r = readEx(); + if (r == 0) { + endDumpLevel(); + return new String(baos.toByteArray(), Utf8Helper.charset); + } + baos.write(r); + } + } + + /** + * Reads one UI32 (Unsigned 32bit integer) value from the stream + * + * @param name + * @return UI32 value + * @throws IOException + */ + public long readUI32(String name) throws IOException { + newDumpLevel(name, "UI32"); + long ret = readUI32Internal(); + endDumpLevel(ret); + return ret; + } + + /** + * Reads one UI32 (Unsigned 32bit integer) value from the stream + * + * @return UI32 value + * @throws IOException + */ + private long readUI32Internal() throws IOException { + return (readEx() + (readEx() << 8) + (readEx() << 16) + (readEx() << 24)) & 0xffffffff; + } + + /** + * Reads one UI16 (Unsigned 16bit integer) value from the stream + * + * @param name + * @return UI16 value + * @throws IOException + */ + public int readUI16(String name) throws IOException { + newDumpLevel(name, "UI16"); + int ret = readUI16Internal(); + endDumpLevel(ret); + return ret; + } + + /** + * Reads one UI16 (Unsigned 16bit integer) value from the stream + * + * @return UI16 value + * @throws IOException + */ + private int readUI16Internal() throws IOException { + return readEx() + (readEx() << 8); + } + + public int readUI24(String name) throws IOException { + newDumpLevel(name, "UI24"); + int ret = readEx() + (readEx() << 8) + (readEx() << 16); + endDumpLevel(ret); + return ret; + } + + /** + * Reads one SI32 (Signed 32bit integer) value from the stream + * + * @param name + * @return SI32 value + * @throws IOException + */ + public long readSI32(String name) throws IOException { + newDumpLevel(name, "SI32"); + long uval = readEx() + (readEx() << 8) + (readEx() << 16) + (readEx() << 24); + if (uval >= 0x80000000) { + uval = -(((~uval) & 0xffffffff) + 1); + } + endDumpLevel(uval); + return uval; + } + + /** + * Reads one SI16 (Signed 16bit integer) value from the stream + * + * @param name + * @return SI16 value + * @throws IOException + */ + public int readSI16(String name) throws IOException { + newDumpLevel(name, "SI16"); + int uval = readEx() + (readEx() << 8); + if (uval >= 0x8000) { + uval = -(((~uval) & 0xffff) + 1); + } + endDumpLevel(uval); + return uval; + } + + /** + * Reads one SI8 (Signed 8bit integer) value from the stream + * + * @param name + * @return SI8 value + * @throws IOException + */ + public int readSI8(String name) throws IOException { + newDumpLevel(name, "SI8"); + int uval = readEx(); + if (uval >= 0x80) { + uval = -(((~uval) & 0xff) + 1); + } + endDumpLevel(uval); + return uval; + } + + /** + * Reads one FIXED (Fixed point 16.16) value from the stream + * + * @param name + * @return FIXED value + * @throws IOException + */ + public double readFIXED(String name) throws IOException { + newDumpLevel(name, "FIXED"); + int afterPoint = readUI16Internal(); + int beforePoint = readUI16Internal(); + double ret = ((double) ((beforePoint << 16) + afterPoint)) / 65536; + endDumpLevel(ret); + return ret; + } + + /** + * Reads one FIXED8 (Fixed point 8.8) value from the stream + * + * @param name + * @return FIXED8 value + * @throws IOException + */ + public float readFIXED8(String name) throws IOException { + newDumpLevel(name, "FIXED8"); + int afterPoint = readEx(); + int beforePoint = readEx(); + float ret = beforePoint + (((float) afterPoint) / 256); + endDumpLevel(ret); + return ret; + } + + private long readLong() throws IOException { + byte[] readBuffer = readBytesInternalEx(8); + return (((long) readBuffer[3] << 56) + + ((long) (readBuffer[2] & 255) << 48) + + ((long) (readBuffer[1] & 255) << 40) + + ((long) (readBuffer[0] & 255) << 32) + + ((long) (readBuffer[7] & 255) << 24) + + ((readBuffer[6] & 255) << 16) + + ((readBuffer[5] & 255) << 8) + + ((readBuffer[4] & 255))); + } + + /** + * Reads one DOUBLE (double precision floating point value) value from the + * stream + * + * @param name + * @return DOUBLE value + * @throws IOException + */ + public double readDOUBLE(String name) throws IOException { + newDumpLevel(name, "DOUBLE"); + long el = readLong(); + double ret = Double.longBitsToDouble(el); + endDumpLevel(ret); + return ret; + } + + /** + * Reads one FLOAT (single precision floating point value) value from the + * stream + * + * @param name + * @return FLOAT value + * @throws IOException + */ + public float readFLOAT(String name) throws IOException { + newDumpLevel(name, "FLOAT"); + int val = (int) readUI32Internal(); + float ret = Float.intBitsToFloat(val); + endDumpLevel(ret); + /*int sign = val >> 31; + int mantisa = val & 0x3FFFFF; + int exp = (val >> 22) & 0xFF; + float ret =(sign == 1 ? -1 : 1) * (float) Math.pow(2, exp)* (1+((mantisa)/ (float)(1<<23)));*/ + return ret; + } + + /** + * Reads one FLOAT16 (16bit floating point value) value from the stream + * + * @param name + * @return FLOAT16 value + * @throws IOException + */ + public float readFLOAT16(String name) throws IOException { + newDumpLevel(name, "FLOAT16"); + int val = readUI16Internal(); + int sign = val >> 15; + int mantisa = val & 0x3FF; + int exp = (val >> 10) & 0x1F; + float ret = (sign == 1 ? -1 : 1) * (float) Math.pow(2, exp) * (1 + ((mantisa) / (float) (1 << 10))); + endDumpLevel(ret); + return ret; + } + + /** + * Reads bytes from the stream + * + * @param count Number of bytes to read + * @param name + * @return Array of read bytes + * @throws IOException + */ + public byte[] readBytesEx(long count, String name) throws IOException { + if (count <= 0) { + return new byte[0]; + } + newDumpLevel(name, "bytes"); + byte[] ret = readBytesInternalEx(count); + endDumpLevel(); + return ret; + } + + /** + * Reads byte range from the stream + * + * @param count Number of bytes to read + * @param name + * @return ByteArrayRange object + * @throws IOException + */ + public ByteArrayRange readByteRangeEx(long count, String name) throws IOException { + if (count <= 0) { + return ByteArrayRange.EMPTY; + } + newDumpLevel(name, "bytes"); + int startPos = (int) getPos(); + skipBytesEx(count); + endDumpLevel(); + return new ByteArrayRange(swf.uncompressedData, startPos, (int) count); + } + + /** + * Reads bytes from the stream + * + * @param count Number of bytes to read + * @return Array of read bytes + * @throws IOException + */ + private byte[] readBytesInternalEx(long count) throws IOException { + if (count <= 0) { + return new byte[0]; + } + + bitPos = 0; + byte[] ret = new byte[(int) count]; + if (is.read(ret) != count) { + throw new EndOfStreamException(); + } + + informListeners(); + return ret; + } + + /** + * Skip bytes from the stream + * + * @param count Number of bytes to skip + * @throws IOException + */ + public void skipBytesEx(long count) throws IOException { + if (count <= 0) { + return; + } + + bitPos = 0; + is.seek(is.getPos() + count); + if (is.available() < 0) { + throw new EndOfStreamException(); + } + + informListeners(); + } + + /** + * Skip bytes from the stream + * + * @param count Number of bytes to skip + * @throws IOException + */ + public void skipBytes(long count) throws IOException { + try { + skipBytesEx(count); + } catch (EOFException | EndOfStreamException ex) { + logger.log(Level.SEVERE, null, ex); + } + } + + /** + * Reads bytes from the stream + * + * @param count Number of bytes to read + * @param name + * @return Array of read bytes + * @throws IOException + */ + public byte[] readBytes(int count, String name) throws IOException { + if (count <= 0) { + return new byte[0]; + } + newDumpLevel(name, "bytes"); + byte[] ret = new byte[count]; + int i = 0; + try { + for (i = 0; i < count; i++) { + ret[i] = (byte) readEx(); + } + } catch (EOFException | EndOfStreamException ex) { + ret = Arrays.copyOf(ret, i); // truncate array + logger.log(Level.SEVERE, null, ex); + } + endDumpLevel(); + return ret; + } + + public byte[] readBytesZlib(long count, String name) throws IOException { + newDumpLevel(name, "bytesZlib"); + byte[] data = readBytesInternalEx(count); + endDumpLevel(); + InflaterInputStream dis = new InflaterInputStream(new ByteArrayInputStream(data)); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + if (count > 0) { + byte[] buf = new byte[4096]; + int c = 0; + while ((c = dis.read(buf)) > 0) { + baos.write(buf, 0, c); + } + } + return baos.toByteArray(); + } + + /** + * Reads one EncodedU32 (Encoded unsigned 32bit value) value from the stream + * + * @param name + * @return U32 value + * @throws IOException + */ + public long readEncodedU32(String name) throws IOException { + newDumpLevel(name, "encodedU32"); + int result = readEx(); + if ((result & 0x00000080) == 0) { + endDumpLevel(result); + return result; + } + result = (result & 0x0000007f) | (readEx()) << 7; + if ((result & 0x00004000) == 0) { + endDumpLevel(result); + return result; + } + result = (result & 0x00003fff) | (readEx()) << 14; + if ((result & 0x00200000) == 0) { + endDumpLevel(result); + return result; + } + result = (result & 0x001fffff) | (readEx()) << 21; + if ((result & 0x10000000) == 0) { + endDumpLevel(result); + return result; + } + result = (result & 0x0fffffff) | (readEx()) << 28; + endDumpLevel(result); + return result; + } + + private int bitPos = 0; + + private int tempByte = 0; + + /** + * Reads UB[nBits] (Unsigned-bit value) value from the stream + * + * @param nBits Number of bits which represent value + * @param name + * @return Unsigned value + * @throws IOException + */ + public long readUB(int nBits, String name) throws IOException { + if (nBits == 0) { + return 0; + } + newDumpLevel(name, "UB"); + long ret = readUBInternal(nBits); + endDumpLevel(ret); + return ret; + } + + /** + * Reads UB[nBits] (Unsigned-bit value) value from the stream + * + * @param nBits Number of bits which represent value + * @return Unsigned value + * @throws IOException + */ + private long readUBInternal(int nBits) throws IOException { + if (nBits == 0) { + return 0; + } + long ret = 0; + if (bitPos == 0) { + tempByte = readNoBitReset(); + } + for (int bit = 0; bit < nBits; bit++) { + int nb = (tempByte >> (7 - bitPos)) & 1; + ret += (nb << (nBits - 1 - bit)); + bitPos++; + if (bitPos == 8) { + bitPos = 0; + if (bit != nBits - 1) { + tempByte = readNoBitReset(); + } + } + } + return ret; + } + + /** + * Reads SB[nBits] (Signed-bit value) value from the stream + * + * @param nBits Number of bits which represent value + * @param name + * @return Signed value + * @throws IOException + */ + public long readSB(int nBits, String name) throws IOException { + if (nBits == 0) { + return 0; + } + newDumpLevel(name, "SB"); + long ret = readSBInternal(nBits); + endDumpLevel(ret); + return ret; + } + + /** + * Reads SB[nBits] (Signed-bit value) value from the stream + * + * @param nBits Number of bits which represent value + * @return Signed value + * @throws IOException + */ + private long readSBInternal(int nBits) throws IOException { + int uval = (int) readUBInternal(nBits); + + int shift = 32 - nBits; + // sign extension + uval = (uval << shift) >> shift; + return uval; + } + + /** + * Reads FB[nBits] (Signed fixed-point bit value) value from the stream + * + * @param nBits Number of bits which represent value + * @param name + * @return Fixed-point value + * @throws IOException + */ + public float readFB(int nBits, String name) throws IOException { + if (nBits == 0) { + return 0; + } + newDumpLevel(name, "FB"); + float val = readSBInternal(nBits); + float ret = val / 0x10000; + endDumpLevel(ret); + return ret; + } + + /** + * Reads one RECT value from the stream + * + * @param name + * @return RECT value + * @throws IOException + */ + public RECT readRECT(String name) throws IOException { + RECT ret = new RECT(); + newDumpLevel(name, "RECT"); + int NBits = (int) readUB(5, "NBits"); + ret.Xmin = (int) readSB(NBits, "Xmin"); + ret.Xmax = (int) readSB(NBits, "Xmax"); + ret.Ymin = (int) readSB(NBits, "Ymin"); + ret.Ymax = (int) readSB(NBits, "Ymax"); + ret.nbits = NBits; + alignByte(); + endDumpLevel(); + return ret; + } + + private static void dumpTag(PrintStream out, int version, Tag tag, int level) { + StringBuilder sb = new StringBuilder(); + sb.append(Helper.formatHex((int) tag.getPos(), 8)); + sb.append(": "); + sb.append(Helper.indent(level, "", " ")); + sb.append(Helper.format(tag.toString(), 25 - 2 * level)); + sb.append(" tagId="); + sb.append(Helper.formatInt(tag.getId(), 3)); + sb.append(" len="); + sb.append(Helper.formatInt(tag.getOriginalDataLength(), 8)); + sb.append(" "); + sb.append(Helper.bytesToHexString(64, tag.getOriginalData(), 0)); + out.println(sb.toString()); + // out.println(Utils.formatHex((int)tag.getPos(), 8) + ": " + Utils.indent(level, "") + Utils.format(tag.toString(), 25 - 2*level) + " tagId="+tag.getId()+" len="+tag.getOrigDataLength()+": "+Utils.bytesToHexString(64, tag.getData(version), 0)); + if (tag instanceof DefineSpriteTag) { + for (Tag subTag : ((DefineSpriteTag) tag).getSubTags()) { + dumpTag(out, version, subTag, level + 1); + } + } + } + + @Override + public void close() { + } + + private class TagResolutionTask implements Callable { + + private final TagStub tag; + + private final DumpInfo dumpInfo; + + private final int level; + + private final boolean parallel; + + private final boolean skipUnusualTags; + + private final boolean lazy; + + public TagResolutionTask(TagStub tag, DumpInfo dumpInfo, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) { + this.tag = tag; + this.dumpInfo = dumpInfo; + this.level = level; + this.parallel = parallel; + this.skipUnusualTags = skipUnusualTags; + this.lazy = lazy; + } + + @Override + public Tag call() throws Exception { + DumpInfo di = dumpInfo; + try { + Tag t = resolveTag(tag, level, parallel, skipUnusualTags, lazy); + if (dumpInfo != null && t != null) { + dumpInfo.name = t.getName(); + } + return t; + } catch (Exception ex) { + tag.getDataStream().endDumpLevelUntil(di); + logger.log(Level.SEVERE, null, ex); + return tag; + } + } + } + + /** + * Reads list of tags from the stream. Reading ends with End tag(=0) or end + * of the stream. Optionally can skip AS1/2 tags when file is AS3 + * + * @param timelined + * @param level + * @param parallel + * @param skipUnusualTags + * @param parseTags + * @param lazy + * @return List of tags + * @throws IOException + * @throws java.lang.InterruptedException + */ + public List readTagList(Timelined timelined, int level, boolean parallel, boolean skipUnusualTags, boolean parseTags, boolean lazy) throws IOException, InterruptedException { + if (Thread.currentThread().interrupted()) { + throw new InterruptedException(); + } + + boolean parallel1 = level == 0 && parallel; + ExecutorService executor = null; + List> futureResults = new ArrayList<>(); + if (parallel1) { + executor = Executors.newFixedThreadPool(Configuration.getParallelThreadCount()); + futureResults = new ArrayList<>(); + } + List tags = new ArrayList<>(); + Tag tag; + boolean isAS3 = false; + while (available() > 0) { + long pos = getPos(); + newDumpLevel(null, "TAG"); + try { + tag = readTag(timelined, level, pos, parseTags && !parallel1, parallel1, skipUnusualTags, lazy); + } catch (EOFException | EndOfStreamException ex) { + tag = null; + } + DumpInfo di = dumpInfo; + if (di != null && tag != null) { + di.name = tag.getName(); + } + endDumpLevel(tag == null ? null : tag.getId()); + if (tag == null) { + break; + } + + tag.setTimelined(timelined); + if (!parallel1) { + tags.add(tag); + } + if (Configuration.dumpTags.get() && level == 0) { + dumpTag(System.out, swf.version, tag, level); + } + + boolean doParse; + if (!skipUnusualTags) { + doParse = true; + } else { + switch (tag.getId()) { + case FileAttributesTag.ID: // FileAttributes + if (tag instanceof TagStub) { + tag = resolveTag((TagStub) tag, level, parallel1, skipUnusualTags, lazy); + } + FileAttributesTag fileAttributes = (FileAttributesTag) tag; + if (fileAttributes.actionScript3) { + isAS3 = true; + } + doParse = true; + break; + case DoActionTag.ID: + case DoInitActionTag.ID: + if (isAS3) { + doParse = false; + } else { + doParse = true; + } + break; + case ShowFrameTag.ID: + case PlaceObjectTag.ID: + case PlaceObject2Tag.ID: + case RemoveObjectTag.ID: + case RemoveObject2Tag.ID: + case PlaceObject3Tag.ID: // ? + case StartSoundTag.ID: + case FrameLabelTag.ID: + case SoundStreamHeadTag.ID: + case SoundStreamHead2Tag.ID: + case SoundStreamBlockTag.ID: + case VideoFrameTag.ID: + case EndTag.ID: + doParse = true; + break; + default: + if (level > 0) { //No such tags in DefineSprite allowed + logger.log(Level.FINE, "Tag({0}) found in DefineSprite => Ignored", tag.getId()); + doParse = false; + } else { + doParse = true; + } + + } + } + if (parseTags && doParse && parallel1 && tag instanceof TagStub) { + Future future = executor.submit(new TagResolutionTask((TagStub) tag, di, level, parallel1, skipUnusualTags, lazy)); + futureResults.add(future); + } else { + Future future = new ImmediateFuture<>(tag); + futureResults.add(future); + if (!(tag instanceof TagStub)) { + if (di != null) { + di.name = tag.getName(); + } + } + } + + if (tag.getId() == EndTag.ID) { + break; + } + } + + if (parallel1) { + for (Future future : futureResults) { + try { + tags.add(future.get()); + } catch (InterruptedException ex) { + future.cancel(true); + } catch (ExecutionException e) { + logger.log(Level.SEVERE, "Error during tag reading", e); + } + } + + executor.shutdown(); + } + return tags; + } + + public static Tag resolveTag(TagStub tag, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws InterruptedException { + Tag ret; + + ByteArrayRange data = tag.getOriginalRange(); + SWF swf = tag.getSwf(); + SWFInputStream sis = tag.getDataStream(); + + try { + switch (tag.getId()) { + case 0: + ret = new EndTag(sis, data); + break; + case 1: + ret = new ShowFrameTag(sis, data); + break; + case 2: + ret = new DefineShapeTag(sis, data, lazy); + break; + //case 3: FreeCharacter + case 4: + ret = new PlaceObjectTag(sis, data); + break; + case 5: + ret = new RemoveObjectTag(sis, data); + break; + case 6: + ret = new DefineBitsTag(sis, data); + break; + case 7: + ret = new DefineButtonTag(sis, data); + break; + case 8: + ret = new JPEGTablesTag(sis, data); + break; + case 9: + ret = new SetBackgroundColorTag(sis, data); + break; + case 10: + ret = new DefineFontTag(sis, data); + break; + case 11: + ret = new DefineTextTag(sis, data); + break; + case 12: + ret = new DoActionTag(sis, data); + break; + case 13: + ret = new DefineFontInfoTag(sis, data); + break; + case 14: + ret = new DefineSoundTag(sis, data); + break; + case 15: + ret = new StartSoundTag(sis, data); + break; + //case 16: StopSound + case 17: + ret = new DefineButtonSoundTag(sis, data); + break; + case 18: + ret = new SoundStreamHeadTag(sis, data); + break; + case 19: + ret = new SoundStreamBlockTag(sis, data); + break; + case 20: + ret = new DefineBitsLosslessTag(sis, data); + break; + case 21: + ret = new DefineBitsJPEG2Tag(sis, data); + break; + case 22: + ret = new DefineShape2Tag(sis, data, lazy); + break; + case 23: + ret = new DefineButtonCxformTag(sis, data); + break; + case 24: + ret = new ProtectTag(sis, data); + break; + //case 25: PathsArePostscript + case 26: + ret = new PlaceObject2Tag(sis, data); + break; + //case 27: + case 28: + ret = new RemoveObject2Tag(sis, data); + break; + //case 29: SyncFrame + //case 30: + //case 31: FreeAll + case 32: + ret = new DefineShape3Tag(sis, data, lazy); + break; + case 33: + ret = new DefineText2Tag(sis, data); + break; + case 34: + ret = new DefineButton2Tag(sis, data); + break; + case 35: + ret = new DefineBitsJPEG3Tag(sis, data); + break; + case 36: + ret = new DefineBitsLossless2Tag(sis, data); + break; + case 37: + ret = new DefineEditTextTag(sis, data); + break; + //case 38: DefineVideo + case 39: + ret = new DefineSpriteTag(sis, level, data, parallel, skipUnusualTags); + break; + //case 40: NameCharacter + case 41: + ret = new ProductInfoTag(sis, data); + break; + //case 42: DefineTextFormat + case 43: + ret = new FrameLabelTag(sis, data); + break; + //case 44: DefineBehavior + case 45: + ret = new SoundStreamHead2Tag(sis, data); + break; + case 46: + ret = new DefineMorphShapeTag(sis, data); + break; + //case 47: GenerateFrame + case 48: + ret = new DefineFont2Tag(sis, data); + break; + //case 49: GeneratorCommand + //case 50: DefineCommandObject + //case 51: CharacterSet + //case 52: ExternalFont + //case 53: DefineFunction + //case 54: PlaceFunction + //case 55: GenTagObject + case 56: + ret = new ExportAssetsTag(sis, data); + break; + case 57: + ret = new ImportAssetsTag(sis, data); + break; + case 58: + ret = new EnableDebuggerTag(sis, data); + break; + case 59: + ret = new DoInitActionTag(sis, data); + break; + case 60: + ret = new DefineVideoStreamTag(sis, data); + break; + case 61: + ret = new VideoFrameTag(sis, data); + break; + case 62: + ret = new DefineFontInfo2Tag(sis, data); + break; + case 63: + ret = new DebugIDTag(sis, data); + break; + case 64: + ret = new EnableDebugger2Tag(sis, data); + break; + case 65: + ret = new ScriptLimitsTag(sis, data); + break; + case 66: + ret = new SetTabIndexTag(sis, data); + break; + //case 67: DefineShape4 ??? + //case 68: DefineMorphShape2 ??? + case 69: + ret = new FileAttributesTag(sis, data); + break; + case 70: + ret = new PlaceObject3Tag(sis, data); + break; + case 71: + ret = new ImportAssets2Tag(sis, data); + break; + case 72: + ret = new DoABCTag(sis, data); + break; + case 73: + ret = new DefineFontAlignZonesTag(sis, data); + break; + case 74: + ret = new CSMTextSettingsTag(sis, data); + break; + case 75: + ret = new DefineFont3Tag(sis, data); + break; + case 76: + ret = new SymbolClassTag(sis, data); + break; + case 77: + ret = new MetadataTag(sis, data); + break; + case 78: + ret = new DefineScalingGridTag(sis, data); + break; + //case 79-81: + case 82: + ret = new DoABCDefineTag(sis, data); + break; + case 83: + ret = new DefineShape4Tag(sis, data, lazy); + break; + case 84: + ret = new DefineMorphShape2Tag(sis, data); + break; + //case 85: + case 86: + ret = new DefineSceneAndFrameLabelDataTag(sis, data); + break; + case 87: + ret = new DefineBinaryDataTag(sis, data); + break; + case 88: + ret = new DefineFontNameTag(sis, data); + break; + case 89: + ret = new StartSound2Tag(sis, data); + break; + case 90: + ret = new DefineBitsJPEG4Tag(sis, data); + break; + case 91: + ret = new DefineFont4Tag(sis, data); + break; + //case 92: certificate + case 93: + ret = new EnableTelemetryTag(sis, data); + break; + case 94: + ret = new PlaceObject4Tag(sis, data); + break; + default: + if (swf.gfx) { // GFX tags only in GFX files. There may be incorrect GFX tags in non GFX files + switch (tag.getId()) { + case 1000: + ret = new ExporterInfo(sis, data); + break; + case 1001: + ret = new DefineExternalImage(sis, data); + break; + case 1002: + ret = new FontTextureInfo(sis, data); + break; + case 1003: + ret = new DefineExternalGradient(sis, data); + break; + case 1004: + ret = new DefineGradientMap(sis, data); + break; + case 1005: + ret = new DefineCompactedFont(sis, data); + break; + case 1006: + ret = new DefineExternalSound(sis, data); + break; + case 1007: + ret = new DefineExternalStreamSound(sis, data); + break; + case 1008: + ret = new DefineSubImage(sis, data); + break; + case 1009: + ret = new DefineExternalImage2(sis, data); + break; + default: + ret = new UnknownTag(swf, tag.getId(), data); + } + } else { + ret = new UnknownTag(swf, tag.getId(), data); + } + } + } catch (IOException ex) { + logger.log(Level.SEVERE, "Error during tag reading. SWF: " + swf.getShortFileName() + " ID: " + tag.getId() + " name: " + tag.getName() + " pos: " + data.getPos(), ex); + ret = new TagStub(swf, tag.getId(), "ErrorTag", data, null); + } + ret.forceWriteAsLong = tag.forceWriteAsLong; + ret.setTimelined(tag.getTimelined()); + return ret; + } + + /** + * Reads one Tag from the stream with optional resolving (= reading tag + * content) + * + * @param timelined + * @param level + * @param pos + * @param resolve + * @param parallel + * @param skipUnusualTags + * @param lazy + * @return Tag or null when End tag + * @throws IOException + * @throws java.lang.InterruptedException + */ + public Tag readTag(Timelined timelined, int level, long pos, boolean resolve, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException, InterruptedException { + int tagIDTagLength = readUI16("tagIDTagLength"); + int tagID = (tagIDTagLength) >> 6; + + logger.log(Level.FINE, "Reading tag. ID={0}, position: {1}", new Object[]{tagID, pos}); + + long tagLength = (tagIDTagLength & 0x003F); + boolean readLong = false; + if (tagLength == 0x3f) { + tagLength = readSI32("tagLength"); + readLong = true; + } + int headerLength = readLong ? 6 : 2; + SWFInputStream tagDataStream = getLimitedStream((int) tagLength); + int available = available(); + if (tagLength > available) { + tagLength = available; + } + + ByteArrayRange dataRange = new ByteArrayRange(swf.uncompressedData, (int) pos, (int) (tagLength + headerLength)); + skipBytes(tagLength); + + TagStub tagStub = new TagStub(swf, tagID, "Unresolved", dataRange, tagDataStream); + tagStub.forceWriteAsLong = readLong; + Tag ret = tagStub; + + if (tagDataStream.dumpInfo == null && dumpInfo != null) { + dumpInfo.tagToResolve = tagStub; + } + + if (resolve) { + DumpInfo di = dumpInfo; + try { + ret = resolveTag(tagStub, level, parallel, skipUnusualTags, lazy); + } catch (Exception ex) { + tagDataStream.endDumpLevelUntil(di); + logger.log(Level.SEVERE, "Problem in " + timelined.toString(), ex); + } + + if (Configuration.debugMode.get()) { + byte[] data = ret.getOriginalData(); + byte[] dataNew = ret.getData(); + int ignoreFirst = 0; + for (int i = 0; i < data.length; i++) { + if (i >= dataNew.length) { + break; + } + if (dataNew[i] != data[i]) { + if (ignoreFirst > 0) { + ignoreFirst--; + continue; + } + String e = "TAG " + ret.toString() + " WRONG, "; + for (int j = i - 10; j <= i + 5; j++) { + while (j < 0) { + j++; + } + if (j >= data.length) { + break; + } + if (j >= dataNew.length) { + break; + } + if (j >= i) { + e += (Long.toHexString(data[j] & 0xff) + " ( is " + Long.toHexString(dataNew[j] & 0xff) + ") "); + } else { + e += (Long.toHexString(data[j] & 0xff) + " "); + } + } + logger.fine(e); + } + } + } + } + return ret; + } + + /** + * Reads one Action from the stream + * + * @return Action or null when ActionEndFlag or end of the stream + * @throws IOException + */ + public Action readAction() throws IOException { + int actionCode = -1; + + try { + actionCode = readUI8("actionCode"); + if (actionCode == 0) { + return new ActionEnd(); + } + if (actionCode == -1) { + return null; + } + int actionLength = 0; + if (actionCode >= 0x80) { + actionLength = readUI16("actionLength"); + } + switch (actionCode) { + // SWF3 Actions + case 0x81: + return new ActionGotoFrame(actionLength, this); + case 0x83: + return new ActionGetURL(actionLength, this, swf.version); + case 0x04: + return new ActionNextFrame(); + case 0x05: + return new ActionPrevFrame(); + case 0x06: + return new ActionPlay(); + case 0x07: + return new ActionStop(); + case 0x08: + return new ActionToggleQuality(); + case 0x09: + return new ActionStopSounds(); + case 0x8A: + return new ActionWaitForFrame(actionLength, this); + case 0x8B: + return new ActionSetTarget(actionLength, this, swf.version); + case 0x8C: + return new ActionGoToLabel(actionLength, this, swf.version); + // SWF4 Actions + case 0x96: + return new ActionPush(actionLength, this, swf.version); + case 0x17: + return new ActionPop(); + case 0x0A: + return new ActionAdd(); + case 0x0B: + return new ActionSubtract(); + case 0x0C: + return new ActionMultiply(); + case 0x0D: + return new ActionDivide(); + case 0x0E: + return new ActionEquals(); + case 0x0F: + return new ActionLess(); + case 0x10: + return new ActionAnd(); + case 0x11: + return new ActionOr(); + case 0x12: + return new ActionNot(); + case 0x13: + return new ActionStringEquals(); + case 0x14: + return new ActionStringLength(); + case 0x21: + return new ActionStringAdd(); + case 0x15: + return new ActionStringExtract(); + case 0x29: + return new ActionStringLess(); + case 0x31: + return new ActionMBStringLength(); + case 0x35: + return new ActionMBStringExtract(); + case 0x18: + return new ActionToInteger(); + case 0x32: + return new ActionCharToAscii(); + case 0x33: + return new ActionAsciiToChar(); + case 0x36: + return new ActionMBCharToAscii(); + case 0x37: + return new ActionMBAsciiToChar(); + case 0x99: + return new ActionJump(actionLength, this); + case 0x9D: + return new ActionIf(actionLength, this); + case 0x9E: + return new ActionCall(actionLength); + case 0x1C: + return new ActionGetVariable(); + case 0x1D: + return new ActionSetVariable(); + case 0x9A: + return new ActionGetURL2(actionLength, this); + case 0x9F: + return new ActionGotoFrame2(actionLength, this); + case 0x20: + return new ActionSetTarget2(); + case 0x22: + return new ActionGetProperty(); + case 0x23: + return new ActionSetProperty(); + case 0x24: + return new ActionCloneSprite(); + case 0x25: + return new ActionRemoveSprite(); + case 0x27: + return new ActionStartDrag(); + case 0x28: + return new ActionEndDrag(); + case 0x8D: + return new ActionWaitForFrame2(actionLength, this); + case 0x26: + return new ActionTrace(); + case 0x34: + return new ActionGetTime(); + case 0x30: + return new ActionRandomNumber(); + // SWF5 Actions + case 0x3D: + return new ActionCallFunction(); + case 0x52: + return new ActionCallMethod(); + case 0x88: + return new ActionConstantPool(actionLength, this, swf.version); + case 0x9B: + return new ActionDefineFunction(actionLength, this, swf.version); + case 0x3C: + return new ActionDefineLocal(); + case 0x41: + return new ActionDefineLocal2(); + case 0x3A: + return new ActionDelete(); + case 0x3B: + return new ActionDelete2(); + case 0x46: + return new ActionEnumerate(); + case 0x49: + return new ActionEquals2(); + case 0x4E: + return new ActionGetMember(); + case 0x42: + return new ActionInitArray(); + case 0x43: + return new ActionInitObject(); + case 0x53: + return new ActionNewMethod(); + case 0x40: + return new ActionNewObject(); + case 0x4F: + return new ActionSetMember(); + case 0x45: + return new ActionTargetPath(); + case 0x94: + return new ActionWith(actionLength, this, swf.version); + case 0x4A: + return new ActionToNumber(); + case 0x4B: + return new ActionToString(); + case 0x44: + return new ActionTypeOf(); + case 0x47: + return new ActionAdd2(); + case 0x48: + return new ActionLess2(); + case 0x3F: + return new ActionModulo(); + case 0x60: + return new ActionBitAnd(); + case 0x63: + return new ActionBitLShift(); + case 0x61: + return new ActionBitOr(); + case 0x64: + return new ActionBitRShift(); + case 0x65: + return new ActionBitURShift(); + case 0x62: + return new ActionBitXor(); + case 0x51: + return new ActionDecrement(); + case 0x50: + return new ActionIncrement(); + case 0x4C: + return new ActionPushDuplicate(); + case 0x3E: + return new ActionReturn(); + case 0x4D: + return new ActionStackSwap(); + case 0x87: + return new ActionStoreRegister(actionLength, this); + // SWF6 Actions + case 0x54: + return new ActionInstanceOf(); + case 0x55: + return new ActionEnumerate2(); + case 0x66: + return new ActionStrictEquals(); + case 0x67: + return new ActionGreater(); + case 0x68: + return new ActionStringGreater(); + // SWF7 Actions + case 0x8E: + return new ActionDefineFunction2(actionLength, this, swf.version); + case 0x69: + return new ActionExtends(); + case 0x2B: + return new ActionCastOp(); + case 0x2C: + return new ActionImplementsOp(); + case 0x8F: + return new ActionTry(actionLength, this, swf.version); + case 0x2A: + return new ActionThrow(); + default: + /*if (actionLength > 0) { + //skip(actionLength); + }*/ + //throw new UnknownActionException(actionCode); + Action r = new ActionNop(); + r.actionCode = actionCode; + r.actionLength = actionLength; + if (Configuration.useDetailedLogging.get()) { + logger.log(Level.SEVERE, "Unknown action code: {0}", actionCode); + } + return r; + } + } catch (EndOfStreamException | ArrayIndexOutOfBoundsException eos) { + return null; + } + } + + /** + * Reads one MATRIX value from the stream + * + * @param name + * @return MATRIX value + * @throws IOException + */ + public MATRIX readMatrix(String name) throws IOException { + MATRIX ret = new MATRIX(); + newDumpLevel(name, "MATRIX"); + ret.hasScale = readUB(1, "hasScale") == 1; + if (ret.hasScale) { + int NScaleBits = (int) readUB(5, "NScaleBits"); + ret.scaleX = (int) readSB(NScaleBits, "scaleX"); + ret.scaleY = (int) readSB(NScaleBits, "scaleY"); + ret.nScaleBits = NScaleBits; + } + ret.hasRotate = readUB(1, "hasRotate") == 1; + if (ret.hasRotate) { + int NRotateBits = (int) readUB(5, "NRotateBits"); + ret.rotateSkew0 = (int) readSB(NRotateBits, "rotateSkew0"); + ret.rotateSkew1 = (int) readSB(NRotateBits, "rotateSkew1"); + ret.nRotateBits = NRotateBits; + } + int NTranslateBits = (int) readUB(5, "NTranslateBits"); + ret.translateX = (int) readSB(NTranslateBits, "translateX"); + ret.translateY = (int) readSB(NTranslateBits, "translateY"); + ret.nTranslateBits = NTranslateBits; + alignByte(); + endDumpLevel(); + return ret; + } + + /** + * Reads one CXFORMWITHALPHA value from the stream + * + * @param name + * @return CXFORMWITHALPHA value + * @throws IOException + */ + public CXFORMWITHALPHA readCXFORMWITHALPHA(String name) throws IOException { + CXFORMWITHALPHA ret = new CXFORMWITHALPHA(); + newDumpLevel(name, "CXFORMWITHALPHA"); + ret.hasAddTerms = readUB(1, "hasAddTerms") == 1; + ret.hasMultTerms = readUB(1, "hasMultTerms") == 1; + int Nbits = (int) readUB(4, "Nbits"); + ret.nbits = Nbits; + if (ret.hasMultTerms) { + ret.redMultTerm = (int) readSB(Nbits, "redMultTerm"); + ret.greenMultTerm = (int) readSB(Nbits, "greenMultTerm"); + ret.blueMultTerm = (int) readSB(Nbits, "blueMultTerm"); + ret.alphaMultTerm = (int) readSB(Nbits, "alphaMultTerm"); + } + if (ret.hasAddTerms) { + ret.redAddTerm = (int) readSB(Nbits, "redAddTerm"); + ret.greenAddTerm = (int) readSB(Nbits, "greenAddTerm"); + ret.blueAddTerm = (int) readSB(Nbits, "blueAddTerm"); + ret.alphaAddTerm = (int) readSB(Nbits, "alphaAddTerm"); + } + alignByte(); + endDumpLevel(); + return ret; + } + + /** + * Reads one CXFORM value from the stream + * + * @param name + * @return CXFORM value + * @throws IOException + */ + public CXFORM readCXFORM(String name) throws IOException { + CXFORM ret = new CXFORM(); + newDumpLevel(name, "CXFORM"); + ret.hasAddTerms = readUB(1, "hasAddTerms") == 1; + ret.hasMultTerms = readUB(1, "hasMultTerms") == 1; + int Nbits = (int) readUB(4, "Nbits"); + ret.nbits = Nbits; + if (ret.hasMultTerms) { + ret.redMultTerm = (int) readSB(Nbits, "redMultTerm"); + ret.greenMultTerm = (int) readSB(Nbits, "greenMultTerm"); + ret.blueMultTerm = (int) readSB(Nbits, "blueMultTerm"); + } + if (ret.hasAddTerms) { + ret.redAddTerm = (int) readSB(Nbits, "redAddTerm"); + ret.greenAddTerm = (int) readSB(Nbits, "greenAddTerm"); + ret.blueAddTerm = (int) readSB(Nbits, "blueAddTerm"); + } + alignByte(); + endDumpLevel(); + return ret; + } + + /** + * Reads one CLIPEVENTFLAGS value from the stream + * + * @param name + * @return CLIPEVENTFLAGS value + * @throws IOException + */ + public CLIPEVENTFLAGS readCLIPEVENTFLAGS(String name) throws IOException { + CLIPEVENTFLAGS ret = new CLIPEVENTFLAGS(); + newDumpLevel(name, "CLIPEVENTFLAGS"); + ret.clipEventKeyUp = readUB(1, "clipEventKeyUp") == 1; + ret.clipEventKeyDown = readUB(1, "clipEventKeyDown") == 1; + ret.clipEventMouseUp = readUB(1, "clipEventMouseUp") == 1; + ret.clipEventMouseDown = readUB(1, "clipEventMouseDown") == 1; + ret.clipEventMouseMove = readUB(1, "clipEventMouseMove") == 1; + ret.clipEventUnload = readUB(1, "clipEventUnload") == 1; + ret.clipEventEnterFrame = readUB(1, "clipEventEnterFrame") == 1; + ret.clipEventLoad = readUB(1, "clipEventLoad") == 1; + ret.clipEventDragOver = readUB(1, "clipEventDragOver") == 1; + ret.clipEventRollOut = readUB(1, "clipEventRollOut") == 1; + ret.clipEventRollOver = readUB(1, "clipEventRollOver") == 1; + ret.clipEventReleaseOutside = readUB(1, "clipEventReleaseOutside") == 1; + ret.clipEventRelease = readUB(1, "clipEventRelease") == 1; + ret.clipEventPress = readUB(1, "clipEventPress") == 1; + ret.clipEventInitialize = readUB(1, "clipEventInitialize") == 1; + ret.clipEventData = readUB(1, "clipEventData") == 1; + if (swf.version >= 6) { + ret.reserved = (int) readUB(5, "reserved"); + ret.clipEventConstruct = readUB(1, "clipEventConstruct") == 1; + ret.clipEventKeyPress = readUB(1, "clipEventKeyPress") == 1; + ret.clipEventDragOut = readUB(1, "clipEventDragOut") == 1; + ret.reserved2 = (int) readUB(8, "reserved2"); + } + endDumpLevel(); + return ret; + } + + /** + * Reads one CLIPACTIONRECORD value from the stream + * + * @param swf + * @param tag + * @param name + * @return CLIPACTIONRECORD value + * @throws IOException + */ + public CLIPACTIONRECORD readCLIPACTIONRECORD(SWF swf, Tag tag, String name) throws IOException { + newDumpLevel(name, "CLIPACTIONRECORD"); + CLIPACTIONRECORD ret = new CLIPACTIONRECORD(swf, this, tag); + endDumpLevel(); + if (ret.eventFlags.isClear()) { + return null; + } + return ret; + } + + /** + * Reads one CLIPACTIONS value from the stream + * + * @param swf + * @param tag + * @param name + * @return CLIPACTIONS value + * @throws IOException + */ + public CLIPACTIONS readCLIPACTIONS(SWF swf, Tag tag, String name) throws IOException { + CLIPACTIONS ret = new CLIPACTIONS(); + newDumpLevel(name, "CLIPACTIONS"); + ret.reserved = readUI16("reserved"); + ret.allEventFlags = readCLIPEVENTFLAGS("allEventFlags"); + CLIPACTIONRECORD cr; + ret.clipActionRecords = new ArrayList<>(); + while ((cr = readCLIPACTIONRECORD(swf, tag, "record")) != null) { + ret.clipActionRecords.add(cr); + } + endDumpLevel(); + return ret; + } + + /** + * Reads one COLORMATRIXFILTER value from the stream + * + * @param name + * @return COLORMATRIXFILTER value + * @throws IOException + */ + public COLORMATRIXFILTER readCOLORMATRIXFILTER(String name) throws IOException { + COLORMATRIXFILTER ret = new COLORMATRIXFILTER(); + newDumpLevel(name, "COLORMATRIXFILTER"); + ret.matrix = new float[20]; + for (int i = 0; i < 20; i++) { + ret.matrix[i] = readFLOAT("cell"); + } + endDumpLevel(); + return ret; + } + + /** + * Reads one RGBA value from the stream + * + * @param name + * @return RGBA value + * @throws IOException + */ + public RGBA readRGBA(String name) throws IOException { + RGBA ret = new RGBA(); + newDumpLevel(name, "RGBA"); + ret.red = readUI8("red"); + ret.green = readUI8("green"); + ret.blue = readUI8("blue"); + ret.alpha = readUI8("alpha"); + endDumpLevel(); + return ret; + } + + /** + * Reads one ARGB value from the stream + * + * @param name + * @return ARGB value + * @throws IOException + */ + public ARGB readARGB(String name) throws IOException { + ARGB ret = new ARGB(); + newDumpLevel(name, "ARGB"); + ret.alpha = readUI8("alpha"); + ret.red = readUI8("red"); + ret.green = readUI8("green"); + ret.blue = readUI8("blue"); + endDumpLevel(); + return ret; + } + + /** + * Reads one RGB value from the stream + * + * @param name + * @return RGB value + * @throws IOException + */ + public RGB readRGB(String name) throws IOException { + RGB ret = new RGB(); + newDumpLevel(name, "RGB"); + ret.red = readUI8("red"); + ret.green = readUI8("green"); + ret.blue = readUI8("blue"); + endDumpLevel(); + return ret; + } + + /** + * Reads one CONVOLUTIONFILTER value from the stream + * + * @param name + * @return CONVOLUTIONFILTER value + * @throws IOException + */ + public CONVOLUTIONFILTER readCONVOLUTIONFILTER(String name) throws IOException { + CONVOLUTIONFILTER ret = new CONVOLUTIONFILTER(); + newDumpLevel(name, "CONVOLUTIONFILTER"); + ret.matrixX = readUI8("matrixX"); + ret.matrixY = readUI8("matrixY"); + ret.divisor = readFLOAT("divisor"); + ret.bias = readFLOAT("bias"); + ret.matrix = new float[ret.matrixX][ret.matrixY]; + for (int x = 0; x < ret.matrixX; x++) { + for (int y = 0; y < ret.matrixY; y++) { + ret.matrix[x][y] = readFLOAT("cell"); + } + } + ret.defaultColor = readRGBA("defaultColor"); + ret.reserved = (int) readUB(6, "reserved"); + ret.clamp = readUB(1, "clamp") == 1; + ret.preserveAlpha = readUB(1, "preserveAlpha") == 1; + endDumpLevel(); + return ret; + } + + /** + * Reads one BLURFILTER value from the stream + * + * @param name + * @return BLURFILTER value + * @throws IOException + */ + public BLURFILTER readBLURFILTER(String name) throws IOException { + BLURFILTER ret = new BLURFILTER(); + newDumpLevel(name, "BLURFILTER"); + ret.blurX = readFIXED("blurX"); + ret.blurY = readFIXED("blurY"); + ret.passes = (int) readUB(5, "passes"); + ret.reserved = (int) readUB(3, "reserved"); + endDumpLevel(); + return ret; + } + + /** + * Reads one DROPSHADOWFILTER value from the stream + * + * @param name + * @return DROPSHADOWFILTER value + * @throws IOException + */ + public DROPSHADOWFILTER readDROPSHADOWFILTER(String name) throws IOException { + DROPSHADOWFILTER ret = new DROPSHADOWFILTER(); + newDumpLevel(name, "DROPSHADOWFILTER"); + ret.dropShadowColor = readRGBA("dropShadowColor"); + ret.blurX = readFIXED("blurX"); + ret.blurY = readFIXED("blurY"); + ret.angle = readFIXED("angle"); + ret.distance = readFIXED("distance"); + ret.strength = readFIXED8("strength"); + ret.innerShadow = readUB(1, "innerShadow") == 1; + ret.knockout = readUB(1, "knockout") == 1; + ret.compositeSource = readUB(1, "compositeSource") == 1; + ret.passes = (int) readUB(5, "passes"); + endDumpLevel(); + return ret; + } + + /** + * Reads one GLOWFILTER value from the stream + * + * @param name + * @return GLOWFILTER value + * @throws IOException + */ + public GLOWFILTER readGLOWFILTER(String name) throws IOException { + GLOWFILTER ret = new GLOWFILTER(); + newDumpLevel(name, "GLOWFILTER"); + ret.glowColor = readRGBA("glowColor"); + ret.blurX = readFIXED("blurX"); + ret.blurY = readFIXED("blurY"); + ret.strength = readFIXED8("strength"); + ret.innerGlow = readUB(1, "innerGlow") == 1; + ret.knockout = readUB(1, "knockout") == 1; + ret.compositeSource = readUB(1, "compositeSource") == 1; + ret.passes = (int) readUB(5, "passes"); + endDumpLevel(); + return ret; + } + + /** + * Reads one BEVELFILTER value from the stream + * + * @param name + * @return BEVELFILTER value + * @throws IOException + */ + public BEVELFILTER readBEVELFILTER(String name) throws IOException { + BEVELFILTER ret = new BEVELFILTER(); + newDumpLevel(name, "BEVELFILTER"); + ret.highlightColor = readRGBA("highlightColor"); // Highlight color first. It it opposite of the documentation + ret.shadowColor = readRGBA("shadowColor"); + ret.blurX = readFIXED("blurX"); + ret.blurY = readFIXED("blurY"); + ret.angle = readFIXED("angle"); + ret.distance = readFIXED("distance"); + ret.strength = readFIXED8("strength"); + ret.innerShadow = readUB(1, "innerShadow") == 1; + ret.knockout = readUB(1, "knockout") == 1; + ret.compositeSource = readUB(1, "compositeSource") == 1; + ret.onTop = readUB(1, "onTop") == 1; + ret.passes = (int) readUB(4, "passes"); + endDumpLevel(); + return ret; + } + + /** + * Reads one GRADIENTGLOWFILTER value from the stream + * + * @param name + * @return GRADIENTGLOWFILTER value + * @throws IOException + */ + public GRADIENTGLOWFILTER readGRADIENTGLOWFILTER(String name) throws IOException { + GRADIENTGLOWFILTER ret = new GRADIENTGLOWFILTER(); + newDumpLevel(name, "GRADIENTGLOWFILTER"); + int numColors = readUI8("numColors"); + ret.gradientColors = new RGBA[numColors]; + ret.gradientRatio = new int[numColors]; + for (int i = 0; i < numColors; i++) { + ret.gradientColors[i] = readRGBA("gradientColor"); + } + for (int i = 0; i < numColors; i++) { + ret.gradientRatio[i] = readUI8("gradientRatio"); + } + ret.blurX = readFIXED("blurX"); + ret.blurY = readFIXED("blurY"); + ret.angle = readFIXED("angle"); + ret.distance = readFIXED("distance"); + ret.strength = readFIXED8("strength"); + ret.innerShadow = readUB(1, "innerShadow") == 1; + ret.knockout = readUB(1, "knockout") == 1; + ret.compositeSource = readUB(1, "compositeSource") == 1; + ret.onTop = readUB(1, "onTop") == 1; + ret.passes = (int) readUB(4, "passes"); + endDumpLevel(); + return ret; + } + + /** + * Reads one GRADIENTBEVELFILTER value from the stream + * + * @param name + * @return GRADIENTBEVELFILTER value + * @throws IOException + */ + public GRADIENTBEVELFILTER readGRADIENTBEVELFILTER(String name) throws IOException { + GRADIENTBEVELFILTER ret = new GRADIENTBEVELFILTER(); + newDumpLevel(name, "GRADIENTBEVELFILTER"); + int numColors = readUI8("numColors"); + ret.gradientColors = new RGBA[numColors]; + ret.gradientRatio = new int[numColors]; + for (int i = 0; i < numColors; i++) { + ret.gradientColors[i] = readRGBA("gradientColor"); + } + for (int i = 0; i < numColors; i++) { + ret.gradientRatio[i] = readUI8("gradientRatio"); + } + ret.blurX = readFIXED("blurX"); + ret.blurY = readFIXED("blurY"); + ret.angle = readFIXED("angle"); + ret.distance = readFIXED("distance"); + ret.strength = readFIXED8("strength"); + ret.innerShadow = readUB(1, "innerShadow") == 1; + ret.knockout = readUB(1, "knockout") == 1; + ret.compositeSource = readUB(1, "compositeSource") == 1; + ret.onTop = readUB(1, "onTop") == 1; + ret.passes = (int) readUB(4, "passes"); + endDumpLevel(); + return ret; + } + + /** + * Reads list of FILTER values from the stream + * + * @param name + * @return List of FILTER values + * @throws IOException + */ + public List readFILTERLIST(String name) throws IOException { + newDumpLevel(name, "FILTERLIST"); + int numberOfFilters = readUI8("numberOfFilters"); + List ret = new ArrayList<>(numberOfFilters); + for (int i = 0; i < numberOfFilters; i++) { + ret.add(readFILTER("filter")); + } + endDumpLevel(); + return ret; + } + + /** + * Reads one FILTER value from the stream + * + * @param name + * @return FILTER value + * @throws IOException + */ + public FILTER readFILTER(String name) throws IOException { + newDumpLevel(name, "FILTER"); + int filterId = readUI8("filterId"); + FILTER ret = null; + switch (filterId) { + case 0: + ret = readDROPSHADOWFILTER("filter"); + break; + case 1: + ret = readBLURFILTER("filter"); + break; + case 2: + ret = readGLOWFILTER("filter"); + break; + case 3: + ret = readBEVELFILTER("filter"); + break; + case 4: + ret = readGRADIENTGLOWFILTER("filter"); + break; + case 5: + ret = readCONVOLUTIONFILTER("filter"); + break; + case 6: + ret = readCOLORMATRIXFILTER("filter"); + break; + case 7: + ret = readGRADIENTBEVELFILTER("filter"); + break; + } + endDumpLevel(); + return ret; + } + + /** + * Reads list of BUTTONRECORD values from the stream + * + * @param inDefineButton2 Whether read from inside of DefineButton2Tag or + * not + * @param name + * @return List of BUTTONRECORD values + * @throws IOException + */ + public List readBUTTONRECORDList(boolean inDefineButton2, String name) throws IOException { + List ret = new ArrayList<>(); + newDumpLevel(name, "BUTTONRECORDList"); + BUTTONRECORD br; + while ((br = readBUTTONRECORD(inDefineButton2, "record")) != null) { + ret.add(br); + } + endDumpLevel(); + return ret; + } + + /** + * Reads one BUTTONRECORD value from the stream + * + * @param inDefineButton2 True when in DefineButton2 + * @param name + * @return BUTTONRECORD value + * @throws IOException + */ + public BUTTONRECORD readBUTTONRECORD(boolean inDefineButton2, String name) throws IOException { + BUTTONRECORD ret = new BUTTONRECORD(); + newDumpLevel(name, "BUTTONRECORD"); + ret.reserved = (int) readUB(2, "reserved"); + ret.buttonHasBlendMode = readUB(1, "buttonHasBlendMode") == 1; + ret.buttonHasFilterList = readUB(1, "buttonHasFilterList") == 1; + ret.buttonStateHitTest = readUB(1, "buttonStateHitTest") == 1; + ret.buttonStateDown = readUB(1, "buttonStateDown") == 1; + ret.buttonStateOver = readUB(1, "buttonStateOver") == 1; + ret.buttonStateUp = readUB(1, "buttonStateUp") == 1; + + if (!ret.buttonHasBlendMode && !ret.buttonHasFilterList + && !ret.buttonStateHitTest && !ret.buttonStateDown + && !ret.buttonStateOver && !ret.buttonStateUp && ret.reserved == 0) { + endDumpLevel(); + return null; + } + + ret.characterId = readUI16("characterId"); + ret.placeDepth = readUI16("placeDepth"); + ret.placeMatrix = readMatrix("placeMatrix"); + if (inDefineButton2) { + ret.colorTransform = readCXFORMWITHALPHA("colorTransform"); + if (ret.buttonHasFilterList) { + ret.filterList = readFILTERLIST("filterList"); + } + if (ret.buttonHasBlendMode) { + ret.blendMode = readUI8("blendMode"); + } + } + endDumpLevel(); + return ret; + } + + /** + * Reads list of BUTTONCONDACTION values from the stream + * + * @param swf + * @param tag + * @param name + * @return List of BUTTONCONDACTION values + * @throws IOException + */ + public List readBUTTONCONDACTIONList(SWF swf, Tag tag, String name) throws IOException { + List ret = new ArrayList<>(); + newDumpLevel(name, "BUTTONCONDACTIONList"); + BUTTONCONDACTION bc; + while (!(bc = readBUTTONCONDACTION(swf, tag, "action")).isLast) { + ret.add(bc); + } + ret.add(bc); + endDumpLevel(); + return ret; + } + + /** + * Reads one BUTTONCONDACTION value from the stream + * + * @param swf + * @param tag + * @param name + * @return BUTTONCONDACTION value + * @throws IOException + */ + public BUTTONCONDACTION readBUTTONCONDACTION(SWF swf, Tag tag, String name) throws IOException { + newDumpLevel(name, "BUTTONCONDACTION"); + BUTTONCONDACTION ret = new BUTTONCONDACTION(swf, this, tag); + //ret.actions = readActionList(); + endDumpLevel(); + return ret; + } + + /** + * Reads one GRADRECORD value from the stream + * + * @param shapeNum 1 in DefineShape, 2 in DefineShape2... + * @param name + * @return GRADRECORD value + * @throws IOException + */ + public GRADRECORD readGRADRECORD(int shapeNum, String name) throws IOException { + GRADRECORD ret = new GRADRECORD(); + newDumpLevel(name, "GRADRECORD"); + ret.ratio = readUI8("ratio"); + if (shapeNum >= 3) { + ret.color = readRGBA("color"); + } else { + ret.color = readRGB("color"); + } + endDumpLevel(); + return ret; + } + + /** + * Reads one GRADIENT value from the stream + * + * @param shapeNum 1 in DefineShape, 2 in DefineShape2... + * @param name + * @return GRADIENT value + * @throws IOException + */ + public GRADIENT readGRADIENT(int shapeNum, String name) throws IOException { + GRADIENT ret = new GRADIENT(); + newDumpLevel(name, "GRADIENT"); + ret.spreadMode = (int) readUB(2, "spreadMode"); + ret.interpolationMode = (int) readUB(2, "interpolationMode"); + int numGradients = (int) readUB(4, "numGradients"); + ret.gradientRecords = new GRADRECORD[numGradients]; + for (int i = 0; i < numGradients; i++) { + ret.gradientRecords[i] = readGRADRECORD(shapeNum, "gradientRecord"); + + } + endDumpLevel(); + return ret; + } + + /** + * Reads one FOCALGRADIENT value from the stream + * + * @param shapeNum 1 in DefineShape, 2 in DefineShape2... + * @param name + * @return FOCALGRADIENT value + * @throws IOException + */ + public FOCALGRADIENT readFOCALGRADIENT(int shapeNum, String name) throws IOException { + FOCALGRADIENT ret = new FOCALGRADIENT(); + newDumpLevel(name, "FOCALGRADIENT"); + ret.spreadMode = (int) readUB(2, "spreadMode"); + ret.interpolationMode = (int) readUB(2, "interpolationMode"); + int numGradients = (int) readUB(4, "numGradients"); + ret.gradientRecords = new GRADRECORD[numGradients]; + for (int i = 0; i < numGradients; i++) { + ret.gradientRecords[i] = readGRADRECORD(shapeNum, "gradientRecord"); + } + ret.focalPoint = readFIXED8("focalPoint"); + endDumpLevel(); + return ret; + } + + /** + * Reads one FILLSTYLE value from the stream + * + * @param shapeNum 1 in DefineShape, 2 in DefineShape2... + * @param name + * @return FILLSTYLE value + * @throws IOException + */ + public FILLSTYLE readFILLSTYLE(int shapeNum, String name) throws IOException { + FILLSTYLE ret = new FILLSTYLE(); + newDumpLevel(name, "FILLSTYLE"); + ret.fillStyleType = readUI8("fillStyleType"); + if (ret.fillStyleType == FILLSTYLE.SOLID) { + if (shapeNum >= 3) { + ret.color = readRGBA("color"); + } else { + ret.color = readRGB("color"); + } + } + if ((ret.fillStyleType == FILLSTYLE.LINEAR_GRADIENT) + || (ret.fillStyleType == FILLSTYLE.RADIAL_GRADIENT) + || (ret.fillStyleType == FILLSTYLE.FOCAL_RADIAL_GRADIENT)) { + ret.gradientMatrix = readMatrix("gradientMatrix"); + } + if ((ret.fillStyleType == FILLSTYLE.LINEAR_GRADIENT) + || (ret.fillStyleType == FILLSTYLE.RADIAL_GRADIENT)) { + ret.gradient = readGRADIENT(shapeNum, "gradient"); + } + if (ret.fillStyleType == FILLSTYLE.FOCAL_RADIAL_GRADIENT) { + ret.gradient = readFOCALGRADIENT(shapeNum, "gradient"); + } + + if ((ret.fillStyleType == FILLSTYLE.REPEATING_BITMAP) + || (ret.fillStyleType == FILLSTYLE.CLIPPED_BITMAP) + || (ret.fillStyleType == FILLSTYLE.NON_SMOOTHED_REPEATING_BITMAP) + || (ret.fillStyleType == FILLSTYLE.NON_SMOOTHED_CLIPPED_BITMAP)) { + ret.bitmapId = readUI16("bitmapId"); + ret.bitmapMatrix = readMatrix("bitmapMatrix"); + } + endDumpLevel(); + return ret; + } + + /** + * Reads one FILLSTYLEARRAY value from the stream + * + * @param shapeNum 1 in DefineShape, 2 in DefineShape2... + * @param name + * @return FILLSTYLEARRAY value + * @throws IOException + */ + public FILLSTYLEARRAY readFILLSTYLEARRAY(int shapeNum, String name) throws IOException { + + FILLSTYLEARRAY ret = new FILLSTYLEARRAY(); + newDumpLevel(name, "FILLSTYLEARRAY"); + int fillStyleCount = readUI8("fillStyleCount"); + if (((shapeNum == 2) || (shapeNum == 3) || (shapeNum == 4/*?*/)) && (fillStyleCount == 0xff)) { + fillStyleCount = readUI16("fillStyleCount"); + } + ret.fillStyles = new FILLSTYLE[fillStyleCount]; + for (int i = 0; i < fillStyleCount; i++) { + ret.fillStyles[i] = readFILLSTYLE(shapeNum, "fillStyle"); + } + endDumpLevel(); + return ret; + } + + /** + * Reads one LINESTYLE value from the stream + * + * @param shapeNum 1 in DefineShape, 2 in DefineShape2... + * @param name + * @return LINESTYLE value + * @throws IOException + */ + public LINESTYLE readLINESTYLE(int shapeNum, String name) throws IOException { + LINESTYLE ret = new LINESTYLE(); + newDumpLevel(name, "LINESTYLE"); + ret.width = readUI16("width"); + if ((shapeNum == 1) || (shapeNum == 2)) { + ret.color = readRGB("color"); + } + if (shapeNum == 3) { + ret.color = readRGBA("color"); + } + endDumpLevel(); + return ret; + } + + /** + * Reads one LINESTYLE2 value from the stream + * + * @param shapeNum 1 in DefineShape, 2 in DefineShape2... + * @param name + * @return LINESTYLE2 value + * @throws IOException + */ + public LINESTYLE2 readLINESTYLE2(int shapeNum, String name) throws IOException { + LINESTYLE2 ret = new LINESTYLE2(); + newDumpLevel(name, "LINESTYLE2"); + ret.width = readUI16("width"); + ret.startCapStyle = (int) readUB(2, "startCapStyle"); + ret.joinStyle = (int) readUB(2, "joinStyle"); + ret.hasFillFlag = (int) readUB(1, "hasFillFlag") == 1; + ret.noHScaleFlag = (int) readUB(1, "noHScaleFlag") == 1; + ret.noVScaleFlag = (int) readUB(1, "noVScaleFlag") == 1; + ret.pixelHintingFlag = (int) readUB(1, "pixelHintingFlag") == 1; + ret.reserved = (int) readUB(5, "reserved"); + ret.noClose = (int) readUB(1, "noClose") == 1; + ret.endCapStyle = (int) readUB(2, "endCapStyle"); + if (ret.joinStyle == LINESTYLE2.MITER_JOIN) { + ret.miterLimitFactor = readUI16("miterLimitFactor"); + } + if (!ret.hasFillFlag) { + ret.color = readRGBA("color"); + } else { + ret.fillType = readFILLSTYLE(shapeNum, "fillType"); + } + endDumpLevel(); + return ret; + } + + /** + * Reads one LINESTYLEARRAY value from the stream + * + * @param shapeNum 1 in DefineShape, 2 in DefineShape2... + * @param name + * @return LINESTYLEARRAY value + * @throws IOException + */ + public LINESTYLEARRAY readLINESTYLEARRAY(int shapeNum, String name) throws IOException { + LINESTYLEARRAY ret = new LINESTYLEARRAY(); + newDumpLevel(name, "LINESTYLEARRAY"); + int lineStyleCount = readUI8("lineStyleCount"); + if (lineStyleCount == 0xff) { + lineStyleCount = readUI16("lineStyleCount"); + } + if ((shapeNum == 1 || shapeNum == 2 || shapeNum == 3)) { + ret.lineStyles = new LINESTYLE[lineStyleCount]; + for (int i = 0; i < lineStyleCount; i++) { + ret.lineStyles[i] = readLINESTYLE(shapeNum, "lineStyle"); + } + } else if (shapeNum == 4) { + ret.lineStyles = new LINESTYLE2[lineStyleCount]; + for (int i = 0; i < lineStyleCount; i++) { + ret.lineStyles[i] = readLINESTYLE2(shapeNum, "lineStyle"); + } + } + endDumpLevel(); + return ret; + } + + /** + * Reads one SHAPERECORD value from the stream + * + * @param fillBits + * @param lineBits + * @param shapeNum 1 in DefineShape, 2 in DefineShape2... + * @return SHAPERECORD value + * @throws IOException + */ + private SHAPERECORD readSHAPERECORD(int fillBits, int lineBits, int shapeNum, boolean morphShape, String name) throws IOException { + SHAPERECORD ret; + newDumpLevel(name, "SHAPERECORD"); + int typeFlag = (int) readUB(1, "typeFlag"); + if (typeFlag == 0) { + boolean stateNewStyles = readUB(1, "stateNewStyles") == 1; + boolean stateLineStyle = readUB(1, "stateLineStyle") == 1; + boolean stateFillStyle1 = readUB(1, "stateFillStyle1") == 1; + boolean stateFillStyle0 = readUB(1, "stateFillStyle0") == 1; + boolean stateMoveTo = readUB(1, "stateMoveTo") == 1; + if ((!stateNewStyles) && (!stateLineStyle) && (!stateFillStyle1) && (!stateFillStyle0) && (!stateMoveTo)) { + ret = new EndShapeRecord(); + } else { + StyleChangeRecord scr = new StyleChangeRecord(); + scr.stateNewStyles = stateNewStyles; + scr.stateLineStyle = stateLineStyle; + scr.stateFillStyle0 = stateFillStyle0; + scr.stateFillStyle1 = stateFillStyle1; + scr.stateMoveTo = stateMoveTo; + if (stateMoveTo) { + scr.moveBits = (int) readUB(5, "moveBits"); + scr.moveDeltaX = (int) readSB(scr.moveBits, "moveDeltaX"); + scr.moveDeltaY = (int) readSB(scr.moveBits, "moveDeltaY"); + } + if (stateFillStyle0) { + scr.fillStyle0 = (int) readUB(fillBits, "fillStyle0"); + } + if (stateFillStyle1) { + scr.fillStyle1 = (int) readUB(fillBits, "fillStyle1"); + } + if (stateLineStyle) { + scr.lineStyle = (int) readUB(lineBits, "lineStyle"); + } + if (stateNewStyles) { + if (morphShape) { + // This should never happen in a valid SWF + throw new IOException("MorphShape should not have new styles."); + } else { + scr.fillStyles = readFILLSTYLEARRAY(shapeNum, "fillStyles"); + scr.lineStyles = readLINESTYLEARRAY(shapeNum, "lineStyles"); + } + scr.numFillBits = (int) readUB(4, "numFillBits"); + scr.numLineBits = (int) readUB(4, "numLineBits"); + } + ret = scr; + } + } else { // typeFlag==1 + int straightFlag = (int) readUB(1, "straightFlag"); + if (straightFlag == 1) { + StraightEdgeRecord ser = new StraightEdgeRecord(); + ser.numBits = (int) readUB(4, "numBits"); + ser.generalLineFlag = readUB(1, "generalLineFlag") == 1; + if (!ser.generalLineFlag) { + ser.vertLineFlag = readUB(1, "vertLineFlag") == 1; + } + if (ser.generalLineFlag || (!ser.vertLineFlag)) { + ser.deltaX = (int) readSB(ser.numBits + 2, "deltaX"); + } + if (ser.generalLineFlag || (ser.vertLineFlag)) { + ser.deltaY = (int) readSB(ser.numBits + 2, "deltaY"); + } + ret = ser; + } else { + CurvedEdgeRecord cer = new CurvedEdgeRecord(); + cer.numBits = (int) readUB(4, "numBits"); + cer.controlDeltaX = (int) readSB(cer.numBits + 2, "controlDeltaX"); + cer.controlDeltaY = (int) readSB(cer.numBits + 2, "controlDeltaY"); + cer.anchorDeltaX = (int) readSB(cer.numBits + 2, "anchorDeltaX"); + cer.anchorDeltaY = (int) readSB(cer.numBits + 2, "anchorDeltaY"); + ret = cer; + } + } + endDumpLevel(); + return ret; + } + + /** + * Reads one SHAPE value from the stream + * + * @param shapeNum 1 in DefineShape, 2 in DefineShape2... + * @param morphShape + * @param name + * @return SHAPE value + * @throws IOException + */ + public SHAPE readSHAPE(int shapeNum, boolean morphShape, String name) throws IOException { + SHAPE ret = new SHAPE(); + newDumpLevel(name, "SHAPE"); + ret.numFillBits = (int) readUB(4, "numFillBits"); + ret.numLineBits = (int) readUB(4, "numLineBits"); + ret.shapeRecords = readSHAPERECORDS(shapeNum, ret.numFillBits, ret.numLineBits, morphShape, "shapeRecords"); + endDumpLevel(); + return ret; + } + + /** + * Reads one SHAPEWITHSTYLE value from the stream + * + * @param shapeNum 1 in DefineShape, 2 in DefineShape2... + * @param morphShape + * @param name + * @return SHAPEWITHSTYLE value + * @throws IOException + */ + public SHAPEWITHSTYLE readSHAPEWITHSTYLE(int shapeNum, boolean morphShape, String name) throws IOException { + SHAPEWITHSTYLE ret = new SHAPEWITHSTYLE(); + newDumpLevel(name, "SHAPEWITHSTYLE"); + ret.fillStyles = readFILLSTYLEARRAY(shapeNum, "fillStyles"); + ret.lineStyles = readLINESTYLEARRAY(shapeNum, "lineStyles"); + ret.numFillBits = (int) readUB(4, "numFillBits"); + ret.numLineBits = (int) readUB(4, "numLineBits"); + ret.shapeRecords = readSHAPERECORDS(shapeNum, ret.numFillBits, ret.numLineBits, morphShape, "shapeRecords"); + endDumpLevel(); + return ret; + } + + /** + * Reads list of SHAPERECORDs from the stream + * + * @param shapeNum 1 in DefineShape, 2 in DefineShape2... + * @param fillBits + * @param lineBits + * @return SHAPERECORDs array + * @throws IOException + */ + private List readSHAPERECORDS(int shapeNum, int fillBits, int lineBits, boolean morphShape, String name) throws IOException { + List ret = new ArrayList<>(); + newDumpLevel(name, "SHAPERECORDS"); + SHAPERECORD rec; + do { + rec = readSHAPERECORD(fillBits, lineBits, shapeNum, morphShape, "record"); + if (rec instanceof StyleChangeRecord) { + StyleChangeRecord scRec = (StyleChangeRecord) rec; + if (scRec.stateNewStyles) { + fillBits = scRec.numFillBits; + lineBits = scRec.numLineBits; + } + } + ret.add(rec); + } while (!(rec instanceof EndShapeRecord)); + alignByte(); + endDumpLevel(); + return ret; + } + + /** + * Reads one SOUNDINFO value from the stream + * + * @param name + * @return SOUNDINFO value + * @throws IOException + */ + public SOUNDINFO readSOUNDINFO(String name) throws IOException { + SOUNDINFO ret = new SOUNDINFO(); + newDumpLevel(name, "SOUNDINFO"); + ret.reserved = (int) readUB(2, "reserved"); + ret.syncStop = readUB(1, "syncStop") == 1; + ret.syncNoMultiple = readUB(1, "syncNoMultiple") == 1; + ret.hasEnvelope = readUB(1, "hasEnvelope") == 1; + ret.hasLoops = readUB(1, "hasLoops") == 1; + ret.hasOutPoint = readUB(1, "hasOutPoint") == 1; + ret.hasInPoint = readUB(1, "hasInPoint") == 1; + if (ret.hasInPoint) { + ret.inPoint = readUI32("inPoint"); + } + if (ret.hasOutPoint) { + ret.outPoint = readUI32("outPoint"); + } + if (ret.hasLoops) { + ret.loopCount = readUI16("loopCount"); + } + if (ret.hasEnvelope) { + int envPoints = readUI8("envPoints"); + ret.envelopeRecords = new SOUNDENVELOPE[envPoints]; + for (int i = 0; i < envPoints; i++) { + ret.envelopeRecords[i] = readSOUNDENVELOPE("envelopeRecord"); + } + } + endDumpLevel(); + return ret; + } + + /** + * Reads one SOUNDENVELOPE value from the stream + * + * @param name + * @return SOUNDENVELOPE value + * @throws IOException + */ + public SOUNDENVELOPE readSOUNDENVELOPE(String name) throws IOException { + SOUNDENVELOPE ret = new SOUNDENVELOPE(); + newDumpLevel(name, "SOUNDENVELOPE"); + ret.pos44 = readUI32("pos44"); + ret.leftLevel = readUI16("leftLevel"); + ret.rightLevel = readUI16("rightLevel"); + endDumpLevel(); + return ret; + } + + /** + * Reads one GLYPHENTRY value from the stream + * + * @param glyphBits + * @param advanceBits + * @param name + * @return GLYPHENTRY value + * @throws IOException + */ + public GLYPHENTRY readGLYPHENTRY(int glyphBits, int advanceBits, String name) throws IOException { + GLYPHENTRY ret = new GLYPHENTRY(); + newDumpLevel(name, "GLYPHENTRY"); + ret.glyphIndex = (int) readUB(glyphBits, "glyphIndex"); + ret.glyphAdvance = (int) readUB(advanceBits, "glyphAdvance"); + endDumpLevel(); + return ret; + } + + /** + * Reads one TEXTRECORD value from the stream + * + * @param inDefineText2 + * @param glyphBits + * @param advanceBits + * @param name + * @return TEXTRECORD value + * @throws IOException + */ + public TEXTRECORD readTEXTRECORD(boolean inDefineText2, int glyphBits, int advanceBits, String name) throws IOException { + TEXTRECORD ret = new TEXTRECORD(); + newDumpLevel(name, "TEXTRECORD"); + int first = (int) readUB(1, "first"); // always 1 + readUB(3, "styleFlagsHasReserved"); // always 0 + ret.styleFlagsHasFont = readUB(1, "styleFlagsHasFont") == 1; + ret.styleFlagsHasColor = readUB(1, "styleFlagsHasColor") == 1; + ret.styleFlagsHasYOffset = readUB(1, "styleFlagsHasYOffset") == 1; + ret.styleFlagsHasXOffset = readUB(1, "styleFlagsHasXOffset") == 1; + if ((!ret.styleFlagsHasFont) && (!ret.styleFlagsHasColor) && (!ret.styleFlagsHasYOffset) && (!ret.styleFlagsHasXOffset) && (first == 0)) { // final text record + endDumpLevel(); + return null; + } + if (ret.styleFlagsHasFont) { + ret.fontId = readUI16("fontId"); + } + if (ret.styleFlagsHasColor) { + if (inDefineText2) { + ret.textColorA = readRGBA("textColorA"); + } else { + ret.textColor = readRGB("textColor"); + } + } + if (ret.styleFlagsHasXOffset) { + ret.xOffset = readSI16("xOffset"); + } + if (ret.styleFlagsHasYOffset) { + ret.yOffset = readSI16("yOffset"); + } + if (ret.styleFlagsHasFont) { + ret.textHeight = readUI16("textHeight"); + } + int glyphCount = readUI8("glyphCount"); + ret.glyphEntries = new ArrayList<>(glyphCount); + for (int i = 0; i < glyphCount; i++) { + ret.glyphEntries.add(readGLYPHENTRY(glyphBits, advanceBits, "glyphEntry")); + } + alignByte(); + endDumpLevel(); + return ret; + } + + /** + * Reads one MORPHGRADRECORD value from the stream + * + * @param name + * @return MORPHGRADRECORD value + * @throws IOException + */ + public MORPHGRADRECORD readMORPHGRADRECORD(String name) throws IOException { + MORPHGRADRECORD ret = new MORPHGRADRECORD(); + newDumpLevel(name, "MORPHGRADRECORD"); + ret.startRatio = readUI8("startRatio"); + ret.startColor = readRGBA("startColor"); + ret.endRatio = readUI8("endRatio"); + ret.endColor = readRGBA("endColor"); + endDumpLevel(); + return ret; + } + + /** + * Reads one MORPHGRADIENT value from the stream + * + * @param name + * @return MORPHGRADIENT value + * @throws IOException + */ + public MORPHGRADIENT readMORPHGRADIENT(String name) throws IOException { + MORPHGRADIENT ret = new MORPHGRADIENT(); + newDumpLevel(name, "MORPHGRADIENT"); + // Despite of documentation (UI8 1-8), there are two fields + // spreadMode and interPolationMode which are same as in GRADIENT + ret.spreadMode = (int) readUB(2, "spreadMode"); + ret.interPolationMode = (int) readUB(2, "interPolationMode"); + int numGradients = (int) readUB(4, "numGradients"); + ret.gradientRecords = new MORPHGRADRECORD[numGradients]; + for (int i = 0; i < numGradients; i++) { + ret.gradientRecords[i] = readMORPHGRADRECORD("gradientRecord"); + } + endDumpLevel(); + return ret; + } + + /** + * Reads one MORPHFOCALGRADIENT value from the stream + * + * This is undocumented feature + * + * @param name + * @return MORPHGRADIENT value + * @throws IOException + */ + public MORPHFOCALGRADIENT readMORPHFOCALGRADIENT(String name) throws IOException { + MORPHFOCALGRADIENT ret = new MORPHFOCALGRADIENT(); + newDumpLevel(name, "MORPHFOCALGRADIENT"); + ret.spreadMode = (int) readUB(2, "spreadMode"); + ret.interPolationMode = (int) readUB(2, "interPolationMode"); + int numGradients = (int) readUB(4, "numGradients"); + ret.gradientRecords = new MORPHGRADRECORD[numGradients]; + for (int i = 0; i < numGradients; i++) { + ret.gradientRecords[i] = readMORPHGRADRECORD("gradientRecord"); + } + ret.startFocalPoint = readFIXED8("startFocalPoint"); + ret.endFocalPoint = readFIXED8("endFocalPoint"); + endDumpLevel(); + return ret; + } + + /** + * Reads one MORPHFILLSTYLE value from the stream + * + * @param name + * @return MORPHFILLSTYLE value + * @throws IOException + */ + public MORPHFILLSTYLE readMORPHFILLSTYLE(String name) throws IOException { + MORPHFILLSTYLE ret = new MORPHFILLSTYLE(); + newDumpLevel(name, "MORPHFILLSTYLE"); + ret.fillStyleType = readUI8("fillStyleType"); + if (ret.fillStyleType == MORPHFILLSTYLE.SOLID) { + ret.startColor = readRGBA("startColor"); + ret.endColor = readRGBA("endColor"); + } + if ((ret.fillStyleType == MORPHFILLSTYLE.LINEAR_GRADIENT) + || (ret.fillStyleType == MORPHFILLSTYLE.RADIAL_GRADIENT) + || (ret.fillStyleType == MORPHFILLSTYLE.FOCAL_RADIAL_GRADIENT)) { + ret.startGradientMatrix = readMatrix("startGradientMatrix"); + ret.endGradientMatrix = readMatrix("endGradientMatrix"); + } + if ((ret.fillStyleType == MORPHFILLSTYLE.LINEAR_GRADIENT) + || (ret.fillStyleType == MORPHFILLSTYLE.RADIAL_GRADIENT)) { + ret.gradient = readMORPHGRADIENT("gradient"); + } + if (ret.fillStyleType == MORPHFILLSTYLE.FOCAL_RADIAL_GRADIENT) { + ret.gradient = readMORPHFOCALGRADIENT("gradient"); + } + + if ((ret.fillStyleType == MORPHFILLSTYLE.REPEATING_BITMAP) + || (ret.fillStyleType == MORPHFILLSTYLE.CLIPPED_BITMAP) + || (ret.fillStyleType == MORPHFILLSTYLE.NON_SMOOTHED_REPEATING_BITMAP) + || (ret.fillStyleType == MORPHFILLSTYLE.NON_SMOOTHED_CLIPPED_BITMAP)) { + ret.bitmapId = readUI16("bitmapId"); + ret.startBitmapMatrix = readMatrix("startBitmapMatrix"); + ret.endBitmapMatrix = readMatrix("endBitmapMatrix"); + } + endDumpLevel(); + return ret; + } + + /** + * Reads one MORPHFILLSTYLEARRAY value from the stream + * + * @param name + * @return MORPHFILLSTYLEARRAY value + * @throws IOException + */ + public MORPHFILLSTYLEARRAY readMORPHFILLSTYLEARRAY(String name) throws IOException { + + MORPHFILLSTYLEARRAY ret = new MORPHFILLSTYLEARRAY(); + newDumpLevel(name, "MORPHFILLSTYLEARRAY"); + int fillStyleCount = readUI8("fillStyleCount"); + if (fillStyleCount == 0xff) { + fillStyleCount = readUI16("fillStyleCount"); + } + ret.fillStyles = new MORPHFILLSTYLE[fillStyleCount]; + for (int i = 0; i < fillStyleCount; i++) { + ret.fillStyles[i] = readMORPHFILLSTYLE("fillStyle"); + } + endDumpLevel(); + return ret; + } + + /** + * Reads one MORPHLINESTYLE value from the stream + * + * @param name + * @return MORPHLINESTYLE value + * @throws IOException + */ + public MORPHLINESTYLE readMORPHLINESTYLE(String name) throws IOException { + MORPHLINESTYLE ret = new MORPHLINESTYLE(); + newDumpLevel(name, "MORPHLINESTYLE"); + ret.startWidth = readUI16("startWidth"); + ret.endWidth = readUI16("endWidth"); + ret.startColor = readRGBA("startColor"); + ret.endColor = readRGBA("endColor"); + endDumpLevel(); + return ret; + } + + /** + * Reads one MORPHLINESTYLE2 value from the stream + * + * @param name + * @return MORPHLINESTYLE2 value + * @throws IOException + */ + public MORPHLINESTYLE2 readMORPHLINESTYLE2(String name) throws IOException { + MORPHLINESTYLE2 ret = new MORPHLINESTYLE2(); + newDumpLevel(name, "MORPHLINESTYLE2"); + ret.startWidth = readUI16("startWidth"); + ret.endWidth = readUI16("endWidth"); + ret.startCapStyle = (int) readUB(2, "startCapStyle"); + ret.joinStyle = (int) readUB(2, "joinStyle"); + ret.hasFillFlag = (int) readUB(1, "hasFillFlag") == 1; + ret.noHScaleFlag = (int) readUB(1, "noHScaleFlag") == 1; + ret.noVScaleFlag = (int) readUB(1, "noVScaleFlag") == 1; + ret.pixelHintingFlag = (int) readUB(1, "pixelHintingFlag") == 1; + ret.reserved = (int) readUB(5, "reserved"); + ret.noClose = (int) readUB(1, "noClose") == 1; + ret.endCapStyle = (int) readUB(2, "endCapStyle"); + if (ret.joinStyle == LINESTYLE2.MITER_JOIN) { + ret.miterLimitFactor = readUI16("miterLimitFactor"); + } + if (!ret.hasFillFlag) { + ret.startColor = readRGBA("startColor"); + ret.endColor = readRGBA("endColor"); + } else { + ret.fillType = readMORPHFILLSTYLE("fillType"); + } + endDumpLevel(); + return ret; + } + + /** + * Reads one MORPHLINESTYLEARRAY value from the stream + * + * @param morphShapeNum 1 on DefineMorphShape, 2 on DefineMorphShape2 + * @param name + * @return MORPHLINESTYLEARRAY value + * @throws IOException + */ + public MORPHLINESTYLEARRAY readMORPHLINESTYLEARRAY(int morphShapeNum, String name) throws IOException { + MORPHLINESTYLEARRAY ret = new MORPHLINESTYLEARRAY(); + newDumpLevel(name, "MORPHLINESTYLEARRAY"); + int lineStyleCount = readUI8("lineStyleCount"); + if (lineStyleCount == 0xff) { + lineStyleCount = readUI16("lineStyleCount"); + } + if (morphShapeNum == 1) { + ret.lineStyles = new MORPHLINESTYLE[lineStyleCount]; + for (int i = 0; i < lineStyleCount; i++) { + ret.lineStyles[i] = readMORPHLINESTYLE("lineStyle"); + } + } else if (morphShapeNum == 2) { + ret.lineStyles2 = new MORPHLINESTYLE2[lineStyleCount]; + for (int i = 0; i < lineStyleCount; i++) { + ret.lineStyles2[i] = readMORPHLINESTYLE2("lineStyle2"); + } + } + endDumpLevel(); + return ret; + } + + /** + * Reads one KERNINGRECORD value from the stream + * + * @param fontFlagsWideCodes + * @param name + * @return KERNINGRECORD value + * @throws IOException + */ + public KERNINGRECORD readKERNINGRECORD(boolean fontFlagsWideCodes, String name) throws IOException { + KERNINGRECORD ret = new KERNINGRECORD(); + newDumpLevel(name, "KERNINGRECORD"); + if (fontFlagsWideCodes) { + ret.fontKerningCode1 = readUI16("fontKerningCode1"); + ret.fontKerningCode2 = readUI16("fontKerningCode2"); + } else { + ret.fontKerningCode1 = readUI8("fontKerningCode1"); + ret.fontKerningCode2 = readUI8("fontKerningCode2"); + } + ret.fontKerningAdjustment = readSI16("fontKerningAdjustment"); + endDumpLevel(); + return ret; + } + + /** + * Reads one LANGCODE value from the stream + * + * @param name + * @return LANGCODE value + * @throws IOException + */ + public LANGCODE readLANGCODE(String name) throws IOException { + LANGCODE ret = new LANGCODE(); + newDumpLevel(name, "LANGCODE"); + ret.languageCode = readUI8("languageCode"); + endDumpLevel(); + return ret; + } + + /** + * Reads one ZONERECORD value from the stream + * + * @param name + * @return ZONERECORD value + * @throws IOException + */ + public ZONERECORD readZONERECORD(String name) throws IOException { + ZONERECORD ret = new ZONERECORD(); + newDumpLevel(name, "ZONERECORD"); + int numZoneData = readUI8("numZoneData"); + ret.zonedata = new ZONEDATA[numZoneData]; + for (int i = 0; i < numZoneData; i++) { + ret.zonedata[i] = readZONEDATA("zonedata"); + } + readUB(6, "reserved"); + ret.zoneMaskY = readUB(1, "zoneMaskY") == 1; + ret.zoneMaskX = readUB(1, "zoneMaskX") == 1; + endDumpLevel(); + return ret; + } + + /** + * Reads one ZONEDATA value from the stream + * + * @param name + * @return ZONEDATA value + * @throws IOException + */ + public ZONEDATA readZONEDATA(String name) throws IOException { + ZONEDATA ret = new ZONEDATA(); + newDumpLevel(name, "ZONEDATA"); + ret.alignmentCoordinate = readUI16("alignmentCoordinate"); + ret.range = readUI16("range"); + endDumpLevel(); + return ret; + } + + /** + * Reads one PIX15 value from the stream + * + * @param name + * @return PIX15 value + * @throws IOException + */ + public PIX15 readPIX15(String name) throws IOException { + PIX15 ret = new PIX15(); + newDumpLevel(name, "PIX15"); + readUB(1, "reserved"); + ret.red = (int) readUB(5, "red"); + ret.green = (int) readUB(5, "green"); + ret.blue = (int) readUB(5, "blue"); + endDumpLevel(); + return ret; + } + + /** + * Reads one PIX24 value from the stream + * + * @param name + * @return PIX24 value + * @throws IOException + */ + public PIX24 readPIX24(String name) throws IOException { + PIX24 ret = new PIX24(); + newDumpLevel(name, "PIX24"); + ret.reserved = readUI8("reserved"); + ret.red = readUI8("red"); + ret.green = readUI8("green"); + ret.blue = readUI8("blue"); + endDumpLevel(); + return ret; + } + + /** + * Reads one COLORMAPDATA value from the stream + * + * @param colorTableSize + * @param bitmapWidth + * @param bitmapHeight + * @param name + * @return COLORMAPDATA value + * @throws IOException + */ + public COLORMAPDATA readCOLORMAPDATA(int colorTableSize, int bitmapWidth, int bitmapHeight, String name) throws IOException { + COLORMAPDATA ret = new COLORMAPDATA(); + newDumpLevel(name, "COLORMAPDATA"); + ret.colorTableRGB = new RGB[colorTableSize + 1]; + for (int i = 0; i < colorTableSize + 1; i++) { + ret.colorTableRGB[i] = readRGB("colorTableRGB"); + } + int dataLen = 0; + for (int y = 0; y < bitmapHeight; y++) { + int x = 0; + for (; x < bitmapWidth; x++) { + dataLen++; + } + while ((x % 4) != 0) { + dataLen++; + x++; + } + } + ret.colorMapPixelData = readBytesEx(dataLen, "colorMapPixelData"); + endDumpLevel(); + return ret; + } + + /** + * Reads one BITMAPDATA value from the stream + * + * @param bitmapFormat + * @param bitmapWidth + * @param bitmapHeight + * @param name + * @return COLORMAPDATA value + * @throws IOException + */ + public BITMAPDATA readBITMAPDATA(int bitmapFormat, int bitmapWidth, int bitmapHeight, String name) throws IOException { + BITMAPDATA ret = new BITMAPDATA(); + newDumpLevel(name, "BITMAPDATA"); + int pixelCount = bitmapWidth * bitmapHeight; + PIX15[] pix15 = bitmapFormat == DefineBitsLosslessTag.FORMAT_15BIT_RGB ? new PIX15[pixelCount] : null; + PIX24[] pix24 = bitmapFormat == DefineBitsLosslessTag.FORMAT_24BIT_RGB ? new PIX24[pixelCount] : null; + int dataLen = 0; + int pos = 0; + for (int y = 0; y < bitmapHeight; y++) { + for (int x = 0; x < bitmapWidth; x++) { + if (bitmapFormat == DefineBitsLosslessTag.FORMAT_15BIT_RGB) { + dataLen += 2; + pix15[pos++] = readPIX15("pix15"); + } + if (bitmapFormat == DefineBitsLosslessTag.FORMAT_24BIT_RGB) { + dataLen += 4; + pix24[pos++] = readPIX24("pix24"); + } + } + while ((dataLen % 4) != 0) { + dataLen++; + readUI8("padding"); + } + } + if (bitmapFormat == DefineBitsLosslessTag.FORMAT_15BIT_RGB) { + ret.bitmapPixelDataPix15 = pix15; + } else if (bitmapFormat == DefineBitsLosslessTag.FORMAT_24BIT_RGB) { + ret.bitmapPixelDataPix24 = pix24; + } + endDumpLevel(); + return ret; + } + + /** + * Reads one BITMAPDATA value from the stream + * + * @param bitmapFormat + * @param bitmapWidth + * @param bitmapHeight + * @param name + * @return COLORMAPDATA value + * @throws IOException + */ + public ALPHABITMAPDATA readALPHABITMAPDATA(int bitmapFormat, int bitmapWidth, int bitmapHeight, String name) throws IOException { + ALPHABITMAPDATA ret = new ALPHABITMAPDATA(); + newDumpLevel(name, "ALPHABITMAPDATA"); + ret.bitmapPixelData = new ARGB[bitmapWidth * bitmapHeight]; + for (int y = 0; y < bitmapHeight; y++) { + for (int x = 0; x < bitmapWidth; x++) { + ret.bitmapPixelData[y * bitmapWidth + x] = readARGB("bitmapPixelData"); + } + } + endDumpLevel(); + return ret; + } + + /** + * Reads one ALPHACOLORMAPDATA value from the stream + * + * @param colorTableSize + * @param bitmapWidth + * @param bitmapHeight + * @param name + * @return ALPHACOLORMAPDATA value + * @throws IOException + */ + public ALPHACOLORMAPDATA readALPHACOLORMAPDATA(int colorTableSize, int bitmapWidth, int bitmapHeight, String name) throws IOException { + ALPHACOLORMAPDATA ret = new ALPHACOLORMAPDATA(); + newDumpLevel(name, "ALPHACOLORMAPDATA"); + ret.colorTableRGB = new RGBA[colorTableSize + 1]; + for (int i = 0; i < colorTableSize + 1; i++) { + ret.colorTableRGB[i] = readRGBA("colorTableRGB"); + } + int dataLen = 0; + for (int y = 0; y < bitmapHeight; y++) { + int x = 0; + for (; x < bitmapWidth; x++) { + dataLen++; + } + while ((x % 4) != 0) { + dataLen++; + x++; + } + } + ret.colorMapPixelData = readBytesEx(dataLen, ""); + endDumpLevel(); + return ret; + } + + public int available() throws IOException { + return is.available(); + } + + public long availableBits() throws IOException { + if (bitPos > 0) { + return available() * 8 + (8 - bitPos); + } + return available() * 8; + } + + public MemoryInputStream getBaseStream() throws IOException { + int pos = (int) is.getPos(); + MemoryInputStream mis = new MemoryInputStream(is.getAllRead(), 0, pos + is.available()); + mis.seek(pos); + return mis; + } + + public SWFInputStream getLimitedStream(int limit) throws IOException { + SWFInputStream sis = new SWFInputStream(swf, is.getAllRead(), startingPos, (int) (is.getPos() + limit)); + + // uncomment the following line to turn off lazy dump info collecting + //sis.dumpInfo = dumpInfo; + sis.seek(is.getPos() + startingPos); + return sis; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWFOutputStream.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWFOutputStream.java index eb82cc566..6f54ed2f3 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWFOutputStream.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWFOutputStream.java @@ -1,1849 +1,1849 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash; - -import com.jpexs.decompiler.flash.configuration.Configuration; -import com.jpexs.decompiler.flash.tags.DefineBitsLosslessTag; -import com.jpexs.decompiler.flash.tags.Tag; -import com.jpexs.decompiler.flash.types.ALPHABITMAPDATA; -import com.jpexs.decompiler.flash.types.ARGB; -import com.jpexs.decompiler.flash.types.BITMAPDATA; -import com.jpexs.decompiler.flash.types.BUTTONCONDACTION; -import com.jpexs.decompiler.flash.types.BUTTONRECORD; -import com.jpexs.decompiler.flash.types.CLIPACTIONRECORD; -import com.jpexs.decompiler.flash.types.CLIPACTIONS; -import com.jpexs.decompiler.flash.types.CLIPEVENTFLAGS; -import com.jpexs.decompiler.flash.types.CXFORM; -import com.jpexs.decompiler.flash.types.CXFORMWITHALPHA; -import com.jpexs.decompiler.flash.types.FILLSTYLE; -import com.jpexs.decompiler.flash.types.FILLSTYLEARRAY; -import com.jpexs.decompiler.flash.types.FOCALGRADIENT; -import com.jpexs.decompiler.flash.types.GLYPHENTRY; -import com.jpexs.decompiler.flash.types.GRADIENT; -import com.jpexs.decompiler.flash.types.GRADRECORD; -import com.jpexs.decompiler.flash.types.KERNINGRECORD; -import com.jpexs.decompiler.flash.types.LANGCODE; -import com.jpexs.decompiler.flash.types.LINESTYLE; -import com.jpexs.decompiler.flash.types.LINESTYLE2; -import com.jpexs.decompiler.flash.types.LINESTYLEARRAY; -import com.jpexs.decompiler.flash.types.MATRIX; -import com.jpexs.decompiler.flash.types.MORPHFILLSTYLE; -import com.jpexs.decompiler.flash.types.MORPHFILLSTYLEARRAY; -import com.jpexs.decompiler.flash.types.MORPHFOCALGRADIENT; -import com.jpexs.decompiler.flash.types.MORPHGRADIENT; -import com.jpexs.decompiler.flash.types.MORPHGRADRECORD; -import com.jpexs.decompiler.flash.types.MORPHLINESTYLE; -import com.jpexs.decompiler.flash.types.MORPHLINESTYLE2; -import com.jpexs.decompiler.flash.types.MORPHLINESTYLEARRAY; -import com.jpexs.decompiler.flash.types.PIX15; -import com.jpexs.decompiler.flash.types.PIX24; -import com.jpexs.decompiler.flash.types.RECT; -import com.jpexs.decompiler.flash.types.RGB; -import com.jpexs.decompiler.flash.types.RGBA; -import com.jpexs.decompiler.flash.types.SHAPE; -import com.jpexs.decompiler.flash.types.SHAPEWITHSTYLE; -import com.jpexs.decompiler.flash.types.SOUNDENVELOPE; -import com.jpexs.decompiler.flash.types.SOUNDINFO; -import com.jpexs.decompiler.flash.types.TEXTRECORD; -import com.jpexs.decompiler.flash.types.ZONEDATA; -import com.jpexs.decompiler.flash.types.ZONERECORD; -import com.jpexs.decompiler.flash.types.filters.BEVELFILTER; -import com.jpexs.decompiler.flash.types.filters.BLURFILTER; -import com.jpexs.decompiler.flash.types.filters.COLORMATRIXFILTER; -import com.jpexs.decompiler.flash.types.filters.CONVOLUTIONFILTER; -import com.jpexs.decompiler.flash.types.filters.DROPSHADOWFILTER; -import com.jpexs.decompiler.flash.types.filters.FILTER; -import com.jpexs.decompiler.flash.types.filters.GLOWFILTER; -import com.jpexs.decompiler.flash.types.filters.GRADIENTBEVELFILTER; -import com.jpexs.decompiler.flash.types.filters.GRADIENTGLOWFILTER; -import com.jpexs.decompiler.flash.types.shaperecords.CurvedEdgeRecord; -import com.jpexs.decompiler.flash.types.shaperecords.EndShapeRecord; -import com.jpexs.decompiler.flash.types.shaperecords.SHAPERECORD; -import com.jpexs.decompiler.flash.types.shaperecords.StraightEdgeRecord; -import com.jpexs.decompiler.flash.types.shaperecords.StyleChangeRecord; -import com.jpexs.helpers.ByteArrayRange; -import com.jpexs.helpers.utf8.Utf8Helper; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.util.List; -import java.util.zip.Deflater; -import java.util.zip.DeflaterOutputStream; - -/** - * Class for writing data into SWF file - * - * @author JPEXS - */ -public class SWFOutputStream extends OutputStream { - - private final OutputStream os; - - private final int version; - - private long pos = 0; - - private int bitPos = 0; - - private int tempByte = 0; - - public long getPos() { - return pos; - } - - /** - * Constructor - * - * @param os OutputStream for writing data - * @param version Version of SWF - */ - public SWFOutputStream(OutputStream os, int version) { - this.version = version; - this.os = os; - } - - /** - * Writes byte to the stream - * - * @param b byte to write - * @throws IOException - */ - @Override - public void write(int b) throws IOException { - alignByte(); - os.write(b); - pos++; - } - - @Override - public void write(byte[] b) throws IOException { - alignByte(); - os.write(b); - pos += b.length; - } - - public void write(ByteArrayRange b) throws IOException { - alignByte(); - os.write(b.getArray(), b.getPos(), b.getLength()); - pos += b.getLength(); - } - - private void alignByte() throws IOException { - if (bitPos > 0) { - bitPos = 0; - write(tempByte); - tempByte = 0; - } - } - - /** - * Writes UI8 (Unsigned 8bit integer) value to the stream - * - * @param value UI8 value to write - * @throws IOException - */ - public void writeUI8(int value) throws IOException { - if (value > 0xff) { - throw new Error("Value is too large for UI8: " + value); - } - - write(value); - } - - /** - * Writes String value to the stream - * - * @param value String value - * @throws IOException - */ - public void writeString(String value) throws IOException { - byte[] data = Utf8Helper.getBytes(value); - for (int i = 0; i < data.length; i++) { - if (data[i] == 0) { - throw new IOException("String should not contain null character."); - } - } - - write(data); - write(0); - } - - /** - * Writes UI32 (Unsigned 32bit integer) value to the stream - * - * @param value UI32 value - * @throws IOException - */ - public void writeUI32(long value) throws IOException { - if (value > 0xffffffffL) { - throw new Error("Value is too large for UI32: " + value); - } - - write((int) (value & 0xff)); - write((int) ((value >> 8) & 0xff)); - write((int) ((value >> 16) & 0xff)); - write((int) ((value >> 24) & 0xff)); - } - - /** - * Writes UI16 (Unsigned 16bit integer) value to the stream - * - * @param value UI16 value - * @throws IOException - */ - public void writeUI16(int value) throws IOException { - if (value > 0xffff) { - throw new Error("Value is too large for UI16: " + value); - } - - write((int) (value & 0xff)); - write((int) ((value >> 8) & 0xff)); - } - - /** - * Writes SI32 (Signed 32bit integer) value to the stream - * - * @param value SI32 value - * @throws IOException - */ - public void writeSI32(long value) throws IOException { - if (value > 0x7fffffffL) { - throw new Error("Value is too large for SI32: " + value); - } - - writeUI32(value); - } - - /** - * Writes SI16 (Signed 16bit integer) value to the stream - * - * @param value SI16 value - * @throws IOException - */ - public void writeSI16(int value) throws IOException { - if (value > 0x7fff) { - throw new Error("Value is too large for SI16: " + value); - } - - writeUI16(value); - } - - /** - * Writes SI8 (Signed 8bit integer) value to the stream - * - * @param value SI8 value - * @throws IOException - */ - public void writeSI8(int value) throws IOException { - if (value > 0x7ff) { - throw new Error("Value is too large for SI8: " + value); - } - - writeUI8(value); - } - - /** - * Writes FIXED (Fixed point 16.16) value to the stream - * - * @param value FIXED value - * @throws IOException - */ - public void writeFIXED(double value) throws IOException { - long valueLong = (long) (value * (1 << 16)); - int beforePoint = (int) valueLong >> 16; - - int afterPoint = (int) valueLong % (1 << 16); - writeUI16(afterPoint); - writeUI16(beforePoint); - } - - /** - * Writes FIXED8 (Fixed point 8.8) value to the stream - * - * @param value FIXED8 value - * @throws IOException - */ - public void writeFIXED8(float value) throws IOException { - int beforePoint = (int) getIntPart(value); - int afterPoint = (int) getIntPart((value + (value < 0 ? beforePoint : -beforePoint)) * 256); - writeUI8(afterPoint); - writeUI8(beforePoint); - } - - private void writeLong(long value) throws IOException { - byte[] writeBuffer = new byte[8]; - writeBuffer[3] = (byte) (value >>> 56); - writeBuffer[2] = (byte) (value >>> 48); - writeBuffer[1] = (byte) (value >>> 40); - writeBuffer[0] = (byte) (value >>> 32); - writeBuffer[7] = (byte) (value >>> 24); - writeBuffer[6] = (byte) (value >>> 16); - writeBuffer[5] = (byte) (value >>> 8); - writeBuffer[4] = (byte) (value); - write(writeBuffer); - } - - /** - * Writes DOUBLE (double precision floating point value) value to the stream - * - * @param value DOUBLE value - * @throws IOException - */ - public void writeDOUBLE(double value) throws IOException { - writeLong(Double.doubleToLongBits(value)); - } - - /** - * Writes FLOAT (single precision floating point value) value to the stream - * - * @param value FLOAT value - * @throws IOException - */ - public void writeFLOAT(float value) throws IOException { - writeUI32(Float.floatToIntBits(value)); - } - - /** - * Writes FLOAT16 (16bit floating point value) value to the stream - * - * @param value FLOAT16 value - * @throws IOException - */ - public void writeFLOAT16(float value) throws IOException { - int bits = Float.floatToRawIntBits(value); - int sign = bits >> 31; - int exponent = (bits >> 22) & 0xff; - int mantisa = bits & 0x3FFFFF; - mantisa >>= 13; - writeUI16((sign << 15) + (exponent << 10) + mantisa); - } - - /** - * Writes EncodedU32 (Encoded unsigned 32bit value) value to the stream - * - * @param value U32 value - * @throws IOException - */ - public void writeEncodedU32(long value) throws IOException { - boolean loop = true; - value &= 0xFFFFFFFF; - do { - int ret = (int) (value & 0x7F); - if (value < 0x80) { - loop = false; - } - if (value > 0x7F) { - ret += 0x80; - } - write(ret); - value >>= 7; - } while (loop); - } - - /** - * Flushes data to underlying stream - * - * @throws IOException - */ - @Override - public void flush() throws IOException { - if (bitPos > 0) { - bitPos = 0; - write(tempByte); - tempByte = 0; - } - os.flush(); - } - - /** - * Closes the stream - * - * @throws IOException - */ - @Override - public void close() throws IOException { - flush(); - os.close(); - } - - /** - * Writes UB[nBits] (Unsigned-bit value) value to the stream - * - * @param nBits Number of bits which represent value - * @param value Unsigned value to write - * @throws IOException - */ - public void writeUB(int nBits, long value) throws IOException { - for (int bit = 0; bit < nBits; bit++) { - int nb = (int) ((value >> (nBits - 1 - bit)) & 1); - tempByte += nb * (1 << (7 - bitPos)); - bitPos++; - if (bitPos == 8) { - bitPos = 0; - write(tempByte); - tempByte = 0; - } - } - } - - /** - * Writes SB[nBits] (Signed-bit value) value to the stream - * - * @param nBits Number of bits which represent value - * @param value Signed value to write - * @throws IOException - */ - public void writeSB(int nBits, long value) throws IOException { - writeUB(nBits, value); - } - - /** - * Writes FB[nBits] (Signed fixed-point bit value) value to the stream - * - * @param nBits Number of bits which represent value - * @param value Double value to write - * @throws IOException - */ - public void writeFB(int nBits, double value) throws IOException { - if (nBits == 0) { - return; - } - long longVal = (long) (value * (1 << 16)); - writeSB(nBits, longVal); - } - - /** - * Writes RECT value to the stream - * - * @param value RECT value - * @throws IOException - */ - public void writeRECT(RECT value) throws IOException { - int nBits = 0; - int xMin = truncateTo31Bit(value.Xmin); - int xMax = truncateTo31Bit(value.Xmax); - int yMin = truncateTo31Bit(value.Ymin); - int yMax = truncateTo31Bit(value.Ymax); - nBits = enlargeBitCountS(nBits, xMin); - nBits = enlargeBitCountS(nBits, xMax); - nBits = enlargeBitCountS(nBits, yMin); - nBits = enlargeBitCountS(nBits, yMax); - - if (Configuration.debugCopy.get()) { - nBits = Math.max(nBits, value.nbits); - } - - writeUB(5, nBits); - writeSB(nBits, xMin); - writeSB(nBits, xMax); - writeSB(nBits, yMin); - writeSB(nBits, yMax); - alignByte(); - } - - private int truncateTo31Bit(int value) { - if (value > 0x3fffffff) { - value = 0x3fffffff; - } - if (value < -0x3fffffff) { - value = -0x3fffffff; - } - return value; - } - - /** - * Writes list of Tag values to the stream - * - * @param tags List of tag values - * @throws IOException - */ - public void writeTags(List tags) throws IOException { - for (Tag tag : tags) { - tag.writeTag(this); - } - } - - /** - * Calculates number of bits needed for representing unsigned value - * - * @param value Unsigned value - * @return Number of bits - */ - public static int getNeededBitsU(int value) { - value = Math.abs(value); - long x = 1; - int nBits; - - for (nBits = 1; nBits <= 64; nBits++) { - x <<= 1; - if (x > value) { - break; - } - } - return nBits; - } - - /** - * Calculates number of bits needed for representing signed value - * - * @param v Signed value - * @return Number of bits - */ - private static int getNeededBitsS(int v) { - int counter = 32; - int mask = 0x80000000; - final int val = (v < 0) ? -v : v; - while (((val & mask) == 0) && (counter > 0)) { - mask >>>= 1; - counter -= 1; - } - return counter + 1; - } - - /** - * Calculates number of bits needed for representing signed values - * - * @param first First Signed value - * @param params Next Signed values - * @return Number of bits - */ - public static int getNeededBitsS(int first, int... params) { - int nBits = 0; - nBits = enlargeBitCountS(nBits, first); - for (int i = 0; i < params.length; i++) { - nBits = enlargeBitCountS(nBits, params[i]); - } - return nBits; - } - - public static int getNeededBitsU(int first, int... params) { - int nBits = 0; - nBits = enlargeBitCountU(nBits, first); - for (int i = 0; i < params.length; i++) { - nBits = enlargeBitCountU(nBits, params[i]); - } - return nBits; - } - - private static long getIntPart(double value) { - if (value < 0) { - return (long) Math.ceil(value); - } - return (long) Math.floor(value); - } - - public static int unsignedSize(final int value) { - - final int val = (value < 0) ? -value - 1 : value; - int counter = 32; - int mask = 0x80000000; - - while (((val & mask) == 0) && (counter > 0)) { - mask >>>= 1; - counter -= 1; - } - return counter; - } - - /** - * Calculates number of bits needed for representing fixed-point value - * - * @param value Fixed-point value - * @return Number of bits - */ - public static int getNeededBitsF(float value) { - // 0.26213074 16bits - // 0.5 17bits - // 1.3476715 18bits - int k = (int) value; - return getNeededBitsS(k) + 16; - } - - public static int enlargeBitCountS(int currentBitCount, int value) { - if (value == 0) { - return currentBitCount; - } - int neededNew = getNeededBitsS(value); - if (neededNew > currentBitCount) { - return neededNew; - } - return currentBitCount; - } - - public static int enlargeBitCountU(int currentBitCount, int value) { - if (value == 0) { - return currentBitCount; - } - int neededNew = getNeededBitsU(value); - if (neededNew > currentBitCount) { - return neededNew; - } - return currentBitCount; - } - - /** - * Writes MATRIX value to the stream - * - * @param value MATRIX value - * @throws IOException - */ - public void writeMatrix(MATRIX value) throws IOException { - writeUB(1, value.hasScale ? 1 : 0); - if (value.hasScale) { - int nBits = 0; - nBits = enlargeBitCountS(nBits, value.scaleX); - nBits = enlargeBitCountS(nBits, value.scaleY); - - if (Configuration.debugCopy.get()) { - nBits = Math.max(nBits, value.nScaleBits); - } - - writeUB(5, nBits); - writeSB(nBits, value.scaleX); - writeSB(nBits, value.scaleY); - } - writeUB(1, value.hasRotate ? 1 : 0); - if (value.hasRotate) { - int nBits = 0; - nBits = enlargeBitCountS(nBits, value.rotateSkew0); - nBits = enlargeBitCountS(nBits, value.rotateSkew1); - - if (Configuration.debugCopy.get()) { - nBits = Math.max(nBits, value.nRotateBits); - } - - writeUB(5, nBits); - writeSB(nBits, value.rotateSkew0); - writeSB(nBits, value.rotateSkew1); - } - int NTranslateBits = 0; - NTranslateBits = enlargeBitCountS(NTranslateBits, value.translateX); - NTranslateBits = enlargeBitCountS(NTranslateBits, value.translateY); - - if (Configuration.debugCopy.get()) { - NTranslateBits = Math.max(NTranslateBits, value.nTranslateBits); - } - - writeUB(5, NTranslateBits); - - writeSB(NTranslateBits, value.translateX); - writeSB(NTranslateBits, value.translateY); - alignByte(); - - } - - /** - * Writes CXFORM value to the stream - * - * @param value CXFORM value - * @throws IOException - */ - public void writeCXFORM(CXFORM value) throws IOException { - writeUB(1, value.hasAddTerms ? 1 : 0); - writeUB(1, value.hasMultTerms ? 1 : 0); - int Nbits = 1; - if (value.hasMultTerms) { - Nbits = enlargeBitCountS(Nbits, value.redMultTerm); - Nbits = enlargeBitCountS(Nbits, value.greenMultTerm); - Nbits = enlargeBitCountS(Nbits, value.blueMultTerm); - } - if (value.hasAddTerms) { - Nbits = enlargeBitCountS(Nbits, value.redAddTerm); - Nbits = enlargeBitCountS(Nbits, value.greenAddTerm); - Nbits = enlargeBitCountS(Nbits, value.blueAddTerm); - } - - if (Configuration.debugCopy.get()) { - Nbits = Math.max(Nbits, value.nbits); - } - - writeUB(4, Nbits); - if (value.hasMultTerms) { - writeSB(Nbits, value.redMultTerm); - writeSB(Nbits, value.greenMultTerm); - writeSB(Nbits, value.blueMultTerm); - } - if (value.hasAddTerms) { - writeSB(Nbits, value.redAddTerm); - writeSB(Nbits, value.greenAddTerm); - writeSB(Nbits, value.blueAddTerm); - } - alignByte(); - } - - /** - * Writes CXFORMWITHALPHA value to the stream - * - * @param value CXFORMWITHALPHA value - * @throws IOException - */ - public void writeCXFORMWITHALPHA(CXFORMWITHALPHA value) throws IOException { - writeUB(1, value.hasAddTerms ? 1 : 0); - writeUB(1, value.hasMultTerms ? 1 : 0); - int Nbits = 1; - if (value.hasMultTerms) { - Nbits = enlargeBitCountS(Nbits, value.redMultTerm); - Nbits = enlargeBitCountS(Nbits, value.greenMultTerm); - Nbits = enlargeBitCountS(Nbits, value.blueMultTerm); - Nbits = enlargeBitCountS(Nbits, value.alphaMultTerm); - } - if (value.hasAddTerms) { - Nbits = enlargeBitCountS(Nbits, value.redAddTerm); - Nbits = enlargeBitCountS(Nbits, value.greenAddTerm); - Nbits = enlargeBitCountS(Nbits, value.blueAddTerm); - Nbits = enlargeBitCountS(Nbits, value.alphaAddTerm); - } - - if (Configuration.debugCopy.get()) { - Nbits = Math.max(Nbits, value.nbits); - } - - writeUB(4, Nbits); - if (value.hasMultTerms) { - writeSB(Nbits, value.redMultTerm); - writeSB(Nbits, value.greenMultTerm); - writeSB(Nbits, value.blueMultTerm); - writeSB(Nbits, value.alphaMultTerm); - } - if (value.hasAddTerms) { - writeSB(Nbits, value.redAddTerm); - writeSB(Nbits, value.greenAddTerm); - writeSB(Nbits, value.blueAddTerm); - writeSB(Nbits, value.alphaAddTerm); - } - alignByte(); - } - - /** - * Writes CLIPEVENTFLAGS value to the stream - * - * @param value CLIPEVENTFLAGS value - * @throws IOException - */ - public void writeCLIPEVENTFLAGS(CLIPEVENTFLAGS value) throws IOException { - writeUB(1, value.clipEventKeyUp ? 1 : 0); - writeUB(1, value.clipEventKeyDown ? 1 : 0); - writeUB(1, value.clipEventMouseUp ? 1 : 0); - writeUB(1, value.clipEventMouseDown ? 1 : 0); - writeUB(1, value.clipEventMouseMove ? 1 : 0); - writeUB(1, value.clipEventUnload ? 1 : 0); - writeUB(1, value.clipEventEnterFrame ? 1 : 0); - writeUB(1, value.clipEventLoad ? 1 : 0); - writeUB(1, value.clipEventDragOver ? 1 : 0); - writeUB(1, value.clipEventRollOut ? 1 : 0); - writeUB(1, value.clipEventRollOver ? 1 : 0); - writeUB(1, value.clipEventReleaseOutside ? 1 : 0); - writeUB(1, value.clipEventRelease ? 1 : 0); - writeUB(1, value.clipEventPress ? 1 : 0); - writeUB(1, value.clipEventInitialize ? 1 : 0); - writeUB(1, value.clipEventData ? 1 : 0); - if (version >= 6) { - writeUB(5, value.reserved); - writeUB(1, value.clipEventConstruct ? 1 : 0); - writeUB(1, value.clipEventKeyPress ? 1 : 0); - writeUB(1, value.clipEventDragOut ? 1 : 0); - writeUB(8, value.reserved2); - } - } - - /** - * Writes CLIPACTIONRECORD value to the stream - * - * @param value CLIPACTIONRECORD value - * @throws IOException - */ - public void writeCLIPACTIONRECORD(CLIPACTIONRECORD value) throws IOException { - writeCLIPEVENTFLAGS(value.eventFlags); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try (SWFOutputStream sos = new SWFOutputStream(baos, version)) { - if (value.eventFlags.clipEventKeyPress) { - sos.writeUI8(value.keyCode); - } - sos.write(value.actionBytes); - } - byte[] data = baos.toByteArray(); - writeUI32(data.length); // actionRecordSize - write(data); - } - - /** - * Writes CLIPACTIONS value to the stream - * - * @param value CLIPACTIONS value - * @throws IOException - */ - public void writeCLIPACTIONS(CLIPACTIONS value) throws IOException { - writeUI16(value.reserved); - writeCLIPEVENTFLAGS(value.allEventFlags); - for (CLIPACTIONRECORD car : value.clipActionRecords) { - writeCLIPACTIONRECORD(car); - } - if (version <= 5) { - writeUI16(0); - } else { - writeUI32(0); - } - } - - /** - * Writes COLORMATRIXFILTER value to the stream - * - * @param value COLORMATRIXFILTER value - * @throws IOException - */ - public void writeCOLORMATRIXFILTER(COLORMATRIXFILTER value) throws IOException { - for (int i = 0; i < 20; i++) { - writeFLOAT(value.matrix[i]); - } - } - - /** - * Writes RGBA value to the stream - * - * @param value RGBA value - * @throws IOException - */ - public void writeRGBA(RGBA value) throws IOException { - writeUI8(value.red); - writeUI8(value.green); - writeUI8(value.blue); - writeUI8(value.alpha); - } - - /** - * Writes ARGB value to the stream - * - * @param value ARGB value - * @throws IOException - */ - public void writeARGB(ARGB value) throws IOException { - writeUI8(value.alpha); - writeUI8(value.red); - writeUI8(value.green); - writeUI8(value.blue); - } - - /** - * Writes RGB value to the stream - * - * @param value RGB value - * @throws IOException - */ - public void writeRGB(RGB value) throws IOException { - writeUI8(value.red); - writeUI8(value.green); - writeUI8(value.blue); - } - - /** - * Writes CONVOLUTIONFILTER value to the stream - * - * @param value CONVOLUTIONFILTER value - * @throws IOException - */ - public void writeCONVOLUTIONFILTER(CONVOLUTIONFILTER value) throws IOException { - writeUI8(value.matrixX); - writeUI8(value.matrixY); - writeFLOAT(value.divisor); - writeFLOAT(value.bias); - for (int x = 0; x < value.matrixX; x++) { - for (int y = 0; y < value.matrixY; y++) { - writeFLOAT(value.matrix[x][y]); - } - } - writeRGBA(value.defaultColor); - writeUB(6, value.reserved); - writeUB(1, value.clamp ? 1 : 0); - writeUB(1, value.preserveAlpha ? 1 : 0); - } - - /** - * Writes BLURFILTER value to the stream - * - * @param value BLURFILTER value - * @throws IOException - */ - public void writeBLURFILTER(BLURFILTER value) throws IOException { - writeFIXED(value.blurX); - writeFIXED(value.blurY); - writeUB(5, value.passes); - writeUB(3, value.reserved); - } - - /** - * Writes DROPSHADOWFILTER value to the stream - * - * @param value DROPSHADOWFILTER value - * @throws IOException - */ - public void writeDROPSHADOWFILTER(DROPSHADOWFILTER value) throws IOException { - writeRGBA(value.dropShadowColor); - writeFIXED(value.blurX); - writeFIXED(value.blurY); - writeFIXED(value.angle); - writeFIXED(value.distance); - writeFIXED8(value.strength); - writeUB(1, value.innerShadow ? 1 : 0); - writeUB(1, value.knockout ? 1 : 0); - writeUB(1, value.compositeSource ? 1 : 0); - writeUB(5, value.passes); - } - - /** - * Writes GLOWFILTER value to the stream - * - * @param value GLOWFILTER value - * @throws IOException - */ - public void writeGLOWFILTER(GLOWFILTER value) throws IOException { - writeRGBA(value.glowColor); - writeFIXED(value.blurX); - writeFIXED(value.blurY); - writeFIXED8(value.strength); - writeUB(1, value.innerGlow ? 1 : 0); - writeUB(1, value.knockout ? 1 : 0); - writeUB(1, value.compositeSource ? 1 : 0); - writeUB(5, value.passes); - } - - /** - * Writes BEVELFILTER value to the stream - * - * @param value BEVELFILTER value - * @throws IOException - */ - public void writeBEVELFILTER(BEVELFILTER value) throws IOException { - writeRGBA(value.highlightColor); - writeRGBA(value.shadowColor); - writeFIXED(value.blurX); - writeFIXED(value.blurY); - writeFIXED(value.angle); - writeFIXED(value.distance); - writeFIXED8(value.strength); - writeUB(1, value.innerShadow ? 1 : 0); - writeUB(1, value.knockout ? 1 : 0); - writeUB(1, value.compositeSource ? 1 : 0); - writeUB(1, value.onTop ? 1 : 0); - writeUB(4, value.passes); - } - - /** - * Writes GRADIENTGLOWFILTER value to the stream - * - * @param value GRADIENTGLOWFILTER value - * @throws IOException - */ - public void writeGRADIENTGLOWFILTER(GRADIENTGLOWFILTER value) throws IOException { - writeUI8(value.gradientColors.length); - for (int i = 0; i < value.gradientColors.length; i++) { - writeRGBA(value.gradientColors[i]); - } - for (int i = 0; i < value.gradientColors.length; i++) { - writeUI8(value.gradientRatio[i]); - } - writeFIXED(value.blurX); - writeFIXED(value.blurY); - writeFIXED(value.angle); - writeFIXED(value.distance); - writeFIXED8(value.strength); - writeUB(1, value.innerShadow ? 1 : 0); - writeUB(1, value.knockout ? 1 : 0); - writeUB(1, value.compositeSource ? 1 : 0); - writeUB(1, value.onTop ? 1 : 0); - writeUB(4, value.passes); - } - - /** - * Writes GRADIENTBEVELFILTER value to the stream - * - * @param value GRADIENTBEVELFILTER value - * @throws IOException - */ - public void writeGRADIENTBEVELFILTER(GRADIENTBEVELFILTER value) throws IOException { - writeUI8(value.gradientColors.length); - for (int i = 0; i < value.gradientColors.length; i++) { - writeRGBA(value.gradientColors[i]); - } - for (int i = 0; i < value.gradientColors.length; i++) { - writeUI8(value.gradientRatio[i]); - } - writeFIXED(value.blurX); - writeFIXED(value.blurY); - writeFIXED(value.angle); - writeFIXED(value.distance); - writeFIXED8(value.strength); - writeUB(1, value.innerShadow ? 1 : 0); - writeUB(1, value.knockout ? 1 : 0); - writeUB(1, value.compositeSource ? 1 : 0); - writeUB(1, value.onTop ? 1 : 0); - writeUB(4, value.passes); - } - - /** - * Writes list of FILTER values to the stream - * - * @param list List of FILTER values - * @throws IOException - */ - public void writeFILTERLIST(List list) throws IOException { - writeUI8(list.size()); - for (int i = 0; i < list.size(); i++) { - writeFILTER(list.get(i)); - } - } - - /** - * Writes FILTER value to the stream - * - * @param value FILTER value - * @throws IOException - */ - public void writeFILTER(FILTER value) throws IOException { - writeUI8(value.id); - if (value instanceof DROPSHADOWFILTER) { - writeDROPSHADOWFILTER((DROPSHADOWFILTER) value); - } - if (value instanceof BLURFILTER) { - writeBLURFILTER((BLURFILTER) value); - } - if (value instanceof GLOWFILTER) { - writeGLOWFILTER((GLOWFILTER) value); - } - if (value instanceof BEVELFILTER) { - writeBEVELFILTER((BEVELFILTER) value); - } - if (value instanceof GRADIENTGLOWFILTER) { - writeGRADIENTGLOWFILTER((GRADIENTGLOWFILTER) value); - } - if (value instanceof CONVOLUTIONFILTER) { - writeCONVOLUTIONFILTER((CONVOLUTIONFILTER) value); - } - if (value instanceof COLORMATRIXFILTER) { - writeCOLORMATRIXFILTER((COLORMATRIXFILTER) value); - } - if (value instanceof GRADIENTBEVELFILTER) { - writeGRADIENTBEVELFILTER((GRADIENTBEVELFILTER) value); - } - } - - /** - * Writes list of BUTTONRECORD values to the stream - * - * @param list List of BUTTONRECORD values - * @param inDefineButton2 Whether write inside of DefineButton2Tag or not - * @throws IOException - */ - public void writeBUTTONRECORDList(List list, boolean inDefineButton2) throws IOException { - for (BUTTONRECORD brec : list) { - writeBUTTONRECORD(brec, inDefineButton2); - } - writeUI8(0); - } - - /** - * Writes BUTTONRECORD value to the stream - * - * @param value BUTTONRECORD value - * @param inDefineButton2 Whether write inside of DefineButton2Tag or not - * @throws IOException - */ - public void writeBUTTONRECORD(BUTTONRECORD value, boolean inDefineButton2) throws IOException { - writeUB(2, value.reserved); - writeUB(1, value.buttonHasBlendMode ? 1 : 0); - writeUB(1, value.buttonHasFilterList ? 1 : 0); - writeUB(1, value.buttonStateHitTest ? 1 : 0); - writeUB(1, value.buttonStateDown ? 1 : 0); - writeUB(1, value.buttonStateOver ? 1 : 0); - writeUB(1, value.buttonStateUp ? 1 : 0); - writeUI16(value.characterId); - writeUI16(value.placeDepth); - writeMatrix(value.placeMatrix); - if (inDefineButton2) { - writeCXFORMWITHALPHA(value.colorTransform); - if (value.buttonHasFilterList) { - writeFILTERLIST(value.filterList); - } - if (value.buttonHasBlendMode) { - writeUI8(value.blendMode); - } - } - } - - /** - * Writes list of BUTTONCONDACTION values to the stream - * - * @param list List of BUTTONCONDACTION values - * @throws IOException - */ - public void writeBUTTONCONDACTIONList(List list) throws IOException { - for (int i = 0; i < list.size(); i++) { - writeBUTTONCONDACTION(list.get(i), i == list.size() - 1); - } - } - - /** - * Writes BUTTONCONDACTION value to the stream - * - * @param value BUTTONCONDACTION value - * @param isLast True if it is last on the list - * @throws IOException - */ - public void writeBUTTONCONDACTION(BUTTONCONDACTION value, boolean isLast) throws IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try (SWFOutputStream sos = new SWFOutputStream(baos, version)) { - sos.writeUB(1, value.condIdleToOverDown ? 1 : 0); - sos.writeUB(1, value.condOutDownToIdle ? 1 : 0); - sos.writeUB(1, value.condOutDownToOverDown ? 1 : 0); - sos.writeUB(1, value.condOverDownToOutDown ? 1 : 0); - sos.writeUB(1, value.condOverDownToOverUp ? 1 : 0); - sos.writeUB(1, value.condOverUpToOverDown ? 1 : 0); - sos.writeUB(1, value.condOverUpToIddle ? 1 : 0); - sos.writeUB(1, value.condIdleToOverUp ? 1 : 0); - sos.writeUB(7, value.condKeyPress); - sos.writeUB(1, value.condOverDownToIdle ? 1 : 0); - sos.write(value.actionBytes); - } - byte[] data = baos.toByteArray(); - if (isLast) { - writeUI16(0); - } else { - writeUI16(data.length + 2); - } - write(data); - } - - /** - * Writes FILLSTYLE value to the stream - * - * @param value FILLSTYLE value - * @param shapeNum 1 in DefineShape, 2 in DefineShape2,... - * @throws IOException - */ - public void writeFILLSTYLE(FILLSTYLE value, int shapeNum) throws IOException { - writeUI8(value.fillStyleType); - if (value.fillStyleType == FILLSTYLE.SOLID) { - if (shapeNum >= 3) { - writeRGBA((RGBA) value.color); - } else if (shapeNum == 1 || shapeNum == 2) { - writeRGB(value.color); - } - } - if ((value.fillStyleType == FILLSTYLE.LINEAR_GRADIENT) - || (value.fillStyleType == FILLSTYLE.RADIAL_GRADIENT) - || (value.fillStyleType == FILLSTYLE.FOCAL_RADIAL_GRADIENT)) { - writeMatrix(value.gradientMatrix); - } - if ((value.fillStyleType == FILLSTYLE.LINEAR_GRADIENT) - || (value.fillStyleType == FILLSTYLE.RADIAL_GRADIENT)) { - writeGRADIENT(value.gradient, shapeNum); - } - if (value.fillStyleType == FILLSTYLE.FOCAL_RADIAL_GRADIENT) { - writeFOCALGRADIENT((FOCALGRADIENT) value.gradient, shapeNum); - } - - if ((value.fillStyleType == FILLSTYLE.REPEATING_BITMAP) - || (value.fillStyleType == FILLSTYLE.CLIPPED_BITMAP) - || (value.fillStyleType == FILLSTYLE.NON_SMOOTHED_REPEATING_BITMAP) - || (value.fillStyleType == FILLSTYLE.NON_SMOOTHED_CLIPPED_BITMAP)) { - writeUI16(value.bitmapId); - writeMatrix(value.bitmapMatrix); - } - } - - /** - * Writes FILLSTYLEARRAY value to the stream - * - * @param value FILLSTYLEARRAY value - * @param shapeNum 1 in DefineShape, 2 in DefineShape2,... - * @throws IOException - */ - public void writeFILLSTYLEARRAY(FILLSTYLEARRAY value, int shapeNum) throws IOException { - int fillStyleCount = value.fillStyles.length; - if (shapeNum == 2 || shapeNum == 3) { - if (fillStyleCount >= 0xff) { - writeUI8(0xff); - writeUI16(fillStyleCount); - } else { - writeUI8(fillStyleCount); - } - } else { - writeUI8(fillStyleCount); - } - for (int i = 0; i < value.fillStyles.length; i++) { - writeFILLSTYLE(value.fillStyles[i], shapeNum); - } - } - - /** - * Writes FOCALGRADIENT value to the stream - * - * @param value FILLSTYLEARRAY value - * @param shapeNum 1 in DefineShape, 2 in DefineShape2,... - * @throws IOException - */ - public void writeFOCALGRADIENT(FOCALGRADIENT value, int shapeNum) throws IOException { - writeUB(2, value.spreadMode); - writeUB(2, value.interpolationMode); - writeUB(4, value.gradientRecords.length); - for (int i = 0; i < value.gradientRecords.length; i++) { - writeGRADRECORD(value.gradientRecords[i], shapeNum); - } - writeFIXED8(value.focalPoint); - } - - /** - * Writes GRADIENT value to the stream - * - * @param value GRADIENT value - * @param shapeNum 1 in DefineShape, 2 in DefineShape2,... - * @throws IOException - */ - public void writeGRADIENT(GRADIENT value, int shapeNum) throws IOException { - writeUB(2, value.spreadMode); - writeUB(2, value.interpolationMode); - writeUB(4, value.gradientRecords.length); - for (int i = 0; i < value.gradientRecords.length; i++) { - writeGRADRECORD(value.gradientRecords[i], shapeNum); - } - } - - /** - * Writes GRADRECORD value to the stream - * - * @param value GRADRECORD value - * @param shapeNum 1 in DefineShape, 2 in DefineShape2,... - * @throws IOException - */ - public void writeGRADRECORD(GRADRECORD value, int shapeNum) throws IOException { - writeUI8(value.ratio); - if (shapeNum >= 3) { - writeRGBA((RGBA) value.color); - } else { - writeRGB(value.color); - } - } - - /** - * Writes LINESTYLE value to the stream - * - * @param value LINESTYLE value - * @param shapeNum 1 in DefineShape, 2 in DefineShape2,... - * @throws IOException - */ - public void writeLINESTYLE(LINESTYLE value, int shapeNum) throws IOException { - writeUI16(value.width); - if (shapeNum == 1 || shapeNum == 2) { - writeRGB(value.color); - } else if (shapeNum == 3) { - writeRGBA((RGBA) value.color); - } - } - - /** - * Writes LINESTYLE2 value to the stream - * - * @param value LINESTYLE2 value - * @param shapeNum 1 in DefineShape, 2 in DefineShape2,... - * @throws IOException - */ - public void writeLINESTYLE2(LINESTYLE2 value, int shapeNum) throws IOException { - writeUI16(value.width); - writeUB(2, value.startCapStyle); - writeUB(2, value.joinStyle); - writeUB(1, value.hasFillFlag ? 1 : 0); - writeUB(1, value.noHScaleFlag ? 1 : 0); - writeUB(1, value.noVScaleFlag ? 1 : 0); - writeUB(1, value.pixelHintingFlag ? 1 : 0); - writeUB(5, value.reserved); - writeUB(1, value.noClose ? 1 : 0); - writeUB(2, value.endCapStyle); - if (value.joinStyle == LINESTYLE2.MITER_JOIN) { - writeUI16(value.miterLimitFactor); - } - if (!value.hasFillFlag) { - writeRGBA((RGBA) value.color); - } else { - writeFILLSTYLE(value.fillType, shapeNum); - } - } - - /** - * Writes LINESTYLEARRAY value to the stream - * - * @param value FILLSTYLEARRAY value - * @param shapeNum 1 in DefineShape, 2 in DefineShape2,... - * @throws IOException - */ - public void writeLINESTYLEARRAY(LINESTYLEARRAY value, int shapeNum) throws IOException { - int lineStyleCount; - if (shapeNum == 1 || shapeNum == 2 || shapeNum == 3) { - lineStyleCount = value.lineStyles.length; - if (lineStyleCount >= 0xff) { - writeUI8(0xff); - writeUI16(lineStyleCount); - } else { - writeUI8(lineStyleCount); - } - for (int i = 0; i < lineStyleCount; i++) { - writeLINESTYLE(value.lineStyles[i], shapeNum); - } - } else if (shapeNum == 4) { - lineStyleCount = value.lineStyles.length; - if (lineStyleCount >= 0xff) { - writeUI8(0xff); - writeUI16(lineStyleCount); - } else { - writeUI8(lineStyleCount); - } - for (int i = 0; i < lineStyleCount; i++) { - writeLINESTYLE2((LINESTYLE2) value.lineStyles[i], shapeNum); - } - } - } - - /** - * Writes SHAPE value to the stream - * - * @param value SHAPE value - * @param shapeNum 1 in DefineShape, 2 in DefineShape2,... - * @throws IOException - */ - public void writeSHAPE(SHAPE value, int shapeNum) throws IOException { - writeUB(4, value.numFillBits); - writeUB(4, value.numLineBits); - writeSHAPERECORDS(value.shapeRecords, value.numFillBits, value.numLineBits, shapeNum); - } - - /** - * Writes SHAPEWITHSTYLE value to the stream - * - * @param value SHAPEWITHSTYLE value - * @param shapeNum 1 in DefineShape, 2 in DefineShape2,... - * @throws IOException - */ - public void writeSHAPEWITHSTYLE(SHAPEWITHSTYLE value, int shapeNum) throws IOException { - writeFILLSTYLEARRAY(value.fillStyles, shapeNum); - writeLINESTYLEARRAY(value.lineStyles, shapeNum); - value.numFillBits = getNeededBitsU(value.fillStyles.fillStyles.length); - value.numLineBits = getNeededBitsU(value.lineStyles.lineStyles.length); - writeUB(4, value.numFillBits); - writeUB(4, value.numLineBits); - writeSHAPERECORDS(value.shapeRecords, value.numFillBits, value.numLineBits, shapeNum); - } - - /** - * Writes SHAPERECORDs value to the stream - * - * @param value SHAPERECORDS value - * @param fillBits - * @param lineBits - * @param shapeNum 1 in DefineShape, 2 in DefineShape2,... - * @throws IOException - */ - private void writeSHAPERECORDS(List value, int fillBits, int lineBits, int shapeNum) throws IOException { - for (SHAPERECORD sh : value) { - if (sh instanceof CurvedEdgeRecord) { - CurvedEdgeRecord cer = (CurvedEdgeRecord) sh; - writeUB(1, 1); // typeFlag - writeUB(1, 0); // curvedEdge - cer.numBits = Math.max(getNeededBitsS(cer.controlDeltaX, cer.controlDeltaY, cer.anchorDeltaX, cer.anchorDeltaY) - 2, 0); - writeUB(4, cer.numBits); - writeSB(cer.numBits + 2, cer.controlDeltaX); - writeSB(cer.numBits + 2, cer.controlDeltaY); - writeSB(cer.numBits + 2, cer.anchorDeltaX); - writeSB(cer.numBits + 2, cer.anchorDeltaY); - } else if (sh instanceof StraightEdgeRecord) { - StraightEdgeRecord ser = (StraightEdgeRecord) sh; - writeUB(1, 1); // typeFlag - writeUB(1, 1); // straightEdge - ser.numBits = Math.max(getNeededBitsS(ser.deltaX, ser.deltaY) - 2, 0); - writeUB(4, ser.numBits); - writeUB(1, ser.generalLineFlag ? 1 : 0); - if (!ser.generalLineFlag) { - writeUB(1, ser.vertLineFlag ? 1 : 0); - } - if (ser.generalLineFlag || (!ser.vertLineFlag)) { - writeSB(ser.numBits + 2, ser.deltaX); - } - if (ser.generalLineFlag || ser.vertLineFlag) { - writeSB(ser.numBits + 2, ser.deltaY); - } - } else if (sh instanceof StyleChangeRecord) { - StyleChangeRecord scr = (StyleChangeRecord) sh; - writeUB(1, 0); // typeFlag - writeUB(1, scr.stateNewStyles ? 1 : 0); - writeUB(1, scr.stateLineStyle ? 1 : 0); - writeUB(1, scr.stateFillStyle1 ? 1 : 0); - writeUB(1, scr.stateFillStyle0 ? 1 : 0); - writeUB(1, scr.stateMoveTo ? 1 : 0); - if (scr.stateMoveTo) { - scr.moveBits = getNeededBitsS(scr.moveDeltaX, scr.moveDeltaY); - writeUB(5, scr.moveBits); - writeSB(scr.moveBits, scr.moveDeltaX); - writeSB(scr.moveBits, scr.moveDeltaY); - } - if (scr.stateFillStyle0) { - writeUB(fillBits, scr.fillStyle0); - } - if (scr.stateFillStyle1) { - writeUB(fillBits, scr.fillStyle1); - } - if (scr.stateLineStyle) { - writeUB(lineBits, scr.lineStyle); - } - if (scr.stateNewStyles) { - writeFILLSTYLEARRAY(scr.fillStyles, shapeNum); - writeLINESTYLEARRAY(scr.lineStyles, shapeNum); - scr.numFillBits = getNeededBitsU(scr.fillStyles.fillStyles.length); - scr.numLineBits = getNeededBitsU(scr.lineStyles.lineStyles.length); - fillBits = scr.numFillBits; - lineBits = scr.numLineBits; - writeUB(4, scr.numFillBits); - writeUB(4, scr.numLineBits); - } - - } else if (sh instanceof EndShapeRecord) { - writeUB(1, 0); // typeFlag - writeUB(5, 0); // end of shape flag - } - } - alignByte(); - } - - /** - * Writes SOUNDINFO value to the stream - * - * @param value SOUNDINFO value - * @throws IOException - */ - public void writeSOUNDINFO(SOUNDINFO value) throws IOException { - writeUB(2, value.reserved); - writeUB(1, value.syncStop ? 1 : 0); - writeUB(1, value.syncNoMultiple ? 1 : 0); - writeUB(1, value.hasEnvelope ? 1 : 0); - writeUB(1, value.hasLoops ? 1 : 0); - writeUB(1, value.hasOutPoint ? 1 : 0); - writeUB(1, value.hasInPoint ? 1 : 0); - if (value.hasInPoint) { - writeUI32(value.inPoint); - } - if (value.hasOutPoint) { - writeUI32(value.outPoint); - } - if (value.hasLoops) { - writeUI16(value.loopCount); - } - if (value.hasEnvelope) { - writeUI8(value.envelopeRecords.length); - for (SOUNDENVELOPE env : value.envelopeRecords) { - writeSOUNDENVELOPE(env); - } - } - } - - /** - * Writes SOUNDENVELOPE value to the stream - * - * @param value SOUNDENVELOPE value - * @throws IOException - */ - public void writeSOUNDENVELOPE(SOUNDENVELOPE value) throws IOException { - writeUI32(value.pos44); - writeUI16(value.leftLevel); - writeUI16(value.rightLevel); - } - - /** - * Writes TEXTRECORD value to the stream - * - * @param value TEXTRECORD value - * @param inDefineText2 - * @param glyphBits - * @param advanceBits - * @throws IOException - */ - public void writeTEXTRECORD(TEXTRECORD value, boolean inDefineText2, int glyphBits, int advanceBits) throws IOException { - writeUB(1, 1); - writeUB(3, 0); - writeUB(1, value.styleFlagsHasFont ? 1 : 0); - writeUB(1, value.styleFlagsHasColor ? 1 : 0); - writeUB(1, value.styleFlagsHasYOffset ? 1 : 0); - writeUB(1, value.styleFlagsHasXOffset ? 1 : 0); - if (value.styleFlagsHasFont) { - writeUI16(value.fontId); - } - if (value.styleFlagsHasColor) { - if (inDefineText2) { - writeRGBA(value.textColorA); - } else { - writeRGB(value.textColor); - } - } - if (value.styleFlagsHasXOffset) { - writeSI16(value.xOffset); - } - if (value.styleFlagsHasYOffset) { - writeSI16(value.yOffset); - } - if (value.styleFlagsHasFont) { - writeUI16(value.textHeight); - } - writeUI8(value.glyphEntries.size()); - for (GLYPHENTRY ge : value.glyphEntries) { - writeGLYPHENTRY(ge, glyphBits, advanceBits); - } - alignByte(); - } - - /** - * Writes GLYPHENTRY value to the stream - * - * @param value GLYPHENTRY value - * @param glyphBits - * @param advanceBits - * @throws IOException - */ - public void writeGLYPHENTRY(GLYPHENTRY value, int glyphBits, int advanceBits) throws IOException { - writeUB(glyphBits, value.glyphIndex); - writeSB(advanceBits, value.glyphAdvance); - } - - /** - * Writes MORPHFILLSTYLE value to the stream - * - * @param value MORPHFILLSTYLE value - * @param shapeNum 1 in DefineMorphShape, 2 in DefineMorphShape2,... - * @throws IOException - */ - public void writeMORPHFILLSTYLE(MORPHFILLSTYLE value, int shapeNum) throws IOException { - writeUI8(value.fillStyleType); - if (value.fillStyleType == MORPHFILLSTYLE.SOLID) { - writeRGBA(value.startColor); - writeRGBA(value.endColor); - } - if ((value.fillStyleType == MORPHFILLSTYLE.LINEAR_GRADIENT) - || (value.fillStyleType == MORPHFILLSTYLE.RADIAL_GRADIENT) - || (value.fillStyleType == MORPHFILLSTYLE.FOCAL_RADIAL_GRADIENT)) { - writeMatrix(value.startGradientMatrix); - writeMatrix(value.endGradientMatrix); - } - if ((value.fillStyleType == MORPHFILLSTYLE.LINEAR_GRADIENT) - || (value.fillStyleType == MORPHFILLSTYLE.RADIAL_GRADIENT)) { - writeMORPHGRADIENT(value.gradient, shapeNum); - } - if (value.fillStyleType == MORPHFILLSTYLE.FOCAL_RADIAL_GRADIENT) { - writeMORPHFOCALGRADIENT((MORPHFOCALGRADIENT) value.gradient, shapeNum); - } - - if ((value.fillStyleType == MORPHFILLSTYLE.REPEATING_BITMAP) - || (value.fillStyleType == MORPHFILLSTYLE.CLIPPED_BITMAP) - || (value.fillStyleType == MORPHFILLSTYLE.NON_SMOOTHED_REPEATING_BITMAP) - || (value.fillStyleType == MORPHFILLSTYLE.NON_SMOOTHED_CLIPPED_BITMAP)) { - writeUI16(value.bitmapId); - writeMatrix(value.startBitmapMatrix); - writeMatrix(value.endBitmapMatrix); - } - } - - /** - * WritesMORPH FILLSTYLEARRAY value to the stream - * - * @param value MORPHFILLSTYLEARRAY value - * @param morphShapeNum 1 on DefineMorphShape, 2 on DefineMorphShape - * @throws IOException - */ - public void writeMORPHFILLSTYLEARRAY(MORPHFILLSTYLEARRAY value, int morphShapeNum) throws IOException { - int fillStyleCount = value.fillStyles.length; - if (fillStyleCount >= 0xff) { - writeUI8(0xff); - writeUI16(fillStyleCount); - } else { - writeUI8(fillStyleCount); - } - for (int i = 0; i < value.fillStyles.length; i++) { - writeMORPHFILLSTYLE(value.fillStyles[i], morphShapeNum); - } - } - - /** - * Writes MORPHGRADIENT value to the stream - * - * @param value MORPHGRADIENT value - * @param shapeNum 1 in DefineMorphShape, 2 in DefineMorphShape2,... - * @throws IOException - */ - public void writeMORPHGRADIENT(MORPHGRADIENT value, int shapeNum) throws IOException { - // Despite of documentation (UI8 1-8), there are two fields - // spreadMode and interPolationMode which are same as in GRADIENT - writeUB(2, value.spreadMode); - writeUB(2, value.interPolationMode); - writeUB(4, value.gradientRecords.length); - for (int i = 0; i < value.gradientRecords.length; i++) { - writeMORPHGRADRECORD(value.gradientRecords[i]); - } - } - - /** - * Writes MORPHFOCALGRADIENT value to the stream - * - * Undocumented feature - * - * @param value MORPHGRADIENT value - * @param shapeNum 1 in DefineMorphShape, 2 in DefineMorphShape2,... - * @throws IOException - */ - public void writeMORPHFOCALGRADIENT(MORPHFOCALGRADIENT value, int shapeNum) throws IOException { - writeUB(2, value.spreadMode); - writeUB(2, value.interPolationMode); - writeUB(4, value.gradientRecords.length); - for (int i = 0; i < value.gradientRecords.length; i++) { - writeMORPHGRADRECORD(value.gradientRecords[i]); - } - writeFIXED8(value.startFocalPoint); - writeFIXED8(value.endFocalPoint); - } - - /** - * Writes MORPHGRADRECORD value to the stream - * - * @param value MORPHGRADRECORD value - * @throws IOException - */ - public void writeMORPHGRADRECORD(MORPHGRADRECORD value) throws IOException { - writeUI8(value.startRatio); - writeRGBA(value.startColor); - writeUI8(value.endRatio); - writeRGBA(value.endColor); - } - - /** - * Writes MORPHLINESTYLE value to the stream - * - * @param value LINESTYLE value - * @param shapeNum 1 in DefineMorphShape, 2 in DefineMorphShape2,... - * @throws IOException - */ - public void writeMORPHLINESTYLE(MORPHLINESTYLE value, int shapeNum) throws IOException { - writeUI16(value.startWidth); - writeUI16(value.endWidth); - writeRGBA(value.startColor); - writeRGBA(value.endColor); - - } - - /** - * Writes MORPHLINESTYLE2 value to the stream - * - * @param value MORPHLINESTYLE2 value - * @param shapeNum 1 in DefineMorphShape, 2 in DefineMorphShape2,... - * @throws IOException - */ - public void writeMORPHLINESTYLE2(MORPHLINESTYLE2 value, int shapeNum) throws IOException { - writeUI16(value.startWidth); - writeUI16(value.endWidth); - writeUB(2, value.startCapStyle); - writeUB(2, value.joinStyle); - writeUB(1, value.hasFillFlag ? 1 : 0); - writeUB(1, value.noHScaleFlag ? 1 : 0); - writeUB(1, value.noVScaleFlag ? 1 : 0); - writeUB(1, value.pixelHintingFlag ? 1 : 0); - writeUB(5, value.reserved); - writeUB(1, value.noClose ? 1 : 0); - writeUB(2, value.endCapStyle); - if (value.joinStyle == LINESTYLE2.MITER_JOIN) { - writeUI16(value.miterLimitFactor); - } - if (!value.hasFillFlag) { - writeRGBA(value.startColor); - writeRGBA(value.endColor); - } else { - writeMORPHFILLSTYLE(value.fillType, shapeNum); - } - } - - /** - * Writes MORPHLINESTYLEARRAY value to the stream - * - * @param value MORPHFILLSTYLEARRAY value - * @param morphShapeNum 1 in DefineMorphShape, 2 in DefineMorphShape2,... - * @throws IOException - */ - public void writeMORPHLINESTYLEARRAY(MORPHLINESTYLEARRAY value, int morphShapeNum) throws IOException { - int lineStyleCount; - if (morphShapeNum == 1) { - lineStyleCount = value.lineStyles.length; - if (lineStyleCount >= 0xff) { - writeUI8(0xff); - writeUI16(lineStyleCount); - } else { - writeUI8(lineStyleCount); - } - for (int i = 0; i < lineStyleCount; i++) { - writeMORPHLINESTYLE(value.lineStyles[i], morphShapeNum); - } - } else if (morphShapeNum == 2) { - lineStyleCount = value.lineStyles2.length; - if (lineStyleCount >= 0xff) { - writeUI8(0xff); - writeUI16(lineStyleCount); - } else { - writeUI8(lineStyleCount); - } - for (int i = 0; i < lineStyleCount; i++) { - writeMORPHLINESTYLE2(value.lineStyles2[i], morphShapeNum); - } - } - } - - /** - * Writes KERNINGRECORD value to the stream - * - * @param value KERNINGRECORD value - * @param fontFlagsWideCodes - * @throws IOException - */ - public void writeKERNINGRECORD(KERNINGRECORD value, boolean fontFlagsWideCodes) throws IOException { - if (fontFlagsWideCodes) { - writeUI16(value.fontKerningCode1); - writeUI16(value.fontKerningCode2); - } else { - writeUI8(value.fontKerningCode1); - writeUI8(value.fontKerningCode2); - } - writeSI16(value.fontKerningAdjustment); - } - - /** - * Writes LANGCODE value to the stream - * - * @param value LANGCODE value - * @throws IOException - */ - public void writeLANGCODE(LANGCODE value) throws IOException { - writeUI8(value.languageCode); - } - - /** - * Writes ZONERECORD value to the stream - * - * @param value ZONERECORD value - * @throws IOException - */ - public void writeZONERECORD(ZONERECORD value) throws IOException { - writeUI8(value.zonedata.length); - for (int i = 0; i < value.zonedata.length; i++) { - writeZONEDATA(value.zonedata[i]); - } - writeUB(6, 0); - writeUB(1, value.zoneMaskY ? 1 : 0); - writeUB(1, value.zoneMaskX ? 1 : 0); - } - - /** - * Writes ZONEDATA value to the stream - * - * @param value ZONEDATA value - * @throws IOException - */ - public void writeZONEDATA(ZONEDATA value) throws IOException { - writeUI16(value.alignmentCoordinate); - writeUI16(value.range); - } - - public void writeBytesZlib(byte[] data) throws IOException { - DeflaterOutputStream deflater = new DeflaterOutputStream(this, new Deflater(9)); - deflater.write(data); - deflater.finish(); - } - - /** - * Reads one BITMAPDATA value from the stream - * - * @param value - * @param bitmapFormat - * @param bitmapWidth - * @param bitmapHeight - * @throws IOException - */ - public void writeBITMAPDATA(BITMAPDATA value, int bitmapFormat, int bitmapWidth, int bitmapHeight) throws IOException { - int dataLen = 0; - int pos = 0; - for (int y = 0; y < bitmapHeight; y++) { - int x = 0; - for (; x < bitmapWidth; x++) { - if (bitmapFormat == DefineBitsLosslessTag.FORMAT_15BIT_RGB) { - dataLen += 2; - writePIX15(value.bitmapPixelDataPix15[pos]); - } - if (bitmapFormat == DefineBitsLosslessTag.FORMAT_24BIT_RGB) { - dataLen += 4; - writePIX24(value.bitmapPixelDataPix24[pos]); - } - pos++; - } - while ((dataLen % 4) != 0) { - dataLen++; - writeUI8(0); - } - } - } - - /** - * Reads one ALPHABITMAPDATA value from the stream - * - * @param value - * @param bitmapFormat - * @param bitmapWidth - * @param bitmapHeight - * @throws IOException - */ - public void writeALPHABITMAPDATA(ALPHABITMAPDATA value, int bitmapFormat, int bitmapWidth, int bitmapHeight) throws IOException { - int pos = 0; - for (int y = 0; y < bitmapHeight; y++) { - for (int x = 0; x < bitmapWidth; x++) { - writeARGB(value.bitmapPixelData[pos]); - pos++; - } - } - } - - /** - * Writes PIX24 value to the stream - * - * @param value PIX24 value - * @throws IOException - */ - public void writePIX24(PIX24 value) throws IOException { - writeUI8(value.reserved); - writeUI8(value.red); - writeUI8(value.green); - writeUI8(value.blue); - } - - /** - * Writes PIX15 value to the stream - * - * @param value PIX15 value - * @throws IOException - */ - public void writePIX15(PIX15 value) throws IOException { - writeUB(1, 0); - writeUB(5, value.red); - writeUB(5, value.green); - writeUB(5, value.blue); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash; + +import com.jpexs.decompiler.flash.configuration.Configuration; +import com.jpexs.decompiler.flash.tags.DefineBitsLosslessTag; +import com.jpexs.decompiler.flash.tags.Tag; +import com.jpexs.decompiler.flash.types.ALPHABITMAPDATA; +import com.jpexs.decompiler.flash.types.ARGB; +import com.jpexs.decompiler.flash.types.BITMAPDATA; +import com.jpexs.decompiler.flash.types.BUTTONCONDACTION; +import com.jpexs.decompiler.flash.types.BUTTONRECORD; +import com.jpexs.decompiler.flash.types.CLIPACTIONRECORD; +import com.jpexs.decompiler.flash.types.CLIPACTIONS; +import com.jpexs.decompiler.flash.types.CLIPEVENTFLAGS; +import com.jpexs.decompiler.flash.types.CXFORM; +import com.jpexs.decompiler.flash.types.CXFORMWITHALPHA; +import com.jpexs.decompiler.flash.types.FILLSTYLE; +import com.jpexs.decompiler.flash.types.FILLSTYLEARRAY; +import com.jpexs.decompiler.flash.types.FOCALGRADIENT; +import com.jpexs.decompiler.flash.types.GLYPHENTRY; +import com.jpexs.decompiler.flash.types.GRADIENT; +import com.jpexs.decompiler.flash.types.GRADRECORD; +import com.jpexs.decompiler.flash.types.KERNINGRECORD; +import com.jpexs.decompiler.flash.types.LANGCODE; +import com.jpexs.decompiler.flash.types.LINESTYLE; +import com.jpexs.decompiler.flash.types.LINESTYLE2; +import com.jpexs.decompiler.flash.types.LINESTYLEARRAY; +import com.jpexs.decompiler.flash.types.MATRIX; +import com.jpexs.decompiler.flash.types.MORPHFILLSTYLE; +import com.jpexs.decompiler.flash.types.MORPHFILLSTYLEARRAY; +import com.jpexs.decompiler.flash.types.MORPHFOCALGRADIENT; +import com.jpexs.decompiler.flash.types.MORPHGRADIENT; +import com.jpexs.decompiler.flash.types.MORPHGRADRECORD; +import com.jpexs.decompiler.flash.types.MORPHLINESTYLE; +import com.jpexs.decompiler.flash.types.MORPHLINESTYLE2; +import com.jpexs.decompiler.flash.types.MORPHLINESTYLEARRAY; +import com.jpexs.decompiler.flash.types.PIX15; +import com.jpexs.decompiler.flash.types.PIX24; +import com.jpexs.decompiler.flash.types.RECT; +import com.jpexs.decompiler.flash.types.RGB; +import com.jpexs.decompiler.flash.types.RGBA; +import com.jpexs.decompiler.flash.types.SHAPE; +import com.jpexs.decompiler.flash.types.SHAPEWITHSTYLE; +import com.jpexs.decompiler.flash.types.SOUNDENVELOPE; +import com.jpexs.decompiler.flash.types.SOUNDINFO; +import com.jpexs.decompiler.flash.types.TEXTRECORD; +import com.jpexs.decompiler.flash.types.ZONEDATA; +import com.jpexs.decompiler.flash.types.ZONERECORD; +import com.jpexs.decompiler.flash.types.filters.BEVELFILTER; +import com.jpexs.decompiler.flash.types.filters.BLURFILTER; +import com.jpexs.decompiler.flash.types.filters.COLORMATRIXFILTER; +import com.jpexs.decompiler.flash.types.filters.CONVOLUTIONFILTER; +import com.jpexs.decompiler.flash.types.filters.DROPSHADOWFILTER; +import com.jpexs.decompiler.flash.types.filters.FILTER; +import com.jpexs.decompiler.flash.types.filters.GLOWFILTER; +import com.jpexs.decompiler.flash.types.filters.GRADIENTBEVELFILTER; +import com.jpexs.decompiler.flash.types.filters.GRADIENTGLOWFILTER; +import com.jpexs.decompiler.flash.types.shaperecords.CurvedEdgeRecord; +import com.jpexs.decompiler.flash.types.shaperecords.EndShapeRecord; +import com.jpexs.decompiler.flash.types.shaperecords.SHAPERECORD; +import com.jpexs.decompiler.flash.types.shaperecords.StraightEdgeRecord; +import com.jpexs.decompiler.flash.types.shaperecords.StyleChangeRecord; +import com.jpexs.helpers.ByteArrayRange; +import com.jpexs.helpers.utf8.Utf8Helper; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.List; +import java.util.zip.Deflater; +import java.util.zip.DeflaterOutputStream; + +/** + * Class for writing data into SWF file + * + * @author JPEXS + */ +public class SWFOutputStream extends OutputStream { + + private final OutputStream os; + + private final int version; + + private long pos = 0; + + private int bitPos = 0; + + private int tempByte = 0; + + public long getPos() { + return pos; + } + + /** + * Constructor + * + * @param os OutputStream for writing data + * @param version Version of SWF + */ + public SWFOutputStream(OutputStream os, int version) { + this.version = version; + this.os = os; + } + + /** + * Writes byte to the stream + * + * @param b byte to write + * @throws IOException + */ + @Override + public void write(int b) throws IOException { + alignByte(); + os.write(b); + pos++; + } + + @Override + public void write(byte[] b) throws IOException { + alignByte(); + os.write(b); + pos += b.length; + } + + public void write(ByteArrayRange b) throws IOException { + alignByte(); + os.write(b.getArray(), b.getPos(), b.getLength()); + pos += b.getLength(); + } + + private void alignByte() throws IOException { + if (bitPos > 0) { + bitPos = 0; + write(tempByte); + tempByte = 0; + } + } + + /** + * Writes UI8 (Unsigned 8bit integer) value to the stream + * + * @param value UI8 value to write + * @throws IOException + */ + public void writeUI8(int value) throws IOException { + if (value > 0xff) { + throw new Error("Value is too large for UI8: " + value); + } + + write(value); + } + + /** + * Writes String value to the stream + * + * @param value String value + * @throws IOException + */ + public void writeString(String value) throws IOException { + byte[] data = Utf8Helper.getBytes(value); + for (int i = 0; i < data.length; i++) { + if (data[i] == 0) { + throw new IOException("String should not contain null character."); + } + } + + write(data); + write(0); + } + + /** + * Writes UI32 (Unsigned 32bit integer) value to the stream + * + * @param value UI32 value + * @throws IOException + */ + public void writeUI32(long value) throws IOException { + if (value > 0xffffffffL) { + throw new Error("Value is too large for UI32: " + value); + } + + write((int) (value & 0xff)); + write((int) ((value >> 8) & 0xff)); + write((int) ((value >> 16) & 0xff)); + write((int) ((value >> 24) & 0xff)); + } + + /** + * Writes UI16 (Unsigned 16bit integer) value to the stream + * + * @param value UI16 value + * @throws IOException + */ + public void writeUI16(int value) throws IOException { + if (value > 0xffff) { + throw new Error("Value is too large for UI16: " + value); + } + + write((int) (value & 0xff)); + write((int) ((value >> 8) & 0xff)); + } + + /** + * Writes SI32 (Signed 32bit integer) value to the stream + * + * @param value SI32 value + * @throws IOException + */ + public void writeSI32(long value) throws IOException { + if (value > 0x7fffffffL) { + throw new Error("Value is too large for SI32: " + value); + } + + writeUI32(value); + } + + /** + * Writes SI16 (Signed 16bit integer) value to the stream + * + * @param value SI16 value + * @throws IOException + */ + public void writeSI16(int value) throws IOException { + if (value > 0x7fff) { + throw new Error("Value is too large for SI16: " + value); + } + + writeUI16(value); + } + + /** + * Writes SI8 (Signed 8bit integer) value to the stream + * + * @param value SI8 value + * @throws IOException + */ + public void writeSI8(int value) throws IOException { + if (value > 0x7ff) { + throw new Error("Value is too large for SI8: " + value); + } + + writeUI8(value); + } + + /** + * Writes FIXED (Fixed point 16.16) value to the stream + * + * @param value FIXED value + * @throws IOException + */ + public void writeFIXED(double value) throws IOException { + long valueLong = (long) (value * (1 << 16)); + int beforePoint = (int) valueLong >> 16; + + int afterPoint = (int) valueLong % (1 << 16); + writeUI16(afterPoint); + writeUI16(beforePoint); + } + + /** + * Writes FIXED8 (Fixed point 8.8) value to the stream + * + * @param value FIXED8 value + * @throws IOException + */ + public void writeFIXED8(float value) throws IOException { + int beforePoint = (int) getIntPart(value); + int afterPoint = (int) getIntPart((value + (value < 0 ? beforePoint : -beforePoint)) * 256); + writeUI8(afterPoint); + writeUI8(beforePoint); + } + + private void writeLong(long value) throws IOException { + byte[] writeBuffer = new byte[8]; + writeBuffer[3] = (byte) (value >>> 56); + writeBuffer[2] = (byte) (value >>> 48); + writeBuffer[1] = (byte) (value >>> 40); + writeBuffer[0] = (byte) (value >>> 32); + writeBuffer[7] = (byte) (value >>> 24); + writeBuffer[6] = (byte) (value >>> 16); + writeBuffer[5] = (byte) (value >>> 8); + writeBuffer[4] = (byte) (value); + write(writeBuffer); + } + + /** + * Writes DOUBLE (double precision floating point value) value to the stream + * + * @param value DOUBLE value + * @throws IOException + */ + public void writeDOUBLE(double value) throws IOException { + writeLong(Double.doubleToLongBits(value)); + } + + /** + * Writes FLOAT (single precision floating point value) value to the stream + * + * @param value FLOAT value + * @throws IOException + */ + public void writeFLOAT(float value) throws IOException { + writeUI32(Float.floatToIntBits(value)); + } + + /** + * Writes FLOAT16 (16bit floating point value) value to the stream + * + * @param value FLOAT16 value + * @throws IOException + */ + public void writeFLOAT16(float value) throws IOException { + int bits = Float.floatToRawIntBits(value); + int sign = bits >> 31; + int exponent = (bits >> 22) & 0xff; + int mantisa = bits & 0x3FFFFF; + mantisa >>= 13; + writeUI16((sign << 15) + (exponent << 10) + mantisa); + } + + /** + * Writes EncodedU32 (Encoded unsigned 32bit value) value to the stream + * + * @param value U32 value + * @throws IOException + */ + public void writeEncodedU32(long value) throws IOException { + boolean loop = true; + value &= 0xFFFFFFFF; + do { + int ret = (int) (value & 0x7F); + if (value < 0x80) { + loop = false; + } + if (value > 0x7F) { + ret += 0x80; + } + write(ret); + value >>= 7; + } while (loop); + } + + /** + * Flushes data to underlying stream + * + * @throws IOException + */ + @Override + public void flush() throws IOException { + if (bitPos > 0) { + bitPos = 0; + write(tempByte); + tempByte = 0; + } + os.flush(); + } + + /** + * Closes the stream + * + * @throws IOException + */ + @Override + public void close() throws IOException { + flush(); + os.close(); + } + + /** + * Writes UB[nBits] (Unsigned-bit value) value to the stream + * + * @param nBits Number of bits which represent value + * @param value Unsigned value to write + * @throws IOException + */ + public void writeUB(int nBits, long value) throws IOException { + for (int bit = 0; bit < nBits; bit++) { + int nb = (int) ((value >> (nBits - 1 - bit)) & 1); + tempByte += nb * (1 << (7 - bitPos)); + bitPos++; + if (bitPos == 8) { + bitPos = 0; + write(tempByte); + tempByte = 0; + } + } + } + + /** + * Writes SB[nBits] (Signed-bit value) value to the stream + * + * @param nBits Number of bits which represent value + * @param value Signed value to write + * @throws IOException + */ + public void writeSB(int nBits, long value) throws IOException { + writeUB(nBits, value); + } + + /** + * Writes FB[nBits] (Signed fixed-point bit value) value to the stream + * + * @param nBits Number of bits which represent value + * @param value Double value to write + * @throws IOException + */ + public void writeFB(int nBits, double value) throws IOException { + if (nBits == 0) { + return; + } + long longVal = (long) (value * (1 << 16)); + writeSB(nBits, longVal); + } + + /** + * Writes RECT value to the stream + * + * @param value RECT value + * @throws IOException + */ + public void writeRECT(RECT value) throws IOException { + int nBits = 0; + int xMin = truncateTo31Bit(value.Xmin); + int xMax = truncateTo31Bit(value.Xmax); + int yMin = truncateTo31Bit(value.Ymin); + int yMax = truncateTo31Bit(value.Ymax); + nBits = enlargeBitCountS(nBits, xMin); + nBits = enlargeBitCountS(nBits, xMax); + nBits = enlargeBitCountS(nBits, yMin); + nBits = enlargeBitCountS(nBits, yMax); + + if (Configuration.debugCopy.get()) { + nBits = Math.max(nBits, value.nbits); + } + + writeUB(5, nBits); + writeSB(nBits, xMin); + writeSB(nBits, xMax); + writeSB(nBits, yMin); + writeSB(nBits, yMax); + alignByte(); + } + + private int truncateTo31Bit(int value) { + if (value > 0x3fffffff) { + value = 0x3fffffff; + } + if (value < -0x3fffffff) { + value = -0x3fffffff; + } + return value; + } + + /** + * Writes list of Tag values to the stream + * + * @param tags List of tag values + * @throws IOException + */ + public void writeTags(List tags) throws IOException { + for (Tag tag : tags) { + tag.writeTag(this); + } + } + + /** + * Calculates number of bits needed for representing unsigned value + * + * @param value Unsigned value + * @return Number of bits + */ + public static int getNeededBitsU(int value) { + value = Math.abs(value); + long x = 1; + int nBits; + + for (nBits = 1; nBits <= 64; nBits++) { + x <<= 1; + if (x > value) { + break; + } + } + return nBits; + } + + /** + * Calculates number of bits needed for representing signed value + * + * @param v Signed value + * @return Number of bits + */ + private static int getNeededBitsS(int v) { + int counter = 32; + int mask = 0x80000000; + final int val = (v < 0) ? -v : v; + while (((val & mask) == 0) && (counter > 0)) { + mask >>>= 1; + counter -= 1; + } + return counter + 1; + } + + /** + * Calculates number of bits needed for representing signed values + * + * @param first First Signed value + * @param params Next Signed values + * @return Number of bits + */ + public static int getNeededBitsS(int first, int... params) { + int nBits = 0; + nBits = enlargeBitCountS(nBits, first); + for (int i = 0; i < params.length; i++) { + nBits = enlargeBitCountS(nBits, params[i]); + } + return nBits; + } + + public static int getNeededBitsU(int first, int... params) { + int nBits = 0; + nBits = enlargeBitCountU(nBits, first); + for (int i = 0; i < params.length; i++) { + nBits = enlargeBitCountU(nBits, params[i]); + } + return nBits; + } + + private static long getIntPart(double value) { + if (value < 0) { + return (long) Math.ceil(value); + } + return (long) Math.floor(value); + } + + public static int unsignedSize(final int value) { + + final int val = (value < 0) ? -value - 1 : value; + int counter = 32; + int mask = 0x80000000; + + while (((val & mask) == 0) && (counter > 0)) { + mask >>>= 1; + counter -= 1; + } + return counter; + } + + /** + * Calculates number of bits needed for representing fixed-point value + * + * @param value Fixed-point value + * @return Number of bits + */ + public static int getNeededBitsF(float value) { + // 0.26213074 16bits + // 0.5 17bits + // 1.3476715 18bits + int k = (int) value; + return getNeededBitsS(k) + 16; + } + + public static int enlargeBitCountS(int currentBitCount, int value) { + if (value == 0) { + return currentBitCount; + } + int neededNew = getNeededBitsS(value); + if (neededNew > currentBitCount) { + return neededNew; + } + return currentBitCount; + } + + public static int enlargeBitCountU(int currentBitCount, int value) { + if (value == 0) { + return currentBitCount; + } + int neededNew = getNeededBitsU(value); + if (neededNew > currentBitCount) { + return neededNew; + } + return currentBitCount; + } + + /** + * Writes MATRIX value to the stream + * + * @param value MATRIX value + * @throws IOException + */ + public void writeMatrix(MATRIX value) throws IOException { + writeUB(1, value.hasScale ? 1 : 0); + if (value.hasScale) { + int nBits = 0; + nBits = enlargeBitCountS(nBits, value.scaleX); + nBits = enlargeBitCountS(nBits, value.scaleY); + + if (Configuration.debugCopy.get()) { + nBits = Math.max(nBits, value.nScaleBits); + } + + writeUB(5, nBits); + writeSB(nBits, value.scaleX); + writeSB(nBits, value.scaleY); + } + writeUB(1, value.hasRotate ? 1 : 0); + if (value.hasRotate) { + int nBits = 0; + nBits = enlargeBitCountS(nBits, value.rotateSkew0); + nBits = enlargeBitCountS(nBits, value.rotateSkew1); + + if (Configuration.debugCopy.get()) { + nBits = Math.max(nBits, value.nRotateBits); + } + + writeUB(5, nBits); + writeSB(nBits, value.rotateSkew0); + writeSB(nBits, value.rotateSkew1); + } + int NTranslateBits = 0; + NTranslateBits = enlargeBitCountS(NTranslateBits, value.translateX); + NTranslateBits = enlargeBitCountS(NTranslateBits, value.translateY); + + if (Configuration.debugCopy.get()) { + NTranslateBits = Math.max(NTranslateBits, value.nTranslateBits); + } + + writeUB(5, NTranslateBits); + + writeSB(NTranslateBits, value.translateX); + writeSB(NTranslateBits, value.translateY); + alignByte(); + + } + + /** + * Writes CXFORM value to the stream + * + * @param value CXFORM value + * @throws IOException + */ + public void writeCXFORM(CXFORM value) throws IOException { + writeUB(1, value.hasAddTerms ? 1 : 0); + writeUB(1, value.hasMultTerms ? 1 : 0); + int Nbits = 1; + if (value.hasMultTerms) { + Nbits = enlargeBitCountS(Nbits, value.redMultTerm); + Nbits = enlargeBitCountS(Nbits, value.greenMultTerm); + Nbits = enlargeBitCountS(Nbits, value.blueMultTerm); + } + if (value.hasAddTerms) { + Nbits = enlargeBitCountS(Nbits, value.redAddTerm); + Nbits = enlargeBitCountS(Nbits, value.greenAddTerm); + Nbits = enlargeBitCountS(Nbits, value.blueAddTerm); + } + + if (Configuration.debugCopy.get()) { + Nbits = Math.max(Nbits, value.nbits); + } + + writeUB(4, Nbits); + if (value.hasMultTerms) { + writeSB(Nbits, value.redMultTerm); + writeSB(Nbits, value.greenMultTerm); + writeSB(Nbits, value.blueMultTerm); + } + if (value.hasAddTerms) { + writeSB(Nbits, value.redAddTerm); + writeSB(Nbits, value.greenAddTerm); + writeSB(Nbits, value.blueAddTerm); + } + alignByte(); + } + + /** + * Writes CXFORMWITHALPHA value to the stream + * + * @param value CXFORMWITHALPHA value + * @throws IOException + */ + public void writeCXFORMWITHALPHA(CXFORMWITHALPHA value) throws IOException { + writeUB(1, value.hasAddTerms ? 1 : 0); + writeUB(1, value.hasMultTerms ? 1 : 0); + int Nbits = 1; + if (value.hasMultTerms) { + Nbits = enlargeBitCountS(Nbits, value.redMultTerm); + Nbits = enlargeBitCountS(Nbits, value.greenMultTerm); + Nbits = enlargeBitCountS(Nbits, value.blueMultTerm); + Nbits = enlargeBitCountS(Nbits, value.alphaMultTerm); + } + if (value.hasAddTerms) { + Nbits = enlargeBitCountS(Nbits, value.redAddTerm); + Nbits = enlargeBitCountS(Nbits, value.greenAddTerm); + Nbits = enlargeBitCountS(Nbits, value.blueAddTerm); + Nbits = enlargeBitCountS(Nbits, value.alphaAddTerm); + } + + if (Configuration.debugCopy.get()) { + Nbits = Math.max(Nbits, value.nbits); + } + + writeUB(4, Nbits); + if (value.hasMultTerms) { + writeSB(Nbits, value.redMultTerm); + writeSB(Nbits, value.greenMultTerm); + writeSB(Nbits, value.blueMultTerm); + writeSB(Nbits, value.alphaMultTerm); + } + if (value.hasAddTerms) { + writeSB(Nbits, value.redAddTerm); + writeSB(Nbits, value.greenAddTerm); + writeSB(Nbits, value.blueAddTerm); + writeSB(Nbits, value.alphaAddTerm); + } + alignByte(); + } + + /** + * Writes CLIPEVENTFLAGS value to the stream + * + * @param value CLIPEVENTFLAGS value + * @throws IOException + */ + public void writeCLIPEVENTFLAGS(CLIPEVENTFLAGS value) throws IOException { + writeUB(1, value.clipEventKeyUp ? 1 : 0); + writeUB(1, value.clipEventKeyDown ? 1 : 0); + writeUB(1, value.clipEventMouseUp ? 1 : 0); + writeUB(1, value.clipEventMouseDown ? 1 : 0); + writeUB(1, value.clipEventMouseMove ? 1 : 0); + writeUB(1, value.clipEventUnload ? 1 : 0); + writeUB(1, value.clipEventEnterFrame ? 1 : 0); + writeUB(1, value.clipEventLoad ? 1 : 0); + writeUB(1, value.clipEventDragOver ? 1 : 0); + writeUB(1, value.clipEventRollOut ? 1 : 0); + writeUB(1, value.clipEventRollOver ? 1 : 0); + writeUB(1, value.clipEventReleaseOutside ? 1 : 0); + writeUB(1, value.clipEventRelease ? 1 : 0); + writeUB(1, value.clipEventPress ? 1 : 0); + writeUB(1, value.clipEventInitialize ? 1 : 0); + writeUB(1, value.clipEventData ? 1 : 0); + if (version >= 6) { + writeUB(5, value.reserved); + writeUB(1, value.clipEventConstruct ? 1 : 0); + writeUB(1, value.clipEventKeyPress ? 1 : 0); + writeUB(1, value.clipEventDragOut ? 1 : 0); + writeUB(8, value.reserved2); + } + } + + /** + * Writes CLIPACTIONRECORD value to the stream + * + * @param value CLIPACTIONRECORD value + * @throws IOException + */ + public void writeCLIPACTIONRECORD(CLIPACTIONRECORD value) throws IOException { + writeCLIPEVENTFLAGS(value.eventFlags); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (SWFOutputStream sos = new SWFOutputStream(baos, version)) { + if (value.eventFlags.clipEventKeyPress) { + sos.writeUI8(value.keyCode); + } + sos.write(value.actionBytes); + } + byte[] data = baos.toByteArray(); + writeUI32(data.length); // actionRecordSize + write(data); + } + + /** + * Writes CLIPACTIONS value to the stream + * + * @param value CLIPACTIONS value + * @throws IOException + */ + public void writeCLIPACTIONS(CLIPACTIONS value) throws IOException { + writeUI16(value.reserved); + writeCLIPEVENTFLAGS(value.allEventFlags); + for (CLIPACTIONRECORD car : value.clipActionRecords) { + writeCLIPACTIONRECORD(car); + } + if (version <= 5) { + writeUI16(0); + } else { + writeUI32(0); + } + } + + /** + * Writes COLORMATRIXFILTER value to the stream + * + * @param value COLORMATRIXFILTER value + * @throws IOException + */ + public void writeCOLORMATRIXFILTER(COLORMATRIXFILTER value) throws IOException { + for (int i = 0; i < 20; i++) { + writeFLOAT(value.matrix[i]); + } + } + + /** + * Writes RGBA value to the stream + * + * @param value RGBA value + * @throws IOException + */ + public void writeRGBA(RGBA value) throws IOException { + writeUI8(value.red); + writeUI8(value.green); + writeUI8(value.blue); + writeUI8(value.alpha); + } + + /** + * Writes ARGB value to the stream + * + * @param value ARGB value + * @throws IOException + */ + public void writeARGB(ARGB value) throws IOException { + writeUI8(value.alpha); + writeUI8(value.red); + writeUI8(value.green); + writeUI8(value.blue); + } + + /** + * Writes RGB value to the stream + * + * @param value RGB value + * @throws IOException + */ + public void writeRGB(RGB value) throws IOException { + writeUI8(value.red); + writeUI8(value.green); + writeUI8(value.blue); + } + + /** + * Writes CONVOLUTIONFILTER value to the stream + * + * @param value CONVOLUTIONFILTER value + * @throws IOException + */ + public void writeCONVOLUTIONFILTER(CONVOLUTIONFILTER value) throws IOException { + writeUI8(value.matrixX); + writeUI8(value.matrixY); + writeFLOAT(value.divisor); + writeFLOAT(value.bias); + for (int x = 0; x < value.matrixX; x++) { + for (int y = 0; y < value.matrixY; y++) { + writeFLOAT(value.matrix[x][y]); + } + } + writeRGBA(value.defaultColor); + writeUB(6, value.reserved); + writeUB(1, value.clamp ? 1 : 0); + writeUB(1, value.preserveAlpha ? 1 : 0); + } + + /** + * Writes BLURFILTER value to the stream + * + * @param value BLURFILTER value + * @throws IOException + */ + public void writeBLURFILTER(BLURFILTER value) throws IOException { + writeFIXED(value.blurX); + writeFIXED(value.blurY); + writeUB(5, value.passes); + writeUB(3, value.reserved); + } + + /** + * Writes DROPSHADOWFILTER value to the stream + * + * @param value DROPSHADOWFILTER value + * @throws IOException + */ + public void writeDROPSHADOWFILTER(DROPSHADOWFILTER value) throws IOException { + writeRGBA(value.dropShadowColor); + writeFIXED(value.blurX); + writeFIXED(value.blurY); + writeFIXED(value.angle); + writeFIXED(value.distance); + writeFIXED8(value.strength); + writeUB(1, value.innerShadow ? 1 : 0); + writeUB(1, value.knockout ? 1 : 0); + writeUB(1, value.compositeSource ? 1 : 0); + writeUB(5, value.passes); + } + + /** + * Writes GLOWFILTER value to the stream + * + * @param value GLOWFILTER value + * @throws IOException + */ + public void writeGLOWFILTER(GLOWFILTER value) throws IOException { + writeRGBA(value.glowColor); + writeFIXED(value.blurX); + writeFIXED(value.blurY); + writeFIXED8(value.strength); + writeUB(1, value.innerGlow ? 1 : 0); + writeUB(1, value.knockout ? 1 : 0); + writeUB(1, value.compositeSource ? 1 : 0); + writeUB(5, value.passes); + } + + /** + * Writes BEVELFILTER value to the stream + * + * @param value BEVELFILTER value + * @throws IOException + */ + public void writeBEVELFILTER(BEVELFILTER value) throws IOException { + writeRGBA(value.highlightColor); + writeRGBA(value.shadowColor); + writeFIXED(value.blurX); + writeFIXED(value.blurY); + writeFIXED(value.angle); + writeFIXED(value.distance); + writeFIXED8(value.strength); + writeUB(1, value.innerShadow ? 1 : 0); + writeUB(1, value.knockout ? 1 : 0); + writeUB(1, value.compositeSource ? 1 : 0); + writeUB(1, value.onTop ? 1 : 0); + writeUB(4, value.passes); + } + + /** + * Writes GRADIENTGLOWFILTER value to the stream + * + * @param value GRADIENTGLOWFILTER value + * @throws IOException + */ + public void writeGRADIENTGLOWFILTER(GRADIENTGLOWFILTER value) throws IOException { + writeUI8(value.gradientColors.length); + for (int i = 0; i < value.gradientColors.length; i++) { + writeRGBA(value.gradientColors[i]); + } + for (int i = 0; i < value.gradientColors.length; i++) { + writeUI8(value.gradientRatio[i]); + } + writeFIXED(value.blurX); + writeFIXED(value.blurY); + writeFIXED(value.angle); + writeFIXED(value.distance); + writeFIXED8(value.strength); + writeUB(1, value.innerShadow ? 1 : 0); + writeUB(1, value.knockout ? 1 : 0); + writeUB(1, value.compositeSource ? 1 : 0); + writeUB(1, value.onTop ? 1 : 0); + writeUB(4, value.passes); + } + + /** + * Writes GRADIENTBEVELFILTER value to the stream + * + * @param value GRADIENTBEVELFILTER value + * @throws IOException + */ + public void writeGRADIENTBEVELFILTER(GRADIENTBEVELFILTER value) throws IOException { + writeUI8(value.gradientColors.length); + for (int i = 0; i < value.gradientColors.length; i++) { + writeRGBA(value.gradientColors[i]); + } + for (int i = 0; i < value.gradientColors.length; i++) { + writeUI8(value.gradientRatio[i]); + } + writeFIXED(value.blurX); + writeFIXED(value.blurY); + writeFIXED(value.angle); + writeFIXED(value.distance); + writeFIXED8(value.strength); + writeUB(1, value.innerShadow ? 1 : 0); + writeUB(1, value.knockout ? 1 : 0); + writeUB(1, value.compositeSource ? 1 : 0); + writeUB(1, value.onTop ? 1 : 0); + writeUB(4, value.passes); + } + + /** + * Writes list of FILTER values to the stream + * + * @param list List of FILTER values + * @throws IOException + */ + public void writeFILTERLIST(List list) throws IOException { + writeUI8(list.size()); + for (int i = 0; i < list.size(); i++) { + writeFILTER(list.get(i)); + } + } + + /** + * Writes FILTER value to the stream + * + * @param value FILTER value + * @throws IOException + */ + public void writeFILTER(FILTER value) throws IOException { + writeUI8(value.id); + if (value instanceof DROPSHADOWFILTER) { + writeDROPSHADOWFILTER((DROPSHADOWFILTER) value); + } + if (value instanceof BLURFILTER) { + writeBLURFILTER((BLURFILTER) value); + } + if (value instanceof GLOWFILTER) { + writeGLOWFILTER((GLOWFILTER) value); + } + if (value instanceof BEVELFILTER) { + writeBEVELFILTER((BEVELFILTER) value); + } + if (value instanceof GRADIENTGLOWFILTER) { + writeGRADIENTGLOWFILTER((GRADIENTGLOWFILTER) value); + } + if (value instanceof CONVOLUTIONFILTER) { + writeCONVOLUTIONFILTER((CONVOLUTIONFILTER) value); + } + if (value instanceof COLORMATRIXFILTER) { + writeCOLORMATRIXFILTER((COLORMATRIXFILTER) value); + } + if (value instanceof GRADIENTBEVELFILTER) { + writeGRADIENTBEVELFILTER((GRADIENTBEVELFILTER) value); + } + } + + /** + * Writes list of BUTTONRECORD values to the stream + * + * @param list List of BUTTONRECORD values + * @param inDefineButton2 Whether write inside of DefineButton2Tag or not + * @throws IOException + */ + public void writeBUTTONRECORDList(List list, boolean inDefineButton2) throws IOException { + for (BUTTONRECORD brec : list) { + writeBUTTONRECORD(brec, inDefineButton2); + } + writeUI8(0); + } + + /** + * Writes BUTTONRECORD value to the stream + * + * @param value BUTTONRECORD value + * @param inDefineButton2 Whether write inside of DefineButton2Tag or not + * @throws IOException + */ + public void writeBUTTONRECORD(BUTTONRECORD value, boolean inDefineButton2) throws IOException { + writeUB(2, value.reserved); + writeUB(1, value.buttonHasBlendMode ? 1 : 0); + writeUB(1, value.buttonHasFilterList ? 1 : 0); + writeUB(1, value.buttonStateHitTest ? 1 : 0); + writeUB(1, value.buttonStateDown ? 1 : 0); + writeUB(1, value.buttonStateOver ? 1 : 0); + writeUB(1, value.buttonStateUp ? 1 : 0); + writeUI16(value.characterId); + writeUI16(value.placeDepth); + writeMatrix(value.placeMatrix); + if (inDefineButton2) { + writeCXFORMWITHALPHA(value.colorTransform); + if (value.buttonHasFilterList) { + writeFILTERLIST(value.filterList); + } + if (value.buttonHasBlendMode) { + writeUI8(value.blendMode); + } + } + } + + /** + * Writes list of BUTTONCONDACTION values to the stream + * + * @param list List of BUTTONCONDACTION values + * @throws IOException + */ + public void writeBUTTONCONDACTIONList(List list) throws IOException { + for (int i = 0; i < list.size(); i++) { + writeBUTTONCONDACTION(list.get(i), i == list.size() - 1); + } + } + + /** + * Writes BUTTONCONDACTION value to the stream + * + * @param value BUTTONCONDACTION value + * @param isLast True if it is last on the list + * @throws IOException + */ + public void writeBUTTONCONDACTION(BUTTONCONDACTION value, boolean isLast) throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (SWFOutputStream sos = new SWFOutputStream(baos, version)) { + sos.writeUB(1, value.condIdleToOverDown ? 1 : 0); + sos.writeUB(1, value.condOutDownToIdle ? 1 : 0); + sos.writeUB(1, value.condOutDownToOverDown ? 1 : 0); + sos.writeUB(1, value.condOverDownToOutDown ? 1 : 0); + sos.writeUB(1, value.condOverDownToOverUp ? 1 : 0); + sos.writeUB(1, value.condOverUpToOverDown ? 1 : 0); + sos.writeUB(1, value.condOverUpToIddle ? 1 : 0); + sos.writeUB(1, value.condIdleToOverUp ? 1 : 0); + sos.writeUB(7, value.condKeyPress); + sos.writeUB(1, value.condOverDownToIdle ? 1 : 0); + sos.write(value.actionBytes); + } + byte[] data = baos.toByteArray(); + if (isLast) { + writeUI16(0); + } else { + writeUI16(data.length + 2); + } + write(data); + } + + /** + * Writes FILLSTYLE value to the stream + * + * @param value FILLSTYLE value + * @param shapeNum 1 in DefineShape, 2 in DefineShape2,... + * @throws IOException + */ + public void writeFILLSTYLE(FILLSTYLE value, int shapeNum) throws IOException { + writeUI8(value.fillStyleType); + if (value.fillStyleType == FILLSTYLE.SOLID) { + if (shapeNum >= 3) { + writeRGBA((RGBA) value.color); + } else if (shapeNum == 1 || shapeNum == 2) { + writeRGB(value.color); + } + } + if ((value.fillStyleType == FILLSTYLE.LINEAR_GRADIENT) + || (value.fillStyleType == FILLSTYLE.RADIAL_GRADIENT) + || (value.fillStyleType == FILLSTYLE.FOCAL_RADIAL_GRADIENT)) { + writeMatrix(value.gradientMatrix); + } + if ((value.fillStyleType == FILLSTYLE.LINEAR_GRADIENT) + || (value.fillStyleType == FILLSTYLE.RADIAL_GRADIENT)) { + writeGRADIENT(value.gradient, shapeNum); + } + if (value.fillStyleType == FILLSTYLE.FOCAL_RADIAL_GRADIENT) { + writeFOCALGRADIENT((FOCALGRADIENT) value.gradient, shapeNum); + } + + if ((value.fillStyleType == FILLSTYLE.REPEATING_BITMAP) + || (value.fillStyleType == FILLSTYLE.CLIPPED_BITMAP) + || (value.fillStyleType == FILLSTYLE.NON_SMOOTHED_REPEATING_BITMAP) + || (value.fillStyleType == FILLSTYLE.NON_SMOOTHED_CLIPPED_BITMAP)) { + writeUI16(value.bitmapId); + writeMatrix(value.bitmapMatrix); + } + } + + /** + * Writes FILLSTYLEARRAY value to the stream + * + * @param value FILLSTYLEARRAY value + * @param shapeNum 1 in DefineShape, 2 in DefineShape2,... + * @throws IOException + */ + public void writeFILLSTYLEARRAY(FILLSTYLEARRAY value, int shapeNum) throws IOException { + int fillStyleCount = value.fillStyles.length; + if (shapeNum == 2 || shapeNum == 3) { + if (fillStyleCount >= 0xff) { + writeUI8(0xff); + writeUI16(fillStyleCount); + } else { + writeUI8(fillStyleCount); + } + } else { + writeUI8(fillStyleCount); + } + for (int i = 0; i < value.fillStyles.length; i++) { + writeFILLSTYLE(value.fillStyles[i], shapeNum); + } + } + + /** + * Writes FOCALGRADIENT value to the stream + * + * @param value FILLSTYLEARRAY value + * @param shapeNum 1 in DefineShape, 2 in DefineShape2,... + * @throws IOException + */ + public void writeFOCALGRADIENT(FOCALGRADIENT value, int shapeNum) throws IOException { + writeUB(2, value.spreadMode); + writeUB(2, value.interpolationMode); + writeUB(4, value.gradientRecords.length); + for (int i = 0; i < value.gradientRecords.length; i++) { + writeGRADRECORD(value.gradientRecords[i], shapeNum); + } + writeFIXED8(value.focalPoint); + } + + /** + * Writes GRADIENT value to the stream + * + * @param value GRADIENT value + * @param shapeNum 1 in DefineShape, 2 in DefineShape2,... + * @throws IOException + */ + public void writeGRADIENT(GRADIENT value, int shapeNum) throws IOException { + writeUB(2, value.spreadMode); + writeUB(2, value.interpolationMode); + writeUB(4, value.gradientRecords.length); + for (int i = 0; i < value.gradientRecords.length; i++) { + writeGRADRECORD(value.gradientRecords[i], shapeNum); + } + } + + /** + * Writes GRADRECORD value to the stream + * + * @param value GRADRECORD value + * @param shapeNum 1 in DefineShape, 2 in DefineShape2,... + * @throws IOException + */ + public void writeGRADRECORD(GRADRECORD value, int shapeNum) throws IOException { + writeUI8(value.ratio); + if (shapeNum >= 3) { + writeRGBA((RGBA) value.color); + } else { + writeRGB(value.color); + } + } + + /** + * Writes LINESTYLE value to the stream + * + * @param value LINESTYLE value + * @param shapeNum 1 in DefineShape, 2 in DefineShape2,... + * @throws IOException + */ + public void writeLINESTYLE(LINESTYLE value, int shapeNum) throws IOException { + writeUI16(value.width); + if (shapeNum == 1 || shapeNum == 2) { + writeRGB(value.color); + } else if (shapeNum == 3) { + writeRGBA((RGBA) value.color); + } + } + + /** + * Writes LINESTYLE2 value to the stream + * + * @param value LINESTYLE2 value + * @param shapeNum 1 in DefineShape, 2 in DefineShape2,... + * @throws IOException + */ + public void writeLINESTYLE2(LINESTYLE2 value, int shapeNum) throws IOException { + writeUI16(value.width); + writeUB(2, value.startCapStyle); + writeUB(2, value.joinStyle); + writeUB(1, value.hasFillFlag ? 1 : 0); + writeUB(1, value.noHScaleFlag ? 1 : 0); + writeUB(1, value.noVScaleFlag ? 1 : 0); + writeUB(1, value.pixelHintingFlag ? 1 : 0); + writeUB(5, value.reserved); + writeUB(1, value.noClose ? 1 : 0); + writeUB(2, value.endCapStyle); + if (value.joinStyle == LINESTYLE2.MITER_JOIN) { + writeUI16(value.miterLimitFactor); + } + if (!value.hasFillFlag) { + writeRGBA((RGBA) value.color); + } else { + writeFILLSTYLE(value.fillType, shapeNum); + } + } + + /** + * Writes LINESTYLEARRAY value to the stream + * + * @param value FILLSTYLEARRAY value + * @param shapeNum 1 in DefineShape, 2 in DefineShape2,... + * @throws IOException + */ + public void writeLINESTYLEARRAY(LINESTYLEARRAY value, int shapeNum) throws IOException { + int lineStyleCount; + if (shapeNum == 1 || shapeNum == 2 || shapeNum == 3) { + lineStyleCount = value.lineStyles.length; + if (lineStyleCount >= 0xff) { + writeUI8(0xff); + writeUI16(lineStyleCount); + } else { + writeUI8(lineStyleCount); + } + for (int i = 0; i < lineStyleCount; i++) { + writeLINESTYLE(value.lineStyles[i], shapeNum); + } + } else if (shapeNum == 4) { + lineStyleCount = value.lineStyles.length; + if (lineStyleCount >= 0xff) { + writeUI8(0xff); + writeUI16(lineStyleCount); + } else { + writeUI8(lineStyleCount); + } + for (int i = 0; i < lineStyleCount; i++) { + writeLINESTYLE2((LINESTYLE2) value.lineStyles[i], shapeNum); + } + } + } + + /** + * Writes SHAPE value to the stream + * + * @param value SHAPE value + * @param shapeNum 1 in DefineShape, 2 in DefineShape2,... + * @throws IOException + */ + public void writeSHAPE(SHAPE value, int shapeNum) throws IOException { + writeUB(4, value.numFillBits); + writeUB(4, value.numLineBits); + writeSHAPERECORDS(value.shapeRecords, value.numFillBits, value.numLineBits, shapeNum); + } + + /** + * Writes SHAPEWITHSTYLE value to the stream + * + * @param value SHAPEWITHSTYLE value + * @param shapeNum 1 in DefineShape, 2 in DefineShape2,... + * @throws IOException + */ + public void writeSHAPEWITHSTYLE(SHAPEWITHSTYLE value, int shapeNum) throws IOException { + writeFILLSTYLEARRAY(value.fillStyles, shapeNum); + writeLINESTYLEARRAY(value.lineStyles, shapeNum); + value.numFillBits = getNeededBitsU(value.fillStyles.fillStyles.length); + value.numLineBits = getNeededBitsU(value.lineStyles.lineStyles.length); + writeUB(4, value.numFillBits); + writeUB(4, value.numLineBits); + writeSHAPERECORDS(value.shapeRecords, value.numFillBits, value.numLineBits, shapeNum); + } + + /** + * Writes SHAPERECORDs value to the stream + * + * @param value SHAPERECORDS value + * @param fillBits + * @param lineBits + * @param shapeNum 1 in DefineShape, 2 in DefineShape2,... + * @throws IOException + */ + private void writeSHAPERECORDS(List value, int fillBits, int lineBits, int shapeNum) throws IOException { + for (SHAPERECORD sh : value) { + if (sh instanceof CurvedEdgeRecord) { + CurvedEdgeRecord cer = (CurvedEdgeRecord) sh; + writeUB(1, 1); // typeFlag + writeUB(1, 0); // curvedEdge + cer.numBits = Math.max(getNeededBitsS(cer.controlDeltaX, cer.controlDeltaY, cer.anchorDeltaX, cer.anchorDeltaY) - 2, 0); + writeUB(4, cer.numBits); + writeSB(cer.numBits + 2, cer.controlDeltaX); + writeSB(cer.numBits + 2, cer.controlDeltaY); + writeSB(cer.numBits + 2, cer.anchorDeltaX); + writeSB(cer.numBits + 2, cer.anchorDeltaY); + } else if (sh instanceof StraightEdgeRecord) { + StraightEdgeRecord ser = (StraightEdgeRecord) sh; + writeUB(1, 1); // typeFlag + writeUB(1, 1); // straightEdge + ser.numBits = Math.max(getNeededBitsS(ser.deltaX, ser.deltaY) - 2, 0); + writeUB(4, ser.numBits); + writeUB(1, ser.generalLineFlag ? 1 : 0); + if (!ser.generalLineFlag) { + writeUB(1, ser.vertLineFlag ? 1 : 0); + } + if (ser.generalLineFlag || (!ser.vertLineFlag)) { + writeSB(ser.numBits + 2, ser.deltaX); + } + if (ser.generalLineFlag || ser.vertLineFlag) { + writeSB(ser.numBits + 2, ser.deltaY); + } + } else if (sh instanceof StyleChangeRecord) { + StyleChangeRecord scr = (StyleChangeRecord) sh; + writeUB(1, 0); // typeFlag + writeUB(1, scr.stateNewStyles ? 1 : 0); + writeUB(1, scr.stateLineStyle ? 1 : 0); + writeUB(1, scr.stateFillStyle1 ? 1 : 0); + writeUB(1, scr.stateFillStyle0 ? 1 : 0); + writeUB(1, scr.stateMoveTo ? 1 : 0); + if (scr.stateMoveTo) { + scr.moveBits = getNeededBitsS(scr.moveDeltaX, scr.moveDeltaY); + writeUB(5, scr.moveBits); + writeSB(scr.moveBits, scr.moveDeltaX); + writeSB(scr.moveBits, scr.moveDeltaY); + } + if (scr.stateFillStyle0) { + writeUB(fillBits, scr.fillStyle0); + } + if (scr.stateFillStyle1) { + writeUB(fillBits, scr.fillStyle1); + } + if (scr.stateLineStyle) { + writeUB(lineBits, scr.lineStyle); + } + if (scr.stateNewStyles) { + writeFILLSTYLEARRAY(scr.fillStyles, shapeNum); + writeLINESTYLEARRAY(scr.lineStyles, shapeNum); + scr.numFillBits = getNeededBitsU(scr.fillStyles.fillStyles.length); + scr.numLineBits = getNeededBitsU(scr.lineStyles.lineStyles.length); + fillBits = scr.numFillBits; + lineBits = scr.numLineBits; + writeUB(4, scr.numFillBits); + writeUB(4, scr.numLineBits); + } + + } else if (sh instanceof EndShapeRecord) { + writeUB(1, 0); // typeFlag + writeUB(5, 0); // end of shape flag + } + } + alignByte(); + } + + /** + * Writes SOUNDINFO value to the stream + * + * @param value SOUNDINFO value + * @throws IOException + */ + public void writeSOUNDINFO(SOUNDINFO value) throws IOException { + writeUB(2, value.reserved); + writeUB(1, value.syncStop ? 1 : 0); + writeUB(1, value.syncNoMultiple ? 1 : 0); + writeUB(1, value.hasEnvelope ? 1 : 0); + writeUB(1, value.hasLoops ? 1 : 0); + writeUB(1, value.hasOutPoint ? 1 : 0); + writeUB(1, value.hasInPoint ? 1 : 0); + if (value.hasInPoint) { + writeUI32(value.inPoint); + } + if (value.hasOutPoint) { + writeUI32(value.outPoint); + } + if (value.hasLoops) { + writeUI16(value.loopCount); + } + if (value.hasEnvelope) { + writeUI8(value.envelopeRecords.length); + for (SOUNDENVELOPE env : value.envelopeRecords) { + writeSOUNDENVELOPE(env); + } + } + } + + /** + * Writes SOUNDENVELOPE value to the stream + * + * @param value SOUNDENVELOPE value + * @throws IOException + */ + public void writeSOUNDENVELOPE(SOUNDENVELOPE value) throws IOException { + writeUI32(value.pos44); + writeUI16(value.leftLevel); + writeUI16(value.rightLevel); + } + + /** + * Writes TEXTRECORD value to the stream + * + * @param value TEXTRECORD value + * @param inDefineText2 + * @param glyphBits + * @param advanceBits + * @throws IOException + */ + public void writeTEXTRECORD(TEXTRECORD value, boolean inDefineText2, int glyphBits, int advanceBits) throws IOException { + writeUB(1, 1); + writeUB(3, 0); + writeUB(1, value.styleFlagsHasFont ? 1 : 0); + writeUB(1, value.styleFlagsHasColor ? 1 : 0); + writeUB(1, value.styleFlagsHasYOffset ? 1 : 0); + writeUB(1, value.styleFlagsHasXOffset ? 1 : 0); + if (value.styleFlagsHasFont) { + writeUI16(value.fontId); + } + if (value.styleFlagsHasColor) { + if (inDefineText2) { + writeRGBA(value.textColorA); + } else { + writeRGB(value.textColor); + } + } + if (value.styleFlagsHasXOffset) { + writeSI16(value.xOffset); + } + if (value.styleFlagsHasYOffset) { + writeSI16(value.yOffset); + } + if (value.styleFlagsHasFont) { + writeUI16(value.textHeight); + } + writeUI8(value.glyphEntries.size()); + for (GLYPHENTRY ge : value.glyphEntries) { + writeGLYPHENTRY(ge, glyphBits, advanceBits); + } + alignByte(); + } + + /** + * Writes GLYPHENTRY value to the stream + * + * @param value GLYPHENTRY value + * @param glyphBits + * @param advanceBits + * @throws IOException + */ + public void writeGLYPHENTRY(GLYPHENTRY value, int glyphBits, int advanceBits) throws IOException { + writeUB(glyphBits, value.glyphIndex); + writeSB(advanceBits, value.glyphAdvance); + } + + /** + * Writes MORPHFILLSTYLE value to the stream + * + * @param value MORPHFILLSTYLE value + * @param shapeNum 1 in DefineMorphShape, 2 in DefineMorphShape2,... + * @throws IOException + */ + public void writeMORPHFILLSTYLE(MORPHFILLSTYLE value, int shapeNum) throws IOException { + writeUI8(value.fillStyleType); + if (value.fillStyleType == MORPHFILLSTYLE.SOLID) { + writeRGBA(value.startColor); + writeRGBA(value.endColor); + } + if ((value.fillStyleType == MORPHFILLSTYLE.LINEAR_GRADIENT) + || (value.fillStyleType == MORPHFILLSTYLE.RADIAL_GRADIENT) + || (value.fillStyleType == MORPHFILLSTYLE.FOCAL_RADIAL_GRADIENT)) { + writeMatrix(value.startGradientMatrix); + writeMatrix(value.endGradientMatrix); + } + if ((value.fillStyleType == MORPHFILLSTYLE.LINEAR_GRADIENT) + || (value.fillStyleType == MORPHFILLSTYLE.RADIAL_GRADIENT)) { + writeMORPHGRADIENT(value.gradient, shapeNum); + } + if (value.fillStyleType == MORPHFILLSTYLE.FOCAL_RADIAL_GRADIENT) { + writeMORPHFOCALGRADIENT((MORPHFOCALGRADIENT) value.gradient, shapeNum); + } + + if ((value.fillStyleType == MORPHFILLSTYLE.REPEATING_BITMAP) + || (value.fillStyleType == MORPHFILLSTYLE.CLIPPED_BITMAP) + || (value.fillStyleType == MORPHFILLSTYLE.NON_SMOOTHED_REPEATING_BITMAP) + || (value.fillStyleType == MORPHFILLSTYLE.NON_SMOOTHED_CLIPPED_BITMAP)) { + writeUI16(value.bitmapId); + writeMatrix(value.startBitmapMatrix); + writeMatrix(value.endBitmapMatrix); + } + } + + /** + * WritesMORPH FILLSTYLEARRAY value to the stream + * + * @param value MORPHFILLSTYLEARRAY value + * @param morphShapeNum 1 on DefineMorphShape, 2 on DefineMorphShape + * @throws IOException + */ + public void writeMORPHFILLSTYLEARRAY(MORPHFILLSTYLEARRAY value, int morphShapeNum) throws IOException { + int fillStyleCount = value.fillStyles.length; + if (fillStyleCount >= 0xff) { + writeUI8(0xff); + writeUI16(fillStyleCount); + } else { + writeUI8(fillStyleCount); + } + for (int i = 0; i < value.fillStyles.length; i++) { + writeMORPHFILLSTYLE(value.fillStyles[i], morphShapeNum); + } + } + + /** + * Writes MORPHGRADIENT value to the stream + * + * @param value MORPHGRADIENT value + * @param shapeNum 1 in DefineMorphShape, 2 in DefineMorphShape2,... + * @throws IOException + */ + public void writeMORPHGRADIENT(MORPHGRADIENT value, int shapeNum) throws IOException { + // Despite of documentation (UI8 1-8), there are two fields + // spreadMode and interPolationMode which are same as in GRADIENT + writeUB(2, value.spreadMode); + writeUB(2, value.interPolationMode); + writeUB(4, value.gradientRecords.length); + for (int i = 0; i < value.gradientRecords.length; i++) { + writeMORPHGRADRECORD(value.gradientRecords[i]); + } + } + + /** + * Writes MORPHFOCALGRADIENT value to the stream + * + * Undocumented feature + * + * @param value MORPHGRADIENT value + * @param shapeNum 1 in DefineMorphShape, 2 in DefineMorphShape2,... + * @throws IOException + */ + public void writeMORPHFOCALGRADIENT(MORPHFOCALGRADIENT value, int shapeNum) throws IOException { + writeUB(2, value.spreadMode); + writeUB(2, value.interPolationMode); + writeUB(4, value.gradientRecords.length); + for (int i = 0; i < value.gradientRecords.length; i++) { + writeMORPHGRADRECORD(value.gradientRecords[i]); + } + writeFIXED8(value.startFocalPoint); + writeFIXED8(value.endFocalPoint); + } + + /** + * Writes MORPHGRADRECORD value to the stream + * + * @param value MORPHGRADRECORD value + * @throws IOException + */ + public void writeMORPHGRADRECORD(MORPHGRADRECORD value) throws IOException { + writeUI8(value.startRatio); + writeRGBA(value.startColor); + writeUI8(value.endRatio); + writeRGBA(value.endColor); + } + + /** + * Writes MORPHLINESTYLE value to the stream + * + * @param value LINESTYLE value + * @param shapeNum 1 in DefineMorphShape, 2 in DefineMorphShape2,... + * @throws IOException + */ + public void writeMORPHLINESTYLE(MORPHLINESTYLE value, int shapeNum) throws IOException { + writeUI16(value.startWidth); + writeUI16(value.endWidth); + writeRGBA(value.startColor); + writeRGBA(value.endColor); + + } + + /** + * Writes MORPHLINESTYLE2 value to the stream + * + * @param value MORPHLINESTYLE2 value + * @param shapeNum 1 in DefineMorphShape, 2 in DefineMorphShape2,... + * @throws IOException + */ + public void writeMORPHLINESTYLE2(MORPHLINESTYLE2 value, int shapeNum) throws IOException { + writeUI16(value.startWidth); + writeUI16(value.endWidth); + writeUB(2, value.startCapStyle); + writeUB(2, value.joinStyle); + writeUB(1, value.hasFillFlag ? 1 : 0); + writeUB(1, value.noHScaleFlag ? 1 : 0); + writeUB(1, value.noVScaleFlag ? 1 : 0); + writeUB(1, value.pixelHintingFlag ? 1 : 0); + writeUB(5, value.reserved); + writeUB(1, value.noClose ? 1 : 0); + writeUB(2, value.endCapStyle); + if (value.joinStyle == LINESTYLE2.MITER_JOIN) { + writeUI16(value.miterLimitFactor); + } + if (!value.hasFillFlag) { + writeRGBA(value.startColor); + writeRGBA(value.endColor); + } else { + writeMORPHFILLSTYLE(value.fillType, shapeNum); + } + } + + /** + * Writes MORPHLINESTYLEARRAY value to the stream + * + * @param value MORPHFILLSTYLEARRAY value + * @param morphShapeNum 1 in DefineMorphShape, 2 in DefineMorphShape2,... + * @throws IOException + */ + public void writeMORPHLINESTYLEARRAY(MORPHLINESTYLEARRAY value, int morphShapeNum) throws IOException { + int lineStyleCount; + if (morphShapeNum == 1) { + lineStyleCount = value.lineStyles.length; + if (lineStyleCount >= 0xff) { + writeUI8(0xff); + writeUI16(lineStyleCount); + } else { + writeUI8(lineStyleCount); + } + for (int i = 0; i < lineStyleCount; i++) { + writeMORPHLINESTYLE(value.lineStyles[i], morphShapeNum); + } + } else if (morphShapeNum == 2) { + lineStyleCount = value.lineStyles2.length; + if (lineStyleCount >= 0xff) { + writeUI8(0xff); + writeUI16(lineStyleCount); + } else { + writeUI8(lineStyleCount); + } + for (int i = 0; i < lineStyleCount; i++) { + writeMORPHLINESTYLE2(value.lineStyles2[i], morphShapeNum); + } + } + } + + /** + * Writes KERNINGRECORD value to the stream + * + * @param value KERNINGRECORD value + * @param fontFlagsWideCodes + * @throws IOException + */ + public void writeKERNINGRECORD(KERNINGRECORD value, boolean fontFlagsWideCodes) throws IOException { + if (fontFlagsWideCodes) { + writeUI16(value.fontKerningCode1); + writeUI16(value.fontKerningCode2); + } else { + writeUI8(value.fontKerningCode1); + writeUI8(value.fontKerningCode2); + } + writeSI16(value.fontKerningAdjustment); + } + + /** + * Writes LANGCODE value to the stream + * + * @param value LANGCODE value + * @throws IOException + */ + public void writeLANGCODE(LANGCODE value) throws IOException { + writeUI8(value.languageCode); + } + + /** + * Writes ZONERECORD value to the stream + * + * @param value ZONERECORD value + * @throws IOException + */ + public void writeZONERECORD(ZONERECORD value) throws IOException { + writeUI8(value.zonedata.length); + for (int i = 0; i < value.zonedata.length; i++) { + writeZONEDATA(value.zonedata[i]); + } + writeUB(6, 0); + writeUB(1, value.zoneMaskY ? 1 : 0); + writeUB(1, value.zoneMaskX ? 1 : 0); + } + + /** + * Writes ZONEDATA value to the stream + * + * @param value ZONEDATA value + * @throws IOException + */ + public void writeZONEDATA(ZONEDATA value) throws IOException { + writeUI16(value.alignmentCoordinate); + writeUI16(value.range); + } + + public void writeBytesZlib(byte[] data) throws IOException { + DeflaterOutputStream deflater = new DeflaterOutputStream(this, new Deflater(9)); + deflater.write(data); + deflater.finish(); + } + + /** + * Reads one BITMAPDATA value from the stream + * + * @param value + * @param bitmapFormat + * @param bitmapWidth + * @param bitmapHeight + * @throws IOException + */ + public void writeBITMAPDATA(BITMAPDATA value, int bitmapFormat, int bitmapWidth, int bitmapHeight) throws IOException { + int dataLen = 0; + int pos = 0; + for (int y = 0; y < bitmapHeight; y++) { + int x = 0; + for (; x < bitmapWidth; x++) { + if (bitmapFormat == DefineBitsLosslessTag.FORMAT_15BIT_RGB) { + dataLen += 2; + writePIX15(value.bitmapPixelDataPix15[pos]); + } + if (bitmapFormat == DefineBitsLosslessTag.FORMAT_24BIT_RGB) { + dataLen += 4; + writePIX24(value.bitmapPixelDataPix24[pos]); + } + pos++; + } + while ((dataLen % 4) != 0) { + dataLen++; + writeUI8(0); + } + } + } + + /** + * Reads one ALPHABITMAPDATA value from the stream + * + * @param value + * @param bitmapFormat + * @param bitmapWidth + * @param bitmapHeight + * @throws IOException + */ + public void writeALPHABITMAPDATA(ALPHABITMAPDATA value, int bitmapFormat, int bitmapWidth, int bitmapHeight) throws IOException { + int pos = 0; + for (int y = 0; y < bitmapHeight; y++) { + for (int x = 0; x < bitmapWidth; x++) { + writeARGB(value.bitmapPixelData[pos]); + pos++; + } + } + } + + /** + * Writes PIX24 value to the stream + * + * @param value PIX24 value + * @throws IOException + */ + public void writePIX24(PIX24 value) throws IOException { + writeUI8(value.reserved); + writeUI8(value.red); + writeUI8(value.green); + writeUI8(value.blue); + } + + /** + * Writes PIX15 value to the stream + * + * @param value PIX15 value + * @throws IOException + */ + public void writePIX15(PIX15 value) throws IOException { + writeUB(1, 0); + writeUB(5, value.red); + writeUB(5, value.green); + writeUB(5, value.blue); + } +} 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 5283fc0a7..4692f7eb3 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 @@ -1,1271 +1,1271 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc; - -import com.jpexs.decompiler.flash.EventListener; -import com.jpexs.decompiler.flash.SWF; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Deobfuscation; -import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; -import com.jpexs.decompiler.flash.abc.avm2.instructions.executing.CallPropertyIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushStringIns; -import com.jpexs.decompiler.flash.abc.avm2.parser.AVM2ParseException; -import com.jpexs.decompiler.flash.abc.avm2.parser.script.ActionScriptParser; -import com.jpexs.decompiler.flash.abc.types.ABCException; -import com.jpexs.decompiler.flash.abc.types.ClassInfo; -import com.jpexs.decompiler.flash.abc.types.InstanceInfo; -import com.jpexs.decompiler.flash.abc.types.MetadataInfo; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.flash.abc.types.Multiname; -import com.jpexs.decompiler.flash.abc.types.Namespace; -import com.jpexs.decompiler.flash.abc.types.NamespaceSet; -import com.jpexs.decompiler.flash.abc.types.ScriptInfo; -import com.jpexs.decompiler.flash.abc.types.traits.Trait; -import com.jpexs.decompiler.flash.abc.types.traits.TraitClass; -import com.jpexs.decompiler.flash.abc.types.traits.TraitFunction; -import com.jpexs.decompiler.flash.abc.types.traits.TraitMethodGetterSetter; -import com.jpexs.decompiler.flash.abc.types.traits.TraitSlotConst; -import com.jpexs.decompiler.flash.abc.types.traits.Traits; -import com.jpexs.decompiler.flash.abc.usages.ClassNameMultinameUsage; -import com.jpexs.decompiler.flash.abc.usages.ConstVarNameMultinameUsage; -import com.jpexs.decompiler.flash.abc.usages.ConstVarTypeMultinameUsage; -import com.jpexs.decompiler.flash.abc.usages.DefinitionUsage; -import com.jpexs.decompiler.flash.abc.usages.ExtendsMultinameUsage; -import com.jpexs.decompiler.flash.abc.usages.ImplementsMultinameUsage; -import com.jpexs.decompiler.flash.abc.usages.MethodBodyMultinameUsage; -import com.jpexs.decompiler.flash.abc.usages.MethodNameMultinameUsage; -import com.jpexs.decompiler.flash.abc.usages.MethodParamsMultinameUsage; -import com.jpexs.decompiler.flash.abc.usages.MethodReturnTypeMultinameUsage; -import com.jpexs.decompiler.flash.abc.usages.MultinameUsage; -import com.jpexs.decompiler.flash.abc.usages.TypeNameMultinameUsage; -import com.jpexs.decompiler.flash.helpers.SWFDecompilerPlugin; -import com.jpexs.decompiler.flash.tags.ABCContainerTag; -import com.jpexs.decompiler.flash.tags.Tag; -import com.jpexs.decompiler.flash.types.annotations.Internal; -import com.jpexs.decompiler.graph.CompilationException; -import com.jpexs.helpers.utf8.Utf8PrintWriter; -import java.io.IOException; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.logging.Level; -import java.util.logging.Logger; - -public class ABC { - - public int major_version = 46; - - public int minor_version = 16; - - public AVM2ConstantPool constants = new AVM2ConstantPool(); - - public List method_info = new ArrayList<>(); - - public List metadata_info = new ArrayList<>(); - - public List instance_info = new ArrayList<>(); - - public List class_info = new ArrayList<>(); - - public List script_info = new ArrayList<>(); - - public List bodies = new ArrayList<>(); - - private Map bodyIdxFromMethodIdx; - - private long[] stringOffsets; - - public static final int MINORwithDECIMAL = 17; - - protected Set listeners = new HashSet<>(); - - private static final Logger logger = Logger.getLogger(ABC.class.getName()); - - private AVM2Deobfuscation deobfuscation; - - @Internal - public ABCContainerTag parentTag; - - /* Map from multiname index of namespace value to namespace name**/ - private Map namespaceMap; - - public ABC(ABCContainerTag tag) { - this.parentTag = tag; - this.deobfuscation = null; - constants.constant_double.add(null); - constants.constant_int.add(null); - constants.constant_uint.add(null); - constants.constant_string.add(null); - constants.constant_multiname.add(null); - constants.constant_namespace.add(null); - constants.constant_namespace_set.add(null); - } - - public SWF getSwf() { - return parentTag.getSwf(); - } - - public List getAbcTags() { - return getSwf().getAbcList(); - } - - public int addMethodBody(MethodBody body) { - bodies.add(body); - bodyIdxFromMethodIdx = null; - return bodies.size() - 1; - } - - public int addMethodInfo(MethodInfo mi) { - method_info.add(mi); - return method_info.size() - 1; - } - - public void addEventListener(EventListener listener) { - listeners.add(listener); - } - - public void removeEventListener(EventListener listener) { - listeners.remove(listener); - } - - protected void informListeners(String event, Object data) { - for (EventListener listener : listeners) { - listener.handleEvent(event, data); - } - } - - public int removeTraps() throws InterruptedException { - int rem = 0; - for (int s = 0; s < script_info.size(); s++) { - rem += script_info.get(s).removeTraps(s, this, ""); - } - return rem; - } - - public int removeDeadCode() throws InterruptedException { - int rem = 0; - for (MethodBody body : bodies) { - rem += body.removeDeadCode(constants, null/*FIXME*/, method_info.get(body.method_info)); - } - return rem; - } - - public void restoreControlFlow() throws InterruptedException { - for (MethodBody body : bodies) { - body.restoreControlFlow(constants, null/*FIXME*/, method_info.get(body.method_info)); - } - } - - public Set getNsStringUsages() { - Set ret = new HashSet<>(); - for (int n = 1; n < constants.getNamespaceCount(); n++) { - ret.add(constants.getNamespace(n).name_index); - } - return ret; - } - - public Set getStringUsages() { - Set ret = new HashSet<>(); - for (MethodBody body : bodies) { - for (AVM2Instruction ins : body.getCode().code) { - for (int i = 0; i < ins.definition.operands.length; i++) { - if (ins.definition.operands[i] == AVM2Code.DAT_STRING_INDEX) { - ret.add(ins.operands[i]); - } - } - } - } - return ret; - } - - private void setStringUsageType(Map ret, int strIndex, String usageType) { - if (ret.containsKey(strIndex)) { - if (!"name".equals(usageType)) { - if (!ret.get(strIndex).equals(usageType)) { - ret.put(strIndex, "name"); - } - } - } else { - ret.put(strIndex, usageType); - } - } - - private void getStringUsageTypes(Map ret, Traits traits, boolean classesOnly) { - for (Trait t : traits.traits) { - int strIndex = constants.getMultiname(t.name_index).name_index; - String usageType = ""; - if (t instanceof TraitClass) { - TraitClass tc = (TraitClass) t; - getStringUsageTypes(ret, class_info.get(tc.class_info).static_traits, classesOnly); - getStringUsageTypes(ret, instance_info.get(tc.class_info).instance_traits, classesOnly); - - if (instance_info.get(tc.class_info).name_index != 0) { - setStringUsageType(ret, constants.getMultiname(instance_info.get(tc.class_info).name_index).name_index, "class"); - } - if (instance_info.get(tc.class_info).super_index != 0) { - setStringUsageType(ret, constants.getMultiname(instance_info.get(tc.class_info).super_index).name_index, "class"); - } - - usageType = "class"; - } - if (t instanceof TraitMethodGetterSetter) { - TraitMethodGetterSetter tm = (TraitMethodGetterSetter) t; - usageType = "method"; - MethodBody body = findBody(tm.method_info); - if (body != null) { - getStringUsageTypes(ret, body.traits, classesOnly); - } - } - if (t instanceof TraitFunction) { - TraitFunction tf = (TraitFunction) t; - MethodBody body = findBody(tf.method_info); - if (body != null) { - getStringUsageTypes(ret, body.traits, classesOnly); - } - usageType = "function"; - } - if (t instanceof TraitSlotConst) { - TraitSlotConst ts = (TraitSlotConst) t; - if (ts.isVar()) { - usageType = "var"; - } - if (ts.isConst()) { - usageType = "const"; - } - } - if (usageType.equals("class") || (!classesOnly)) { - setStringUsageType(ret, strIndex, usageType); - } - } - } - - public void getStringUsageTypes(Map ret, boolean classesOnly) { - for (ScriptInfo script : script_info) { - getStringUsageTypes(ret, script.traits, classesOnly); - } - } - - public void renameMultiname(int multinameIndex, String newname) { - if (multinameIndex <= 0 || multinameIndex >= constants.getMultinameCount()) { - throw new IllegalArgumentException("Multiname with index " + multinameIndex + " does not exist"); - } - Set stringUsages = getStringUsages(); - Set namespaceUsages = getNsStringUsages(); - int strIndex = constants.getMultiname(multinameIndex).name_index; - if (stringUsages.contains(strIndex) || namespaceUsages.contains(strIndex)) { // name is used elsewhere as string literal - strIndex = constants.getStringId(newname, true); - constants.getMultiname(multinameIndex).name_index = strIndex; - } else { - constants.setString(strIndex, newname); - } - } - - public void deobfuscateIdentifiers(HashMap namesMap, RenameType renameType, boolean classesOnly) { - Set stringUsages = getStringUsages(); - Set namespaceUsages = getNsStringUsages(); - Map stringUsageTypes = new HashMap<>(); - informListeners("deobfuscate", "Getting usage types..."); - getStringUsageTypes(stringUsageTypes, classesOnly); - AVM2Deobfuscation deobfuscation = getDeobfuscation(); - for (int i = 0; i < instance_info.size(); i++) { - informListeners("deobfuscate", "class " + i + "/" + instance_info.size()); - InstanceInfo insti = instance_info.get(i); - if (insti.name_index != 0) { - constants.getMultiname(insti.name_index).name_index = deobfuscation.deobfuscateName(stringUsageTypes, stringUsages, namespaceUsages, namesMap, constants.getMultiname(insti.name_index).name_index, true, renameType); - if (constants.getMultiname(insti.name_index).namespace_index != 0) { - constants.getNamespace(constants.getMultiname(insti.name_index).namespace_index).name_index - = deobfuscation.deobfuscatePackageName(stringUsageTypes, stringUsages, namesMap, constants.getNamespace(constants.getMultiname(insti.name_index).namespace_index).name_index, renameType); - } - } - if (insti.super_index != 0) { - constants.getMultiname(insti.super_index).name_index = deobfuscation.deobfuscateName(stringUsageTypes, stringUsages, namespaceUsages, namesMap, constants.getMultiname(insti.super_index).name_index, true, renameType); - } - } - if (classesOnly) { - return; - } - for (int i = 1; i < constants.getMultinameCount(); i++) { - informListeners("deobfuscate", "name " + i + "/" + constants.getMultinameCount()); - constants.getMultiname(i).name_index = deobfuscation.deobfuscateName(stringUsageTypes, stringUsages, namespaceUsages, namesMap, constants.getMultiname(i).name_index, false, renameType); - } - for (int i = 1; i < constants.getNamespaceCount(); i++) { - informListeners("deobfuscate", "namespace " + i + "/" + constants.getNamespaceCount()); - if (constants.getNamespace(i).kind != Namespace.KIND_PACKAGE) { // only packages - continue; - } - constants.getNamespace(i).name_index = deobfuscation.deobfuscatePackageName(stringUsageTypes, stringUsages, namesMap, constants.getNamespace(i).name_index, renameType); - } - - // process reflection using getDefinitionByName too - for (MethodBody body : bodies) { - for (int ip = 0; ip < body.getCode().code.size(); ip++) { - if (body.getCode().code.get(ip).definition instanceof CallPropertyIns) { - int mIndex = body.getCode().code.get(ip).operands[0]; - if (mIndex > 0) { - Multiname m = constants.getMultiname(mIndex); - if (m.getNameWithNamespace(constants, true).equals("flash.utils.getDefinitionByName")) { - if (ip > 0) { - if (body.getCode().code.get(ip - 1).definition instanceof PushStringIns) { - int strIndex = body.getCode().code.get(ip - 1).operands[0]; - String fullname = constants.getString(strIndex); - String pkg = ""; - String name = fullname; - if (fullname.contains(".")) { - pkg = fullname.substring(0, fullname.lastIndexOf('.')); - name = fullname.substring(fullname.lastIndexOf('.') + 1); - } - if (!pkg.isEmpty()) { - int pkgStrIndex = constants.getStringId(pkg, true); - pkgStrIndex = deobfuscation.deobfuscatePackageName(stringUsageTypes, stringUsages, namesMap, pkgStrIndex, renameType); - pkg = constants.getString(pkgStrIndex); - } - int nameStrIndex = constants.getStringId(name, true); - nameStrIndex = deobfuscation.deobfuscateName(stringUsageTypes, stringUsages, namespaceUsages, namesMap, nameStrIndex, true, renameType); - name = constants.getString(nameStrIndex); - String fullChanged = ""; - if (!pkg.isEmpty()) { - fullChanged = pkg + "."; - } - fullChanged += name; - strIndex = constants.getStringId(fullChanged, true); - body.getCode().code.get(ip - 1).operands[0] = strIndex; - } - } - } - } - } - } - } - } - - public ABC(ABCInputStream ais, SWF swf, ABCContainerTag tag) throws IOException { - this.parentTag = tag; - minor_version = ais.readU16("minor_version"); - major_version = ais.readU16("major_version"); - logger.log(Level.FINE, "ABC minor_version: {0}, major_version: {1}", new Object[]{minor_version, major_version}); - - constants = new AVM2ConstantPool(); - ais.newDumpLevel("constant_pool", "cpool_info"); - - // constant integers - int constant_int_pool_count = ais.readU30("int_count"); - constants.constant_int = new ArrayList<>(constant_int_pool_count); - if (constant_int_pool_count > 0) { - constants.addInt(0); - } - if (constant_int_pool_count > 1) { - ais.newDumpLevel("integers", "integer[]"); - for (int i = 1; i < constant_int_pool_count; i++) { // index 0 not used. Values 1..n-1 - constants.addInt(ais.readS32("int")); - } - ais.endDumpLevel(); - } - - // constant unsigned integers - int constant_uint_pool_count = ais.readU30("uint_count"); - constants.constant_uint = new ArrayList<>(constant_uint_pool_count); - if (constant_uint_pool_count > 0) { - constants.addUInt(0); - } - if (constant_uint_pool_count > 1) { - ais.newDumpLevel("uintegers", "uinteger[]"); - for (int i = 1; i < constant_uint_pool_count; i++) { // index 0 not used. Values 1..n-1 - constants.addUInt(ais.readU32("uint")); - } - ais.endDumpLevel(); - } - - // constant double - int constant_double_pool_count = ais.readU30("double_count"); - constants.constant_double = new ArrayList<>(constant_double_pool_count); - if (constant_double_pool_count > 0) { - constants.addDouble(0); - } - if (constant_double_pool_count > 1) { - ais.newDumpLevel("doubles", "double[]"); - for (int i = 1; i < constant_double_pool_count; i++) { // index 0 not used. Values 1..n-1 - constants.addDouble(ais.readDouble("double")); - } - ais.endDumpLevel(); - } - - // constant decimal - if (minor_version >= MINORwithDECIMAL) { - int constant_decimal_pool_count = ais.readU30("decimal_count"); - constants.constant_decimal = new ArrayList<>(constant_decimal_pool_count); - if (constant_decimal_pool_count > 0) { - constants.addDecimal(null); - } - if (constant_decimal_pool_count > 1) { - ais.newDumpLevel("decimals", "decimal[]"); - for (int i = 1; i < constant_decimal_pool_count; i++) { // index 0 not used. Values 1..n-1 - constants.addDecimal(ais.readDecimal("decimal")); - } - ais.endDumpLevel(); - } - } else { - constants.constant_decimal = new ArrayList<>(0); - } - - // constant string - int constant_string_pool_count = ais.readU30("string_count"); - constants.constant_string = new ArrayList<>(constant_string_pool_count); - stringOffsets = new long[constant_string_pool_count]; - if (constant_string_pool_count > 0) { - constants.addString(""); - } - if (constant_string_pool_count > 1) { - ais.newDumpLevel("strings", "string[]"); - for (int i = 1; i < constant_string_pool_count; i++) { // index 0 not used. Values 1..n-1 - long pos = ais.getPosition(); - constants.addString(ais.readString("string")); - stringOffsets[i] = pos; - } - ais.endDumpLevel(); - } - - // constant namespace - int constant_namespace_pool_count = ais.readU30("namespace_count"); - constants.constant_namespace = new ArrayList<>(constant_namespace_pool_count); - if (constant_namespace_pool_count > 0) { - constants.addNamespace(null); - } - if (constant_namespace_pool_count > 1) { - ais.newDumpLevel("namespaces", "namespace[]"); - for (int i = 1; i < constant_namespace_pool_count; i++) { // index 0 not used. Values 1..n-1 - constants.addNamespace(ais.readNamespace("namespace")); - } - ais.endDumpLevel(); - } - - // constant namespace set - int constant_namespace_set_pool_count = ais.readU30("ns_set_count"); - constants.constant_namespace_set = new ArrayList<>(constant_namespace_set_pool_count); - if (constant_namespace_set_pool_count > 0) { - constants.addNamespaceSet(null); - } - if (constant_namespace_set_pool_count > 1) { - ais.newDumpLevel("ns_sets", "ns_set[]"); - for (int i = 1; i < constant_namespace_set_pool_count; i++) { // index 0 not used. Values 1..n-1 - ais.newDumpLevel("ns_set_infos", "ns_set_info[]"); - constants.addNamespaceSet(new NamespaceSet()); - int namespace_count = ais.readU30("count"); - constants.getNamespaceSet(i).namespaces = new int[namespace_count]; - for (int j = 0; j < namespace_count; j++) { - constants.getNamespaceSet(i).namespaces[j] = ais.readU30("ns"); - } - ais.endDumpLevel(); - } - ais.endDumpLevel(); - } - - // constant multiname - int constant_multiname_pool_count = ais.readU30("multiname_count"); - constants.constant_multiname = new ArrayList<>(constant_multiname_pool_count); - if (constant_multiname_pool_count > 0) { - constants.addMultiname(null); - } - if (constant_multiname_pool_count > 1) { - ais.newDumpLevel("multiname", "multinames[]"); - for (int i = 1; i < constant_multiname_pool_count; i++) { // index 0 not used. Values 1..n-1 - constants.addMultiname(ais.readMultiname("multiname")); - } - ais.endDumpLevel(); - } - - ais.endDumpLevel(); // cpool_info - - // method info - int methods_count = ais.readU30("methods_count"); - method_info = new ArrayList<>(methods_count); // MethodInfo[methods_count]; - for (int i = 0; i < methods_count; i++) { - method_info.add(ais.readMethodInfo("method")); - } - - // metadata info - int metadata_count = ais.readU30("metadata_count"); - metadata_info = new ArrayList<>(metadata_count); - for (int i = 0; i < metadata_count; i++) { - int name_index = ais.readU30("name_index"); - int values_count = ais.readU30("values_count"); - int[] keys = new int[values_count]; - for (int v = 0; v < values_count; v++) { - keys[v] = ais.readU30("key"); - } - int[] values = new int[values_count]; - for (int v = 0; v < values_count; v++) { - values[v] = ais.readU30("value"); - } - metadata_info.add(new MetadataInfo(name_index, keys, values)); - } - - int class_count = ais.readU30("class_count"); - instance_info = new ArrayList<>(class_count); - for (int i = 0; i < class_count; i++) { - instance_info.add(ais.readInstanceInfo("instance")); - } - class_info = new ArrayList<>(class_count); - for (int i = 0; i < class_count; i++) { - ais.newDumpLevel("class", "class_info"); - ClassInfo ci = new ClassInfo(null); // do not create Traits in constructor - ci.cinit_index = ais.readU30("cinit_index"); - ci.static_traits = ais.readTraits("static_traits"); - class_info.add(ci); - ais.endDumpLevel(); - } - int script_count = ais.readU30("script_count"); - script_info = new ArrayList<>(script_count); - for (int i = 0; i < script_count; i++) { - ais.newDumpLevel("script", "script_info"); - ScriptInfo si = new ScriptInfo(null); // do not create Traits in constructor - si.init_index = ais.readU30("init_index"); - si.traits = ais.readTraits("traits"); - script_info.add(si); - ais.endDumpLevel(); - si.setModified(false); - } - - int bodies_count = ais.readU30("bodies_count"); - bodies = new ArrayList<>(bodies_count); - for (int i = 0; i < bodies_count; i++) { - ais.newDumpLevel("method_body", "method_body_info"); - MethodBody mb = new MethodBody(null, null, null); // do not create Traits in constructor - mb.method_info = ais.readU30("method_info"); - mb.max_stack = ais.readU30("max_stack"); - mb.max_regs = ais.readU30("max_regs"); - mb.init_scope_depth = ais.readU30("init_scope_depth"); - mb.max_scope_depth = ais.readU30("max_scope_depth"); - int code_length = ais.readU30("code_length"); - mb.setCodeBytes(ais.readBytes(code_length, "code")); - int ex_count = ais.readU30("ex_count"); - mb.exceptions = new ABCException[ex_count]; - for (int j = 0; j < ex_count; j++) { - ABCException abce = new ABCException(); - abce.start = ais.readU30("start"); - abce.end = ais.readU30("end"); - abce.target = ais.readU30("target"); - abce.type_index = ais.readU30("type_index"); - abce.name_index = ais.readU30("name_index"); - mb.exceptions[j] = abce; - } - mb.traits = ais.readTraits("traits"); - bodies.add(mb); - method_info.get(mb.method_info).setBody(mb); - ais.endDumpLevel(); - - SWFDecompilerPlugin.fireMethodBodyParsed(mb, swf); - } - - /*for(int i=0;i()); - } catch (InterruptedException ex) { - Logger.getLogger(ABC.class.getName()).log(Level.SEVERE, null, ex); - } - System.out.println(""+t.toString()); - } - //System.exit(0);*/ - SWFDecompilerPlugin.fireAbcParsed(this, swf); - } - - public void saveToStream(OutputStream os) throws IOException { - ABCOutputStream aos = new ABCOutputStream(os); - aos.writeU16(minor_version); - aos.writeU16(major_version); - - aos.writeU30(constants.getIntCount()); - for (int i = 1; i < constants.getIntCount(); i++) { - aos.writeS32(constants.getInt(i)); - } - aos.writeU30(constants.getUIntCount()); - for (int i = 1; i < constants.getUIntCount(); i++) { - aos.writeU32(constants.getUInt(i)); - } - - aos.writeU30(constants.getDoubleCount()); - for (int i = 1; i < constants.getDoubleCount(); i++) { - aos.writeDouble(constants.getDouble(i)); - } - - if (minor_version >= MINORwithDECIMAL) { - aos.writeU30(constants.getDecimalCount()); - for (int i = 1; i < constants.getDecimalCount(); i++) { - aos.writeDecimal(constants.getDecimal(i)); - } - } - - aos.writeU30(constants.getStringCount()); - for (int i = 1; i < constants.getStringCount(); i++) { - aos.writeString(constants.getString(i)); - } - - aos.writeU30(constants.getNamespaceCount()); - for (int i = 1; i < constants.getNamespaceCount(); i++) { - aos.writeNamespace(constants.getNamespace(i)); - } - - aos.writeU30(constants.getNamespaceSetCount()); - for (int i = 1; i < constants.getNamespaceSetCount(); i++) { - aos.writeU30(constants.getNamespaceSet(i).namespaces.length); - for (int j = 0; j < constants.getNamespaceSet(i).namespaces.length; j++) { - aos.writeU30(constants.getNamespaceSet(i).namespaces[j]); - } - } - - aos.writeU30(constants.getMultinameCount()); - for (int i = 1; i < constants.getMultinameCount(); i++) { - aos.writeMultiname(constants.getMultiname(i)); - } - - aos.writeU30(method_info.size()); - for (MethodInfo mi : method_info) { - aos.writeMethodInfo(mi); - } - - aos.writeU30(metadata_info.size()); - for (MetadataInfo mi : metadata_info) { - aos.writeU30(mi.name_index); - aos.writeU30(mi.values.length); - for (int j = 0; j < mi.values.length; j++) { - aos.writeU30(mi.keys[j]); - } - for (int j = 0; j < mi.values.length; j++) { - aos.writeU30(mi.values[j]); - } - } - - aos.writeU30(class_info.size()); - for (InstanceInfo ii : instance_info) { - aos.writeInstanceInfo(ii); - } - for (ClassInfo ci : class_info) { - aos.writeU30(ci.cinit_index); - aos.writeTraits(ci.static_traits); - } - aos.writeU30(script_info.size()); - for (ScriptInfo si : script_info) { - aos.writeU30(si.init_index); - aos.writeTraits(si.traits); - } - - aos.writeU30(bodies.size()); - for (MethodBody mb : bodies) { - aos.writeU30(mb.method_info); - aos.writeU30(mb.max_stack); - aos.writeU30(mb.max_regs); - aos.writeU30(mb.init_scope_depth); - aos.writeU30(mb.max_scope_depth); - byte[] codeBytes = mb.getCodeBytes(); - aos.writeU30(codeBytes.length); - aos.write(codeBytes); - aos.writeU30(mb.exceptions.length); - for (int j = 0; j < mb.exceptions.length; j++) { - aos.writeU30(mb.exceptions[j].start); - aos.writeU30(mb.exceptions[j].end); - aos.writeU30(mb.exceptions[j].target); - aos.writeU30(mb.exceptions[j].type_index); - aos.writeU30(mb.exceptions[j].name_index); - } - aos.writeTraits(mb.traits); - } - } - - public MethodBody findBody(int methodInfo) { - if (methodInfo < 0) { - return null; - } - return method_info.get(methodInfo).getBody(); - } - - public int findBodyIndex(int methodInfo) { - if (methodInfo == -1) { - return -1; - } - - Integer result = getBodyIdxFromMethodIdx().get(methodInfo); - if (result == null) { - return -1; - } - - return result; - } - - public MethodBody findBodyByClassAndName(String className, String methodName) { - for (int i = 0; i < instance_info.size(); i++) { - if (className.equals(constants.getMultiname(instance_info.get(i).name_index).getName(constants, new ArrayList(), true))) { - for (Trait t : instance_info.get(i).instance_traits.traits) { - if (t instanceof TraitMethodGetterSetter) { - TraitMethodGetterSetter t2 = (TraitMethodGetterSetter) t; - if (methodName.equals(t2.getName(this).getName(constants, new ArrayList(), true))) { - for (MethodBody body : bodies) { - if (body.method_info == t2.method_info) { - return body; - } - } - } - } - } - //break; - } - } - for (int i = 0; i < class_info.size(); i++) { - if (className.equals(constants.getMultiname(instance_info.get(i).name_index).getName(constants, new ArrayList(), true))) { - for (Trait t : class_info.get(i).static_traits.traits) { - if (t instanceof TraitMethodGetterSetter) { - TraitMethodGetterSetter t2 = (TraitMethodGetterSetter) t; - if (methodName.equals(t2.getName(this).getName(constants, new ArrayList(), true))) { - for (MethodBody body : bodies) { - if (body.method_info == t2.method_info) { - return body; - } - } - } - } - } - //break; - } - } - - return null; - } - - public boolean isStaticTraitId(int classIndex, int traitId) { - if (traitId < class_info.get(classIndex).static_traits.traits.size()) { - return true; - } else if (traitId < class_info.get(classIndex).static_traits.traits.size() + instance_info.get(classIndex).instance_traits.traits.size()) { - return false; - } else { - return true; // Can be class or instance initializer - } - } - - public Trait findTraitByTraitId(int classIndex, int traitId) { - if (classIndex == -1) { - return null; - } - List staticTraits = class_info.get(classIndex).static_traits.traits; - if (traitId < staticTraits.size()) { - return staticTraits.get(traitId); - } else { - List instanceTraits = instance_info.get(classIndex).instance_traits.traits; - if (traitId < staticTraits.size() + instanceTraits.size()) { - traitId -= staticTraits.size(); - return instanceTraits.get(traitId); - } else { - return null; // Can be class or instance initializer - } - } - } - - public int findMethodIdByTraitId(int classIndex, int traitId) { - if (classIndex == -1) { - return -1; - } - List staticTraits = class_info.get(classIndex).static_traits.traits; - if (traitId < staticTraits.size()) { - if (staticTraits.get(traitId) instanceof TraitMethodGetterSetter) { - return ((TraitMethodGetterSetter) staticTraits.get(traitId)).method_info; - } else { - return -1; - } - } else { - List instanceTraits = instance_info.get(classIndex).instance_traits.traits; - if (traitId < staticTraits.size() + instanceTraits.size()) { - traitId -= staticTraits.size(); - if (instanceTraits.get(traitId) instanceof TraitMethodGetterSetter) { - return ((TraitMethodGetterSetter) instanceTraits.get(traitId)).method_info; - } else { - return -1; - } - } else { - traitId -= staticTraits.size() + instanceTraits.size(); - if (traitId == 0) { - return instance_info.get(classIndex).iinit_index; - } else if (traitId == 1) { - return class_info.get(classIndex).cinit_index; - } else { - return -1; - } - } - } - } - - private Map getNamespaceMap() { - if (namespaceMap == null) { - Map map = new HashMap<>(); - for (ScriptInfo si : script_info) { - for (Trait t : si.traits.traits) { - if (t instanceof TraitSlotConst) { - TraitSlotConst s = ((TraitSlotConst) t); - if (s.isNamespace()) { - String key = constants.getNamespace(s.value_index).getName(constants, true); // assume not null - String val = constants.getMultiname(s.name_index).getNameWithNamespace(constants, true); - map.put(key, val); - } - } - } - } - namespaceMap = map; - } - - return namespaceMap; - } - - private AVM2Deobfuscation getDeobfuscation() { - if (deobfuscation == null) { - deobfuscation = new AVM2Deobfuscation(constants); - } - - return deobfuscation; - } - - private Map getBodyIdxFromMethodIdx() { - if (bodyIdxFromMethodIdx == null) { - Map map = new HashMap<>(bodies.size()); - for (int i = 0; i < bodies.size(); i++) { - MethodBody mb = bodies.get(i); - map.put(mb.method_info, i); - } - - bodyIdxFromMethodIdx = map; - } - - return bodyIdxFromMethodIdx; - } - - public String nsValueToName(String value) { - if (getNamespaceMap().containsKey(value)) { - return getNamespaceMap().get(value); - } else { - String ns = getDeobfuscation().builtInNs(value); - if (ns == null) { - return ""; - } else { - return ns; - } - } - } - - public List getScriptPacks(String packagePrefix) { - List ret = new ArrayList<>(); - for (int i = 0; i < script_info.size(); i++) { - ret.addAll(script_info.get(i).getPacks(this, i, packagePrefix)); - } - return ret; - } - - public void dump(OutputStream os) { - Utf8PrintWriter output; - output = new Utf8PrintWriter(os); - constants.dump(output); - for (int i = 0; i < method_info.size(); i++) { - output.println("MethodInfo[" + i + "]:" + method_info.get(i).toString(constants, new ArrayList())); - } - for (int i = 0; i < metadata_info.size(); i++) { - output.println("MetadataInfo[" + i + "]:" + metadata_info.get(i).toString(constants)); - } - for (int i = 0; i < instance_info.size(); i++) { - output.println("InstanceInfo[" + i + "]:" + instance_info.get(i).toString(this, new ArrayList())); - } - for (int i = 0; i < class_info.size(); i++) { - output.println("ClassInfo[" + i + "]:" + class_info.get(i).toString(this, new ArrayList())); - } - for (int i = 0; i < script_info.size(); i++) { - output.println("ScriptInfo[" + i + "]:" + script_info.get(i).toString(this, new ArrayList())); - } - for (int i = 0; i < bodies.size(); i++) { - output.println("MethodBody[" + i + "]:"); //+ bodies[i].toString(this, constants, method_info)); - } - } - - private void checkMultinameUsedInMethod(int multinameIndex, int methodInfo, List ret, int classIndex, int traitIndex, boolean isStatic, boolean isInitializer, Traits traits, int parentTraitIndex) { - for (int p = 0; p < method_info.get(methodInfo).param_types.length; p++) { - if (method_info.get(methodInfo).param_types[p] == multinameIndex) { - ret.add(new MethodParamsMultinameUsage(this, multinameIndex, classIndex, traitIndex, isStatic, isInitializer, traits, parentTraitIndex)); - break; - } - } - if (method_info.get(methodInfo).ret_type == multinameIndex) { - ret.add(new MethodReturnTypeMultinameUsage(this, multinameIndex, classIndex, traitIndex, isStatic, isInitializer, traits, parentTraitIndex)); - } - MethodBody body = findBody(methodInfo); - if (body != null) { - findMultinameUsageInTraits(body.traits, multinameIndex, isStatic, classIndex, ret, traitIndex); - for (ABCException e : body.exceptions) { - if ((e.name_index == multinameIndex) || (e.type_index == multinameIndex)) { - ret.add(new MethodBodyMultinameUsage(this, multinameIndex, classIndex, traitIndex, isStatic, isInitializer, traits, parentTraitIndex)); - return; - } - } - for (AVM2Instruction ins : body.getCode().code) { - for (int o = 0; o < ins.definition.operands.length; o++) { - if (ins.definition.operands[o] == AVM2Code.DAT_MULTINAME_INDEX) { - if (ins.operands[o] == multinameIndex) { - ret.add(new MethodBodyMultinameUsage(this, multinameIndex, classIndex, traitIndex, isStatic, isInitializer, traits, parentTraitIndex)); - return; - } - } - } - } - } - } - - private void findMultinameUsageInTraits(Traits traits, int multinameIndex, boolean isStatic, int classIndex, List ret, int parentTraitIndex) { - for (int t = 0; t < traits.traits.size(); t++) { - if (traits.traits.get(t) instanceof TraitSlotConst) { - TraitSlotConst tsc = (TraitSlotConst) traits.traits.get(t); - if (tsc.name_index == multinameIndex) { - ret.add(new ConstVarNameMultinameUsage(this, multinameIndex, classIndex, t, isStatic, traits, parentTraitIndex)); - } - if (tsc.type_index == multinameIndex) { - ret.add(new ConstVarTypeMultinameUsage(this, multinameIndex, classIndex, t, isStatic, traits, parentTraitIndex)); - } - } - if (traits.traits.get(t) instanceof TraitMethodGetterSetter) { - TraitMethodGetterSetter tmgs = (TraitMethodGetterSetter) traits.traits.get(t); - if (tmgs.name_index == multinameIndex) { - ret.add(new MethodNameMultinameUsage(this, multinameIndex, classIndex, t, isStatic, false, traits, parentTraitIndex)); - } - checkMultinameUsedInMethod(multinameIndex, tmgs.method_info, ret, classIndex, t, isStatic, false, traits, parentTraitIndex); - } - } - } - - public List findMultinameDefinition(int multinameIndex) { - List usages = findMultinameUsage(multinameIndex); - List ret = new ArrayList<>(); - for (MultinameUsage u : usages) { - if (u instanceof DefinitionUsage) { - ret.add(u); - } - } - return ret; - } - - public List findMultinameUsage(int multinameIndex) { - List ret = new ArrayList<>(); - if (multinameIndex == 0) { - return ret; - } - for (int c = 0; c < instance_info.size(); c++) { - if (instance_info.get(c).name_index == multinameIndex) { - ret.add(new ClassNameMultinameUsage(this, multinameIndex, c)); - } - if (instance_info.get(c).super_index == multinameIndex) { - ret.add(new ExtendsMultinameUsage(this, multinameIndex, c)); - } - for (int i = 0; i < instance_info.get(c).interfaces.length; i++) { - if (instance_info.get(c).interfaces[i] == multinameIndex) { - ret.add(new ImplementsMultinameUsage(this, multinameIndex, c)); - } - } - checkMultinameUsedInMethod(multinameIndex, instance_info.get(c).iinit_index, ret, c, 0, false, true, null, -1); - checkMultinameUsedInMethod(multinameIndex, class_info.get(c).cinit_index, ret, c, 0, true, true, null, -1); - findMultinameUsageInTraits(instance_info.get(c).instance_traits, multinameIndex, false, c, ret, -1); - findMultinameUsageInTraits(class_info.get(c).static_traits, multinameIndex, true, c, ret, -1); - } - loopm: - for (int m = 1; m < constants.getMultinameCount(); m++) { - if (constants.getMultiname(m).kind == Multiname.TYPENAME) { - if (constants.getMultiname(m).qname_index == multinameIndex) { - ret.add(new TypeNameMultinameUsage(this, m)); - continue; - } - for (int mp : constants.getMultiname(m).params) { - if (mp == multinameIndex) { - ret.add(new TypeNameMultinameUsage(this, m)); - continue loopm; - } - } - } - } - return ret; - } - - public int findMethodInfoByName(int classId, String methodName) { - if (classId > -1) { - for (Trait t : instance_info.get(classId).instance_traits.traits) { - if (t instanceof TraitMethodGetterSetter) { - if (t.getName(this).getName(constants, new ArrayList(), true).equals(methodName)) { - return ((TraitMethodGetterSetter) t).method_info; - } - } - } - } - return -1; - } - - public int findMethodBodyByName(int classId, String methodName) { - if (classId > -1) { - for (Trait t : instance_info.get(classId).instance_traits.traits) { - if (t instanceof TraitMethodGetterSetter) { - if (t.getName(this).getName(constants, new ArrayList(), true).equals(methodName)) { - return findBodyIndex(((TraitMethodGetterSetter) t).method_info); - } - } - } - } - return -1; - } - - public int findMethodBodyByName(String className, String methodName) { - int classId = findClassByName(className); - return findMethodBodyByName(classId, methodName); - } - - public int findClassByName(String name) { - for (int c = 0; c < instance_info.size(); c++) { - String s = constants.getMultiname(instance_info.get(c).name_index).getNameWithNamespace(constants, true); - if (name.equals(s)) { - return c; - } - } - return -1; - } - - public List findScriptPacksByPath(String name) { - List ret = new ArrayList<>(); - List allPacks = getScriptPacks(null); // todo: honfika: use filter parameter - if (name.endsWith(".**") || name.equals("**") || name.endsWith(".++") || name.equals("++")) { - name = name.substring(0, name.length() - 2); - - for (ScriptPack en : allPacks) { - if (en.getClassPath().toString().startsWith(name)) { - ret.add(en); - } - } - } else if (name.endsWith(".*") || name.equals("*") || name.endsWith(".+") || name.equals("+")) { - name = name.substring(0, name.length() - 1); - for (ScriptPack en : allPacks) { - String classPathStr = en.getClassPath().toString(); - if (classPathStr.startsWith(name)) { - String rem = name.isEmpty() ? classPathStr : classPathStr.substring(name.length()); - if (!rem.contains(".")) { - ret.add(en); - } - } - } - } else { - ScriptPack p = findScriptPackByPath(name); - if (p != null) { - ret.add(p); - } - } - return ret; - - } - - public ScriptPack findScriptPackByPath(String name) { - List packs = getScriptPacks(null); - for (ScriptPack en : packs) { - if (en.getClassPath().toString().equals(name)) { - return en; - } - } - return null; - } - - private void removeClassFromTraits(Traits traits, int index) { - for (Trait t : traits.traits) { - if (t instanceof TraitClass) { - TraitClass tc = (TraitClass) t; - removeClassFromTraits(instance_info.get(tc.class_info).instance_traits, index); - removeClassFromTraits(class_info.get(tc.class_info).static_traits, index); - if (tc.class_info > index) { - tc.class_info--; - } - } - } - } - - public void addClass(ClassInfo ci, InstanceInfo ii, int index) { - for (MethodBody b : bodies) { - for (AVM2Instruction ins : b.getCode().code) { - for (int i = 0; i < ins.definition.operands.length; i++) { - if (ins.definition.operands[i] == AVM2Code.DAT_CLASS_INDEX) { - if (ins.operands[i] >= index) { - ins.operands[i]++; - } - } - } - } - } - for (ScriptInfo si : script_info) { - addClassInTraits(si.traits, index); - } - for (MethodBody b : bodies) { - addClassInTraits(b.traits, index); - } - instance_info.add(index, ii); - class_info.add(index, ci); - } - - private void addClassInTraits(Traits traits, int index) { - for (Trait t : traits.traits) { - if (t instanceof TraitClass) { - TraitClass tc = (TraitClass) t; - addClassInTraits(instance_info.get(tc.class_info).instance_traits, index); - addClassInTraits(class_info.get(tc.class_info).static_traits, index); - if (tc.class_info >= index) { - tc.class_info++; - } - } - } - } - - public void removeClass(int index) { - for (MethodBody b : bodies) { - for (AVM2Instruction ins : b.getCode().code) { - for (int i = 0; i < ins.definition.operands.length; i++) { - if (ins.definition.operands[i] == AVM2Code.DAT_CLASS_INDEX) { - if (ins.operands[i] > index) { - ins.operands[i]--; - } - } - } - } - } - for (ScriptInfo si : script_info) { - removeClassFromTraits(si.traits, index); - } - for (MethodBody b : bodies) { - removeClassFromTraits(b.traits, index); - } - instance_info.remove(index); - class_info.remove(index); - } - - private void removeMethodFromTraits(Traits traits, int index) { - for (Trait t : traits.traits) { - if (t instanceof TraitClass) { - TraitClass tc = (TraitClass) t; - removeMethodFromTraits(instance_info.get(tc.class_info).instance_traits, index); - removeMethodFromTraits(class_info.get(tc.class_info).static_traits, index); - } - if (t instanceof TraitMethodGetterSetter) { - TraitMethodGetterSetter tmgs = (TraitMethodGetterSetter) t; - if (tmgs.method_info > index) { - tmgs.method_info--; - } - } - if (t instanceof TraitFunction) { - TraitFunction tf = (TraitFunction) t; - if (tf.method_info > index) { - tf.method_info--; - } - } - } - } - - public void removeMethod(int index) { - - int bindex = -1; - for (int b = 0; b < bodies.size(); b++) { - if (bodies.get(b).method_info == index) { - bodies.remove(b); - bindex = b; - b--; - } - } - - for (MethodBody b : bodies) { - if (b.method_info > index) { - b.method_info--; - } - for (AVM2Instruction ins : b.getCode().code) { - for (int i = 0; i < ins.definition.operands.length; i++) { - if (ins.definition.operands[i] == AVM2Code.DAT_METHOD_INDEX) { - if (ins.operands[i] > index) { - ins.operands[i]--; - } - } - } - } - removeMethodFromTraits(b.traits, index); - } - - for (int c = 0; c < instance_info.size(); c++) { - InstanceInfo ii = instance_info.get(c); - if (ii.iinit_index > index) { - ii.iinit_index--; - } - ClassInfo ci = class_info.get(c); - if (ci.cinit_index > index) { - ci.cinit_index--; - } - } - - for (ScriptInfo si : script_info) { - if (si.init_index > index) { - si.init_index--; - } - removeMethodFromTraits(si.traits, index); - } - - bodyIdxFromMethodIdx = null; - - method_info.remove(index); - } - - public void replaceScriptPack(ScriptPack pack, String as) throws AVM2ParseException, CompilationException, IOException, InterruptedException { - String scriptName = pack.getPathScriptName() + ".as"; - int oldIndex = pack.scriptIndex; - int newIndex = script_info.size(); - String documentClass = getSwf().getDocumentClass(); - boolean isDocumentClass = documentClass != null && documentClass.equals(pack.getClassPath().toString()); - - ScriptInfo si = script_info.get(oldIndex); - si.delete(this, true); - int newClassIndex = instance_info.size(); - for (Trait t : si.traits.traits) { - if (t instanceof TraitClass) { - TraitClass tc = (TraitClass) t; - newClassIndex = tc.class_info + 1; - } - } - ActionScriptParser.compile(as, this, new ArrayList(), isDocumentClass, scriptName, newClassIndex); - // Move newly added script to its position - script_info.set(oldIndex, script_info.get(newIndex)); - script_info.remove(newIndex); - script_info.get(oldIndex).setModified(true); - pack(); // removes old classes/methods - ((Tag) parentTag).setModified(true); - } - - public void pack() { - for (int c = 0; c < instance_info.size(); c++) { - if (instance_info.get(c).deleted) { - removeClass(c); - c--; - } - } - for (int m = 0; m < method_info.size(); m++) { - if (method_info.get(m).deleted) { - removeMethod(m); - m--; - } - } - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc; + +import com.jpexs.decompiler.flash.EventListener; +import com.jpexs.decompiler.flash.SWF; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Deobfuscation; +import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; +import com.jpexs.decompiler.flash.abc.avm2.instructions.executing.CallPropertyIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushStringIns; +import com.jpexs.decompiler.flash.abc.avm2.parser.AVM2ParseException; +import com.jpexs.decompiler.flash.abc.avm2.parser.script.ActionScriptParser; +import com.jpexs.decompiler.flash.abc.types.ABCException; +import com.jpexs.decompiler.flash.abc.types.ClassInfo; +import com.jpexs.decompiler.flash.abc.types.InstanceInfo; +import com.jpexs.decompiler.flash.abc.types.MetadataInfo; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.flash.abc.types.Multiname; +import com.jpexs.decompiler.flash.abc.types.Namespace; +import com.jpexs.decompiler.flash.abc.types.NamespaceSet; +import com.jpexs.decompiler.flash.abc.types.ScriptInfo; +import com.jpexs.decompiler.flash.abc.types.traits.Trait; +import com.jpexs.decompiler.flash.abc.types.traits.TraitClass; +import com.jpexs.decompiler.flash.abc.types.traits.TraitFunction; +import com.jpexs.decompiler.flash.abc.types.traits.TraitMethodGetterSetter; +import com.jpexs.decompiler.flash.abc.types.traits.TraitSlotConst; +import com.jpexs.decompiler.flash.abc.types.traits.Traits; +import com.jpexs.decompiler.flash.abc.usages.ClassNameMultinameUsage; +import com.jpexs.decompiler.flash.abc.usages.ConstVarNameMultinameUsage; +import com.jpexs.decompiler.flash.abc.usages.ConstVarTypeMultinameUsage; +import com.jpexs.decompiler.flash.abc.usages.DefinitionUsage; +import com.jpexs.decompiler.flash.abc.usages.ExtendsMultinameUsage; +import com.jpexs.decompiler.flash.abc.usages.ImplementsMultinameUsage; +import com.jpexs.decompiler.flash.abc.usages.MethodBodyMultinameUsage; +import com.jpexs.decompiler.flash.abc.usages.MethodNameMultinameUsage; +import com.jpexs.decompiler.flash.abc.usages.MethodParamsMultinameUsage; +import com.jpexs.decompiler.flash.abc.usages.MethodReturnTypeMultinameUsage; +import com.jpexs.decompiler.flash.abc.usages.MultinameUsage; +import com.jpexs.decompiler.flash.abc.usages.TypeNameMultinameUsage; +import com.jpexs.decompiler.flash.helpers.SWFDecompilerPlugin; +import com.jpexs.decompiler.flash.tags.ABCContainerTag; +import com.jpexs.decompiler.flash.tags.Tag; +import com.jpexs.decompiler.flash.types.annotations.Internal; +import com.jpexs.decompiler.graph.CompilationException; +import com.jpexs.helpers.utf8.Utf8PrintWriter; +import java.io.IOException; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class ABC { + + public int major_version = 46; + + public int minor_version = 16; + + public AVM2ConstantPool constants = new AVM2ConstantPool(); + + public List method_info = new ArrayList<>(); + + public List metadata_info = new ArrayList<>(); + + public List instance_info = new ArrayList<>(); + + public List class_info = new ArrayList<>(); + + public List script_info = new ArrayList<>(); + + public List bodies = new ArrayList<>(); + + private Map bodyIdxFromMethodIdx; + + private long[] stringOffsets; + + public static final int MINORwithDECIMAL = 17; + + protected Set listeners = new HashSet<>(); + + private static final Logger logger = Logger.getLogger(ABC.class.getName()); + + private AVM2Deobfuscation deobfuscation; + + @Internal + public ABCContainerTag parentTag; + + /* Map from multiname index of namespace value to namespace name**/ + private Map namespaceMap; + + public ABC(ABCContainerTag tag) { + this.parentTag = tag; + this.deobfuscation = null; + constants.constant_double.add(null); + constants.constant_int.add(null); + constants.constant_uint.add(null); + constants.constant_string.add(null); + constants.constant_multiname.add(null); + constants.constant_namespace.add(null); + constants.constant_namespace_set.add(null); + } + + public SWF getSwf() { + return parentTag.getSwf(); + } + + public List getAbcTags() { + return getSwf().getAbcList(); + } + + public int addMethodBody(MethodBody body) { + bodies.add(body); + bodyIdxFromMethodIdx = null; + return bodies.size() - 1; + } + + public int addMethodInfo(MethodInfo mi) { + method_info.add(mi); + return method_info.size() - 1; + } + + public void addEventListener(EventListener listener) { + listeners.add(listener); + } + + public void removeEventListener(EventListener listener) { + listeners.remove(listener); + } + + protected void informListeners(String event, Object data) { + for (EventListener listener : listeners) { + listener.handleEvent(event, data); + } + } + + public int removeTraps() throws InterruptedException { + int rem = 0; + for (int s = 0; s < script_info.size(); s++) { + rem += script_info.get(s).removeTraps(s, this, ""); + } + return rem; + } + + public int removeDeadCode() throws InterruptedException { + int rem = 0; + for (MethodBody body : bodies) { + rem += body.removeDeadCode(constants, null/*FIXME*/, method_info.get(body.method_info)); + } + return rem; + } + + public void restoreControlFlow() throws InterruptedException { + for (MethodBody body : bodies) { + body.restoreControlFlow(constants, null/*FIXME*/, method_info.get(body.method_info)); + } + } + + public Set getNsStringUsages() { + Set ret = new HashSet<>(); + for (int n = 1; n < constants.getNamespaceCount(); n++) { + ret.add(constants.getNamespace(n).name_index); + } + return ret; + } + + public Set getStringUsages() { + Set ret = new HashSet<>(); + for (MethodBody body : bodies) { + for (AVM2Instruction ins : body.getCode().code) { + for (int i = 0; i < ins.definition.operands.length; i++) { + if (ins.definition.operands[i] == AVM2Code.DAT_STRING_INDEX) { + ret.add(ins.operands[i]); + } + } + } + } + return ret; + } + + private void setStringUsageType(Map ret, int strIndex, String usageType) { + if (ret.containsKey(strIndex)) { + if (!"name".equals(usageType)) { + if (!ret.get(strIndex).equals(usageType)) { + ret.put(strIndex, "name"); + } + } + } else { + ret.put(strIndex, usageType); + } + } + + private void getStringUsageTypes(Map ret, Traits traits, boolean classesOnly) { + for (Trait t : traits.traits) { + int strIndex = constants.getMultiname(t.name_index).name_index; + String usageType = ""; + if (t instanceof TraitClass) { + TraitClass tc = (TraitClass) t; + getStringUsageTypes(ret, class_info.get(tc.class_info).static_traits, classesOnly); + getStringUsageTypes(ret, instance_info.get(tc.class_info).instance_traits, classesOnly); + + if (instance_info.get(tc.class_info).name_index != 0) { + setStringUsageType(ret, constants.getMultiname(instance_info.get(tc.class_info).name_index).name_index, "class"); + } + if (instance_info.get(tc.class_info).super_index != 0) { + setStringUsageType(ret, constants.getMultiname(instance_info.get(tc.class_info).super_index).name_index, "class"); + } + + usageType = "class"; + } + if (t instanceof TraitMethodGetterSetter) { + TraitMethodGetterSetter tm = (TraitMethodGetterSetter) t; + usageType = "method"; + MethodBody body = findBody(tm.method_info); + if (body != null) { + getStringUsageTypes(ret, body.traits, classesOnly); + } + } + if (t instanceof TraitFunction) { + TraitFunction tf = (TraitFunction) t; + MethodBody body = findBody(tf.method_info); + if (body != null) { + getStringUsageTypes(ret, body.traits, classesOnly); + } + usageType = "function"; + } + if (t instanceof TraitSlotConst) { + TraitSlotConst ts = (TraitSlotConst) t; + if (ts.isVar()) { + usageType = "var"; + } + if (ts.isConst()) { + usageType = "const"; + } + } + if (usageType.equals("class") || (!classesOnly)) { + setStringUsageType(ret, strIndex, usageType); + } + } + } + + public void getStringUsageTypes(Map ret, boolean classesOnly) { + for (ScriptInfo script : script_info) { + getStringUsageTypes(ret, script.traits, classesOnly); + } + } + + public void renameMultiname(int multinameIndex, String newname) { + if (multinameIndex <= 0 || multinameIndex >= constants.getMultinameCount()) { + throw new IllegalArgumentException("Multiname with index " + multinameIndex + " does not exist"); + } + Set stringUsages = getStringUsages(); + Set namespaceUsages = getNsStringUsages(); + int strIndex = constants.getMultiname(multinameIndex).name_index; + if (stringUsages.contains(strIndex) || namespaceUsages.contains(strIndex)) { // name is used elsewhere as string literal + strIndex = constants.getStringId(newname, true); + constants.getMultiname(multinameIndex).name_index = strIndex; + } else { + constants.setString(strIndex, newname); + } + } + + public void deobfuscateIdentifiers(HashMap namesMap, RenameType renameType, boolean classesOnly) { + Set stringUsages = getStringUsages(); + Set namespaceUsages = getNsStringUsages(); + Map stringUsageTypes = new HashMap<>(); + informListeners("deobfuscate", "Getting usage types..."); + getStringUsageTypes(stringUsageTypes, classesOnly); + AVM2Deobfuscation deobfuscation = getDeobfuscation(); + for (int i = 0; i < instance_info.size(); i++) { + informListeners("deobfuscate", "class " + i + "/" + instance_info.size()); + InstanceInfo insti = instance_info.get(i); + if (insti.name_index != 0) { + constants.getMultiname(insti.name_index).name_index = deobfuscation.deobfuscateName(stringUsageTypes, stringUsages, namespaceUsages, namesMap, constants.getMultiname(insti.name_index).name_index, true, renameType); + if (constants.getMultiname(insti.name_index).namespace_index != 0) { + constants.getNamespace(constants.getMultiname(insti.name_index).namespace_index).name_index + = deobfuscation.deobfuscatePackageName(stringUsageTypes, stringUsages, namesMap, constants.getNamespace(constants.getMultiname(insti.name_index).namespace_index).name_index, renameType); + } + } + if (insti.super_index != 0) { + constants.getMultiname(insti.super_index).name_index = deobfuscation.deobfuscateName(stringUsageTypes, stringUsages, namespaceUsages, namesMap, constants.getMultiname(insti.super_index).name_index, true, renameType); + } + } + if (classesOnly) { + return; + } + for (int i = 1; i < constants.getMultinameCount(); i++) { + informListeners("deobfuscate", "name " + i + "/" + constants.getMultinameCount()); + constants.getMultiname(i).name_index = deobfuscation.deobfuscateName(stringUsageTypes, stringUsages, namespaceUsages, namesMap, constants.getMultiname(i).name_index, false, renameType); + } + for (int i = 1; i < constants.getNamespaceCount(); i++) { + informListeners("deobfuscate", "namespace " + i + "/" + constants.getNamespaceCount()); + if (constants.getNamespace(i).kind != Namespace.KIND_PACKAGE) { // only packages + continue; + } + constants.getNamespace(i).name_index = deobfuscation.deobfuscatePackageName(stringUsageTypes, stringUsages, namesMap, constants.getNamespace(i).name_index, renameType); + } + + // process reflection using getDefinitionByName too + for (MethodBody body : bodies) { + for (int ip = 0; ip < body.getCode().code.size(); ip++) { + if (body.getCode().code.get(ip).definition instanceof CallPropertyIns) { + int mIndex = body.getCode().code.get(ip).operands[0]; + if (mIndex > 0) { + Multiname m = constants.getMultiname(mIndex); + if (m.getNameWithNamespace(constants, true).equals("flash.utils.getDefinitionByName")) { + if (ip > 0) { + if (body.getCode().code.get(ip - 1).definition instanceof PushStringIns) { + int strIndex = body.getCode().code.get(ip - 1).operands[0]; + String fullname = constants.getString(strIndex); + String pkg = ""; + String name = fullname; + if (fullname.contains(".")) { + pkg = fullname.substring(0, fullname.lastIndexOf('.')); + name = fullname.substring(fullname.lastIndexOf('.') + 1); + } + if (!pkg.isEmpty()) { + int pkgStrIndex = constants.getStringId(pkg, true); + pkgStrIndex = deobfuscation.deobfuscatePackageName(stringUsageTypes, stringUsages, namesMap, pkgStrIndex, renameType); + pkg = constants.getString(pkgStrIndex); + } + int nameStrIndex = constants.getStringId(name, true); + nameStrIndex = deobfuscation.deobfuscateName(stringUsageTypes, stringUsages, namespaceUsages, namesMap, nameStrIndex, true, renameType); + name = constants.getString(nameStrIndex); + String fullChanged = ""; + if (!pkg.isEmpty()) { + fullChanged = pkg + "."; + } + fullChanged += name; + strIndex = constants.getStringId(fullChanged, true); + body.getCode().code.get(ip - 1).operands[0] = strIndex; + } + } + } + } + } + } + } + } + + public ABC(ABCInputStream ais, SWF swf, ABCContainerTag tag) throws IOException { + this.parentTag = tag; + minor_version = ais.readU16("minor_version"); + major_version = ais.readU16("major_version"); + logger.log(Level.FINE, "ABC minor_version: {0}, major_version: {1}", new Object[]{minor_version, major_version}); + + constants = new AVM2ConstantPool(); + ais.newDumpLevel("constant_pool", "cpool_info"); + + // constant integers + int constant_int_pool_count = ais.readU30("int_count"); + constants.constant_int = new ArrayList<>(constant_int_pool_count); + if (constant_int_pool_count > 0) { + constants.addInt(0); + } + if (constant_int_pool_count > 1) { + ais.newDumpLevel("integers", "integer[]"); + for (int i = 1; i < constant_int_pool_count; i++) { // index 0 not used. Values 1..n-1 + constants.addInt(ais.readS32("int")); + } + ais.endDumpLevel(); + } + + // constant unsigned integers + int constant_uint_pool_count = ais.readU30("uint_count"); + constants.constant_uint = new ArrayList<>(constant_uint_pool_count); + if (constant_uint_pool_count > 0) { + constants.addUInt(0); + } + if (constant_uint_pool_count > 1) { + ais.newDumpLevel("uintegers", "uinteger[]"); + for (int i = 1; i < constant_uint_pool_count; i++) { // index 0 not used. Values 1..n-1 + constants.addUInt(ais.readU32("uint")); + } + ais.endDumpLevel(); + } + + // constant double + int constant_double_pool_count = ais.readU30("double_count"); + constants.constant_double = new ArrayList<>(constant_double_pool_count); + if (constant_double_pool_count > 0) { + constants.addDouble(0); + } + if (constant_double_pool_count > 1) { + ais.newDumpLevel("doubles", "double[]"); + for (int i = 1; i < constant_double_pool_count; i++) { // index 0 not used. Values 1..n-1 + constants.addDouble(ais.readDouble("double")); + } + ais.endDumpLevel(); + } + + // constant decimal + if (minor_version >= MINORwithDECIMAL) { + int constant_decimal_pool_count = ais.readU30("decimal_count"); + constants.constant_decimal = new ArrayList<>(constant_decimal_pool_count); + if (constant_decimal_pool_count > 0) { + constants.addDecimal(null); + } + if (constant_decimal_pool_count > 1) { + ais.newDumpLevel("decimals", "decimal[]"); + for (int i = 1; i < constant_decimal_pool_count; i++) { // index 0 not used. Values 1..n-1 + constants.addDecimal(ais.readDecimal("decimal")); + } + ais.endDumpLevel(); + } + } else { + constants.constant_decimal = new ArrayList<>(0); + } + + // constant string + int constant_string_pool_count = ais.readU30("string_count"); + constants.constant_string = new ArrayList<>(constant_string_pool_count); + stringOffsets = new long[constant_string_pool_count]; + if (constant_string_pool_count > 0) { + constants.addString(""); + } + if (constant_string_pool_count > 1) { + ais.newDumpLevel("strings", "string[]"); + for (int i = 1; i < constant_string_pool_count; i++) { // index 0 not used. Values 1..n-1 + long pos = ais.getPosition(); + constants.addString(ais.readString("string")); + stringOffsets[i] = pos; + } + ais.endDumpLevel(); + } + + // constant namespace + int constant_namespace_pool_count = ais.readU30("namespace_count"); + constants.constant_namespace = new ArrayList<>(constant_namespace_pool_count); + if (constant_namespace_pool_count > 0) { + constants.addNamespace(null); + } + if (constant_namespace_pool_count > 1) { + ais.newDumpLevel("namespaces", "namespace[]"); + for (int i = 1; i < constant_namespace_pool_count; i++) { // index 0 not used. Values 1..n-1 + constants.addNamespace(ais.readNamespace("namespace")); + } + ais.endDumpLevel(); + } + + // constant namespace set + int constant_namespace_set_pool_count = ais.readU30("ns_set_count"); + constants.constant_namespace_set = new ArrayList<>(constant_namespace_set_pool_count); + if (constant_namespace_set_pool_count > 0) { + constants.addNamespaceSet(null); + } + if (constant_namespace_set_pool_count > 1) { + ais.newDumpLevel("ns_sets", "ns_set[]"); + for (int i = 1; i < constant_namespace_set_pool_count; i++) { // index 0 not used. Values 1..n-1 + ais.newDumpLevel("ns_set_infos", "ns_set_info[]"); + constants.addNamespaceSet(new NamespaceSet()); + int namespace_count = ais.readU30("count"); + constants.getNamespaceSet(i).namespaces = new int[namespace_count]; + for (int j = 0; j < namespace_count; j++) { + constants.getNamespaceSet(i).namespaces[j] = ais.readU30("ns"); + } + ais.endDumpLevel(); + } + ais.endDumpLevel(); + } + + // constant multiname + int constant_multiname_pool_count = ais.readU30("multiname_count"); + constants.constant_multiname = new ArrayList<>(constant_multiname_pool_count); + if (constant_multiname_pool_count > 0) { + constants.addMultiname(null); + } + if (constant_multiname_pool_count > 1) { + ais.newDumpLevel("multiname", "multinames[]"); + for (int i = 1; i < constant_multiname_pool_count; i++) { // index 0 not used. Values 1..n-1 + constants.addMultiname(ais.readMultiname("multiname")); + } + ais.endDumpLevel(); + } + + ais.endDumpLevel(); // cpool_info + + // method info + int methods_count = ais.readU30("methods_count"); + method_info = new ArrayList<>(methods_count); // MethodInfo[methods_count]; + for (int i = 0; i < methods_count; i++) { + method_info.add(ais.readMethodInfo("method")); + } + + // metadata info + int metadata_count = ais.readU30("metadata_count"); + metadata_info = new ArrayList<>(metadata_count); + for (int i = 0; i < metadata_count; i++) { + int name_index = ais.readU30("name_index"); + int values_count = ais.readU30("values_count"); + int[] keys = new int[values_count]; + for (int v = 0; v < values_count; v++) { + keys[v] = ais.readU30("key"); + } + int[] values = new int[values_count]; + for (int v = 0; v < values_count; v++) { + values[v] = ais.readU30("value"); + } + metadata_info.add(new MetadataInfo(name_index, keys, values)); + } + + int class_count = ais.readU30("class_count"); + instance_info = new ArrayList<>(class_count); + for (int i = 0; i < class_count; i++) { + instance_info.add(ais.readInstanceInfo("instance")); + } + class_info = new ArrayList<>(class_count); + for (int i = 0; i < class_count; i++) { + ais.newDumpLevel("class", "class_info"); + ClassInfo ci = new ClassInfo(null); // do not create Traits in constructor + ci.cinit_index = ais.readU30("cinit_index"); + ci.static_traits = ais.readTraits("static_traits"); + class_info.add(ci); + ais.endDumpLevel(); + } + int script_count = ais.readU30("script_count"); + script_info = new ArrayList<>(script_count); + for (int i = 0; i < script_count; i++) { + ais.newDumpLevel("script", "script_info"); + ScriptInfo si = new ScriptInfo(null); // do not create Traits in constructor + si.init_index = ais.readU30("init_index"); + si.traits = ais.readTraits("traits"); + script_info.add(si); + ais.endDumpLevel(); + si.setModified(false); + } + + int bodies_count = ais.readU30("bodies_count"); + bodies = new ArrayList<>(bodies_count); + for (int i = 0; i < bodies_count; i++) { + ais.newDumpLevel("method_body", "method_body_info"); + MethodBody mb = new MethodBody(null, null, null); // do not create Traits in constructor + mb.method_info = ais.readU30("method_info"); + mb.max_stack = ais.readU30("max_stack"); + mb.max_regs = ais.readU30("max_regs"); + mb.init_scope_depth = ais.readU30("init_scope_depth"); + mb.max_scope_depth = ais.readU30("max_scope_depth"); + int code_length = ais.readU30("code_length"); + mb.setCodeBytes(ais.readBytes(code_length, "code")); + int ex_count = ais.readU30("ex_count"); + mb.exceptions = new ABCException[ex_count]; + for (int j = 0; j < ex_count; j++) { + ABCException abce = new ABCException(); + abce.start = ais.readU30("start"); + abce.end = ais.readU30("end"); + abce.target = ais.readU30("target"); + abce.type_index = ais.readU30("type_index"); + abce.name_index = ais.readU30("name_index"); + mb.exceptions[j] = abce; + } + mb.traits = ais.readTraits("traits"); + bodies.add(mb); + method_info.get(mb.method_info).setBody(mb); + ais.endDumpLevel(); + + SWFDecompilerPlugin.fireMethodBodyParsed(mb, swf); + } + + /*for(int i=0;i()); + } catch (InterruptedException ex) { + Logger.getLogger(ABC.class.getName()).log(Level.SEVERE, null, ex); + } + System.out.println(""+t.toString()); + } + //System.exit(0);*/ + SWFDecompilerPlugin.fireAbcParsed(this, swf); + } + + public void saveToStream(OutputStream os) throws IOException { + ABCOutputStream aos = new ABCOutputStream(os); + aos.writeU16(minor_version); + aos.writeU16(major_version); + + aos.writeU30(constants.getIntCount()); + for (int i = 1; i < constants.getIntCount(); i++) { + aos.writeS32(constants.getInt(i)); + } + aos.writeU30(constants.getUIntCount()); + for (int i = 1; i < constants.getUIntCount(); i++) { + aos.writeU32(constants.getUInt(i)); + } + + aos.writeU30(constants.getDoubleCount()); + for (int i = 1; i < constants.getDoubleCount(); i++) { + aos.writeDouble(constants.getDouble(i)); + } + + if (minor_version >= MINORwithDECIMAL) { + aos.writeU30(constants.getDecimalCount()); + for (int i = 1; i < constants.getDecimalCount(); i++) { + aos.writeDecimal(constants.getDecimal(i)); + } + } + + aos.writeU30(constants.getStringCount()); + for (int i = 1; i < constants.getStringCount(); i++) { + aos.writeString(constants.getString(i)); + } + + aos.writeU30(constants.getNamespaceCount()); + for (int i = 1; i < constants.getNamespaceCount(); i++) { + aos.writeNamespace(constants.getNamespace(i)); + } + + aos.writeU30(constants.getNamespaceSetCount()); + for (int i = 1; i < constants.getNamespaceSetCount(); i++) { + aos.writeU30(constants.getNamespaceSet(i).namespaces.length); + for (int j = 0; j < constants.getNamespaceSet(i).namespaces.length; j++) { + aos.writeU30(constants.getNamespaceSet(i).namespaces[j]); + } + } + + aos.writeU30(constants.getMultinameCount()); + for (int i = 1; i < constants.getMultinameCount(); i++) { + aos.writeMultiname(constants.getMultiname(i)); + } + + aos.writeU30(method_info.size()); + for (MethodInfo mi : method_info) { + aos.writeMethodInfo(mi); + } + + aos.writeU30(metadata_info.size()); + for (MetadataInfo mi : metadata_info) { + aos.writeU30(mi.name_index); + aos.writeU30(mi.values.length); + for (int j = 0; j < mi.values.length; j++) { + aos.writeU30(mi.keys[j]); + } + for (int j = 0; j < mi.values.length; j++) { + aos.writeU30(mi.values[j]); + } + } + + aos.writeU30(class_info.size()); + for (InstanceInfo ii : instance_info) { + aos.writeInstanceInfo(ii); + } + for (ClassInfo ci : class_info) { + aos.writeU30(ci.cinit_index); + aos.writeTraits(ci.static_traits); + } + aos.writeU30(script_info.size()); + for (ScriptInfo si : script_info) { + aos.writeU30(si.init_index); + aos.writeTraits(si.traits); + } + + aos.writeU30(bodies.size()); + for (MethodBody mb : bodies) { + aos.writeU30(mb.method_info); + aos.writeU30(mb.max_stack); + aos.writeU30(mb.max_regs); + aos.writeU30(mb.init_scope_depth); + aos.writeU30(mb.max_scope_depth); + byte[] codeBytes = mb.getCodeBytes(); + aos.writeU30(codeBytes.length); + aos.write(codeBytes); + aos.writeU30(mb.exceptions.length); + for (int j = 0; j < mb.exceptions.length; j++) { + aos.writeU30(mb.exceptions[j].start); + aos.writeU30(mb.exceptions[j].end); + aos.writeU30(mb.exceptions[j].target); + aos.writeU30(mb.exceptions[j].type_index); + aos.writeU30(mb.exceptions[j].name_index); + } + aos.writeTraits(mb.traits); + } + } + + public MethodBody findBody(int methodInfo) { + if (methodInfo < 0) { + return null; + } + return method_info.get(methodInfo).getBody(); + } + + public int findBodyIndex(int methodInfo) { + if (methodInfo == -1) { + return -1; + } + + Integer result = getBodyIdxFromMethodIdx().get(methodInfo); + if (result == null) { + return -1; + } + + return result; + } + + public MethodBody findBodyByClassAndName(String className, String methodName) { + for (int i = 0; i < instance_info.size(); i++) { + if (className.equals(constants.getMultiname(instance_info.get(i).name_index).getName(constants, new ArrayList(), true))) { + for (Trait t : instance_info.get(i).instance_traits.traits) { + if (t instanceof TraitMethodGetterSetter) { + TraitMethodGetterSetter t2 = (TraitMethodGetterSetter) t; + if (methodName.equals(t2.getName(this).getName(constants, new ArrayList(), true))) { + for (MethodBody body : bodies) { + if (body.method_info == t2.method_info) { + return body; + } + } + } + } + } + //break; + } + } + for (int i = 0; i < class_info.size(); i++) { + if (className.equals(constants.getMultiname(instance_info.get(i).name_index).getName(constants, new ArrayList(), true))) { + for (Trait t : class_info.get(i).static_traits.traits) { + if (t instanceof TraitMethodGetterSetter) { + TraitMethodGetterSetter t2 = (TraitMethodGetterSetter) t; + if (methodName.equals(t2.getName(this).getName(constants, new ArrayList(), true))) { + for (MethodBody body : bodies) { + if (body.method_info == t2.method_info) { + return body; + } + } + } + } + } + //break; + } + } + + return null; + } + + public boolean isStaticTraitId(int classIndex, int traitId) { + if (traitId < class_info.get(classIndex).static_traits.traits.size()) { + return true; + } else if (traitId < class_info.get(classIndex).static_traits.traits.size() + instance_info.get(classIndex).instance_traits.traits.size()) { + return false; + } else { + return true; // Can be class or instance initializer + } + } + + public Trait findTraitByTraitId(int classIndex, int traitId) { + if (classIndex == -1) { + return null; + } + List staticTraits = class_info.get(classIndex).static_traits.traits; + if (traitId < staticTraits.size()) { + return staticTraits.get(traitId); + } else { + List instanceTraits = instance_info.get(classIndex).instance_traits.traits; + if (traitId < staticTraits.size() + instanceTraits.size()) { + traitId -= staticTraits.size(); + return instanceTraits.get(traitId); + } else { + return null; // Can be class or instance initializer + } + } + } + + public int findMethodIdByTraitId(int classIndex, int traitId) { + if (classIndex == -1) { + return -1; + } + List staticTraits = class_info.get(classIndex).static_traits.traits; + if (traitId < staticTraits.size()) { + if (staticTraits.get(traitId) instanceof TraitMethodGetterSetter) { + return ((TraitMethodGetterSetter) staticTraits.get(traitId)).method_info; + } else { + return -1; + } + } else { + List instanceTraits = instance_info.get(classIndex).instance_traits.traits; + if (traitId < staticTraits.size() + instanceTraits.size()) { + traitId -= staticTraits.size(); + if (instanceTraits.get(traitId) instanceof TraitMethodGetterSetter) { + return ((TraitMethodGetterSetter) instanceTraits.get(traitId)).method_info; + } else { + return -1; + } + } else { + traitId -= staticTraits.size() + instanceTraits.size(); + if (traitId == 0) { + return instance_info.get(classIndex).iinit_index; + } else if (traitId == 1) { + return class_info.get(classIndex).cinit_index; + } else { + return -1; + } + } + } + } + + private Map getNamespaceMap() { + if (namespaceMap == null) { + Map map = new HashMap<>(); + for (ScriptInfo si : script_info) { + for (Trait t : si.traits.traits) { + if (t instanceof TraitSlotConst) { + TraitSlotConst s = ((TraitSlotConst) t); + if (s.isNamespace()) { + String key = constants.getNamespace(s.value_index).getName(constants, true); // assume not null + String val = constants.getMultiname(s.name_index).getNameWithNamespace(constants, true); + map.put(key, val); + } + } + } + } + namespaceMap = map; + } + + return namespaceMap; + } + + private AVM2Deobfuscation getDeobfuscation() { + if (deobfuscation == null) { + deobfuscation = new AVM2Deobfuscation(constants); + } + + return deobfuscation; + } + + private Map getBodyIdxFromMethodIdx() { + if (bodyIdxFromMethodIdx == null) { + Map map = new HashMap<>(bodies.size()); + for (int i = 0; i < bodies.size(); i++) { + MethodBody mb = bodies.get(i); + map.put(mb.method_info, i); + } + + bodyIdxFromMethodIdx = map; + } + + return bodyIdxFromMethodIdx; + } + + public String nsValueToName(String value) { + if (getNamespaceMap().containsKey(value)) { + return getNamespaceMap().get(value); + } else { + String ns = getDeobfuscation().builtInNs(value); + if (ns == null) { + return ""; + } else { + return ns; + } + } + } + + public List getScriptPacks(String packagePrefix) { + List ret = new ArrayList<>(); + for (int i = 0; i < script_info.size(); i++) { + ret.addAll(script_info.get(i).getPacks(this, i, packagePrefix)); + } + return ret; + } + + public void dump(OutputStream os) { + Utf8PrintWriter output; + output = new Utf8PrintWriter(os); + constants.dump(output); + for (int i = 0; i < method_info.size(); i++) { + output.println("MethodInfo[" + i + "]:" + method_info.get(i).toString(constants, new ArrayList())); + } + for (int i = 0; i < metadata_info.size(); i++) { + output.println("MetadataInfo[" + i + "]:" + metadata_info.get(i).toString(constants)); + } + for (int i = 0; i < instance_info.size(); i++) { + output.println("InstanceInfo[" + i + "]:" + instance_info.get(i).toString(this, new ArrayList())); + } + for (int i = 0; i < class_info.size(); i++) { + output.println("ClassInfo[" + i + "]:" + class_info.get(i).toString(this, new ArrayList())); + } + for (int i = 0; i < script_info.size(); i++) { + output.println("ScriptInfo[" + i + "]:" + script_info.get(i).toString(this, new ArrayList())); + } + for (int i = 0; i < bodies.size(); i++) { + output.println("MethodBody[" + i + "]:"); //+ bodies[i].toString(this, constants, method_info)); + } + } + + private void checkMultinameUsedInMethod(int multinameIndex, int methodInfo, List ret, int classIndex, int traitIndex, boolean isStatic, boolean isInitializer, Traits traits, int parentTraitIndex) { + for (int p = 0; p < method_info.get(methodInfo).param_types.length; p++) { + if (method_info.get(methodInfo).param_types[p] == multinameIndex) { + ret.add(new MethodParamsMultinameUsage(this, multinameIndex, classIndex, traitIndex, isStatic, isInitializer, traits, parentTraitIndex)); + break; + } + } + if (method_info.get(methodInfo).ret_type == multinameIndex) { + ret.add(new MethodReturnTypeMultinameUsage(this, multinameIndex, classIndex, traitIndex, isStatic, isInitializer, traits, parentTraitIndex)); + } + MethodBody body = findBody(methodInfo); + if (body != null) { + findMultinameUsageInTraits(body.traits, multinameIndex, isStatic, classIndex, ret, traitIndex); + for (ABCException e : body.exceptions) { + if ((e.name_index == multinameIndex) || (e.type_index == multinameIndex)) { + ret.add(new MethodBodyMultinameUsage(this, multinameIndex, classIndex, traitIndex, isStatic, isInitializer, traits, parentTraitIndex)); + return; + } + } + for (AVM2Instruction ins : body.getCode().code) { + for (int o = 0; o < ins.definition.operands.length; o++) { + if (ins.definition.operands[o] == AVM2Code.DAT_MULTINAME_INDEX) { + if (ins.operands[o] == multinameIndex) { + ret.add(new MethodBodyMultinameUsage(this, multinameIndex, classIndex, traitIndex, isStatic, isInitializer, traits, parentTraitIndex)); + return; + } + } + } + } + } + } + + private void findMultinameUsageInTraits(Traits traits, int multinameIndex, boolean isStatic, int classIndex, List ret, int parentTraitIndex) { + for (int t = 0; t < traits.traits.size(); t++) { + if (traits.traits.get(t) instanceof TraitSlotConst) { + TraitSlotConst tsc = (TraitSlotConst) traits.traits.get(t); + if (tsc.name_index == multinameIndex) { + ret.add(new ConstVarNameMultinameUsage(this, multinameIndex, classIndex, t, isStatic, traits, parentTraitIndex)); + } + if (tsc.type_index == multinameIndex) { + ret.add(new ConstVarTypeMultinameUsage(this, multinameIndex, classIndex, t, isStatic, traits, parentTraitIndex)); + } + } + if (traits.traits.get(t) instanceof TraitMethodGetterSetter) { + TraitMethodGetterSetter tmgs = (TraitMethodGetterSetter) traits.traits.get(t); + if (tmgs.name_index == multinameIndex) { + ret.add(new MethodNameMultinameUsage(this, multinameIndex, classIndex, t, isStatic, false, traits, parentTraitIndex)); + } + checkMultinameUsedInMethod(multinameIndex, tmgs.method_info, ret, classIndex, t, isStatic, false, traits, parentTraitIndex); + } + } + } + + public List findMultinameDefinition(int multinameIndex) { + List usages = findMultinameUsage(multinameIndex); + List ret = new ArrayList<>(); + for (MultinameUsage u : usages) { + if (u instanceof DefinitionUsage) { + ret.add(u); + } + } + return ret; + } + + public List findMultinameUsage(int multinameIndex) { + List ret = new ArrayList<>(); + if (multinameIndex == 0) { + return ret; + } + for (int c = 0; c < instance_info.size(); c++) { + if (instance_info.get(c).name_index == multinameIndex) { + ret.add(new ClassNameMultinameUsage(this, multinameIndex, c)); + } + if (instance_info.get(c).super_index == multinameIndex) { + ret.add(new ExtendsMultinameUsage(this, multinameIndex, c)); + } + for (int i = 0; i < instance_info.get(c).interfaces.length; i++) { + if (instance_info.get(c).interfaces[i] == multinameIndex) { + ret.add(new ImplementsMultinameUsage(this, multinameIndex, c)); + } + } + checkMultinameUsedInMethod(multinameIndex, instance_info.get(c).iinit_index, ret, c, 0, false, true, null, -1); + checkMultinameUsedInMethod(multinameIndex, class_info.get(c).cinit_index, ret, c, 0, true, true, null, -1); + findMultinameUsageInTraits(instance_info.get(c).instance_traits, multinameIndex, false, c, ret, -1); + findMultinameUsageInTraits(class_info.get(c).static_traits, multinameIndex, true, c, ret, -1); + } + loopm: + for (int m = 1; m < constants.getMultinameCount(); m++) { + if (constants.getMultiname(m).kind == Multiname.TYPENAME) { + if (constants.getMultiname(m).qname_index == multinameIndex) { + ret.add(new TypeNameMultinameUsage(this, m)); + continue; + } + for (int mp : constants.getMultiname(m).params) { + if (mp == multinameIndex) { + ret.add(new TypeNameMultinameUsage(this, m)); + continue loopm; + } + } + } + } + return ret; + } + + public int findMethodInfoByName(int classId, String methodName) { + if (classId > -1) { + for (Trait t : instance_info.get(classId).instance_traits.traits) { + if (t instanceof TraitMethodGetterSetter) { + if (t.getName(this).getName(constants, new ArrayList(), true).equals(methodName)) { + return ((TraitMethodGetterSetter) t).method_info; + } + } + } + } + return -1; + } + + public int findMethodBodyByName(int classId, String methodName) { + if (classId > -1) { + for (Trait t : instance_info.get(classId).instance_traits.traits) { + if (t instanceof TraitMethodGetterSetter) { + if (t.getName(this).getName(constants, new ArrayList(), true).equals(methodName)) { + return findBodyIndex(((TraitMethodGetterSetter) t).method_info); + } + } + } + } + return -1; + } + + public int findMethodBodyByName(String className, String methodName) { + int classId = findClassByName(className); + return findMethodBodyByName(classId, methodName); + } + + public int findClassByName(String name) { + for (int c = 0; c < instance_info.size(); c++) { + String s = constants.getMultiname(instance_info.get(c).name_index).getNameWithNamespace(constants, true); + if (name.equals(s)) { + return c; + } + } + return -1; + } + + public List findScriptPacksByPath(String name) { + List ret = new ArrayList<>(); + List allPacks = getScriptPacks(null); // todo: honfika: use filter parameter + if (name.endsWith(".**") || name.equals("**") || name.endsWith(".++") || name.equals("++")) { + name = name.substring(0, name.length() - 2); + + for (ScriptPack en : allPacks) { + if (en.getClassPath().toString().startsWith(name)) { + ret.add(en); + } + } + } else if (name.endsWith(".*") || name.equals("*") || name.endsWith(".+") || name.equals("+")) { + name = name.substring(0, name.length() - 1); + for (ScriptPack en : allPacks) { + String classPathStr = en.getClassPath().toString(); + if (classPathStr.startsWith(name)) { + String rem = name.isEmpty() ? classPathStr : classPathStr.substring(name.length()); + if (!rem.contains(".")) { + ret.add(en); + } + } + } + } else { + ScriptPack p = findScriptPackByPath(name); + if (p != null) { + ret.add(p); + } + } + return ret; + + } + + public ScriptPack findScriptPackByPath(String name) { + List packs = getScriptPacks(null); + for (ScriptPack en : packs) { + if (en.getClassPath().toString().equals(name)) { + return en; + } + } + return null; + } + + private void removeClassFromTraits(Traits traits, int index) { + for (Trait t : traits.traits) { + if (t instanceof TraitClass) { + TraitClass tc = (TraitClass) t; + removeClassFromTraits(instance_info.get(tc.class_info).instance_traits, index); + removeClassFromTraits(class_info.get(tc.class_info).static_traits, index); + if (tc.class_info > index) { + tc.class_info--; + } + } + } + } + + public void addClass(ClassInfo ci, InstanceInfo ii, int index) { + for (MethodBody b : bodies) { + for (AVM2Instruction ins : b.getCode().code) { + for (int i = 0; i < ins.definition.operands.length; i++) { + if (ins.definition.operands[i] == AVM2Code.DAT_CLASS_INDEX) { + if (ins.operands[i] >= index) { + ins.operands[i]++; + } + } + } + } + } + for (ScriptInfo si : script_info) { + addClassInTraits(si.traits, index); + } + for (MethodBody b : bodies) { + addClassInTraits(b.traits, index); + } + instance_info.add(index, ii); + class_info.add(index, ci); + } + + private void addClassInTraits(Traits traits, int index) { + for (Trait t : traits.traits) { + if (t instanceof TraitClass) { + TraitClass tc = (TraitClass) t; + addClassInTraits(instance_info.get(tc.class_info).instance_traits, index); + addClassInTraits(class_info.get(tc.class_info).static_traits, index); + if (tc.class_info >= index) { + tc.class_info++; + } + } + } + } + + public void removeClass(int index) { + for (MethodBody b : bodies) { + for (AVM2Instruction ins : b.getCode().code) { + for (int i = 0; i < ins.definition.operands.length; i++) { + if (ins.definition.operands[i] == AVM2Code.DAT_CLASS_INDEX) { + if (ins.operands[i] > index) { + ins.operands[i]--; + } + } + } + } + } + for (ScriptInfo si : script_info) { + removeClassFromTraits(si.traits, index); + } + for (MethodBody b : bodies) { + removeClassFromTraits(b.traits, index); + } + instance_info.remove(index); + class_info.remove(index); + } + + private void removeMethodFromTraits(Traits traits, int index) { + for (Trait t : traits.traits) { + if (t instanceof TraitClass) { + TraitClass tc = (TraitClass) t; + removeMethodFromTraits(instance_info.get(tc.class_info).instance_traits, index); + removeMethodFromTraits(class_info.get(tc.class_info).static_traits, index); + } + if (t instanceof TraitMethodGetterSetter) { + TraitMethodGetterSetter tmgs = (TraitMethodGetterSetter) t; + if (tmgs.method_info > index) { + tmgs.method_info--; + } + } + if (t instanceof TraitFunction) { + TraitFunction tf = (TraitFunction) t; + if (tf.method_info > index) { + tf.method_info--; + } + } + } + } + + public void removeMethod(int index) { + + int bindex = -1; + for (int b = 0; b < bodies.size(); b++) { + if (bodies.get(b).method_info == index) { + bodies.remove(b); + bindex = b; + b--; + } + } + + for (MethodBody b : bodies) { + if (b.method_info > index) { + b.method_info--; + } + for (AVM2Instruction ins : b.getCode().code) { + for (int i = 0; i < ins.definition.operands.length; i++) { + if (ins.definition.operands[i] == AVM2Code.DAT_METHOD_INDEX) { + if (ins.operands[i] > index) { + ins.operands[i]--; + } + } + } + } + removeMethodFromTraits(b.traits, index); + } + + for (int c = 0; c < instance_info.size(); c++) { + InstanceInfo ii = instance_info.get(c); + if (ii.iinit_index > index) { + ii.iinit_index--; + } + ClassInfo ci = class_info.get(c); + if (ci.cinit_index > index) { + ci.cinit_index--; + } + } + + for (ScriptInfo si : script_info) { + if (si.init_index > index) { + si.init_index--; + } + removeMethodFromTraits(si.traits, index); + } + + bodyIdxFromMethodIdx = null; + + method_info.remove(index); + } + + public void replaceScriptPack(ScriptPack pack, String as) throws AVM2ParseException, CompilationException, IOException, InterruptedException { + String scriptName = pack.getPathScriptName() + ".as"; + int oldIndex = pack.scriptIndex; + int newIndex = script_info.size(); + String documentClass = getSwf().getDocumentClass(); + boolean isDocumentClass = documentClass != null && documentClass.equals(pack.getClassPath().toString()); + + ScriptInfo si = script_info.get(oldIndex); + si.delete(this, true); + int newClassIndex = instance_info.size(); + for (Trait t : si.traits.traits) { + if (t instanceof TraitClass) { + TraitClass tc = (TraitClass) t; + newClassIndex = tc.class_info + 1; + } + } + ActionScriptParser.compile(as, this, new ArrayList(), isDocumentClass, scriptName, newClassIndex); + // Move newly added script to its position + script_info.set(oldIndex, script_info.get(newIndex)); + script_info.remove(newIndex); + script_info.get(oldIndex).setModified(true); + pack(); // removes old classes/methods + ((Tag) parentTag).setModified(true); + } + + public void pack() { + for (int c = 0; c < instance_info.size(); c++) { + if (instance_info.get(c).deleted) { + removeClass(c); + c--; + } + } + for (int m = 0; m < method_info.size(); m++) { + if (method_info.get(m).deleted) { + removeMethod(m); + m--; + } + } + } +} 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 34e800683..981416490 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 @@ -1,508 +1,508 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc; - -import com.jpexs.decompiler.flash.EndOfStreamException; -import com.jpexs.decompiler.flash.abc.types.Decimal; -import com.jpexs.decompiler.flash.abc.types.InstanceInfo; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.flash.abc.types.Multiname; -import com.jpexs.decompiler.flash.abc.types.Namespace; -import com.jpexs.decompiler.flash.abc.types.ValueKind; -import com.jpexs.decompiler.flash.abc.types.traits.Trait; -import com.jpexs.decompiler.flash.abc.types.traits.TraitClass; -import com.jpexs.decompiler.flash.abc.types.traits.TraitFunction; -import com.jpexs.decompiler.flash.abc.types.traits.TraitMethodGetterSetter; -import com.jpexs.decompiler.flash.abc.types.traits.TraitSlotConst; -import com.jpexs.decompiler.flash.abc.types.traits.Traits; -import com.jpexs.decompiler.flash.dumpview.DumpInfo; -import com.jpexs.helpers.MemoryInputStream; -import com.jpexs.helpers.utf8.Utf8Helper; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -public class ABCInputStream implements AutoCloseable { - - private static final int CLASS_PROTECTED_NS = 8; - - private static final int ATTR_METADATA = 4; - - private final MemoryInputStream is; - - private ByteArrayOutputStream bufferOs = null; - - public static final boolean DEBUG_READ = false; - - public DumpInfo dumpInfo; - - private byte[] stringDataBuffer = new byte[256]; - - public void startBuffer() { - if (bufferOs == null) { - bufferOs = new ByteArrayOutputStream(); - } else { - bufferOs.reset(); - } - } - - public byte[] stopBuffer() { - if (bufferOs == null) { - return new byte[0]; - } - byte[] ret = bufferOs.toByteArray(); - bufferOs.reset(); - return ret; - } - - public ABCInputStream(MemoryInputStream is) { - this.is = is; - } - - /** - * Sets position in bytes in the stream - * - * @param pos Number of bytes - * @throws java.io.IOException - */ - public void seek(long pos) throws IOException { - is.seek(pos); - } - - public DumpInfo newDumpLevel(String name, String type) { - if (dumpInfo != null) { - long startByte = is.getPos(); - DumpInfo di = new DumpInfo(name, type, null, startByte, 0, 0, 0); - di.parent = dumpInfo; - dumpInfo.getChildInfos().add(di); - dumpInfo = di; - } - - return dumpInfo; - } - - public void endDumpLevel() { - endDumpLevel(null); - } - - public void endDumpLevel(Object value) { - if (dumpInfo != null) { - dumpInfo.lengthBytes = is.getPos() - dumpInfo.startByte; - dumpInfo.previewValue = value; - dumpInfo = dumpInfo.parent; - } - } - - public void endDumpLevelUntil(DumpInfo di) { - if (di != null) { - while (dumpInfo != null && dumpInfo != di) { - endDumpLevel(); - } - } - } - - private int readInternal() throws IOException { - int i = is.read(); - if (i == -1) { - throw new EndOfStreamException(); - } - if (DEBUG_READ) { - System.out.println("Read:0x" + Integer.toHexString(i)); - } - if (bufferOs != null) { - if (i != -1) { - bufferOs.write(i); - } - } - return i; - } - - public int read(String name) throws IOException { - newDumpLevel(name, "byte"); - int ret = readInternal(); - endDumpLevel(ret); - return ret; - } - - private int read(byte[] b) throws IOException { - int currBytesRead = is.read(b); - if (DEBUG_READ) { - StringBuilder sb = new StringBuilder("Read["); - sb.append(currBytesRead); - sb.append('/'); - sb.append(b.length); - sb.append("]: "); - for (int jj = 0; jj < currBytesRead; jj++) { - sb.append("0x"); - sb.append(Integer.toHexString(b[jj])); - sb.append(' '); - } - System.out.println(sb.toString()); - } - if (bufferOs != null) { - if (currBytesRead > 0) { - bufferOs.write(b, 0, currBytesRead); - } - } - return currBytesRead; - } - - public int readU8(String name) throws IOException { - newDumpLevel(name, "U8"); - int ret = readInternal(); - endDumpLevel(ret); - return ret; - } - - private long readU32Internal() throws IOException { - int i; - long ret = 0; - int bytePos = 0; - int byteCount = 0; - boolean nextByte; - do { - i = readInternal(); - nextByte = (i >> 7) == 1; - i &= 0x7f; - ret += (((long) i) << bytePos); - byteCount++; - bytePos += 7; - } while (nextByte); - return ret; - } - - public long readU32(String name) throws IOException { - newDumpLevel(name, "U32"); - long ret = readU32Internal(); - endDumpLevel(ret); - return ret; - } - - private int readU30Internal() throws IOException { - return (int) readU32Internal(); - } - - public int readU30(String name) throws IOException { - newDumpLevel(name, "U30"); - int ret = readU30Internal(); - endDumpLevel(ret); - return ret; - } - - public int readS24(String name) throws IOException { - newDumpLevel(name, "S24"); - int ret = (readInternal()) + (readInternal() << 8) + (readInternal() << 16); - - if ((ret >> 23) == 1) { - ret |= 0xff000000; - } - - endDumpLevel(ret); - return ret; - } - - public int readU16(String name) throws IOException { - newDumpLevel(name, "U16"); - int ret = (readInternal()) + (readInternal() << 8); - endDumpLevel(ret); - return ret; - } - - public long readS32(String name) throws IOException { - int i; - long ret = 0; - int bytePos = 0; - int byteCount = 0; - boolean nextByte; - newDumpLevel(name, "S32"); - do { - i = readInternal(); - nextByte = (i >> 7) == 1; - i &= 0x7f; - ret += (i << bytePos); - byteCount++; - bytePos += 7; - if (bytePos == 35) { - if ((ret >> 31) == 1) { - ret = -(ret & 0x7fffffff); - } - break; - } - } while (nextByte); - endDumpLevel(ret); - return ret; - } - - public int available() throws IOException { - return is.available(); - } - - private long readLong() throws IOException { - safeRead(8, stringDataBuffer); - byte[] readBuffer = stringDataBuffer; - return (((long) readBuffer[7] << 56) - + ((long) (readBuffer[6] & 255) << 48) - + ((long) (readBuffer[5] & 255) << 40) - + ((long) (readBuffer[4] & 255) << 32) - + ((long) (readBuffer[3] & 255) << 24) - + ((readBuffer[2] & 255) << 16) - + ((readBuffer[1] & 255) << 8) - + ((readBuffer[0] & 255))); - } - - public double readDouble(String name) throws IOException { - newDumpLevel(name, "Double"); - long el = readLong(); - double ret = Double.longBitsToDouble(el); - endDumpLevel(ret); - return ret; - } - - private void safeRead(int count, byte[] data) throws IOException { - for (int i = 0; i < count; i++) { - data[i] = (byte) readInternal(); - } - } - - public Namespace readNamespace(String name) throws IOException { - newDumpLevel(name, "Namespace"); - int kind = read("kind"); - int name_index = 0; - for (int k = 0; k < Namespace.nameSpaceKinds.length; k++) { - if (Namespace.nameSpaceKinds[k] == kind) { - name_index = readU30("name_index"); - break; - } - } - endDumpLevel(); - return new Namespace(kind, name_index); - } - - public Multiname readMultiname(String name) throws IOException { - int kind = readU8("kind"); - int namespace_index = 0; - int name_index = 0; - int namespace_set_index = 0; - int qname_index = 0; - List params = new ArrayList<>(); - - newDumpLevel(name, "Multiname"); - if ((kind == Multiname.QNAME) || (kind == Multiname.QNAMEA)) { - namespace_index = readU30("namespace_index"); - name_index = readU30("name_index"); - } else if ((kind == Multiname.RTQNAME) || (kind == Multiname.RTQNAMEA)) { - name_index = readU30("name_index"); - } else if ((kind == Multiname.RTQNAMEL) || (kind == Multiname.RTQNAMELA)) { - - } else if ((kind == Multiname.MULTINAME) || (kind == Multiname.MULTINAMEA)) { - name_index = readU30("name_index"); - namespace_set_index = readU30("namespace_set_index"); - } else if ((kind == Multiname.MULTINAMEL) || (kind == Multiname.MULTINAMELA)) { - namespace_set_index = readU30("namespace_set_index"); - } else if (kind == Multiname.TYPENAME) { - qname_index = readU30("qname_index"); // Multiname index!!! - int paramsLength = readU30("paramsLength"); - for (int i = 0; i < paramsLength; i++) { - params.add(readU30("param")); // multiname indices! - } - } else { - throw new IOException("Unknown kind of Multiname:0x" + Integer.toHexString(kind)); - } - - endDumpLevel(); - return new Multiname(kind, name_index, namespace_index, namespace_set_index, qname_index, params); - } - - public MethodInfo readMethodInfo(String name) throws IOException { - newDumpLevel(name, "method_info"); - int param_count = readU30("param_count"); - int ret_type = readU30("ret_type"); - int[] param_types = new int[param_count]; - for (int i = 0; i < param_count; i++) { - param_types[i] = readU30("param_type"); - } - int name_index = readU30("name_index"); - int flags = read("flags"); - - // 1=need_arguments, 2=need_activation, 4=need_rest 8=has_optional (16=ignore_rest, 32=explicit,) 64=setsdxns, 128=has_paramnames - ValueKind[] optional = new ValueKind[0]; - if ((flags & 8) == 8) { // if has_optional - int optional_count = readU30("optional_count"); - optional = new ValueKind[optional_count]; - for (int i = 0; i < optional_count; i++) { - optional[i] = new ValueKind(readU30("value_index"), read("value_kind")); - } - } - - int[] param_names = new int[param_count]; - if ((flags & 128) == 128) { // if has_paramnames - for (int i = 0; i < param_count; i++) { - param_names[i] = readU30("param_name"); - } - } - - endDumpLevel(); - return new MethodInfo(param_types, ret_type, name_index, flags, optional, param_names); - } - - public Trait readTrait(String name) throws IOException { - newDumpLevel(name, "Trait"); - long pos = getPosition(); - startBuffer(); - int name_index = readU30("name_index"); - int kind = read("kind"); - int kindType = 0xf & kind; - int kindFlags = kind >> 4; - Trait trait; - - switch (kindType) { - case 0: // slot - case 6: // const - TraitSlotConst t1 = new TraitSlotConst(); - t1.slot_id = readU30("slot_id"); - t1.type_index = readU30("type_index"); - t1.value_index = readU30("value_index"); - if (t1.value_index != 0) { - t1.value_kind = read("value_kind"); - } - trait = t1; - break; - case 1: // method - case 2: // getter - case 3: // setter - TraitMethodGetterSetter t2 = new TraitMethodGetterSetter(); - t2.disp_id = readU30("disp_id"); - t2.method_info = readU30("method_info"); - trait = t2; - break; - case 4: // class - TraitClass t3 = new TraitClass(); - t3.slot_id = readU30("slot_id"); - t3.class_info = readU30("class_info"); - trait = t3; - break; - case 5: // function - TraitFunction t4 = new TraitFunction(); - t4.slot_id = readU30("slot_id"); - t4.method_info = readU30("method_info"); - trait = t4; - break; - default: - throw new IOException("Unknown trait kind:" + kind); - } - trait.fileOffset = pos; - trait.kindType = kindType; - trait.kindFlags = kindFlags; - trait.name_index = name_index; - if ((kindFlags & ATTR_METADATA) != 0) { - int metadata_count = readU30("metadata_count"); - trait.metadata = new int[metadata_count]; - for (int i = 0; i < metadata_count; i++) { - trait.metadata[i] = readU30("metadata"); - } - } - trait.bytes = stopBuffer(); - endDumpLevel(); - return trait; - } - - public Traits readTraits(String name) throws IOException { - newDumpLevel(name, "Traits"); - int count = readU30("count"); - Traits traits = new Traits(count); - for (int i = 0; i < count; i++) { - traits.traits.add(readTrait("trait")); - } - endDumpLevel(); - return traits; - } - - private byte[] readBytesInternal(int count) throws IOException { - byte[] ret = new byte[count]; - for (int i = 0; i < count; i++) { - ret[i] = (byte) readInternal(); - } - return ret; - } - - public byte[] readBytes(int count, String name) throws IOException { - newDumpLevel(name, "Bytes"); - byte[] ret = readBytesInternal(count); - endDumpLevel(); - return ret; - } - - public Decimal readDecimal(String name) throws IOException { - newDumpLevel(name, "Decimal"); - byte[] data = readBytesInternal(16); - endDumpLevel(); - return new Decimal(data); - } - - public InstanceInfo readInstanceInfo(String name) throws IOException { - newDumpLevel(name, "instance_info"); - InstanceInfo ret = new InstanceInfo(null); // do not create Traits in constructor - ret.name_index = readU30("name_index"); - ret.super_index = readU30("super_index"); - ret.flags = readInternal(); - if ((ret.flags & CLASS_PROTECTED_NS) != 0) { - ret.protectedNS = readU30("protectedNS"); - } - int interfaces_count = readU30("interfaces_count"); - ret.interfaces = new int[interfaces_count]; - for (int i = 0; i < interfaces_count; i++) { - ret.interfaces[i] = readU30("interface"); - } - ret.iinit_index = readU30("iinit_index"); - ret.instance_traits = readTraits("instance_traits"); - endDumpLevel(); - return ret; - } - - public String readString(String name) throws IOException { - newDumpLevel(name, "String"); - int length = readU30Internal(); - - // avoid creating new byte array every time - if (stringDataBuffer.length < length) { - int newLength = stringDataBuffer.length * 2; - while (newLength < length) { - newLength *= 2; - } - - stringDataBuffer = new byte[newLength]; - } - - safeRead(length, stringDataBuffer); - String r = new String(stringDataBuffer, 0, length, Utf8Helper.charset); - endDumpLevel(r); - return r; - } - - - /*public void markStart(){ - bytesRead=0; - }*/ - public long getPosition() { - return is.getPos(); - } - - @Override - public void close() { - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc; + +import com.jpexs.decompiler.flash.EndOfStreamException; +import com.jpexs.decompiler.flash.abc.types.Decimal; +import com.jpexs.decompiler.flash.abc.types.InstanceInfo; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.flash.abc.types.Multiname; +import com.jpexs.decompiler.flash.abc.types.Namespace; +import com.jpexs.decompiler.flash.abc.types.ValueKind; +import com.jpexs.decompiler.flash.abc.types.traits.Trait; +import com.jpexs.decompiler.flash.abc.types.traits.TraitClass; +import com.jpexs.decompiler.flash.abc.types.traits.TraitFunction; +import com.jpexs.decompiler.flash.abc.types.traits.TraitMethodGetterSetter; +import com.jpexs.decompiler.flash.abc.types.traits.TraitSlotConst; +import com.jpexs.decompiler.flash.abc.types.traits.Traits; +import com.jpexs.decompiler.flash.dumpview.DumpInfo; +import com.jpexs.helpers.MemoryInputStream; +import com.jpexs.helpers.utf8.Utf8Helper; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +public class ABCInputStream implements AutoCloseable { + + private static final int CLASS_PROTECTED_NS = 8; + + private static final int ATTR_METADATA = 4; + + private final MemoryInputStream is; + + private ByteArrayOutputStream bufferOs = null; + + public static final boolean DEBUG_READ = false; + + public DumpInfo dumpInfo; + + private byte[] stringDataBuffer = new byte[256]; + + public void startBuffer() { + if (bufferOs == null) { + bufferOs = new ByteArrayOutputStream(); + } else { + bufferOs.reset(); + } + } + + public byte[] stopBuffer() { + if (bufferOs == null) { + return new byte[0]; + } + byte[] ret = bufferOs.toByteArray(); + bufferOs.reset(); + return ret; + } + + public ABCInputStream(MemoryInputStream is) { + this.is = is; + } + + /** + * Sets position in bytes in the stream + * + * @param pos Number of bytes + * @throws java.io.IOException + */ + public void seek(long pos) throws IOException { + is.seek(pos); + } + + public DumpInfo newDumpLevel(String name, String type) { + if (dumpInfo != null) { + long startByte = is.getPos(); + DumpInfo di = new DumpInfo(name, type, null, startByte, 0, 0, 0); + di.parent = dumpInfo; + dumpInfo.getChildInfos().add(di); + dumpInfo = di; + } + + return dumpInfo; + } + + public void endDumpLevel() { + endDumpLevel(null); + } + + public void endDumpLevel(Object value) { + if (dumpInfo != null) { + dumpInfo.lengthBytes = is.getPos() - dumpInfo.startByte; + dumpInfo.previewValue = value; + dumpInfo = dumpInfo.parent; + } + } + + public void endDumpLevelUntil(DumpInfo di) { + if (di != null) { + while (dumpInfo != null && dumpInfo != di) { + endDumpLevel(); + } + } + } + + private int readInternal() throws IOException { + int i = is.read(); + if (i == -1) { + throw new EndOfStreamException(); + } + if (DEBUG_READ) { + System.out.println("Read:0x" + Integer.toHexString(i)); + } + if (bufferOs != null) { + if (i != -1) { + bufferOs.write(i); + } + } + return i; + } + + public int read(String name) throws IOException { + newDumpLevel(name, "byte"); + int ret = readInternal(); + endDumpLevel(ret); + return ret; + } + + private int read(byte[] b) throws IOException { + int currBytesRead = is.read(b); + if (DEBUG_READ) { + StringBuilder sb = new StringBuilder("Read["); + sb.append(currBytesRead); + sb.append('/'); + sb.append(b.length); + sb.append("]: "); + for (int jj = 0; jj < currBytesRead; jj++) { + sb.append("0x"); + sb.append(Integer.toHexString(b[jj])); + sb.append(' '); + } + System.out.println(sb.toString()); + } + if (bufferOs != null) { + if (currBytesRead > 0) { + bufferOs.write(b, 0, currBytesRead); + } + } + return currBytesRead; + } + + public int readU8(String name) throws IOException { + newDumpLevel(name, "U8"); + int ret = readInternal(); + endDumpLevel(ret); + return ret; + } + + private long readU32Internal() throws IOException { + int i; + long ret = 0; + int bytePos = 0; + int byteCount = 0; + boolean nextByte; + do { + i = readInternal(); + nextByte = (i >> 7) == 1; + i &= 0x7f; + ret += (((long) i) << bytePos); + byteCount++; + bytePos += 7; + } while (nextByte); + return ret; + } + + public long readU32(String name) throws IOException { + newDumpLevel(name, "U32"); + long ret = readU32Internal(); + endDumpLevel(ret); + return ret; + } + + private int readU30Internal() throws IOException { + return (int) readU32Internal(); + } + + public int readU30(String name) throws IOException { + newDumpLevel(name, "U30"); + int ret = readU30Internal(); + endDumpLevel(ret); + return ret; + } + + public int readS24(String name) throws IOException { + newDumpLevel(name, "S24"); + int ret = (readInternal()) + (readInternal() << 8) + (readInternal() << 16); + + if ((ret >> 23) == 1) { + ret |= 0xff000000; + } + + endDumpLevel(ret); + return ret; + } + + public int readU16(String name) throws IOException { + newDumpLevel(name, "U16"); + int ret = (readInternal()) + (readInternal() << 8); + endDumpLevel(ret); + return ret; + } + + public long readS32(String name) throws IOException { + int i; + long ret = 0; + int bytePos = 0; + int byteCount = 0; + boolean nextByte; + newDumpLevel(name, "S32"); + do { + i = readInternal(); + nextByte = (i >> 7) == 1; + i &= 0x7f; + ret += (i << bytePos); + byteCount++; + bytePos += 7; + if (bytePos == 35) { + if ((ret >> 31) == 1) { + ret = -(ret & 0x7fffffff); + } + break; + } + } while (nextByte); + endDumpLevel(ret); + return ret; + } + + public int available() throws IOException { + return is.available(); + } + + private long readLong() throws IOException { + safeRead(8, stringDataBuffer); + byte[] readBuffer = stringDataBuffer; + return (((long) readBuffer[7] << 56) + + ((long) (readBuffer[6] & 255) << 48) + + ((long) (readBuffer[5] & 255) << 40) + + ((long) (readBuffer[4] & 255) << 32) + + ((long) (readBuffer[3] & 255) << 24) + + ((readBuffer[2] & 255) << 16) + + ((readBuffer[1] & 255) << 8) + + ((readBuffer[0] & 255))); + } + + public double readDouble(String name) throws IOException { + newDumpLevel(name, "Double"); + long el = readLong(); + double ret = Double.longBitsToDouble(el); + endDumpLevel(ret); + return ret; + } + + private void safeRead(int count, byte[] data) throws IOException { + for (int i = 0; i < count; i++) { + data[i] = (byte) readInternal(); + } + } + + public Namespace readNamespace(String name) throws IOException { + newDumpLevel(name, "Namespace"); + int kind = read("kind"); + int name_index = 0; + for (int k = 0; k < Namespace.nameSpaceKinds.length; k++) { + if (Namespace.nameSpaceKinds[k] == kind) { + name_index = readU30("name_index"); + break; + } + } + endDumpLevel(); + return new Namespace(kind, name_index); + } + + public Multiname readMultiname(String name) throws IOException { + int kind = readU8("kind"); + int namespace_index = 0; + int name_index = 0; + int namespace_set_index = 0; + int qname_index = 0; + List params = new ArrayList<>(); + + newDumpLevel(name, "Multiname"); + if ((kind == Multiname.QNAME) || (kind == Multiname.QNAMEA)) { + namespace_index = readU30("namespace_index"); + name_index = readU30("name_index"); + } else if ((kind == Multiname.RTQNAME) || (kind == Multiname.RTQNAMEA)) { + name_index = readU30("name_index"); + } else if ((kind == Multiname.RTQNAMEL) || (kind == Multiname.RTQNAMELA)) { + + } else if ((kind == Multiname.MULTINAME) || (kind == Multiname.MULTINAMEA)) { + name_index = readU30("name_index"); + namespace_set_index = readU30("namespace_set_index"); + } else if ((kind == Multiname.MULTINAMEL) || (kind == Multiname.MULTINAMELA)) { + namespace_set_index = readU30("namespace_set_index"); + } else if (kind == Multiname.TYPENAME) { + qname_index = readU30("qname_index"); // Multiname index!!! + int paramsLength = readU30("paramsLength"); + for (int i = 0; i < paramsLength; i++) { + params.add(readU30("param")); // multiname indices! + } + } else { + throw new IOException("Unknown kind of Multiname:0x" + Integer.toHexString(kind)); + } + + endDumpLevel(); + return new Multiname(kind, name_index, namespace_index, namespace_set_index, qname_index, params); + } + + public MethodInfo readMethodInfo(String name) throws IOException { + newDumpLevel(name, "method_info"); + int param_count = readU30("param_count"); + int ret_type = readU30("ret_type"); + int[] param_types = new int[param_count]; + for (int i = 0; i < param_count; i++) { + param_types[i] = readU30("param_type"); + } + int name_index = readU30("name_index"); + int flags = read("flags"); + + // 1=need_arguments, 2=need_activation, 4=need_rest 8=has_optional (16=ignore_rest, 32=explicit,) 64=setsdxns, 128=has_paramnames + ValueKind[] optional = new ValueKind[0]; + if ((flags & 8) == 8) { // if has_optional + int optional_count = readU30("optional_count"); + optional = new ValueKind[optional_count]; + for (int i = 0; i < optional_count; i++) { + optional[i] = new ValueKind(readU30("value_index"), read("value_kind")); + } + } + + int[] param_names = new int[param_count]; + if ((flags & 128) == 128) { // if has_paramnames + for (int i = 0; i < param_count; i++) { + param_names[i] = readU30("param_name"); + } + } + + endDumpLevel(); + return new MethodInfo(param_types, ret_type, name_index, flags, optional, param_names); + } + + public Trait readTrait(String name) throws IOException { + newDumpLevel(name, "Trait"); + long pos = getPosition(); + startBuffer(); + int name_index = readU30("name_index"); + int kind = read("kind"); + int kindType = 0xf & kind; + int kindFlags = kind >> 4; + Trait trait; + + switch (kindType) { + case 0: // slot + case 6: // const + TraitSlotConst t1 = new TraitSlotConst(); + t1.slot_id = readU30("slot_id"); + t1.type_index = readU30("type_index"); + t1.value_index = readU30("value_index"); + if (t1.value_index != 0) { + t1.value_kind = read("value_kind"); + } + trait = t1; + break; + case 1: // method + case 2: // getter + case 3: // setter + TraitMethodGetterSetter t2 = new TraitMethodGetterSetter(); + t2.disp_id = readU30("disp_id"); + t2.method_info = readU30("method_info"); + trait = t2; + break; + case 4: // class + TraitClass t3 = new TraitClass(); + t3.slot_id = readU30("slot_id"); + t3.class_info = readU30("class_info"); + trait = t3; + break; + case 5: // function + TraitFunction t4 = new TraitFunction(); + t4.slot_id = readU30("slot_id"); + t4.method_info = readU30("method_info"); + trait = t4; + break; + default: + throw new IOException("Unknown trait kind:" + kind); + } + trait.fileOffset = pos; + trait.kindType = kindType; + trait.kindFlags = kindFlags; + trait.name_index = name_index; + if ((kindFlags & ATTR_METADATA) != 0) { + int metadata_count = readU30("metadata_count"); + trait.metadata = new int[metadata_count]; + for (int i = 0; i < metadata_count; i++) { + trait.metadata[i] = readU30("metadata"); + } + } + trait.bytes = stopBuffer(); + endDumpLevel(); + return trait; + } + + public Traits readTraits(String name) throws IOException { + newDumpLevel(name, "Traits"); + int count = readU30("count"); + Traits traits = new Traits(count); + for (int i = 0; i < count; i++) { + traits.traits.add(readTrait("trait")); + } + endDumpLevel(); + return traits; + } + + private byte[] readBytesInternal(int count) throws IOException { + byte[] ret = new byte[count]; + for (int i = 0; i < count; i++) { + ret[i] = (byte) readInternal(); + } + return ret; + } + + public byte[] readBytes(int count, String name) throws IOException { + newDumpLevel(name, "Bytes"); + byte[] ret = readBytesInternal(count); + endDumpLevel(); + return ret; + } + + public Decimal readDecimal(String name) throws IOException { + newDumpLevel(name, "Decimal"); + byte[] data = readBytesInternal(16); + endDumpLevel(); + return new Decimal(data); + } + + public InstanceInfo readInstanceInfo(String name) throws IOException { + newDumpLevel(name, "instance_info"); + InstanceInfo ret = new InstanceInfo(null); // do not create Traits in constructor + ret.name_index = readU30("name_index"); + ret.super_index = readU30("super_index"); + ret.flags = readInternal(); + if ((ret.flags & CLASS_PROTECTED_NS) != 0) { + ret.protectedNS = readU30("protectedNS"); + } + int interfaces_count = readU30("interfaces_count"); + ret.interfaces = new int[interfaces_count]; + for (int i = 0; i < interfaces_count; i++) { + ret.interfaces[i] = readU30("interface"); + } + ret.iinit_index = readU30("iinit_index"); + ret.instance_traits = readTraits("instance_traits"); + endDumpLevel(); + return ret; + } + + public String readString(String name) throws IOException { + newDumpLevel(name, "String"); + int length = readU30Internal(); + + // avoid creating new byte array every time + if (stringDataBuffer.length < length) { + int newLength = stringDataBuffer.length * 2; + while (newLength < length) { + newLength *= 2; + } + + stringDataBuffer = new byte[newLength]; + } + + safeRead(length, stringDataBuffer); + String r = new String(stringDataBuffer, 0, length, Utf8Helper.charset); + endDumpLevel(r); + return r; + } + + + /*public void markStart(){ + bytesRead=0; + }*/ + public long getPosition() { + return is.getPos(); + } + + @Override + public void close() { + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ScriptPack.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ScriptPack.java index 15010ac41..7ec467459 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ScriptPack.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ScriptPack.java @@ -1,251 +1,251 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc; - -import com.jpexs.decompiler.flash.SWF; -import com.jpexs.decompiler.flash.abc.types.Multiname; -import com.jpexs.decompiler.flash.abc.types.Namespace; -import com.jpexs.decompiler.flash.abc.types.traits.Trait; -import com.jpexs.decompiler.flash.configuration.Configuration; -import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; -import com.jpexs.decompiler.flash.exporters.settings.ScriptExportSettings; -import com.jpexs.decompiler.flash.helpers.FileTextWriter; -import com.jpexs.decompiler.flash.helpers.GraphTextWriter; -import com.jpexs.decompiler.flash.helpers.NulWriter; -import com.jpexs.decompiler.flash.treeitems.AS3ClassTreeItem; -import com.jpexs.helpers.CancellableWorker; -import com.jpexs.helpers.Helper; -import com.jpexs.helpers.Path; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * - * @author JPEXS - */ -public class ScriptPack extends AS3ClassTreeItem { - - public final ABC abc; - - public final int scriptIndex; - - public final List traitIndices; - - private final ClassPath path; - - @Override - public SWF getSwf() { - return abc.getSwf(); - } - - public ClassPath getClassPath() { - return path; - } - - public ScriptPack(ClassPath path, ABC abc, int scriptIndex, List traitIndices) { - super(path.className, path); - this.abc = abc; - this.scriptIndex = scriptIndex; - this.traitIndices = traitIndices; - this.path = path; - } - - public String getPathPackage() { - String packageName = ""; - for (int t : traitIndices) { - Multiname name = abc.script_info.get(scriptIndex).traits.traits.get(t).getName(abc); - Namespace ns = name.getNamespace(abc.constants); - if ((ns.kind == Namespace.KIND_PACKAGE) || (ns.kind == Namespace.KIND_PACKAGE_INTERNAL)) { - packageName = ns.getName(abc.constants, false); // assume not null - } - } - return packageName; - } - - public String getPathScriptName() { - String scriptName = ""; - for (int t : traitIndices) { - Multiname name = abc.script_info.get(scriptIndex).traits.traits.get(t).getName(abc); - Namespace ns = name.getNamespace(abc.constants); - if ((ns.kind == Namespace.KIND_PACKAGE) || (ns.kind == Namespace.KIND_PACKAGE_INTERNAL)) { - scriptName = name.getName(abc.constants, new ArrayList(), false); - } - } - return scriptName; - } - - /*public String getPath() { - String packageName = ""; - String scriptName = ""; - for (int t : traitIndices) { - Multiname name = abc.script_info[scriptIndex].traits.traits.get(t).getName(abc); - Namespace ns = name.getNamespace(abc.constants); - if ((ns.kind == Namespace.KIND_PACKAGE) || (ns.kind == Namespace.KIND_PACKAGE_INTERNAL)) { - packageName = ns.getName(abc.constants); - scriptName = name.getName(abc.constants, new ArrayList()); - } - } - return packageName.equals("") ? scriptName : packageName + "." + scriptName; - }*/ - private static String makeDirPath(String packageName) { - if (packageName.isEmpty()) { - return ""; - } - String[] pathParts; - if (packageName.contains(".")) { - pathParts = packageName.split("\\."); - } else { - pathParts = new String[]{packageName}; - } - for (int i = 0; i < pathParts.length; i++) { - pathParts[i] = Helper.makeFileName(pathParts[i]); - } - return Helper.joinStrings(pathParts, File.separator); - } - - public void convert(final NulWriter writer, final List traits, final ScriptExportMode exportMode, final boolean parallel) throws InterruptedException { - for (int t : traitIndices) { - Trait trait = traits.get(t); - Multiname name = trait.getName(abc); - Namespace ns = name.getNamespace(abc.constants); - if ((ns.kind == Namespace.KIND_PACKAGE) || (ns.kind == Namespace.KIND_PACKAGE_INTERNAL)) { - trait.convertPackaged(null, "", abc, false, exportMode, scriptIndex, -1, writer, new ArrayList(), parallel); - } else { - trait.convert(null, "", abc, false, exportMode, scriptIndex, -1, writer, new ArrayList(), parallel); - } - } - } - - private void appendTo(GraphTextWriter writer, List traits, ScriptExportMode exportMode, boolean parallel) throws InterruptedException { - boolean first = true; - for (int t : traitIndices) { - if (!first) { - writer.newLine(); - } - - Trait trait = traits.get(t); - Multiname name = trait.getName(abc); - Namespace ns = name.getNamespace(abc.constants); - if ((ns.kind == Namespace.KIND_PACKAGE) || (ns.kind == Namespace.KIND_PACKAGE_INTERNAL)) { - trait.toStringPackaged(null, "", abc, false, exportMode, scriptIndex, -1, writer, new ArrayList(), parallel); - } else { - trait.toString(null, "", abc, false, exportMode, scriptIndex, -1, writer, new ArrayList(), parallel); - } - - first = false; - } - } - - public void toSource(GraphTextWriter writer, final List traits, final ScriptExportMode exportMode, final boolean parallel) throws InterruptedException { - writer.suspendMeasure(); - int timeout = Configuration.decompilationTimeoutFile.get(); - try { - CancellableWorker.call(new Callable() { - @Override - public Void call() throws Exception { - convert(new NulWriter(), traits, exportMode, parallel); - return null; - } - }, timeout, TimeUnit.SECONDS); - } catch (TimeoutException ex) { - writer.continueMeasure(); - Logger.getLogger(ScriptPack.class.getName()).log(Level.SEVERE, "Decompilation error", ex); - Helper.appendTimeoutComment(writer, timeout); - return; - } catch (ExecutionException ex) { - writer.continueMeasure(); - Logger.getLogger(ScriptPack.class.getName()).log(Level.SEVERE, "Decompilation error", ex); - Helper.appendErrorComment(writer, ex); - return; - } - writer.continueMeasure(); - - appendTo(writer, traits, exportMode, parallel); - } - - public File export(String directory, ScriptExportSettings exportSettings, boolean parallel) throws IOException { - File file = null; - - if (!exportSettings.singleFile) { - String scriptName = getPathScriptName(); - String packageName = getPathPackage(); - File outDir = new File(directory + File.separatorChar + makeDirPath(packageName)); - Path.createDirectorySafe(outDir); - String fileName = outDir.toString() + File.separator + Helper.makeFileName(scriptName) + exportSettings.getFileExtension(); - file = new File(fileName); - } - - try (FileTextWriter writer = exportSettings.singleFile ? null : new FileTextWriter(Configuration.getCodeFormatting(), new FileOutputStream(file))) { - try { - FileTextWriter writer2 = exportSettings.singleFile ? exportSettings.singleFileWriter : writer; - toSource(writer2, abc.script_info.get(scriptIndex).traits.traits, exportSettings.mode, parallel); - } catch (InterruptedException ex) { - Logger.getLogger(ScriptPack.class.getName()).log(Level.SEVERE, null, ex); - } - } catch (FileNotFoundException ex) { - Logger.getLogger(ScriptPack.class.getName()).log(Level.SEVERE, "The file path is probably too long", ex); - } - - return file; - } - - @Override - public int hashCode() { - int hash = 7; - hash = 79 * hash + Objects.hashCode(this.abc); - hash = 79 * hash + this.scriptIndex; - hash = 79 * hash + Objects.hashCode(this.path); - return hash; - } - - @Override - public boolean equals(Object obj) { - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final ScriptPack other = (ScriptPack) obj; - if (!Objects.equals(this.abc, other.abc)) { - return false; - } - if (this.scriptIndex != other.scriptIndex) { - return false; - } - if (!Objects.equals(this.path, other.path)) { - return false; - } - return true; - } - - @Override - public boolean isModified() { - return abc.script_info.get(scriptIndex).isModified(); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc; + +import com.jpexs.decompiler.flash.SWF; +import com.jpexs.decompiler.flash.abc.types.Multiname; +import com.jpexs.decompiler.flash.abc.types.Namespace; +import com.jpexs.decompiler.flash.abc.types.traits.Trait; +import com.jpexs.decompiler.flash.configuration.Configuration; +import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; +import com.jpexs.decompiler.flash.exporters.settings.ScriptExportSettings; +import com.jpexs.decompiler.flash.helpers.FileTextWriter; +import com.jpexs.decompiler.flash.helpers.GraphTextWriter; +import com.jpexs.decompiler.flash.helpers.NulWriter; +import com.jpexs.decompiler.flash.treeitems.AS3ClassTreeItem; +import com.jpexs.helpers.CancellableWorker; +import com.jpexs.helpers.Helper; +import com.jpexs.helpers.Path; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * + * @author JPEXS + */ +public class ScriptPack extends AS3ClassTreeItem { + + public final ABC abc; + + public final int scriptIndex; + + public final List traitIndices; + + private final ClassPath path; + + @Override + public SWF getSwf() { + return abc.getSwf(); + } + + public ClassPath getClassPath() { + return path; + } + + public ScriptPack(ClassPath path, ABC abc, int scriptIndex, List traitIndices) { + super(path.className, path); + this.abc = abc; + this.scriptIndex = scriptIndex; + this.traitIndices = traitIndices; + this.path = path; + } + + public String getPathPackage() { + String packageName = ""; + for (int t : traitIndices) { + Multiname name = abc.script_info.get(scriptIndex).traits.traits.get(t).getName(abc); + Namespace ns = name.getNamespace(abc.constants); + if ((ns.kind == Namespace.KIND_PACKAGE) || (ns.kind == Namespace.KIND_PACKAGE_INTERNAL)) { + packageName = ns.getName(abc.constants, false); // assume not null + } + } + return packageName; + } + + public String getPathScriptName() { + String scriptName = ""; + for (int t : traitIndices) { + Multiname name = abc.script_info.get(scriptIndex).traits.traits.get(t).getName(abc); + Namespace ns = name.getNamespace(abc.constants); + if ((ns.kind == Namespace.KIND_PACKAGE) || (ns.kind == Namespace.KIND_PACKAGE_INTERNAL)) { + scriptName = name.getName(abc.constants, new ArrayList(), false); + } + } + return scriptName; + } + + /*public String getPath() { + String packageName = ""; + String scriptName = ""; + for (int t : traitIndices) { + Multiname name = abc.script_info[scriptIndex].traits.traits.get(t).getName(abc); + Namespace ns = name.getNamespace(abc.constants); + if ((ns.kind == Namespace.KIND_PACKAGE) || (ns.kind == Namespace.KIND_PACKAGE_INTERNAL)) { + packageName = ns.getName(abc.constants); + scriptName = name.getName(abc.constants, new ArrayList()); + } + } + return packageName.equals("") ? scriptName : packageName + "." + scriptName; + }*/ + private static String makeDirPath(String packageName) { + if (packageName.isEmpty()) { + return ""; + } + String[] pathParts; + if (packageName.contains(".")) { + pathParts = packageName.split("\\."); + } else { + pathParts = new String[]{packageName}; + } + for (int i = 0; i < pathParts.length; i++) { + pathParts[i] = Helper.makeFileName(pathParts[i]); + } + return Helper.joinStrings(pathParts, File.separator); + } + + public void convert(final NulWriter writer, final List traits, final ScriptExportMode exportMode, final boolean parallel) throws InterruptedException { + for (int t : traitIndices) { + Trait trait = traits.get(t); + Multiname name = trait.getName(abc); + Namespace ns = name.getNamespace(abc.constants); + if ((ns.kind == Namespace.KIND_PACKAGE) || (ns.kind == Namespace.KIND_PACKAGE_INTERNAL)) { + trait.convertPackaged(null, "", abc, false, exportMode, scriptIndex, -1, writer, new ArrayList(), parallel); + } else { + trait.convert(null, "", abc, false, exportMode, scriptIndex, -1, writer, new ArrayList(), parallel); + } + } + } + + private void appendTo(GraphTextWriter writer, List traits, ScriptExportMode exportMode, boolean parallel) throws InterruptedException { + boolean first = true; + for (int t : traitIndices) { + if (!first) { + writer.newLine(); + } + + Trait trait = traits.get(t); + Multiname name = trait.getName(abc); + Namespace ns = name.getNamespace(abc.constants); + if ((ns.kind == Namespace.KIND_PACKAGE) || (ns.kind == Namespace.KIND_PACKAGE_INTERNAL)) { + trait.toStringPackaged(null, "", abc, false, exportMode, scriptIndex, -1, writer, new ArrayList(), parallel); + } else { + trait.toString(null, "", abc, false, exportMode, scriptIndex, -1, writer, new ArrayList(), parallel); + } + + first = false; + } + } + + public void toSource(GraphTextWriter writer, final List traits, final ScriptExportMode exportMode, final boolean parallel) throws InterruptedException { + writer.suspendMeasure(); + int timeout = Configuration.decompilationTimeoutFile.get(); + try { + CancellableWorker.call(new Callable() { + @Override + public Void call() throws Exception { + convert(new NulWriter(), traits, exportMode, parallel); + return null; + } + }, timeout, TimeUnit.SECONDS); + } catch (TimeoutException ex) { + writer.continueMeasure(); + Logger.getLogger(ScriptPack.class.getName()).log(Level.SEVERE, "Decompilation error", ex); + Helper.appendTimeoutComment(writer, timeout); + return; + } catch (ExecutionException ex) { + writer.continueMeasure(); + Logger.getLogger(ScriptPack.class.getName()).log(Level.SEVERE, "Decompilation error", ex); + Helper.appendErrorComment(writer, ex); + return; + } + writer.continueMeasure(); + + appendTo(writer, traits, exportMode, parallel); + } + + public File export(String directory, ScriptExportSettings exportSettings, boolean parallel) throws IOException { + File file = null; + + if (!exportSettings.singleFile) { + String scriptName = getPathScriptName(); + String packageName = getPathPackage(); + File outDir = new File(directory + File.separatorChar + makeDirPath(packageName)); + Path.createDirectorySafe(outDir); + String fileName = outDir.toString() + File.separator + Helper.makeFileName(scriptName) + exportSettings.getFileExtension(); + file = new File(fileName); + } + + try (FileTextWriter writer = exportSettings.singleFile ? null : new FileTextWriter(Configuration.getCodeFormatting(), new FileOutputStream(file))) { + try { + FileTextWriter writer2 = exportSettings.singleFile ? exportSettings.singleFileWriter : writer; + toSource(writer2, abc.script_info.get(scriptIndex).traits.traits, exportSettings.mode, parallel); + } catch (InterruptedException ex) { + Logger.getLogger(ScriptPack.class.getName()).log(Level.SEVERE, null, ex); + } + } catch (FileNotFoundException ex) { + Logger.getLogger(ScriptPack.class.getName()).log(Level.SEVERE, "The file path is probably too long", ex); + } + + return file; + } + + @Override + public int hashCode() { + int hash = 7; + hash = 79 * hash + Objects.hashCode(this.abc); + hash = 79 * hash + this.scriptIndex; + hash = 79 * hash + Objects.hashCode(this.path); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final ScriptPack other = (ScriptPack) obj; + if (!Objects.equals(this.abc, other.abc)) { + return false; + } + if (this.scriptIndex != other.scriptIndex) { + return false; + } + if (!Objects.equals(this.path, other.path)) { + return false; + } + return true; + } + + @Override + public boolean isModified() { + return abc.script_info.get(scriptIndex).isModified(); + } +} 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 4e97c4458..6f92d2f78 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 @@ -1,2971 +1,2971 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2; - -import com.jpexs.decompiler.flash.EndOfStreamException; -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.ABCInputStream; -import com.jpexs.decompiler.flash.abc.AVM2LocalData; -import com.jpexs.decompiler.flash.abc.CopyOutputStream; -import com.jpexs.decompiler.flash.abc.avm2.graph.AVM2Graph; -import com.jpexs.decompiler.flash.abc.avm2.graph.AVM2GraphSource; -import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; -import com.jpexs.decompiler.flash.abc.avm2.instructions.DeobfuscatePopIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.IfTypeIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.instructions.alchemy.Lf32Ins; -import com.jpexs.decompiler.flash.abc.avm2.instructions.alchemy.Lf64Ins; -import com.jpexs.decompiler.flash.abc.avm2.instructions.alchemy.Li16Ins; -import com.jpexs.decompiler.flash.abc.avm2.instructions.alchemy.Li32Ins; -import com.jpexs.decompiler.flash.abc.avm2.instructions.alchemy.Li8Ins; -import com.jpexs.decompiler.flash.abc.avm2.instructions.alchemy.Sf32Ins; -import com.jpexs.decompiler.flash.abc.avm2.instructions.alchemy.Sf64Ins; -import com.jpexs.decompiler.flash.abc.avm2.instructions.alchemy.Si16Ins; -import com.jpexs.decompiler.flash.abc.avm2.instructions.alchemy.Si32Ins; -import com.jpexs.decompiler.flash.abc.avm2.instructions.alchemy.Si8Ins; -import com.jpexs.decompiler.flash.abc.avm2.instructions.alchemy.Sxi16Ins; -import com.jpexs.decompiler.flash.abc.avm2.instructions.alchemy.Sxi1Ins; -import com.jpexs.decompiler.flash.abc.avm2.instructions.alchemy.Sxi8Ins; -import com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic.AddIIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic.AddIns; -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.DivideIns; -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.arithmetic.ModuloIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic.MultiplyIIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic.MultiplyIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic.NegateIIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic.NegateIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic.NotIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic.SubtractIIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic.SubtractIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.bitwise.BitAndIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.bitwise.BitNotIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.bitwise.BitOrIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.bitwise.BitXorIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.bitwise.LShiftIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.bitwise.RShiftIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.bitwise.URShiftIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.comparison.EqualsIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.comparison.GreaterEqualsIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.comparison.GreaterThanIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.comparison.LessEqualsIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.comparison.LessThanIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.comparison.StrictEqualsIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.construction.ConstructIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.construction.ConstructPropIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.construction.ConstructSuperIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.construction.NewActivationIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.construction.NewArrayIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.construction.NewCatchIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.construction.NewClassIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.construction.NewFunctionIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.construction.NewObjectIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.debug.DebugFileIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.debug.DebugIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.debug.DebugLineIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.executing.CallIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.executing.CallMethodIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.executing.CallPropLexIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.executing.CallPropVoidIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.executing.CallPropertyIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.executing.CallStaticIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.executing.CallSuperIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.executing.CallSuperVoidIns; -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.IfGeIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.IfGtIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.IfLeIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.IfLtIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.IfNGeIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.IfNGtIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.IfNLeIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.IfNLtIns; -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.abc.avm2.instructions.jumps.IfTrueIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.JumpIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.LookupSwitchIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.DecLocalIIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.DecLocalIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.GetLocal0Ins; -import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.GetLocal1Ins; -import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.GetLocal2Ins; -import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.GetLocal3Ins; -import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.GetLocalIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.GetLocalTypeIns; -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.localregs.KillIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.SetLocal0Ins; -import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.SetLocal1Ins; -import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.SetLocal2Ins; -import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.SetLocal3Ins; -import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.SetLocalIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.SetLocalTypeIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other.DeletePropertyIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other.FindDefIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other.FindPropertyIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other.FindPropertyStrictIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetDescendantsIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetGlobalScopeIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetGlobalSlotIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetLexIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetPropertyIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetScopeObjectIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetSlotIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetSuperIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other.HasNext2Ins; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other.HasNextIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other.InIns; -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.NextNameIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other.NextValueIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other.NopIns; -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.other.SetGlobalSlotIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other.SetPropertyIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other.SetSlotIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other.SetSuperIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other.ThrowIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.AbsJumpIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.AddDIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.AddPIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.AllocIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.BkptIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.BkptLineIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.CallInterfaceIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.CallSuperIdIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.CodeGenOpIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.CoerceBIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.CoerceDIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.CoerceIIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.CoerceOIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.CoerceUIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.ConcatIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.ConvertF4Ins; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.ConvertMIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.ConvertMPIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.DecLocalPIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.DecodeIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.DecrementPIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.DelDescendantsIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.DeletePropertyLateIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.DividePIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.DoubleToAtomIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.FindPropGlobalIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.GetOuterScopeIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.IncLocalPIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.IncrementPIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.InvalidIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.Lf32x4Ins; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.MarkIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.ModuloPIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.MultiplyPIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.NegatePIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.PrologueIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.PushConstantIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.PushDNanIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.PushDecimalIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.PushFloat4Ins; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.SendEnterIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.SetPropertyLateIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.Sf32x4Ins; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.SubtractPIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.SweepIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.TimestampIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.VerifyOpIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.VerifyPassIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.WbIns; -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.PopScopeIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushByteIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushDoubleIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushFalseIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushIntIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushNamespaceIns; -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.stack.PushScopeIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushShortIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushStringIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushTrueIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushUIntIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushUndefinedIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushWithIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.SwapIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.types.ApplyTypeIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.types.AsTypeIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.types.AsTypeLateIns; -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.CoerceOrConvertTypeIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.types.CoerceSIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.types.ConvertBIns; -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.ConvertOIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.types.ConvertSIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.types.ConvertUIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.types.InstanceOfIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.types.IsTypeIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.types.IsTypeLateIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.types.TypeOfIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.xml.CheckFilterIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.xml.DXNSIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.xml.DXNSLateIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.xml.EscXAttrIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.xml.EscXElemIns; -import com.jpexs.decompiler.flash.abc.avm2.model.BooleanAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.FullMultinameAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.HasNextAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.InitPropertyAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.LocalRegAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.NewFunctionAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.ReturnValueAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.ReturnVoidAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.SetLocalAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.SetPropertyAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.SetSlotAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.WithAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.clauses.DeclarationAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.clauses.ForEachInAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.clauses.ForInAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.parser.AVM2ParseException; -import com.jpexs.decompiler.flash.abc.avm2.parser.pcode.ASM3Parser; -import com.jpexs.decompiler.flash.abc.avm2.parser.script.PropertyAVM2Item; -import com.jpexs.decompiler.flash.abc.types.ABCException; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.flash.abc.types.Multiname; -import com.jpexs.decompiler.flash.abc.types.ValueKind; -import com.jpexs.decompiler.flash.abc.types.traits.Trait; -import com.jpexs.decompiler.flash.abc.types.traits.TraitFunction; -import com.jpexs.decompiler.flash.abc.types.traits.TraitMethodGetterSetter; -import com.jpexs.decompiler.flash.abc.types.traits.TraitSlotConst; -import com.jpexs.decompiler.flash.abc.types.traits.Traits; -import com.jpexs.decompiler.flash.configuration.Configuration; -import com.jpexs.decompiler.flash.dumpview.DumpInfo; -import com.jpexs.decompiler.flash.ecma.EcmaScript; -import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; -import com.jpexs.decompiler.flash.helpers.GraphTextWriter; -import com.jpexs.decompiler.flash.helpers.HighlightedTextWriter; -import com.jpexs.decompiler.flash.helpers.hilight.HighlightSpecialType; -import com.jpexs.decompiler.graph.Block; -import com.jpexs.decompiler.graph.Graph; -import com.jpexs.decompiler.graph.GraphPart; -import com.jpexs.decompiler.graph.GraphSourceItem; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.NotCompileTimeItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateException; -import com.jpexs.decompiler.graph.TranslateStack; -import com.jpexs.decompiler.graph.TypeItem; -import com.jpexs.decompiler.graph.model.LocalData; -import com.jpexs.decompiler.graph.model.ScriptEndItem; -import com.jpexs.helpers.Helper; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.io.StringReader; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeMap; -import java.util.logging.Level; -import java.util.logging.Logger; - -public class AVM2Code implements Cloneable { - - private static final Logger logger = Logger.getLogger(AVM2Code.class.getName()); - - private static final boolean DEBUG_MODE = false; - - public static int toSourceLimit = -1; - - public List code = new ArrayList<>(); - - public static boolean DEBUG_REWRITE = false; - - public static final int OPT_U30 = 0x100; - - public static final int OPT_U8 = 0x200; - - public static final int OPT_S24 = 0x300; - - public static final int OPT_CASE_OFFSETS = 0x400; - - public static final int OPT_BYTE = 0x500; - - public static final int DAT_MULTINAME_INDEX = OPT_U30 + 0x01; - - public static final int DAT_ARG_COUNT = OPT_U30 + 0x02; - - public static final int DAT_METHOD_INDEX = OPT_U30 + 0x03; - - public static final int DAT_STRING_INDEX = OPT_U30 + 0x04; - - public static final int DAT_DEBUG_TYPE = OPT_U8 + 0x05; - - public static final int DAT_REGISTER_INDEX = OPT_U8 + 0x06; - - public static final int DAT_LINENUM = OPT_U30 + 0x07; - - public static final int DAT_LOCAL_REG_INDEX = OPT_U30 + 0x08; - - public static final int DAT_SLOT_INDEX = OPT_U30 + 0x09; - - public static final int DAT_SLOT_SCOPE_INDEX = OPT_U30 + 0x0A; - - public static final int DAT_OFFSET = OPT_S24 + 0x0B; - - public static final int DAT_EXCEPTION_INDEX = OPT_U30 + 0x0C; - - public static final int DAT_CLASS_INDEX = OPT_U30 + 0x0D; - - public static final int DAT_INT_INDEX = OPT_U30 + 0x0E; - - public static final int DAT_UINT_INDEX = OPT_U30 + 0x0F; - - public static final int DAT_DOUBLE_INDEX = OPT_U30 + 0x10; - - public static final int DAT_DECIMAL_INDEX = OPT_U30 + 0x11; - - public static final int DAT_CASE_BASEOFFSET = OPT_S24 + 0x12; - - public static final int DAT_DECIMAL_PARAMS = OPT_U30 + 0x13; - - public static InstructionDefinition[] instructionSet = new InstructionDefinition[]{ - /*0x00*/null, - /*0x01*/ new BkptIns(), - /*0x02*/ new NopIns(), - /*0x03*/ new ThrowIns(), - /*0x04*/ new GetSuperIns(), - /*0x05*/ new SetSuperIns(), - /*0x06*/ new DXNSIns(), - /*0x07*/ new DXNSLateIns(), - /*0x08*/ new KillIns(), - /*0x09*/ new LabelIns(), - /*0x0A*/ new Lf32x4Ins(), - /*0x0B*/ new Sf32x4Ins(), - /*0x0C*/ new IfNLtIns(), - /*0x0D*/ new IfNLeIns(), - /*0x0E*/ new IfNGtIns(), - /*0x0F*/ new IfNGeIns(), - /*0x10*/ new JumpIns(), - /*0x11*/ new IfTrueIns(), - /*0x12*/ new IfFalseIns(), - /*0x13*/ new IfEqIns(), - /*0x14*/ new IfNeIns(), - /*0x15*/ new IfLtIns(), - /*0x16*/ new IfLeIns(), - /*0x17*/ new IfGtIns(), - /*0x18*/ new IfGeIns(), - /*0x19*/ new IfStrictEqIns(), - /*0x1A*/ new IfStrictNeIns(), - /*0x1B*/ new LookupSwitchIns(), - /*0x1C*/ new PushWithIns(), - /*0x1D*/ new PopScopeIns(), - /*0x1E*/ new NextNameIns(), - /*0x1F*/ new HasNextIns(), - /*0x20*/ new PushNullIns(), - /*0x21*/ new PushUndefinedIns(), - /*0x22*/ new PushConstantIns(), // new PushUninitializedIns() - /*0x23*/ new NextValueIns(), - /*0x24*/ new PushByteIns(), - /*0x25*/ new PushShortIns(), - /*0x26*/ new PushTrueIns(), - /*0x27*/ new PushFalseIns(), - /*0x28*/ new PushNanIns(), - /*0x29*/ new PopIns(), - /*0x2A*/ new DupIns(), - /*0x2B*/ new SwapIns(), - /*0x2C*/ new PushStringIns(), - /*0x2D*/ new PushIntIns(), - /*0x2E*/ new PushUIntIns(), - /*0x2F*/ new PushDoubleIns(), - /*0x30*/ new PushScopeIns(), - /*0x31*/ new PushNamespaceIns(), - /*0x32*/ new HasNext2Ins(), - /*0x33*/ new PushDecimalIns(), - /*0x34*/ new PushDNanIns(), - /*0x35*/ new Li8Ins(), - /*0x36*/ new Li16Ins(), - /*0x37*/ new Li32Ins(), - /*0x38*/ new Lf32Ins(), - /*0x39*/ new Lf64Ins(), - /*0x3A*/ new Si8Ins(), - /*0x3B*/ new Si16Ins(), - /*0x3C*/ new Si32Ins(), - /*0x3D*/ new Sf32Ins(), - /*0x3E*/ new Sf64Ins(), - /*0x3F*/ null, - /*0x40*/ new NewFunctionIns(), - /*0x41*/ new CallIns(), - /*0x42*/ new ConstructIns(), - /*0x43*/ new CallMethodIns(), - /*0x44*/ new CallStaticIns(), - /*0x45*/ new CallSuperIns(), - /*0x46*/ new CallPropertyIns(), - /*0x47*/ new ReturnVoidIns(), - /*0x48*/ new ReturnValueIns(), - /*0x49*/ new ConstructSuperIns(), - /*0x4A*/ new ConstructPropIns(), - /*0x4B*/ new CallSuperIdIns(), - /*0x4C*/ new CallPropLexIns(), - /*0x4D*/ new CallInterfaceIns(), - /*0x4E*/ new CallSuperVoidIns(), - /*0x4F*/ new CallPropVoidIns(), - /*0x50*/ new Sxi1Ins(), - /*0x51*/ new Sxi8Ins(), - /*0x52*/ new Sxi16Ins(), - /*0x53*/ new ApplyTypeIns(), - /*0x54*/ new PushFloat4Ins(), - /*0x55*/ new NewObjectIns(), - /*0x56*/ new NewArrayIns(), - /*0x57*/ new NewActivationIns(), - /*0x58*/ new NewClassIns(), - /*0x59*/ new GetDescendantsIns(), - /*0x5A*/ new NewCatchIns(), - /*0x5B*/ new DelDescendantsIns(), - /* // Duplicate OPCODE with deldescendants. Prefering deldescendants (found in FLEX compiler) - new FindPropGlobalStrictIns(),*/ - /*0x5C*/ new FindPropGlobalIns(), - /*0x5D*/ new FindPropertyStrictIns(), - /*0x5E*/ new FindPropertyIns(), - /*0x5F*/ new FindDefIns(), - /*0x60*/ new GetLexIns(), - /*0x61*/ new SetPropertyIns(), - /*0x62*/ new GetLocalIns(), - /*0x63*/ new SetLocalIns(), - /*0x64*/ new GetGlobalScopeIns(), - /*0x65*/ new GetScopeObjectIns(), - /*0x66*/ new GetPropertyIns(), - /*0x67*/ new GetOuterScopeIns(), // new GetPropertyLateIns() - /*0x68*/ new InitPropertyIns(), - /*0x69*/ new SetPropertyLateIns(), - /*0x6A*/ new DeletePropertyIns(), - /*0x6B*/ new DeletePropertyLateIns(), - /*0x6C*/ new GetSlotIns(), - /*0x6D*/ new SetSlotIns(), - /*0x6E*/ new GetGlobalSlotIns(), - /*0x6F*/ new SetGlobalSlotIns(), - /*0x70*/ new ConvertSIns(), - /*0x71*/ new EscXElemIns(), - /*0x72*/ new EscXAttrIns(), - /*0x73*/ new ConvertIIns(), - /*0x74*/ new ConvertUIns(), - /*0x75*/ new ConvertDIns(), - /*0x76*/ new ConvertBIns(), - /*0x77*/ new ConvertOIns(), - /*0x78*/ new CheckFilterIns(), - /*0x79*/ new ConvertMIns(), - /*0x7A*/ new ConvertMPIns(), - /*0x7B*/ new ConvertF4Ins(), - /*0x7C*/ null, - /*0x7D*/ null, - /*0x7E*/ null, - /*0x7F*/ null, - /*0x80*/ new CoerceIns(), - /*0x81*/ new CoerceBIns(), - /*0x82*/ new CoerceAIns(), - /*0x83*/ new CoerceIIns(), - /*0x84*/ new CoerceDIns(), - /*0x85*/ new CoerceSIns(), - /*0x86*/ new AsTypeIns(), - /*0x87*/ new AsTypeLateIns(), - /*0x88*/ new CoerceUIns(), - /*0x89*/ new CoerceOIns(), - /*0x8A*/ null, - /*0x8B*/ null, - /*0x8C*/ null, - /*0x8D*/ null, - /*0x8E*/ null, - /*0x8F*/ new NegatePIns(), - /*0x90*/ new NegateIns(), - /*0x91*/ new IncrementIns(), - /*0x92*/ new IncLocalIns(), - /*0x93*/ new DecrementIns(), - /*0x94*/ new DecLocalIns(), - /*0x95*/ new TypeOfIns(), - /*0x96*/ new NotIns(), - /*0x97*/ new BitNotIns(), - /*0x98*/ null, - /*0x99*/ null, - /*0x9A*/ new ConcatIns(), - /*0x9B*/ new AddDIns(), - /*0x9C*/ new IncrementPIns(), - /*0x9D*/ new IncLocalPIns(), - /*0x9E*/ new DecrementPIns(), - /*0x9F*/ new DecLocalPIns(), - /*0xA0*/ new AddIns(), - /*0xA1*/ new SubtractIns(), - /*0xA2*/ new MultiplyIns(), - /*0xA3*/ new DivideIns(), - /*0xA4*/ new ModuloIns(), - /*0xA5*/ new LShiftIns(), - /*0xA6*/ new RShiftIns(), - /*0xA7*/ new URShiftIns(), - /*0xA8*/ new BitAndIns(), - /*0xA9*/ new BitOrIns(), - /*0xAA*/ new BitXorIns(), - /*0xAB*/ new EqualsIns(), - /*0xAC*/ new StrictEqualsIns(), - /*0xAD*/ new LessThanIns(), - /*0xAE*/ new LessEqualsIns(), - /*0xAF*/ new GreaterThanIns(), - /*0xB0*/ new GreaterEqualsIns(), - /*0xB1*/ new InstanceOfIns(), - /*0xB2*/ new IsTypeIns(), - /*0xB3*/ new IsTypeLateIns(), - /*0xB4*/ new InIns(), - /*0xB5*/ new AddPIns(), - /*0xB6*/ new SubtractPIns(), - /*0xB7*/ new MultiplyPIns(), - /*0xB8*/ new DividePIns(), - /*0xB9*/ new ModuloPIns(), - /*0xBA*/ null, - /*0xBB*/ null, - /*0xBC*/ null, - /*0xBD*/ null, - /*0xBE*/ null, - /*0xBF*/ null, - /*0xC0*/ new IncrementIIns(), - /*0xC1*/ new DecrementIIns(), - /*0xC2*/ new IncLocalIIns(), - /*0xC3*/ new DecLocalIIns(), - /*0xC4*/ new NegateIIns(), - /*0xC5*/ new AddIIns(), - /*0xC6*/ new SubtractIIns(), - /*0xC7*/ new MultiplyIIns(), - /*0xC8*/ null, - /*0xC9*/ null, - /*0xCA*/ null, - /*0xCB*/ null, - /*0xCC*/ null, - /*0xCD*/ null, - /*0xCE*/ null, - /*0xCF*/ null, - /*0xD0*/ new GetLocal0Ins(), - /*0xD1*/ new GetLocal1Ins(), - /*0xD2*/ new GetLocal2Ins(), - /*0xD3*/ new GetLocal3Ins(), - /*0xD4*/ new SetLocal0Ins(), - /*0xD5*/ new SetLocal1Ins(), - /*0xD6*/ new SetLocal2Ins(), - /*0xD7*/ new SetLocal3Ins(), - /*0xD8*/ null, - /*0xD9*/ null, - /*0xDA*/ null, - /*0xDB*/ null, - /*0xDC*/ null, - /*0xDD*/ null, - /*0xDE*/ null, - /*0xDF*/ null, - /*0xE0*/ null, - /*0xE1*/ null, - /*0xE2*/ null, - /*0xE3*/ null, - /*0xE4*/ null, - /*0xE5*/ null, - /*0xE6*/ null, - /*0xE7*/ null, - /*0xE8*/ null, - /*0xE9*/ null, - /*0xEA*/ null, - /*0xEB*/ null, - /*0xEC*/ null, - /*0xED*/ new InvalidIns(), - /*0xEE*/ new AbsJumpIns(), - /*0xEF*/ new DebugIns(), - /*0xF0*/ new DebugLineIns(), - /*0xF1*/ new DebugFileIns(), - /*0xF2*/ new BkptLineIns(), - /*0xF3*/ new TimestampIns(), - /*0xF4*/ null, - /*0xF5*/ new VerifyPassIns(), - /*0xF6*/ new AllocIns(), - /*0xF7*/ new MarkIns(), - /*0xF8*/ new WbIns(), - /*0xF9*/ new PrologueIns(), - /*0xFA*/ new SendEnterIns(), - /*0xFB*/ new DoubleToAtomIns(), - /*0xFC*/ new SweepIns(), - /*0xFD*/ new CodeGenOpIns(), - /*0xFE*/ new VerifyOpIns(), - /*0xFF*/ new DecodeIns(),}; - // endoflist - - public boolean hideTemporaryRegisters = true; - - public static final String IDENTOPEN = "/*IDENTOPEN*/"; - - public static final String IDENTCLOSE = "/*IDENTCLOSE*/"; - - public AVM2Code() { - } - - public Object execute(HashMap arguments, AVM2ConstantPool constants) { - int pos = 0; - LocalDataArea lda = new LocalDataArea(); - lda.localRegisters = arguments; - try { - while (true) { - AVM2Instruction ins = code.get(pos); - if (ins.definition instanceof JumpIns) { - pos = adr2pos((Long) ins.getParamsAsList(constants).get(0)); - continue; - } - if (ins.definition instanceof IfFalseIns) { - Boolean b = (Boolean) lda.operandStack.pop(); - if (b == false) { - pos = adr2pos((Long) ins.getParamsAsList(constants).get(0)); - } else { - pos++; - } - continue; - } - if (ins.definition instanceof IfTrueIns) { - Boolean b = (Boolean) lda.operandStack.pop(); - if (b == true) { - pos = adr2pos((Long) ins.getParamsAsList(constants).get(0)); - } else { - pos++; - } - continue; - } - if (ins.definition instanceof ReturnValueIns) { - return lda.operandStack.pop(); - } - if (ins.definition instanceof ReturnVoidIns) { - return null; - } - ins.definition.execute(lda, constants, ins.getParamsAsList(constants)); - pos++; - } - } catch (ConvertException e) { - } - return null; - } - - public void calculateDebugFileLine(ABC abc) { - calculateDebugFileLine(null, 0, 0, abc, new HashSet()); - } - - private boolean calculateDebugFileLine(String debugFile, int debugLine, int pos, ABC abc, Set seen) { - while (pos < code.size()) { - AVM2Instruction ins = code.get(pos); - if (seen.contains(pos)) { - return true; - } - - seen.add(pos); - - if (ins.definition instanceof DebugFileIns) { - debugFile = abc.constants.getString(ins.operands[0]); - } - - if (ins.definition instanceof DebugLineIns) { - debugLine = ins.operands[0]; - } - - ins.setFileLine(debugFile, debugLine); - - if (ins.definition instanceof NewFunctionIns) { - MethodBody innerBody = abc.findBody(ins.operands[0]); - innerBody.getCode().calculateDebugFileLine(debugFile, debugLine, 0, abc, new HashSet()); - } - - if (ins.definition instanceof ReturnValueIns) { - return true; - } - if (ins.definition instanceof ReturnVoidIns) { - return true; - } - if (ins.definition instanceof JumpIns) { - try { - pos = adr2pos(pos2adr(pos) + ins.getBytes().length + ins.operands[0]); - continue; - } catch (ConvertException ex) { - return false; - } - } else if (ins.definition instanceof IfTypeIns) { - try { - int newpos = adr2pos(pos2adr(pos) + ins.getBytes().length + ins.operands[0]); - calculateDebugFileLine(debugFile, debugLine, newpos, abc, seen); - } catch (ConvertException ex) { - return false; - } - } - if (ins.definition instanceof LookupSwitchIns) { - for (int i = 0; i < ins.operands.length; i++) { - if (i == 1) { - continue; - } - try { - int newpos = adr2pos(pos2adr(pos) + ins.operands[i]); - if (!calculateDebugFileLine(debugFile, debugLine, newpos, abc, seen)) { - return false; - } - } catch (ConvertException ex) { - return false; - } - } - } - pos++; - } - return true; - } - - public AVM2Code(ABCInputStream ais) throws IOException { - Map codeMap = new TreeMap<>(); - DumpInfo diParent = ais.dumpInfo; - List addresses = new ArrayList<>(); - long startPos = ais.getPosition(); - addresses.add(startPos); - - while (!addresses.isEmpty()) { - long address = addresses.remove(0); - boolean afterExit = false; - if (codeMap.containsKey(address)) { - continue; - } - if (address < startPos) // no jump outside block - { - continue; - } - try { - ais.seek(address); - while (ais.available() > 0) { - DumpInfo di = ais.newDumpLevel("instruction", "instruction"); - long startOffset = ais.getPosition(); - int instructionCode = ais.read("instructionCode"); - InstructionDefinition instr = instructionSet[instructionCode]; - if (di != null) { - di.name = instr.instructionName; - } - if (instr != null) { - int[] actualOperands = null; - if (instructionCode == 0x1b) { // switch - int firstOperand = ais.readS24("default_offset"); - int case_count = ais.readU30("case_count"); - actualOperands = new int[case_count + 3]; - actualOperands[0] = firstOperand; - actualOperands[1] = case_count; - for (int c = 0; c < case_count + 1; c++) { - actualOperands[2 + c] = ais.readS24("actualOperand"); - } - } else { - if (instr.operands.length > 0) { - actualOperands = new int[instr.operands.length]; - for (int op = 0; op < instr.operands.length; op++) { - switch (instr.operands[op] & 0xff00) { - case OPT_U30: - actualOperands[op] = ais.readU30("operand"); - break; - case OPT_U8: - actualOperands[op] = ais.read("operand"); - break; - case OPT_BYTE: - actualOperands[op] = (byte) ais.read("operand"); - break; - case OPT_S24: - actualOperands[op] = ais.readS24("operand"); - break; - } - } - } - } - - if (!afterExit && (instr instanceof IfTypeIns)) { - long target = ais.getPosition() + actualOperands[0]; - addresses.add(target); - } - codeMap.put(startOffset, new AVM2Instruction(startOffset, instr, actualOperands)); - ais.endDumpLevel(instr.instructionCode); - if (instr.isExitInstruction()) { //do not process jumps if there is return/throw instruction - afterExit = true; - } - } else { - ais.endDumpLevel(); - break; // Unknown instructions are ignored (Some of the obfuscators add unknown instructions) - //throw new UnknownInstructionCode(instructionCode); - } - } - } catch (EndOfStreamException ex) { - // lookupswitch obfuscation, ignore - ais.endDumpLevelUntil(diParent); - } - } - code.addAll(codeMap.values()); - } - - public void compact() { - if (code instanceof ArrayList) { - ((ArrayList) code).trimToSize(); - } - } - - public byte[] getBytes() { - return getBytes(null); - } - - public byte[] getBytes(byte[] origBytes) { - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - - OutputStream cos; - if ((origBytes != null) && (DEBUG_REWRITE)) { - ByteArrayInputStream origis = new ByteArrayInputStream(origBytes); - cos = new CopyOutputStream(bos, origis); - } else { - cos = bos; - } - try { - for (AVM2Instruction instruction : code) { - cos.write(instruction.getBytes()); - } - } catch (IOException ex) { - } - return bos.toByteArray(); - } - - @Override - public String toString() { - StringBuilder s = new StringBuilder(); - for (AVM2Instruction instruction : code) { - s.append(instruction.toString()); - s.append("\r\n"); - } - return s.toString(); - } - - public GraphTextWriter toString(GraphTextWriter writer, LocalData localData) { - int i = 0; - for (AVM2Instruction instruction : code) { - writer.appendNoHilight(Helper.formatAddress(i)); - writer.appendNoHilight(" "); - instruction.toString(writer, localData).newLine(); - i++; - } - return writer; - } - - public GraphTextWriter toASMSource(AVM2ConstantPool constants, Trait trait, MethodInfo info, MethodBody body, ScriptExportMode exportMode, GraphTextWriter writer) { - return toASMSource(constants, trait, info, body, new ArrayList(), exportMode, writer); - } - - public GraphTextWriter toASMSource(AVM2ConstantPool constants, Trait trait, MethodInfo info, MethodBody body, List outputMap, ScriptExportMode exportMode, GraphTextWriter writer) { - invalidateCache(); - if (trait != null) { - if (trait instanceof TraitFunction) { - TraitFunction tf = (TraitFunction) trait; - writer.appendNoHilight("trait "); - writer.hilightSpecial("function ", HighlightSpecialType.TRAIT_TYPE); - writer.hilightSpecial(constants.multinameToString(tf.name_index), HighlightSpecialType.TRAIT_NAME); - writer.appendNoHilight(" slotid "); - writer.hilightSpecial("" + tf.slot_id, HighlightSpecialType.SLOT_ID); - writer.newLine(); - } - if (trait instanceof TraitMethodGetterSetter) { - TraitMethodGetterSetter tm = (TraitMethodGetterSetter) trait; - writer.appendNoHilight("trait "); - switch (tm.kindType) { - case Trait.TRAIT_METHOD: - writer.hilightSpecial("method ", HighlightSpecialType.TRAIT_TYPE); - break; - case Trait.TRAIT_GETTER: - writer.hilightSpecial("getter ", HighlightSpecialType.TRAIT_TYPE); - break; - case Trait.TRAIT_SETTER: - writer.hilightSpecial("setter ", HighlightSpecialType.TRAIT_TYPE); - break; - } - writer.hilightSpecial(constants.multinameToString(tm.name_index), HighlightSpecialType.TRAIT_NAME); - writer.appendNoHilight(" dispid "); - writer.hilightSpecial("" + tm.disp_id, HighlightSpecialType.DISP_ID); - writer.newLine(); - } - } - if (info != null) { - writer.appendNoHilight("method").newLine(); - writer.appendNoHilight("name "); - writer.hilightSpecial(info.name_index == 0 ? "null" : "\"" + Helper.escapeString(info.getName(constants)) + "\"", HighlightSpecialType.METHOD_NAME); - writer.newLine(); - if (info.flagExplicit()) { - writer.appendNoHilight("flag "); - writer.hilightSpecial("EXPLICIT", HighlightSpecialType.FLAG_EXPLICIT); - writer.newLine(); - } - if (info.flagHas_optional()) { - writer.appendNoHilight("flag "); - writer.hilightSpecial("HAS_OPTIONAL", HighlightSpecialType.FLAG_HAS_OPTIONAL); - writer.newLine(); - writer.appendNoHilight("flag HAS_OPTIONAL").newLine(); - } - if (info.flagHas_paramnames()) { - writer.appendNoHilight("flag "); - writer.hilightSpecial("HAS_PARAM_NAMES", HighlightSpecialType.FLAG_HAS_PARAM_NAMES); - writer.newLine(); - } - if (info.flagIgnore_rest()) { - writer.appendNoHilight("flag "); - writer.hilightSpecial("EXPLICIT", HighlightSpecialType.FLAG_IGNORE_REST); - writer.newLine(); - } - if (info.flagNeed_activation()) { - writer.appendNoHilight("flag "); - writer.hilightSpecial("NEED_ACTIVATION", HighlightSpecialType.FLAG_NEED_ACTIVATION); - writer.newLine(); - } - if (info.flagNeed_arguments()) { - writer.appendNoHilight("flag "); - writer.hilightSpecial("NEED_ARGUMENTS", HighlightSpecialType.FLAG_NEED_ARGUMENTS); - writer.newLine(); - } - if (info.flagNeed_rest()) { - writer.appendNoHilight("flag "); - writer.hilightSpecial("NEED_REST", HighlightSpecialType.FLAG_NEED_REST); - writer.newLine(); - } - if (info.flagSetsdxns()) { - writer.appendNoHilight("flag "); - writer.hilightSpecial("SET_DXNS", HighlightSpecialType.FLAG_SET_DXNS); - writer.newLine(); - } - for (int p = 0; p < info.param_types.length; p++) { - writer.appendNoHilight("param "); - writer.hilightSpecial(constants.multinameToString(info.param_types[p]), HighlightSpecialType.PARAM, p); - writer.newLine(); - } - if (info.flagHas_paramnames()) { - for (int n : info.paramNames) { - writer.appendNoHilight("paramname "); - if (n == 0) { - writer.appendNoHilight("null"); - } else { - writer.appendNoHilight("\""); - writer.appendNoHilight(constants.getString(n)); - writer.appendNoHilight("\""); - } - writer.newLine(); - } - } - if (info.flagHas_optional()) { - for (int i = 0; i < info.optional.length; i++) { - ValueKind vk = info.optional[i]; - writer.appendNoHilight("optional "); - writer.hilightSpecial(vk.toString(constants), HighlightSpecialType.OPTIONAL, i); - writer.newLine(); - } - } - writer.appendNoHilight("returns "); - writer.hilightSpecial(constants.multinameToString(info.ret_type), HighlightSpecialType.RETURNS); - writer.newLine(); - } - writer.newLine(); - writer.appendNoHilight("body").newLine(); - - writer.appendNoHilight("maxstack "); - writer.appendNoHilight(body.max_stack); - writer.newLine(); - - writer.appendNoHilight("localcount "); - writer.appendNoHilight(body.max_regs); - writer.newLine(); - - writer.appendNoHilight("initscopedepth "); - writer.appendNoHilight(body.init_scope_depth); - writer.newLine(); - - writer.appendNoHilight("maxscopedepth "); - writer.appendNoHilight(body.max_scope_depth); - writer.newLine(); - - List offsets = new ArrayList<>(); - for (int e = 0; e < body.exceptions.length; e++) { - writer.appendNoHilight("try"); - - writer.appendNoHilight(" from "); - writer.appendNoHilight("ofs"); - writer.appendNoHilight(Helper.formatAddress(body.exceptions[e].start)); - offsets.add((long) body.exceptions[e].start); - - writer.appendNoHilight(" to "); - writer.appendNoHilight("ofs"); - writer.appendNoHilight(Helper.formatAddress(body.exceptions[e].end)); - offsets.add((long) body.exceptions[e].end); - - writer.appendNoHilight(" target "); - writer.appendNoHilight("ofs"); - writer.appendNoHilight(Helper.formatAddress(body.exceptions[e].target)); - offsets.add((long) body.exceptions[e].target); - - writer.appendNoHilight(" type "); - writer.hilightSpecial(body.exceptions[e].type_index == 0 ? "null" : constants.getMultiname(body.exceptions[e].type_index).toString(constants, new ArrayList()), HighlightSpecialType.TRY_TYPE, e); - - writer.appendNoHilight(" name "); - writer.hilightSpecial(body.exceptions[e].name_index == 0 ? "null" : constants.getMultiname(body.exceptions[e].name_index).toString(constants, new ArrayList()), HighlightSpecialType.TRY_NAME, e); - writer.newLine(); - } - - writer.newLine(); - writer.appendNoHilight("code").newLine(); - - for (AVM2Instruction ins : code) { - offsets.addAll(ins.getOffsets()); - } - for (AVM2Instruction ins : code) { - if (ins.replaceWith != null) { - for (Object o : ins.replaceWith) { - if (o instanceof ControlFlowTag) { - ControlFlowTag cft = (ControlFlowTag) o; - if (cft.name.equals("appendjump")) { - offsets.add((long) pos2adr(cft.value)); - } - } - } - } - } - int ip = 0; - int largeLimit = 20000; - boolean markOffsets = code.size() <= largeLimit; - - if (exportMode == ScriptExportMode.HEX) { - Helper.byteArrayToHexWithHeader(writer, getBytes()); - } else { - for (AVM2Instruction ins : code) { - long ofs = ins.offset; - if (exportMode == ScriptExportMode.PCODE_HEX) { - writer.appendNoHilight("; "); - writer.appendNoHilight(Helper.bytesToHexString(ins.getBytes())); - writer.newLine(); - } - if (Configuration.showAllAddresses.get() || offsets.contains(ofs)) { - writer.appendNoHilight("ofs" + Helper.formatAddress(ofs) + ":"); - } - /*for (int e = 0; e < body.exceptions.length; e++) { - if (body.exceptions[e].start == ofs) { - ret.append("exceptionstart " + e + ":"); - } - if (body.exceptions[e].end == ofs) { - ret.append("exceptionend " + e + ":"); - } - if (body.exceptions[e].target == ofs) { - ret.append("exceptiontarget " + e + ":"); - } - }*/ - if (ins.replaceWith != null) { - for (Object o : ins.replaceWith) { - if (o instanceof Integer) { - AVM2Instruction ins2 = code.get((Integer) o); - if (ins2.isIgnored()) { - continue; - } - writer.append("", ins2.mappedOffset > -1 ? ins2.mappedOffset : ofs); - writer.appendNoHilight(ins2.toStringNoAddress(constants, new ArrayList()) + " ;copy from " + Helper.formatAddress(pos2adr((Integer) o))); - writer.newLine(); - outputMap.add((Integer) o); - } else if (o instanceof ControlFlowTag) { - ControlFlowTag cft = (ControlFlowTag) o; - if (cft.name.equals("appendjump")) { - writer.appendNoHilight("jump ofs" + Helper.formatAddress(pos2adr(cft.value))).newLine(); - outputMap.add(-1); - } - if (cft.name.equals("mark")) { - writer.appendNoHilight("ofs" + Helper.formatAddress(pos2adr(cft.value)) + ":"); - } - } - } - } else { - if (!ins.isIgnored()) { - if (markOffsets) { - writer.append("", ins.mappedOffset > -1 ? ins.mappedOffset : ofs); - } - int fixBranch = ins.getFixBranch(); - if (fixBranch > -1) { - if (ins.definition instanceof IfTypeIns) { - for (int i = 0; i < -ins.definition.getStackDelta(ins, null/*IfTypeIns do not require ABCs*/); i++) { - writer.appendNoHilight(new DeobfuscatePopIns().instructionName).newLine(); - } - if (fixBranch == 0) { // jump - writer.appendNoHilight(new JumpIns().instructionName + " ofs" + Helper.formatAddress(ofs + ins.getBytes().length + ins.operands[0])); - } else { - // nojump, ignore - } - } - // TODO: lookupswitch ? - } else { - if (ins.changeJumpTo > -1) { - writer.appendNoHilight(ins.definition.instructionName + " ofs" + Helper.formatAddress(pos2adr(ins.changeJumpTo))); - } else { - writer.appendNoHilight(ins.toStringNoAddress(constants, new ArrayList())); - } - } - writer.newLine(); - outputMap.add(ip); - } - } - ip++; - } - } - return writer; - } - - private boolean cacheActual = false; - - private List posCache; - - private void buildCache() { - posCache = new ArrayList<>(); - long a = 0; - for (int i = 0; i < code.size(); i++) { - posCache.add(a); - a += code.get(i).getBytes().length; - } - posCache.add(a); - cacheActual = true; - } - - public int adr2pos(long address) throws ConvertException { - if (!cacheActual) { - buildCache(); - } - int ret = posCache.indexOf(address); - if (ret == -1) { - throw new ConvertException("Bad jump try conver ofs" + Helper.formatAddress(address) + " ", -1); - } - return ret; - } - - public int pos2adr(int pos) { - if (!cacheActual) { - buildCache(); - } - return posCache.get(pos).intValue(); - } - - public void invalidateCache() { - cacheActual = false; - } - - private List unknownJumps; - - private List ignoredIns; - - boolean isCatched = false; - - /** - * Test for killed register. CalcKilledStats must be called before - * - * @param regName - * @param start - * @param end - * @return - */ - public boolean isKilled(int regName, int start, int end) { - if (!killedRegs.containsKey(regName)) { - return false; - } - for (int ip : killedRegs.get(regName)) { - if (ip >= start && ip <= end) { - return true; - } - } - return false; - } - - private int toSourceCount = 0; - - public Map getLocalRegNamesFromDebug(ABC abc) { - Map localRegNames = new HashMap<>(); - - for (AVM2Instruction ins : code) { - if (ins.definition instanceof DebugIns) { - if (ins.operands[0] == 1) { - String v = abc.constants.getString(ins.operands[1]); - // Same name already exists, it may be wrong names inserted by obfuscator - if (localRegNames.values().contains(v)) { - return new HashMap<>(); - } - localRegNames.put(ins.operands[2] + 1, v); - } - } - } - - // TODO: Make this immune to using existing multinames (?) - return localRegNames; - } - - private Map> killedRegs = new HashMap<>(); - - public void calcKilledStats(MethodBody body) { - killedRegs.clear(); - try { - HashMap> vis = visitCode(body); - for (int k = 0; k < code.size(); k++) { - if (vis.get(k).isEmpty()) { - continue; - } - if (code.get(k).definition instanceof KillIns) { - int regid = code.get(k).operands[0]; - if (!killedRegs.containsKey(regid)) { - killedRegs.put(regid, new HashSet()); - } - killedRegs.get(regid).add(k); - } - } - - } catch (InterruptedException ex) { - // ignored - } - } - - public List clearTemporaryRegisters(List output) { - for (int i = 0; i < output.size(); i++) { - if (output.get(i) instanceof SetLocalAVM2Item) { - if (isKilled(((SetLocalAVM2Item) output.get(i)).regIndex, 0, code.size() - 1)) { - SetLocalAVM2Item lsi = (SetLocalAVM2Item) output.get(i); - if (i + 1 < output.size()) { - if (output.get(i + 1) instanceof ReturnValueAVM2Item) { - ReturnValueAVM2Item rv = (ReturnValueAVM2Item) output.get(i + 1); - if (rv.value instanceof LocalRegAVM2Item) { - LocalRegAVM2Item lr = (LocalRegAVM2Item) rv.value; - if (lr.regIndex == lsi.regIndex) { - rv.value = lsi.value; - } - } - } - } - output.remove(i); - i--; - } - } else if (output.get(i) instanceof WithAVM2Item) { - clearTemporaryRegisters(((WithAVM2Item) output.get(i)).items); - } - } - return output; - } - - public int fixIPAfterDebugLine(int ip) { - if (code.isEmpty()) { - return ip; - } - if (ip >= code.size()) { - return code.size() - 1; - } - while (code.get(ip).definition instanceof DebugLineIns) { - ip++; - } - return ip; - } - - public int fixAddrAfterDebugLine(int addr) throws ConvertException { - return pos2adr(fixIPAfterDebugLine(adr2pos(addr))); - } - - public ConvertOutput toSourceOutput(String path, GraphPart part, boolean processJumps, boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, ABC abc, AVM2ConstantPool constants, List method_info, MethodBody body, int start, int end, HashMap localRegNames, List fullyQualifiedNames, boolean[] visited, HashMap localRegAssigmentIps, HashMap> refs) throws ConvertException, InterruptedException { - calcKilledStats(body); - boolean debugMode = DEBUG_MODE; - if (debugMode) { - System.out.println("OPEN SubSource:" + start + "-" + end + " " + code.get(start).toString() + " to " + code.get(end).toString()); - } - if (visited == null) { - visited = new boolean[code.size()]; - } - //if(true) return ""; - toSourceCount++; - if (toSourceLimit > 0) { - if (toSourceCount > toSourceLimit) { - throw new ConvertException("Limit of subs(" + toSourceLimit + ") was reached", start); - } - } - List output = new ArrayList<>(); - int ip = start; - //try { - //int addr; - iploop: - while (ip <= end) { - - if (ignoredIns.contains(ip)) { - ip++; - continue; - } - boolean processTry = processJumps; - //addr = pos2adr(ip); - int ipfix = fixIPAfterDebugLine(ip); - //int addrfix = pos2adr(ipfix); - int maxend = -1; - - if (ip > end) { - break; - } - - if (unknownJumps.contains(ip)) { - unknownJumps.remove(Integer.valueOf(ip)); - throw new UnknownJumpException(stack, ip, output); - } - if (visited[ip]) { - logger.warning("Code already visited, ofs:" + Helper.formatAddress(pos2adr(ip)) + ", ip:" + ip); - break; - } - visited[ip] = true; - AVM2Instruction ins = code.get(ip); - if (debugMode) { - System.err.println("translating ip " + ip + " ins " + ins.toString() + " stack:" + stack.toString() + " scopeStack:" + scopeStack.toString()); - } - if (ins.definition instanceof NewFunctionIns) { - if (ip + 1 <= end) { - if (code.get(ip + 1).definition instanceof PopIns) { - ip += 2; - continue; - } - } - } - /*if ((ip + 8 < code.size())) { //return in finally clause - if (ins.definition instanceof SetLocalTypeIns) { - if (code.get(ip + 1).definition instanceof PushByteIns) { - AVM2Instruction jmp = code.get(ip + 2); - if (jmp.definition instanceof JumpIns) { - if (jmp.operands[0] == 0) { - if (code.get(ip + 3).definition instanceof LabelIns) { - if (code.get(ip + 4).definition instanceof PopIns) { - if (code.get(ip + 5).definition instanceof LabelIns) { - AVM2Instruction gl = code.get(ip + 6); - if (gl.definition instanceof GetLocalTypeIns) { - if (((GetLocalTypeIns) gl.definition).getRegisterId(gl) == ((SetLocalTypeIns) ins.definition).getRegisterId(ins)) { - AVM2Instruction ki = code.get(ip + 7); - if (ki.definition instanceof KillIns) { - if (ki.operands[0] == ((SetLocalTypeIns) ins.definition).getRegisterId(ins)) { - if (code.get(ip + 8).definition instanceof ReturnValueIns) { - ip = ip + 8; - continue; - } - } - } - } - } - } - } - } - } - } - } - } - }//*/ - - /*if ((ip + 2 < code.size()) && (ins.definition instanceof NewCatchIns)) { // Filling local register in catch clause - if (code.get(ip + 1).definition instanceof DupIns) { - if (code.get(ip + 2).definition instanceof SetLocalTypeIns) { - ins.definition.translate(isStatic, classIndex, localRegs, stack, scopeStack, constants, ins, method_info, output, body, abc, localRegNames, fullyQualifiedNames); - ip += 3; - continue; - } - } - }*/ - if ((ins.definition instanceof GetLocalTypeIns) && (!output.isEmpty()) && (output.get(output.size() - 1) instanceof SetLocalAVM2Item) && (((SetLocalAVM2Item) output.get(output.size() - 1)).regIndex == ((GetLocalTypeIns) ins.definition).getRegisterId(ins)) && isKilled(((SetLocalAVM2Item) output.get(output.size() - 1)).regIndex, start, end)) { - SetLocalAVM2Item slt = (SetLocalAVM2Item) output.remove(output.size() - 1); - stack.push(slt.getValue()); - ip++; - } else if ((ins.definition instanceof SetLocalTypeIns) && (ip + 1 <= end) && (isKilled(((SetLocalTypeIns) ins.definition).getRegisterId(ins), ip, end))) { // set_local_x,get_local_x..kill x - AVM2Instruction insAfter = code.get(ip + 1); - if ((insAfter.definition instanceof GetLocalTypeIns) && (((GetLocalTypeIns) insAfter.definition).getRegisterId(insAfter) == ((SetLocalTypeIns) ins.definition).getRegisterId(ins))) { - GraphTargetItem before = stack.peek(); - ins.definition.translate(isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, constants, ins, method_info, output, body, abc, localRegNames, fullyQualifiedNames, path, localRegAssigmentIps, ip, refs, this); - stack.push(before); - ip += 2; - continue iploop; - } else { - ins.definition.translate(isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, constants, ins, method_info, output, body, abc, localRegNames, fullyQualifiedNames, path, localRegAssigmentIps, ip, refs, this); - ip++; - continue iploop; - } - } else if (ins.definition instanceof DupIns) { - int nextPos; - do { - AVM2Instruction insAfter = code.get(ip + 1); - AVM2Instruction insBefore = ins; - if (ip - 1 >= start) { - insBefore = code.get(ip - 1); - } - if (insAfter.definition instanceof ConvertBIns) { // SWF compiled with debug contain convert_b - ip++; - //addr = pos2adr(ip); - insAfter = code.get(ip + 1); - } - - boolean isAnd; - if (processJumps && (insAfter.definition instanceof IfFalseIns)) { - //stack.add("(" + stack.pop() + ")&&"); - isAnd = true; - } else if (processJumps && (insAfter.definition instanceof IfTrueIns)) { - //stack.add("(" + stack.pop() + ")||"); - isAnd = false; - } else if (insAfter.definition instanceof SetLocalTypeIns) { - // chained assignments - int reg = (((SetLocalTypeIns) insAfter.definition).getRegisterId(insAfter)); - for (int t = ip + 1; t <= end - 1; t++) { - if (code.get(t).definition instanceof KillIns) { - if (code.get(t).operands[0] == reg) { - break; - } - } - if (code.get(t).definition instanceof GetLocalTypeIns) { - if (((GetLocalTypeIns) code.get(t).definition).getRegisterId(code.get(t)) == reg) { - if (code.get(t + 1).definition instanceof KillIns) { - if (code.get(t + 1).operands[0] == reg) { - ConvertOutput assignment = toSourceOutput(path, part, processJumps, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, abc, constants, method_info, body, ip + 2, t - 1, localRegNames, fullyQualifiedNames, visited, localRegAssigmentIps, refs); - GraphTargetItem tar = assignment.output.remove(assignment.output.size() - 1); - tar.firstPart = part; - stack.push(tar); - ip = t + 2; - continue iploop; - } - } - } - } - } - if (!isKilled(reg, 0, end)) { - for (int i = ip; i >= start; i--) { - if (code.get(i).definition instanceof DupIns) { - if (stack.isEmpty()) { - break; // FIXME?o - } - GraphTargetItem v = stack.pop(); - stack.push(new LocalRegAVM2Item(ins, reg, v)); - stack.push(v); - } else { - break; - } - } - } else { - ins.definition.translate(isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, constants, ins, method_info, output, body, abc, localRegNames, fullyQualifiedNames, path, localRegAssigmentIps, ip, refs, this); - } - ip++; - break; - //} - - } else { - ins.definition.translate(isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, constants, ins, method_info, output, body, abc, localRegNames, fullyQualifiedNames, path, localRegAssigmentIps, ip, refs, this); - ip++; - break; - //throw new ConvertException("Unknown pattern after DUP:" + insComparsion.toString()); - } - } while (ins.definition instanceof DupIns); - } else if ((ins.definition instanceof ReturnValueIns) || (ins.definition instanceof ReturnVoidIns) || (ins.definition instanceof ThrowIns)) { - ins.definition.translate(isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, constants, ins, method_info, output, body, abc, localRegNames, fullyQualifiedNames, path, localRegAssigmentIps, ip, refs, this); - //ip = end + 1; - break; - } else if (ins.definition instanceof NewFunctionIns) { - String functionName = ""; - if ((ip >= start + 2) && (ip <= end - 4)) { - AVM2Instruction prev2 = code.get(ip - 2); - if (prev2.definition instanceof NewObjectIns) { - if (prev2.operands[0] == 0) { - if (code.get(ip - 1).definition instanceof PushWithIns) { - boolean hasDup = false; - int plus = 0; - if (code.get(ip + 1).definition instanceof DupIns) { - hasDup = true; - plus = 1; - } - AVM2Instruction psco = code.get(ip + 1 + plus); - if (psco.definition instanceof GetScopeObjectIns) { - if (psco.operands[0] == scopeStack.size() - 1) { - if (code.get(ip + plus + 2).definition instanceof SwapIns) { - if (code.get(ip + plus + 4).definition instanceof PopScopeIns) { - if (code.get(ip + plus + 3).definition instanceof SetPropertyIns) { - functionName = abc.constants.getMultiname(code.get(ip + plus + 3).operands[0]).getName(constants, fullyQualifiedNames, true); - scopeStack.pop();// with - output.remove(output.size() - 1); // with - ip = ip + plus + 4; // +1 below - } - } - } - } - } - } - } - } - } - // What to do when hasDup is false? - ins.definition.translate(isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, constants, ins, method_info, output, body, abc, localRegNames, fullyQualifiedNames, path, localRegAssigmentIps, ip, refs, this); - NewFunctionAVM2Item nft = (NewFunctionAVM2Item) stack.peek(); - nft.functionName = functionName; - ip++; - } else { - try { - ins.definition.translate(isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, constants, ins, method_info, output, body, abc, localRegNames, fullyQualifiedNames, path, localRegAssigmentIps, ip, refs, this); - } catch (RuntimeException re) { - /*String last=""; - int len=5; - for(int i=(ip-len<0?0:ip-len);i maxRegister) { - maxRegister = regId; - } - } - return maxRegister + 1; - } - - public HashMap getLocalRegTypes(AVM2ConstantPool constants, List fullyQualifiedNames) { - HashMap ret = new HashMap<>(); - AVM2Instruction prev = null; - for (AVM2Instruction ins : code) { - if (ins.definition instanceof SetLocalTypeIns) { - if (prev != null) { - if (prev.definition instanceof CoerceOrConvertTypeIns) { - ret.put(((SetLocalTypeIns) ins.definition).getRegisterId(ins), ((CoerceOrConvertTypeIns) prev.definition).getTargetType(constants, prev, fullyQualifiedNames)); - } - } - } - prev = ins; - } - return ret; - - } - - private class Slot { - - public GraphTargetItem scope; - - public Multiname multiname; - - public Slot(GraphTargetItem scope, Multiname multiname) { - this.scope = scope; - this.multiname = multiname; - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof Slot) { - return (((Slot) obj).scope.getThroughRegister() == scope.getThroughRegister()) - && (((Slot) obj).multiname == multiname); - } - return false; - } - - @Override - public int hashCode() { - int hash = 7; - hash = 59 * hash + (this.scope != null ? this.scope.hashCode() : 0); - hash = 59 * hash + (this.multiname != null ? this.multiname.hashCode() : 0); - return hash; - } - } - - public void initToSource() { - toSourceCount = 0; - unknownJumps = new ArrayList<>(); - ignoredIns = new ArrayList<>(); - } - - private void injectDeclarations(List list, boolean[] declaredRegisters, List declaredSlots, ABC abc, MethodBody body) { - //List nowdeclaredRegs=new ArrayList<>(); - //List nowdeclaredSlots=new ArrayList<>(); - for (int i = 0; i < list.size(); i++) { - GraphTargetItem ti = list.get(i); - if (ti instanceof ForEachInAVM2Item) { - ForEachInAVM2Item fei = (ForEachInAVM2Item) ti; - if (fei.expression.object instanceof LocalRegAVM2Item) { - int reg = ((LocalRegAVM2Item) fei.expression.object).regIndex; - if (!declaredRegisters[reg]) { - fei.expression.object = new DeclarationAVM2Item(fei.expression.object); - declaredRegisters[reg] = true; - //nowdeclaredRegs.add(reg); - } - } - } - if (ti instanceof ForInAVM2Item) { - ForInAVM2Item fi = (ForInAVM2Item) ti; - if (fi.expression.object instanceof LocalRegAVM2Item) { - int reg = ((LocalRegAVM2Item) fi.expression.object).regIndex; - if (!declaredRegisters[reg]) { - fi.expression.object = new DeclarationAVM2Item(fi.expression.object); - declaredRegisters[reg] = true; - //nowdeclaredRegs.add(reg); - } - } - } - if (ti instanceof Block) { - Block bl = (Block) ti; - for (List s : bl.getSubs()) { - injectDeclarations(s, declaredRegisters, declaredSlots, abc, body); - } - } - if (ti instanceof SetLocalAVM2Item) { - int reg = ((SetLocalAVM2Item) ti).regIndex; - if (!declaredRegisters[reg]) { - list.set(i, new DeclarationAVM2Item(ti)); - declaredRegisters[reg] = true; - //nowdeclaredRegs.add(reg); - } - } - if (ti instanceof SetSlotAVM2Item) { - SetSlotAVM2Item ssti = (SetSlotAVM2Item) ti; - Slot sl = new Slot(ssti.scope, ssti.slotName); - if (!declaredSlots.contains(sl)) { - GraphTargetItem type = TypeItem.UNBOUNDED; - for (int t = 0; t < body.traits.traits.size(); t++) { - if (body.traits.traits.get(t).getName(abc) == sl.multiname) { - if (body.traits.traits.get(t) instanceof TraitSlotConst) { - type = PropertyAVM2Item.multinameToType(((TraitSlotConst) body.traits.traits.get(t)).type_index, abc.constants); - } - } - } - list.set(i, new DeclarationAVM2Item(ti, type)); - declaredSlots.add(sl); - //nowdeclaredSlots.add(sl); - } - } - } - - /* - //undeclare registers at the end of the block? - for(int reg:nowdeclaredRegs){ - declaredRegisters[reg] = false; - } - - for(Slot s:nowdeclaredSlots){ - declaredSlots.remove(s); - }*/ - } - - public List toGraphTargetItems(String path, boolean isStatic, int scriptIndex, int classIndex, ABC abc, AVM2ConstantPool constants, List method_info, MethodBody body, HashMap localRegNames, ScopeStack scopeStack, boolean isStaticInitializer, List fullyQualifiedNames, Traits initTraits, int staticOperation, HashMap localRegAssigmentIps, HashMap> refs) throws InterruptedException { - initToSource(); - List list; - HashMap localRegs = new HashMap<>(); - - int regCount = getRegisterCount(); - - //try { - list = AVM2Graph.translateViaGraph(path, this, abc, body, isStatic, scriptIndex, classIndex, localRegs, scopeStack, localRegNames, fullyQualifiedNames, staticOperation, localRegAssigmentIps, refs); - - if (initTraits != null) { - for (int i = 0; i < list.size(); i++) { - GraphTargetItem ti = list.get(i); - if ((ti instanceof InitPropertyAVM2Item) || (ti instanceof SetPropertyAVM2Item)) { - int multinameIndex = 0; - GraphTargetItem value = null; - if (ti instanceof InitPropertyAVM2Item) { - multinameIndex = ((InitPropertyAVM2Item) ti).propertyName.multinameIndex; - value = ((InitPropertyAVM2Item) ti).value; - } - if (ti instanceof SetPropertyAVM2Item) { - multinameIndex = ((FullMultinameAVM2Item) ((SetPropertyAVM2Item) ti).propertyName).multinameIndex; - value = ((SetPropertyAVM2Item) ti).value; - } - for (Trait t : initTraits.traits) { - if (t.name_index == multinameIndex) { - if ((t instanceof TraitSlotConst)) { - if (((TraitSlotConst) t).isConst() || isStaticInitializer) { - if ((((TraitSlotConst) t).assignedValue) == null) { - ((TraitSlotConst) t).assignedValue = value; - list.remove(i); - i--; - continue; - } - } - break; - } - } - } - } else { - // In obfuscated code, SetLocal instructions comes first - //break; - } - } - } - if (isStaticInitializer) { - List newList = new ArrayList<>(); - for (GraphTargetItem ti : list) { - if (!(ti instanceof ReturnVoidAVM2Item)) { - if (!(ti instanceof InitPropertyAVM2Item)) { - newList.add(ti); - } - } - } - list = newList; - if (list.isEmpty()) { - return list; - } - } - // Declarations - injectDeclarations(list, new boolean[regCount], new ArrayList(), abc, body); - - int lastPos = list.size() - 1; - if (lastPos < 0) { - lastPos = 0; - } - if ((list.size() > lastPos) && (list.get(lastPos) instanceof ScriptEndItem)) { - lastPos--; - } - if (lastPos < 0) { - lastPos = 0; - } - if ((list.size() > lastPos) && (list.get(lastPos) instanceof ReturnVoidAVM2Item)) { - list.remove(lastPos); - } - - return list; - } - - public void removeInstruction(int pos, MethodBody body) { - if ((pos < 0) || (pos >= code.size())) { - throw new IndexOutOfBoundsException(); - } - int byteCount = code.get(pos).getBytes().length; - long remOffset = code.get(pos).offset; - for (int i = pos + 1; i < code.size(); i++) { - code.get(i).offset -= byteCount; - } - - for (ABCException ex : body.exceptions) { - if (ex.start > remOffset) { - ex.start -= byteCount; - } - if (ex.end > remOffset) { - ex.end -= byteCount; - } - if (ex.target > remOffset) { - ex.target -= byteCount; - } - } - - for (int i = 0; i < pos; i++) { - if (code.get(i).definition instanceof LookupSwitchIns) { - long target = code.get(i).offset + code.get(i).operands[0]; - if (target > remOffset) { - code.get(i).operands[0] -= byteCount; - } - for (int k = 2; k < code.get(i).operands.length; k++) { - target = code.get(i).offset + code.get(i).operands[k]; - if (target > remOffset) { - code.get(i).operands[k] -= byteCount; - } - } - } else { - for (int j = 0; j < code.get(i).definition.operands.length; j++) { - if (code.get(i).definition.operands[j] == AVM2Code.DAT_OFFSET) { - long target = code.get(i).offset + code.get(i).getBytes().length + code.get(i).operands[j]; - if (target > remOffset) { - code.get(i).operands[j] -= byteCount; - } - } - } - } - } - for (int i = pos + 1; i < code.size(); i++) { - if (code.get(i).definition instanceof LookupSwitchIns) { - long target = code.get(i).offset + code.get(i).operands[0]; - if (target < remOffset) { - code.get(i).operands[0] += byteCount; - } - for (int k = 2; k < code.get(i).operands.length; k++) { - target = code.get(i).offset + code.get(i).operands[k]; - if (target < remOffset) { - code.get(i).operands[k] += byteCount; - } - } - } else { - for (int j = 0; j < code.get(i).definition.operands.length; j++) { - if (code.get(i).definition.operands[j] == AVM2Code.DAT_OFFSET) { - long target = code.get(i).offset + code.get(i).getBytes().length + code.get(i).operands[j]; - if (target < remOffset) { - code.get(i).operands[j] += byteCount; - } - } - } - } - } - - code.remove(pos); - invalidateCache(); - } - - public void insertInstruction(int pos, AVM2Instruction instruction) { - if (pos < 0) { - pos = 0; - } - if (pos > code.size()) { - pos = code.size(); - } - int byteCount = instruction.getBytes().length; - if (pos == code.size()) { - instruction.offset = code.get(pos - 1).offset + code.get(pos - 1).getBytes().length; - } else { - instruction.offset = code.get(pos).offset; - } - - for (int i = 0; i < pos; i++) { - for (int j = 0; j < code.get(i).definition.operands.length; j++) { - if (code.get(i).definition.operands[j] == AVM2Code.DAT_OFFSET) { - long target = code.get(i).offset + code.get(i).getBytes().length + code.get(i).operands[j]; - if (target >= instruction.offset) { - code.get(i).operands[j] += byteCount; - } - } - } - } - for (int i = pos; i < code.size(); i++) { - for (int j = 0; j < code.get(i).definition.operands.length; j++) { - if (code.get(i).definition.operands[j] == AVM2Code.DAT_OFFSET) { - long target = code.get(i).offset + code.get(i).getBytes().length + code.get(i).operands[j]; - if (target < instruction.offset) { - code.get(i).operands[j] -= byteCount; - } - } - } - } - - for (int i = pos + 1; i < code.size(); i++) { - code.get(i).offset += byteCount; - } - code.add(pos, instruction); - } - - @SuppressWarnings("unchecked") - private static AVM2LocalData prepareBranchLocalData(AVM2LocalData localData) { - AVM2LocalData ret = new AVM2LocalData(); - ret.isStatic = localData.isStatic; - ret.classIndex = localData.classIndex; - ret.localRegs = new HashMap<>(localData.localRegs); - ret.scopeStack = (ScopeStack) (localData.scopeStack).clone(); - ret.constants = localData.constants; - ret.methodInfo = localData.methodInfo; - ret.methodBody = localData.methodBody; - ret.abc = localData.abc; - ret.localRegNames = localData.localRegNames; - ret.fullyQualifiedNames = localData.fullyQualifiedNames; - ret.parsedExceptions = localData.parsedExceptions; - ret.finallyJumps = localData.finallyJumps; - ret.ignoredSwitches = localData.ignoredSwitches; - ret.scriptIndex = localData.scriptIndex; - ret.localRegAssignmentIps = localData.localRegAssignmentIps; - ret.ip = localData.ip; - ret.refs = localData.refs; - ret.code = localData.code; - return ret; - } - - public int removeTraps(AVM2ConstantPool constants, Trait trait, MethodInfo info, MethodBody body, ABC abc, int scriptIndex, int classIndex, boolean isStatic, String path) throws InterruptedException { - removeDeadCode(constants, trait, info, body); - AVM2LocalData localData = new AVM2LocalData(); - localData.isStatic = isStatic; - localData.classIndex = classIndex; - localData.localRegs = new HashMap<>(); - localData.scopeStack = new ScopeStack(); - localData.constants = abc.constants; - localData.methodInfo = abc.method_info; - localData.methodBody = body; - localData.abc = abc; - localData.localRegNames = body.getLocalRegNames(abc); - localData.fullyQualifiedNames = new ArrayList<>(); - localData.parsedExceptions = new ArrayList<>(); - localData.finallyJumps = new ArrayList<>(); - localData.ignoredSwitches = new ArrayList<>(); - localData.scriptIndex = scriptIndex; - localData.localRegAssignmentIps = new HashMap<>(); - localData.ip = 0; - HashMap> refs = visitCode(body); - localData.refs = refs; - localData.code = this; - int ret = 0; - ret += removeTraps(constants, trait, info, body, localData, new AVM2GraphSource(this, false, -1, -1, new HashMap(), new ScopeStack(), abc, body, new HashMap(), new ArrayList(), new HashMap(), refs), 0, path, refs); - removeIgnored(constants, trait, info, body); - removeDeadCode(constants, trait, info, body); - - return ret; - } - - private void handleRegister(CodeStats stats, int reg) { - if (reg + 1 > stats.maxlocal) { - stats.maxlocal = reg + 1; - } - } - - private boolean walkCode(CodeStats stats, int pos, int stack, int scope, ABC abc) { - while (pos < code.size()) { - AVM2Instruction ins = code.get(pos); - if (stats.instructionStats[pos].seen) { - // check stack mismatch here - return true; - } - - if (ins.definition instanceof NewFunctionIns) { - MethodBody innerBody = abc.findBody(ins.operands[0]); - innerBody.autoFillStats(abc, stats.initscope + (stats.has_activation ? 1 : 0), false); - } - - stats.instructionStats[pos].seen = true; - stats.instructionStats[pos].stackpos = stack; - stats.instructionStats[pos].scopepos = scope; - - int stackDelta = ins.definition.getStackDelta(ins, abc); - int scopeDelta = ins.definition.getScopeStackDelta(ins, abc); - int oldStack = stack; - - //+" deltaScope:"+(scopeDelta>0?"+"+scopeDelta:scopeDelta)+" stack:"+stack+" scope:"+scope); - stack += stackDelta; - scope += scopeDelta; - - stats.instructionStats[pos].stackpos_after = stack; - stats.instructionStats[pos].scopepos_after = scope; - - if (stack > stats.maxstack) { - stats.maxstack = stack; - } - if (scope > stats.maxscope) { - stats.maxscope = scope; - } - - //System.out.println("stack "+oldStack+(stackDelta>=0?"+"+stackDelta:stackDelta)+" max:"+stats.maxstack+" "+ins); - if ((ins.definition instanceof DXNSIns) || (ins.definition instanceof DXNSLateIns)) { - stats.has_set_dxns = true; - } - if (ins.definition instanceof NewActivationIns) { - stats.has_activation = true; - } - if (ins.definition instanceof SetLocalTypeIns) { - handleRegister(stats, ((SetLocalTypeIns) ins.definition).getRegisterId(ins)); - } else if (ins.definition instanceof GetLocalTypeIns) { - handleRegister(stats, ((GetLocalTypeIns) ins.definition).getRegisterId(ins)); - } else { - for (int i = 0; i < ins.definition.operands.length; i++) { - if (ins.definition.operands[i] == DAT_REGISTER_INDEX) { - handleRegister(stats, ins.operands[i]); - } - } - } - if (ins.definition instanceof ReturnValueIns) { - // check stack=1 - return true; - } - if (ins.definition instanceof ReturnVoidIns) { - // check stack=0 - return true; - } - if (ins.definition instanceof JumpIns) { - try { - pos = adr2pos(pos2adr(pos) + ins.getBytes().length + ins.operands[0]); - continue; - } catch (ConvertException ex) { - return false; - } - } else if (ins.definition instanceof IfTypeIns) { - try { - int newpos = adr2pos(pos2adr(pos) + ins.getBytes().length + ins.operands[0]); - walkCode(stats, newpos, stack, scope, abc); - } catch (ConvertException ex) { - return false; - } - } - if (ins.definition instanceof LookupSwitchIns) { - for (int i = 0; i < ins.operands.length; i++) { - if (i == 1) { - continue; - } - try { - int newpos = adr2pos(pos2adr(pos) + ins.operands[i]); - if (!walkCode(stats, newpos, stack, scope, abc)) { - return false; - } - } catch (ConvertException ex) { - return false; - } - } - } - pos++; - } - return true; - } - - public CodeStats getStats(ABC abc, MethodBody body, int initScope) { - CodeStats stats = new CodeStats(this); - stats.initscope = initScope; - if (!walkCode(stats, 0, 0, initScope, abc)) { - return null; - } - int scopePos = -1; - int prevStart = 0; - for (int e = 0; e < body.exceptions.length; e++) { - ABCException ex = body.exceptions[e]; - try { - if (scopePos == -1) { - scopePos = stats.instructionStats[adr2pos(ex.end) - 1].scopepos_after; - } - List visited = new ArrayList<>(); - for (int i = 0; i < stats.instructionStats.length; i++) { - if (stats.instructionStats[i].seen) { - visited.add(i); - } - } - if (!walkCode(stats, adr2pos(ex.target), 1 + (ex.isFinally() ? 1 : 0), scopePos, abc)) { - return null; - } - int maxIp = 0; - // searching for visited instruction in second run which has maximum position - for (int i = 0; i < stats.instructionStats.length; i++) { - if (stats.instructionStats[i].seen && !visited.contains(i)) { - maxIp = i; - } - } - scopePos = stats.instructionStats[maxIp].scopepos_after; - int stackPos = stats.instructionStats[maxIp].stackpos_after; - int nextIp = maxIp + 1; - if (code.get(maxIp).definition instanceof JumpIns) { - nextIp = adr2pos(pos2adr(nextIp) + code.get(maxIp).operands[0]); - } - if (nextIp < stats.instructionStats.length) { - int origScopePos = stats.instructionStats[nextIp].scopepos; - int origStackPos = stats.instructionStats[nextIp].stackpos; - - if (prevStart == ex.start && ex.isFinally() && !code.get(nextIp).isExit() && stats.instructionStats[nextIp].seen) { - for (int i = 0; i < stats.instructionStats.length; i++) { - stats.instructionStats[i].seen = false; - } - // Rerun rest with new scopePos, stackPos - if (!walkCode(stats, nextIp, origStackPos + 1/*magic!*/, scopePos - 1 /*magic!*/, abc)) { - return null; - } - scopePos--; - } - } - prevStart = ex.start; - } catch (ConvertException ex1) { - // ignore - } - } - //stats.maxscope+=initScope; - return stats; - } - - private void visitCode(int ip, int lastIp, HashMap> refs) throws InterruptedException { - if (Thread.currentThread().isInterrupted()) { - throw new InterruptedException(); - } - while (ip < code.size()) { - if (!refs.containsKey(ip)) { - refs.put(ip, new ArrayList()); - } - refs.get(ip).add(lastIp); - lastIp = ip; - if (refs.get(ip).size() > 1) { - break; - } - AVM2Instruction ins = code.get(ip); - if (ins.definition instanceof ThrowIns) { - break; - } - if (ins.definition instanceof ReturnValueIns) { - break; - } - if (ins.definition instanceof ReturnVoidIns) { - break; - } - if (ins.definition instanceof LookupSwitchIns) { - try { - for (int i = 2; i < ins.operands.length; i++) { - visitCode(adr2pos(pos2adr(ip) + ins.operands[i]), ip, refs); - } - ip = adr2pos(pos2adr(ip) + ins.operands[0]); - continue; - } catch (ConvertException ex) { - } - } - if (ins.definition instanceof JumpIns) { - try { - ip = adr2pos(pos2adr(ip) + ins.getBytes().length + ins.operands[0]); - continue; - } catch (ConvertException ex) { - logger.log(Level.FINE, null, ex); - } - } else if (ins.definition instanceof IfTypeIns) { - try { - visitCode(adr2pos(pos2adr(ip) + ins.getBytes().length + ins.operands[0]), ip, refs); - } catch (ConvertException ex) { - logger.log(Level.FINE, null, ex); - } - } - ip++; - }; - } - - public HashMap> visitCode(MethodBody body) throws InterruptedException { - HashMap> refs = new HashMap<>(); - for (int i = 0; i < code.size(); i++) { - refs.put(i, new ArrayList()); - } - visitCode(0, 0, refs); - int pos = 0; - for (ABCException e : body.exceptions) { - pos++; - try { - visitCode(adr2pos(e.start), adr2pos(e.start) - 1, refs); - visitCode(adr2pos(e.start), -1, refs); - visitCode(adr2pos(e.target), adr2pos(e.end), refs); - visitCode(adr2pos(e.end), -pos, refs); - } catch (ConvertException ex) { - logger.log(Level.FINE, null, ex); - } - } - return refs; - } - - private int visitCodeTrap(int ip, int[] visited, AVM2Instruction prev, AVM2Instruction prev2) { - int ret = 0; - while (ip < visited.length) { - visited[ip]++; - if (visited[ip] > 1) { - break; - } - AVM2Instruction ins = code.get(ip); - if (ins.definition instanceof ThrowIns) { - break; - } - if (ins.definition instanceof ReturnValueIns) { - break; - } - if (ins.definition instanceof ReturnVoidIns) { - break; - } - if (ins.definition instanceof LookupSwitchIns) { - try { - for (int i = 2; i < ins.operands.length; i++) { - ret += visitCodeTrap(adr2pos(pos2adr(ip) + ins.operands[i]), visited, prev, prev2); - } - ip = adr2pos(pos2adr(ip) + ins.operands[0]); - prev2 = prev; - prev = ins; - continue; - } catch (ConvertException ex) { - } - } - if (ins.definition instanceof JumpIns) { - try { - ip = adr2pos(pos2adr(ip) + ins.getBytes().length + ins.operands[0]); - prev2 = prev; - prev = ins; - continue; - } catch (ConvertException ex) { - logger.log(Level.FINE, null, ex); - } - } else if (ins.definition instanceof IfTypeIns) { - if ((prev != null) && (prev2 != null)) { - if ((prev.definition instanceof PushByteIns) && (prev2.definition instanceof PushByteIns)) { - if (ins.definition instanceof IfEqIns) { - prev.ignored = true; - prev2.ignored = true; - if (prev.operands[0] == prev2.operands[0]) { - ins.definition = new JumpIns(); - visited[ip]--; - } else { - ins.ignored = true; - ip++; - } - ret++; - continue; - } - if (ins.definition instanceof IfNeIns) { - prev.ignored = true; - prev2.ignored = true; - if (prev.operands[0] != prev2.operands[0]) { - ins.definition = new JumpIns(); - visited[ip]--; - } else { - ins.ignored = true; - ip++; - } - ret++; - continue; - } - } - } - if ((prev != null) && ins.definition instanceof IfTrueIns) { - if (prev.definition instanceof PushTrueIns) { - prev.ignored = true; - ins.definition = new JumpIns(); - visited[ip]--; - ret++; - continue; - } else if (prev.definition instanceof PushFalseIns) { - prev.ignored = true; - ins.ignored = true; - ret++; - ip++; - continue; - } - } - if ((prev != null) && ins.definition instanceof IfFalseIns) { - if (prev.definition instanceof PushFalseIns) { - prev.ignored = true; - ins.definition = new JumpIns(); - visited[ip]--; - ret++; - continue; - } else if (prev.definition instanceof PushTrueIns) { - prev.ignored = true; - ins.ignored = true; - ret++; - ip++; - continue; - } - } - try { - ret += visitCodeTrap(adr2pos(pos2adr(ip) + ins.getBytes().length + ins.operands[0]), visited, prev, prev2); - } catch (ConvertException ex) { - logger.log(Level.FINE, null, ex); - } - } - ip++; - prev2 = prev; - prev = ins; - }; - return ret; - - } - - private static class ControlFlowTag { - - public String name; - - public int value; - - public ControlFlowTag(String name, int value) { - this.name = name; - this.value = value; - } - } - - public void restoreControlFlow(int ip, HashMap> refs, int[] visited2, HashMap> appended) throws ConvertException { - List buf = new ArrayList<>(); - boolean cont = false; - int continueip = 0; - for (; ip < code.size(); ip++) { - AVM2Instruction ins = code.get(ip); - - if ((refs.containsKey(ip) && refs.get(ip).size() > 1) || (visited2[ip] > 0)) { - if (cont) { - buf.add(new ControlFlowTag("appendjump", ip)); - } - cont = false; - if (visited2[ip] > 0) { - break; - } - } - visited2[ip]++; - if (ins.definition instanceof LookupSwitchIns) { - - if (cont) { - buf.add(new ControlFlowTag("appendjump", ip)); - } - cont = false; - restoreControlFlow(adr2pos(pos2adr(ip) + ins.operands[0]), refs, visited2, appended); - for (int i = 2; i < ins.operands.length; i++) { - restoreControlFlow(adr2pos(pos2adr(ip) + ins.operands[i]), refs, visited2, appended); - } - break; - } - if (ins.definition instanceof JumpIns) { - int newip = adr2pos(pos2adr(ip + 1) + ins.operands[0]); - - boolean allJumpsOrIfs = true; - for (int ref : refs.get(ip)) { - if (ref < 0) { - continue; - } - if (!(code.get(ref).definition instanceof JumpIns)) { - if (!(code.get(ref).definition instanceof IfTypeIns)) { - allJumpsOrIfs = false; - break; - } else { - if (adr2pos(pos2adr(ref + 1) + code.get(ref).operands[0]) != ip) { - allJumpsOrIfs = false; - break; - } - } - } - } - if (allJumpsOrIfs) { - for (int ref : refs.get(ip)) { - if (ref < 0) { - continue; - } - code.get(ref).changeJumpTo = newip; - } - } - if ((newip < code.size()) && (refs.containsKey(newip) && refs.get(newip).size() == 1)) { - if (!cont) { - continueip = ip; - buf = new ArrayList<>(); - appended.put(continueip, buf); - } - cont = true; - } else { - if (cont) { - buf.add(new ControlFlowTag("appendjump", newip)); - } - cont = false; - } - ip = newip - 1; - } else if (ins.definition instanceof IfTypeIns) { - int newip = adr2pos(pos2adr(ip + 1) + ins.operands[0]); - if (cont) { - buf.add(new ControlFlowTag("appendjump", ip)); - } - cont = false; - restoreControlFlow(newip, refs, visited2, appended); - } else if ((ins.definition instanceof ReturnVoidIns) || (ins.definition instanceof ReturnValueIns) || (ins.definition instanceof ThrowIns)) { - if (cont) { - buf.add(ip); - } - break; - } else if (cont) { - buf.add(ip); - } - } - - } - - private void restoreControlFlowPass(AVM2ConstantPool constants, Trait trait, MethodInfo info, MethodBody body, boolean secondpass) throws InterruptedException { - try { - HashMap> refs; - int[] visited2 = new int[code.size()]; - refs = visitCode(body); - HashMap> appended = new HashMap<>(); - /*if (secondpass) { - restoreControlFlow(code.size() - 1, refs, visited2, appended); - } else*/ { - restoreControlFlow(0, refs, visited2, appended); - for (ABCException e : body.exceptions) { - try { - restoreControlFlow(adr2pos(e.start), refs, visited2, appended); - restoreControlFlow(adr2pos(e.target), refs, visited2, appended); - restoreControlFlow(adr2pos(e.end), refs, visited2, appended); - } catch (ConvertException ex) { - logger.log(Level.FINE, null, ex); - } - } - } - for (int ip : appended.keySet()) { - code.get(ip).replaceWith = appended.get(ip); - } - } catch (ConvertException cex) { - logger.log(Level.SEVERE, "Error during restore control flow", cex); - } - invalidateCache(); - try { - List outputMap = new ArrayList<>(); - HighlightedTextWriter writer = new HighlightedTextWriter(Configuration.getCodeFormatting(), false); - toASMSource(constants, trait, info, body, outputMap, ScriptExportMode.PCODE, writer); - String src = writer.toString(); - - AVM2Code acode = ASM3Parser.parse(new StringReader(src), constants, null, body, info); - for (int i = 0; i < acode.code.size(); i++) { - if (outputMap.size() > i) { - int tpos = outputMap.get(i); - if (tpos == -1) { - } else if (code.get(tpos).mappedOffset >= 0) { - acode.code.get(i).mappedOffset = code.get(tpos).mappedOffset; - } else { - acode.code.get(i).mappedOffset = pos2adr(tpos); - } - - } - } - this.code = acode.code; - } catch (IOException ex) { - logger.log(Level.SEVERE, null, ex); - } catch (AVM2ParseException ex) { - logger.log(Level.FINE, null, ex); - } - invalidateCache(); - removeDeadCode(constants, trait, info, body); - } - - public void restoreControlFlow(AVM2ConstantPool constants, Trait trait, MethodInfo info, MethodBody body) throws InterruptedException { - restoreControlFlowPass(constants, trait, info, body, false); - //restoreControlFlowPass(constants, body, true); - } - - /*private void removeIgnored(MethodBody body) { - for (int rem = code.size() - 1; rem >= 0; rem--) { - if (code.get(rem).ignored) { - removeInstruction(rem, body); - } - } - }*/ - public void removeIgnored(AVM2ConstantPool constants, Trait trait, MethodInfo info, MethodBody body) throws InterruptedException { - try { - List outputMap = new ArrayList<>(); - HighlightedTextWriter writer = new HighlightedTextWriter(Configuration.getCodeFormatting(), false); - toASMSource(constants, trait, info, body, outputMap, ScriptExportMode.PCODE, writer); - String src = writer.toString(); - AVM2Code acode = ASM3Parser.parse(new StringReader(src), constants, trait, body, info); - for (int i = 0; i < acode.code.size(); i++) { - if (outputMap.size() > i) { - int tpos = outputMap.get(i); - if (tpos == -1) { - } else if (code.get(tpos).mappedOffset >= 0) { - acode.code.get(i).mappedOffset = code.get(tpos).mappedOffset; - } else { - acode.code.get(i).mappedOffset = pos2adr(tpos); - } - } - } - this.code = acode.code; - } catch (IOException | AVM2ParseException ex) { - } - invalidateCache(); - } - - public int removeDeadCode(AVM2ConstantPool constants, Trait trait, MethodInfo info, MethodBody body) throws InterruptedException { - HashMap> refs = visitCode(body); - - int cnt = 0; - for (int i = code.size() - 1; i >= 0; i--) { - if (refs.get(i).isEmpty()) { - code.get(i).ignored = true; - //removeInstruction(i, body); - cnt++; - } - } - - removeIgnored(constants, trait, info, body); - for (int i = code.size() - 1; i >= 0; i--) { - AVM2Instruction ins = code.get(i); - if (ins.definition instanceof JumpIns) { - if (ins.operands[0] == 0) { - code.get(i).ignored = true; - //removeInstruction(i, body); - cnt++; - } - } - } - removeIgnored(constants, trait, info, body); - return cnt; - } - - public void markMappedOffsets() { - int ofs = 0; - for (int i = 0; i < code.size(); i++) { - code.get(i).mappedOffset = ofs; - ofs += code.get(i).getBytes().length; - - } - } - - private static class Decision { - - public boolean jumpUsed = false; - - public boolean skipUsed = false; - - public Set casesUsed = new HashSet<>(); - - HashMap registers = new HashMap<>(); - } - - private static int getMostCommonIp(AVM2GraphSource code, List branches) { - List> reachable = new ArrayList<>(); - for (int i = 0; i < branches.size(); i++) { - List r = new ArrayList<>(); - getReachableIps(code, branches.get(i), r); - } - - int commonLevel; - Map levelMap = new HashMap<>(); - for (List first : reachable) { - int maxclevel = 0; - Set visited = new HashSet<>(); - for (Integer p : first) { - if (visited.contains(p)) { - continue; - } - visited.add(p); - boolean common = true; - commonLevel = 1; - for (List r : reachable) { - if (r == first) { - continue; - } - if (r.contains(p)) { - commonLevel++; - } - } - if (commonLevel <= maxclevel) { - continue; - } - maxclevel = commonLevel; - if (levelMap.containsKey(p)) { - if (levelMap.get(p) > commonLevel) { - commonLevel = levelMap.get(p); - } - } - levelMap.put(p, commonLevel); - if (common) { - //return p; - } - } - } - for (int i = reachable.size() - 1; i >= 2; i--) { - for (Integer p : levelMap.keySet()) { - if (levelMap.get(p) == i) { - return p; - } - } - } - for (Integer p : levelMap.keySet()) { - if (levelMap.get(p) == branches.size()) { - return p; - } - } - return -1; - } - - public static void getReachableIps(AVM2GraphSource code, int ip, List reachable) { - do { - if (reachable.contains(ip)) { - return; - } - reachable.add(ip); - GraphSourceItem ins = code.get(ip); - if (ins.isJump() || ins.isBranch()) { - List branches = ins.getBranches(code); - for (int i = 1; i < branches.size(); i++) { - getReachableIps(code, branches.get(i), reachable); - } - ip = branches.get(0); - continue; - } - ip++; - } while (ip < code.size()); - } - - public static boolean isDirectAncestor(int currentIp, int ancestor, HashMap> refs) { - return isDirectAncestor(currentIp, ancestor, refs, new ArrayList()); - } - - private static boolean isDirectAncestor(int currentIp, int ancestor, HashMap> refs, List visited) { - if (currentIp == -1) { - return true; - } - do { - if (currentIp == ancestor) { - return true; - } - if (currentIp == 0) { - return false; - } - if (visited.contains(currentIp)) { - return true; - } - visited.add(currentIp); - if (refs.containsKey(currentIp)) { - List currentRefs = refs.get(currentIp); - if ((currentRefs != null) && (!currentRefs.isEmpty())) { - for (int i = 1; i < currentRefs.size(); i++) { - if (!isDirectAncestor(currentRefs.get(i), ancestor, refs, visited)) { - return false; - } - } - currentIp = currentRefs.get(0); - continue; - } - } - currentIp--; - } while (currentIp >= 0); - return false; - } - - public static boolean getPreviousReachableIps(int currentIp, HashMap> refs, Set reachable, Set visited) { - do { - if (visited.contains(currentIp)) { - return false; - } - reachable.add(currentIp); - visited.add(currentIp); - if (refs.containsKey(currentIp)) { - List currentRefs = refs.get(currentIp); - if ((currentRefs != null) && (!currentRefs.isEmpty())) { - if (currentRefs.size() == 1) { - currentIp = currentRefs.get(0); - continue; - } - boolean r = false; - for (int i = 0; i < currentRefs.size(); i++) { - Set nr = new HashSet<>(); - boolean v = getPreviousReachableIps(currentRefs.get(i), refs, nr, visited); - if ((!v) || nr.contains(0)) { - reachable.addAll(nr); - } - r = r || v; - } - return r; - } - } - currentIp--; - } while (currentIp >= 0); - return true; - } - - @SuppressWarnings("unchecked") - private static int removeTraps(HashMap> refs, boolean secondPass, boolean indeterminate, AVM2LocalData localData, TranslateStack stack, List output, AVM2GraphSource code, int ip, HashMap visited, HashMap> visitedStates, HashMap decisions, String path, int recursionLevel) throws InterruptedException { - if (Thread.currentThread().isInterrupted()) { - throw new InterruptedException(); - } - if (recursionLevel > code.size() + 1) { - throw new TranslateException("removeTraps max recursion level reached."); - } - boolean debugMode = false; - int ret = 0; - iploop: - while ((ip > -1) && ip < code.size()) { - - if (false) { //useVisited) { - if (visited.containsKey(ip)) { - break; - } - if (!visited.containsKey(ip)) { - visited.put(ip, 0); - } else { - visited.put(ip, visited.get(ip) + 1); - } - } else { - HashMap currentState = localData.localRegs; - - if (visitedStates.containsKey(ip)) { - HashMap lastState = visitedStates.get(ip); - if (lastState.equals(currentState)) { - break; - } - } - visitedStates.put(ip, (HashMap) currentState.clone()); - - } - - int curVisited; - if (!visited.containsKey(ip)) { - curVisited = 1; - } else { - curVisited = visited.get(ip) + 1; - } - visited.put(ip, curVisited); - - List r = refs.get(ip); - /*if (r != null) { - if (r.size() > 1) { - if (!stack.isEmpty()) { - GraphTargetItem it = stack.pop(); - stack.push(new NotCompileTimeAVM2Item(null, it)); - } - } - }*/ - - AVM2Instruction ins = code.get(ip); - // Errorneous code inserted by some obfuscators - if (ins.definition instanceof NewObjectIns) { - if (ins.operands[0] > stack.size()) { - ins.setIgnored(true, 0); - } - } - if (ins.definition instanceof NewArrayIns) { - if (ins.operands[0] > stack.size()) { - ins.setIgnored(true, 0); - } - } - - if (ins.isIgnored()) { - ip++; - continue; - } - - if (debugMode) { - System.out.println((indeterminate ? "useV " : "") + (secondPass ? "secondPass " : "") + "Visit " + ip + ": " + ins + " stack:" + stack.toString()); - HashMap registers = localData.localRegs; - System.out.print("Registers:"); - for (int reg : registers.keySet()) { - try { - System.out.print(" r" + reg + ": " + registers.get(reg).getResult()); - } catch (NullPointerException npe) { - System.out.print(" r" + reg + ": " + "null"); - } - } - System.out.println(""); - } - if (secondPass) { - /*if ((ins instanceof AVM2Instruction) && (((AVM2Instruction) ins).definition instanceof PopIns)) { - GraphTargetItem top = stack.peek(); - for (GraphSourceItemPos p : top.getNeededSources()) { - if (p == null) { - continue; - } - if (p.item == null) { - continue; - } - if (p.item.isIgnored()) { - ins.setIgnored(true, 0); - break; - } - } - }*/ - } - - if (ins.definition instanceof NewFunctionIns) { - stack.push(new BooleanAVM2Item(null, true)); - } else { - localData.ip = ip; - ins.translate(localData, stack, output, Graph.SOP_USE_STATIC, path); - } - - if (ins.definition instanceof SetLocalTypeIns) { - SetLocalTypeIns slt = (SetLocalTypeIns) ins.definition; - int regId = slt.getRegisterId(ins); - if (indeterminate) { - HashMap registers = localData.localRegs; - GraphTargetItem regVal = registers.get(regId); - if (regVal.isCompileTime()) { - registers.put(regId, new NotCompileTimeItem(null, regVal)); - } - } - } - - if (ins.isExit()) { - break; - } - - if (ins.isBranch() || ins.isJump()) { - List branches = ins.getBranches(code); - if (ins.definition instanceof IfTypeIns - && (!(ins.definition instanceof JumpIns)) - && (!stack.isEmpty()) - && (stack.peek().isCompileTime()) - && (!stack.peek().hasSideEffect())) { - boolean condition = EcmaScript.toBoolean(stack.peek().getResult()); - if (debugMode) { - if (condition) { - System.out.println("JUMP"); - } else { - System.out.println("SKIP"); - } - } - Decision dec = new Decision(); - if (decisions.containsKey(ins)) { - dec = decisions.get(ins); - } else { - decisions.put(ins, dec); - } - if (condition) { - dec.jumpUsed = true; - } else { - dec.skipUsed = true; - } - - if (branches.size() > 1) { - if (secondPass) { - if (condition && (dec.jumpUsed) && (!dec.skipUsed)) { - ins.setFixBranch(0); - //((AVM2Instruction) ins).definition = new JumpIns(); - } - if ((!condition) && (!dec.jumpUsed) && (dec.skipUsed)) { - ins.setFixBranch(1); - //ins.setIgnored(true, 0); - } - } - } - GraphTargetItem tar = stack.pop(); - /*if (secondPass && (dec.jumpUsed != dec.skipUsed)) { - for (GraphSourceItemPos pos : tar.getNeededSources()) { - if (pos.item instanceof AVM2Instruction) { - if (((AVM2Instruction) pos.item).definition instanceof DupIns) { - pos.item.setIgnored(true, 0); - break; - } - } - if (pos.item != ins) { - pos.item.setIgnored(true, 0); - } - } - - }*/ - if (branches.size() == 1) { - ip = branches.get(0); - } else { - ip = condition ? branches.get(0) : branches.get(1); - } - continue; - } else { - if (ins.isBranch() && (!ins.isJump())) { - GraphTargetItem top = stack.pop(); - - Decision dec = new Decision(); - if (decisions.containsKey(ins)) { - dec = decisions.get(ins); - } else { - decisions.put(ins, dec); - } - HashMap registers = localData.localRegs; - boolean regChanged = false; - if (!dec.registers.isEmpty()) { - if (dec.registers.size() != registers.size()) { - regChanged = true; - } else { - for (int reg : registers.keySet()) { - if (!dec.registers.containsKey(reg)) { - regChanged = true; - break; - } - if (!registers.get(reg).isCompileTime() && dec.registers.get(reg).isCompileTime()) { - regChanged = true; - break; - } - } - } - } - dec.registers.putAll(registers); - dec.jumpUsed = true; - dec.skipUsed = true; - - if (!regChanged && ((!(top instanceof HasNextAVM2Item) && curVisited > 1) || (curVisited > 2))) { - for (int b : branches) { - int visc = 0; - if (visited.containsKey(b)) { - visc = visited.get(b); - } - if (visc == 0) {//= 0) { //useVisited || (!ins.isJump()) - ret += removeTraps(refs, secondPass, indeterminate, prepareBranchLocalData(localData), brStack, output, code, b, visited, visitedStates, decisions, path, recursionLevel + 1); - } else { - if (debugMode) { - System.out.println("Negative branch:" + b); - } - } - } - } - break; - } - ip++; - } - if (ip < 0) { - System.out.println("Visited Negative: " + ip); - } - return ret; - } - - public static int removeTraps(AVM2ConstantPool constants, Trait trait, MethodInfo info, MethodBody body, AVM2LocalData localData, AVM2GraphSource code, int addr, String path, HashMap> refs) throws InterruptedException { - HashMap decisions = new HashMap<>(); - removeTraps(refs, false, false, localData, new TranslateStack(), new ArrayList(), code, code.adr2pos(addr), new HashMap(), new HashMap>(), decisions, path, 0); - int cnt = 0; - for (AVM2Instruction src : decisions.keySet()) { - Decision dec = decisions.get(src); - if (dec != null) { - if (src.definition instanceof LookupSwitchIns) { - if (dec.casesUsed.size() == 1) { - for (int c : dec.casesUsed) { - src.setFixBranch(c); - cnt++; - } - } - } else { - if (dec.jumpUsed && !dec.skipUsed) { - src.setFixBranch(0); - cnt++; - } - if (!dec.jumpUsed && dec.skipUsed) { - src.setFixBranch(1); - cnt++; - } - } - } - } - //int cnt = removeTraps(refs, true, false, localData, new TranslateStack(), new ArrayList(), code, code.adr2pos(addr), new HashMap(), new HashMap>(), decisions, path); - code.getCode().removeIgnored(constants, trait, info, body); - return cnt; - } - /*public static int removeTraps(AVM2LocalData localData, AVM2GraphSource code, int addr) { - AVM2Graph.translateViaGraph(localData, "", code, new ArrayList(), Graph.SOP_REMOVE_STATIC); - return 1; - }*/ - - @Override - public AVM2Code clone() throws CloneNotSupportedException { - AVM2Code ret = (AVM2Code) super.clone(); - if (code != null) { - List codeCopy = new ArrayList<>(code.size()); - for (AVM2Instruction ins : code) { - codeCopy.add(ins.clone()); - } - ret.code = codeCopy; - } - return ret; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2; + +import com.jpexs.decompiler.flash.EndOfStreamException; +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.ABCInputStream; +import com.jpexs.decompiler.flash.abc.AVM2LocalData; +import com.jpexs.decompiler.flash.abc.CopyOutputStream; +import com.jpexs.decompiler.flash.abc.avm2.graph.AVM2Graph; +import com.jpexs.decompiler.flash.abc.avm2.graph.AVM2GraphSource; +import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; +import com.jpexs.decompiler.flash.abc.avm2.instructions.DeobfuscatePopIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.IfTypeIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.instructions.alchemy.Lf32Ins; +import com.jpexs.decompiler.flash.abc.avm2.instructions.alchemy.Lf64Ins; +import com.jpexs.decompiler.flash.abc.avm2.instructions.alchemy.Li16Ins; +import com.jpexs.decompiler.flash.abc.avm2.instructions.alchemy.Li32Ins; +import com.jpexs.decompiler.flash.abc.avm2.instructions.alchemy.Li8Ins; +import com.jpexs.decompiler.flash.abc.avm2.instructions.alchemy.Sf32Ins; +import com.jpexs.decompiler.flash.abc.avm2.instructions.alchemy.Sf64Ins; +import com.jpexs.decompiler.flash.abc.avm2.instructions.alchemy.Si16Ins; +import com.jpexs.decompiler.flash.abc.avm2.instructions.alchemy.Si32Ins; +import com.jpexs.decompiler.flash.abc.avm2.instructions.alchemy.Si8Ins; +import com.jpexs.decompiler.flash.abc.avm2.instructions.alchemy.Sxi16Ins; +import com.jpexs.decompiler.flash.abc.avm2.instructions.alchemy.Sxi1Ins; +import com.jpexs.decompiler.flash.abc.avm2.instructions.alchemy.Sxi8Ins; +import com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic.AddIIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic.AddIns; +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.DivideIns; +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.arithmetic.ModuloIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic.MultiplyIIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic.MultiplyIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic.NegateIIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic.NegateIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic.NotIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic.SubtractIIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic.SubtractIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.bitwise.BitAndIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.bitwise.BitNotIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.bitwise.BitOrIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.bitwise.BitXorIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.bitwise.LShiftIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.bitwise.RShiftIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.bitwise.URShiftIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.comparison.EqualsIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.comparison.GreaterEqualsIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.comparison.GreaterThanIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.comparison.LessEqualsIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.comparison.LessThanIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.comparison.StrictEqualsIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.construction.ConstructIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.construction.ConstructPropIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.construction.ConstructSuperIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.construction.NewActivationIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.construction.NewArrayIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.construction.NewCatchIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.construction.NewClassIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.construction.NewFunctionIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.construction.NewObjectIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.debug.DebugFileIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.debug.DebugIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.debug.DebugLineIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.executing.CallIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.executing.CallMethodIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.executing.CallPropLexIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.executing.CallPropVoidIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.executing.CallPropertyIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.executing.CallStaticIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.executing.CallSuperIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.executing.CallSuperVoidIns; +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.IfGeIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.IfGtIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.IfLeIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.IfLtIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.IfNGeIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.IfNGtIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.IfNLeIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.IfNLtIns; +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.abc.avm2.instructions.jumps.IfTrueIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.JumpIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.LookupSwitchIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.DecLocalIIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.DecLocalIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.GetLocal0Ins; +import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.GetLocal1Ins; +import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.GetLocal2Ins; +import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.GetLocal3Ins; +import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.GetLocalIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.GetLocalTypeIns; +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.localregs.KillIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.SetLocal0Ins; +import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.SetLocal1Ins; +import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.SetLocal2Ins; +import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.SetLocal3Ins; +import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.SetLocalIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.SetLocalTypeIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other.DeletePropertyIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other.FindDefIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other.FindPropertyIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other.FindPropertyStrictIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetDescendantsIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetGlobalScopeIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetGlobalSlotIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetLexIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetPropertyIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetScopeObjectIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetSlotIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetSuperIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other.HasNext2Ins; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other.HasNextIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other.InIns; +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.NextNameIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other.NextValueIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other.NopIns; +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.other.SetGlobalSlotIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other.SetPropertyIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other.SetSlotIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other.SetSuperIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other.ThrowIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.AbsJumpIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.AddDIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.AddPIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.AllocIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.BkptIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.BkptLineIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.CallInterfaceIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.CallSuperIdIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.CodeGenOpIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.CoerceBIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.CoerceDIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.CoerceIIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.CoerceOIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.CoerceUIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.ConcatIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.ConvertF4Ins; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.ConvertMIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.ConvertMPIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.DecLocalPIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.DecodeIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.DecrementPIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.DelDescendantsIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.DeletePropertyLateIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.DividePIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.DoubleToAtomIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.FindPropGlobalIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.GetOuterScopeIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.IncLocalPIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.IncrementPIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.InvalidIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.Lf32x4Ins; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.MarkIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.ModuloPIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.MultiplyPIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.NegatePIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.PrologueIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.PushConstantIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.PushDNanIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.PushDecimalIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.PushFloat4Ins; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.SendEnterIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.SetPropertyLateIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.Sf32x4Ins; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.SubtractPIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.SweepIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.TimestampIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.VerifyOpIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.VerifyPassIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.WbIns; +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.PopScopeIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushByteIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushDoubleIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushFalseIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushIntIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushNamespaceIns; +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.stack.PushScopeIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushShortIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushStringIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushTrueIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushUIntIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushUndefinedIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushWithIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.SwapIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.types.ApplyTypeIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.types.AsTypeIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.types.AsTypeLateIns; +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.CoerceOrConvertTypeIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.types.CoerceSIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.types.ConvertBIns; +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.ConvertOIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.types.ConvertSIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.types.ConvertUIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.types.InstanceOfIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.types.IsTypeIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.types.IsTypeLateIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.types.TypeOfIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.xml.CheckFilterIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.xml.DXNSIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.xml.DXNSLateIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.xml.EscXAttrIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.xml.EscXElemIns; +import com.jpexs.decompiler.flash.abc.avm2.model.BooleanAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.FullMultinameAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.HasNextAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.InitPropertyAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.LocalRegAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.NewFunctionAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.ReturnValueAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.ReturnVoidAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.SetLocalAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.SetPropertyAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.SetSlotAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.WithAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.clauses.DeclarationAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.clauses.ForEachInAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.clauses.ForInAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.parser.AVM2ParseException; +import com.jpexs.decompiler.flash.abc.avm2.parser.pcode.ASM3Parser; +import com.jpexs.decompiler.flash.abc.avm2.parser.script.PropertyAVM2Item; +import com.jpexs.decompiler.flash.abc.types.ABCException; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.flash.abc.types.Multiname; +import com.jpexs.decompiler.flash.abc.types.ValueKind; +import com.jpexs.decompiler.flash.abc.types.traits.Trait; +import com.jpexs.decompiler.flash.abc.types.traits.TraitFunction; +import com.jpexs.decompiler.flash.abc.types.traits.TraitMethodGetterSetter; +import com.jpexs.decompiler.flash.abc.types.traits.TraitSlotConst; +import com.jpexs.decompiler.flash.abc.types.traits.Traits; +import com.jpexs.decompiler.flash.configuration.Configuration; +import com.jpexs.decompiler.flash.dumpview.DumpInfo; +import com.jpexs.decompiler.flash.ecma.EcmaScript; +import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; +import com.jpexs.decompiler.flash.helpers.GraphTextWriter; +import com.jpexs.decompiler.flash.helpers.HighlightedTextWriter; +import com.jpexs.decompiler.flash.helpers.hilight.HighlightSpecialType; +import com.jpexs.decompiler.graph.Block; +import com.jpexs.decompiler.graph.Graph; +import com.jpexs.decompiler.graph.GraphPart; +import com.jpexs.decompiler.graph.GraphSourceItem; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.NotCompileTimeItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateException; +import com.jpexs.decompiler.graph.TranslateStack; +import com.jpexs.decompiler.graph.TypeItem; +import com.jpexs.decompiler.graph.model.LocalData; +import com.jpexs.decompiler.graph.model.ScriptEndItem; +import com.jpexs.helpers.Helper; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.StringReader; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class AVM2Code implements Cloneable { + + private static final Logger logger = Logger.getLogger(AVM2Code.class.getName()); + + private static final boolean DEBUG_MODE = false; + + public static int toSourceLimit = -1; + + public List code = new ArrayList<>(); + + public static boolean DEBUG_REWRITE = false; + + public static final int OPT_U30 = 0x100; + + public static final int OPT_U8 = 0x200; + + public static final int OPT_S24 = 0x300; + + public static final int OPT_CASE_OFFSETS = 0x400; + + public static final int OPT_BYTE = 0x500; + + public static final int DAT_MULTINAME_INDEX = OPT_U30 + 0x01; + + public static final int DAT_ARG_COUNT = OPT_U30 + 0x02; + + public static final int DAT_METHOD_INDEX = OPT_U30 + 0x03; + + public static final int DAT_STRING_INDEX = OPT_U30 + 0x04; + + public static final int DAT_DEBUG_TYPE = OPT_U8 + 0x05; + + public static final int DAT_REGISTER_INDEX = OPT_U8 + 0x06; + + public static final int DAT_LINENUM = OPT_U30 + 0x07; + + public static final int DAT_LOCAL_REG_INDEX = OPT_U30 + 0x08; + + public static final int DAT_SLOT_INDEX = OPT_U30 + 0x09; + + public static final int DAT_SLOT_SCOPE_INDEX = OPT_U30 + 0x0A; + + public static final int DAT_OFFSET = OPT_S24 + 0x0B; + + public static final int DAT_EXCEPTION_INDEX = OPT_U30 + 0x0C; + + public static final int DAT_CLASS_INDEX = OPT_U30 + 0x0D; + + public static final int DAT_INT_INDEX = OPT_U30 + 0x0E; + + public static final int DAT_UINT_INDEX = OPT_U30 + 0x0F; + + public static final int DAT_DOUBLE_INDEX = OPT_U30 + 0x10; + + public static final int DAT_DECIMAL_INDEX = OPT_U30 + 0x11; + + public static final int DAT_CASE_BASEOFFSET = OPT_S24 + 0x12; + + public static final int DAT_DECIMAL_PARAMS = OPT_U30 + 0x13; + + public static InstructionDefinition[] instructionSet = new InstructionDefinition[]{ + /*0x00*/null, + /*0x01*/ new BkptIns(), + /*0x02*/ new NopIns(), + /*0x03*/ new ThrowIns(), + /*0x04*/ new GetSuperIns(), + /*0x05*/ new SetSuperIns(), + /*0x06*/ new DXNSIns(), + /*0x07*/ new DXNSLateIns(), + /*0x08*/ new KillIns(), + /*0x09*/ new LabelIns(), + /*0x0A*/ new Lf32x4Ins(), + /*0x0B*/ new Sf32x4Ins(), + /*0x0C*/ new IfNLtIns(), + /*0x0D*/ new IfNLeIns(), + /*0x0E*/ new IfNGtIns(), + /*0x0F*/ new IfNGeIns(), + /*0x10*/ new JumpIns(), + /*0x11*/ new IfTrueIns(), + /*0x12*/ new IfFalseIns(), + /*0x13*/ new IfEqIns(), + /*0x14*/ new IfNeIns(), + /*0x15*/ new IfLtIns(), + /*0x16*/ new IfLeIns(), + /*0x17*/ new IfGtIns(), + /*0x18*/ new IfGeIns(), + /*0x19*/ new IfStrictEqIns(), + /*0x1A*/ new IfStrictNeIns(), + /*0x1B*/ new LookupSwitchIns(), + /*0x1C*/ new PushWithIns(), + /*0x1D*/ new PopScopeIns(), + /*0x1E*/ new NextNameIns(), + /*0x1F*/ new HasNextIns(), + /*0x20*/ new PushNullIns(), + /*0x21*/ new PushUndefinedIns(), + /*0x22*/ new PushConstantIns(), // new PushUninitializedIns() + /*0x23*/ new NextValueIns(), + /*0x24*/ new PushByteIns(), + /*0x25*/ new PushShortIns(), + /*0x26*/ new PushTrueIns(), + /*0x27*/ new PushFalseIns(), + /*0x28*/ new PushNanIns(), + /*0x29*/ new PopIns(), + /*0x2A*/ new DupIns(), + /*0x2B*/ new SwapIns(), + /*0x2C*/ new PushStringIns(), + /*0x2D*/ new PushIntIns(), + /*0x2E*/ new PushUIntIns(), + /*0x2F*/ new PushDoubleIns(), + /*0x30*/ new PushScopeIns(), + /*0x31*/ new PushNamespaceIns(), + /*0x32*/ new HasNext2Ins(), + /*0x33*/ new PushDecimalIns(), + /*0x34*/ new PushDNanIns(), + /*0x35*/ new Li8Ins(), + /*0x36*/ new Li16Ins(), + /*0x37*/ new Li32Ins(), + /*0x38*/ new Lf32Ins(), + /*0x39*/ new Lf64Ins(), + /*0x3A*/ new Si8Ins(), + /*0x3B*/ new Si16Ins(), + /*0x3C*/ new Si32Ins(), + /*0x3D*/ new Sf32Ins(), + /*0x3E*/ new Sf64Ins(), + /*0x3F*/ null, + /*0x40*/ new NewFunctionIns(), + /*0x41*/ new CallIns(), + /*0x42*/ new ConstructIns(), + /*0x43*/ new CallMethodIns(), + /*0x44*/ new CallStaticIns(), + /*0x45*/ new CallSuperIns(), + /*0x46*/ new CallPropertyIns(), + /*0x47*/ new ReturnVoidIns(), + /*0x48*/ new ReturnValueIns(), + /*0x49*/ new ConstructSuperIns(), + /*0x4A*/ new ConstructPropIns(), + /*0x4B*/ new CallSuperIdIns(), + /*0x4C*/ new CallPropLexIns(), + /*0x4D*/ new CallInterfaceIns(), + /*0x4E*/ new CallSuperVoidIns(), + /*0x4F*/ new CallPropVoidIns(), + /*0x50*/ new Sxi1Ins(), + /*0x51*/ new Sxi8Ins(), + /*0x52*/ new Sxi16Ins(), + /*0x53*/ new ApplyTypeIns(), + /*0x54*/ new PushFloat4Ins(), + /*0x55*/ new NewObjectIns(), + /*0x56*/ new NewArrayIns(), + /*0x57*/ new NewActivationIns(), + /*0x58*/ new NewClassIns(), + /*0x59*/ new GetDescendantsIns(), + /*0x5A*/ new NewCatchIns(), + /*0x5B*/ new DelDescendantsIns(), + /* // Duplicate OPCODE with deldescendants. Prefering deldescendants (found in FLEX compiler) + new FindPropGlobalStrictIns(),*/ + /*0x5C*/ new FindPropGlobalIns(), + /*0x5D*/ new FindPropertyStrictIns(), + /*0x5E*/ new FindPropertyIns(), + /*0x5F*/ new FindDefIns(), + /*0x60*/ new GetLexIns(), + /*0x61*/ new SetPropertyIns(), + /*0x62*/ new GetLocalIns(), + /*0x63*/ new SetLocalIns(), + /*0x64*/ new GetGlobalScopeIns(), + /*0x65*/ new GetScopeObjectIns(), + /*0x66*/ new GetPropertyIns(), + /*0x67*/ new GetOuterScopeIns(), // new GetPropertyLateIns() + /*0x68*/ new InitPropertyIns(), + /*0x69*/ new SetPropertyLateIns(), + /*0x6A*/ new DeletePropertyIns(), + /*0x6B*/ new DeletePropertyLateIns(), + /*0x6C*/ new GetSlotIns(), + /*0x6D*/ new SetSlotIns(), + /*0x6E*/ new GetGlobalSlotIns(), + /*0x6F*/ new SetGlobalSlotIns(), + /*0x70*/ new ConvertSIns(), + /*0x71*/ new EscXElemIns(), + /*0x72*/ new EscXAttrIns(), + /*0x73*/ new ConvertIIns(), + /*0x74*/ new ConvertUIns(), + /*0x75*/ new ConvertDIns(), + /*0x76*/ new ConvertBIns(), + /*0x77*/ new ConvertOIns(), + /*0x78*/ new CheckFilterIns(), + /*0x79*/ new ConvertMIns(), + /*0x7A*/ new ConvertMPIns(), + /*0x7B*/ new ConvertF4Ins(), + /*0x7C*/ null, + /*0x7D*/ null, + /*0x7E*/ null, + /*0x7F*/ null, + /*0x80*/ new CoerceIns(), + /*0x81*/ new CoerceBIns(), + /*0x82*/ new CoerceAIns(), + /*0x83*/ new CoerceIIns(), + /*0x84*/ new CoerceDIns(), + /*0x85*/ new CoerceSIns(), + /*0x86*/ new AsTypeIns(), + /*0x87*/ new AsTypeLateIns(), + /*0x88*/ new CoerceUIns(), + /*0x89*/ new CoerceOIns(), + /*0x8A*/ null, + /*0x8B*/ null, + /*0x8C*/ null, + /*0x8D*/ null, + /*0x8E*/ null, + /*0x8F*/ new NegatePIns(), + /*0x90*/ new NegateIns(), + /*0x91*/ new IncrementIns(), + /*0x92*/ new IncLocalIns(), + /*0x93*/ new DecrementIns(), + /*0x94*/ new DecLocalIns(), + /*0x95*/ new TypeOfIns(), + /*0x96*/ new NotIns(), + /*0x97*/ new BitNotIns(), + /*0x98*/ null, + /*0x99*/ null, + /*0x9A*/ new ConcatIns(), + /*0x9B*/ new AddDIns(), + /*0x9C*/ new IncrementPIns(), + /*0x9D*/ new IncLocalPIns(), + /*0x9E*/ new DecrementPIns(), + /*0x9F*/ new DecLocalPIns(), + /*0xA0*/ new AddIns(), + /*0xA1*/ new SubtractIns(), + /*0xA2*/ new MultiplyIns(), + /*0xA3*/ new DivideIns(), + /*0xA4*/ new ModuloIns(), + /*0xA5*/ new LShiftIns(), + /*0xA6*/ new RShiftIns(), + /*0xA7*/ new URShiftIns(), + /*0xA8*/ new BitAndIns(), + /*0xA9*/ new BitOrIns(), + /*0xAA*/ new BitXorIns(), + /*0xAB*/ new EqualsIns(), + /*0xAC*/ new StrictEqualsIns(), + /*0xAD*/ new LessThanIns(), + /*0xAE*/ new LessEqualsIns(), + /*0xAF*/ new GreaterThanIns(), + /*0xB0*/ new GreaterEqualsIns(), + /*0xB1*/ new InstanceOfIns(), + /*0xB2*/ new IsTypeIns(), + /*0xB3*/ new IsTypeLateIns(), + /*0xB4*/ new InIns(), + /*0xB5*/ new AddPIns(), + /*0xB6*/ new SubtractPIns(), + /*0xB7*/ new MultiplyPIns(), + /*0xB8*/ new DividePIns(), + /*0xB9*/ new ModuloPIns(), + /*0xBA*/ null, + /*0xBB*/ null, + /*0xBC*/ null, + /*0xBD*/ null, + /*0xBE*/ null, + /*0xBF*/ null, + /*0xC0*/ new IncrementIIns(), + /*0xC1*/ new DecrementIIns(), + /*0xC2*/ new IncLocalIIns(), + /*0xC3*/ new DecLocalIIns(), + /*0xC4*/ new NegateIIns(), + /*0xC5*/ new AddIIns(), + /*0xC6*/ new SubtractIIns(), + /*0xC7*/ new MultiplyIIns(), + /*0xC8*/ null, + /*0xC9*/ null, + /*0xCA*/ null, + /*0xCB*/ null, + /*0xCC*/ null, + /*0xCD*/ null, + /*0xCE*/ null, + /*0xCF*/ null, + /*0xD0*/ new GetLocal0Ins(), + /*0xD1*/ new GetLocal1Ins(), + /*0xD2*/ new GetLocal2Ins(), + /*0xD3*/ new GetLocal3Ins(), + /*0xD4*/ new SetLocal0Ins(), + /*0xD5*/ new SetLocal1Ins(), + /*0xD6*/ new SetLocal2Ins(), + /*0xD7*/ new SetLocal3Ins(), + /*0xD8*/ null, + /*0xD9*/ null, + /*0xDA*/ null, + /*0xDB*/ null, + /*0xDC*/ null, + /*0xDD*/ null, + /*0xDE*/ null, + /*0xDF*/ null, + /*0xE0*/ null, + /*0xE1*/ null, + /*0xE2*/ null, + /*0xE3*/ null, + /*0xE4*/ null, + /*0xE5*/ null, + /*0xE6*/ null, + /*0xE7*/ null, + /*0xE8*/ null, + /*0xE9*/ null, + /*0xEA*/ null, + /*0xEB*/ null, + /*0xEC*/ null, + /*0xED*/ new InvalidIns(), + /*0xEE*/ new AbsJumpIns(), + /*0xEF*/ new DebugIns(), + /*0xF0*/ new DebugLineIns(), + /*0xF1*/ new DebugFileIns(), + /*0xF2*/ new BkptLineIns(), + /*0xF3*/ new TimestampIns(), + /*0xF4*/ null, + /*0xF5*/ new VerifyPassIns(), + /*0xF6*/ new AllocIns(), + /*0xF7*/ new MarkIns(), + /*0xF8*/ new WbIns(), + /*0xF9*/ new PrologueIns(), + /*0xFA*/ new SendEnterIns(), + /*0xFB*/ new DoubleToAtomIns(), + /*0xFC*/ new SweepIns(), + /*0xFD*/ new CodeGenOpIns(), + /*0xFE*/ new VerifyOpIns(), + /*0xFF*/ new DecodeIns(),}; + // endoflist + + public boolean hideTemporaryRegisters = true; + + public static final String IDENTOPEN = "/*IDENTOPEN*/"; + + public static final String IDENTCLOSE = "/*IDENTCLOSE*/"; + + public AVM2Code() { + } + + public Object execute(HashMap arguments, AVM2ConstantPool constants) { + int pos = 0; + LocalDataArea lda = new LocalDataArea(); + lda.localRegisters = arguments; + try { + while (true) { + AVM2Instruction ins = code.get(pos); + if (ins.definition instanceof JumpIns) { + pos = adr2pos((Long) ins.getParamsAsList(constants).get(0)); + continue; + } + if (ins.definition instanceof IfFalseIns) { + Boolean b = (Boolean) lda.operandStack.pop(); + if (b == false) { + pos = adr2pos((Long) ins.getParamsAsList(constants).get(0)); + } else { + pos++; + } + continue; + } + if (ins.definition instanceof IfTrueIns) { + Boolean b = (Boolean) lda.operandStack.pop(); + if (b == true) { + pos = adr2pos((Long) ins.getParamsAsList(constants).get(0)); + } else { + pos++; + } + continue; + } + if (ins.definition instanceof ReturnValueIns) { + return lda.operandStack.pop(); + } + if (ins.definition instanceof ReturnVoidIns) { + return null; + } + ins.definition.execute(lda, constants, ins.getParamsAsList(constants)); + pos++; + } + } catch (ConvertException e) { + } + return null; + } + + public void calculateDebugFileLine(ABC abc) { + calculateDebugFileLine(null, 0, 0, abc, new HashSet()); + } + + private boolean calculateDebugFileLine(String debugFile, int debugLine, int pos, ABC abc, Set seen) { + while (pos < code.size()) { + AVM2Instruction ins = code.get(pos); + if (seen.contains(pos)) { + return true; + } + + seen.add(pos); + + if (ins.definition instanceof DebugFileIns) { + debugFile = abc.constants.getString(ins.operands[0]); + } + + if (ins.definition instanceof DebugLineIns) { + debugLine = ins.operands[0]; + } + + ins.setFileLine(debugFile, debugLine); + + if (ins.definition instanceof NewFunctionIns) { + MethodBody innerBody = abc.findBody(ins.operands[0]); + innerBody.getCode().calculateDebugFileLine(debugFile, debugLine, 0, abc, new HashSet()); + } + + if (ins.definition instanceof ReturnValueIns) { + return true; + } + if (ins.definition instanceof ReturnVoidIns) { + return true; + } + if (ins.definition instanceof JumpIns) { + try { + pos = adr2pos(pos2adr(pos) + ins.getBytes().length + ins.operands[0]); + continue; + } catch (ConvertException ex) { + return false; + } + } else if (ins.definition instanceof IfTypeIns) { + try { + int newpos = adr2pos(pos2adr(pos) + ins.getBytes().length + ins.operands[0]); + calculateDebugFileLine(debugFile, debugLine, newpos, abc, seen); + } catch (ConvertException ex) { + return false; + } + } + if (ins.definition instanceof LookupSwitchIns) { + for (int i = 0; i < ins.operands.length; i++) { + if (i == 1) { + continue; + } + try { + int newpos = adr2pos(pos2adr(pos) + ins.operands[i]); + if (!calculateDebugFileLine(debugFile, debugLine, newpos, abc, seen)) { + return false; + } + } catch (ConvertException ex) { + return false; + } + } + } + pos++; + } + return true; + } + + public AVM2Code(ABCInputStream ais) throws IOException { + Map codeMap = new TreeMap<>(); + DumpInfo diParent = ais.dumpInfo; + List addresses = new ArrayList<>(); + long startPos = ais.getPosition(); + addresses.add(startPos); + + while (!addresses.isEmpty()) { + long address = addresses.remove(0); + boolean afterExit = false; + if (codeMap.containsKey(address)) { + continue; + } + if (address < startPos) // no jump outside block + { + continue; + } + try { + ais.seek(address); + while (ais.available() > 0) { + DumpInfo di = ais.newDumpLevel("instruction", "instruction"); + long startOffset = ais.getPosition(); + int instructionCode = ais.read("instructionCode"); + InstructionDefinition instr = instructionSet[instructionCode]; + if (di != null) { + di.name = instr.instructionName; + } + if (instr != null) { + int[] actualOperands = null; + if (instructionCode == 0x1b) { // switch + int firstOperand = ais.readS24("default_offset"); + int case_count = ais.readU30("case_count"); + actualOperands = new int[case_count + 3]; + actualOperands[0] = firstOperand; + actualOperands[1] = case_count; + for (int c = 0; c < case_count + 1; c++) { + actualOperands[2 + c] = ais.readS24("actualOperand"); + } + } else { + if (instr.operands.length > 0) { + actualOperands = new int[instr.operands.length]; + for (int op = 0; op < instr.operands.length; op++) { + switch (instr.operands[op] & 0xff00) { + case OPT_U30: + actualOperands[op] = ais.readU30("operand"); + break; + case OPT_U8: + actualOperands[op] = ais.read("operand"); + break; + case OPT_BYTE: + actualOperands[op] = (byte) ais.read("operand"); + break; + case OPT_S24: + actualOperands[op] = ais.readS24("operand"); + break; + } + } + } + } + + if (!afterExit && (instr instanceof IfTypeIns)) { + long target = ais.getPosition() + actualOperands[0]; + addresses.add(target); + } + codeMap.put(startOffset, new AVM2Instruction(startOffset, instr, actualOperands)); + ais.endDumpLevel(instr.instructionCode); + if (instr.isExitInstruction()) { //do not process jumps if there is return/throw instruction + afterExit = true; + } + } else { + ais.endDumpLevel(); + break; // Unknown instructions are ignored (Some of the obfuscators add unknown instructions) + //throw new UnknownInstructionCode(instructionCode); + } + } + } catch (EndOfStreamException ex) { + // lookupswitch obfuscation, ignore + ais.endDumpLevelUntil(diParent); + } + } + code.addAll(codeMap.values()); + } + + public void compact() { + if (code instanceof ArrayList) { + ((ArrayList) code).trimToSize(); + } + } + + public byte[] getBytes() { + return getBytes(null); + } + + public byte[] getBytes(byte[] origBytes) { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + + OutputStream cos; + if ((origBytes != null) && (DEBUG_REWRITE)) { + ByteArrayInputStream origis = new ByteArrayInputStream(origBytes); + cos = new CopyOutputStream(bos, origis); + } else { + cos = bos; + } + try { + for (AVM2Instruction instruction : code) { + cos.write(instruction.getBytes()); + } + } catch (IOException ex) { + } + return bos.toByteArray(); + } + + @Override + public String toString() { + StringBuilder s = new StringBuilder(); + for (AVM2Instruction instruction : code) { + s.append(instruction.toString()); + s.append("\r\n"); + } + return s.toString(); + } + + public GraphTextWriter toString(GraphTextWriter writer, LocalData localData) { + int i = 0; + for (AVM2Instruction instruction : code) { + writer.appendNoHilight(Helper.formatAddress(i)); + writer.appendNoHilight(" "); + instruction.toString(writer, localData).newLine(); + i++; + } + return writer; + } + + public GraphTextWriter toASMSource(AVM2ConstantPool constants, Trait trait, MethodInfo info, MethodBody body, ScriptExportMode exportMode, GraphTextWriter writer) { + return toASMSource(constants, trait, info, body, new ArrayList(), exportMode, writer); + } + + public GraphTextWriter toASMSource(AVM2ConstantPool constants, Trait trait, MethodInfo info, MethodBody body, List outputMap, ScriptExportMode exportMode, GraphTextWriter writer) { + invalidateCache(); + if (trait != null) { + if (trait instanceof TraitFunction) { + TraitFunction tf = (TraitFunction) trait; + writer.appendNoHilight("trait "); + writer.hilightSpecial("function ", HighlightSpecialType.TRAIT_TYPE); + writer.hilightSpecial(constants.multinameToString(tf.name_index), HighlightSpecialType.TRAIT_NAME); + writer.appendNoHilight(" slotid "); + writer.hilightSpecial("" + tf.slot_id, HighlightSpecialType.SLOT_ID); + writer.newLine(); + } + if (trait instanceof TraitMethodGetterSetter) { + TraitMethodGetterSetter tm = (TraitMethodGetterSetter) trait; + writer.appendNoHilight("trait "); + switch (tm.kindType) { + case Trait.TRAIT_METHOD: + writer.hilightSpecial("method ", HighlightSpecialType.TRAIT_TYPE); + break; + case Trait.TRAIT_GETTER: + writer.hilightSpecial("getter ", HighlightSpecialType.TRAIT_TYPE); + break; + case Trait.TRAIT_SETTER: + writer.hilightSpecial("setter ", HighlightSpecialType.TRAIT_TYPE); + break; + } + writer.hilightSpecial(constants.multinameToString(tm.name_index), HighlightSpecialType.TRAIT_NAME); + writer.appendNoHilight(" dispid "); + writer.hilightSpecial("" + tm.disp_id, HighlightSpecialType.DISP_ID); + writer.newLine(); + } + } + if (info != null) { + writer.appendNoHilight("method").newLine(); + writer.appendNoHilight("name "); + writer.hilightSpecial(info.name_index == 0 ? "null" : "\"" + Helper.escapeString(info.getName(constants)) + "\"", HighlightSpecialType.METHOD_NAME); + writer.newLine(); + if (info.flagExplicit()) { + writer.appendNoHilight("flag "); + writer.hilightSpecial("EXPLICIT", HighlightSpecialType.FLAG_EXPLICIT); + writer.newLine(); + } + if (info.flagHas_optional()) { + writer.appendNoHilight("flag "); + writer.hilightSpecial("HAS_OPTIONAL", HighlightSpecialType.FLAG_HAS_OPTIONAL); + writer.newLine(); + writer.appendNoHilight("flag HAS_OPTIONAL").newLine(); + } + if (info.flagHas_paramnames()) { + writer.appendNoHilight("flag "); + writer.hilightSpecial("HAS_PARAM_NAMES", HighlightSpecialType.FLAG_HAS_PARAM_NAMES); + writer.newLine(); + } + if (info.flagIgnore_rest()) { + writer.appendNoHilight("flag "); + writer.hilightSpecial("EXPLICIT", HighlightSpecialType.FLAG_IGNORE_REST); + writer.newLine(); + } + if (info.flagNeed_activation()) { + writer.appendNoHilight("flag "); + writer.hilightSpecial("NEED_ACTIVATION", HighlightSpecialType.FLAG_NEED_ACTIVATION); + writer.newLine(); + } + if (info.flagNeed_arguments()) { + writer.appendNoHilight("flag "); + writer.hilightSpecial("NEED_ARGUMENTS", HighlightSpecialType.FLAG_NEED_ARGUMENTS); + writer.newLine(); + } + if (info.flagNeed_rest()) { + writer.appendNoHilight("flag "); + writer.hilightSpecial("NEED_REST", HighlightSpecialType.FLAG_NEED_REST); + writer.newLine(); + } + if (info.flagSetsdxns()) { + writer.appendNoHilight("flag "); + writer.hilightSpecial("SET_DXNS", HighlightSpecialType.FLAG_SET_DXNS); + writer.newLine(); + } + for (int p = 0; p < info.param_types.length; p++) { + writer.appendNoHilight("param "); + writer.hilightSpecial(constants.multinameToString(info.param_types[p]), HighlightSpecialType.PARAM, p); + writer.newLine(); + } + if (info.flagHas_paramnames()) { + for (int n : info.paramNames) { + writer.appendNoHilight("paramname "); + if (n == 0) { + writer.appendNoHilight("null"); + } else { + writer.appendNoHilight("\""); + writer.appendNoHilight(constants.getString(n)); + writer.appendNoHilight("\""); + } + writer.newLine(); + } + } + if (info.flagHas_optional()) { + for (int i = 0; i < info.optional.length; i++) { + ValueKind vk = info.optional[i]; + writer.appendNoHilight("optional "); + writer.hilightSpecial(vk.toString(constants), HighlightSpecialType.OPTIONAL, i); + writer.newLine(); + } + } + writer.appendNoHilight("returns "); + writer.hilightSpecial(constants.multinameToString(info.ret_type), HighlightSpecialType.RETURNS); + writer.newLine(); + } + writer.newLine(); + writer.appendNoHilight("body").newLine(); + + writer.appendNoHilight("maxstack "); + writer.appendNoHilight(body.max_stack); + writer.newLine(); + + writer.appendNoHilight("localcount "); + writer.appendNoHilight(body.max_regs); + writer.newLine(); + + writer.appendNoHilight("initscopedepth "); + writer.appendNoHilight(body.init_scope_depth); + writer.newLine(); + + writer.appendNoHilight("maxscopedepth "); + writer.appendNoHilight(body.max_scope_depth); + writer.newLine(); + + List offsets = new ArrayList<>(); + for (int e = 0; e < body.exceptions.length; e++) { + writer.appendNoHilight("try"); + + writer.appendNoHilight(" from "); + writer.appendNoHilight("ofs"); + writer.appendNoHilight(Helper.formatAddress(body.exceptions[e].start)); + offsets.add((long) body.exceptions[e].start); + + writer.appendNoHilight(" to "); + writer.appendNoHilight("ofs"); + writer.appendNoHilight(Helper.formatAddress(body.exceptions[e].end)); + offsets.add((long) body.exceptions[e].end); + + writer.appendNoHilight(" target "); + writer.appendNoHilight("ofs"); + writer.appendNoHilight(Helper.formatAddress(body.exceptions[e].target)); + offsets.add((long) body.exceptions[e].target); + + writer.appendNoHilight(" type "); + writer.hilightSpecial(body.exceptions[e].type_index == 0 ? "null" : constants.getMultiname(body.exceptions[e].type_index).toString(constants, new ArrayList()), HighlightSpecialType.TRY_TYPE, e); + + writer.appendNoHilight(" name "); + writer.hilightSpecial(body.exceptions[e].name_index == 0 ? "null" : constants.getMultiname(body.exceptions[e].name_index).toString(constants, new ArrayList()), HighlightSpecialType.TRY_NAME, e); + writer.newLine(); + } + + writer.newLine(); + writer.appendNoHilight("code").newLine(); + + for (AVM2Instruction ins : code) { + offsets.addAll(ins.getOffsets()); + } + for (AVM2Instruction ins : code) { + if (ins.replaceWith != null) { + for (Object o : ins.replaceWith) { + if (o instanceof ControlFlowTag) { + ControlFlowTag cft = (ControlFlowTag) o; + if (cft.name.equals("appendjump")) { + offsets.add((long) pos2adr(cft.value)); + } + } + } + } + } + int ip = 0; + int largeLimit = 20000; + boolean markOffsets = code.size() <= largeLimit; + + if (exportMode == ScriptExportMode.HEX) { + Helper.byteArrayToHexWithHeader(writer, getBytes()); + } else { + for (AVM2Instruction ins : code) { + long ofs = ins.offset; + if (exportMode == ScriptExportMode.PCODE_HEX) { + writer.appendNoHilight("; "); + writer.appendNoHilight(Helper.bytesToHexString(ins.getBytes())); + writer.newLine(); + } + if (Configuration.showAllAddresses.get() || offsets.contains(ofs)) { + writer.appendNoHilight("ofs" + Helper.formatAddress(ofs) + ":"); + } + /*for (int e = 0; e < body.exceptions.length; e++) { + if (body.exceptions[e].start == ofs) { + ret.append("exceptionstart " + e + ":"); + } + if (body.exceptions[e].end == ofs) { + ret.append("exceptionend " + e + ":"); + } + if (body.exceptions[e].target == ofs) { + ret.append("exceptiontarget " + e + ":"); + } + }*/ + if (ins.replaceWith != null) { + for (Object o : ins.replaceWith) { + if (o instanceof Integer) { + AVM2Instruction ins2 = code.get((Integer) o); + if (ins2.isIgnored()) { + continue; + } + writer.append("", ins2.mappedOffset > -1 ? ins2.mappedOffset : ofs); + writer.appendNoHilight(ins2.toStringNoAddress(constants, new ArrayList()) + " ;copy from " + Helper.formatAddress(pos2adr((Integer) o))); + writer.newLine(); + outputMap.add((Integer) o); + } else if (o instanceof ControlFlowTag) { + ControlFlowTag cft = (ControlFlowTag) o; + if (cft.name.equals("appendjump")) { + writer.appendNoHilight("jump ofs" + Helper.formatAddress(pos2adr(cft.value))).newLine(); + outputMap.add(-1); + } + if (cft.name.equals("mark")) { + writer.appendNoHilight("ofs" + Helper.formatAddress(pos2adr(cft.value)) + ":"); + } + } + } + } else { + if (!ins.isIgnored()) { + if (markOffsets) { + writer.append("", ins.mappedOffset > -1 ? ins.mappedOffset : ofs); + } + int fixBranch = ins.getFixBranch(); + if (fixBranch > -1) { + if (ins.definition instanceof IfTypeIns) { + for (int i = 0; i < -ins.definition.getStackDelta(ins, null/*IfTypeIns do not require ABCs*/); i++) { + writer.appendNoHilight(new DeobfuscatePopIns().instructionName).newLine(); + } + if (fixBranch == 0) { // jump + writer.appendNoHilight(new JumpIns().instructionName + " ofs" + Helper.formatAddress(ofs + ins.getBytes().length + ins.operands[0])); + } else { + // nojump, ignore + } + } + // TODO: lookupswitch ? + } else { + if (ins.changeJumpTo > -1) { + writer.appendNoHilight(ins.definition.instructionName + " ofs" + Helper.formatAddress(pos2adr(ins.changeJumpTo))); + } else { + writer.appendNoHilight(ins.toStringNoAddress(constants, new ArrayList())); + } + } + writer.newLine(); + outputMap.add(ip); + } + } + ip++; + } + } + return writer; + } + + private boolean cacheActual = false; + + private List posCache; + + private void buildCache() { + posCache = new ArrayList<>(); + long a = 0; + for (int i = 0; i < code.size(); i++) { + posCache.add(a); + a += code.get(i).getBytes().length; + } + posCache.add(a); + cacheActual = true; + } + + public int adr2pos(long address) throws ConvertException { + if (!cacheActual) { + buildCache(); + } + int ret = posCache.indexOf(address); + if (ret == -1) { + throw new ConvertException("Bad jump try conver ofs" + Helper.formatAddress(address) + " ", -1); + } + return ret; + } + + public int pos2adr(int pos) { + if (!cacheActual) { + buildCache(); + } + return posCache.get(pos).intValue(); + } + + public void invalidateCache() { + cacheActual = false; + } + + private List unknownJumps; + + private List ignoredIns; + + boolean isCatched = false; + + /** + * Test for killed register. CalcKilledStats must be called before + * + * @param regName + * @param start + * @param end + * @return + */ + public boolean isKilled(int regName, int start, int end) { + if (!killedRegs.containsKey(regName)) { + return false; + } + for (int ip : killedRegs.get(regName)) { + if (ip >= start && ip <= end) { + return true; + } + } + return false; + } + + private int toSourceCount = 0; + + public Map getLocalRegNamesFromDebug(ABC abc) { + Map localRegNames = new HashMap<>(); + + for (AVM2Instruction ins : code) { + if (ins.definition instanceof DebugIns) { + if (ins.operands[0] == 1) { + String v = abc.constants.getString(ins.operands[1]); + // Same name already exists, it may be wrong names inserted by obfuscator + if (localRegNames.values().contains(v)) { + return new HashMap<>(); + } + localRegNames.put(ins.operands[2] + 1, v); + } + } + } + + // TODO: Make this immune to using existing multinames (?) + return localRegNames; + } + + private Map> killedRegs = new HashMap<>(); + + public void calcKilledStats(MethodBody body) { + killedRegs.clear(); + try { + HashMap> vis = visitCode(body); + for (int k = 0; k < code.size(); k++) { + if (vis.get(k).isEmpty()) { + continue; + } + if (code.get(k).definition instanceof KillIns) { + int regid = code.get(k).operands[0]; + if (!killedRegs.containsKey(regid)) { + killedRegs.put(regid, new HashSet()); + } + killedRegs.get(regid).add(k); + } + } + + } catch (InterruptedException ex) { + // ignored + } + } + + public List clearTemporaryRegisters(List output) { + for (int i = 0; i < output.size(); i++) { + if (output.get(i) instanceof SetLocalAVM2Item) { + if (isKilled(((SetLocalAVM2Item) output.get(i)).regIndex, 0, code.size() - 1)) { + SetLocalAVM2Item lsi = (SetLocalAVM2Item) output.get(i); + if (i + 1 < output.size()) { + if (output.get(i + 1) instanceof ReturnValueAVM2Item) { + ReturnValueAVM2Item rv = (ReturnValueAVM2Item) output.get(i + 1); + if (rv.value instanceof LocalRegAVM2Item) { + LocalRegAVM2Item lr = (LocalRegAVM2Item) rv.value; + if (lr.regIndex == lsi.regIndex) { + rv.value = lsi.value; + } + } + } + } + output.remove(i); + i--; + } + } else if (output.get(i) instanceof WithAVM2Item) { + clearTemporaryRegisters(((WithAVM2Item) output.get(i)).items); + } + } + return output; + } + + public int fixIPAfterDebugLine(int ip) { + if (code.isEmpty()) { + return ip; + } + if (ip >= code.size()) { + return code.size() - 1; + } + while (code.get(ip).definition instanceof DebugLineIns) { + ip++; + } + return ip; + } + + public int fixAddrAfterDebugLine(int addr) throws ConvertException { + return pos2adr(fixIPAfterDebugLine(adr2pos(addr))); + } + + public ConvertOutput toSourceOutput(String path, GraphPart part, boolean processJumps, boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, ABC abc, AVM2ConstantPool constants, List method_info, MethodBody body, int start, int end, HashMap localRegNames, List fullyQualifiedNames, boolean[] visited, HashMap localRegAssigmentIps, HashMap> refs) throws ConvertException, InterruptedException { + calcKilledStats(body); + boolean debugMode = DEBUG_MODE; + if (debugMode) { + System.out.println("OPEN SubSource:" + start + "-" + end + " " + code.get(start).toString() + " to " + code.get(end).toString()); + } + if (visited == null) { + visited = new boolean[code.size()]; + } + //if(true) return ""; + toSourceCount++; + if (toSourceLimit > 0) { + if (toSourceCount > toSourceLimit) { + throw new ConvertException("Limit of subs(" + toSourceLimit + ") was reached", start); + } + } + List output = new ArrayList<>(); + int ip = start; + //try { + //int addr; + iploop: + while (ip <= end) { + + if (ignoredIns.contains(ip)) { + ip++; + continue; + } + boolean processTry = processJumps; + //addr = pos2adr(ip); + int ipfix = fixIPAfterDebugLine(ip); + //int addrfix = pos2adr(ipfix); + int maxend = -1; + + if (ip > end) { + break; + } + + if (unknownJumps.contains(ip)) { + unknownJumps.remove(Integer.valueOf(ip)); + throw new UnknownJumpException(stack, ip, output); + } + if (visited[ip]) { + logger.warning("Code already visited, ofs:" + Helper.formatAddress(pos2adr(ip)) + ", ip:" + ip); + break; + } + visited[ip] = true; + AVM2Instruction ins = code.get(ip); + if (debugMode) { + System.err.println("translating ip " + ip + " ins " + ins.toString() + " stack:" + stack.toString() + " scopeStack:" + scopeStack.toString()); + } + if (ins.definition instanceof NewFunctionIns) { + if (ip + 1 <= end) { + if (code.get(ip + 1).definition instanceof PopIns) { + ip += 2; + continue; + } + } + } + /*if ((ip + 8 < code.size())) { //return in finally clause + if (ins.definition instanceof SetLocalTypeIns) { + if (code.get(ip + 1).definition instanceof PushByteIns) { + AVM2Instruction jmp = code.get(ip + 2); + if (jmp.definition instanceof JumpIns) { + if (jmp.operands[0] == 0) { + if (code.get(ip + 3).definition instanceof LabelIns) { + if (code.get(ip + 4).definition instanceof PopIns) { + if (code.get(ip + 5).definition instanceof LabelIns) { + AVM2Instruction gl = code.get(ip + 6); + if (gl.definition instanceof GetLocalTypeIns) { + if (((GetLocalTypeIns) gl.definition).getRegisterId(gl) == ((SetLocalTypeIns) ins.definition).getRegisterId(ins)) { + AVM2Instruction ki = code.get(ip + 7); + if (ki.definition instanceof KillIns) { + if (ki.operands[0] == ((SetLocalTypeIns) ins.definition).getRegisterId(ins)) { + if (code.get(ip + 8).definition instanceof ReturnValueIns) { + ip = ip + 8; + continue; + } + } + } + } + } + } + } + } + } + } + } + } + }//*/ + + /*if ((ip + 2 < code.size()) && (ins.definition instanceof NewCatchIns)) { // Filling local register in catch clause + if (code.get(ip + 1).definition instanceof DupIns) { + if (code.get(ip + 2).definition instanceof SetLocalTypeIns) { + ins.definition.translate(isStatic, classIndex, localRegs, stack, scopeStack, constants, ins, method_info, output, body, abc, localRegNames, fullyQualifiedNames); + ip += 3; + continue; + } + } + }*/ + if ((ins.definition instanceof GetLocalTypeIns) && (!output.isEmpty()) && (output.get(output.size() - 1) instanceof SetLocalAVM2Item) && (((SetLocalAVM2Item) output.get(output.size() - 1)).regIndex == ((GetLocalTypeIns) ins.definition).getRegisterId(ins)) && isKilled(((SetLocalAVM2Item) output.get(output.size() - 1)).regIndex, start, end)) { + SetLocalAVM2Item slt = (SetLocalAVM2Item) output.remove(output.size() - 1); + stack.push(slt.getValue()); + ip++; + } else if ((ins.definition instanceof SetLocalTypeIns) && (ip + 1 <= end) && (isKilled(((SetLocalTypeIns) ins.definition).getRegisterId(ins), ip, end))) { // set_local_x,get_local_x..kill x + AVM2Instruction insAfter = code.get(ip + 1); + if ((insAfter.definition instanceof GetLocalTypeIns) && (((GetLocalTypeIns) insAfter.definition).getRegisterId(insAfter) == ((SetLocalTypeIns) ins.definition).getRegisterId(ins))) { + GraphTargetItem before = stack.peek(); + ins.definition.translate(isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, constants, ins, method_info, output, body, abc, localRegNames, fullyQualifiedNames, path, localRegAssigmentIps, ip, refs, this); + stack.push(before); + ip += 2; + continue iploop; + } else { + ins.definition.translate(isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, constants, ins, method_info, output, body, abc, localRegNames, fullyQualifiedNames, path, localRegAssigmentIps, ip, refs, this); + ip++; + continue iploop; + } + } else if (ins.definition instanceof DupIns) { + int nextPos; + do { + AVM2Instruction insAfter = code.get(ip + 1); + AVM2Instruction insBefore = ins; + if (ip - 1 >= start) { + insBefore = code.get(ip - 1); + } + if (insAfter.definition instanceof ConvertBIns) { // SWF compiled with debug contain convert_b + ip++; + //addr = pos2adr(ip); + insAfter = code.get(ip + 1); + } + + boolean isAnd; + if (processJumps && (insAfter.definition instanceof IfFalseIns)) { + //stack.add("(" + stack.pop() + ")&&"); + isAnd = true; + } else if (processJumps && (insAfter.definition instanceof IfTrueIns)) { + //stack.add("(" + stack.pop() + ")||"); + isAnd = false; + } else if (insAfter.definition instanceof SetLocalTypeIns) { + // chained assignments + int reg = (((SetLocalTypeIns) insAfter.definition).getRegisterId(insAfter)); + for (int t = ip + 1; t <= end - 1; t++) { + if (code.get(t).definition instanceof KillIns) { + if (code.get(t).operands[0] == reg) { + break; + } + } + if (code.get(t).definition instanceof GetLocalTypeIns) { + if (((GetLocalTypeIns) code.get(t).definition).getRegisterId(code.get(t)) == reg) { + if (code.get(t + 1).definition instanceof KillIns) { + if (code.get(t + 1).operands[0] == reg) { + ConvertOutput assignment = toSourceOutput(path, part, processJumps, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, abc, constants, method_info, body, ip + 2, t - 1, localRegNames, fullyQualifiedNames, visited, localRegAssigmentIps, refs); + GraphTargetItem tar = assignment.output.remove(assignment.output.size() - 1); + tar.firstPart = part; + stack.push(tar); + ip = t + 2; + continue iploop; + } + } + } + } + } + if (!isKilled(reg, 0, end)) { + for (int i = ip; i >= start; i--) { + if (code.get(i).definition instanceof DupIns) { + if (stack.isEmpty()) { + break; // FIXME?o + } + GraphTargetItem v = stack.pop(); + stack.push(new LocalRegAVM2Item(ins, reg, v)); + stack.push(v); + } else { + break; + } + } + } else { + ins.definition.translate(isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, constants, ins, method_info, output, body, abc, localRegNames, fullyQualifiedNames, path, localRegAssigmentIps, ip, refs, this); + } + ip++; + break; + //} + + } else { + ins.definition.translate(isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, constants, ins, method_info, output, body, abc, localRegNames, fullyQualifiedNames, path, localRegAssigmentIps, ip, refs, this); + ip++; + break; + //throw new ConvertException("Unknown pattern after DUP:" + insComparsion.toString()); + } + } while (ins.definition instanceof DupIns); + } else if ((ins.definition instanceof ReturnValueIns) || (ins.definition instanceof ReturnVoidIns) || (ins.definition instanceof ThrowIns)) { + ins.definition.translate(isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, constants, ins, method_info, output, body, abc, localRegNames, fullyQualifiedNames, path, localRegAssigmentIps, ip, refs, this); + //ip = end + 1; + break; + } else if (ins.definition instanceof NewFunctionIns) { + String functionName = ""; + if ((ip >= start + 2) && (ip <= end - 4)) { + AVM2Instruction prev2 = code.get(ip - 2); + if (prev2.definition instanceof NewObjectIns) { + if (prev2.operands[0] == 0) { + if (code.get(ip - 1).definition instanceof PushWithIns) { + boolean hasDup = false; + int plus = 0; + if (code.get(ip + 1).definition instanceof DupIns) { + hasDup = true; + plus = 1; + } + AVM2Instruction psco = code.get(ip + 1 + plus); + if (psco.definition instanceof GetScopeObjectIns) { + if (psco.operands[0] == scopeStack.size() - 1) { + if (code.get(ip + plus + 2).definition instanceof SwapIns) { + if (code.get(ip + plus + 4).definition instanceof PopScopeIns) { + if (code.get(ip + plus + 3).definition instanceof SetPropertyIns) { + functionName = abc.constants.getMultiname(code.get(ip + plus + 3).operands[0]).getName(constants, fullyQualifiedNames, true); + scopeStack.pop();// with + output.remove(output.size() - 1); // with + ip = ip + plus + 4; // +1 below + } + } + } + } + } + } + } + } + } + // What to do when hasDup is false? + ins.definition.translate(isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, constants, ins, method_info, output, body, abc, localRegNames, fullyQualifiedNames, path, localRegAssigmentIps, ip, refs, this); + NewFunctionAVM2Item nft = (NewFunctionAVM2Item) stack.peek(); + nft.functionName = functionName; + ip++; + } else { + try { + ins.definition.translate(isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, constants, ins, method_info, output, body, abc, localRegNames, fullyQualifiedNames, path, localRegAssigmentIps, ip, refs, this); + } catch (RuntimeException re) { + /*String last=""; + int len=5; + for(int i=(ip-len<0?0:ip-len);i maxRegister) { + maxRegister = regId; + } + } + return maxRegister + 1; + } + + public HashMap getLocalRegTypes(AVM2ConstantPool constants, List fullyQualifiedNames) { + HashMap ret = new HashMap<>(); + AVM2Instruction prev = null; + for (AVM2Instruction ins : code) { + if (ins.definition instanceof SetLocalTypeIns) { + if (prev != null) { + if (prev.definition instanceof CoerceOrConvertTypeIns) { + ret.put(((SetLocalTypeIns) ins.definition).getRegisterId(ins), ((CoerceOrConvertTypeIns) prev.definition).getTargetType(constants, prev, fullyQualifiedNames)); + } + } + } + prev = ins; + } + return ret; + + } + + private class Slot { + + public GraphTargetItem scope; + + public Multiname multiname; + + public Slot(GraphTargetItem scope, Multiname multiname) { + this.scope = scope; + this.multiname = multiname; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof Slot) { + return (((Slot) obj).scope.getThroughRegister() == scope.getThroughRegister()) + && (((Slot) obj).multiname == multiname); + } + return false; + } + + @Override + public int hashCode() { + int hash = 7; + hash = 59 * hash + (this.scope != null ? this.scope.hashCode() : 0); + hash = 59 * hash + (this.multiname != null ? this.multiname.hashCode() : 0); + return hash; + } + } + + public void initToSource() { + toSourceCount = 0; + unknownJumps = new ArrayList<>(); + ignoredIns = new ArrayList<>(); + } + + private void injectDeclarations(List list, boolean[] declaredRegisters, List declaredSlots, ABC abc, MethodBody body) { + //List nowdeclaredRegs=new ArrayList<>(); + //List nowdeclaredSlots=new ArrayList<>(); + for (int i = 0; i < list.size(); i++) { + GraphTargetItem ti = list.get(i); + if (ti instanceof ForEachInAVM2Item) { + ForEachInAVM2Item fei = (ForEachInAVM2Item) ti; + if (fei.expression.object instanceof LocalRegAVM2Item) { + int reg = ((LocalRegAVM2Item) fei.expression.object).regIndex; + if (!declaredRegisters[reg]) { + fei.expression.object = new DeclarationAVM2Item(fei.expression.object); + declaredRegisters[reg] = true; + //nowdeclaredRegs.add(reg); + } + } + } + if (ti instanceof ForInAVM2Item) { + ForInAVM2Item fi = (ForInAVM2Item) ti; + if (fi.expression.object instanceof LocalRegAVM2Item) { + int reg = ((LocalRegAVM2Item) fi.expression.object).regIndex; + if (!declaredRegisters[reg]) { + fi.expression.object = new DeclarationAVM2Item(fi.expression.object); + declaredRegisters[reg] = true; + //nowdeclaredRegs.add(reg); + } + } + } + if (ti instanceof Block) { + Block bl = (Block) ti; + for (List s : bl.getSubs()) { + injectDeclarations(s, declaredRegisters, declaredSlots, abc, body); + } + } + if (ti instanceof SetLocalAVM2Item) { + int reg = ((SetLocalAVM2Item) ti).regIndex; + if (!declaredRegisters[reg]) { + list.set(i, new DeclarationAVM2Item(ti)); + declaredRegisters[reg] = true; + //nowdeclaredRegs.add(reg); + } + } + if (ti instanceof SetSlotAVM2Item) { + SetSlotAVM2Item ssti = (SetSlotAVM2Item) ti; + Slot sl = new Slot(ssti.scope, ssti.slotName); + if (!declaredSlots.contains(sl)) { + GraphTargetItem type = TypeItem.UNBOUNDED; + for (int t = 0; t < body.traits.traits.size(); t++) { + if (body.traits.traits.get(t).getName(abc) == sl.multiname) { + if (body.traits.traits.get(t) instanceof TraitSlotConst) { + type = PropertyAVM2Item.multinameToType(((TraitSlotConst) body.traits.traits.get(t)).type_index, abc.constants); + } + } + } + list.set(i, new DeclarationAVM2Item(ti, type)); + declaredSlots.add(sl); + //nowdeclaredSlots.add(sl); + } + } + } + + /* + //undeclare registers at the end of the block? + for(int reg:nowdeclaredRegs){ + declaredRegisters[reg] = false; + } + + for(Slot s:nowdeclaredSlots){ + declaredSlots.remove(s); + }*/ + } + + public List toGraphTargetItems(String path, boolean isStatic, int scriptIndex, int classIndex, ABC abc, AVM2ConstantPool constants, List method_info, MethodBody body, HashMap localRegNames, ScopeStack scopeStack, boolean isStaticInitializer, List fullyQualifiedNames, Traits initTraits, int staticOperation, HashMap localRegAssigmentIps, HashMap> refs) throws InterruptedException { + initToSource(); + List list; + HashMap localRegs = new HashMap<>(); + + int regCount = getRegisterCount(); + + //try { + list = AVM2Graph.translateViaGraph(path, this, abc, body, isStatic, scriptIndex, classIndex, localRegs, scopeStack, localRegNames, fullyQualifiedNames, staticOperation, localRegAssigmentIps, refs); + + if (initTraits != null) { + for (int i = 0; i < list.size(); i++) { + GraphTargetItem ti = list.get(i); + if ((ti instanceof InitPropertyAVM2Item) || (ti instanceof SetPropertyAVM2Item)) { + int multinameIndex = 0; + GraphTargetItem value = null; + if (ti instanceof InitPropertyAVM2Item) { + multinameIndex = ((InitPropertyAVM2Item) ti).propertyName.multinameIndex; + value = ((InitPropertyAVM2Item) ti).value; + } + if (ti instanceof SetPropertyAVM2Item) { + multinameIndex = ((FullMultinameAVM2Item) ((SetPropertyAVM2Item) ti).propertyName).multinameIndex; + value = ((SetPropertyAVM2Item) ti).value; + } + for (Trait t : initTraits.traits) { + if (t.name_index == multinameIndex) { + if ((t instanceof TraitSlotConst)) { + if (((TraitSlotConst) t).isConst() || isStaticInitializer) { + if ((((TraitSlotConst) t).assignedValue) == null) { + ((TraitSlotConst) t).assignedValue = value; + list.remove(i); + i--; + continue; + } + } + break; + } + } + } + } else { + // In obfuscated code, SetLocal instructions comes first + //break; + } + } + } + if (isStaticInitializer) { + List newList = new ArrayList<>(); + for (GraphTargetItem ti : list) { + if (!(ti instanceof ReturnVoidAVM2Item)) { + if (!(ti instanceof InitPropertyAVM2Item)) { + newList.add(ti); + } + } + } + list = newList; + if (list.isEmpty()) { + return list; + } + } + // Declarations + injectDeclarations(list, new boolean[regCount], new ArrayList(), abc, body); + + int lastPos = list.size() - 1; + if (lastPos < 0) { + lastPos = 0; + } + if ((list.size() > lastPos) && (list.get(lastPos) instanceof ScriptEndItem)) { + lastPos--; + } + if (lastPos < 0) { + lastPos = 0; + } + if ((list.size() > lastPos) && (list.get(lastPos) instanceof ReturnVoidAVM2Item)) { + list.remove(lastPos); + } + + return list; + } + + public void removeInstruction(int pos, MethodBody body) { + if ((pos < 0) || (pos >= code.size())) { + throw new IndexOutOfBoundsException(); + } + int byteCount = code.get(pos).getBytes().length; + long remOffset = code.get(pos).offset; + for (int i = pos + 1; i < code.size(); i++) { + code.get(i).offset -= byteCount; + } + + for (ABCException ex : body.exceptions) { + if (ex.start > remOffset) { + ex.start -= byteCount; + } + if (ex.end > remOffset) { + ex.end -= byteCount; + } + if (ex.target > remOffset) { + ex.target -= byteCount; + } + } + + for (int i = 0; i < pos; i++) { + if (code.get(i).definition instanceof LookupSwitchIns) { + long target = code.get(i).offset + code.get(i).operands[0]; + if (target > remOffset) { + code.get(i).operands[0] -= byteCount; + } + for (int k = 2; k < code.get(i).operands.length; k++) { + target = code.get(i).offset + code.get(i).operands[k]; + if (target > remOffset) { + code.get(i).operands[k] -= byteCount; + } + } + } else { + for (int j = 0; j < code.get(i).definition.operands.length; j++) { + if (code.get(i).definition.operands[j] == AVM2Code.DAT_OFFSET) { + long target = code.get(i).offset + code.get(i).getBytes().length + code.get(i).operands[j]; + if (target > remOffset) { + code.get(i).operands[j] -= byteCount; + } + } + } + } + } + for (int i = pos + 1; i < code.size(); i++) { + if (code.get(i).definition instanceof LookupSwitchIns) { + long target = code.get(i).offset + code.get(i).operands[0]; + if (target < remOffset) { + code.get(i).operands[0] += byteCount; + } + for (int k = 2; k < code.get(i).operands.length; k++) { + target = code.get(i).offset + code.get(i).operands[k]; + if (target < remOffset) { + code.get(i).operands[k] += byteCount; + } + } + } else { + for (int j = 0; j < code.get(i).definition.operands.length; j++) { + if (code.get(i).definition.operands[j] == AVM2Code.DAT_OFFSET) { + long target = code.get(i).offset + code.get(i).getBytes().length + code.get(i).operands[j]; + if (target < remOffset) { + code.get(i).operands[j] += byteCount; + } + } + } + } + } + + code.remove(pos); + invalidateCache(); + } + + public void insertInstruction(int pos, AVM2Instruction instruction) { + if (pos < 0) { + pos = 0; + } + if (pos > code.size()) { + pos = code.size(); + } + int byteCount = instruction.getBytes().length; + if (pos == code.size()) { + instruction.offset = code.get(pos - 1).offset + code.get(pos - 1).getBytes().length; + } else { + instruction.offset = code.get(pos).offset; + } + + for (int i = 0; i < pos; i++) { + for (int j = 0; j < code.get(i).definition.operands.length; j++) { + if (code.get(i).definition.operands[j] == AVM2Code.DAT_OFFSET) { + long target = code.get(i).offset + code.get(i).getBytes().length + code.get(i).operands[j]; + if (target >= instruction.offset) { + code.get(i).operands[j] += byteCount; + } + } + } + } + for (int i = pos; i < code.size(); i++) { + for (int j = 0; j < code.get(i).definition.operands.length; j++) { + if (code.get(i).definition.operands[j] == AVM2Code.DAT_OFFSET) { + long target = code.get(i).offset + code.get(i).getBytes().length + code.get(i).operands[j]; + if (target < instruction.offset) { + code.get(i).operands[j] -= byteCount; + } + } + } + } + + for (int i = pos + 1; i < code.size(); i++) { + code.get(i).offset += byteCount; + } + code.add(pos, instruction); + } + + @SuppressWarnings("unchecked") + private static AVM2LocalData prepareBranchLocalData(AVM2LocalData localData) { + AVM2LocalData ret = new AVM2LocalData(); + ret.isStatic = localData.isStatic; + ret.classIndex = localData.classIndex; + ret.localRegs = new HashMap<>(localData.localRegs); + ret.scopeStack = (ScopeStack) (localData.scopeStack).clone(); + ret.constants = localData.constants; + ret.methodInfo = localData.methodInfo; + ret.methodBody = localData.methodBody; + ret.abc = localData.abc; + ret.localRegNames = localData.localRegNames; + ret.fullyQualifiedNames = localData.fullyQualifiedNames; + ret.parsedExceptions = localData.parsedExceptions; + ret.finallyJumps = localData.finallyJumps; + ret.ignoredSwitches = localData.ignoredSwitches; + ret.scriptIndex = localData.scriptIndex; + ret.localRegAssignmentIps = localData.localRegAssignmentIps; + ret.ip = localData.ip; + ret.refs = localData.refs; + ret.code = localData.code; + return ret; + } + + public int removeTraps(AVM2ConstantPool constants, Trait trait, MethodInfo info, MethodBody body, ABC abc, int scriptIndex, int classIndex, boolean isStatic, String path) throws InterruptedException { + removeDeadCode(constants, trait, info, body); + AVM2LocalData localData = new AVM2LocalData(); + localData.isStatic = isStatic; + localData.classIndex = classIndex; + localData.localRegs = new HashMap<>(); + localData.scopeStack = new ScopeStack(); + localData.constants = abc.constants; + localData.methodInfo = abc.method_info; + localData.methodBody = body; + localData.abc = abc; + localData.localRegNames = body.getLocalRegNames(abc); + localData.fullyQualifiedNames = new ArrayList<>(); + localData.parsedExceptions = new ArrayList<>(); + localData.finallyJumps = new ArrayList<>(); + localData.ignoredSwitches = new ArrayList<>(); + localData.scriptIndex = scriptIndex; + localData.localRegAssignmentIps = new HashMap<>(); + localData.ip = 0; + HashMap> refs = visitCode(body); + localData.refs = refs; + localData.code = this; + int ret = 0; + ret += removeTraps(constants, trait, info, body, localData, new AVM2GraphSource(this, false, -1, -1, new HashMap(), new ScopeStack(), abc, body, new HashMap(), new ArrayList(), new HashMap(), refs), 0, path, refs); + removeIgnored(constants, trait, info, body); + removeDeadCode(constants, trait, info, body); + + return ret; + } + + private void handleRegister(CodeStats stats, int reg) { + if (reg + 1 > stats.maxlocal) { + stats.maxlocal = reg + 1; + } + } + + private boolean walkCode(CodeStats stats, int pos, int stack, int scope, ABC abc) { + while (pos < code.size()) { + AVM2Instruction ins = code.get(pos); + if (stats.instructionStats[pos].seen) { + // check stack mismatch here + return true; + } + + if (ins.definition instanceof NewFunctionIns) { + MethodBody innerBody = abc.findBody(ins.operands[0]); + innerBody.autoFillStats(abc, stats.initscope + (stats.has_activation ? 1 : 0), false); + } + + stats.instructionStats[pos].seen = true; + stats.instructionStats[pos].stackpos = stack; + stats.instructionStats[pos].scopepos = scope; + + int stackDelta = ins.definition.getStackDelta(ins, abc); + int scopeDelta = ins.definition.getScopeStackDelta(ins, abc); + int oldStack = stack; + + //+" deltaScope:"+(scopeDelta>0?"+"+scopeDelta:scopeDelta)+" stack:"+stack+" scope:"+scope); + stack += stackDelta; + scope += scopeDelta; + + stats.instructionStats[pos].stackpos_after = stack; + stats.instructionStats[pos].scopepos_after = scope; + + if (stack > stats.maxstack) { + stats.maxstack = stack; + } + if (scope > stats.maxscope) { + stats.maxscope = scope; + } + + //System.out.println("stack "+oldStack+(stackDelta>=0?"+"+stackDelta:stackDelta)+" max:"+stats.maxstack+" "+ins); + if ((ins.definition instanceof DXNSIns) || (ins.definition instanceof DXNSLateIns)) { + stats.has_set_dxns = true; + } + if (ins.definition instanceof NewActivationIns) { + stats.has_activation = true; + } + if (ins.definition instanceof SetLocalTypeIns) { + handleRegister(stats, ((SetLocalTypeIns) ins.definition).getRegisterId(ins)); + } else if (ins.definition instanceof GetLocalTypeIns) { + handleRegister(stats, ((GetLocalTypeIns) ins.definition).getRegisterId(ins)); + } else { + for (int i = 0; i < ins.definition.operands.length; i++) { + if (ins.definition.operands[i] == DAT_REGISTER_INDEX) { + handleRegister(stats, ins.operands[i]); + } + } + } + if (ins.definition instanceof ReturnValueIns) { + // check stack=1 + return true; + } + if (ins.definition instanceof ReturnVoidIns) { + // check stack=0 + return true; + } + if (ins.definition instanceof JumpIns) { + try { + pos = adr2pos(pos2adr(pos) + ins.getBytes().length + ins.operands[0]); + continue; + } catch (ConvertException ex) { + return false; + } + } else if (ins.definition instanceof IfTypeIns) { + try { + int newpos = adr2pos(pos2adr(pos) + ins.getBytes().length + ins.operands[0]); + walkCode(stats, newpos, stack, scope, abc); + } catch (ConvertException ex) { + return false; + } + } + if (ins.definition instanceof LookupSwitchIns) { + for (int i = 0; i < ins.operands.length; i++) { + if (i == 1) { + continue; + } + try { + int newpos = adr2pos(pos2adr(pos) + ins.operands[i]); + if (!walkCode(stats, newpos, stack, scope, abc)) { + return false; + } + } catch (ConvertException ex) { + return false; + } + } + } + pos++; + } + return true; + } + + public CodeStats getStats(ABC abc, MethodBody body, int initScope) { + CodeStats stats = new CodeStats(this); + stats.initscope = initScope; + if (!walkCode(stats, 0, 0, initScope, abc)) { + return null; + } + int scopePos = -1; + int prevStart = 0; + for (int e = 0; e < body.exceptions.length; e++) { + ABCException ex = body.exceptions[e]; + try { + if (scopePos == -1) { + scopePos = stats.instructionStats[adr2pos(ex.end) - 1].scopepos_after; + } + List visited = new ArrayList<>(); + for (int i = 0; i < stats.instructionStats.length; i++) { + if (stats.instructionStats[i].seen) { + visited.add(i); + } + } + if (!walkCode(stats, adr2pos(ex.target), 1 + (ex.isFinally() ? 1 : 0), scopePos, abc)) { + return null; + } + int maxIp = 0; + // searching for visited instruction in second run which has maximum position + for (int i = 0; i < stats.instructionStats.length; i++) { + if (stats.instructionStats[i].seen && !visited.contains(i)) { + maxIp = i; + } + } + scopePos = stats.instructionStats[maxIp].scopepos_after; + int stackPos = stats.instructionStats[maxIp].stackpos_after; + int nextIp = maxIp + 1; + if (code.get(maxIp).definition instanceof JumpIns) { + nextIp = adr2pos(pos2adr(nextIp) + code.get(maxIp).operands[0]); + } + if (nextIp < stats.instructionStats.length) { + int origScopePos = stats.instructionStats[nextIp].scopepos; + int origStackPos = stats.instructionStats[nextIp].stackpos; + + if (prevStart == ex.start && ex.isFinally() && !code.get(nextIp).isExit() && stats.instructionStats[nextIp].seen) { + for (int i = 0; i < stats.instructionStats.length; i++) { + stats.instructionStats[i].seen = false; + } + // Rerun rest with new scopePos, stackPos + if (!walkCode(stats, nextIp, origStackPos + 1/*magic!*/, scopePos - 1 /*magic!*/, abc)) { + return null; + } + scopePos--; + } + } + prevStart = ex.start; + } catch (ConvertException ex1) { + // ignore + } + } + //stats.maxscope+=initScope; + return stats; + } + + private void visitCode(int ip, int lastIp, HashMap> refs) throws InterruptedException { + if (Thread.currentThread().isInterrupted()) { + throw new InterruptedException(); + } + while (ip < code.size()) { + if (!refs.containsKey(ip)) { + refs.put(ip, new ArrayList()); + } + refs.get(ip).add(lastIp); + lastIp = ip; + if (refs.get(ip).size() > 1) { + break; + } + AVM2Instruction ins = code.get(ip); + if (ins.definition instanceof ThrowIns) { + break; + } + if (ins.definition instanceof ReturnValueIns) { + break; + } + if (ins.definition instanceof ReturnVoidIns) { + break; + } + if (ins.definition instanceof LookupSwitchIns) { + try { + for (int i = 2; i < ins.operands.length; i++) { + visitCode(adr2pos(pos2adr(ip) + ins.operands[i]), ip, refs); + } + ip = adr2pos(pos2adr(ip) + ins.operands[0]); + continue; + } catch (ConvertException ex) { + } + } + if (ins.definition instanceof JumpIns) { + try { + ip = adr2pos(pos2adr(ip) + ins.getBytes().length + ins.operands[0]); + continue; + } catch (ConvertException ex) { + logger.log(Level.FINE, null, ex); + } + } else if (ins.definition instanceof IfTypeIns) { + try { + visitCode(adr2pos(pos2adr(ip) + ins.getBytes().length + ins.operands[0]), ip, refs); + } catch (ConvertException ex) { + logger.log(Level.FINE, null, ex); + } + } + ip++; + }; + } + + public HashMap> visitCode(MethodBody body) throws InterruptedException { + HashMap> refs = new HashMap<>(); + for (int i = 0; i < code.size(); i++) { + refs.put(i, new ArrayList()); + } + visitCode(0, 0, refs); + int pos = 0; + for (ABCException e : body.exceptions) { + pos++; + try { + visitCode(adr2pos(e.start), adr2pos(e.start) - 1, refs); + visitCode(adr2pos(e.start), -1, refs); + visitCode(adr2pos(e.target), adr2pos(e.end), refs); + visitCode(adr2pos(e.end), -pos, refs); + } catch (ConvertException ex) { + logger.log(Level.FINE, null, ex); + } + } + return refs; + } + + private int visitCodeTrap(int ip, int[] visited, AVM2Instruction prev, AVM2Instruction prev2) { + int ret = 0; + while (ip < visited.length) { + visited[ip]++; + if (visited[ip] > 1) { + break; + } + AVM2Instruction ins = code.get(ip); + if (ins.definition instanceof ThrowIns) { + break; + } + if (ins.definition instanceof ReturnValueIns) { + break; + } + if (ins.definition instanceof ReturnVoidIns) { + break; + } + if (ins.definition instanceof LookupSwitchIns) { + try { + for (int i = 2; i < ins.operands.length; i++) { + ret += visitCodeTrap(adr2pos(pos2adr(ip) + ins.operands[i]), visited, prev, prev2); + } + ip = adr2pos(pos2adr(ip) + ins.operands[0]); + prev2 = prev; + prev = ins; + continue; + } catch (ConvertException ex) { + } + } + if (ins.definition instanceof JumpIns) { + try { + ip = adr2pos(pos2adr(ip) + ins.getBytes().length + ins.operands[0]); + prev2 = prev; + prev = ins; + continue; + } catch (ConvertException ex) { + logger.log(Level.FINE, null, ex); + } + } else if (ins.definition instanceof IfTypeIns) { + if ((prev != null) && (prev2 != null)) { + if ((prev.definition instanceof PushByteIns) && (prev2.definition instanceof PushByteIns)) { + if (ins.definition instanceof IfEqIns) { + prev.ignored = true; + prev2.ignored = true; + if (prev.operands[0] == prev2.operands[0]) { + ins.definition = new JumpIns(); + visited[ip]--; + } else { + ins.ignored = true; + ip++; + } + ret++; + continue; + } + if (ins.definition instanceof IfNeIns) { + prev.ignored = true; + prev2.ignored = true; + if (prev.operands[0] != prev2.operands[0]) { + ins.definition = new JumpIns(); + visited[ip]--; + } else { + ins.ignored = true; + ip++; + } + ret++; + continue; + } + } + } + if ((prev != null) && ins.definition instanceof IfTrueIns) { + if (prev.definition instanceof PushTrueIns) { + prev.ignored = true; + ins.definition = new JumpIns(); + visited[ip]--; + ret++; + continue; + } else if (prev.definition instanceof PushFalseIns) { + prev.ignored = true; + ins.ignored = true; + ret++; + ip++; + continue; + } + } + if ((prev != null) && ins.definition instanceof IfFalseIns) { + if (prev.definition instanceof PushFalseIns) { + prev.ignored = true; + ins.definition = new JumpIns(); + visited[ip]--; + ret++; + continue; + } else if (prev.definition instanceof PushTrueIns) { + prev.ignored = true; + ins.ignored = true; + ret++; + ip++; + continue; + } + } + try { + ret += visitCodeTrap(adr2pos(pos2adr(ip) + ins.getBytes().length + ins.operands[0]), visited, prev, prev2); + } catch (ConvertException ex) { + logger.log(Level.FINE, null, ex); + } + } + ip++; + prev2 = prev; + prev = ins; + }; + return ret; + + } + + private static class ControlFlowTag { + + public String name; + + public int value; + + public ControlFlowTag(String name, int value) { + this.name = name; + this.value = value; + } + } + + public void restoreControlFlow(int ip, HashMap> refs, int[] visited2, HashMap> appended) throws ConvertException { + List buf = new ArrayList<>(); + boolean cont = false; + int continueip = 0; + for (; ip < code.size(); ip++) { + AVM2Instruction ins = code.get(ip); + + if ((refs.containsKey(ip) && refs.get(ip).size() > 1) || (visited2[ip] > 0)) { + if (cont) { + buf.add(new ControlFlowTag("appendjump", ip)); + } + cont = false; + if (visited2[ip] > 0) { + break; + } + } + visited2[ip]++; + if (ins.definition instanceof LookupSwitchIns) { + + if (cont) { + buf.add(new ControlFlowTag("appendjump", ip)); + } + cont = false; + restoreControlFlow(adr2pos(pos2adr(ip) + ins.operands[0]), refs, visited2, appended); + for (int i = 2; i < ins.operands.length; i++) { + restoreControlFlow(adr2pos(pos2adr(ip) + ins.operands[i]), refs, visited2, appended); + } + break; + } + if (ins.definition instanceof JumpIns) { + int newip = adr2pos(pos2adr(ip + 1) + ins.operands[0]); + + boolean allJumpsOrIfs = true; + for (int ref : refs.get(ip)) { + if (ref < 0) { + continue; + } + if (!(code.get(ref).definition instanceof JumpIns)) { + if (!(code.get(ref).definition instanceof IfTypeIns)) { + allJumpsOrIfs = false; + break; + } else { + if (adr2pos(pos2adr(ref + 1) + code.get(ref).operands[0]) != ip) { + allJumpsOrIfs = false; + break; + } + } + } + } + if (allJumpsOrIfs) { + for (int ref : refs.get(ip)) { + if (ref < 0) { + continue; + } + code.get(ref).changeJumpTo = newip; + } + } + if ((newip < code.size()) && (refs.containsKey(newip) && refs.get(newip).size() == 1)) { + if (!cont) { + continueip = ip; + buf = new ArrayList<>(); + appended.put(continueip, buf); + } + cont = true; + } else { + if (cont) { + buf.add(new ControlFlowTag("appendjump", newip)); + } + cont = false; + } + ip = newip - 1; + } else if (ins.definition instanceof IfTypeIns) { + int newip = adr2pos(pos2adr(ip + 1) + ins.operands[0]); + if (cont) { + buf.add(new ControlFlowTag("appendjump", ip)); + } + cont = false; + restoreControlFlow(newip, refs, visited2, appended); + } else if ((ins.definition instanceof ReturnVoidIns) || (ins.definition instanceof ReturnValueIns) || (ins.definition instanceof ThrowIns)) { + if (cont) { + buf.add(ip); + } + break; + } else if (cont) { + buf.add(ip); + } + } + + } + + private void restoreControlFlowPass(AVM2ConstantPool constants, Trait trait, MethodInfo info, MethodBody body, boolean secondpass) throws InterruptedException { + try { + HashMap> refs; + int[] visited2 = new int[code.size()]; + refs = visitCode(body); + HashMap> appended = new HashMap<>(); + /*if (secondpass) { + restoreControlFlow(code.size() - 1, refs, visited2, appended); + } else*/ { + restoreControlFlow(0, refs, visited2, appended); + for (ABCException e : body.exceptions) { + try { + restoreControlFlow(adr2pos(e.start), refs, visited2, appended); + restoreControlFlow(adr2pos(e.target), refs, visited2, appended); + restoreControlFlow(adr2pos(e.end), refs, visited2, appended); + } catch (ConvertException ex) { + logger.log(Level.FINE, null, ex); + } + } + } + for (int ip : appended.keySet()) { + code.get(ip).replaceWith = appended.get(ip); + } + } catch (ConvertException cex) { + logger.log(Level.SEVERE, "Error during restore control flow", cex); + } + invalidateCache(); + try { + List outputMap = new ArrayList<>(); + HighlightedTextWriter writer = new HighlightedTextWriter(Configuration.getCodeFormatting(), false); + toASMSource(constants, trait, info, body, outputMap, ScriptExportMode.PCODE, writer); + String src = writer.toString(); + + AVM2Code acode = ASM3Parser.parse(new StringReader(src), constants, null, body, info); + for (int i = 0; i < acode.code.size(); i++) { + if (outputMap.size() > i) { + int tpos = outputMap.get(i); + if (tpos == -1) { + } else if (code.get(tpos).mappedOffset >= 0) { + acode.code.get(i).mappedOffset = code.get(tpos).mappedOffset; + } else { + acode.code.get(i).mappedOffset = pos2adr(tpos); + } + + } + } + this.code = acode.code; + } catch (IOException ex) { + logger.log(Level.SEVERE, null, ex); + } catch (AVM2ParseException ex) { + logger.log(Level.FINE, null, ex); + } + invalidateCache(); + removeDeadCode(constants, trait, info, body); + } + + public void restoreControlFlow(AVM2ConstantPool constants, Trait trait, MethodInfo info, MethodBody body) throws InterruptedException { + restoreControlFlowPass(constants, trait, info, body, false); + //restoreControlFlowPass(constants, body, true); + } + + /*private void removeIgnored(MethodBody body) { + for (int rem = code.size() - 1; rem >= 0; rem--) { + if (code.get(rem).ignored) { + removeInstruction(rem, body); + } + } + }*/ + public void removeIgnored(AVM2ConstantPool constants, Trait trait, MethodInfo info, MethodBody body) throws InterruptedException { + try { + List outputMap = new ArrayList<>(); + HighlightedTextWriter writer = new HighlightedTextWriter(Configuration.getCodeFormatting(), false); + toASMSource(constants, trait, info, body, outputMap, ScriptExportMode.PCODE, writer); + String src = writer.toString(); + AVM2Code acode = ASM3Parser.parse(new StringReader(src), constants, trait, body, info); + for (int i = 0; i < acode.code.size(); i++) { + if (outputMap.size() > i) { + int tpos = outputMap.get(i); + if (tpos == -1) { + } else if (code.get(tpos).mappedOffset >= 0) { + acode.code.get(i).mappedOffset = code.get(tpos).mappedOffset; + } else { + acode.code.get(i).mappedOffset = pos2adr(tpos); + } + } + } + this.code = acode.code; + } catch (IOException | AVM2ParseException ex) { + } + invalidateCache(); + } + + public int removeDeadCode(AVM2ConstantPool constants, Trait trait, MethodInfo info, MethodBody body) throws InterruptedException { + HashMap> refs = visitCode(body); + + int cnt = 0; + for (int i = code.size() - 1; i >= 0; i--) { + if (refs.get(i).isEmpty()) { + code.get(i).ignored = true; + //removeInstruction(i, body); + cnt++; + } + } + + removeIgnored(constants, trait, info, body); + for (int i = code.size() - 1; i >= 0; i--) { + AVM2Instruction ins = code.get(i); + if (ins.definition instanceof JumpIns) { + if (ins.operands[0] == 0) { + code.get(i).ignored = true; + //removeInstruction(i, body); + cnt++; + } + } + } + removeIgnored(constants, trait, info, body); + return cnt; + } + + public void markMappedOffsets() { + int ofs = 0; + for (int i = 0; i < code.size(); i++) { + code.get(i).mappedOffset = ofs; + ofs += code.get(i).getBytes().length; + + } + } + + private static class Decision { + + public boolean jumpUsed = false; + + public boolean skipUsed = false; + + public Set casesUsed = new HashSet<>(); + + HashMap registers = new HashMap<>(); + } + + private static int getMostCommonIp(AVM2GraphSource code, List branches) { + List> reachable = new ArrayList<>(); + for (int i = 0; i < branches.size(); i++) { + List r = new ArrayList<>(); + getReachableIps(code, branches.get(i), r); + } + + int commonLevel; + Map levelMap = new HashMap<>(); + for (List first : reachable) { + int maxclevel = 0; + Set visited = new HashSet<>(); + for (Integer p : first) { + if (visited.contains(p)) { + continue; + } + visited.add(p); + boolean common = true; + commonLevel = 1; + for (List r : reachable) { + if (r == first) { + continue; + } + if (r.contains(p)) { + commonLevel++; + } + } + if (commonLevel <= maxclevel) { + continue; + } + maxclevel = commonLevel; + if (levelMap.containsKey(p)) { + if (levelMap.get(p) > commonLevel) { + commonLevel = levelMap.get(p); + } + } + levelMap.put(p, commonLevel); + if (common) { + //return p; + } + } + } + for (int i = reachable.size() - 1; i >= 2; i--) { + for (Integer p : levelMap.keySet()) { + if (levelMap.get(p) == i) { + return p; + } + } + } + for (Integer p : levelMap.keySet()) { + if (levelMap.get(p) == branches.size()) { + return p; + } + } + return -1; + } + + public static void getReachableIps(AVM2GraphSource code, int ip, List reachable) { + do { + if (reachable.contains(ip)) { + return; + } + reachable.add(ip); + GraphSourceItem ins = code.get(ip); + if (ins.isJump() || ins.isBranch()) { + List branches = ins.getBranches(code); + for (int i = 1; i < branches.size(); i++) { + getReachableIps(code, branches.get(i), reachable); + } + ip = branches.get(0); + continue; + } + ip++; + } while (ip < code.size()); + } + + public static boolean isDirectAncestor(int currentIp, int ancestor, HashMap> refs) { + return isDirectAncestor(currentIp, ancestor, refs, new ArrayList()); + } + + private static boolean isDirectAncestor(int currentIp, int ancestor, HashMap> refs, List visited) { + if (currentIp == -1) { + return true; + } + do { + if (currentIp == ancestor) { + return true; + } + if (currentIp == 0) { + return false; + } + if (visited.contains(currentIp)) { + return true; + } + visited.add(currentIp); + if (refs.containsKey(currentIp)) { + List currentRefs = refs.get(currentIp); + if ((currentRefs != null) && (!currentRefs.isEmpty())) { + for (int i = 1; i < currentRefs.size(); i++) { + if (!isDirectAncestor(currentRefs.get(i), ancestor, refs, visited)) { + return false; + } + } + currentIp = currentRefs.get(0); + continue; + } + } + currentIp--; + } while (currentIp >= 0); + return false; + } + + public static boolean getPreviousReachableIps(int currentIp, HashMap> refs, Set reachable, Set visited) { + do { + if (visited.contains(currentIp)) { + return false; + } + reachable.add(currentIp); + visited.add(currentIp); + if (refs.containsKey(currentIp)) { + List currentRefs = refs.get(currentIp); + if ((currentRefs != null) && (!currentRefs.isEmpty())) { + if (currentRefs.size() == 1) { + currentIp = currentRefs.get(0); + continue; + } + boolean r = false; + for (int i = 0; i < currentRefs.size(); i++) { + Set nr = new HashSet<>(); + boolean v = getPreviousReachableIps(currentRefs.get(i), refs, nr, visited); + if ((!v) || nr.contains(0)) { + reachable.addAll(nr); + } + r = r || v; + } + return r; + } + } + currentIp--; + } while (currentIp >= 0); + return true; + } + + @SuppressWarnings("unchecked") + private static int removeTraps(HashMap> refs, boolean secondPass, boolean indeterminate, AVM2LocalData localData, TranslateStack stack, List output, AVM2GraphSource code, int ip, HashMap visited, HashMap> visitedStates, HashMap decisions, String path, int recursionLevel) throws InterruptedException { + if (Thread.currentThread().isInterrupted()) { + throw new InterruptedException(); + } + if (recursionLevel > code.size() + 1) { + throw new TranslateException("removeTraps max recursion level reached."); + } + boolean debugMode = false; + int ret = 0; + iploop: + while ((ip > -1) && ip < code.size()) { + + if (false) { //useVisited) { + if (visited.containsKey(ip)) { + break; + } + if (!visited.containsKey(ip)) { + visited.put(ip, 0); + } else { + visited.put(ip, visited.get(ip) + 1); + } + } else { + HashMap currentState = localData.localRegs; + + if (visitedStates.containsKey(ip)) { + HashMap lastState = visitedStates.get(ip); + if (lastState.equals(currentState)) { + break; + } + } + visitedStates.put(ip, (HashMap) currentState.clone()); + + } + + int curVisited; + if (!visited.containsKey(ip)) { + curVisited = 1; + } else { + curVisited = visited.get(ip) + 1; + } + visited.put(ip, curVisited); + + List r = refs.get(ip); + /*if (r != null) { + if (r.size() > 1) { + if (!stack.isEmpty()) { + GraphTargetItem it = stack.pop(); + stack.push(new NotCompileTimeAVM2Item(null, it)); + } + } + }*/ + + AVM2Instruction ins = code.get(ip); + // Errorneous code inserted by some obfuscators + if (ins.definition instanceof NewObjectIns) { + if (ins.operands[0] > stack.size()) { + ins.setIgnored(true, 0); + } + } + if (ins.definition instanceof NewArrayIns) { + if (ins.operands[0] > stack.size()) { + ins.setIgnored(true, 0); + } + } + + if (ins.isIgnored()) { + ip++; + continue; + } + + if (debugMode) { + System.out.println((indeterminate ? "useV " : "") + (secondPass ? "secondPass " : "") + "Visit " + ip + ": " + ins + " stack:" + stack.toString()); + HashMap registers = localData.localRegs; + System.out.print("Registers:"); + for (int reg : registers.keySet()) { + try { + System.out.print(" r" + reg + ": " + registers.get(reg).getResult()); + } catch (NullPointerException npe) { + System.out.print(" r" + reg + ": " + "null"); + } + } + System.out.println(""); + } + if (secondPass) { + /*if ((ins instanceof AVM2Instruction) && (((AVM2Instruction) ins).definition instanceof PopIns)) { + GraphTargetItem top = stack.peek(); + for (GraphSourceItemPos p : top.getNeededSources()) { + if (p == null) { + continue; + } + if (p.item == null) { + continue; + } + if (p.item.isIgnored()) { + ins.setIgnored(true, 0); + break; + } + } + }*/ + } + + if (ins.definition instanceof NewFunctionIns) { + stack.push(new BooleanAVM2Item(null, true)); + } else { + localData.ip = ip; + ins.translate(localData, stack, output, Graph.SOP_USE_STATIC, path); + } + + if (ins.definition instanceof SetLocalTypeIns) { + SetLocalTypeIns slt = (SetLocalTypeIns) ins.definition; + int regId = slt.getRegisterId(ins); + if (indeterminate) { + HashMap registers = localData.localRegs; + GraphTargetItem regVal = registers.get(regId); + if (regVal.isCompileTime()) { + registers.put(regId, new NotCompileTimeItem(null, regVal)); + } + } + } + + if (ins.isExit()) { + break; + } + + if (ins.isBranch() || ins.isJump()) { + List branches = ins.getBranches(code); + if (ins.definition instanceof IfTypeIns + && (!(ins.definition instanceof JumpIns)) + && (!stack.isEmpty()) + && (stack.peek().isCompileTime()) + && (!stack.peek().hasSideEffect())) { + boolean condition = EcmaScript.toBoolean(stack.peek().getResult()); + if (debugMode) { + if (condition) { + System.out.println("JUMP"); + } else { + System.out.println("SKIP"); + } + } + Decision dec = new Decision(); + if (decisions.containsKey(ins)) { + dec = decisions.get(ins); + } else { + decisions.put(ins, dec); + } + if (condition) { + dec.jumpUsed = true; + } else { + dec.skipUsed = true; + } + + if (branches.size() > 1) { + if (secondPass) { + if (condition && (dec.jumpUsed) && (!dec.skipUsed)) { + ins.setFixBranch(0); + //((AVM2Instruction) ins).definition = new JumpIns(); + } + if ((!condition) && (!dec.jumpUsed) && (dec.skipUsed)) { + ins.setFixBranch(1); + //ins.setIgnored(true, 0); + } + } + } + GraphTargetItem tar = stack.pop(); + /*if (secondPass && (dec.jumpUsed != dec.skipUsed)) { + for (GraphSourceItemPos pos : tar.getNeededSources()) { + if (pos.item instanceof AVM2Instruction) { + if (((AVM2Instruction) pos.item).definition instanceof DupIns) { + pos.item.setIgnored(true, 0); + break; + } + } + if (pos.item != ins) { + pos.item.setIgnored(true, 0); + } + } + + }*/ + if (branches.size() == 1) { + ip = branches.get(0); + } else { + ip = condition ? branches.get(0) : branches.get(1); + } + continue; + } else { + if (ins.isBranch() && (!ins.isJump())) { + GraphTargetItem top = stack.pop(); + + Decision dec = new Decision(); + if (decisions.containsKey(ins)) { + dec = decisions.get(ins); + } else { + decisions.put(ins, dec); + } + HashMap registers = localData.localRegs; + boolean regChanged = false; + if (!dec.registers.isEmpty()) { + if (dec.registers.size() != registers.size()) { + regChanged = true; + } else { + for (int reg : registers.keySet()) { + if (!dec.registers.containsKey(reg)) { + regChanged = true; + break; + } + if (!registers.get(reg).isCompileTime() && dec.registers.get(reg).isCompileTime()) { + regChanged = true; + break; + } + } + } + } + dec.registers.putAll(registers); + dec.jumpUsed = true; + dec.skipUsed = true; + + if (!regChanged && ((!(top instanceof HasNextAVM2Item) && curVisited > 1) || (curVisited > 2))) { + for (int b : branches) { + int visc = 0; + if (visited.containsKey(b)) { + visc = visited.get(b); + } + if (visc == 0) {//= 0) { //useVisited || (!ins.isJump()) + ret += removeTraps(refs, secondPass, indeterminate, prepareBranchLocalData(localData), brStack, output, code, b, visited, visitedStates, decisions, path, recursionLevel + 1); + } else { + if (debugMode) { + System.out.println("Negative branch:" + b); + } + } + } + } + break; + } + ip++; + } + if (ip < 0) { + System.out.println("Visited Negative: " + ip); + } + return ret; + } + + public static int removeTraps(AVM2ConstantPool constants, Trait trait, MethodInfo info, MethodBody body, AVM2LocalData localData, AVM2GraphSource code, int addr, String path, HashMap> refs) throws InterruptedException { + HashMap decisions = new HashMap<>(); + removeTraps(refs, false, false, localData, new TranslateStack(), new ArrayList(), code, code.adr2pos(addr), new HashMap(), new HashMap>(), decisions, path, 0); + int cnt = 0; + for (AVM2Instruction src : decisions.keySet()) { + Decision dec = decisions.get(src); + if (dec != null) { + if (src.definition instanceof LookupSwitchIns) { + if (dec.casesUsed.size() == 1) { + for (int c : dec.casesUsed) { + src.setFixBranch(c); + cnt++; + } + } + } else { + if (dec.jumpUsed && !dec.skipUsed) { + src.setFixBranch(0); + cnt++; + } + if (!dec.jumpUsed && dec.skipUsed) { + src.setFixBranch(1); + cnt++; + } + } + } + } + //int cnt = removeTraps(refs, true, false, localData, new TranslateStack(), new ArrayList(), code, code.adr2pos(addr), new HashMap(), new HashMap>(), decisions, path); + code.getCode().removeIgnored(constants, trait, info, body); + return cnt; + } + /*public static int removeTraps(AVM2LocalData localData, AVM2GraphSource code, int addr) { + AVM2Graph.translateViaGraph(localData, "", code, new ArrayList(), Graph.SOP_REMOVE_STATIC); + return 1; + }*/ + + @Override + public AVM2Code clone() throws CloneNotSupportedException { + AVM2Code ret = (AVM2Code) super.clone(); + if (code != null) { + List codeCopy = new ArrayList<>(code.size()); + for (AVM2Instruction ins : code) { + codeCopy.add(ins.clone()); + } + ret.code = codeCopy; + } + return ret; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2Graph.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2Graph.java index 616ef7bbb..38713f132 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2Graph.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2Graph.java @@ -1,826 +1,826 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.graph; - -import com.jpexs.decompiler.flash.BaseLocalData; -import com.jpexs.decompiler.flash.FinalProcessLocalData; -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.AVM2LocalData; -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.jumps.IfStrictEqIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.IfStrictNeIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.JumpIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.LookupSwitchIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.GetLocalTypeIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.KillIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other.ReturnValueIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushIntegerTypeIns; -import com.jpexs.decompiler.flash.abc.avm2.model.FilteredCheckAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.HasNextAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.InAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.IntegerValueAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.LocalRegAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.NextNameAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.NextValueAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.NullAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.ReturnValueAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.ReturnVoidAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.SetLocalAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.SetPropertyAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.SetTypeAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.WithAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.clauses.ExceptionAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.clauses.FilterAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.clauses.ForEachInAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.clauses.ForInAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.clauses.TryAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.StrictEqAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.StrictNeqAVM2Item; -import com.jpexs.decompiler.flash.abc.types.ABCException; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.ecma.EcmaScript; -import com.jpexs.decompiler.graph.Graph; -import com.jpexs.decompiler.graph.GraphPart; -import com.jpexs.decompiler.graph.GraphPartMulti; -import com.jpexs.decompiler.graph.GraphSource; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.Loop; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import com.jpexs.decompiler.graph.model.BreakItem; -import com.jpexs.decompiler.graph.model.IfItem; -import com.jpexs.decompiler.graph.model.LoopItem; -import com.jpexs.decompiler.graph.model.NotItem; -import com.jpexs.decompiler.graph.model.SwitchItem; -import com.jpexs.decompiler.graph.model.WhileItem; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.List; - -/** - * - * @author JPEXS - */ -public class AVM2Graph extends Graph { - - private final AVM2Code avm2code; - - private final ABC abc; - - private final MethodBody body; - - public AVM2Code getCode() { - return avm2code; - } - - public AVM2Graph(AVM2Code code, ABC abc, MethodBody body, boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, ScopeStack scopeStack, HashMap localRegNames, List fullyQualifiedNames, HashMap localRegAssigmentIps, HashMap> refs) { - super(new AVM2GraphSource(code, isStatic, scriptIndex, classIndex, localRegs, scopeStack, abc, body, localRegNames, fullyQualifiedNames, localRegAssigmentIps, refs), body.getExceptionEntries()); - this.avm2code = code; - this.abc = abc; - this.body = body; - /*heads = makeGraph(code, new ArrayList(), body); - this.code = code; - this.abc = abc; - this.body = body; - for (GraphPart head : heads) { - fixGraph(head); - makeMulti(head, new ArrayList()); - }*/ - - } - - public static List translateViaGraph(String path, AVM2Code code, ABC abc, MethodBody body, boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, ScopeStack scopeStack, HashMap localRegNames, List fullyQualifiedNames, int staticOperation, HashMap localRegAssigmentIps, HashMap> refs) throws InterruptedException { - AVM2Graph g = new AVM2Graph(code, abc, body, isStatic, scriptIndex, classIndex, localRegs, scopeStack, localRegNames, fullyQualifiedNames, localRegAssigmentIps, refs); - - AVM2LocalData localData = new AVM2LocalData(); - localData.isStatic = isStatic; - localData.classIndex = classIndex; - localData.localRegs = localRegs; - localData.scopeStack = scopeStack; - localData.constants = abc.constants; - localData.methodInfo = abc.method_info; - localData.methodBody = body; - localData.abc = abc; - localData.localRegNames = localRegNames; - localData.fullyQualifiedNames = fullyQualifiedNames; - localData.parsedExceptions = new ArrayList<>(); - localData.finallyJumps = new ArrayList<>(); - localData.ignoredSwitches = new ArrayList<>(); - localData.scriptIndex = scriptIndex; - localData.localRegAssignmentIps = new HashMap<>(); - localData.ip = 0; - localData.refs = refs; - localData.code = code; - g.init(localData); - List allParts = new ArrayList<>(); - for (GraphPart head : g.heads) { - populateParts(head, allParts); - } - return g.translate(localData, staticOperation, path); - } - - @Override - protected void checkGraph(List allBlocks) { - for (ABCException ex : body.exceptions) { - int startIp = avm2code.adr2pos(ex.start); - int endIp = avm2code.adr2pos(ex.end); - int targetIp = avm2code.adr2pos(ex.target); - GraphPart target = null; - for (GraphPart p : allBlocks) { - if (p.start == targetIp) { - target = p; - break; - } - } - for (GraphPart p : allBlocks) { - if (p.start >= startIp && p.end <= endIp) { - p.throwParts.add(target); - target.refs.add(p); - } - } - } - - /*for(ABCException ex:body.exceptions){ - for(GraphPart p:allBlocks){ - boolean next_is_ex_start=false; - for(GraphPart n:p.nextParts){ - if(n.start==code.adr2pos(ex.start)){ - next_is_ex_start = true; - break; - } - } - if(next_is_ex_start){ - for(GraphPart q:allBlocks){ //find target part - if(q.start==code.adr2pos(ex.target)){ - p.nextParts.add(q); - break; - } - } - } - } - }*/ - } - - @Override - protected List check(GraphSource code, BaseLocalData localData, List allParts, TranslateStack stack, GraphPart parent, GraphPart part, List stopPart, List loops, List output, Loop currentLoop, int staticOperation, String path) throws InterruptedException { - List ret = null; - - AVM2LocalData aLocalData = (AVM2LocalData) localData; - List parsedExceptions = aLocalData.parsedExceptions; - List finallyJumps = aLocalData.finallyJumps; - List ignoredSwitches = aLocalData.ignoredSwitches; - int ip = part.start; - int addr = this.avm2code.fixAddrAfterDebugLine(this.avm2code.pos2adr(part.start)); - int maxend = -1; - List catchedExceptions = new ArrayList<>(); - for (int e = 0; e < body.exceptions.length; e++) { - if (addr == this.avm2code.fixAddrAfterDebugLine(body.exceptions[e].start)) { - //Add finally only when the list is empty - if (!body.exceptions[e].isFinally() || catchedExceptions.isEmpty()) { - if (!parsedExceptions.contains(body.exceptions[e])) { - if (((body.exceptions[e].end) > maxend)) { - catchedExceptions.clear(); - maxend = this.avm2code.fixAddrAfterDebugLine(body.exceptions[e].end); - catchedExceptions.add(body.exceptions[e]); - } else if (this.avm2code.fixAddrAfterDebugLine(body.exceptions[e].end) == maxend) { - catchedExceptions.add(body.exceptions[e]); - } - - } - } else if (body.exceptions[e].isFinally()) { - parsedExceptions.add(body.exceptions[e]); - } - } - } - if (catchedExceptions.size() > 0) { - parsedExceptions.addAll(catchedExceptions); - int endpos = code.adr2pos(this.avm2code.fixAddrAfterDebugLine(catchedExceptions.get(0).end)); - int endposStartBlock = code.adr2pos(catchedExceptions.get(0).end); - - List> catchedCommands = new ArrayList<>(); - if (this.avm2code.code.get(endpos).definition instanceof JumpIns) { - int afterCatchAddr = this.avm2code.pos2adr(endpos + 1) + this.avm2code.code.get(endpos).operands[0]; - int afterCatchPos = this.avm2code.adr2pos(afterCatchAddr); - final AVM2Graph t = this; - Collections.sort(catchedExceptions, new Comparator() { - @Override - public int compare(ABCException o1, ABCException o2) { - return t.avm2code.fixAddrAfterDebugLine(o1.target) - t.avm2code.fixAddrAfterDebugLine(o2.target); - } - }); - - List finallyCommands = new ArrayList<>(); - int returnPos = afterCatchPos; - for (int e = 0; e < body.exceptions.length; e++) { - if (body.exceptions[e].isFinally()) { - if (addr == this.avm2code.fixAddrAfterDebugLine(body.exceptions[e].start)) { - if (afterCatchPos + 1 == code.adr2pos(this.avm2code.fixAddrAfterDebugLine(body.exceptions[e].end))) { - AVM2Instruction jmpIns = this.avm2code.code.get(code.adr2pos(this.avm2code.fixAddrAfterDebugLine(body.exceptions[e].end))); - - if (jmpIns.definition instanceof JumpIns) { - int finStart = code.adr2pos(this.avm2code.fixAddrAfterDebugLine(body.exceptions[e].end) + jmpIns.getBytes().length + jmpIns.operands[0]); - - GraphPart fpart = null; - for (GraphPart p : allParts) { - if (p.start == finStart) { - fpart = p; - break; - } - } - int swPos = -1; - for (int f = finStart; f < this.avm2code.code.size(); f++) { - if (this.avm2code.code.get(f).definition instanceof LookupSwitchIns) { - AVM2Instruction swins = this.avm2code.code.get(f); - if (swins.operands.length >= 3) { - if (swins.operands[0] == swins.getBytes().length) { - if (code.adr2pos(code.pos2adr(f) + swins.operands[2]) < finStart) { - stack.push(new ExceptionAVM2Item(body.exceptions[e])); - GraphPart fepart = null; - for (GraphPart p : allParts) { - if (p.start == f + 1) { - fepart = p; - break; - } - } - //this.code.code.get(f).ignored = true; - //ignoredSwitches.add(f); - swPos = f; - - List stopPart2 = new ArrayList<>(stopPart); - stopPart2.add(fepart); - //finallyCommands = printGraph(new ArrayList(), localData, stack, allParts, parent, fpart, stopPart2, loops, staticOperation, path); - returnPos = f + 1; - break; - } - } - } - } - } - //ignoredSwitches.add(-1); - //int igs_size=ignoredSwitches.size(); - List oldFinallyJumps = new ArrayList<>(finallyJumps); - finallyJumps.clear(); - ignoredSwitches.add(swPos); - finallyCommands = printGraph(localData, stack, allParts, parent, fpart, null, loops, staticOperation, path); - //ignoredSwitches.remove(igs_size-1); - finallyJumps.addAll(oldFinallyJumps); - finallyJumps.add(finStart); - break; - } - } - } - } - } - - GraphPart retPart = null; - for (GraphPart p : allParts) { - if (p.start == returnPos) { - retPart = p; - break; - } - } - List catchParts = new ArrayList<>(); - for (int e = 0; e < catchedExceptions.size(); e++) { - int eendpos; - if (e < catchedExceptions.size() - 1) { - eendpos = code.adr2pos(this.avm2code.fixAddrAfterDebugLine(catchedExceptions.get(e + 1).target)) - 2; - } else { - eendpos = afterCatchPos - 1; - } - - GraphPart npart = null; - int findpos = code.adr2pos(catchedExceptions.get(e).target); - for (GraphPart p : allParts) { - if (p.start == findpos) { - npart = p; - catchParts.add(p); - break; - } - } - - GraphPart nepart = null; - for (GraphPart p : allParts) { - if (p.start == eendpos + 1) { - nepart = p; - break; - } - } - stack.add(new ExceptionAVM2Item(catchedExceptions.get(e))); - AVM2LocalData localData2 = new AVM2LocalData(aLocalData); - localData2.scopeStack = new ScopeStack(); - List stopPart2 = new ArrayList<>(stopPart); - stopPart2.add(nepart); - if (retPart != null) { - stopPart2.add(retPart); - } - catchedCommands.add(printGraph(localData2, stack, allParts, parent, npart, stopPart2, loops, staticOperation, path)); - if (catchedExceptions.get(e).isFinally()) { - catchedCommands.remove(catchedCommands.size() - 1); - catchedExceptions.remove(e); - e--; - } - } - - GraphPart nepart = null; - - for (GraphPart p : allParts) { - if (p.start == endposStartBlock) { - nepart = p; - break; - } - } - List stopPart2 = new ArrayList<>(stopPart); - stopPart2.add(nepart); - stopPart2.addAll(catchParts); - - if (retPart != null) { - stopPart2.add(retPart); - } - List tryCommands = printGraph(localData, stack, allParts, parent, part, stopPart2, loops, staticOperation, path); - - output.clear(); - output.add(new TryAVM2Item(tryCommands, catchedExceptions, catchedCommands, finallyCommands)); - ip = returnPos; - } - - } - - if (ip != part.start) { - part = null; - for (GraphPart p : allParts) { - List ps = p.getSubParts(); - for (GraphPart p2 : ps) { - if (p2.start == ip) { - part = p2; - break; - } - } - } - ret = new ArrayList<>(); - ret.addAll(output); - GraphTargetItem lop = checkLoop(part, stopPart, loops); - if (lop == null) { - ret.addAll(printGraph(localData, stack, allParts, null, part, stopPart, loops, staticOperation, path)); - } else { - ret.add(lop); - } - return ret; - } - - if (part.nextParts.isEmpty()) { - if (this.avm2code.code.get(part.end).definition instanceof ReturnValueIns) { //returns in finally clause - if (part.getHeight() >= 3) { - if (this.avm2code.code.get(part.getPosAt(part.getHeight() - 2)).definition instanceof KillIns) { - if (this.avm2code.code.get(part.getPosAt(part.getHeight() - 3)).definition instanceof GetLocalTypeIns) { - if (output.size() >= 2) { - if (output.get(output.size() - 2) instanceof SetLocalAVM2Item) { - ret = new ArrayList<>(); - ret.addAll(output); - ret.remove(ret.size() - 1); - ret.add(new ReturnValueAVM2Item(this.avm2code.code.get(part.end), ((SetLocalAVM2Item) output.get(output.size() - 2)).value)); - return ret; - } - } - } - } - } - } - } - if ((this.avm2code.code.get(part.end).definition instanceof LookupSwitchIns) && ignoredSwitches.contains(part.end)) { - ret = new ArrayList<>(); - ret.addAll(output); - return ret; - } - if (((part.nextParts.size() == 2) - && (!stack.isEmpty()) - && (stack.peek() instanceof StrictEqAVM2Item) - && (part.nextParts.get(0).getHeight() >= 2) - && (this.avm2code.code.get(this.avm2code.fixIPAfterDebugLine(part.nextParts.get(0).start)).definition instanceof PushIntegerTypeIns) - && (!part.nextParts.get(0).nextParts.isEmpty()) - && (this.avm2code.code.get(part.nextParts.get(0).nextParts.get(0).end).definition instanceof LookupSwitchIns)) - || ((part.nextParts.size() == 2) - && (!stack.isEmpty()) - && (stack.peek() instanceof StrictNeqAVM2Item) - && (part.nextParts.get(1).getHeight() >= 2) - && (this.avm2code.code.get(this.avm2code.fixIPAfterDebugLine(part.nextParts.get(1).start)).definition instanceof PushIntegerTypeIns) - && (!part.nextParts.get(1).nextParts.isEmpty()) - && (this.avm2code.code.get(part.nextParts.get(1).nextParts.get(0).end).definition instanceof LookupSwitchIns))) { - - if (stack.peek() instanceof StrictEqAVM2Item) { - ignoredSwitches.add(part.nextParts.get(0).nextParts.get(0).end); - } else { - ignoredSwitches.add(part.nextParts.get(1).nextParts.get(0).end); - } - ret = new ArrayList<>(); - ret.addAll(output); - boolean reversed = false; - if (stack.peek() instanceof StrictEqAVM2Item) { - reversed = true; - } - GraphTargetItem switchedObject = null; - if (!output.isEmpty()) { - if (output.get(output.size() - 1) instanceof SetLocalAVM2Item) { - switchedObject = ((SetLocalAVM2Item) output.get(output.size() - 1)).value; - } - } - if (switchedObject == null) { - switchedObject = new NullAVM2Item(null); - } - HashMap caseValuesMap = new HashMap<>(); - - GraphTargetItem tar = stack.pop(); - if (tar instanceof StrictEqAVM2Item) { - tar = ((StrictEqAVM2Item) tar).leftSide; - } - if (tar instanceof StrictNeqAVM2Item) { - tar = ((StrictNeqAVM2Item) tar).leftSide; - } - caseValuesMap.put(this.avm2code.code.get(part.nextParts.get(reversed ? 0 : 1).start).operands[0], tar); - - GraphPart switchLoc = part.nextParts.get(reversed ? 0 : 1).nextParts.get(0); - - while ((this.avm2code.code.get(part.nextParts.get(reversed ? 1 : 0).end).definition instanceof IfStrictNeIns) - || (this.avm2code.code.get(part.nextParts.get(reversed ? 1 : 0).end).definition instanceof IfStrictEqIns)) { - part = part.nextParts.get(reversed ? 1 : 0); - translatePart(localData, part, stack, staticOperation, null); - tar = stack.pop(); - if (tar instanceof StrictEqAVM2Item) { - tar = ((StrictEqAVM2Item) tar).leftSide; - } - if (tar instanceof StrictNeqAVM2Item) { - tar = ((StrictNeqAVM2Item) tar).leftSide; - } - if (this.avm2code.code.get(part.end).definition instanceof IfStrictNeIns) { - reversed = false; - } else { - reversed = true; - } - GraphPart numPart = part.nextParts.get(reversed ? 0 : 1); - AVM2Instruction ins = null; - TranslateStack sstack = new TranslateStack(); - do { - for (int n = 0; n < numPart.getHeight(); n++) { - ins = this.avm2code.code.get(numPart.getPosAt(n)); - if (ins.definition instanceof LookupSwitchIns) { - break; - } - ins.translate(localData, sstack, new ArrayList(), staticOperation, path); - } - if (numPart.nextParts.size() > 1) { - break; - } else { - numPart = numPart.nextParts.get(0); - } - } while (!(this.avm2code.code.get(numPart.end).definition instanceof LookupSwitchIns)); - GraphTargetItem nt = sstack.peek(); - - if (!(nt instanceof IntegerValueAVM2Item)) { - throw new RuntimeException("Invalid integer value in Switch"); - } - IntegerValueAVM2Item iv = (IntegerValueAVM2Item) nt; - caseValuesMap.put((int) (long) iv.value, tar); - while (this.avm2code.code.get(part.nextParts.get(reversed ? 1 : 0).start).definition instanceof JumpIns) { - reversed = false; - part = part.nextParts.get(reversed ? 1 : 0); - if (part instanceof GraphPartMulti) { - part = ((GraphPartMulti) part).parts.get(0); - } - } - } - boolean hasDefault = false; - GraphPart dp = part.nextParts.get(reversed ? 1 : 0); - while (this.avm2code.code.get(dp.start).definition instanceof JumpIns) { - if (dp instanceof GraphPartMulti) { - dp = ((GraphPartMulti) dp).parts.get(0); - } - dp = dp.nextParts.get(0); - } - - GraphPart numPart = dp; - AVM2Instruction ins = null; - TranslateStack sstack = new TranslateStack(); - do { - for (int n = 0; n < numPart.getHeight(); n++) { - ins = this.avm2code.code.get(numPart.getPosAt(n)); - if (ins.definition instanceof LookupSwitchIns) { - break; - } - ins.translate(localData, sstack, new ArrayList(), staticOperation, path); - } - if (numPart.nextParts.size() > 1) { - break; - } else { - numPart = numPart.nextParts.get(0); - } - } while (!(this.avm2code.code.get(numPart.end).definition instanceof LookupSwitchIns)); - GraphTargetItem nt = sstack.peek(); - if (nt instanceof IntegerValueAVM2Item) { - hasDefault = true; - } - List caseValues = new ArrayList<>(); - for (int i = 0; i < switchLoc.nextParts.size() - 1; i++) { - if (caseValuesMap.containsKey(i)) { - caseValues.add(caseValuesMap.get(i)); - } else { - continue; - } - } - - List> caseCommands = new ArrayList<>(); - GraphPart next = null; - - next = getMostCommonPart(localData, switchLoc.nextParts, loops);//getNextPartPath(loopContinues); - currentLoop = new Loop(loops.size(), null, next); - currentLoop.phase = 1; - loops.add(currentLoop); - //switchLoc.getNextPartPath(new ArrayList()); - List valuesMapping = new ArrayList<>(); - List caseBodies = new ArrayList<>(); - for (int i = 0; i < caseValues.size(); i++) { - GraphPart cur = switchLoc.nextParts.get(1 + i); - if (!caseBodies.contains(cur)) { - caseBodies.add(cur); - } - valuesMapping.add(caseBodies.indexOf(cur)); - } - - List defaultCommands = new ArrayList<>(); - GraphPart defaultPart = null; - if (hasDefault) { - defaultPart = switchLoc.nextParts.get(switchLoc.nextParts.size() - 1); - List stopPart2 = new ArrayList<>(stopPart); - stopPart2.add(next); - defaultCommands = printGraph(localData, stack, allParts, switchLoc, defaultPart, stopPart2, loops, staticOperation, path); - if (!defaultCommands.isEmpty()) { - if (defaultCommands.get(defaultCommands.size() - 1) instanceof BreakItem) { - if (((BreakItem) defaultCommands.get(defaultCommands.size() - 1)).loopId == currentLoop.id) { - defaultCommands.remove(defaultCommands.size() - 1); - } - } - } - } - - List ignored = new ArrayList<>(); - for (Loop l : loops) { - ignored.add(l.loopContinue); - } - - for (int i = 0; i < caseBodies.size(); i++) { - List cc = new ArrayList<>(); - List stopPart2 = new ArrayList<>(stopPart); - for (int j = 0; j < caseBodies.size(); j++) { - if (caseBodies.get(j) != caseBodies.get(i)) { - stopPart2.add(caseBodies.get(j)); - } - } - if (hasDefault) { - stopPart2.add(defaultPart); - } - - cc.addAll(0, printGraph(localData, stack, allParts, switchLoc, caseBodies.get(i), stopPart2, loops, staticOperation, path)); - caseCommands.add(cc); - } - - SwitchItem sti = new SwitchItem(null, currentLoop, switchedObject, caseValues, caseCommands, defaultCommands, valuesMapping); - ret.add(sti); - //loops.remove(currentLoop); - if (next != null) { - /*if (ti != null) { - ret.add(ti); - } else {*/ - currentLoop.phase = 2; - ret.addAll(printGraph(localData, stack, allParts, null, next, stopPart, loops, staticOperation, path)); - //} - } - } - return ret; - } - - @Override - protected GraphPart checkPart(TranslateStack stack, BaseLocalData localData, GraphPart next, List allParts) { - AVM2LocalData aLocalData = (AVM2LocalData) localData; - List finallyJumps = aLocalData.finallyJumps; - List ignoredSwitches = aLocalData.ignoredSwitches; - GraphPart ret = next; - for (int f = 0; f < finallyJumps.size(); f++) { - int fip = finallyJumps.get(f); - int swip = ignoredSwitches.get(f); - if (next.start == fip) { - if (stack != null && swip != -1) { - AVM2Instruction swIns = avm2code.code.get(swip); - GraphTargetItem t = stack.pop(); - Double dval = EcmaScript.toNumber(t.getResult()); - int val = (int) (double) dval; - if (swIns.definition instanceof LookupSwitchIns) { - List branches = swIns.getBranches(code); - int nip = branches.get(0); - if (val >= 0 && val < branches.size() - 1) { - nip = branches.get(1 + val); - } - for (GraphPart p : allParts) { - if (p.start == nip) { - return p; - } - } - ret = null; - } - } - ret = null; - } - } - if (ret != next) { - return ret; - } - - int pos = next.start; - int addr = this.avm2code.fixAddrAfterDebugLine(avm2code.pos2adr(pos)); - for (int e = 0; e < body.exceptions.length; e++) { - if (body.exceptions[e].isFinally()) { - if (addr == this.avm2code.fixAddrAfterDebugLine(body.exceptions[e].start)) { - if (true) { //afterCatchPos + 1 == code.adr2pos(this.code.fixAddrAfterDebugLine(body.exceptions[e].end))) { - AVM2Instruction jmpIns = this.avm2code.code.get(avm2code.adr2pos(this.avm2code.fixAddrAfterDebugLine(body.exceptions[e].end))); - if (jmpIns.definition instanceof JumpIns) { - int finStart = avm2code.adr2pos(this.avm2code.fixAddrAfterDebugLine(body.exceptions[e].end) + jmpIns.getBytes().length + jmpIns.operands[0]); - finallyJumps.add(finStart); - ignoredSwitches.add(-1); - break; - } - } - } - } - } - - return next; - } - - @Override - protected GraphTargetItem checkLoop(LoopItem loopItem, BaseLocalData localData, List loops) { - AVM2LocalData aLocalData = (AVM2LocalData) localData; - if (loopItem instanceof WhileItem) { - WhileItem w = (WhileItem) loopItem; - - if ((!w.expression.isEmpty()) && (w.expression.get(w.expression.size() - 1) instanceof HasNextAVM2Item)) { - HasNextAVM2Item hn = (HasNextAVM2Item) w.expression.get(w.expression.size() - 1); - if (((HasNextAVM2Item) w.expression.get(w.expression.size() - 1)).collection != null) { - if (((HasNextAVM2Item) w.expression.get(w.expression.size() - 1)).collection.getNotCoerced().getThroughRegister() instanceof FilteredCheckAVM2Item) { - //GraphTargetItem gti = ((HasNextAVM2Item) ((HasNextAVM2Item) w.expression.get(w.expression.size() - 1))).collection.getNotCoerced().getThroughRegister(); - if (w.commands.size() >= 3) { //((w.commands.size() == 3) || (w.commands.size() == 4)) { - int pos = 0; - while (w.commands.get(pos) instanceof SetLocalAVM2Item) { - pos++; - } - GraphTargetItem ft = w.commands.get(pos); - if (ft instanceof WithAVM2Item) { - ft = w.commands.get(pos + 1); - if (ft instanceof IfItem) { - IfItem ift = (IfItem) ft; - if (ift.onTrue.size() > 0) { - ft = ift.onTrue.get(0); - if (ft instanceof SetPropertyAVM2Item) { - SetPropertyAVM2Item spt = (SetPropertyAVM2Item) ft; - if (spt.object instanceof LocalRegAVM2Item) { - int regIndex = ((LocalRegAVM2Item) spt.object).regIndex; - HasNextAVM2Item iti = (HasNextAVM2Item) w.expression.get(w.expression.size() - 1); - HashMap localRegs = aLocalData.localRegs; - localRegs.put(regIndex, new FilterAVM2Item(null, iti.collection.getThroughRegister(), ift.expression)); - return null; - } - } - } - } - } - } - } else if (!w.commands.isEmpty()) { - if (w.commands.get(0) instanceof SetTypeAVM2Item) { - SetTypeAVM2Item sti = (SetTypeAVM2Item) w.commands.remove(0); - GraphTargetItem gti = sti.getValue().getNotCoerced(); - if (gti instanceof NextValueAVM2Item) { - return new ForEachInAVM2Item(w.src, w.loop, new InAVM2Item(hn.instruction, sti.getObject(), ((HasNextAVM2Item) w.expression.get(w.expression.size() - 1)).collection), w.commands); - } else if (gti instanceof NextNameAVM2Item) { - return new ForInAVM2Item(w.src, w.loop, new InAVM2Item(hn.instruction, sti.getObject(), ((HasNextAVM2Item) w.expression.get(w.expression.size() - 1)).collection), w.commands); - } - } - } - } - } - } - return loopItem; - } - - @Override - protected void finalProcess(List list, int level, FinalProcessLocalData localData) { - super.finalProcess(list, level, localData); - if (level == 0) { - if (!list.isEmpty()) { - if (list.get(list.size() - 1) instanceof ReturnVoidAVM2Item) { - list.remove(list.size() - 1); - } - } - } - - /*for (int i = 0; i < list.size(); i++) { - - if (list.get(i) instanceof WhileItem) { - WhileItem w = (WhileItem) list.get(i); - - } - }*/ - List ret = avm2code.clearTemporaryRegisters(list); - if (ret != list) { - list.clear(); - list.addAll(ret); - } - for (int i = 0; i < list.size(); i++) { - if (list.get(i) instanceof SetTypeAVM2Item) { - if (((SetTypeAVM2Item) list.get(i)).getValue() instanceof ExceptionAVM2Item) { - list.remove(i); - i--; - continue; - } - } - if (list.get(i) instanceof IfItem) { - IfItem ifi = (IfItem) list.get(i); - if (((ifi.expression instanceof HasNextAVM2Item) - || ((ifi.expression instanceof NotItem) - && (((NotItem) ifi.expression).getOriginal() instanceof HasNextAVM2Item)))) { - HasNextAVM2Item hnt = null; - List body = new ArrayList<>(); - List nextbody = new ArrayList<>(); - if (ifi.expression instanceof NotItem) { - hnt = (HasNextAVM2Item) ((NotItem) ifi.expression).getOriginal(); - body.addAll(ifi.onFalse); - for (int j = i + 1; j < list.size();) { - body.add(list.remove(i + 1)); - } - nextbody = ifi.onTrue; - } else { - hnt = (HasNextAVM2Item) ifi.expression; - body = ifi.onTrue; - nextbody = ifi.onFalse; - } - if (!body.isEmpty()) { - if (body.get(0) instanceof SetTypeAVM2Item) { - SetTypeAVM2Item sti = (SetTypeAVM2Item) body.remove(0); - GraphTargetItem gti = sti.getValue().getNotCoerced(); - GraphTargetItem repl = null; - - if (gti instanceof NextValueAVM2Item) { - repl = new ForEachInAVM2Item(ifi.src, new Loop(0, null, null), new InAVM2Item(null, sti.getObject(), hnt.collection), body); - } else if (gti instanceof NextNameAVM2Item) { - repl = new ForInAVM2Item(ifi.src, new Loop(0, null, null), new InAVM2Item(null, sti.getObject(), hnt.collection), body); - } - if (repl != null) { - list.remove(i); - list.add(i, repl); - list.addAll(i + 1, nextbody); - } - } - } - } - } - } - } - - @Override - protected boolean isEmpty(List output) { - if (super.isEmpty(output)) { - return true; - } - for (GraphTargetItem i : output) { - if (i instanceof SetLocalAVM2Item) { - if (avm2code.isKilled(((SetLocalAVM2Item) i).regIndex, 0, avm2code.code.size() - 1)) { - continue; - } - } - return false; - } - return true; - } - - @Override - public AVM2LocalData prepareBranchLocalData(BaseLocalData localData) { - AVM2LocalData aLocalData = (AVM2LocalData) localData; - AVM2LocalData ret = new AVM2LocalData(aLocalData); - ScopeStack copyScopeStack = new ScopeStack(); - copyScopeStack.addAll(ret.scopeStack); - ret.scopeStack = copyScopeStack; - return ret; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.graph; + +import com.jpexs.decompiler.flash.BaseLocalData; +import com.jpexs.decompiler.flash.FinalProcessLocalData; +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.AVM2LocalData; +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.jumps.IfStrictEqIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.IfStrictNeIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.JumpIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.LookupSwitchIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.GetLocalTypeIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.KillIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other.ReturnValueIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushIntegerTypeIns; +import com.jpexs.decompiler.flash.abc.avm2.model.FilteredCheckAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.HasNextAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.InAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.IntegerValueAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.LocalRegAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.NextNameAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.NextValueAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.NullAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.ReturnValueAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.ReturnVoidAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.SetLocalAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.SetPropertyAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.SetTypeAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.WithAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.clauses.ExceptionAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.clauses.FilterAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.clauses.ForEachInAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.clauses.ForInAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.clauses.TryAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.StrictEqAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.StrictNeqAVM2Item; +import com.jpexs.decompiler.flash.abc.types.ABCException; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.ecma.EcmaScript; +import com.jpexs.decompiler.graph.Graph; +import com.jpexs.decompiler.graph.GraphPart; +import com.jpexs.decompiler.graph.GraphPartMulti; +import com.jpexs.decompiler.graph.GraphSource; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.Loop; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import com.jpexs.decompiler.graph.model.BreakItem; +import com.jpexs.decompiler.graph.model.IfItem; +import com.jpexs.decompiler.graph.model.LoopItem; +import com.jpexs.decompiler.graph.model.NotItem; +import com.jpexs.decompiler.graph.model.SwitchItem; +import com.jpexs.decompiler.graph.model.WhileItem; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; + +/** + * + * @author JPEXS + */ +public class AVM2Graph extends Graph { + + private final AVM2Code avm2code; + + private final ABC abc; + + private final MethodBody body; + + public AVM2Code getCode() { + return avm2code; + } + + public AVM2Graph(AVM2Code code, ABC abc, MethodBody body, boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, ScopeStack scopeStack, HashMap localRegNames, List fullyQualifiedNames, HashMap localRegAssigmentIps, HashMap> refs) { + super(new AVM2GraphSource(code, isStatic, scriptIndex, classIndex, localRegs, scopeStack, abc, body, localRegNames, fullyQualifiedNames, localRegAssigmentIps, refs), body.getExceptionEntries()); + this.avm2code = code; + this.abc = abc; + this.body = body; + /*heads = makeGraph(code, new ArrayList(), body); + this.code = code; + this.abc = abc; + this.body = body; + for (GraphPart head : heads) { + fixGraph(head); + makeMulti(head, new ArrayList()); + }*/ + + } + + public static List translateViaGraph(String path, AVM2Code code, ABC abc, MethodBody body, boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, ScopeStack scopeStack, HashMap localRegNames, List fullyQualifiedNames, int staticOperation, HashMap localRegAssigmentIps, HashMap> refs) throws InterruptedException { + AVM2Graph g = new AVM2Graph(code, abc, body, isStatic, scriptIndex, classIndex, localRegs, scopeStack, localRegNames, fullyQualifiedNames, localRegAssigmentIps, refs); + + AVM2LocalData localData = new AVM2LocalData(); + localData.isStatic = isStatic; + localData.classIndex = classIndex; + localData.localRegs = localRegs; + localData.scopeStack = scopeStack; + localData.constants = abc.constants; + localData.methodInfo = abc.method_info; + localData.methodBody = body; + localData.abc = abc; + localData.localRegNames = localRegNames; + localData.fullyQualifiedNames = fullyQualifiedNames; + localData.parsedExceptions = new ArrayList<>(); + localData.finallyJumps = new ArrayList<>(); + localData.ignoredSwitches = new ArrayList<>(); + localData.scriptIndex = scriptIndex; + localData.localRegAssignmentIps = new HashMap<>(); + localData.ip = 0; + localData.refs = refs; + localData.code = code; + g.init(localData); + List allParts = new ArrayList<>(); + for (GraphPart head : g.heads) { + populateParts(head, allParts); + } + return g.translate(localData, staticOperation, path); + } + + @Override + protected void checkGraph(List allBlocks) { + for (ABCException ex : body.exceptions) { + int startIp = avm2code.adr2pos(ex.start); + int endIp = avm2code.adr2pos(ex.end); + int targetIp = avm2code.adr2pos(ex.target); + GraphPart target = null; + for (GraphPart p : allBlocks) { + if (p.start == targetIp) { + target = p; + break; + } + } + for (GraphPart p : allBlocks) { + if (p.start >= startIp && p.end <= endIp) { + p.throwParts.add(target); + target.refs.add(p); + } + } + } + + /*for(ABCException ex:body.exceptions){ + for(GraphPart p:allBlocks){ + boolean next_is_ex_start=false; + for(GraphPart n:p.nextParts){ + if(n.start==code.adr2pos(ex.start)){ + next_is_ex_start = true; + break; + } + } + if(next_is_ex_start){ + for(GraphPart q:allBlocks){ //find target part + if(q.start==code.adr2pos(ex.target)){ + p.nextParts.add(q); + break; + } + } + } + } + }*/ + } + + @Override + protected List check(GraphSource code, BaseLocalData localData, List allParts, TranslateStack stack, GraphPart parent, GraphPart part, List stopPart, List loops, List output, Loop currentLoop, int staticOperation, String path) throws InterruptedException { + List ret = null; + + AVM2LocalData aLocalData = (AVM2LocalData) localData; + List parsedExceptions = aLocalData.parsedExceptions; + List finallyJumps = aLocalData.finallyJumps; + List ignoredSwitches = aLocalData.ignoredSwitches; + int ip = part.start; + int addr = this.avm2code.fixAddrAfterDebugLine(this.avm2code.pos2adr(part.start)); + int maxend = -1; + List catchedExceptions = new ArrayList<>(); + for (int e = 0; e < body.exceptions.length; e++) { + if (addr == this.avm2code.fixAddrAfterDebugLine(body.exceptions[e].start)) { + //Add finally only when the list is empty + if (!body.exceptions[e].isFinally() || catchedExceptions.isEmpty()) { + if (!parsedExceptions.contains(body.exceptions[e])) { + if (((body.exceptions[e].end) > maxend)) { + catchedExceptions.clear(); + maxend = this.avm2code.fixAddrAfterDebugLine(body.exceptions[e].end); + catchedExceptions.add(body.exceptions[e]); + } else if (this.avm2code.fixAddrAfterDebugLine(body.exceptions[e].end) == maxend) { + catchedExceptions.add(body.exceptions[e]); + } + + } + } else if (body.exceptions[e].isFinally()) { + parsedExceptions.add(body.exceptions[e]); + } + } + } + if (catchedExceptions.size() > 0) { + parsedExceptions.addAll(catchedExceptions); + int endpos = code.adr2pos(this.avm2code.fixAddrAfterDebugLine(catchedExceptions.get(0).end)); + int endposStartBlock = code.adr2pos(catchedExceptions.get(0).end); + + List> catchedCommands = new ArrayList<>(); + if (this.avm2code.code.get(endpos).definition instanceof JumpIns) { + int afterCatchAddr = this.avm2code.pos2adr(endpos + 1) + this.avm2code.code.get(endpos).operands[0]; + int afterCatchPos = this.avm2code.adr2pos(afterCatchAddr); + final AVM2Graph t = this; + Collections.sort(catchedExceptions, new Comparator() { + @Override + public int compare(ABCException o1, ABCException o2) { + return t.avm2code.fixAddrAfterDebugLine(o1.target) - t.avm2code.fixAddrAfterDebugLine(o2.target); + } + }); + + List finallyCommands = new ArrayList<>(); + int returnPos = afterCatchPos; + for (int e = 0; e < body.exceptions.length; e++) { + if (body.exceptions[e].isFinally()) { + if (addr == this.avm2code.fixAddrAfterDebugLine(body.exceptions[e].start)) { + if (afterCatchPos + 1 == code.adr2pos(this.avm2code.fixAddrAfterDebugLine(body.exceptions[e].end))) { + AVM2Instruction jmpIns = this.avm2code.code.get(code.adr2pos(this.avm2code.fixAddrAfterDebugLine(body.exceptions[e].end))); + + if (jmpIns.definition instanceof JumpIns) { + int finStart = code.adr2pos(this.avm2code.fixAddrAfterDebugLine(body.exceptions[e].end) + jmpIns.getBytes().length + jmpIns.operands[0]); + + GraphPart fpart = null; + for (GraphPart p : allParts) { + if (p.start == finStart) { + fpart = p; + break; + } + } + int swPos = -1; + for (int f = finStart; f < this.avm2code.code.size(); f++) { + if (this.avm2code.code.get(f).definition instanceof LookupSwitchIns) { + AVM2Instruction swins = this.avm2code.code.get(f); + if (swins.operands.length >= 3) { + if (swins.operands[0] == swins.getBytes().length) { + if (code.adr2pos(code.pos2adr(f) + swins.operands[2]) < finStart) { + stack.push(new ExceptionAVM2Item(body.exceptions[e])); + GraphPart fepart = null; + for (GraphPart p : allParts) { + if (p.start == f + 1) { + fepart = p; + break; + } + } + //this.code.code.get(f).ignored = true; + //ignoredSwitches.add(f); + swPos = f; + + List stopPart2 = new ArrayList<>(stopPart); + stopPart2.add(fepart); + //finallyCommands = printGraph(new ArrayList(), localData, stack, allParts, parent, fpart, stopPart2, loops, staticOperation, path); + returnPos = f + 1; + break; + } + } + } + } + } + //ignoredSwitches.add(-1); + //int igs_size=ignoredSwitches.size(); + List oldFinallyJumps = new ArrayList<>(finallyJumps); + finallyJumps.clear(); + ignoredSwitches.add(swPos); + finallyCommands = printGraph(localData, stack, allParts, parent, fpart, null, loops, staticOperation, path); + //ignoredSwitches.remove(igs_size-1); + finallyJumps.addAll(oldFinallyJumps); + finallyJumps.add(finStart); + break; + } + } + } + } + } + + GraphPart retPart = null; + for (GraphPart p : allParts) { + if (p.start == returnPos) { + retPart = p; + break; + } + } + List catchParts = new ArrayList<>(); + for (int e = 0; e < catchedExceptions.size(); e++) { + int eendpos; + if (e < catchedExceptions.size() - 1) { + eendpos = code.adr2pos(this.avm2code.fixAddrAfterDebugLine(catchedExceptions.get(e + 1).target)) - 2; + } else { + eendpos = afterCatchPos - 1; + } + + GraphPart npart = null; + int findpos = code.adr2pos(catchedExceptions.get(e).target); + for (GraphPart p : allParts) { + if (p.start == findpos) { + npart = p; + catchParts.add(p); + break; + } + } + + GraphPart nepart = null; + for (GraphPart p : allParts) { + if (p.start == eendpos + 1) { + nepart = p; + break; + } + } + stack.add(new ExceptionAVM2Item(catchedExceptions.get(e))); + AVM2LocalData localData2 = new AVM2LocalData(aLocalData); + localData2.scopeStack = new ScopeStack(); + List stopPart2 = new ArrayList<>(stopPart); + stopPart2.add(nepart); + if (retPart != null) { + stopPart2.add(retPart); + } + catchedCommands.add(printGraph(localData2, stack, allParts, parent, npart, stopPart2, loops, staticOperation, path)); + if (catchedExceptions.get(e).isFinally()) { + catchedCommands.remove(catchedCommands.size() - 1); + catchedExceptions.remove(e); + e--; + } + } + + GraphPart nepart = null; + + for (GraphPart p : allParts) { + if (p.start == endposStartBlock) { + nepart = p; + break; + } + } + List stopPart2 = new ArrayList<>(stopPart); + stopPart2.add(nepart); + stopPart2.addAll(catchParts); + + if (retPart != null) { + stopPart2.add(retPart); + } + List tryCommands = printGraph(localData, stack, allParts, parent, part, stopPart2, loops, staticOperation, path); + + output.clear(); + output.add(new TryAVM2Item(tryCommands, catchedExceptions, catchedCommands, finallyCommands)); + ip = returnPos; + } + + } + + if (ip != part.start) { + part = null; + for (GraphPart p : allParts) { + List ps = p.getSubParts(); + for (GraphPart p2 : ps) { + if (p2.start == ip) { + part = p2; + break; + } + } + } + ret = new ArrayList<>(); + ret.addAll(output); + GraphTargetItem lop = checkLoop(part, stopPart, loops); + if (lop == null) { + ret.addAll(printGraph(localData, stack, allParts, null, part, stopPart, loops, staticOperation, path)); + } else { + ret.add(lop); + } + return ret; + } + + if (part.nextParts.isEmpty()) { + if (this.avm2code.code.get(part.end).definition instanceof ReturnValueIns) { //returns in finally clause + if (part.getHeight() >= 3) { + if (this.avm2code.code.get(part.getPosAt(part.getHeight() - 2)).definition instanceof KillIns) { + if (this.avm2code.code.get(part.getPosAt(part.getHeight() - 3)).definition instanceof GetLocalTypeIns) { + if (output.size() >= 2) { + if (output.get(output.size() - 2) instanceof SetLocalAVM2Item) { + ret = new ArrayList<>(); + ret.addAll(output); + ret.remove(ret.size() - 1); + ret.add(new ReturnValueAVM2Item(this.avm2code.code.get(part.end), ((SetLocalAVM2Item) output.get(output.size() - 2)).value)); + return ret; + } + } + } + } + } + } + } + if ((this.avm2code.code.get(part.end).definition instanceof LookupSwitchIns) && ignoredSwitches.contains(part.end)) { + ret = new ArrayList<>(); + ret.addAll(output); + return ret; + } + if (((part.nextParts.size() == 2) + && (!stack.isEmpty()) + && (stack.peek() instanceof StrictEqAVM2Item) + && (part.nextParts.get(0).getHeight() >= 2) + && (this.avm2code.code.get(this.avm2code.fixIPAfterDebugLine(part.nextParts.get(0).start)).definition instanceof PushIntegerTypeIns) + && (!part.nextParts.get(0).nextParts.isEmpty()) + && (this.avm2code.code.get(part.nextParts.get(0).nextParts.get(0).end).definition instanceof LookupSwitchIns)) + || ((part.nextParts.size() == 2) + && (!stack.isEmpty()) + && (stack.peek() instanceof StrictNeqAVM2Item) + && (part.nextParts.get(1).getHeight() >= 2) + && (this.avm2code.code.get(this.avm2code.fixIPAfterDebugLine(part.nextParts.get(1).start)).definition instanceof PushIntegerTypeIns) + && (!part.nextParts.get(1).nextParts.isEmpty()) + && (this.avm2code.code.get(part.nextParts.get(1).nextParts.get(0).end).definition instanceof LookupSwitchIns))) { + + if (stack.peek() instanceof StrictEqAVM2Item) { + ignoredSwitches.add(part.nextParts.get(0).nextParts.get(0).end); + } else { + ignoredSwitches.add(part.nextParts.get(1).nextParts.get(0).end); + } + ret = new ArrayList<>(); + ret.addAll(output); + boolean reversed = false; + if (stack.peek() instanceof StrictEqAVM2Item) { + reversed = true; + } + GraphTargetItem switchedObject = null; + if (!output.isEmpty()) { + if (output.get(output.size() - 1) instanceof SetLocalAVM2Item) { + switchedObject = ((SetLocalAVM2Item) output.get(output.size() - 1)).value; + } + } + if (switchedObject == null) { + switchedObject = new NullAVM2Item(null); + } + HashMap caseValuesMap = new HashMap<>(); + + GraphTargetItem tar = stack.pop(); + if (tar instanceof StrictEqAVM2Item) { + tar = ((StrictEqAVM2Item) tar).leftSide; + } + if (tar instanceof StrictNeqAVM2Item) { + tar = ((StrictNeqAVM2Item) tar).leftSide; + } + caseValuesMap.put(this.avm2code.code.get(part.nextParts.get(reversed ? 0 : 1).start).operands[0], tar); + + GraphPart switchLoc = part.nextParts.get(reversed ? 0 : 1).nextParts.get(0); + + while ((this.avm2code.code.get(part.nextParts.get(reversed ? 1 : 0).end).definition instanceof IfStrictNeIns) + || (this.avm2code.code.get(part.nextParts.get(reversed ? 1 : 0).end).definition instanceof IfStrictEqIns)) { + part = part.nextParts.get(reversed ? 1 : 0); + translatePart(localData, part, stack, staticOperation, null); + tar = stack.pop(); + if (tar instanceof StrictEqAVM2Item) { + tar = ((StrictEqAVM2Item) tar).leftSide; + } + if (tar instanceof StrictNeqAVM2Item) { + tar = ((StrictNeqAVM2Item) tar).leftSide; + } + if (this.avm2code.code.get(part.end).definition instanceof IfStrictNeIns) { + reversed = false; + } else { + reversed = true; + } + GraphPart numPart = part.nextParts.get(reversed ? 0 : 1); + AVM2Instruction ins = null; + TranslateStack sstack = new TranslateStack(); + do { + for (int n = 0; n < numPart.getHeight(); n++) { + ins = this.avm2code.code.get(numPart.getPosAt(n)); + if (ins.definition instanceof LookupSwitchIns) { + break; + } + ins.translate(localData, sstack, new ArrayList(), staticOperation, path); + } + if (numPart.nextParts.size() > 1) { + break; + } else { + numPart = numPart.nextParts.get(0); + } + } while (!(this.avm2code.code.get(numPart.end).definition instanceof LookupSwitchIns)); + GraphTargetItem nt = sstack.peek(); + + if (!(nt instanceof IntegerValueAVM2Item)) { + throw new RuntimeException("Invalid integer value in Switch"); + } + IntegerValueAVM2Item iv = (IntegerValueAVM2Item) nt; + caseValuesMap.put((int) (long) iv.value, tar); + while (this.avm2code.code.get(part.nextParts.get(reversed ? 1 : 0).start).definition instanceof JumpIns) { + reversed = false; + part = part.nextParts.get(reversed ? 1 : 0); + if (part instanceof GraphPartMulti) { + part = ((GraphPartMulti) part).parts.get(0); + } + } + } + boolean hasDefault = false; + GraphPart dp = part.nextParts.get(reversed ? 1 : 0); + while (this.avm2code.code.get(dp.start).definition instanceof JumpIns) { + if (dp instanceof GraphPartMulti) { + dp = ((GraphPartMulti) dp).parts.get(0); + } + dp = dp.nextParts.get(0); + } + + GraphPart numPart = dp; + AVM2Instruction ins = null; + TranslateStack sstack = new TranslateStack(); + do { + for (int n = 0; n < numPart.getHeight(); n++) { + ins = this.avm2code.code.get(numPart.getPosAt(n)); + if (ins.definition instanceof LookupSwitchIns) { + break; + } + ins.translate(localData, sstack, new ArrayList(), staticOperation, path); + } + if (numPart.nextParts.size() > 1) { + break; + } else { + numPart = numPart.nextParts.get(0); + } + } while (!(this.avm2code.code.get(numPart.end).definition instanceof LookupSwitchIns)); + GraphTargetItem nt = sstack.peek(); + if (nt instanceof IntegerValueAVM2Item) { + hasDefault = true; + } + List caseValues = new ArrayList<>(); + for (int i = 0; i < switchLoc.nextParts.size() - 1; i++) { + if (caseValuesMap.containsKey(i)) { + caseValues.add(caseValuesMap.get(i)); + } else { + continue; + } + } + + List> caseCommands = new ArrayList<>(); + GraphPart next = null; + + next = getMostCommonPart(localData, switchLoc.nextParts, loops);//getNextPartPath(loopContinues); + currentLoop = new Loop(loops.size(), null, next); + currentLoop.phase = 1; + loops.add(currentLoop); + //switchLoc.getNextPartPath(new ArrayList()); + List valuesMapping = new ArrayList<>(); + List caseBodies = new ArrayList<>(); + for (int i = 0; i < caseValues.size(); i++) { + GraphPart cur = switchLoc.nextParts.get(1 + i); + if (!caseBodies.contains(cur)) { + caseBodies.add(cur); + } + valuesMapping.add(caseBodies.indexOf(cur)); + } + + List defaultCommands = new ArrayList<>(); + GraphPart defaultPart = null; + if (hasDefault) { + defaultPart = switchLoc.nextParts.get(switchLoc.nextParts.size() - 1); + List stopPart2 = new ArrayList<>(stopPart); + stopPart2.add(next); + defaultCommands = printGraph(localData, stack, allParts, switchLoc, defaultPart, stopPart2, loops, staticOperation, path); + if (!defaultCommands.isEmpty()) { + if (defaultCommands.get(defaultCommands.size() - 1) instanceof BreakItem) { + if (((BreakItem) defaultCommands.get(defaultCommands.size() - 1)).loopId == currentLoop.id) { + defaultCommands.remove(defaultCommands.size() - 1); + } + } + } + } + + List ignored = new ArrayList<>(); + for (Loop l : loops) { + ignored.add(l.loopContinue); + } + + for (int i = 0; i < caseBodies.size(); i++) { + List cc = new ArrayList<>(); + List stopPart2 = new ArrayList<>(stopPart); + for (int j = 0; j < caseBodies.size(); j++) { + if (caseBodies.get(j) != caseBodies.get(i)) { + stopPart2.add(caseBodies.get(j)); + } + } + if (hasDefault) { + stopPart2.add(defaultPart); + } + + cc.addAll(0, printGraph(localData, stack, allParts, switchLoc, caseBodies.get(i), stopPart2, loops, staticOperation, path)); + caseCommands.add(cc); + } + + SwitchItem sti = new SwitchItem(null, currentLoop, switchedObject, caseValues, caseCommands, defaultCommands, valuesMapping); + ret.add(sti); + //loops.remove(currentLoop); + if (next != null) { + /*if (ti != null) { + ret.add(ti); + } else {*/ + currentLoop.phase = 2; + ret.addAll(printGraph(localData, stack, allParts, null, next, stopPart, loops, staticOperation, path)); + //} + } + } + return ret; + } + + @Override + protected GraphPart checkPart(TranslateStack stack, BaseLocalData localData, GraphPart next, List allParts) { + AVM2LocalData aLocalData = (AVM2LocalData) localData; + List finallyJumps = aLocalData.finallyJumps; + List ignoredSwitches = aLocalData.ignoredSwitches; + GraphPart ret = next; + for (int f = 0; f < finallyJumps.size(); f++) { + int fip = finallyJumps.get(f); + int swip = ignoredSwitches.get(f); + if (next.start == fip) { + if (stack != null && swip != -1) { + AVM2Instruction swIns = avm2code.code.get(swip); + GraphTargetItem t = stack.pop(); + Double dval = EcmaScript.toNumber(t.getResult()); + int val = (int) (double) dval; + if (swIns.definition instanceof LookupSwitchIns) { + List branches = swIns.getBranches(code); + int nip = branches.get(0); + if (val >= 0 && val < branches.size() - 1) { + nip = branches.get(1 + val); + } + for (GraphPart p : allParts) { + if (p.start == nip) { + return p; + } + } + ret = null; + } + } + ret = null; + } + } + if (ret != next) { + return ret; + } + + int pos = next.start; + int addr = this.avm2code.fixAddrAfterDebugLine(avm2code.pos2adr(pos)); + for (int e = 0; e < body.exceptions.length; e++) { + if (body.exceptions[e].isFinally()) { + if (addr == this.avm2code.fixAddrAfterDebugLine(body.exceptions[e].start)) { + if (true) { //afterCatchPos + 1 == code.adr2pos(this.code.fixAddrAfterDebugLine(body.exceptions[e].end))) { + AVM2Instruction jmpIns = this.avm2code.code.get(avm2code.adr2pos(this.avm2code.fixAddrAfterDebugLine(body.exceptions[e].end))); + if (jmpIns.definition instanceof JumpIns) { + int finStart = avm2code.adr2pos(this.avm2code.fixAddrAfterDebugLine(body.exceptions[e].end) + jmpIns.getBytes().length + jmpIns.operands[0]); + finallyJumps.add(finStart); + ignoredSwitches.add(-1); + break; + } + } + } + } + } + + return next; + } + + @Override + protected GraphTargetItem checkLoop(LoopItem loopItem, BaseLocalData localData, List loops) { + AVM2LocalData aLocalData = (AVM2LocalData) localData; + if (loopItem instanceof WhileItem) { + WhileItem w = (WhileItem) loopItem; + + if ((!w.expression.isEmpty()) && (w.expression.get(w.expression.size() - 1) instanceof HasNextAVM2Item)) { + HasNextAVM2Item hn = (HasNextAVM2Item) w.expression.get(w.expression.size() - 1); + if (((HasNextAVM2Item) w.expression.get(w.expression.size() - 1)).collection != null) { + if (((HasNextAVM2Item) w.expression.get(w.expression.size() - 1)).collection.getNotCoerced().getThroughRegister() instanceof FilteredCheckAVM2Item) { + //GraphTargetItem gti = ((HasNextAVM2Item) ((HasNextAVM2Item) w.expression.get(w.expression.size() - 1))).collection.getNotCoerced().getThroughRegister(); + if (w.commands.size() >= 3) { //((w.commands.size() == 3) || (w.commands.size() == 4)) { + int pos = 0; + while (w.commands.get(pos) instanceof SetLocalAVM2Item) { + pos++; + } + GraphTargetItem ft = w.commands.get(pos); + if (ft instanceof WithAVM2Item) { + ft = w.commands.get(pos + 1); + if (ft instanceof IfItem) { + IfItem ift = (IfItem) ft; + if (ift.onTrue.size() > 0) { + ft = ift.onTrue.get(0); + if (ft instanceof SetPropertyAVM2Item) { + SetPropertyAVM2Item spt = (SetPropertyAVM2Item) ft; + if (spt.object instanceof LocalRegAVM2Item) { + int regIndex = ((LocalRegAVM2Item) spt.object).regIndex; + HasNextAVM2Item iti = (HasNextAVM2Item) w.expression.get(w.expression.size() - 1); + HashMap localRegs = aLocalData.localRegs; + localRegs.put(regIndex, new FilterAVM2Item(null, iti.collection.getThroughRegister(), ift.expression)); + return null; + } + } + } + } + } + } + } else if (!w.commands.isEmpty()) { + if (w.commands.get(0) instanceof SetTypeAVM2Item) { + SetTypeAVM2Item sti = (SetTypeAVM2Item) w.commands.remove(0); + GraphTargetItem gti = sti.getValue().getNotCoerced(); + if (gti instanceof NextValueAVM2Item) { + return new ForEachInAVM2Item(w.src, w.loop, new InAVM2Item(hn.instruction, sti.getObject(), ((HasNextAVM2Item) w.expression.get(w.expression.size() - 1)).collection), w.commands); + } else if (gti instanceof NextNameAVM2Item) { + return new ForInAVM2Item(w.src, w.loop, new InAVM2Item(hn.instruction, sti.getObject(), ((HasNextAVM2Item) w.expression.get(w.expression.size() - 1)).collection), w.commands); + } + } + } + } + } + } + return loopItem; + } + + @Override + protected void finalProcess(List list, int level, FinalProcessLocalData localData) { + super.finalProcess(list, level, localData); + if (level == 0) { + if (!list.isEmpty()) { + if (list.get(list.size() - 1) instanceof ReturnVoidAVM2Item) { + list.remove(list.size() - 1); + } + } + } + + /*for (int i = 0; i < list.size(); i++) { + + if (list.get(i) instanceof WhileItem) { + WhileItem w = (WhileItem) list.get(i); + + } + }*/ + List ret = avm2code.clearTemporaryRegisters(list); + if (ret != list) { + list.clear(); + list.addAll(ret); + } + for (int i = 0; i < list.size(); i++) { + if (list.get(i) instanceof SetTypeAVM2Item) { + if (((SetTypeAVM2Item) list.get(i)).getValue() instanceof ExceptionAVM2Item) { + list.remove(i); + i--; + continue; + } + } + if (list.get(i) instanceof IfItem) { + IfItem ifi = (IfItem) list.get(i); + if (((ifi.expression instanceof HasNextAVM2Item) + || ((ifi.expression instanceof NotItem) + && (((NotItem) ifi.expression).getOriginal() instanceof HasNextAVM2Item)))) { + HasNextAVM2Item hnt = null; + List body = new ArrayList<>(); + List nextbody = new ArrayList<>(); + if (ifi.expression instanceof NotItem) { + hnt = (HasNextAVM2Item) ((NotItem) ifi.expression).getOriginal(); + body.addAll(ifi.onFalse); + for (int j = i + 1; j < list.size();) { + body.add(list.remove(i + 1)); + } + nextbody = ifi.onTrue; + } else { + hnt = (HasNextAVM2Item) ifi.expression; + body = ifi.onTrue; + nextbody = ifi.onFalse; + } + if (!body.isEmpty()) { + if (body.get(0) instanceof SetTypeAVM2Item) { + SetTypeAVM2Item sti = (SetTypeAVM2Item) body.remove(0); + GraphTargetItem gti = sti.getValue().getNotCoerced(); + GraphTargetItem repl = null; + + if (gti instanceof NextValueAVM2Item) { + repl = new ForEachInAVM2Item(ifi.src, new Loop(0, null, null), new InAVM2Item(null, sti.getObject(), hnt.collection), body); + } else if (gti instanceof NextNameAVM2Item) { + repl = new ForInAVM2Item(ifi.src, new Loop(0, null, null), new InAVM2Item(null, sti.getObject(), hnt.collection), body); + } + if (repl != null) { + list.remove(i); + list.add(i, repl); + list.addAll(i + 1, nextbody); + } + } + } + } + } + } + } + + @Override + protected boolean isEmpty(List output) { + if (super.isEmpty(output)) { + return true; + } + for (GraphTargetItem i : output) { + if (i instanceof SetLocalAVM2Item) { + if (avm2code.isKilled(((SetLocalAVM2Item) i).regIndex, 0, avm2code.code.size() - 1)) { + continue; + } + } + return false; + } + return true; + } + + @Override + public AVM2LocalData prepareBranchLocalData(BaseLocalData localData) { + AVM2LocalData aLocalData = (AVM2LocalData) localData; + AVM2LocalData ret = new AVM2LocalData(aLocalData); + ScopeStack copyScopeStack = new ScopeStack(); + copyScopeStack.addAll(ret.scopeStack); + ret.scopeStack = copyScopeStack; + return ret; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2GraphSource.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2GraphSource.java index c15483e34..a3bd3f2d1 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2GraphSource.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2GraphSource.java @@ -1,118 +1,118 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.graph; - -import com.jpexs.decompiler.flash.BaseLocalData; -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.AVM2LocalData; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.ConvertOutput; -import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.graph.GraphPart; -import com.jpexs.decompiler.graph.GraphSource; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; - -/** - * - * @author JPEXS - */ -public class AVM2GraphSource extends GraphSource { - - private final AVM2Code code; - - boolean isStatic; - - int classIndex; - - int scriptIndex; - - HashMap localRegs; - - ScopeStack scopeStack; - - ABC abc; - - MethodBody body; - - HashMap localRegNames; - - List fullyQualifiedNames; - - HashMap localRegAssigmentIps; - - HashMap> refs; - - public AVM2Code getCode() { - return code; - } - - public AVM2GraphSource(AVM2Code code, boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, ScopeStack scopeStack, ABC abc, MethodBody body, HashMap localRegNames, List fullyQualifiedNames, HashMap localRegAssigmentIp, HashMap> refs) { - this.code = code; - this.isStatic = isStatic; - this.classIndex = classIndex; - this.localRegs = localRegs; - this.scopeStack = scopeStack; - this.abc = abc; - this.body = body; - this.localRegNames = localRegNames; - this.fullyQualifiedNames = fullyQualifiedNames; - this.scriptIndex = scriptIndex; - this.localRegAssigmentIps = localRegAssigmentIp; - this.refs = refs; - code.calculateDebugFileLine(abc); - } - - @Override - public int size() { - return code.code.size(); - } - - @Override - public AVM2Instruction get(int pos) { - return code.code.get(pos); - } - - @Override - public boolean isEmpty() { - return code.code.isEmpty(); - } - - @Override - public List translatePart(GraphPart part, BaseLocalData localData, TranslateStack stack, int start, int end, int staticOperation, String path) throws InterruptedException { - List ret = new ArrayList<>(); - ScopeStack newstack = ((AVM2LocalData) localData).scopeStack; - ConvertOutput co = code.toSourceOutput(path, part, false, isStatic, scriptIndex, classIndex, localRegs, stack, newstack, abc, abc.constants, abc.method_info, body, start, end, localRegNames, fullyQualifiedNames, new boolean[size()], localRegAssigmentIps, refs); - ret.addAll(co.output); - return ret; - } - - @Override - public int adr2pos(long adr) { - return code.adr2pos(adr); - } - - @Override - public long pos2adr(int pos) { - return code.pos2adr(pos); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.graph; + +import com.jpexs.decompiler.flash.BaseLocalData; +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.AVM2LocalData; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.ConvertOutput; +import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.graph.GraphPart; +import com.jpexs.decompiler.graph.GraphSource; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +/** + * + * @author JPEXS + */ +public class AVM2GraphSource extends GraphSource { + + private final AVM2Code code; + + boolean isStatic; + + int classIndex; + + int scriptIndex; + + HashMap localRegs; + + ScopeStack scopeStack; + + ABC abc; + + MethodBody body; + + HashMap localRegNames; + + List fullyQualifiedNames; + + HashMap localRegAssigmentIps; + + HashMap> refs; + + public AVM2Code getCode() { + return code; + } + + public AVM2GraphSource(AVM2Code code, boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, ScopeStack scopeStack, ABC abc, MethodBody body, HashMap localRegNames, List fullyQualifiedNames, HashMap localRegAssigmentIp, HashMap> refs) { + this.code = code; + this.isStatic = isStatic; + this.classIndex = classIndex; + this.localRegs = localRegs; + this.scopeStack = scopeStack; + this.abc = abc; + this.body = body; + this.localRegNames = localRegNames; + this.fullyQualifiedNames = fullyQualifiedNames; + this.scriptIndex = scriptIndex; + this.localRegAssigmentIps = localRegAssigmentIp; + this.refs = refs; + code.calculateDebugFileLine(abc); + } + + @Override + public int size() { + return code.code.size(); + } + + @Override + public AVM2Instruction get(int pos) { + return code.code.get(pos); + } + + @Override + public boolean isEmpty() { + return code.code.isEmpty(); + } + + @Override + public List translatePart(GraphPart part, BaseLocalData localData, TranslateStack stack, int start, int end, int staticOperation, String path) throws InterruptedException { + List ret = new ArrayList<>(); + ScopeStack newstack = ((AVM2LocalData) localData).scopeStack; + ConvertOutput co = code.toSourceOutput(path, part, false, isStatic, scriptIndex, classIndex, localRegs, stack, newstack, abc, abc.constants, abc.method_info, body, start, end, localRegNames, fullyQualifiedNames, new boolean[size()], localRegAssigmentIps, refs); + ret.addAll(co.output); + return ret; + } + + @Override + public int adr2pos(long adr) { + return code.adr2pos(adr); + } + + @Override + public long pos2adr(int pos) { + return code.pos2adr(pos); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/AVM2Instruction.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/AVM2Instruction.java index 7bfae4a7e..c603bf140 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/AVM2Instruction.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/AVM2Instruction.java @@ -1,405 +1,404 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions; - -import com.jpexs.decompiler.flash.BaseLocalData; -import com.jpexs.decompiler.flash.abc.ABCOutputStream; -import com.jpexs.decompiler.flash.abc.AVM2LocalData; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.JumpIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.LookupSwitchIns; -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.other.ThrowIns; -import com.jpexs.decompiler.flash.abc.types.Multiname; -import com.jpexs.decompiler.flash.helpers.GraphTextWriter; -import com.jpexs.decompiler.graph.GraphSource; -import com.jpexs.decompiler.graph.GraphSourceItem; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.TranslateStack; -import com.jpexs.decompiler.graph.model.LocalData; -import com.jpexs.helpers.Helper; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -public class AVM2Instruction implements Cloneable, GraphSourceItem { - - public InstructionDefinition definition; - - public int[] operands; - - public long offset; - - public String comment; - - public boolean ignored = false; - - public long mappedOffset = -1; - - public int changeJumpTo = -1; - - private int line; - - private String file; - - public void setFileLine(String file, int line) { - this.file = file; - this.line = line; - } - - public AVM2Instruction(long offset, InstructionDefinition definition, int[] operands) { - this.definition = definition; - this.operands = operands != null && operands.length > 0 ? operands : null; - this.offset = offset; - } - - public byte[] getBytes() { - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - try { - ABCOutputStream aos = new ABCOutputStream(bos); - aos.write(definition.instructionCode); - for (int i = 0; i < definition.operands.length; i++) { - int opt = definition.operands[i] & 0xff00; - switch (opt) { - case AVM2Code.OPT_S24: - aos.writeS24(operands[i]); - break; - case AVM2Code.OPT_U30: - aos.writeU30(operands[i]); - break; - case AVM2Code.OPT_U8: - aos.writeU8(operands[i]); - break; - case AVM2Code.OPT_BYTE: - aos.writeU8(0xff & operands[i]); - break; - case AVM2Code.OPT_CASE_OFFSETS: - - aos.writeU30(operands[i]); //case count - for (int j = i + 1; j < operands.length; j++) { - aos.writeS24(operands[j]); - } - break; - } - } - } catch (IOException ex) { - // ignored - } - return bos.toByteArray(); - } - - @Override - public String toString() { - StringBuilder s = new StringBuilder(); - s.append(definition.instructionName); - if (operands != null) { - for (int i = 0; i < operands.length; i++) { - s.append(" "); - s.append(operands[i]); - } - } - return s.toString(); - } - - public List getOffsets() { - List ret = new ArrayList<>(); - String s = ""; - for (int i = 0; i < definition.operands.length; i++) { - switch (definition.operands[i]) { - case AVM2Code.DAT_OFFSET: - ret.add(offset + operands[i] + getBytes().length); - break; - case AVM2Code.DAT_CASE_BASEOFFSET: - ret.add(offset + operands[i]); - break; - case AVM2Code.OPT_CASE_OFFSETS: - for (int j = i + 1; j < operands.length; j++) { - ret.add(offset + operands[j]); - } - break; - } - - } - return ret; - } - - public List getParamsAsList(AVM2ConstantPool constants) { - List s = new ArrayList<>(); - for (int i = 0; i < definition.operands.length; i++) { - switch (definition.operands[i]) { - case AVM2Code.DAT_MULTINAME_INDEX: - s.add(constants.getMultiname(operands[i])); - break; - case AVM2Code.DAT_STRING_INDEX: - s.add(constants.getString(operands[i])); - break; - case AVM2Code.DAT_INT_INDEX: - s.add(constants.getInt(operands[i])); - break; - case AVM2Code.DAT_UINT_INDEX: - s.add(constants.getUInt(operands[i])); - break; - case AVM2Code.DAT_DOUBLE_INDEX: - s.add(constants.getDouble(operands[i])); - break; - case AVM2Code.DAT_OFFSET: - s.add(offset + operands[i] + getBytes().length); - break; - case AVM2Code.DAT_CASE_BASEOFFSET: - s.add(offset + operands[i]); - break; - case AVM2Code.OPT_CASE_OFFSETS: - s.add((long) operands[i]); - for (int j = i + 1; j < operands.length; j++) { - s.add(offset + operands[j]); - } - break; - default: - s.add((long) operands[i]); - } - - } - return s; - } - - public String getParams(AVM2ConstantPool constants, List fullyQualifiedNames) { - StringBuilder s = new StringBuilder(); - for (int i = 0; i < definition.operands.length; i++) { - switch (definition.operands[i]) { - case AVM2Code.DAT_MULTINAME_INDEX: - if (operands[i] == 0) { - s.append(" null"); - } else { - s.append(" "); - Multiname multiname = constants.getMultiname(operands[i]); - if (multiname != null) { - s.append(multiname.toString(constants, fullyQualifiedNames)); - } else { - s.append("Multiname not found."); - } - } - /*s.append(" m["); - s.append(operands[i]); - s.append("]\""); - if (constants.constant_multiname[operands[i]] == null) { - s.append(""); - } else { - s.append(Helper.escapeString(constants.constant_multiname[operands[i]].toString(constants, fullyQualifiedNames))); - } - s.append("\"");*/ - break; - case AVM2Code.DAT_STRING_INDEX: - if (operands[i] == 0) { - s.append(" null"); - } else { - s.append(" \""); - s.append(Helper.escapeString(constants.getString(operands[i]))); - s.append("\""); - } - break; - case AVM2Code.DAT_INT_INDEX: - if (operands[i] == 0) { - s.append(" null"); - } else { - s.append(" "); - s.append(constants.getInt(operands[i])); - } - break; - case AVM2Code.DAT_UINT_INDEX: - if (operands[i] == 0) { - s.append(" null"); - } else { - s.append(" "); - s.append(constants.getUInt(operands[i])); - } - break; - case AVM2Code.DAT_DOUBLE_INDEX: - if (operands[i] == 0) { - s.append(" null"); - } else { - s.append(" "); - s.append(constants.getDouble(operands[i])); - } - break; - case AVM2Code.DAT_OFFSET: - s.append(" "); - s.append("ofs"); - s.append(Helper.formatAddress(offset + operands[i] + getBytes().length)); - break; - case AVM2Code.DAT_CASE_BASEOFFSET: - s.append(" "); - s.append("ofs"); - s.append(Helper.formatAddress(offset + operands[i])); - break; - case AVM2Code.OPT_CASE_OFFSETS: - s.append(" "); - s.append(operands[i]); - for (int j = i + 1; j < operands.length; j++) { - s.append(" "); - s.append("ofs"); - s.append(Helper.formatAddress(offset + operands[j])); - } - break; - default: - s.append(" "); - s.append(operands[i]); - } - - } - return s.toString(); - } - - public String getComment() { - if (ignored) { - return " ;ignored"; - } - if ((comment == null) || comment.isEmpty()) { - return ""; - } - return " ;" + comment; - } - - @Override - public boolean isIgnored() { - return ignored; - } - - public GraphTextWriter toString(GraphTextWriter writer, LocalData localData) { - writer.appendNoHilight(Helper.formatAddress(offset) + " " + Helper.padSpaceRight(Helper.byteArrToString(getBytes()), 30) + definition.instructionName); - writer.appendNoHilight(getParams(localData.constantsAvm2, localData.fullyQualifiedNames) + getComment()); - return writer; - } - - public String toStringNoAddress(AVM2ConstantPool constants, List fullyQualifiedNames) { - String s = definition.instructionName; - s += getParams(constants, fullyQualifiedNames) + getComment(); - return s; - } - - public List replaceWith; - - @Override - public void translate(BaseLocalData localData, TranslateStack stack, List output, int staticOperation, String path) throws InterruptedException { - AVM2LocalData aLocalData = (AVM2LocalData) localData; - definition.translate(aLocalData.isStatic, - aLocalData.scriptIndex, - aLocalData.classIndex, - aLocalData.localRegs, - stack, - aLocalData.scopeStack, - aLocalData.constants, this, aLocalData.methodInfo, output, aLocalData.methodBody, aLocalData.abc, aLocalData.localRegNames, aLocalData.fullyQualifiedNames, null, aLocalData.localRegAssignmentIps, aLocalData.ip, aLocalData.refs, aLocalData.code); - } - - @Override - public boolean isJump() { - return (definition instanceof JumpIns) || (fixedBranch > -1); - } - - @Override - public boolean isBranch() { - if (fixedBranch > -1) { - return false; - } - return (definition instanceof IfTypeIns) || (definition instanceof LookupSwitchIns); - } - - @Override - public boolean isExit() { - return (definition instanceof ReturnValueIns) || (definition instanceof ReturnVoidIns) || (definition instanceof ThrowIns); - } - - @Override - public long getOffset() { - return mappedOffset > -1 ? mappedOffset : offset; - } - - @Override - public List getBranches(GraphSource code) { - List ret = new ArrayList<>(); - if (definition instanceof IfTypeIns) { - - if (fixedBranch == -1 || fixedBranch == 0) { - ret.add(code.adr2pos(offset + getBytes().length + operands[0])); - } - if (!(definition instanceof JumpIns)) { - if (fixedBranch == -1 || fixedBranch == 1) { - ret.add(code.adr2pos(offset + getBytes().length)); - } - } - } - if (definition instanceof LookupSwitchIns) { - if (fixedBranch == -1 || fixedBranch == 0) { - ret.add(code.adr2pos(offset + operands[0])); - } - for (int k = 2; k < operands.length; k++) { - if (fixedBranch == -1 || fixedBranch == k - 1) { - ret.add(code.adr2pos(offset + operands[k])); - } - } - } - return ret; - } - - @Override - public boolean ignoredLoops() { - return false; - } - - @Override - public void setIgnored(boolean ignored, int pos) { - this.ignored = ignored; - } - - public void setFixBranch(int pos) { - this.fixedBranch = pos; - } - - private int fixedBranch = -1; - - public int getFixBranch() { - return fixedBranch; - } - - @Override - public boolean isDeobfuscatePop() { - return definition instanceof DeobfuscatePopIns; - } - - @Override - public AVM2Instruction clone() throws CloneNotSupportedException { - AVM2Instruction ret = (AVM2Instruction) super.clone(); - if (operands != null) { - ret.operands = Arrays.copyOf(operands, operands.length); - } - return ret; - } - - @Override - public int getLine() { - return line; - } - - @Override - public String getFile() { - return file; - } - -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions; + +import com.jpexs.decompiler.flash.BaseLocalData; +import com.jpexs.decompiler.flash.abc.ABCOutputStream; +import com.jpexs.decompiler.flash.abc.AVM2LocalData; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.JumpIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.LookupSwitchIns; +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.other.ThrowIns; +import com.jpexs.decompiler.flash.abc.types.Multiname; +import com.jpexs.decompiler.flash.helpers.GraphTextWriter; +import com.jpexs.decompiler.graph.GraphSource; +import com.jpexs.decompiler.graph.GraphSourceItem; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.TranslateStack; +import com.jpexs.decompiler.graph.model.LocalData; +import com.jpexs.helpers.Helper; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class AVM2Instruction implements Cloneable, GraphSourceItem { + + public InstructionDefinition definition; + + public int[] operands; + + public long offset; + + public String comment; + + public boolean ignored = false; + + public long mappedOffset = -1; + + public int changeJumpTo = -1; + + private int line; + + private String file; + + public void setFileLine(String file, int line) { + this.file = file; + this.line = line; + } + + public AVM2Instruction(long offset, InstructionDefinition definition, int[] operands) { + this.definition = definition; + this.operands = operands != null && operands.length > 0 ? operands : null; + this.offset = offset; + } + + public byte[] getBytes() { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + try { + ABCOutputStream aos = new ABCOutputStream(bos); + aos.write(definition.instructionCode); + for (int i = 0; i < definition.operands.length; i++) { + int opt = definition.operands[i] & 0xff00; + switch (opt) { + case AVM2Code.OPT_S24: + aos.writeS24(operands[i]); + break; + case AVM2Code.OPT_U30: + aos.writeU30(operands[i]); + break; + case AVM2Code.OPT_U8: + aos.writeU8(operands[i]); + break; + case AVM2Code.OPT_BYTE: + aos.writeU8(0xff & operands[i]); + break; + case AVM2Code.OPT_CASE_OFFSETS: + + aos.writeU30(operands[i]); //case count + for (int j = i + 1; j < operands.length; j++) { + aos.writeS24(operands[j]); + } + break; + } + } + } catch (IOException ex) { + // ignored + } + return bos.toByteArray(); + } + + @Override + public String toString() { + StringBuilder s = new StringBuilder(); + s.append(definition.instructionName); + if (operands != null) { + for (int i = 0; i < operands.length; i++) { + s.append(" "); + s.append(operands[i]); + } + } + return s.toString(); + } + + public List getOffsets() { + List ret = new ArrayList<>(); + String s = ""; + for (int i = 0; i < definition.operands.length; i++) { + switch (definition.operands[i]) { + case AVM2Code.DAT_OFFSET: + ret.add(offset + operands[i] + getBytes().length); + break; + case AVM2Code.DAT_CASE_BASEOFFSET: + ret.add(offset + operands[i]); + break; + case AVM2Code.OPT_CASE_OFFSETS: + for (int j = i + 1; j < operands.length; j++) { + ret.add(offset + operands[j]); + } + break; + } + + } + return ret; + } + + public List getParamsAsList(AVM2ConstantPool constants) { + List s = new ArrayList<>(); + for (int i = 0; i < definition.operands.length; i++) { + switch (definition.operands[i]) { + case AVM2Code.DAT_MULTINAME_INDEX: + s.add(constants.getMultiname(operands[i])); + break; + case AVM2Code.DAT_STRING_INDEX: + s.add(constants.getString(operands[i])); + break; + case AVM2Code.DAT_INT_INDEX: + s.add(constants.getInt(operands[i])); + break; + case AVM2Code.DAT_UINT_INDEX: + s.add(constants.getUInt(operands[i])); + break; + case AVM2Code.DAT_DOUBLE_INDEX: + s.add(constants.getDouble(operands[i])); + break; + case AVM2Code.DAT_OFFSET: + s.add(offset + operands[i] + getBytes().length); + break; + case AVM2Code.DAT_CASE_BASEOFFSET: + s.add(offset + operands[i]); + break; + case AVM2Code.OPT_CASE_OFFSETS: + s.add((long) operands[i]); + for (int j = i + 1; j < operands.length; j++) { + s.add(offset + operands[j]); + } + break; + default: + s.add((long) operands[i]); + } + + } + return s; + } + + public String getParams(AVM2ConstantPool constants, List fullyQualifiedNames) { + StringBuilder s = new StringBuilder(); + for (int i = 0; i < definition.operands.length; i++) { + switch (definition.operands[i]) { + case AVM2Code.DAT_MULTINAME_INDEX: + if (operands[i] == 0) { + s.append(" null"); + } else { + s.append(" "); + Multiname multiname = constants.getMultiname(operands[i]); + if (multiname != null) { + s.append(multiname.toString(constants, fullyQualifiedNames)); + } else { + s.append("Multiname not found."); + } + } + /*s.append(" m["); + s.append(operands[i]); + s.append("]\""); + if (constants.constant_multiname[operands[i]] == null) { + s.append(""); + } else { + s.append(Helper.escapeString(constants.constant_multiname[operands[i]].toString(constants, fullyQualifiedNames))); + } + s.append("\"");*/ + break; + case AVM2Code.DAT_STRING_INDEX: + if (operands[i] == 0) { + s.append(" null"); + } else { + s.append(" \""); + s.append(Helper.escapeString(constants.getString(operands[i]))); + s.append("\""); + } + break; + case AVM2Code.DAT_INT_INDEX: + if (operands[i] == 0) { + s.append(" null"); + } else { + s.append(" "); + s.append(constants.getInt(operands[i])); + } + break; + case AVM2Code.DAT_UINT_INDEX: + if (operands[i] == 0) { + s.append(" null"); + } else { + s.append(" "); + s.append(constants.getUInt(operands[i])); + } + break; + case AVM2Code.DAT_DOUBLE_INDEX: + if (operands[i] == 0) { + s.append(" null"); + } else { + s.append(" "); + s.append(constants.getDouble(operands[i])); + } + break; + case AVM2Code.DAT_OFFSET: + s.append(" "); + s.append("ofs"); + s.append(Helper.formatAddress(offset + operands[i] + getBytes().length)); + break; + case AVM2Code.DAT_CASE_BASEOFFSET: + s.append(" "); + s.append("ofs"); + s.append(Helper.formatAddress(offset + operands[i])); + break; + case AVM2Code.OPT_CASE_OFFSETS: + s.append(" "); + s.append(operands[i]); + for (int j = i + 1; j < operands.length; j++) { + s.append(" "); + s.append("ofs"); + s.append(Helper.formatAddress(offset + operands[j])); + } + break; + default: + s.append(" "); + s.append(operands[i]); + } + + } + return s.toString(); + } + + public String getComment() { + if (ignored) { + return " ;ignored"; + } + if ((comment == null) || comment.isEmpty()) { + return ""; + } + return " ;" + comment; + } + + @Override + public boolean isIgnored() { + return ignored; + } + + public GraphTextWriter toString(GraphTextWriter writer, LocalData localData) { + writer.appendNoHilight(Helper.formatAddress(offset) + " " + Helper.padSpaceRight(Helper.byteArrToString(getBytes()), 30) + definition.instructionName); + writer.appendNoHilight(getParams(localData.constantsAvm2, localData.fullyQualifiedNames) + getComment()); + return writer; + } + + public String toStringNoAddress(AVM2ConstantPool constants, List fullyQualifiedNames) { + String s = definition.instructionName; + s += getParams(constants, fullyQualifiedNames) + getComment(); + return s; + } + + public List replaceWith; + + @Override + public void translate(BaseLocalData localData, TranslateStack stack, List output, int staticOperation, String path) throws InterruptedException { + AVM2LocalData aLocalData = (AVM2LocalData) localData; + definition.translate(aLocalData.isStatic, + aLocalData.scriptIndex, + aLocalData.classIndex, + aLocalData.localRegs, + stack, + aLocalData.scopeStack, + aLocalData.constants, this, aLocalData.methodInfo, output, aLocalData.methodBody, aLocalData.abc, aLocalData.localRegNames, aLocalData.fullyQualifiedNames, null, aLocalData.localRegAssignmentIps, aLocalData.ip, aLocalData.refs, aLocalData.code); + } + + @Override + public boolean isJump() { + return (definition instanceof JumpIns) || (fixedBranch > -1); + } + + @Override + public boolean isBranch() { + if (fixedBranch > -1) { + return false; + } + return (definition instanceof IfTypeIns) || (definition instanceof LookupSwitchIns); + } + + @Override + public boolean isExit() { + return (definition instanceof ReturnValueIns) || (definition instanceof ReturnVoidIns) || (definition instanceof ThrowIns); + } + + @Override + public long getOffset() { + return mappedOffset > -1 ? mappedOffset : offset; + } + + @Override + public List getBranches(GraphSource code) { + List ret = new ArrayList<>(); + if (definition instanceof IfTypeIns) { + + if (fixedBranch == -1 || fixedBranch == 0) { + ret.add(code.adr2pos(offset + getBytes().length + operands[0])); + } + if (!(definition instanceof JumpIns)) { + if (fixedBranch == -1 || fixedBranch == 1) { + ret.add(code.adr2pos(offset + getBytes().length)); + } + } + } + if (definition instanceof LookupSwitchIns) { + if (fixedBranch == -1 || fixedBranch == 0) { + ret.add(code.adr2pos(offset + operands[0])); + } + for (int k = 2; k < operands.length; k++) { + if (fixedBranch == -1 || fixedBranch == k - 1) { + ret.add(code.adr2pos(offset + operands[k])); + } + } + } + return ret; + } + + @Override + public boolean ignoredLoops() { + return false; + } + + @Override + public void setIgnored(boolean ignored, int pos) { + this.ignored = ignored; + } + + public void setFixBranch(int pos) { + this.fixedBranch = pos; + } + + private int fixedBranch = -1; + + public int getFixBranch() { + return fixedBranch; + } + + @Override + public boolean isDeobfuscatePop() { + return definition instanceof DeobfuscatePopIns; + } + + @Override + public AVM2Instruction clone() throws CloneNotSupportedException { + AVM2Instruction ret = (AVM2Instruction) super.clone(); + if (operands != null) { + ret.operands = Arrays.copyOf(operands, operands.length); + } + return ret; + } + + @Override + public int getLine() { + return line; + } + + @Override + public String getFile() { + return file; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/InstructionDefinition.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/InstructionDefinition.java index 74909950a..be72de1a2 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/InstructionDefinition.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/InstructionDefinition.java @@ -1,176 +1,176 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.DecLocalIIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.DecLocalIns; -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.localregs.SetLocalTypeIns; -import com.jpexs.decompiler.flash.abc.avm2.model.AVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.FullMultinameAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.flash.helpers.GraphTextWriter; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.io.Serializable; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.Stack; - -public class InstructionDefinition implements Serializable { - - public static final long serialVersionUID = 1L; - - public int[] operands; - - public String instructionName = ""; - - public int instructionCode = 0; - - public boolean canThrow; - - public InstructionDefinition(int instructionCode, String instructionName, int[] operands, boolean canThrow) { - this.instructionCode = instructionCode; - this.instructionName = instructionName; - this.operands = operands; - this.canThrow = canThrow; - } - - @Override - public String toString() { - StringBuilder s = new StringBuilder(); - s.append(instructionName); - for (int i = 0; i < operands.length; i++) { - if ((operands[i] & 0xff00) == AVM2Code.OPT_U30) { - s.append(" U30"); - } - if ((operands[i] & 0xff00) == AVM2Code.OPT_U8) { - s.append(" U8"); - } - if ((operands[i] & 0xff00) == AVM2Code.OPT_BYTE) { - s.append(" BYTE"); - } - if ((operands[i] & 0xff00) == AVM2Code.OPT_S24) { - s.append(" S24"); - } - if ((operands[i] & 0xff00) == AVM2Code.OPT_CASE_OFFSETS) { - s.append(" U30 S24,[S24]..."); - } - } - return s.toString(); - } - - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - throw new UnsupportedOperationException("Instruction " + instructionName + " not implemented"); - } - - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) throws InterruptedException { - } - - protected FullMultinameAVM2Item resolveMultiname(TranslateStack stack, AVM2ConstantPool constants, int multinameIndex, AVM2Instruction ins) { - GraphTargetItem ns = null; - GraphTargetItem name = null; - if (constants.getMultiname(multinameIndex).needsName()) { - name = stack.pop(); - } - if (constants.getMultiname(multinameIndex).needsNs()) { - ns = stack.pop(); - } - return new FullMultinameAVM2Item(ins, multinameIndex, name, ns); - } - - protected int resolvedCount(AVM2ConstantPool constants, int multinameIndex) { - int pos = 0; - if (constants.getMultiname(multinameIndex).needsNs()) { - pos++; - } - if (constants.getMultiname(multinameIndex).needsName()) { - pos++; - } - return pos; - - } - - protected String resolveMultinameNoPop(int pos, Stack stack, AVM2ConstantPool constants, int multinameIndex, AVM2Instruction ins, List fullyQualifiedNames) { - String ns = ""; - String name; - if (constants.getMultiname(multinameIndex).needsNs()) { - ns = "[" + stack.get(pos) + "]"; - pos++; - } - if (constants.getMultiname(multinameIndex).needsName()) { - name = stack.get(pos).toString(); - } else { - name = GraphTextWriter.hilighOffset(constants.getMultiname(multinameIndex).getName(constants, fullyQualifiedNames, false), ins.offset); - } - return name + ns; - } - - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return 0; - } - - public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { - return 0; - } - - protected boolean isRegisterCompileTime(int regId, int ip, HashMap> refs, AVM2Code code) { - Set previous = new HashSet<>(); - AVM2Code.getPreviousReachableIps(ip, refs, previous, new HashSet()); - for (int p : previous) { - if (p < 0) { - continue; - } - if (p >= code.code.size()) { - continue; - } - AVM2Instruction sins = code.code.get(p); - if (code.code.get(p).definition instanceof SetLocalTypeIns) { - SetLocalTypeIns sl = (SetLocalTypeIns) sins.definition; - if (sl.getRegisterId(sins) == regId) { - if (!AVM2Code.isDirectAncestor(ip, p, refs)) { - return false; - } - } - } - if ((code.code.get(p).definition instanceof IncLocalIns) - || (code.code.get(p).definition instanceof IncLocalIIns) - || (code.code.get(p).definition instanceof DecLocalIns) - || (code.code.get(p).definition instanceof DecLocalIIns)) { - if (sins.operands[0] == regId) { - if (!AVM2Code.isDirectAncestor(ip, p, refs)) { - return false; - } - } - } - } - return true; - } - - public boolean isExitInstruction() { - return false; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.DecLocalIIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.DecLocalIns; +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.localregs.SetLocalTypeIns; +import com.jpexs.decompiler.flash.abc.avm2.model.AVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.FullMultinameAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.flash.helpers.GraphTextWriter; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.io.Serializable; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.Stack; + +public class InstructionDefinition implements Serializable { + + public static final long serialVersionUID = 1L; + + public int[] operands; + + public String instructionName = ""; + + public int instructionCode = 0; + + public boolean canThrow; + + public InstructionDefinition(int instructionCode, String instructionName, int[] operands, boolean canThrow) { + this.instructionCode = instructionCode; + this.instructionName = instructionName; + this.operands = operands; + this.canThrow = canThrow; + } + + @Override + public String toString() { + StringBuilder s = new StringBuilder(); + s.append(instructionName); + for (int i = 0; i < operands.length; i++) { + if ((operands[i] & 0xff00) == AVM2Code.OPT_U30) { + s.append(" U30"); + } + if ((operands[i] & 0xff00) == AVM2Code.OPT_U8) { + s.append(" U8"); + } + if ((operands[i] & 0xff00) == AVM2Code.OPT_BYTE) { + s.append(" BYTE"); + } + if ((operands[i] & 0xff00) == AVM2Code.OPT_S24) { + s.append(" S24"); + } + if ((operands[i] & 0xff00) == AVM2Code.OPT_CASE_OFFSETS) { + s.append(" U30 S24,[S24]..."); + } + } + return s.toString(); + } + + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + throw new UnsupportedOperationException("Instruction " + instructionName + " not implemented"); + } + + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) throws InterruptedException { + } + + protected FullMultinameAVM2Item resolveMultiname(TranslateStack stack, AVM2ConstantPool constants, int multinameIndex, AVM2Instruction ins) { + GraphTargetItem ns = null; + GraphTargetItem name = null; + if (constants.getMultiname(multinameIndex).needsName()) { + name = stack.pop(); + } + if (constants.getMultiname(multinameIndex).needsNs()) { + ns = stack.pop(); + } + return new FullMultinameAVM2Item(ins, multinameIndex, name, ns); + } + + protected int resolvedCount(AVM2ConstantPool constants, int multinameIndex) { + int pos = 0; + if (constants.getMultiname(multinameIndex).needsNs()) { + pos++; + } + if (constants.getMultiname(multinameIndex).needsName()) { + pos++; + } + return pos; + + } + + protected String resolveMultinameNoPop(int pos, Stack stack, AVM2ConstantPool constants, int multinameIndex, AVM2Instruction ins, List fullyQualifiedNames) { + String ns = ""; + String name; + if (constants.getMultiname(multinameIndex).needsNs()) { + ns = "[" + stack.get(pos) + "]"; + pos++; + } + if (constants.getMultiname(multinameIndex).needsName()) { + name = stack.get(pos).toString(); + } else { + name = GraphTextWriter.hilighOffset(constants.getMultiname(multinameIndex).getName(constants, fullyQualifiedNames, false), ins.offset); + } + return name + ns; + } + + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return 0; + } + + public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { + return 0; + } + + protected boolean isRegisterCompileTime(int regId, int ip, HashMap> refs, AVM2Code code) { + Set previous = new HashSet<>(); + AVM2Code.getPreviousReachableIps(ip, refs, previous, new HashSet()); + for (int p : previous) { + if (p < 0) { + continue; + } + if (p >= code.code.size()) { + continue; + } + AVM2Instruction sins = code.code.get(p); + if (code.code.get(p).definition instanceof SetLocalTypeIns) { + SetLocalTypeIns sl = (SetLocalTypeIns) sins.definition; + if (sl.getRegisterId(sins) == regId) { + if (!AVM2Code.isDirectAncestor(ip, p, refs)) { + return false; + } + } + } + if ((code.code.get(p).definition instanceof IncLocalIns) + || (code.code.get(p).definition instanceof IncLocalIIns) + || (code.code.get(p).definition instanceof DecLocalIns) + || (code.code.get(p).definition instanceof DecLocalIIns)) { + if (sins.operands[0] == regId) { + if (!AVM2Code.isDirectAncestor(ip, p, refs)) { + return false; + } + } + } + } + return true; + } + + public boolean isExitInstruction() { + return false; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/TagInstruction.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/TagInstruction.java index a0a527233..5e59adab8 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/TagInstruction.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/TagInstruction.java @@ -1,30 +1,30 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions; - -/** - * - * @author JPEXS - */ -public class TagInstruction extends InstructionDefinition { - - public static final long serialVersionUID = 1L; - - public TagInstruction(String tagName) { - super(-1, tagName, new int[0], false /*?*/); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions; + +/** + * + * @author JPEXS + */ +public class TagInstruction extends InstructionDefinition { + + public static final long serialVersionUID = 1L; + + public TagInstruction(String tagName) { + super(-1, tagName, new int[0], false /*?*/); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/alchemy/Lf32Ins.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/alchemy/Lf32Ins.java index a33941e89..6739f5d58 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/alchemy/Lf32Ins.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/alchemy/Lf32Ins.java @@ -1,58 +1,58 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.alchemy; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.AlchemyLoadAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -/** - * - * @author JPEXS - */ -public class Lf32Ins extends InstructionDefinition { - - public Lf32Ins() { - super(0x38, "lf32", new int[]{}, true); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return 1 - 1; - } - - @Override - public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { - return 0; - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem ofs = stack.pop(); - stack.push(new AlchemyLoadAVM2Item(ins, ofs, instructionName)); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.alchemy; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.AlchemyLoadAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +/** + * + * @author JPEXS + */ +public class Lf32Ins extends InstructionDefinition { + + public Lf32Ins() { + super(0x38, "lf32", new int[]{}, true); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return 1 - 1; + } + + @Override + public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { + return 0; + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem ofs = stack.pop(); + stack.push(new AlchemyLoadAVM2Item(ins, ofs, instructionName)); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/alchemy/Lf64Ins.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/alchemy/Lf64Ins.java index 16d87eac8..33b88d996 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/alchemy/Lf64Ins.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/alchemy/Lf64Ins.java @@ -1,58 +1,58 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.alchemy; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.AlchemyLoadAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -/** - * - * @author JPEXS - */ -public class Lf64Ins extends InstructionDefinition { - - public Lf64Ins() { - super(0x39, "lf64", new int[]{}, true); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return 1 - 1; - } - - @Override - public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { - return 0; - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem ofs = stack.pop(); - stack.push(new AlchemyLoadAVM2Item(ins, ofs, instructionName)); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.alchemy; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.AlchemyLoadAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +/** + * + * @author JPEXS + */ +public class Lf64Ins extends InstructionDefinition { + + public Lf64Ins() { + super(0x39, "lf64", new int[]{}, true); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return 1 - 1; + } + + @Override + public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { + return 0; + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem ofs = stack.pop(); + stack.push(new AlchemyLoadAVM2Item(ins, ofs, instructionName)); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/alchemy/Li16Ins.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/alchemy/Li16Ins.java index de9cb813e..327dcafe8 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/alchemy/Li16Ins.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/alchemy/Li16Ins.java @@ -1,58 +1,58 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.alchemy; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.AlchemyLoadAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -/** - * - * @author JPEXS - */ -public class Li16Ins extends InstructionDefinition { - - public Li16Ins() { - super(0x36, "li16", new int[]{}, true); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return 1 - 1; - } - - @Override - public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { - return 0; - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem ofs = stack.pop(); - stack.push(new AlchemyLoadAVM2Item(ins, ofs, instructionName)); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.alchemy; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.AlchemyLoadAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +/** + * + * @author JPEXS + */ +public class Li16Ins extends InstructionDefinition { + + public Li16Ins() { + super(0x36, "li16", new int[]{}, true); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return 1 - 1; + } + + @Override + public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { + return 0; + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem ofs = stack.pop(); + stack.push(new AlchemyLoadAVM2Item(ins, ofs, instructionName)); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/alchemy/Li32Ins.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/alchemy/Li32Ins.java index 51159a5a5..1f9086b89 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/alchemy/Li32Ins.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/alchemy/Li32Ins.java @@ -1,58 +1,58 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.alchemy; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.AlchemyLoadAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -/** - * - * @author JPEXS - */ -public class Li32Ins extends InstructionDefinition { - - public Li32Ins() { - super(0x37, "li32", new int[]{}, true); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return 1 - 1; - } - - @Override - public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { - return 0; - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem ofs = stack.pop(); - stack.push(new AlchemyLoadAVM2Item(ins, ofs, instructionName)); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.alchemy; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.AlchemyLoadAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +/** + * + * @author JPEXS + */ +public class Li32Ins extends InstructionDefinition { + + public Li32Ins() { + super(0x37, "li32", new int[]{}, true); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return 1 - 1; + } + + @Override + public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { + return 0; + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem ofs = stack.pop(); + stack.push(new AlchemyLoadAVM2Item(ins, ofs, instructionName)); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/alchemy/Li8Ins.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/alchemy/Li8Ins.java index 2387f2035..3d4d7aef6 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/alchemy/Li8Ins.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/alchemy/Li8Ins.java @@ -1,58 +1,58 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.alchemy; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.AlchemyLoadAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -/** - * - * @author JPEXS - */ -public class Li8Ins extends InstructionDefinition { - - public Li8Ins() { - super(0x35, "li8", new int[]{}, true); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return 1 - 1; - } - - @Override - public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { - return 0; - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem ofs = stack.pop(); - stack.push(new AlchemyLoadAVM2Item(ins, ofs, instructionName)); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.alchemy; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.AlchemyLoadAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +/** + * + * @author JPEXS + */ +public class Li8Ins extends InstructionDefinition { + + public Li8Ins() { + super(0x35, "li8", new int[]{}, true); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return 1 - 1; + } + + @Override + public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { + return 0; + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem ofs = stack.pop(); + stack.push(new AlchemyLoadAVM2Item(ins, ofs, instructionName)); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/alchemy/Sf32Ins.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/alchemy/Sf32Ins.java index 8aca2188d..3600a9a38 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/alchemy/Sf32Ins.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/alchemy/Sf32Ins.java @@ -1,59 +1,59 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.alchemy; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.AlchemyStoreAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -/** - * - * @author JPEXS - */ -public class Sf32Ins extends InstructionDefinition { - - public Sf32Ins() { - super(0x3D, "sf32", new int[]{}, true); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -2; - } - - @Override - public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { - return 0; - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem ofs = stack.pop(); - GraphTargetItem value = stack.pop(); - stack.push(new AlchemyStoreAVM2Item(ins, value, ofs, instructionName)); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.alchemy; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.AlchemyStoreAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +/** + * + * @author JPEXS + */ +public class Sf32Ins extends InstructionDefinition { + + public Sf32Ins() { + super(0x3D, "sf32", new int[]{}, true); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -2; + } + + @Override + public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { + return 0; + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem ofs = stack.pop(); + GraphTargetItem value = stack.pop(); + stack.push(new AlchemyStoreAVM2Item(ins, value, ofs, instructionName)); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/alchemy/Sf64Ins.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/alchemy/Sf64Ins.java index eedb625ee..b3ab4aafd 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/alchemy/Sf64Ins.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/alchemy/Sf64Ins.java @@ -1,59 +1,59 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.alchemy; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.AlchemyStoreAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -/** - * - * @author JPEXS - */ -public class Sf64Ins extends InstructionDefinition { - - public Sf64Ins() { - super(0x3E, "sf64", new int[]{}, true); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -2; - } - - @Override - public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { - return 0; - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem ofs = stack.pop(); - GraphTargetItem value = stack.pop(); - stack.push(new AlchemyStoreAVM2Item(ins, value, ofs, instructionName)); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.alchemy; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.AlchemyStoreAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +/** + * + * @author JPEXS + */ +public class Sf64Ins extends InstructionDefinition { + + public Sf64Ins() { + super(0x3E, "sf64", new int[]{}, true); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -2; + } + + @Override + public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { + return 0; + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem ofs = stack.pop(); + GraphTargetItem value = stack.pop(); + stack.push(new AlchemyStoreAVM2Item(ins, value, ofs, instructionName)); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/alchemy/Si16Ins.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/alchemy/Si16Ins.java index 63d022dea..94a030a38 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/alchemy/Si16Ins.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/alchemy/Si16Ins.java @@ -1,59 +1,59 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.alchemy; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.AlchemyStoreAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -/** - * - * @author JPEXS - */ -public class Si16Ins extends InstructionDefinition { - - public Si16Ins() { - super(0x3B, "si16", new int[]{}, true); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -2; - } - - @Override - public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { - return 0; - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem ofs = stack.pop(); - GraphTargetItem value = stack.pop(); - stack.push(new AlchemyStoreAVM2Item(ins, value, ofs, instructionName)); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.alchemy; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.AlchemyStoreAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +/** + * + * @author JPEXS + */ +public class Si16Ins extends InstructionDefinition { + + public Si16Ins() { + super(0x3B, "si16", new int[]{}, true); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -2; + } + + @Override + public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { + return 0; + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem ofs = stack.pop(); + GraphTargetItem value = stack.pop(); + stack.push(new AlchemyStoreAVM2Item(ins, value, ofs, instructionName)); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/alchemy/Si32Ins.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/alchemy/Si32Ins.java index 9e2c6e737..2c02aed1f 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/alchemy/Si32Ins.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/alchemy/Si32Ins.java @@ -1,59 +1,59 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.alchemy; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.AlchemyStoreAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -/** - * - * @author JPEXS - */ -public class Si32Ins extends InstructionDefinition { - - public Si32Ins() { - super(0x3C, "si32", new int[]{}, true); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -2; - } - - @Override - public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { - return 0; - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem ofs = stack.pop(); - GraphTargetItem value = stack.pop(); - stack.push(new AlchemyStoreAVM2Item(ins, value, ofs, instructionName)); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.alchemy; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.AlchemyStoreAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +/** + * + * @author JPEXS + */ +public class Si32Ins extends InstructionDefinition { + + public Si32Ins() { + super(0x3C, "si32", new int[]{}, true); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -2; + } + + @Override + public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { + return 0; + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem ofs = stack.pop(); + GraphTargetItem value = stack.pop(); + stack.push(new AlchemyStoreAVM2Item(ins, value, ofs, instructionName)); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/alchemy/Si8Ins.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/alchemy/Si8Ins.java index c971fb782..32a14bc3b 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/alchemy/Si8Ins.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/alchemy/Si8Ins.java @@ -1,59 +1,59 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.alchemy; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.AlchemyStoreAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -/** - * - * @author JPEXS - */ -public class Si8Ins extends InstructionDefinition { - - public Si8Ins() { - super(0x3A, "si8", new int[]{}, true); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -2; - } - - @Override - public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { - return 0; - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem ofs = stack.pop(); - GraphTargetItem value = stack.pop(); - stack.push(new AlchemyStoreAVM2Item(ins, value, ofs, instructionName)); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.alchemy; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.AlchemyStoreAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +/** + * + * @author JPEXS + */ +public class Si8Ins extends InstructionDefinition { + + public Si8Ins() { + super(0x3A, "si8", new int[]{}, true); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -2; + } + + @Override + public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { + return 0; + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem ofs = stack.pop(); + GraphTargetItem value = stack.pop(); + stack.push(new AlchemyStoreAVM2Item(ins, value, ofs, instructionName)); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/alchemy/Sxi16Ins.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/alchemy/Sxi16Ins.java index 955e538c2..b52e0d8f0 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/alchemy/Sxi16Ins.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/alchemy/Sxi16Ins.java @@ -1,58 +1,58 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.alchemy; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.AlchemySignExtendAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -/** - * - * @author JPEXS - */ -public class Sxi16Ins extends InstructionDefinition { - - public Sxi16Ins() { - super(0x52, "sxi_16", new int[]{}, false); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return 1 - 1; - } - - @Override - public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { - return 0; - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem value = stack.pop(); - stack.push(new AlchemySignExtendAVM2Item(ins, value, instructionName)); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.alchemy; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.AlchemySignExtendAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +/** + * + * @author JPEXS + */ +public class Sxi16Ins extends InstructionDefinition { + + public Sxi16Ins() { + super(0x52, "sxi_16", new int[]{}, false); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return 1 - 1; + } + + @Override + public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { + return 0; + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem value = stack.pop(); + stack.push(new AlchemySignExtendAVM2Item(ins, value, instructionName)); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/alchemy/Sxi1Ins.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/alchemy/Sxi1Ins.java index efd57b0d2..434b7e479 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/alchemy/Sxi1Ins.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/alchemy/Sxi1Ins.java @@ -1,58 +1,58 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.alchemy; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.AlchemySignExtendAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -/** - * - * @author JPEXS - */ -public class Sxi1Ins extends InstructionDefinition { - - public Sxi1Ins() { - super(0x50, "sxi_1", new int[]{}, false); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return 1 - 1; - } - - @Override - public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { - return 0; - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem value = stack.pop(); - stack.push(new AlchemySignExtendAVM2Item(ins, value, instructionName)); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.alchemy; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.AlchemySignExtendAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +/** + * + * @author JPEXS + */ +public class Sxi1Ins extends InstructionDefinition { + + public Sxi1Ins() { + super(0x50, "sxi_1", new int[]{}, false); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return 1 - 1; + } + + @Override + public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { + return 0; + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem value = stack.pop(); + stack.push(new AlchemySignExtendAVM2Item(ins, value, instructionName)); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/alchemy/Sxi8Ins.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/alchemy/Sxi8Ins.java index ec3836395..90096eafd 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/alchemy/Sxi8Ins.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/alchemy/Sxi8Ins.java @@ -1,58 +1,58 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.alchemy; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.AlchemySignExtendAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -/** - * - * @author JPEXS - */ -public class Sxi8Ins extends InstructionDefinition { - - public Sxi8Ins() { - super(0x51, "sxi_8", new int[]{}, false); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return 1 - 1; - } - - @Override - public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { - return 0; - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem value = stack.pop(); - stack.push(new AlchemySignExtendAVM2Item(ins, value, instructionName)); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.alchemy; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.AlchemySignExtendAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +/** + * + * @author JPEXS + */ +public class Sxi8Ins extends InstructionDefinition { + + public Sxi8Ins() { + super(0x51, "sxi_8", new int[]{}, false); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return 1 - 1; + } + + @Override + public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { + return 0; + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem value = stack.pop(); + stack.push(new AlchemySignExtendAVM2Item(ins, value, instructionName)); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/arithmetic/AddIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/arithmetic/AddIns.java index f9ffb4a0e..370e35076 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/arithmetic/AddIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/arithmetic/AddIns.java @@ -1,73 +1,73 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -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.model.operations.AddAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class AddIns extends InstructionDefinition { - - public AddIns() { - super(0xa0, "add", new int[]{}, true); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - Object o1 = lda.operandStack.pop(); - Object o2 = lda.operandStack.pop(); - if ((o1 instanceof Long) && ((o2 instanceof Long))) { - Long ret = ((Long) o1) + ((Long) o2); - lda.operandStack.push(ret); - } else if ((o1 instanceof Double) && ((o2 instanceof Double))) { - Double ret = ((Double) o1) + ((Double) o2); - lda.operandStack.push(ret); - } else if ((o1 instanceof Long) && ((o2 instanceof Double))) { - Double ret = ((Long) o1) + ((Double) o2); - lda.operandStack.push(ret); - } else if ((o1 instanceof Double) && ((o2 instanceof Long))) { - Double ret = ((Double) o1) + ((Long) o2); - lda.operandStack.push(ret); - } else { - String s = o1.toString() + o2.toString(); - lda.operandStack.push(s); - } - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem v2 = stack.pop(); - GraphTargetItem v1 = stack.pop(); - stack.push(new AddAVM2Item(ins, v1, v2)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -2 + 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +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.model.operations.AddAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class AddIns extends InstructionDefinition { + + public AddIns() { + super(0xa0, "add", new int[]{}, true); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + Object o1 = lda.operandStack.pop(); + Object o2 = lda.operandStack.pop(); + if ((o1 instanceof Long) && ((o2 instanceof Long))) { + Long ret = ((Long) o1) + ((Long) o2); + lda.operandStack.push(ret); + } else if ((o1 instanceof Double) && ((o2 instanceof Double))) { + Double ret = ((Double) o1) + ((Double) o2); + lda.operandStack.push(ret); + } else if ((o1 instanceof Long) && ((o2 instanceof Double))) { + Double ret = ((Long) o1) + ((Double) o2); + lda.operandStack.push(ret); + } else if ((o1 instanceof Double) && ((o2 instanceof Long))) { + Double ret = ((Double) o1) + ((Long) o2); + lda.operandStack.push(ret); + } else { + String s = o1.toString() + o2.toString(); + lda.operandStack.push(s); + } + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem v2 = stack.pop(); + GraphTargetItem v1 = stack.pop(); + stack.push(new AddAVM2Item(ins, v1, v2)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -2 + 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/arithmetic/DecrementIIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/arithmetic/DecrementIIns.java index a51bce8d8..bb9df3a8a 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/arithmetic/DecrementIIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/arithmetic/DecrementIIns.java @@ -1,67 +1,67 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -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.model.DecrementAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class DecrementIIns extends InstructionDefinition { - - public DecrementIIns() { - super(0xc1, "decrement_i", new int[]{}, true); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - Object obj = lda.operandStack.pop(); - if (obj instanceof Long) { - Long obj2 = ((Long) obj) - 1; - lda.operandStack.push(obj2); - } else if (obj instanceof Double) { - Double obj2 = ((Double) obj) - 1; - lda.operandStack.push(obj2); - } - if (obj instanceof String) { - Double obj2 = Double.parseDouble((String) obj) - 1; - lda.operandStack.push(obj2); - } else { - throw new RuntimeException("Cannot decrement local register"); - } - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - stack.push(new DecrementAVM2Item(ins, stack.pop())); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -1 + 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +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.model.DecrementAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class DecrementIIns extends InstructionDefinition { + + public DecrementIIns() { + super(0xc1, "decrement_i", new int[]{}, true); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + Object obj = lda.operandStack.pop(); + if (obj instanceof Long) { + Long obj2 = ((Long) obj) - 1; + lda.operandStack.push(obj2); + } else if (obj instanceof Double) { + Double obj2 = ((Double) obj) - 1; + lda.operandStack.push(obj2); + } + if (obj instanceof String) { + Double obj2 = Double.parseDouble((String) obj) - 1; + lda.operandStack.push(obj2); + } else { + throw new RuntimeException("Cannot decrement local register"); + } + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + stack.push(new DecrementAVM2Item(ins, stack.pop())); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -1 + 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/arithmetic/DecrementIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/arithmetic/DecrementIns.java index 4a9c30204..6f4fd7762 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/arithmetic/DecrementIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/arithmetic/DecrementIns.java @@ -1,67 +1,67 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -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.model.DecrementAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class DecrementIns extends InstructionDefinition { - - public DecrementIns() { - super(0x93, "decrement", new int[]{}, true); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - Object obj = lda.operandStack.pop(); - if (obj instanceof Long) { - Long obj2 = ((Long) obj) - 1; - lda.operandStack.push(obj2); - } else if (obj instanceof Double) { - Double obj2 = ((Double) obj) - 1; - lda.operandStack.push(obj2); - } - if (obj instanceof String) { - Double obj2 = Double.parseDouble((String) obj) - 1; - lda.operandStack.push(obj2); - } else { - throw new RuntimeException("Cannot decrement local register"); - } - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - stack.push(new DecrementAVM2Item(ins, stack.pop())); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -1 + 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +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.model.DecrementAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class DecrementIns extends InstructionDefinition { + + public DecrementIns() { + super(0x93, "decrement", new int[]{}, true); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + Object obj = lda.operandStack.pop(); + if (obj instanceof Long) { + Long obj2 = ((Long) obj) - 1; + lda.operandStack.push(obj2); + } else if (obj instanceof Double) { + Double obj2 = ((Double) obj) - 1; + lda.operandStack.push(obj2); + } + if (obj instanceof String) { + Double obj2 = Double.parseDouble((String) obj) - 1; + lda.operandStack.push(obj2); + } else { + throw new RuntimeException("Cannot decrement local register"); + } + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + stack.push(new DecrementAVM2Item(ins, stack.pop())); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -1 + 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/arithmetic/DivideIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/arithmetic/DivideIns.java index f0cb1cf9b..4245222d3 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/arithmetic/DivideIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/arithmetic/DivideIns.java @@ -1,79 +1,79 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -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.model.operations.DivideAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class DivideIns extends InstructionDefinition { - - public DivideIns() { - super(0xa3, "divide", new int[]{}, true); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - Object o2 = lda.operandStack.pop(); - Object o1 = lda.operandStack.pop(); - if ((o1 instanceof Long) && ((o2 instanceof Long))) { - Long l1 = (Long) o1; - Long l2 = (Long) o2; - if (l1 % l2 == 0) { - Long ret = l1 / l2; - lda.operandStack.push(ret); - } else { - Double ret = l1.doubleValue() / l2.doubleValue(); - lda.operandStack.push(ret); - } - } else if ((o1 instanceof Double) && ((o2 instanceof Double))) { - Double ret = ((Double) o1) / ((Double) o2); - lda.operandStack.push(ret); - } else if ((o1 instanceof Long) && ((o2 instanceof Double))) { - Double ret = ((Long) o1) / ((Double) o2); - lda.operandStack.push(ret); - } else if ((o1 instanceof Double) && ((o2 instanceof Long))) { - Double ret = ((Double) o1) / ((Long) o2); - lda.operandStack.push(ret); - } else { - throw new RuntimeException("Cannot divide"); - } - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem v2 = stack.pop(); - GraphTargetItem v1 = stack.pop(); - stack.push(new DivideAVM2Item(ins, v1, v2)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -2 + 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +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.model.operations.DivideAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class DivideIns extends InstructionDefinition { + + public DivideIns() { + super(0xa3, "divide", new int[]{}, true); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + Object o2 = lda.operandStack.pop(); + Object o1 = lda.operandStack.pop(); + if ((o1 instanceof Long) && ((o2 instanceof Long))) { + Long l1 = (Long) o1; + Long l2 = (Long) o2; + if (l1 % l2 == 0) { + Long ret = l1 / l2; + lda.operandStack.push(ret); + } else { + Double ret = l1.doubleValue() / l2.doubleValue(); + lda.operandStack.push(ret); + } + } else if ((o1 instanceof Double) && ((o2 instanceof Double))) { + Double ret = ((Double) o1) / ((Double) o2); + lda.operandStack.push(ret); + } else if ((o1 instanceof Long) && ((o2 instanceof Double))) { + Double ret = ((Long) o1) / ((Double) o2); + lda.operandStack.push(ret); + } else if ((o1 instanceof Double) && ((o2 instanceof Long))) { + Double ret = ((Double) o1) / ((Long) o2); + lda.operandStack.push(ret); + } else { + throw new RuntimeException("Cannot divide"); + } + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem v2 = stack.pop(); + GraphTargetItem v1 = stack.pop(); + stack.push(new DivideAVM2Item(ins, v1, v2)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -2 + 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/arithmetic/IncrementIIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/arithmetic/IncrementIIns.java index dc662171b..74902b342 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/arithmetic/IncrementIIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/arithmetic/IncrementIIns.java @@ -1,48 +1,48 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.IncrementAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class IncrementIIns extends InstructionDefinition { - - public IncrementIIns() { - super(0xc0, "increment_i", new int[]{}, true); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - stack.push(new IncrementAVM2Item(ins, stack.pop())); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -1 + 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.IncrementAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class IncrementIIns extends InstructionDefinition { + + public IncrementIIns() { + super(0xc0, "increment_i", new int[]{}, true); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + stack.push(new IncrementAVM2Item(ins, stack.pop())); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -1 + 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/arithmetic/IncrementIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/arithmetic/IncrementIns.java index 9dda3ac64..5a8181b5c 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/arithmetic/IncrementIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/arithmetic/IncrementIns.java @@ -1,48 +1,48 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.IncrementAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class IncrementIns extends InstructionDefinition { - - public IncrementIns() { - super(0x91, "increment", new int[]{}, true); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - stack.push(new IncrementAVM2Item(ins, stack.pop())); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -1 + 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.IncrementAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class IncrementIns extends InstructionDefinition { + + public IncrementIns() { + super(0x91, "increment", new int[]{}, true); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + stack.push(new IncrementAVM2Item(ins, stack.pop())); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -1 + 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/arithmetic/ModuloIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/arithmetic/ModuloIns.java index f9b5e5fb9..d7ce0c2a6 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/arithmetic/ModuloIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/arithmetic/ModuloIns.java @@ -1,64 +1,64 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -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.model.operations.ModuloAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class ModuloIns extends InstructionDefinition { - - public ModuloIns() { - super(0xa4, "modulo", new int[]{}, true); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - Object o1 = lda.operandStack.pop(); - Object o2 = lda.operandStack.pop(); - - if ((o1 instanceof Long) && ((o2 instanceof Long))) { - Long ret = ((Long) o2) % ((Long) o1); - lda.operandStack.push(ret); - } else { - throw new RuntimeException("Cannot modulo"); - } - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem v2 = stack.pop(); - GraphTargetItem v1 = stack.pop(); - stack.push(new ModuloAVM2Item(ins, v1, v2)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -2 + 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +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.model.operations.ModuloAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class ModuloIns extends InstructionDefinition { + + public ModuloIns() { + super(0xa4, "modulo", new int[]{}, true); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + Object o1 = lda.operandStack.pop(); + Object o2 = lda.operandStack.pop(); + + if ((o1 instanceof Long) && ((o2 instanceof Long))) { + Long ret = ((Long) o2) % ((Long) o1); + lda.operandStack.push(ret); + } else { + throw new RuntimeException("Cannot modulo"); + } + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem v2 = stack.pop(); + GraphTargetItem v1 = stack.pop(); + stack.push(new ModuloAVM2Item(ins, v1, v2)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -2 + 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/arithmetic/MultiplyIIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/arithmetic/MultiplyIIns.java index 9d2e17840..6ceb173b2 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/arithmetic/MultiplyIIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/arithmetic/MultiplyIIns.java @@ -1,50 +1,50 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.MultiplyAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class MultiplyIIns extends InstructionDefinition { - - public MultiplyIIns() { - super(0xc7, "multiply_i", new int[]{}, true); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem v2 = stack.pop(); - GraphTargetItem v1 = stack.pop(); - stack.push(new MultiplyAVM2Item(ins, v1, v2)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -2 + 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.MultiplyAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class MultiplyIIns extends InstructionDefinition { + + public MultiplyIIns() { + super(0xc7, "multiply_i", new int[]{}, true); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem v2 = stack.pop(); + GraphTargetItem v1 = stack.pop(); + stack.push(new MultiplyAVM2Item(ins, v1, v2)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -2 + 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/arithmetic/MultiplyIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/arithmetic/MultiplyIns.java index 83725febe..dca26eff1 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/arithmetic/MultiplyIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/arithmetic/MultiplyIns.java @@ -1,72 +1,72 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -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.model.operations.MultiplyAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class MultiplyIns extends InstructionDefinition { - - public MultiplyIns() { - super(0xa2, "multiply", new int[]{}, true); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - Object o1 = lda.operandStack.pop(); - Object o2 = lda.operandStack.pop(); - if ((o1 instanceof Long) && ((o2 instanceof Long))) { - Long ret = ((Long) o1) * ((Long) o2); - lda.operandStack.push(ret); - } else if ((o1 instanceof Double) && ((o2 instanceof Double))) { - Double ret = ((Double) o1) * ((Double) o2); - lda.operandStack.push(ret); - } else if ((o1 instanceof Long) && ((o2 instanceof Double))) { - Double ret = ((Long) o1) * ((Double) o2); - lda.operandStack.push(ret); - } else if ((o1 instanceof Double) && ((o2 instanceof Long))) { - Double ret = ((Double) o1) * ((Long) o2); - lda.operandStack.push(ret); - } else { - throw new RuntimeException("Cannot multiply"); - } - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem v2 = stack.pop(); - GraphTargetItem v1 = stack.pop(); - stack.push(new MultiplyAVM2Item(ins, v1, v2)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -2 + 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +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.model.operations.MultiplyAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class MultiplyIns extends InstructionDefinition { + + public MultiplyIns() { + super(0xa2, "multiply", new int[]{}, true); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + Object o1 = lda.operandStack.pop(); + Object o2 = lda.operandStack.pop(); + if ((o1 instanceof Long) && ((o2 instanceof Long))) { + Long ret = ((Long) o1) * ((Long) o2); + lda.operandStack.push(ret); + } else if ((o1 instanceof Double) && ((o2 instanceof Double))) { + Double ret = ((Double) o1) * ((Double) o2); + lda.operandStack.push(ret); + } else if ((o1 instanceof Long) && ((o2 instanceof Double))) { + Double ret = ((Long) o1) * ((Double) o2); + lda.operandStack.push(ret); + } else if ((o1 instanceof Double) && ((o2 instanceof Long))) { + Double ret = ((Double) o1) * ((Long) o2); + lda.operandStack.push(ret); + } else { + throw new RuntimeException("Cannot multiply"); + } + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem v2 = stack.pop(); + GraphTargetItem v1 = stack.pop(); + stack.push(new MultiplyAVM2Item(ins, v1, v2)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -2 + 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/arithmetic/NegateIIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/arithmetic/NegateIIns.java index bd3545d13..66e77ea7d 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/arithmetic/NegateIIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/arithmetic/NegateIIns.java @@ -1,49 +1,49 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.NegAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class NegateIIns extends InstructionDefinition { - - public NegateIIns() { - super(0xc4, "negate_i", new int[]{}, true); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem v = stack.pop(); - stack.push(new NegAVM2Item(ins, v)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -1 + 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.NegAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class NegateIIns extends InstructionDefinition { + + public NegateIIns() { + super(0xc4, "negate_i", new int[]{}, true); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem v = stack.pop(); + stack.push(new NegAVM2Item(ins, v)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -1 + 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/arithmetic/NegateIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/arithmetic/NegateIns.java index 9c171dbcf..a41983b56 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/arithmetic/NegateIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/arithmetic/NegateIns.java @@ -1,49 +1,49 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.NegAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class NegateIns extends InstructionDefinition { - - public NegateIns() { - super(0x90, "negate", new int[]{}, true); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem v = stack.pop(); - stack.push(new NegAVM2Item(ins, v)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -1 + 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.NegAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class NegateIns extends InstructionDefinition { + + public NegateIns() { + super(0x90, "negate", new int[]{}, true); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem v = stack.pop(); + stack.push(new NegAVM2Item(ins, v)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -1 + 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/arithmetic/NotIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/arithmetic/NotIns.java index 2f4a4b71a..f222a3d22 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/arithmetic/NotIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/arithmetic/NotIns.java @@ -1,49 +1,49 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import com.jpexs.decompiler.graph.model.NotItem; -import java.util.HashMap; -import java.util.List; - -public class NotIns extends InstructionDefinition { - - public NotIns() { - super(0x96, "not", new int[]{}, false); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem v = stack.pop(); - stack.push(new NotItem(ins, v)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -1 + 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import com.jpexs.decompiler.graph.model.NotItem; +import java.util.HashMap; +import java.util.List; + +public class NotIns extends InstructionDefinition { + + public NotIns() { + super(0x96, "not", new int[]{}, false); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem v = stack.pop(); + stack.push(new NotItem(ins, v)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -1 + 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/arithmetic/SubtractIIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/arithmetic/SubtractIIns.java index dadcd10b1..54fe9a4d5 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/arithmetic/SubtractIIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/arithmetic/SubtractIIns.java @@ -1,50 +1,50 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.SubtractAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class SubtractIIns extends InstructionDefinition { - - public SubtractIIns() { - super(0xc6, "subtract_i", new int[]{}, true); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem v2 = stack.pop(); - GraphTargetItem v1 = stack.pop(); - stack.push(new SubtractAVM2Item(ins, v1, v2)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -2 + 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.SubtractAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class SubtractIIns extends InstructionDefinition { + + public SubtractIIns() { + super(0xc6, "subtract_i", new int[]{}, true); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem v2 = stack.pop(); + GraphTargetItem v1 = stack.pop(); + stack.push(new SubtractAVM2Item(ins, v1, v2)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -2 + 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/arithmetic/SubtractIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/arithmetic/SubtractIns.java index 414f4da90..5fd7dde1e 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/arithmetic/SubtractIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/arithmetic/SubtractIns.java @@ -1,50 +1,50 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.SubtractAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class SubtractIns extends InstructionDefinition { - - public SubtractIns() { - super(0xa1, "subtract", new int[]{}, true); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem v2 = stack.pop(); - GraphTargetItem v1 = stack.pop(); - stack.push(new SubtractAVM2Item(ins, v1, v2)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -2 + 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.SubtractAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class SubtractIns extends InstructionDefinition { + + public SubtractIns() { + super(0xa1, "subtract", new int[]{}, true); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem v2 = stack.pop(); + GraphTargetItem v1 = stack.pop(); + stack.push(new SubtractAVM2Item(ins, v1, v2)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -2 + 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/bitwise/BitAndIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/bitwise/BitAndIns.java index 0a7af1b30..5fc241837 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/bitwise/BitAndIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/bitwise/BitAndIns.java @@ -1,59 +1,59 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.bitwise; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -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.model.operations.BitAndAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class BitAndIns extends InstructionDefinition { - - public BitAndIns() { - super(0xa8, "bitand", new int[]{}, true); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - Long value2 = (Long) lda.operandStack.pop(); - Long value1 = (Long) lda.operandStack.pop(); - Long value3 = value1 & value2; - lda.operandStack.push(value3); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem v2 = stack.pop(); - GraphTargetItem v1 = stack.pop(); - stack.push(new BitAndAVM2Item(ins, v1, v2)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -2 + 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.bitwise; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +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.model.operations.BitAndAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class BitAndIns extends InstructionDefinition { + + public BitAndIns() { + super(0xa8, "bitand", new int[]{}, true); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + Long value2 = (Long) lda.operandStack.pop(); + Long value1 = (Long) lda.operandStack.pop(); + Long value3 = value1 & value2; + lda.operandStack.push(value3); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem v2 = stack.pop(); + GraphTargetItem v1 = stack.pop(); + stack.push(new BitAndAVM2Item(ins, v1, v2)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -2 + 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/bitwise/BitNotIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/bitwise/BitNotIns.java index f0bd5fc94..845b93d4d 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/bitwise/BitNotIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/bitwise/BitNotIns.java @@ -1,57 +1,57 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.bitwise; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -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.model.operations.BitNotAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class BitNotIns extends InstructionDefinition { - - public BitNotIns() { - super(0x97, "bitnot", new int[]{}, true); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - Long value = (Long) lda.operandStack.pop(); - Long ret = -value; - lda.operandStack.push(ret); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem v = stack.pop(); - stack.push(new BitNotAVM2Item(ins, v)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -1 + 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.bitwise; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +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.model.operations.BitNotAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class BitNotIns extends InstructionDefinition { + + public BitNotIns() { + super(0x97, "bitnot", new int[]{}, true); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + Long value = (Long) lda.operandStack.pop(); + Long ret = -value; + lda.operandStack.push(ret); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem v = stack.pop(); + stack.push(new BitNotAVM2Item(ins, v)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -1 + 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/bitwise/BitOrIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/bitwise/BitOrIns.java index 7e3cbff25..e667136ed 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/bitwise/BitOrIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/bitwise/BitOrIns.java @@ -1,59 +1,59 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.bitwise; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -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.model.operations.BitOrAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class BitOrIns extends InstructionDefinition { - - public BitOrIns() { - super(0xa9, "bitor", new int[]{}, true); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - Long value2 = (Long) lda.operandStack.pop(); - Long value1 = (Long) lda.operandStack.pop(); - Long value3 = value1 | value2; - lda.operandStack.push(value3); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem v2 = stack.pop(); - GraphTargetItem v1 = stack.pop(); - stack.push(new BitOrAVM2Item(ins, v1, v2)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -2 + 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.bitwise; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +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.model.operations.BitOrAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class BitOrIns extends InstructionDefinition { + + public BitOrIns() { + super(0xa9, "bitor", new int[]{}, true); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + Long value2 = (Long) lda.operandStack.pop(); + Long value1 = (Long) lda.operandStack.pop(); + Long value3 = value1 | value2; + lda.operandStack.push(value3); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem v2 = stack.pop(); + GraphTargetItem v1 = stack.pop(); + stack.push(new BitOrAVM2Item(ins, v1, v2)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -2 + 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/bitwise/BitXorIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/bitwise/BitXorIns.java index d485f25ba..7a91b7a19 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/bitwise/BitXorIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/bitwise/BitXorIns.java @@ -1,59 +1,59 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.bitwise; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -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.model.operations.BitXorAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class BitXorIns extends InstructionDefinition { - - public BitXorIns() { - super(0xaa, "bitxor", new int[]{}, true); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - Long value2 = (Long) lda.operandStack.pop(); - Long value1 = (Long) lda.operandStack.pop(); - Long value3 = value1 ^ value2; - lda.operandStack.push(value3); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem v2 = stack.pop(); - GraphTargetItem v1 = stack.pop(); - stack.push(new BitXorAVM2Item(ins, v1, v2)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -2 + 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.bitwise; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +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.model.operations.BitXorAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class BitXorIns extends InstructionDefinition { + + public BitXorIns() { + super(0xaa, "bitxor", new int[]{}, true); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + Long value2 = (Long) lda.operandStack.pop(); + Long value1 = (Long) lda.operandStack.pop(); + Long value3 = value1 ^ value2; + lda.operandStack.push(value3); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem v2 = stack.pop(); + GraphTargetItem v1 = stack.pop(); + stack.push(new BitXorAVM2Item(ins, v1, v2)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -2 + 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/bitwise/LShiftIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/bitwise/LShiftIns.java index a24db9a1f..8147d6657 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/bitwise/LShiftIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/bitwise/LShiftIns.java @@ -1,50 +1,50 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.bitwise; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.LShiftAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class LShiftIns extends InstructionDefinition { - - public LShiftIns() { - super(0xa5, "lshift", new int[]{}, true); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem v2 = stack.pop(); - GraphTargetItem v1 = stack.pop(); - stack.push(new LShiftAVM2Item(ins, v1, v2)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -2 + 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.bitwise; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.LShiftAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class LShiftIns extends InstructionDefinition { + + public LShiftIns() { + super(0xa5, "lshift", new int[]{}, true); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem v2 = stack.pop(); + GraphTargetItem v1 = stack.pop(); + stack.push(new LShiftAVM2Item(ins, v1, v2)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -2 + 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/bitwise/RShiftIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/bitwise/RShiftIns.java index 311d7e74f..6f0d1599c 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/bitwise/RShiftIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/bitwise/RShiftIns.java @@ -1,50 +1,50 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.bitwise; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.RShiftAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class RShiftIns extends InstructionDefinition { - - public RShiftIns() { - super(0xa6, "rshift", new int[]{}, true); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem v2 = stack.pop(); - GraphTargetItem v1 = stack.pop(); - stack.push(new RShiftAVM2Item(ins, v1, v2)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -2 + 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.bitwise; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.RShiftAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class RShiftIns extends InstructionDefinition { + + public RShiftIns() { + super(0xa6, "rshift", new int[]{}, true); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem v2 = stack.pop(); + GraphTargetItem v1 = stack.pop(); + stack.push(new RShiftAVM2Item(ins, v1, v2)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -2 + 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/bitwise/URShiftIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/bitwise/URShiftIns.java index 4f5856f00..d99b30da3 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/bitwise/URShiftIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/bitwise/URShiftIns.java @@ -1,50 +1,50 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.bitwise; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.URShiftAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class URShiftIns extends InstructionDefinition { - - public URShiftIns() { - super(0xa7, "urshift", new int[]{}, true); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem v2 = stack.pop(); - GraphTargetItem v1 = stack.pop(); - stack.push(new URShiftAVM2Item(ins, v1, v2)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -2 + 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.bitwise; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.URShiftAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class URShiftIns extends InstructionDefinition { + + public URShiftIns() { + super(0xa7, "urshift", new int[]{}, true); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem v2 = stack.pop(); + GraphTargetItem v1 = stack.pop(); + stack.push(new URShiftAVM2Item(ins, v1, v2)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -2 + 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/comparison/EqualsIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/comparison/EqualsIns.java index f427e8cc5..451b64575 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/comparison/EqualsIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/comparison/EqualsIns.java @@ -1,59 +1,59 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.comparison; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -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.model.operations.EqAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class EqualsIns extends InstructionDefinition { - - public EqualsIns() { - super(0xab, "equals", new int[]{}, true); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - Object obj1 = lda.operandStack.pop(); - Object obj2 = lda.operandStack.pop(); - Boolean res = obj1.equals(obj2); - lda.operandStack.push(res); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem v2 = stack.pop(); - GraphTargetItem v1 = stack.pop(); - stack.push(new EqAVM2Item(ins, v1, v2)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -2 + 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.comparison; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +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.model.operations.EqAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class EqualsIns extends InstructionDefinition { + + public EqualsIns() { + super(0xab, "equals", new int[]{}, true); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + Object obj1 = lda.operandStack.pop(); + Object obj2 = lda.operandStack.pop(); + Boolean res = obj1.equals(obj2); + lda.operandStack.push(res); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem v2 = stack.pop(); + GraphTargetItem v1 = stack.pop(); + stack.push(new EqAVM2Item(ins, v1, v2)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -2 + 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/comparison/GreaterEqualsIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/comparison/GreaterEqualsIns.java index 1f7760c33..2c8c46446 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/comparison/GreaterEqualsIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/comparison/GreaterEqualsIns.java @@ -1,50 +1,50 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.comparison; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.GeAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class GreaterEqualsIns extends InstructionDefinition { - - public GreaterEqualsIns() { - super(0xb0, "greaterequals", new int[]{}, true); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem v2 = stack.pop(); - GraphTargetItem v1 = stack.pop(); - stack.push(new GeAVM2Item(ins, v1, v2)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -2 + 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.comparison; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.GeAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class GreaterEqualsIns extends InstructionDefinition { + + public GreaterEqualsIns() { + super(0xb0, "greaterequals", new int[]{}, true); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem v2 = stack.pop(); + GraphTargetItem v1 = stack.pop(); + stack.push(new GeAVM2Item(ins, v1, v2)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -2 + 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/comparison/GreaterThanIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/comparison/GreaterThanIns.java index 8252f2c93..10e47cc39 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/comparison/GreaterThanIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/comparison/GreaterThanIns.java @@ -1,50 +1,50 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.comparison; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.GtAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class GreaterThanIns extends InstructionDefinition { - - public GreaterThanIns() { - super(0xaf, "greaterthan", new int[]{}, true); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem v2 = stack.pop(); - GraphTargetItem v1 = stack.pop(); - stack.push(new GtAVM2Item(ins, v1, v2)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -2 + 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.comparison; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.GtAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class GreaterThanIns extends InstructionDefinition { + + public GreaterThanIns() { + super(0xaf, "greaterthan", new int[]{}, true); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem v2 = stack.pop(); + GraphTargetItem v1 = stack.pop(); + stack.push(new GtAVM2Item(ins, v1, v2)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -2 + 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/comparison/LessEqualsIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/comparison/LessEqualsIns.java index 1ed77ab08..a20b73963 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/comparison/LessEqualsIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/comparison/LessEqualsIns.java @@ -1,50 +1,50 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.comparison; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.LeAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class LessEqualsIns extends InstructionDefinition { - - public LessEqualsIns() { - super(0xae, "lessequals", new int[]{}, true); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem v2 = stack.pop(); - GraphTargetItem v1 = stack.pop(); - stack.push(new LeAVM2Item(ins, v1, v2)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -2 + 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.comparison; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.LeAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class LessEqualsIns extends InstructionDefinition { + + public LessEqualsIns() { + super(0xae, "lessequals", new int[]{}, true); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem v2 = stack.pop(); + GraphTargetItem v1 = stack.pop(); + stack.push(new LeAVM2Item(ins, v1, v2)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -2 + 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/comparison/LessThanIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/comparison/LessThanIns.java index 6b2591a27..1179dd817 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/comparison/LessThanIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/comparison/LessThanIns.java @@ -1,50 +1,50 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.comparison; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.LtAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class LessThanIns extends InstructionDefinition { - - public LessThanIns() { - super(0xad, "lessthan", new int[]{}, true); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem v2 = stack.pop(); - GraphTargetItem v1 = stack.pop(); - stack.push(new LtAVM2Item(ins, v1, v2)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -2 + 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.comparison; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.LtAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class LessThanIns extends InstructionDefinition { + + public LessThanIns() { + super(0xad, "lessthan", new int[]{}, true); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem v2 = stack.pop(); + GraphTargetItem v1 = stack.pop(); + stack.push(new LtAVM2Item(ins, v1, v2)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -2 + 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/comparison/StrictEqualsIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/comparison/StrictEqualsIns.java index bb20e54ed..989e5528d 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/comparison/StrictEqualsIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/comparison/StrictEqualsIns.java @@ -1,50 +1,50 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.comparison; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.StrictEqAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class StrictEqualsIns extends InstructionDefinition { - - public StrictEqualsIns() { - super(0xac, "strictequals", new int[]{}, true); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem v2 = stack.pop(); - GraphTargetItem v1 = stack.pop(); - stack.push(new StrictEqAVM2Item(ins, v1, v2)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -2 + 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.comparison; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.StrictEqAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class StrictEqualsIns extends InstructionDefinition { + + public StrictEqualsIns() { + super(0xac, "strictequals", new int[]{}, true); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem v2 = stack.pop(); + GraphTargetItem v1 = stack.pop(); + stack.push(new StrictEqAVM2Item(ins, v1, v2)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -2 + 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/construction/ConstructIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/construction/ConstructIns.java index a3d743050..d0fae520c 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/construction/ConstructIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/construction/ConstructIns.java @@ -1,120 +1,120 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.construction; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -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.model.ConstructAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.EscapeXAttrAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.EscapeXElemAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.FindPropertyAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.FullMultinameAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.GetLexAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.GetPropertyAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.StringAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.XMLAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.AddAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; - -public class ConstructIns extends InstructionDefinition { - - public ConstructIns() { - super(0x42, "construct", new int[]{AVM2Code.DAT_ARG_COUNT}, true); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - /*int argCount = (int) ((Long) arguments.get(0)).longValue(); - List passArguments = new ArrayList(); - for (int i = argCount - 1; i >= 0; i--) { - passArguments.set(i, lda.operandStack.pop()); - } - Object obj = lda.operandStack.pop();*/ - throw new RuntimeException("Cannot call constructor"); - //call construct property of obj - //push new instance - } - - public static boolean walkXML(GraphTargetItem item, List list) { - boolean ret = true; - if (item instanceof StringAVM2Item) { - list.add(item); - } else if (item instanceof AddAVM2Item) { - ret = ret && walkXML(((AddAVM2Item) item).leftSide, list); - ret = ret && walkXML(((AddAVM2Item) item).rightSide, list); - } else if ((item instanceof EscapeXElemAVM2Item) || (item instanceof EscapeXAttrAVM2Item)) { - list.add(item); - } else { - return false; - } - return ret; - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) throws InterruptedException { - int argCount = ins.operands[0]; - List args = new ArrayList<>(); - for (int a = 0; a < argCount; a++) { - args.add(0, stack.pop()); - } - GraphTargetItem obj = stack.pop(); - - FullMultinameAVM2Item xmlMult = null; - boolean isXML = false; - if (obj instanceof GetPropertyAVM2Item) { - GetPropertyAVM2Item gpt = (GetPropertyAVM2Item) obj; - if (gpt.object instanceof FindPropertyAVM2Item) { - FindPropertyAVM2Item fpt = (FindPropertyAVM2Item) gpt.object; - xmlMult = (FullMultinameAVM2Item) fpt.propertyName; - isXML = xmlMult.isXML(constants, localRegNames, fullyQualifiedNames) && xmlMult.isXML(constants, localRegNames, fullyQualifiedNames); - } - } - if (obj instanceof GetLexAVM2Item) { - GetLexAVM2Item glt = (GetLexAVM2Item) obj; - isXML = glt.propertyName.getName(constants, fullyQualifiedNames, true).equals("XML"); - } - - if (isXML) { - if (args.size() == 1) { - GraphTargetItem arg = args.get(0); - List xmlLines = new ArrayList<>(); - if (walkXML(arg, xmlLines)) { - stack.push(new XMLAVM2Item(ins, xmlLines)); - return; - } - } - } - - stack.push(new ConstructAVM2Item(ins, obj, args)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -ins.operands[0] - 1 + 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.construction; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +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.model.ConstructAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.EscapeXAttrAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.EscapeXElemAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.FindPropertyAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.FullMultinameAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.GetLexAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.GetPropertyAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.StringAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.XMLAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.AddAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +public class ConstructIns extends InstructionDefinition { + + public ConstructIns() { + super(0x42, "construct", new int[]{AVM2Code.DAT_ARG_COUNT}, true); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + /*int argCount = (int) ((Long) arguments.get(0)).longValue(); + List passArguments = new ArrayList(); + for (int i = argCount - 1; i >= 0; i--) { + passArguments.set(i, lda.operandStack.pop()); + } + Object obj = lda.operandStack.pop();*/ + throw new RuntimeException("Cannot call constructor"); + //call construct property of obj + //push new instance + } + + public static boolean walkXML(GraphTargetItem item, List list) { + boolean ret = true; + if (item instanceof StringAVM2Item) { + list.add(item); + } else if (item instanceof AddAVM2Item) { + ret = ret && walkXML(((AddAVM2Item) item).leftSide, list); + ret = ret && walkXML(((AddAVM2Item) item).rightSide, list); + } else if ((item instanceof EscapeXElemAVM2Item) || (item instanceof EscapeXAttrAVM2Item)) { + list.add(item); + } else { + return false; + } + return ret; + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) throws InterruptedException { + int argCount = ins.operands[0]; + List args = new ArrayList<>(); + for (int a = 0; a < argCount; a++) { + args.add(0, stack.pop()); + } + GraphTargetItem obj = stack.pop(); + + FullMultinameAVM2Item xmlMult = null; + boolean isXML = false; + if (obj instanceof GetPropertyAVM2Item) { + GetPropertyAVM2Item gpt = (GetPropertyAVM2Item) obj; + if (gpt.object instanceof FindPropertyAVM2Item) { + FindPropertyAVM2Item fpt = (FindPropertyAVM2Item) gpt.object; + xmlMult = (FullMultinameAVM2Item) fpt.propertyName; + isXML = xmlMult.isXML(constants, localRegNames, fullyQualifiedNames) && xmlMult.isXML(constants, localRegNames, fullyQualifiedNames); + } + } + if (obj instanceof GetLexAVM2Item) { + GetLexAVM2Item glt = (GetLexAVM2Item) obj; + isXML = glt.propertyName.getName(constants, fullyQualifiedNames, true).equals("XML"); + } + + if (isXML) { + if (args.size() == 1) { + GraphTargetItem arg = args.get(0); + List xmlLines = new ArrayList<>(); + if (walkXML(arg, xmlLines)) { + stack.push(new XMLAVM2Item(ins, xmlLines)); + return; + } + } + } + + stack.push(new ConstructAVM2Item(ins, obj, args)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -ins.operands[0] - 1 + 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/construction/ConstructPropIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/construction/ConstructPropIns.java index 8205f775b..e94951fd2 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/construction/ConstructPropIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/construction/ConstructPropIns.java @@ -1,95 +1,95 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.construction; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -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.model.ConstructPropAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.FullMultinameAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.XMLAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; - -public class ConstructPropIns extends InstructionDefinition { - - public ConstructPropIns() { - super(0x4a, "constructprop", new int[]{AVM2Code.DAT_MULTINAME_INDEX, AVM2Code.DAT_ARG_COUNT}, true); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - /*int multinameIndex = (int) ((Long) arguments.get(0)).longValue(); - int argCount = (int) ((Long) arguments.get(1)).longValue(); - List passArguments = new ArrayList(); - for (int i = argCount - 1; i >= 0; i--) { - passArguments.set(i, lda.operandStack.pop()); - }*/ - //if multiname[multinameIndex] is runtime - //pop(name) pop(ns) - throw new RuntimeException("Cannot construct property"); - //create property - //push new instance - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) throws InterruptedException { - int multinameIndex = ins.operands[0]; - int argCount = ins.operands[1]; - List args = new ArrayList<>(); - for (int a = 0; a < argCount; a++) { - args.add(0, stack.pop()); - } - FullMultinameAVM2Item multiname = resolveMultiname(stack, constants, multinameIndex, ins); - GraphTargetItem obj = stack.pop(); - - if (multiname.isXML(constants, localRegNames, fullyQualifiedNames)) { - if (args.size() == 1) { - GraphTargetItem arg = args.get(0); - List xmlLines = new ArrayList<>(); - if (ConstructIns.walkXML(arg, xmlLines)) { - stack.push(new XMLAVM2Item(ins, xmlLines)); - return; - } - } - } - - stack.push(new ConstructPropAVM2Item(ins, obj, multiname, args)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - int ret = -ins.operands[1] - 1 + 1; - int multinameIndex = ins.operands[0]; - if (abc.constants.getMultiname(multinameIndex).needsName()) { - ret--; - } - if (abc.constants.getMultiname(multinameIndex).needsNs()) { - ret--; - } - return ret; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.construction; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +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.model.ConstructPropAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.FullMultinameAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.XMLAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +public class ConstructPropIns extends InstructionDefinition { + + public ConstructPropIns() { + super(0x4a, "constructprop", new int[]{AVM2Code.DAT_MULTINAME_INDEX, AVM2Code.DAT_ARG_COUNT}, true); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + /*int multinameIndex = (int) ((Long) arguments.get(0)).longValue(); + int argCount = (int) ((Long) arguments.get(1)).longValue(); + List passArguments = new ArrayList(); + for (int i = argCount - 1; i >= 0; i--) { + passArguments.set(i, lda.operandStack.pop()); + }*/ + //if multiname[multinameIndex] is runtime + //pop(name) pop(ns) + throw new RuntimeException("Cannot construct property"); + //create property + //push new instance + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) throws InterruptedException { + int multinameIndex = ins.operands[0]; + int argCount = ins.operands[1]; + List args = new ArrayList<>(); + for (int a = 0; a < argCount; a++) { + args.add(0, stack.pop()); + } + FullMultinameAVM2Item multiname = resolveMultiname(stack, constants, multinameIndex, ins); + GraphTargetItem obj = stack.pop(); + + if (multiname.isXML(constants, localRegNames, fullyQualifiedNames)) { + if (args.size() == 1) { + GraphTargetItem arg = args.get(0); + List xmlLines = new ArrayList<>(); + if (ConstructIns.walkXML(arg, xmlLines)) { + stack.push(new XMLAVM2Item(ins, xmlLines)); + return; + } + } + } + + stack.push(new ConstructPropAVM2Item(ins, obj, multiname, args)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + int ret = -ins.operands[1] - 1 + 1; + int multinameIndex = ins.operands[0]; + if (abc.constants.getMultiname(multinameIndex).needsName()) { + ret--; + } + if (abc.constants.getMultiname(multinameIndex).needsNs()) { + ret--; + } + return ret; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/construction/ConstructSuperIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/construction/ConstructSuperIns.java index 793f6802a..fa678a0a7 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/construction/ConstructSuperIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/construction/ConstructSuperIns.java @@ -1,69 +1,69 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.construction; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -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.model.ConstructSuperAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; - -public class ConstructSuperIns extends InstructionDefinition { - - public ConstructSuperIns() { - super(0x49, "constructsuper", new int[]{AVM2Code.DAT_ARG_COUNT}, true); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - /*int argCount = (int) ((Long) arguments.get(0)).longValue(); - List passArguments = new ArrayList(); - for (int i = argCount - 1; i >= 0; i--) { - passArguments.set(i, lda.operandStack.pop()); - } - Object obj = lda.operandStack.pop();*/ - throw new RuntimeException("Cannot call super constructor"); - //call construct property of obj - //do not push anything - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - int argCount = ins.operands[0]; - List args = new ArrayList<>(); - for (int a = 0; a < argCount; a++) { - args.add(0, stack.pop()); - } - GraphTargetItem obj = stack.pop(); - output.add(new ConstructSuperAVM2Item(ins, obj, args)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -ins.operands[0] - 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.construction; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +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.model.ConstructSuperAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +public class ConstructSuperIns extends InstructionDefinition { + + public ConstructSuperIns() { + super(0x49, "constructsuper", new int[]{AVM2Code.DAT_ARG_COUNT}, true); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + /*int argCount = (int) ((Long) arguments.get(0)).longValue(); + List passArguments = new ArrayList(); + for (int i = argCount - 1; i >= 0; i--) { + passArguments.set(i, lda.operandStack.pop()); + } + Object obj = lda.operandStack.pop();*/ + throw new RuntimeException("Cannot call super constructor"); + //call construct property of obj + //do not push anything + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + int argCount = ins.operands[0]; + List args = new ArrayList<>(); + for (int a = 0; a < argCount; a++) { + args.add(0, stack.pop()); + } + GraphTargetItem obj = stack.pop(); + output.add(new ConstructSuperAVM2Item(ins, obj, args)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -ins.operands[0] - 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/construction/NewActivationIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/construction/NewActivationIns.java index 6ae75d69c..636bb628e 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/construction/NewActivationIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/construction/NewActivationIns.java @@ -1,48 +1,48 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.construction; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.NewActivationAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class NewActivationIns extends InstructionDefinition { - - public NewActivationIns() { - super(0x57, "newactivation", new int[]{}, true); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - stack.push(new NewActivationAVM2Item(ins)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.construction; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.NewActivationAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class NewActivationIns extends InstructionDefinition { + + public NewActivationIns() { + super(0x57, "newactivation", new int[]{}, true); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + stack.push(new NewActivationAVM2Item(ins)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/construction/NewArrayIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/construction/NewArrayIns.java index 5d4ac4d70..44444dd8e 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/construction/NewArrayIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/construction/NewArrayIns.java @@ -1,54 +1,54 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.construction; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.NewArrayAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; - -public class NewArrayIns extends InstructionDefinition { - - public NewArrayIns() { - super(0x56, "newarray", new int[]{AVM2Code.DAT_ARG_COUNT}, true); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - int argCount = ins.operands[0]; - List args = new ArrayList<>(); - for (int a = 0; a < argCount; a++) { - args.add(0, stack.pop()); - } - stack.push(new NewArrayAVM2Item(ins, args)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -ins.operands[0] + 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.construction; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.NewArrayAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +public class NewArrayIns extends InstructionDefinition { + + public NewArrayIns() { + super(0x56, "newarray", new int[]{AVM2Code.DAT_ARG_COUNT}, true); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + int argCount = ins.operands[0]; + List args = new ArrayList<>(); + for (int a = 0; a < argCount; a++) { + args.add(0, stack.pop()); + } + stack.push(new NewArrayAVM2Item(ins, args)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -ins.operands[0] + 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/construction/NewCatchIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/construction/NewCatchIns.java index f73d1fec3..d727c78b8 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/construction/NewCatchIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/construction/NewCatchIns.java @@ -1,49 +1,49 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.construction; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.clauses.ExceptionAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class NewCatchIns extends InstructionDefinition { - - public NewCatchIns() { - super(0x5a, "newcatch", new int[]{AVM2Code.DAT_EXCEPTION_INDEX}, true); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - int exInfo = ins.operands[0]; - stack.push(new ExceptionAVM2Item(body.exceptions[exInfo])); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.construction; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.clauses.ExceptionAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class NewCatchIns extends InstructionDefinition { + + public NewCatchIns() { + super(0x5a, "newcatch", new int[]{AVM2Code.DAT_EXCEPTION_INDEX}, true); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + int exInfo = ins.operands[0]; + stack.push(new ExceptionAVM2Item(body.exceptions[exInfo])); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/construction/NewClassIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/construction/NewClassIns.java index 5e668eb12..22dd00e05 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/construction/NewClassIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/construction/NewClassIns.java @@ -1,55 +1,55 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.construction; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.UnparsedAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.flash.configuration.Configuration; -import com.jpexs.decompiler.flash.helpers.HighlightedTextWriter; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import com.jpexs.decompiler.graph.model.LocalData; -import java.util.HashMap; -import java.util.List; - -public class NewClassIns extends InstructionDefinition { - - public NewClassIns() { - super(0x58, "newclass", new int[]{AVM2Code.DAT_CLASS_INDEX}, true); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) throws InterruptedException { - int clsIndex = ins.operands[0]; - HighlightedTextWriter writer = new HighlightedTextWriter(Configuration.getCodeFormatting(), false); - stack.pop().toString(writer, LocalData.create(constants, localRegNames, fullyQualifiedNames)); - String baseType = writer.toString(); - stack.push(new UnparsedAVM2Item(ins, "new " + abc.constants.getMultiname(abc.instance_info.get(clsIndex).name_index).getName(constants, fullyQualifiedNames, false) + ".class extends " + baseType)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -1 + 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.construction; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.UnparsedAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.flash.configuration.Configuration; +import com.jpexs.decompiler.flash.helpers.HighlightedTextWriter; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import com.jpexs.decompiler.graph.model.LocalData; +import java.util.HashMap; +import java.util.List; + +public class NewClassIns extends InstructionDefinition { + + public NewClassIns() { + super(0x58, "newclass", new int[]{AVM2Code.DAT_CLASS_INDEX}, true); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) throws InterruptedException { + int clsIndex = ins.operands[0]; + HighlightedTextWriter writer = new HighlightedTextWriter(Configuration.getCodeFormatting(), false); + stack.pop().toString(writer, LocalData.create(constants, localRegNames, fullyQualifiedNames)); + String baseType = writer.toString(); + stack.push(new UnparsedAVM2Item(ins, "new " + abc.constants.getMultiname(abc.instance_info.get(clsIndex).name_index).getName(constants, fullyQualifiedNames, false) + ".class extends " + baseType)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -1 + 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/construction/NewFunctionIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/construction/NewFunctionIns.java index 1e28f8c5e..24bbf94a0 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/construction/NewFunctionIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/construction/NewFunctionIns.java @@ -1,50 +1,50 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.construction; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.NewFunctionAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class NewFunctionIns extends InstructionDefinition { - - public NewFunctionIns() { - super(0x40, "newfunction", new int[]{AVM2Code.DAT_METHOD_INDEX}, true); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - int methodIndex = ins.operands[0]; - NewFunctionAVM2Item function = new NewFunctionAVM2Item(ins, "", path, isStatic, scriptIndex, classIndex, abc, fullyQualifiedNames, constants, method_info, methodIndex); - stack.push(function); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.construction; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.NewFunctionAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class NewFunctionIns extends InstructionDefinition { + + public NewFunctionIns() { + super(0x40, "newfunction", new int[]{AVM2Code.DAT_METHOD_INDEX}, true); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + int methodIndex = ins.operands[0]; + NewFunctionAVM2Item function = new NewFunctionAVM2Item(ins, "", path, isStatic, scriptIndex, classIndex, abc, fullyQualifiedNames, constants, method_info, methodIndex); + stack.push(function); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/construction/NewObjectIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/construction/NewObjectIns.java index edf2d852f..ab78700b7 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/construction/NewObjectIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/construction/NewObjectIns.java @@ -1,57 +1,57 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.construction; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.NameValuePair; -import com.jpexs.decompiler.flash.abc.avm2.model.NewObjectAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; - -public class NewObjectIns extends InstructionDefinition { - - public NewObjectIns() { - super(0x55, "newobject", new int[]{AVM2Code.DAT_ARG_COUNT}, true); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - int argCount = ins.operands[0]; - List args = new ArrayList<>(); - for (int a = 0; a < argCount; a++) { - GraphTargetItem value = stack.pop(); - GraphTargetItem name = stack.pop(); - args.add(0, new NameValuePair(name, value)); - } - stack.push(new NewObjectAVM2Item(ins, args)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -ins.operands[0] * 2 + 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.construction; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.NameValuePair; +import com.jpexs.decompiler.flash.abc.avm2.model.NewObjectAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +public class NewObjectIns extends InstructionDefinition { + + public NewObjectIns() { + super(0x55, "newobject", new int[]{AVM2Code.DAT_ARG_COUNT}, true); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + int argCount = ins.operands[0]; + List args = new ArrayList<>(); + for (int a = 0; a < argCount; a++) { + GraphTargetItem value = stack.pop(); + GraphTargetItem name = stack.pop(); + args.add(0, new NameValuePair(name, value)); + } + stack.push(new NewObjectAVM2Item(ins, args)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -ins.operands[0] * 2 + 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/debug/DebugFileIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/debug/DebugFileIns.java index 9fa629b86..02b2ff4b3 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/debug/DebugFileIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/debug/DebugFileIns.java @@ -1,34 +1,34 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.debug; - -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; -import java.util.List; - -public class DebugFileIns extends InstructionDefinition { - - public DebugFileIns() { - super(0xf1, "debugfile", new int[]{AVM2Code.DAT_STRING_INDEX}, false); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.debug; + +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; +import java.util.List; + +public class DebugFileIns extends InstructionDefinition { + + public DebugFileIns() { + super(0xf1, "debugfile", new int[]{AVM2Code.DAT_STRING_INDEX}, false); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/debug/DebugIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/debug/DebugIns.java index efe5dccd1..58fd5ffec 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/debug/DebugIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/debug/DebugIns.java @@ -1,34 +1,34 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.debug; - -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; -import java.util.List; - -public class DebugIns extends InstructionDefinition { - - public DebugIns() { - super(0xef, "debug", new int[]{AVM2Code.DAT_DEBUG_TYPE, AVM2Code.DAT_STRING_INDEX, AVM2Code.DAT_REGISTER_INDEX, AVM2Code.OPT_U30}, false); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.debug; + +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; +import java.util.List; + +public class DebugIns extends InstructionDefinition { + + public DebugIns() { + super(0xef, "debug", new int[]{AVM2Code.DAT_DEBUG_TYPE, AVM2Code.DAT_STRING_INDEX, AVM2Code.DAT_REGISTER_INDEX, AVM2Code.OPT_U30}, false); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/debug/DebugLineIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/debug/DebugLineIns.java index 865fbf900..ff97fac04 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/debug/DebugLineIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/debug/DebugLineIns.java @@ -1,34 +1,34 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.debug; - -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; -import java.util.List; - -public class DebugLineIns extends InstructionDefinition { - - public DebugLineIns() { - super(0xf0, "debugline", new int[]{AVM2Code.DAT_LINENUM}, false); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.debug; + +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; +import java.util.List; + +public class DebugLineIns extends InstructionDefinition { + + public DebugLineIns() { + super(0xf0, "debugline", new int[]{AVM2Code.DAT_LINENUM}, false); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/executing/CallIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/executing/CallIns.java index 3c90e4488..bacc44c2c 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/executing/CallIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/executing/CallIns.java @@ -1,70 +1,70 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.executing; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -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.model.CallAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; - -public class CallIns extends InstructionDefinition { - - public CallIns() { - super(0x41, "call", new int[]{AVM2Code.DAT_ARG_COUNT}, true); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - /*int argCount = (int) ((Long) arguments.get(0)).longValue(); - List passArguments = new ArrayList(); - for (int i = argCount - 1; i >= 0; i--) { - passArguments.set(i, lda.operandStack.pop()); - } - Object receiver = lda.operandStack.pop(); - Object function = lda.operandStack.pop();*/ - throw new RuntimeException("Call to unknown function"); - //push(result) - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - int argCount = ins.operands[0]; - List args = new ArrayList<>(); - for (int a = 0; a < argCount; a++) { - args.add(0, stack.pop()); - } - GraphTargetItem receiver = stack.pop(); - GraphTargetItem function = stack.pop(); - stack.push(new CallAVM2Item(ins, receiver, function, args)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -2 + 1 - ins.operands[0]; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.executing; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +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.model.CallAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +public class CallIns extends InstructionDefinition { + + public CallIns() { + super(0x41, "call", new int[]{AVM2Code.DAT_ARG_COUNT}, true); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + /*int argCount = (int) ((Long) arguments.get(0)).longValue(); + List passArguments = new ArrayList(); + for (int i = argCount - 1; i >= 0; i--) { + passArguments.set(i, lda.operandStack.pop()); + } + Object receiver = lda.operandStack.pop(); + Object function = lda.operandStack.pop();*/ + throw new RuntimeException("Call to unknown function"); + //push(result) + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + int argCount = ins.operands[0]; + List args = new ArrayList<>(); + for (int a = 0; a < argCount; a++) { + args.add(0, stack.pop()); + } + GraphTargetItem receiver = stack.pop(); + GraphTargetItem function = stack.pop(); + stack.push(new CallAVM2Item(ins, receiver, function, args)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -2 + 1 - ins.operands[0]; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/executing/CallMethodIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/executing/CallMethodIns.java index 0cf96ec1e..16c711ec7 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/executing/CallMethodIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/executing/CallMethodIns.java @@ -1,71 +1,71 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.executing; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -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.model.CallMethodAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; - -public class CallMethodIns extends InstructionDefinition { - - public CallMethodIns() { - super(0x43, "callmethod", new int[]{AVM2Code.DAT_METHOD_INDEX, AVM2Code.DAT_ARG_COUNT}, true); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - /*int methodIndex = (int) ((Long) arguments.get(0)).longValue(); //index of object's method - int argCount = (int) ((Long) arguments.get(1)).longValue(); - List passArguments = new ArrayList(); - for (int i = argCount - 1; i >= 0; i--) { - passArguments.set(i, lda.operandStack.pop()); - } - Object receiver = lda.operandStack.pop();*/ - throw new RuntimeException("Call to unknown method"); - //push(result) - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - int methodIndex = ins.operands[0]; - int argCount = ins.operands[1]; - List args = new ArrayList<>(); - for (int a = 0; a < argCount; a++) { - args.add(0, stack.pop()); - } - GraphTargetItem receiver = stack.pop(); - String methodName = method_info.get(methodIndex).getName(constants); - stack.push(new CallMethodAVM2Item(ins, receiver, methodName, args)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -1 + 1 - ins.operands[1]; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.executing; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +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.model.CallMethodAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +public class CallMethodIns extends InstructionDefinition { + + public CallMethodIns() { + super(0x43, "callmethod", new int[]{AVM2Code.DAT_METHOD_INDEX, AVM2Code.DAT_ARG_COUNT}, true); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + /*int methodIndex = (int) ((Long) arguments.get(0)).longValue(); //index of object's method + int argCount = (int) ((Long) arguments.get(1)).longValue(); + List passArguments = new ArrayList(); + for (int i = argCount - 1; i >= 0; i--) { + passArguments.set(i, lda.operandStack.pop()); + } + Object receiver = lda.operandStack.pop();*/ + throw new RuntimeException("Call to unknown method"); + //push(result) + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + int methodIndex = ins.operands[0]; + int argCount = ins.operands[1]; + List args = new ArrayList<>(); + for (int a = 0; a < argCount; a++) { + args.add(0, stack.pop()); + } + GraphTargetItem receiver = stack.pop(); + String methodName = method_info.get(methodIndex).getName(constants); + stack.push(new CallMethodAVM2Item(ins, receiver, methodName, args)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -1 + 1 - ins.operands[1]; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/executing/CallPropVoidIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/executing/CallPropVoidIns.java index 976ff7159..5a412f962 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/executing/CallPropVoidIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/executing/CallPropVoidIns.java @@ -1,86 +1,86 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.executing; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -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.model.CallPropertyAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.FullMultinameAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; - -public class CallPropVoidIns extends InstructionDefinition { - - public CallPropVoidIns() { - super(0x4f, "callpropvoid", new int[]{AVM2Code.DAT_MULTINAME_INDEX, AVM2Code.DAT_ARG_COUNT}, true); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - //same as callproperty -/* - int multinameIndex = (int) ((Long) arguments.get(0)).longValue(); - int argCount = (int) ((Long) arguments.get(1)).longValue(); - List passArguments = new ArrayList(); - for (int i = argCount - 1; i >= 0; i--) { - passArguments.set(i, lda.operandStack.pop()); - } - //if multiname[multinameIndex] is runtime - //pop(name) pop(ns) - Object obj = lda.operandStack.pop();*/ - throw new RuntimeException("Call to unknown property"); - //do not push anything - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - int multinameIndex = ins.operands[0]; - int argCount = ins.operands[1]; - List args = new ArrayList<>(); - for (int a = 0; a < argCount; a++) { - args.add(0, stack.pop()); - } - FullMultinameAVM2Item multiname = resolveMultiname(stack, constants, multinameIndex, ins); - - GraphTargetItem receiver = stack.pop(); - - output.add(new CallPropertyAVM2Item(ins, true, receiver, multiname, args)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - int ret = -ins.operands[1] - 1; - int multinameIndex = ins.operands[0]; - if (abc.constants.getMultiname(multinameIndex).needsName()) { - ret--; - } - if (abc.constants.getMultiname(multinameIndex).needsNs()) { - ret--; - } - return ret; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.executing; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +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.model.CallPropertyAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.FullMultinameAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +public class CallPropVoidIns extends InstructionDefinition { + + public CallPropVoidIns() { + super(0x4f, "callpropvoid", new int[]{AVM2Code.DAT_MULTINAME_INDEX, AVM2Code.DAT_ARG_COUNT}, true); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + //same as callproperty +/* + int multinameIndex = (int) ((Long) arguments.get(0)).longValue(); + int argCount = (int) ((Long) arguments.get(1)).longValue(); + List passArguments = new ArrayList(); + for (int i = argCount - 1; i >= 0; i--) { + passArguments.set(i, lda.operandStack.pop()); + } + //if multiname[multinameIndex] is runtime + //pop(name) pop(ns) + Object obj = lda.operandStack.pop();*/ + throw new RuntimeException("Call to unknown property"); + //do not push anything + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + int multinameIndex = ins.operands[0]; + int argCount = ins.operands[1]; + List args = new ArrayList<>(); + for (int a = 0; a < argCount; a++) { + args.add(0, stack.pop()); + } + FullMultinameAVM2Item multiname = resolveMultiname(stack, constants, multinameIndex, ins); + + GraphTargetItem receiver = stack.pop(); + + output.add(new CallPropertyAVM2Item(ins, true, receiver, multiname, args)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + int ret = -ins.operands[1] - 1; + int multinameIndex = ins.operands[0]; + if (abc.constants.getMultiname(multinameIndex).needsName()) { + ret--; + } + if (abc.constants.getMultiname(multinameIndex).needsNs()) { + ret--; + } + return ret; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/executing/CallPropertyIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/executing/CallPropertyIns.java index 8ccafbe53..70cca5917 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/executing/CallPropertyIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/executing/CallPropertyIns.java @@ -1,84 +1,84 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.executing; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -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.model.CallPropertyAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.FullMultinameAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; - -public class CallPropertyIns extends InstructionDefinition { - - public CallPropertyIns() { - super(0x46, "callproperty", new int[]{AVM2Code.DAT_MULTINAME_INDEX, AVM2Code.DAT_ARG_COUNT}, true); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - /*int multinameIndex = (int) ((Long) arguments.get(0)).longValue(); - int argCount = (int) ((Long) arguments.get(1)).longValue(); - List passArguments = new ArrayList(); - for (int i = argCount - 1; i >= 0; i--) { - passArguments.set(i, lda.operandStack.pop()); - } - //if multiname[multinameIndex] is runtime - //pop(name) pop(ns) - Object obj = lda.operandStack.pop();*/ - throw new RuntimeException("Call to unknown property"); - //push(result) - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - int multinameIndex = ins.operands[0]; - int argCount = ins.operands[1]; - List args = new ArrayList<>(); - for (int a = 0; a < argCount; a++) { - args.add(0, stack.pop()); - } - FullMultinameAVM2Item multiname = resolveMultiname(stack, constants, multinameIndex, ins); - - GraphTargetItem receiver = stack.pop(); - - stack.push(new CallPropertyAVM2Item(ins, false, receiver, multiname, args)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - int ret = -ins.operands[1] - 1 + 1; - int multinameIndex = ins.operands[0]; - if (abc.constants.getMultiname(multinameIndex).needsName()) { - ret--; - } - if (abc.constants.getMultiname(multinameIndex).needsNs()) { - ret--; - } - return ret; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.executing; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +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.model.CallPropertyAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.FullMultinameAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +public class CallPropertyIns extends InstructionDefinition { + + public CallPropertyIns() { + super(0x46, "callproperty", new int[]{AVM2Code.DAT_MULTINAME_INDEX, AVM2Code.DAT_ARG_COUNT}, true); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + /*int multinameIndex = (int) ((Long) arguments.get(0)).longValue(); + int argCount = (int) ((Long) arguments.get(1)).longValue(); + List passArguments = new ArrayList(); + for (int i = argCount - 1; i >= 0; i--) { + passArguments.set(i, lda.operandStack.pop()); + } + //if multiname[multinameIndex] is runtime + //pop(name) pop(ns) + Object obj = lda.operandStack.pop();*/ + throw new RuntimeException("Call to unknown property"); + //push(result) + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + int multinameIndex = ins.operands[0]; + int argCount = ins.operands[1]; + List args = new ArrayList<>(); + for (int a = 0; a < argCount; a++) { + args.add(0, stack.pop()); + } + FullMultinameAVM2Item multiname = resolveMultiname(stack, constants, multinameIndex, ins); + + GraphTargetItem receiver = stack.pop(); + + stack.push(new CallPropertyAVM2Item(ins, false, receiver, multiname, args)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + int ret = -ins.operands[1] - 1 + 1; + int multinameIndex = ins.operands[0]; + if (abc.constants.getMultiname(multinameIndex).needsName()) { + ret--; + } + if (abc.constants.getMultiname(multinameIndex).needsNs()) { + ret--; + } + return ret; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/executing/CallStaticIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/executing/CallStaticIns.java index 62914a3cc..8b61f33a1 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/executing/CallStaticIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/executing/CallStaticIns.java @@ -1,71 +1,71 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.executing; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -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.model.CallStaticAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; - -public class CallStaticIns extends InstructionDefinition { - - public CallStaticIns() { - super(0x44, "callstatic", new int[]{AVM2Code.DAT_METHOD_INDEX, AVM2Code.DAT_ARG_COUNT}, true); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - /*int methodIndex = (int) ((Long) arguments.get(0)).longValue(); //index of method_info - int argCount = (int) ((Long) arguments.get(1)).longValue(); - List passArguments = new ArrayList(); - for (int i = argCount - 1; i >= 0; i--) { - passArguments.set(i, lda.operandStack.pop()); - } - Object receiver = lda.operandStack.pop();*/ - throw new RuntimeException("Call to unknown static method"); - //push(result) - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - int methodIndex = ins.operands[0]; - int argCount = ins.operands[1]; - List args = new ArrayList<>(); - for (int a = 0; a < argCount; a++) { - args.add(0, stack.pop()); - } - GraphTargetItem receiver = stack.pop(); - String methodName = method_info.get(methodIndex).getName(constants); - stack.push(new CallStaticAVM2Item(ins, receiver, methodName, args)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -1 + 1 - ins.operands[1]; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.executing; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +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.model.CallStaticAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +public class CallStaticIns extends InstructionDefinition { + + public CallStaticIns() { + super(0x44, "callstatic", new int[]{AVM2Code.DAT_METHOD_INDEX, AVM2Code.DAT_ARG_COUNT}, true); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + /*int methodIndex = (int) ((Long) arguments.get(0)).longValue(); //index of method_info + int argCount = (int) ((Long) arguments.get(1)).longValue(); + List passArguments = new ArrayList(); + for (int i = argCount - 1; i >= 0; i--) { + passArguments.set(i, lda.operandStack.pop()); + } + Object receiver = lda.operandStack.pop();*/ + throw new RuntimeException("Call to unknown static method"); + //push(result) + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + int methodIndex = ins.operands[0]; + int argCount = ins.operands[1]; + List args = new ArrayList<>(); + for (int a = 0; a < argCount; a++) { + args.add(0, stack.pop()); + } + GraphTargetItem receiver = stack.pop(); + String methodName = method_info.get(methodIndex).getName(constants); + stack.push(new CallStaticAVM2Item(ins, receiver, methodName, args)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -1 + 1 - ins.operands[1]; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/executing/CallSuperIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/executing/CallSuperIns.java index c39408c3a..fba3915b9 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/executing/CallSuperIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/executing/CallSuperIns.java @@ -1,83 +1,83 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.executing; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -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.model.CallSuperAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.FullMultinameAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; - -public class CallSuperIns extends InstructionDefinition { - - public CallSuperIns() { - super(0x45, "callsuper", new int[]{AVM2Code.DAT_MULTINAME_INDEX, AVM2Code.DAT_ARG_COUNT}, true); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - /*int multinameIndex = (int) ((Long) arguments.get(0)).longValue(); - int argCount = (int) ((Long) arguments.get(1)).longValue(); - List passArguments = new ArrayList(); - for (int i = argCount - 1; i >= 0; i--) { - passArguments.set(i, lda.operandStack.pop()); - } - //if multiname[multinameIndex] is runtime - //pop(name) pop(ns) - Object receiver = lda.operandStack.pop();*/ - throw new RuntimeException("Call to unknown super method"); - //push(result) - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - int multinameIndex = ins.operands[0]; - int argCount = ins.operands[1]; - List args = new ArrayList<>(); - for (int a = 0; a < argCount; a++) { - args.add(0, stack.pop()); - } - FullMultinameAVM2Item multiname = resolveMultiname(stack, constants, multinameIndex, ins); - GraphTargetItem receiver = stack.pop(); - - stack.push(new CallSuperAVM2Item(ins, false, receiver, multiname, args)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - int ret = -ins.operands[1] - 1 + 1; - int multinameIndex = ins.operands[0]; - if (abc.constants.getMultiname(multinameIndex).needsName()) { - ret--; - } - if (abc.constants.getMultiname(multinameIndex).needsNs()) { - ret--; - } - return ret; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.executing; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +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.model.CallSuperAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.FullMultinameAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +public class CallSuperIns extends InstructionDefinition { + + public CallSuperIns() { + super(0x45, "callsuper", new int[]{AVM2Code.DAT_MULTINAME_INDEX, AVM2Code.DAT_ARG_COUNT}, true); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + /*int multinameIndex = (int) ((Long) arguments.get(0)).longValue(); + int argCount = (int) ((Long) arguments.get(1)).longValue(); + List passArguments = new ArrayList(); + for (int i = argCount - 1; i >= 0; i--) { + passArguments.set(i, lda.operandStack.pop()); + } + //if multiname[multinameIndex] is runtime + //pop(name) pop(ns) + Object receiver = lda.operandStack.pop();*/ + throw new RuntimeException("Call to unknown super method"); + //push(result) + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + int multinameIndex = ins.operands[0]; + int argCount = ins.operands[1]; + List args = new ArrayList<>(); + for (int a = 0; a < argCount; a++) { + args.add(0, stack.pop()); + } + FullMultinameAVM2Item multiname = resolveMultiname(stack, constants, multinameIndex, ins); + GraphTargetItem receiver = stack.pop(); + + stack.push(new CallSuperAVM2Item(ins, false, receiver, multiname, args)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + int ret = -ins.operands[1] - 1 + 1; + int multinameIndex = ins.operands[0]; + if (abc.constants.getMultiname(multinameIndex).needsName()) { + ret--; + } + if (abc.constants.getMultiname(multinameIndex).needsNs()) { + ret--; + } + return ret; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/executing/CallSuperVoidIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/executing/CallSuperVoidIns.java index 0001065e9..3954b3c35 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/executing/CallSuperVoidIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/executing/CallSuperVoidIns.java @@ -1,84 +1,84 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.executing; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -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.model.CallSuperAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.FullMultinameAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; - -public class CallSuperVoidIns extends InstructionDefinition { - - public CallSuperVoidIns() { - super(0x4e, "callsupervoid", new int[]{AVM2Code.DAT_MULTINAME_INDEX, AVM2Code.DAT_ARG_COUNT}, true); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - /*int multinameIndex = (int) ((Long) arguments.get(0)).longValue(); - int argCount = (int) ((Long) arguments.get(1)).longValue(); - List passArguments = new ArrayList(); - for (int i = argCount - 1; i >= 0; i--) { - passArguments.set(i, lda.operandStack.pop()); - } - //if multiname[multinameIndex] is runtime - //pop(name) pop(ns) - Object receiver = lda.operandStack.pop();*/ - throw new RuntimeException("Call to unknown super method"); - //do not push anything - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - int multinameIndex = ins.operands[0]; - int argCount = ins.operands[1]; - List args = new ArrayList<>(); - for (int a = 0; a < argCount; a++) { - args.add(0, stack.pop()); - } - FullMultinameAVM2Item multiname = resolveMultiname(stack, constants, multinameIndex, ins); - GraphTargetItem receiver = stack.pop(); - - output.add(new CallSuperAVM2Item(ins, true, receiver, multiname, args)); - - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - int ret = -ins.operands[1] - 1; - int multinameIndex = ins.operands[0]; - if (abc.constants.getMultiname(multinameIndex).needsName()) { - ret--; - } - if (abc.constants.getMultiname(multinameIndex).needsNs()) { - ret--; - } - return ret; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.executing; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +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.model.CallSuperAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.FullMultinameAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +public class CallSuperVoidIns extends InstructionDefinition { + + public CallSuperVoidIns() { + super(0x4e, "callsupervoid", new int[]{AVM2Code.DAT_MULTINAME_INDEX, AVM2Code.DAT_ARG_COUNT}, true); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + /*int multinameIndex = (int) ((Long) arguments.get(0)).longValue(); + int argCount = (int) ((Long) arguments.get(1)).longValue(); + List passArguments = new ArrayList(); + for (int i = argCount - 1; i >= 0; i--) { + passArguments.set(i, lda.operandStack.pop()); + } + //if multiname[multinameIndex] is runtime + //pop(name) pop(ns) + Object receiver = lda.operandStack.pop();*/ + throw new RuntimeException("Call to unknown super method"); + //do not push anything + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + int multinameIndex = ins.operands[0]; + int argCount = ins.operands[1]; + List args = new ArrayList<>(); + for (int a = 0; a < argCount; a++) { + args.add(0, stack.pop()); + } + FullMultinameAVM2Item multiname = resolveMultiname(stack, constants, multinameIndex, ins); + GraphTargetItem receiver = stack.pop(); + + output.add(new CallSuperAVM2Item(ins, true, receiver, multiname, args)); + + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + int ret = -ins.operands[1] - 1; + int multinameIndex = ins.operands[0]; + if (abc.constants.getMultiname(multinameIndex).needsName()) { + ret--; + } + if (abc.constants.getMultiname(multinameIndex).needsNs()) { + ret--; + } + return ret; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/IfEqIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/IfEqIns.java index 7555ae3c0..19270bbd7 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/IfEqIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/IfEqIns.java @@ -1,59 +1,59 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.jumps; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.IfTypeIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.EqAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.NeqAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class IfEqIns extends InstructionDefinition implements IfTypeIns { - - public IfEqIns() { - super(0x13, "ifeq", new int[]{AVM2Code.DAT_OFFSET}, true); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem v2 = stack.pop(); - GraphTargetItem v1 = stack.pop(); - stack.push(new EqAVM2Item(ins, v1, v2)); - } - - @Override - public void translateInverted(HashMap localRegs, TranslateStack stack, AVM2Instruction ins) { - GraphTargetItem v2 = stack.pop(); - GraphTargetItem v1 = stack.pop(); - stack.push(new NeqAVM2Item(ins, v1, v2)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -2; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.jumps; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.IfTypeIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.EqAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.NeqAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class IfEqIns extends InstructionDefinition implements IfTypeIns { + + public IfEqIns() { + super(0x13, "ifeq", new int[]{AVM2Code.DAT_OFFSET}, true); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem v2 = stack.pop(); + GraphTargetItem v1 = stack.pop(); + stack.push(new EqAVM2Item(ins, v1, v2)); + } + + @Override + public void translateInverted(HashMap localRegs, TranslateStack stack, AVM2Instruction ins) { + GraphTargetItem v2 = stack.pop(); + GraphTargetItem v1 = stack.pop(); + stack.push(new NeqAVM2Item(ins, v1, v2)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -2; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/IfFalseIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/IfFalseIns.java index aaaa0f492..1ac54af7a 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/IfFalseIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/IfFalseIns.java @@ -1,56 +1,56 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.jumps; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.IfTypeIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import com.jpexs.decompiler.graph.model.NotItem; -import java.util.HashMap; -import java.util.List; - -public class IfFalseIns extends InstructionDefinition implements IfTypeIns { - - public IfFalseIns() { - super(0x12, "iffalse", new int[]{AVM2Code.DAT_OFFSET}, false); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem v1 = stack.pop(); - stack.push(new NotItem(ins, v1)); - } - - @Override - public void translateInverted(HashMap localRegs, TranslateStack stack, AVM2Instruction ins) { - //String v1 = stack.pop().toString(); - //stack.push("(" + v1 + ")"); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.jumps; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.IfTypeIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import com.jpexs.decompiler.graph.model.NotItem; +import java.util.HashMap; +import java.util.List; + +public class IfFalseIns extends InstructionDefinition implements IfTypeIns { + + public IfFalseIns() { + super(0x12, "iffalse", new int[]{AVM2Code.DAT_OFFSET}, false); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem v1 = stack.pop(); + stack.push(new NotItem(ins, v1)); + } + + @Override + public void translateInverted(HashMap localRegs, TranslateStack stack, AVM2Instruction ins) { + //String v1 = stack.pop().toString(); + //stack.push("(" + v1 + ")"); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/IfGeIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/IfGeIns.java index 9363dabbb..b978d60bf 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/IfGeIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/IfGeIns.java @@ -1,59 +1,59 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.jumps; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.IfTypeIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.GeAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.LtAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class IfGeIns extends InstructionDefinition implements IfTypeIns { - - public IfGeIns() { - super(0x18, "ifge", new int[]{AVM2Code.DAT_OFFSET}, true); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem v2 = stack.pop(); - GraphTargetItem v1 = stack.pop(); - stack.push(new GeAVM2Item(ins, v1, v2)); - } - - @Override - public void translateInverted(HashMap localRegs, TranslateStack stack, AVM2Instruction ins) { - GraphTargetItem v2 = stack.pop(); - GraphTargetItem v1 = stack.pop(); - stack.push(new LtAVM2Item(ins, v1, v2)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -2; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.jumps; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.IfTypeIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.GeAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.LtAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class IfGeIns extends InstructionDefinition implements IfTypeIns { + + public IfGeIns() { + super(0x18, "ifge", new int[]{AVM2Code.DAT_OFFSET}, true); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem v2 = stack.pop(); + GraphTargetItem v1 = stack.pop(); + stack.push(new GeAVM2Item(ins, v1, v2)); + } + + @Override + public void translateInverted(HashMap localRegs, TranslateStack stack, AVM2Instruction ins) { + GraphTargetItem v2 = stack.pop(); + GraphTargetItem v1 = stack.pop(); + stack.push(new LtAVM2Item(ins, v1, v2)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -2; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/IfGtIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/IfGtIns.java index 580cb8e16..34757b10c 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/IfGtIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/IfGtIns.java @@ -1,59 +1,59 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.jumps; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.IfTypeIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.GtAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.LeAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class IfGtIns extends InstructionDefinition implements IfTypeIns { - - public IfGtIns() { - super(0x17, "ifgt", new int[]{AVM2Code.DAT_OFFSET}, true); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem v2 = stack.pop(); - GraphTargetItem v1 = stack.pop(); - stack.push(new GtAVM2Item(ins, v1, v2)); - } - - @Override - public void translateInverted(HashMap localRegs, TranslateStack stack, AVM2Instruction ins) { - GraphTargetItem v2 = stack.pop(); - GraphTargetItem v1 = stack.pop(); - stack.push(new LeAVM2Item(ins, v1, v2)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -2; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.jumps; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.IfTypeIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.GtAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.LeAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class IfGtIns extends InstructionDefinition implements IfTypeIns { + + public IfGtIns() { + super(0x17, "ifgt", new int[]{AVM2Code.DAT_OFFSET}, true); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem v2 = stack.pop(); + GraphTargetItem v1 = stack.pop(); + stack.push(new GtAVM2Item(ins, v1, v2)); + } + + @Override + public void translateInverted(HashMap localRegs, TranslateStack stack, AVM2Instruction ins) { + GraphTargetItem v2 = stack.pop(); + GraphTargetItem v1 = stack.pop(); + stack.push(new LeAVM2Item(ins, v1, v2)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -2; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/IfLeIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/IfLeIns.java index acd3cb081..3132a8467 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/IfLeIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/IfLeIns.java @@ -1,59 +1,59 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.jumps; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.IfTypeIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.GtAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.LeAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class IfLeIns extends InstructionDefinition implements IfTypeIns { - - public IfLeIns() { - super(0x16, "ifle", new int[]{AVM2Code.DAT_OFFSET}, true); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem v2 = stack.pop(); - GraphTargetItem v1 = stack.pop(); - stack.push(new LeAVM2Item(ins, v1, v2)); - } - - @Override - public void translateInverted(HashMap localRegs, TranslateStack stack, AVM2Instruction ins) { - GraphTargetItem v2 = stack.pop(); - GraphTargetItem v1 = stack.pop(); - stack.push(new GtAVM2Item(ins, v1, v2)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -2; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.jumps; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.IfTypeIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.GtAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.LeAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class IfLeIns extends InstructionDefinition implements IfTypeIns { + + public IfLeIns() { + super(0x16, "ifle", new int[]{AVM2Code.DAT_OFFSET}, true); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem v2 = stack.pop(); + GraphTargetItem v1 = stack.pop(); + stack.push(new LeAVM2Item(ins, v1, v2)); + } + + @Override + public void translateInverted(HashMap localRegs, TranslateStack stack, AVM2Instruction ins) { + GraphTargetItem v2 = stack.pop(); + GraphTargetItem v1 = stack.pop(); + stack.push(new GtAVM2Item(ins, v1, v2)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -2; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/IfLtIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/IfLtIns.java index 5da79aadb..385bda7e2 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/IfLtIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/IfLtIns.java @@ -1,59 +1,59 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.jumps; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.IfTypeIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.GeAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.LtAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class IfLtIns extends InstructionDefinition implements IfTypeIns { - - public IfLtIns() { - super(0x15, "iflt", new int[]{AVM2Code.DAT_OFFSET}, true); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem v2 = stack.pop(); - GraphTargetItem v1 = stack.pop(); - stack.push(new LtAVM2Item(ins, v1, v2)); - } - - @Override - public void translateInverted(HashMap localRegs, TranslateStack stack, AVM2Instruction ins) { - GraphTargetItem v2 = stack.pop(); - GraphTargetItem v1 = stack.pop(); - stack.push(new GeAVM2Item(ins, v1, v2)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -2; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.jumps; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.IfTypeIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.GeAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.LtAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class IfLtIns extends InstructionDefinition implements IfTypeIns { + + public IfLtIns() { + super(0x15, "iflt", new int[]{AVM2Code.DAT_OFFSET}, true); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem v2 = stack.pop(); + GraphTargetItem v1 = stack.pop(); + stack.push(new LtAVM2Item(ins, v1, v2)); + } + + @Override + public void translateInverted(HashMap localRegs, TranslateStack stack, AVM2Instruction ins) { + GraphTargetItem v2 = stack.pop(); + GraphTargetItem v1 = stack.pop(); + stack.push(new GeAVM2Item(ins, v1, v2)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -2; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/IfNGeIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/IfNGeIns.java index 834f0244e..9bde31453 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/IfNGeIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/IfNGeIns.java @@ -1,59 +1,59 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.jumps; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.IfTypeIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.GeAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.LtAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class IfNGeIns extends InstructionDefinition implements IfTypeIns { - - public IfNGeIns() { - super(0x0f, "ifnge", new int[]{AVM2Code.DAT_OFFSET}, true); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem v2 = stack.pop(); - GraphTargetItem v1 = stack.pop(); - stack.push(new LtAVM2Item(ins, v1, v2)); - } - - @Override - public void translateInverted(HashMap localRegs, TranslateStack stack, AVM2Instruction ins) { - GraphTargetItem v2 = stack.pop(); - GraphTargetItem v1 = stack.pop(); - stack.push(new GeAVM2Item(ins, v1, v2)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -2; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.jumps; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.IfTypeIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.GeAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.LtAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class IfNGeIns extends InstructionDefinition implements IfTypeIns { + + public IfNGeIns() { + super(0x0f, "ifnge", new int[]{AVM2Code.DAT_OFFSET}, true); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem v2 = stack.pop(); + GraphTargetItem v1 = stack.pop(); + stack.push(new LtAVM2Item(ins, v1, v2)); + } + + @Override + public void translateInverted(HashMap localRegs, TranslateStack stack, AVM2Instruction ins) { + GraphTargetItem v2 = stack.pop(); + GraphTargetItem v1 = stack.pop(); + stack.push(new GeAVM2Item(ins, v1, v2)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -2; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/IfNGtIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/IfNGtIns.java index d049a6e55..2c21ffb1c 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/IfNGtIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/IfNGtIns.java @@ -1,59 +1,59 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.jumps; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.IfTypeIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.GtAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.LeAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class IfNGtIns extends InstructionDefinition implements IfTypeIns { - - public IfNGtIns() { - super(0x0e, "ifngt", new int[]{AVM2Code.DAT_OFFSET}, true); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem v2 = stack.pop(); - GraphTargetItem v1 = stack.pop(); - stack.push(new LeAVM2Item(ins, v1, v2)); - } - - @Override - public void translateInverted(HashMap localRegs, TranslateStack stack, AVM2Instruction ins) { - GraphTargetItem v2 = stack.pop(); - GraphTargetItem v1 = stack.pop(); - stack.push(new GtAVM2Item(ins, v1, v2)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -2; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.jumps; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.IfTypeIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.GtAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.LeAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class IfNGtIns extends InstructionDefinition implements IfTypeIns { + + public IfNGtIns() { + super(0x0e, "ifngt", new int[]{AVM2Code.DAT_OFFSET}, true); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem v2 = stack.pop(); + GraphTargetItem v1 = stack.pop(); + stack.push(new LeAVM2Item(ins, v1, v2)); + } + + @Override + public void translateInverted(HashMap localRegs, TranslateStack stack, AVM2Instruction ins) { + GraphTargetItem v2 = stack.pop(); + GraphTargetItem v1 = stack.pop(); + stack.push(new GtAVM2Item(ins, v1, v2)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -2; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/IfNLeIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/IfNLeIns.java index 41677a62e..be7eebb5b 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/IfNLeIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/IfNLeIns.java @@ -1,59 +1,59 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.jumps; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.IfTypeIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.GtAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.LeAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class IfNLeIns extends InstructionDefinition implements IfTypeIns { - - public IfNLeIns() { - super(0x0d, "ifnle", new int[]{AVM2Code.DAT_OFFSET}, true); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem v2 = stack.pop(); - GraphTargetItem v1 = stack.pop(); - stack.push(new GtAVM2Item(ins, v1, v2)); - } - - @Override - public void translateInverted(HashMap localRegs, TranslateStack stack, AVM2Instruction ins) { - GraphTargetItem v2 = stack.pop(); - GraphTargetItem v1 = stack.pop(); - stack.push(new LeAVM2Item(ins, v1, v2)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -2; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.jumps; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.IfTypeIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.GtAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.LeAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class IfNLeIns extends InstructionDefinition implements IfTypeIns { + + public IfNLeIns() { + super(0x0d, "ifnle", new int[]{AVM2Code.DAT_OFFSET}, true); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem v2 = stack.pop(); + GraphTargetItem v1 = stack.pop(); + stack.push(new GtAVM2Item(ins, v1, v2)); + } + + @Override + public void translateInverted(HashMap localRegs, TranslateStack stack, AVM2Instruction ins) { + GraphTargetItem v2 = stack.pop(); + GraphTargetItem v1 = stack.pop(); + stack.push(new LeAVM2Item(ins, v1, v2)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -2; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/IfNLtIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/IfNLtIns.java index 726f87bc4..95aee7be9 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/IfNLtIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/IfNLtIns.java @@ -1,59 +1,59 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.jumps; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.IfTypeIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.GeAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.LtAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class IfNLtIns extends InstructionDefinition implements IfTypeIns { - - public IfNLtIns() { - super(0x0c, "ifnlt", new int[]{AVM2Code.DAT_OFFSET}, true); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem v2 = stack.pop(); - GraphTargetItem v1 = stack.pop(); - stack.push(new GeAVM2Item(ins, v1, v2)); - } - - @Override - public void translateInverted(HashMap localRegs, TranslateStack stack, AVM2Instruction ins) { - GraphTargetItem v2 = stack.pop(); - GraphTargetItem v1 = stack.pop(); - stack.push(new LtAVM2Item(ins, v1, v2)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -2; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.jumps; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.IfTypeIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.GeAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.LtAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class IfNLtIns extends InstructionDefinition implements IfTypeIns { + + public IfNLtIns() { + super(0x0c, "ifnlt", new int[]{AVM2Code.DAT_OFFSET}, true); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem v2 = stack.pop(); + GraphTargetItem v1 = stack.pop(); + stack.push(new GeAVM2Item(ins, v1, v2)); + } + + @Override + public void translateInverted(HashMap localRegs, TranslateStack stack, AVM2Instruction ins) { + GraphTargetItem v2 = stack.pop(); + GraphTargetItem v1 = stack.pop(); + stack.push(new LtAVM2Item(ins, v1, v2)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -2; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/IfNeIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/IfNeIns.java index a13657215..d5249357d 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/IfNeIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/IfNeIns.java @@ -1,59 +1,59 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.jumps; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.IfTypeIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.EqAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.NeqAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class IfNeIns extends InstructionDefinition implements IfTypeIns { - - public IfNeIns() { - super(0x14, "ifne", new int[]{AVM2Code.DAT_OFFSET}, true); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem v2 = stack.pop(); - GraphTargetItem v1 = stack.pop(); - stack.push(new NeqAVM2Item(ins, v1, v2)); - } - - @Override - public void translateInverted(HashMap localRegs, TranslateStack stack, AVM2Instruction ins) { - GraphTargetItem v2 = stack.pop(); - GraphTargetItem v1 = stack.pop(); - stack.push(new EqAVM2Item(ins, v1, v2)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -2; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.jumps; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.IfTypeIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.EqAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.NeqAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class IfNeIns extends InstructionDefinition implements IfTypeIns { + + public IfNeIns() { + super(0x14, "ifne", new int[]{AVM2Code.DAT_OFFSET}, true); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem v2 = stack.pop(); + GraphTargetItem v1 = stack.pop(); + stack.push(new NeqAVM2Item(ins, v1, v2)); + } + + @Override + public void translateInverted(HashMap localRegs, TranslateStack stack, AVM2Instruction ins) { + GraphTargetItem v2 = stack.pop(); + GraphTargetItem v1 = stack.pop(); + stack.push(new EqAVM2Item(ins, v1, v2)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -2; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/IfStrictEqIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/IfStrictEqIns.java index fc53f4fca..fa3cd08c8 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/IfStrictEqIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/IfStrictEqIns.java @@ -1,59 +1,59 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.jumps; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.IfTypeIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.StrictEqAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.StrictNeqAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class IfStrictEqIns extends InstructionDefinition implements IfTypeIns { - - public IfStrictEqIns() { - super(0x19, "ifstricteq", new int[]{AVM2Code.DAT_OFFSET}, false); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem v2 = stack.pop(); - GraphTargetItem v1 = stack.pop(); - stack.push(new StrictEqAVM2Item(ins, v1, v2)); - } - - @Override - public void translateInverted(HashMap localRegs, TranslateStack stack, AVM2Instruction ins) { - GraphTargetItem v2 = stack.pop(); - GraphTargetItem v1 = stack.pop(); - stack.push(new StrictNeqAVM2Item(ins, v1, v2)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -2; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.jumps; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.IfTypeIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.StrictEqAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.StrictNeqAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class IfStrictEqIns extends InstructionDefinition implements IfTypeIns { + + public IfStrictEqIns() { + super(0x19, "ifstricteq", new int[]{AVM2Code.DAT_OFFSET}, false); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem v2 = stack.pop(); + GraphTargetItem v1 = stack.pop(); + stack.push(new StrictEqAVM2Item(ins, v1, v2)); + } + + @Override + public void translateInverted(HashMap localRegs, TranslateStack stack, AVM2Instruction ins) { + GraphTargetItem v2 = stack.pop(); + GraphTargetItem v1 = stack.pop(); + stack.push(new StrictNeqAVM2Item(ins, v1, v2)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -2; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/IfStrictNeIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/IfStrictNeIns.java index 48cc96fce..9985a4e1b 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/IfStrictNeIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/IfStrictNeIns.java @@ -1,59 +1,59 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.jumps; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.IfTypeIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.StrictEqAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.StrictNeqAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class IfStrictNeIns extends InstructionDefinition implements IfTypeIns { - - public IfStrictNeIns() { - super(0x1A, "ifstrictne", new int[]{AVM2Code.DAT_OFFSET}, false); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem v2 = stack.pop(); - GraphTargetItem v1 = stack.pop(); - stack.push(new StrictNeqAVM2Item(ins, v1, v2)); - } - - @Override - public void translateInverted(HashMap localRegs, TranslateStack stack, AVM2Instruction ins) { - GraphTargetItem v2 = stack.pop(); - GraphTargetItem v1 = stack.pop(); - stack.push(new StrictEqAVM2Item(ins, v1, v2)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -2; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.jumps; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.IfTypeIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.StrictEqAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.StrictNeqAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class IfStrictNeIns extends InstructionDefinition implements IfTypeIns { + + public IfStrictNeIns() { + super(0x1A, "ifstrictne", new int[]{AVM2Code.DAT_OFFSET}, false); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem v2 = stack.pop(); + GraphTargetItem v1 = stack.pop(); + stack.push(new StrictNeqAVM2Item(ins, v1, v2)); + } + + @Override + public void translateInverted(HashMap localRegs, TranslateStack stack, AVM2Instruction ins) { + GraphTargetItem v2 = stack.pop(); + GraphTargetItem v1 = stack.pop(); + stack.push(new StrictEqAVM2Item(ins, v1, v2)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -2; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/IfTrueIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/IfTrueIns.java index c71bbae50..8f61976f0 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/IfTrueIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/IfTrueIns.java @@ -1,56 +1,56 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.jumps; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.IfTypeIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import com.jpexs.decompiler.graph.model.NotItem; -import java.util.HashMap; -import java.util.List; - -public class IfTrueIns extends InstructionDefinition implements IfTypeIns { - - public IfTrueIns() { - super(0x11, "iftrue", new int[]{AVM2Code.DAT_OFFSET}, false); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - //String v1 = stack.pop().toString(); - //stack.push("(" + v1 + ")"); - } - - @Override - public void translateInverted(HashMap localRegs, TranslateStack stack, AVM2Instruction ins) { - GraphTargetItem v1 = stack.pop(); - stack.push(new NotItem(ins, v1)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.jumps; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.IfTypeIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import com.jpexs.decompiler.graph.model.NotItem; +import java.util.HashMap; +import java.util.List; + +public class IfTrueIns extends InstructionDefinition implements IfTypeIns { + + public IfTrueIns() { + super(0x11, "iftrue", new int[]{AVM2Code.DAT_OFFSET}, false); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + //String v1 = stack.pop().toString(); + //stack.push("(" + v1 + ")"); + } + + @Override + public void translateInverted(HashMap localRegs, TranslateStack stack, AVM2Instruction ins) { + GraphTargetItem v1 = stack.pop(); + stack.push(new NotItem(ins, v1)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/JumpIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/JumpIns.java index 104990550..e82be3350 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/JumpIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/JumpIns.java @@ -1,47 +1,47 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.jumps; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.IfTypeIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class JumpIns extends InstructionDefinition implements IfTypeIns { - - public JumpIns() { - super(0x10, "jump", new int[]{AVM2Code.DAT_OFFSET}, false); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - //stack.push(new BooleanAVM2Item(ins, Boolean.TRUE));// + ins.operands[0]); - } - - @Override - public void translateInverted(HashMap localRegs, TranslateStack stack, AVM2Instruction ins) { - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.jumps; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.IfTypeIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class JumpIns extends InstructionDefinition implements IfTypeIns { + + public JumpIns() { + super(0x10, "jump", new int[]{AVM2Code.DAT_OFFSET}, false); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + //stack.push(new BooleanAVM2Item(ins, Boolean.TRUE));// + ins.operands[0]); + } + + @Override + public void translateInverted(HashMap localRegs, TranslateStack stack, AVM2Instruction ins) { + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/LookupSwitchIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/LookupSwitchIns.java index e9c961682..05fcd98ff 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/LookupSwitchIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/jumps/LookupSwitchIns.java @@ -1,49 +1,49 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.jumps; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class LookupSwitchIns extends InstructionDefinition { - - public LookupSwitchIns() { - super(0x1b, "lookupswitch", new int[]{AVM2Code.DAT_CASE_BASEOFFSET, AVM2Code.OPT_CASE_OFFSETS}, false); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - //int defaultOffset = ins.operands[0]; - //int caseCount = ins.operands[1]; - //stack.push("switch(...)"); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.jumps; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class LookupSwitchIns extends InstructionDefinition { + + public LookupSwitchIns() { + super(0x1b, "lookupswitch", new int[]{AVM2Code.DAT_CASE_BASEOFFSET, AVM2Code.OPT_CASE_OFFSETS}, false); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + //int defaultOffset = ins.operands[0]; + //int caseCount = ins.operands[1]; + //stack.push("switch(...)"); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/DecLocalIIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/DecLocalIIns.java index 5b5751176..fc81e4d90 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/DecLocalIIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/DecLocalIIns.java @@ -1,76 +1,76 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.localregs; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -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.model.DecLocalAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.IntegerValueAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.SubtractAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class DecLocalIIns extends InstructionDefinition { - - public DecLocalIIns() { - super(0xc3, "declocal_i", new int[]{AVM2Code.DAT_LOCAL_REG_INDEX}, true); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - int locRegIndex = (int) ((Long) arguments.get(0)).longValue(); - Object obj = lda.localRegisters.get(locRegIndex); - if (obj instanceof Long) { - Long obj2 = ((Long) obj) - 1; - lda.localRegisters.put(locRegIndex, obj2); - } else if (obj instanceof Double) { - Double obj2 = ((Double) obj) - 1; - lda.localRegisters.put(locRegIndex, obj2); - } - if (obj instanceof String) { - Double obj2 = Double.parseDouble((String) obj) - 1; - lda.localRegisters.put(locRegIndex, obj2); - } else { - throw new RuntimeException("Cannot decrement local register"); - } - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap regAssignCount, int ip, HashMap> refs, AVM2Code code) { - int regId = ins.operands[0]; - output.add(new DecLocalAVM2Item(ins, regId)); - if (localRegs.containsKey(regId)) { - localRegs.put(regId, new SubtractAVM2Item(ins, localRegs.get(regId), new IntegerValueAVM2Item(ins, 1L))); - } else { - //localRegs.put(regIndex, new SubtractAVM2Item(ins, new IntegerValueAVM2Item(ins, new Long(0)), new IntegerValueAVM2Item(ins, new Long(1)))); - } - if (!regAssignCount.containsKey(regId)) { - regAssignCount.put(regId, 0); - } - regAssignCount.put(regId, regAssignCount.get(regId) + 1); - - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.localregs; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +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.model.DecLocalAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.IntegerValueAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.SubtractAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class DecLocalIIns extends InstructionDefinition { + + public DecLocalIIns() { + super(0xc3, "declocal_i", new int[]{AVM2Code.DAT_LOCAL_REG_INDEX}, true); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + int locRegIndex = (int) ((Long) arguments.get(0)).longValue(); + Object obj = lda.localRegisters.get(locRegIndex); + if (obj instanceof Long) { + Long obj2 = ((Long) obj) - 1; + lda.localRegisters.put(locRegIndex, obj2); + } else if (obj instanceof Double) { + Double obj2 = ((Double) obj) - 1; + lda.localRegisters.put(locRegIndex, obj2); + } + if (obj instanceof String) { + Double obj2 = Double.parseDouble((String) obj) - 1; + lda.localRegisters.put(locRegIndex, obj2); + } else { + throw new RuntimeException("Cannot decrement local register"); + } + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap regAssignCount, int ip, HashMap> refs, AVM2Code code) { + int regId = ins.operands[0]; + output.add(new DecLocalAVM2Item(ins, regId)); + if (localRegs.containsKey(regId)) { + localRegs.put(regId, new SubtractAVM2Item(ins, localRegs.get(regId), new IntegerValueAVM2Item(ins, 1L))); + } else { + //localRegs.put(regIndex, new SubtractAVM2Item(ins, new IntegerValueAVM2Item(ins, new Long(0)), new IntegerValueAVM2Item(ins, new Long(1)))); + } + if (!regAssignCount.containsKey(regId)) { + regAssignCount.put(regId, 0); + } + regAssignCount.put(regId, regAssignCount.get(regId) + 1); + + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/DecLocalIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/DecLocalIns.java index 5ee042dd3..13aaad5ed 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/DecLocalIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/DecLocalIns.java @@ -1,75 +1,75 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.localregs; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -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.model.DecLocalAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.IntegerValueAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.SubtractAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class DecLocalIns extends InstructionDefinition { - - public DecLocalIns() { - super(0x94, "declocal", new int[]{AVM2Code.DAT_LOCAL_REG_INDEX}, true); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - int locRegIndex = (int) ((Long) arguments.get(0)).longValue(); - Object obj = lda.localRegisters.get(locRegIndex); - if (obj instanceof Long) { - Long obj2 = ((Long) obj) - 1; - lda.localRegisters.put(locRegIndex, obj2); - } else if (obj instanceof Double) { - Double obj2 = ((Double) obj) - 1; - lda.localRegisters.put(locRegIndex, obj2); - } - if (obj instanceof String) { - Double obj2 = Double.parseDouble((String) obj) - 1; - lda.localRegisters.put(locRegIndex, obj2); - } else { - throw new RuntimeException("Cannot decrement local register"); - } - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap regAssignCount, int ip, HashMap> refs, AVM2Code code) { - int regId = ins.operands[0]; - output.add(new DecLocalAVM2Item(ins, regId)); - if (localRegs.containsKey(regId)) { - localRegs.put(regId, new SubtractAVM2Item(ins, localRegs.get(regId), new IntegerValueAVM2Item(ins, 1L))); - } else { - //localRegs.put(regIndex, new SubtractAVM2Item(ins, new IntegerValueAVM2Item(ins, new Long(0)), new IntegerValueAVM2Item(ins, new Long(1)))); - } - if (!regAssignCount.containsKey(regId)) { - regAssignCount.put(regId, 0); - } - regAssignCount.put(regId, regAssignCount.get(regId) + 1); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.localregs; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +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.model.DecLocalAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.IntegerValueAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.SubtractAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class DecLocalIns extends InstructionDefinition { + + public DecLocalIns() { + super(0x94, "declocal", new int[]{AVM2Code.DAT_LOCAL_REG_INDEX}, true); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + int locRegIndex = (int) ((Long) arguments.get(0)).longValue(); + Object obj = lda.localRegisters.get(locRegIndex); + if (obj instanceof Long) { + Long obj2 = ((Long) obj) - 1; + lda.localRegisters.put(locRegIndex, obj2); + } else if (obj instanceof Double) { + Double obj2 = ((Double) obj) - 1; + lda.localRegisters.put(locRegIndex, obj2); + } + if (obj instanceof String) { + Double obj2 = Double.parseDouble((String) obj) - 1; + lda.localRegisters.put(locRegIndex, obj2); + } else { + throw new RuntimeException("Cannot decrement local register"); + } + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap regAssignCount, int ip, HashMap> refs, AVM2Code code) { + int regId = ins.operands[0]; + output.add(new DecLocalAVM2Item(ins, regId)); + if (localRegs.containsKey(regId)) { + localRegs.put(regId, new SubtractAVM2Item(ins, localRegs.get(regId), new IntegerValueAVM2Item(ins, 1L))); + } else { + //localRegs.put(regIndex, new SubtractAVM2Item(ins, new IntegerValueAVM2Item(ins, new Long(0)), new IntegerValueAVM2Item(ins, new Long(1)))); + } + if (!regAssignCount.containsKey(regId)) { + regAssignCount.put(regId, 0); + } + regAssignCount.put(regId, regAssignCount.get(regId) + 1); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/GetLocal0Ins.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/GetLocal0Ins.java index 33ec50c82..e233b65ac 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/GetLocal0Ins.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/GetLocal0Ins.java @@ -1,39 +1,39 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.localregs; - -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; -import java.util.List; - -public class GetLocal0Ins extends GetLocalTypeIns { - - public GetLocal0Ins() { - super(0xd0, "getlocal_0", new int[]{}, false); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - lda.operandStack.push(lda.localRegisters.get(0)); - } - - @Override - public int getRegisterId(AVM2Instruction par0) { - return 0; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.localregs; + +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; +import java.util.List; + +public class GetLocal0Ins extends GetLocalTypeIns { + + public GetLocal0Ins() { + super(0xd0, "getlocal_0", new int[]{}, false); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + lda.operandStack.push(lda.localRegisters.get(0)); + } + + @Override + public int getRegisterId(AVM2Instruction par0) { + return 0; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/GetLocal1Ins.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/GetLocal1Ins.java index fd7d447e0..a969ca3f6 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/GetLocal1Ins.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/GetLocal1Ins.java @@ -1,39 +1,39 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.localregs; - -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; -import java.util.List; - -public class GetLocal1Ins extends GetLocalTypeIns { - - public GetLocal1Ins() { - super(0xd1, "getlocal_1", new int[]{}, false); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - lda.operandStack.push(lda.localRegisters.get(1)); - } - - @Override - public int getRegisterId(AVM2Instruction par0) { - return 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.localregs; + +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; +import java.util.List; + +public class GetLocal1Ins extends GetLocalTypeIns { + + public GetLocal1Ins() { + super(0xd1, "getlocal_1", new int[]{}, false); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + lda.operandStack.push(lda.localRegisters.get(1)); + } + + @Override + public int getRegisterId(AVM2Instruction par0) { + return 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/GetLocal2Ins.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/GetLocal2Ins.java index d2d34a85f..41b9aae32 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/GetLocal2Ins.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/GetLocal2Ins.java @@ -1,39 +1,39 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.localregs; - -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; -import java.util.List; - -public class GetLocal2Ins extends GetLocalTypeIns { - - public GetLocal2Ins() { - super(0xd2, "getlocal_2", new int[]{}, false); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - lda.operandStack.push(lda.localRegisters.get(2)); - } - - @Override - public int getRegisterId(AVM2Instruction par0) { - return 2; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.localregs; + +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; +import java.util.List; + +public class GetLocal2Ins extends GetLocalTypeIns { + + public GetLocal2Ins() { + super(0xd2, "getlocal_2", new int[]{}, false); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + lda.operandStack.push(lda.localRegisters.get(2)); + } + + @Override + public int getRegisterId(AVM2Instruction par0) { + return 2; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/GetLocal3Ins.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/GetLocal3Ins.java index 118d1636e..edafb3d08 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/GetLocal3Ins.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/GetLocal3Ins.java @@ -1,39 +1,39 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.localregs; - -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; -import java.util.List; - -public class GetLocal3Ins extends GetLocalTypeIns { - - public GetLocal3Ins() { - super(0xd3, "getlocal_3", new int[]{}, false); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - lda.operandStack.push(lda.localRegisters.get(3)); - } - - @Override - public int getRegisterId(AVM2Instruction par0) { - return 3; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.localregs; + +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; +import java.util.List; + +public class GetLocal3Ins extends GetLocalTypeIns { + + public GetLocal3Ins() { + super(0xd3, "getlocal_3", new int[]{}, false); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + lda.operandStack.push(lda.localRegisters.get(3)); + } + + @Override + public int getRegisterId(AVM2Instruction par0) { + return 3; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/GetLocalIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/GetLocalIns.java index 879888422..f7bfce8ee 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/GetLocalIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/GetLocalIns.java @@ -1,40 +1,40 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.localregs; - -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; -import java.util.List; - -public class GetLocalIns extends GetLocalTypeIns { - - public GetLocalIns() { - super(0x62, "getlocal", new int[]{AVM2Code.DAT_LOCAL_REG_INDEX}, false); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - lda.operandStack.push(lda.localRegisters.get((int) (long) (Long) arguments.get(0))); - } - - @Override - public int getRegisterId(AVM2Instruction ins) { - return ins.operands[0]; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.localregs; + +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; +import java.util.List; + +public class GetLocalIns extends GetLocalTypeIns { + + public GetLocalIns() { + super(0x62, "getlocal", new int[]{AVM2Code.DAT_LOCAL_REG_INDEX}, false); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + lda.operandStack.push(lda.localRegisters.get((int) (long) (Long) arguments.get(0))); + } + + @Override + public int getRegisterId(AVM2Instruction ins) { + return ins.operands[0]; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/GetLocalTypeIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/GetLocalTypeIns.java index 9d509cbda..9e6cd9a63 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/GetLocalTypeIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/GetLocalTypeIns.java @@ -1,86 +1,86 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.localregs; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.ClassAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.LocalRegAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.ScriptAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.ThisAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.NotCompileTimeItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public abstract class GetLocalTypeIns extends InstructionDefinition { - - public GetLocalTypeIns(int instructionCode, String instructionName, int[] operands, boolean canThrow) { - super(instructionCode, instructionName, operands, canThrow); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap regAssignCount, int ip, HashMap> refs, AVM2Code code) { - - int regId = getRegisterId(ins); - - if (regId == 0) { - if ((classIndex >= abc.instance_info.size()) || classIndex < 0) { - stack.push(new ScriptAVM2Item(scriptIndex)); - return; - } - if (isStatic) { - stack.push(new ClassAVM2Item(abc.instance_info.get(classIndex).getName(constants))); - } else { - stack.push(new ThisAVM2Item(ins, abc.instance_info.get(classIndex).getName(constants))); - } - return; - } - - GraphTargetItem computedValue = localRegs.get(regId); - int assignCount = 0; - if (regAssignCount.containsKey(regId)) { - assignCount = regAssignCount.get(regId); - } - if (assignCount > 5) { //Do not allow change register more than 5 - for deobfuscation - computedValue = new NotCompileTimeItem(ins, computedValue); - } - /*if (!isRegisterCompileTime(regId, ip, refs, code)) { - computedValue = new NotCompileTimeAVM2Item(ins, computedValue); - } - if (computedValue == null) { - if (!localRegNames.containsKey(regId)) { - computedValue = new UndefinedAVM2Item(null); //In some obfuscated code there seems to be reading of undefined registers - } - }*/ - stack.push(new LocalRegAVM2Item(ins, regId, computedValue)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return 1; - } - - public abstract int getRegisterId(AVM2Instruction ins); -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.localregs; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.ClassAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.LocalRegAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.ScriptAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.ThisAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.NotCompileTimeItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public abstract class GetLocalTypeIns extends InstructionDefinition { + + public GetLocalTypeIns(int instructionCode, String instructionName, int[] operands, boolean canThrow) { + super(instructionCode, instructionName, operands, canThrow); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap regAssignCount, int ip, HashMap> refs, AVM2Code code) { + + int regId = getRegisterId(ins); + + if (regId == 0) { + if ((classIndex >= abc.instance_info.size()) || classIndex < 0) { + stack.push(new ScriptAVM2Item(scriptIndex)); + return; + } + if (isStatic) { + stack.push(new ClassAVM2Item(abc.instance_info.get(classIndex).getName(constants))); + } else { + stack.push(new ThisAVM2Item(ins, abc.instance_info.get(classIndex).getName(constants))); + } + return; + } + + GraphTargetItem computedValue = localRegs.get(regId); + int assignCount = 0; + if (regAssignCount.containsKey(regId)) { + assignCount = regAssignCount.get(regId); + } + if (assignCount > 5) { //Do not allow change register more than 5 - for deobfuscation + computedValue = new NotCompileTimeItem(ins, computedValue); + } + /*if (!isRegisterCompileTime(regId, ip, refs, code)) { + computedValue = new NotCompileTimeAVM2Item(ins, computedValue); + } + if (computedValue == null) { + if (!localRegNames.containsKey(regId)) { + computedValue = new UndefinedAVM2Item(null); //In some obfuscated code there seems to be reading of undefined registers + } + }*/ + stack.push(new LocalRegAVM2Item(ins, regId, computedValue)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return 1; + } + + public abstract int getRegisterId(AVM2Instruction ins); +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/IncLocalIIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/IncLocalIIns.java index c29a0b176..ddba14b2e 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/IncLocalIIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/IncLocalIIns.java @@ -1,55 +1,55 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.localregs; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.IncLocalAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.IntegerValueAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.AddAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class IncLocalIIns extends InstructionDefinition { - - public IncLocalIIns() { - super(0xc2, "inclocal_i", new int[]{AVM2Code.DAT_LOCAL_REG_INDEX}, true); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap regAssignCount, int ip, HashMap> refs, AVM2Code code) { - int regId = ins.operands[0]; - output.add(new IncLocalAVM2Item(ins, regId)); - if (localRegs.containsKey(regId)) { - localRegs.put(regId, new AddAVM2Item(ins, localRegs.get(regId), new IntegerValueAVM2Item(ins, 1L))); - } else { - //localRegs.put(regIndex, new AddAVM2Item(ins, null, new IntegerValueAVM2Item(ins, new Long(1)))); - } - if (!regAssignCount.containsKey(regId)) { - regAssignCount.put(regId, 0); - } - regAssignCount.put(regId, regAssignCount.get(regId) + 1); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.localregs; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.IncLocalAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.IntegerValueAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.AddAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class IncLocalIIns extends InstructionDefinition { + + public IncLocalIIns() { + super(0xc2, "inclocal_i", new int[]{AVM2Code.DAT_LOCAL_REG_INDEX}, true); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap regAssignCount, int ip, HashMap> refs, AVM2Code code) { + int regId = ins.operands[0]; + output.add(new IncLocalAVM2Item(ins, regId)); + if (localRegs.containsKey(regId)) { + localRegs.put(regId, new AddAVM2Item(ins, localRegs.get(regId), new IntegerValueAVM2Item(ins, 1L))); + } else { + //localRegs.put(regIndex, new AddAVM2Item(ins, null, new IntegerValueAVM2Item(ins, new Long(1)))); + } + if (!regAssignCount.containsKey(regId)) { + regAssignCount.put(regId, 0); + } + regAssignCount.put(regId, regAssignCount.get(regId) + 1); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/IncLocalIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/IncLocalIns.java index 03c595d74..525e6e64b 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/IncLocalIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/IncLocalIns.java @@ -1,55 +1,55 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.localregs; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.IncLocalAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.IntegerValueAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.AddAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class IncLocalIns extends InstructionDefinition { - - public IncLocalIns() { - super(0x92, "inclocal", new int[]{AVM2Code.DAT_LOCAL_REG_INDEX}, true); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap regAssignCount, int ip, HashMap> refs, AVM2Code code) { - int regId = ins.operands[0]; - output.add(new IncLocalAVM2Item(ins, regId)); - if (localRegs.containsKey(regId)) { - localRegs.put(regId, new AddAVM2Item(ins, localRegs.get(regId), new IntegerValueAVM2Item(ins, 1L))); - } else { - //localRegs.put(regIndex, new AddAVM2Item(ins, null, new IntegerValueAVM2Item(ins, new Long(1)))); - } - if (!regAssignCount.containsKey(regId)) { - regAssignCount.put(regId, 0); - } - regAssignCount.put(regId, regAssignCount.get(regId) + 1); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.localregs; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.IncLocalAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.IntegerValueAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.AddAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class IncLocalIns extends InstructionDefinition { + + public IncLocalIns() { + super(0x92, "inclocal", new int[]{AVM2Code.DAT_LOCAL_REG_INDEX}, true); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap regAssignCount, int ip, HashMap> refs, AVM2Code code) { + int regId = ins.operands[0]; + output.add(new IncLocalAVM2Item(ins, regId)); + if (localRegs.containsKey(regId)) { + localRegs.put(regId, new AddAVM2Item(ins, localRegs.get(regId), new IntegerValueAVM2Item(ins, 1L))); + } else { + //localRegs.put(regIndex, new AddAVM2Item(ins, null, new IntegerValueAVM2Item(ins, new Long(1)))); + } + if (!regAssignCount.containsKey(regId)) { + regAssignCount.put(regId, 0); + } + regAssignCount.put(regId, regAssignCount.get(regId) + 1); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/KillIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/KillIns.java index fbcf9e6c4..c6f9d1985 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/KillIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/KillIns.java @@ -1,42 +1,42 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.localregs; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class KillIns extends InstructionDefinition { - - public KillIns() { - super(0x08, "kill", new int[]{AVM2Code.DAT_LOCAL_REG_INDEX}, false); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - //kill local register - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.localregs; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class KillIns extends InstructionDefinition { + + public KillIns() { + super(0x08, "kill", new int[]{AVM2Code.DAT_LOCAL_REG_INDEX}, false); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + //kill local register + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/SetLocal0Ins.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/SetLocal0Ins.java index 1cb1cffb4..0bb3baed7 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/SetLocal0Ins.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/SetLocal0Ins.java @@ -1,31 +1,31 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.localregs; - -import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; - -public class SetLocal0Ins extends SetLocalTypeIns { - - public SetLocal0Ins() { - super(0xd4, "setlocal_0", new int[]{}, false); - } - - @Override - public int getRegisterId(AVM2Instruction ins) { - return 0; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.localregs; + +import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; + +public class SetLocal0Ins extends SetLocalTypeIns { + + public SetLocal0Ins() { + super(0xd4, "setlocal_0", new int[]{}, false); + } + + @Override + public int getRegisterId(AVM2Instruction ins) { + return 0; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/SetLocal1Ins.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/SetLocal1Ins.java index 6a9e5365b..30121df8e 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/SetLocal1Ins.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/SetLocal1Ins.java @@ -1,31 +1,31 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.localregs; - -import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; - -public class SetLocal1Ins extends SetLocalTypeIns { - - public SetLocal1Ins() { - super(0xd5, "setlocal_1", new int[]{}, false); - } - - @Override - public int getRegisterId(AVM2Instruction ins) { - return 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.localregs; + +import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; + +public class SetLocal1Ins extends SetLocalTypeIns { + + public SetLocal1Ins() { + super(0xd5, "setlocal_1", new int[]{}, false); + } + + @Override + public int getRegisterId(AVM2Instruction ins) { + return 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/SetLocal2Ins.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/SetLocal2Ins.java index 4dd930b98..68d508216 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/SetLocal2Ins.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/SetLocal2Ins.java @@ -1,31 +1,31 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.localregs; - -import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; - -public class SetLocal2Ins extends SetLocalTypeIns { - - public SetLocal2Ins() { - super(0xd6, "setlocal_2", new int[]{}, false); - } - - @Override - public int getRegisterId(AVM2Instruction ins) { - return 2; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.localregs; + +import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; + +public class SetLocal2Ins extends SetLocalTypeIns { + + public SetLocal2Ins() { + super(0xd6, "setlocal_2", new int[]{}, false); + } + + @Override + public int getRegisterId(AVM2Instruction ins) { + return 2; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/SetLocal3Ins.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/SetLocal3Ins.java index 28a1f8da2..87975cb76 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/SetLocal3Ins.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/SetLocal3Ins.java @@ -1,31 +1,31 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.localregs; - -import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; - -public class SetLocal3Ins extends SetLocalTypeIns { - - public SetLocal3Ins() { - super(0xd7, "setlocal_3", new int[]{}, false); - } - - @Override - public int getRegisterId(AVM2Instruction ins) { - return 3; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.localregs; + +import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; + +public class SetLocal3Ins extends SetLocalTypeIns { + + public SetLocal3Ins() { + super(0xd7, "setlocal_3", new int[]{}, false); + } + + @Override + public int getRegisterId(AVM2Instruction ins) { + return 3; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/SetLocalIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/SetLocalIns.java index f3c25a753..e01d3c122 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/SetLocalIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/SetLocalIns.java @@ -1,32 +1,32 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.localregs; - -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; - -public class SetLocalIns extends SetLocalTypeIns { - - public SetLocalIns() { - super(0x63, "setlocal", new int[]{AVM2Code.DAT_LOCAL_REG_INDEX}, false); - } - - @Override - public int getRegisterId(AVM2Instruction ins) { - return ins.operands[0]; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.localregs; + +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; + +public class SetLocalIns extends SetLocalTypeIns { + + public SetLocalIns() { + super(0x63, "setlocal", new int[]{AVM2Code.DAT_LOCAL_REG_INDEX}, false); + } + + @Override + public int getRegisterId(AVM2Instruction ins) { + return ins.operands[0]; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/SetLocalTypeIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/SetLocalTypeIns.java index e5be575d4..973dcde54 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/SetLocalTypeIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/SetLocalTypeIns.java @@ -1,134 +1,134 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.localregs; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.instructions.SetTypeIns; -import com.jpexs.decompiler.flash.abc.avm2.model.AVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.DecrementAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.FindPropertyAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.IncrementAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.LocalRegAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.NewActivationAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.PostDecrementAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.PostIncrementAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.SetLocalAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.PreDecrementAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.PreIncrementAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; -import java.util.Stack; - -public abstract class SetLocalTypeIns extends InstructionDefinition implements SetTypeIns { - - public SetLocalTypeIns(int instructionCode, String instructionName, int[] operands, boolean canThrow) { - super(instructionCode, instructionName, operands, canThrow); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap regAssignCount, int ip, HashMap> refs, AVM2Code code) { - int regId = getRegisterId(ins); - GraphTargetItem value = stack.pop(); - /*if (localRegs.containsKey(regId)) { - localRegs.put(regId, new NotCompileTimeAVM2Item(ins, value)); - } else { - localRegs.put(regId, value); - }*/ - localRegs.put(regId, value); - if (!regAssignCount.containsKey(regId)) { - regAssignCount.put(regId, 0); - } - regAssignCount.put(regId, regAssignCount.get(regId) + 1); - //localRegsAssignmentIps.put(regId, ip); - if (value instanceof NewActivationAVM2Item) { - return; - } - if (value instanceof FindPropertyAVM2Item) { - return; - } - if (value.getNotCoerced() instanceof IncrementAVM2Item) { - GraphTargetItem inside = ((IncrementAVM2Item) value.getNotCoerced()).value.getNotCoerced().getThroughDuplicate(); - if (inside instanceof LocalRegAVM2Item) { - if (((LocalRegAVM2Item) inside).regIndex == regId) { - if (stack.size() > 0) { - GraphTargetItem top = stack.peek().getNotCoerced().getThroughDuplicate(); - if (top == inside) { - stack.pop(); - stack.push(new PostIncrementAVM2Item(ins, inside)); - } else if ((top instanceof IncrementAVM2Item) && (((IncrementAVM2Item) top).value == inside)) { - stack.pop(); - stack.push(new PreIncrementAVM2Item(ins, inside)); - } else { - output.add(new PostIncrementAVM2Item(ins, inside)); - } - } else { - output.add(new PostIncrementAVM2Item(ins, inside)); - } - return; - } - } - } - - if (value.getNotCoerced() instanceof DecrementAVM2Item) { - GraphTargetItem inside = ((DecrementAVM2Item) value.getNotCoerced()).value.getNotCoerced().getThroughDuplicate(); - if (inside instanceof LocalRegAVM2Item) { - if (((LocalRegAVM2Item) inside).regIndex == regId) { - if (stack.size() > 0) { - GraphTargetItem top = stack.peek().getNotCoerced().getThroughDuplicate(); - if (top == inside) { - stack.pop(); - stack.push(new PostDecrementAVM2Item(ins, inside)); - } else if ((top instanceof DecrementAVM2Item) && (((DecrementAVM2Item) top).value == inside)) { - stack.pop(); - stack.push(new PreDecrementAVM2Item(ins, inside)); - } else { - output.add(new PostDecrementAVM2Item(ins, inside)); - } - } else { - output.add(new PostDecrementAVM2Item(ins, inside)); - } - return; - } - } - } - - //if(val.startsWith("catchscope ")) return; - //if(val.startsWith("newactivation()")) return; - output.add(new SetLocalAVM2Item(ins, regId, value)); - } - - @Override - public String getObject(Stack stack, ABC abc, AVM2Instruction ins, List output, MethodBody body, HashMap localRegNames, List fullyQualifiedNames) { - return AVM2Item.localRegName(localRegNames, getRegisterId(ins)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -1; - } - - public abstract int getRegisterId(AVM2Instruction ins); -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.localregs; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.instructions.SetTypeIns; +import com.jpexs.decompiler.flash.abc.avm2.model.AVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.DecrementAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.FindPropertyAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.IncrementAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.LocalRegAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.NewActivationAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.PostDecrementAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.PostIncrementAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.SetLocalAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.PreDecrementAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.PreIncrementAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; +import java.util.Stack; + +public abstract class SetLocalTypeIns extends InstructionDefinition implements SetTypeIns { + + public SetLocalTypeIns(int instructionCode, String instructionName, int[] operands, boolean canThrow) { + super(instructionCode, instructionName, operands, canThrow); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap regAssignCount, int ip, HashMap> refs, AVM2Code code) { + int regId = getRegisterId(ins); + GraphTargetItem value = stack.pop(); + /*if (localRegs.containsKey(regId)) { + localRegs.put(regId, new NotCompileTimeAVM2Item(ins, value)); + } else { + localRegs.put(regId, value); + }*/ + localRegs.put(regId, value); + if (!regAssignCount.containsKey(regId)) { + regAssignCount.put(regId, 0); + } + regAssignCount.put(regId, regAssignCount.get(regId) + 1); + //localRegsAssignmentIps.put(regId, ip); + if (value instanceof NewActivationAVM2Item) { + return; + } + if (value instanceof FindPropertyAVM2Item) { + return; + } + if (value.getNotCoerced() instanceof IncrementAVM2Item) { + GraphTargetItem inside = ((IncrementAVM2Item) value.getNotCoerced()).value.getNotCoerced().getThroughDuplicate(); + if (inside instanceof LocalRegAVM2Item) { + if (((LocalRegAVM2Item) inside).regIndex == regId) { + if (stack.size() > 0) { + GraphTargetItem top = stack.peek().getNotCoerced().getThroughDuplicate(); + if (top == inside) { + stack.pop(); + stack.push(new PostIncrementAVM2Item(ins, inside)); + } else if ((top instanceof IncrementAVM2Item) && (((IncrementAVM2Item) top).value == inside)) { + stack.pop(); + stack.push(new PreIncrementAVM2Item(ins, inside)); + } else { + output.add(new PostIncrementAVM2Item(ins, inside)); + } + } else { + output.add(new PostIncrementAVM2Item(ins, inside)); + } + return; + } + } + } + + if (value.getNotCoerced() instanceof DecrementAVM2Item) { + GraphTargetItem inside = ((DecrementAVM2Item) value.getNotCoerced()).value.getNotCoerced().getThroughDuplicate(); + if (inside instanceof LocalRegAVM2Item) { + if (((LocalRegAVM2Item) inside).regIndex == regId) { + if (stack.size() > 0) { + GraphTargetItem top = stack.peek().getNotCoerced().getThroughDuplicate(); + if (top == inside) { + stack.pop(); + stack.push(new PostDecrementAVM2Item(ins, inside)); + } else if ((top instanceof DecrementAVM2Item) && (((DecrementAVM2Item) top).value == inside)) { + stack.pop(); + stack.push(new PreDecrementAVM2Item(ins, inside)); + } else { + output.add(new PostDecrementAVM2Item(ins, inside)); + } + } else { + output.add(new PostDecrementAVM2Item(ins, inside)); + } + return; + } + } + } + + //if(val.startsWith("catchscope ")) return; + //if(val.startsWith("newactivation()")) return; + output.add(new SetLocalAVM2Item(ins, regId, value)); + } + + @Override + public String getObject(Stack stack, ABC abc, AVM2Instruction ins, List output, MethodBody body, HashMap localRegNames, List fullyQualifiedNames) { + return AVM2Item.localRegName(localRegNames, getRegisterId(ins)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -1; + } + + public abstract int getRegisterId(AVM2Instruction ins); +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/DeletePropertyIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/DeletePropertyIns.java index 85e5eb47c..aa4cf8829 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/DeletePropertyIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/DeletePropertyIns.java @@ -1,74 +1,74 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -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.model.BooleanAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.FullMultinameAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.DeletePropertyAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class DeletePropertyIns extends InstructionDefinition { - - public DeletePropertyIns() { - super(0x6a, "deleteproperty", new int[]{AVM2Code.DAT_MULTINAME_INDEX}, true); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - /*int multiIndex = (int) ((Long) arguments.get(0)).longValue(); - //if multiname[multinameIndex] is runtime - //pop(name) pop(ns) - Object obj = lda.operandStack.pop(); - //push true if removed*/ - throw new RuntimeException("Cannot remove property"); - - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - int multinameIndex = ins.operands[0]; - FullMultinameAVM2Item multiname = resolveMultiname(stack, constants, multinameIndex, ins); - GraphTargetItem obj = stack.pop(); - stack.add(new BooleanAVM2Item(ins, Boolean.TRUE));//property successfully deleted - output.add(new DeletePropertyAVM2Item(ins, obj, multiname)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - int ret = -1 + 1; - int multinameIndex = ins.operands[0]; - if (abc.constants.getMultiname(multinameIndex).needsName()) { - ret--; - } - if (abc.constants.getMultiname(multinameIndex).needsNs()) { - ret--; - } - return ret; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +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.model.BooleanAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.FullMultinameAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.DeletePropertyAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class DeletePropertyIns extends InstructionDefinition { + + public DeletePropertyIns() { + super(0x6a, "deleteproperty", new int[]{AVM2Code.DAT_MULTINAME_INDEX}, true); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + /*int multiIndex = (int) ((Long) arguments.get(0)).longValue(); + //if multiname[multinameIndex] is runtime + //pop(name) pop(ns) + Object obj = lda.operandStack.pop(); + //push true if removed*/ + throw new RuntimeException("Cannot remove property"); + + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + int multinameIndex = ins.operands[0]; + FullMultinameAVM2Item multiname = resolveMultiname(stack, constants, multinameIndex, ins); + GraphTargetItem obj = stack.pop(); + stack.add(new BooleanAVM2Item(ins, Boolean.TRUE));//property successfully deleted + output.add(new DeletePropertyAVM2Item(ins, obj, multiname)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + int ret = -1 + 1; + int multinameIndex = ins.operands[0]; + if (abc.constants.getMultiname(multinameIndex).needsName()) { + ret--; + } + if (abc.constants.getMultiname(multinameIndex).needsNs()) { + ret--; + } + return ret; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/FindDefIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/FindDefIns.java index 59fe0c8c4..e7ec397ae 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/FindDefIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/FindDefIns.java @@ -1,51 +1,51 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.FindDefAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.flash.abc.types.Multiname; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class FindDefIns extends InstructionDefinition { - - public FindDefIns() { - super(0x5f, "finddef", new int[]{AVM2Code.DAT_MULTINAME_INDEX}, true); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - int multinameIndex = ins.operands[0]; - Multiname multiname = constants.getMultiname(multinameIndex); - stack.push(new FindDefAVM2Item(ins, multiname)); - } - - @Override - public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { - return 1; //multiname may not be runtime - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.FindDefAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.flash.abc.types.Multiname; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class FindDefIns extends InstructionDefinition { + + public FindDefIns() { + super(0x5f, "finddef", new int[]{AVM2Code.DAT_MULTINAME_INDEX}, true); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + int multinameIndex = ins.operands[0]; + Multiname multiname = constants.getMultiname(multinameIndex); + stack.push(new FindDefAVM2Item(ins, multiname)); + } + + @Override + public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { + return 1; //multiname may not be runtime + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/FindPropertyIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/FindPropertyIns.java index 130573c52..9b27f3047 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/FindPropertyIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/FindPropertyIns.java @@ -1,69 +1,69 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -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.model.FindPropertyAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.FullMultinameAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class FindPropertyIns extends InstructionDefinition { - - public FindPropertyIns() { - super(0x5e, "findproperty", new int[]{AVM2Code.DAT_MULTINAME_INDEX}, true); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - //int multiIndex = (int) ((Long) arguments.get(0)).longValue(); - //if is runtime - //pop(name), pop(ns) - throw new RuntimeException("Cannot find property"); - - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - int multinameIndex = ins.operands[0]; - FullMultinameAVM2Item multiname = resolveMultiname(stack, constants, multinameIndex, ins); - stack.push(new FindPropertyAVM2Item(ins, multiname)); //resolve right object - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - int ret = 1; - int multinameIndex = ins.operands[0]; - if (abc.constants.getMultiname(multinameIndex).needsName()) { - ret--; - } - if (abc.constants.getMultiname(multinameIndex).needsNs()) { - ret--; - } - return ret; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +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.model.FindPropertyAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.FullMultinameAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class FindPropertyIns extends InstructionDefinition { + + public FindPropertyIns() { + super(0x5e, "findproperty", new int[]{AVM2Code.DAT_MULTINAME_INDEX}, true); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + //int multiIndex = (int) ((Long) arguments.get(0)).longValue(); + //if is runtime + //pop(name), pop(ns) + throw new RuntimeException("Cannot find property"); + + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + int multinameIndex = ins.operands[0]; + FullMultinameAVM2Item multiname = resolveMultiname(stack, constants, multinameIndex, ins); + stack.push(new FindPropertyAVM2Item(ins, multiname)); //resolve right object + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + int ret = 1; + int multinameIndex = ins.operands[0]; + if (abc.constants.getMultiname(multinameIndex).needsName()) { + ret--; + } + if (abc.constants.getMultiname(multinameIndex).needsNs()) { + ret--; + } + return ret; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/FindPropertyStrictIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/FindPropertyStrictIns.java index 275cbffdd..7e373f7eb 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/FindPropertyStrictIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/FindPropertyStrictIns.java @@ -1,68 +1,68 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -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.model.FindPropertyAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.FullMultinameAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class FindPropertyStrictIns extends InstructionDefinition { - - public FindPropertyStrictIns() { - super(0x5d, "findpropstrict", new int[]{AVM2Code.DAT_MULTINAME_INDEX}, true); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - //int multiIndex = (int) ((Long) arguments.get(0)).longValue(); - //if is runtime - //pop(name), pop(ns) - throw new RuntimeException("Cannot find property"); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - int multinameIndex = ins.operands[0]; - FullMultinameAVM2Item multiname = resolveMultiname(stack, constants, multinameIndex, ins); - stack.push(new FindPropertyAVM2Item(ins, multiname)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - int ret = 1; - int multinameIndex = ins.operands[0]; - if (abc.constants.getMultiname(multinameIndex).needsName()) { - ret--; - } - if (abc.constants.getMultiname(multinameIndex).needsNs()) { - ret--; - } - return ret; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +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.model.FindPropertyAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.FullMultinameAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class FindPropertyStrictIns extends InstructionDefinition { + + public FindPropertyStrictIns() { + super(0x5d, "findpropstrict", new int[]{AVM2Code.DAT_MULTINAME_INDEX}, true); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + //int multiIndex = (int) ((Long) arguments.get(0)).longValue(); + //if is runtime + //pop(name), pop(ns) + throw new RuntimeException("Cannot find property"); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + int multinameIndex = ins.operands[0]; + FullMultinameAVM2Item multiname = resolveMultiname(stack, constants, multinameIndex, ins); + stack.push(new FindPropertyAVM2Item(ins, multiname)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + int ret = 1; + int multinameIndex = ins.operands[0]; + if (abc.constants.getMultiname(multinameIndex).needsName()) { + ret--; + } + if (abc.constants.getMultiname(multinameIndex).needsNs()) { + ret--; + } + return ret; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetDescendantsIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetDescendantsIns.java index f77e5354c..2fd66da93 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetDescendantsIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetDescendantsIns.java @@ -1,70 +1,70 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -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.model.FullMultinameAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.GetDescendantsAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class GetDescendantsIns extends InstructionDefinition { - - public GetDescendantsIns() { - super(0x59, "getdescendants", new int[]{AVM2Code.DAT_MULTINAME_INDEX}, true); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - /*int multiIndex = (int) ((Long) arguments.get(0)).longValue(); - //if is runtime - //pop(name), pop(ns) - Object obj = lda.operandStack.pop();*/ - throw new RuntimeException("getdescendants not working"); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - int multinameIndex = ins.operands[0]; - FullMultinameAVM2Item multiname = resolveMultiname(stack, constants, multinameIndex, ins); - GraphTargetItem obj = stack.pop(); - stack.push(new GetDescendantsAVM2Item(ins, obj, multiname)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - int ret = -1 + 1; - int multinameIndex = ins.operands[0]; - if (abc.constants.getMultiname(multinameIndex).needsName()) { - ret--; - } - if (abc.constants.getMultiname(multinameIndex).needsNs()) { - ret--; - } - return ret; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +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.model.FullMultinameAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.GetDescendantsAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class GetDescendantsIns extends InstructionDefinition { + + public GetDescendantsIns() { + super(0x59, "getdescendants", new int[]{AVM2Code.DAT_MULTINAME_INDEX}, true); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + /*int multiIndex = (int) ((Long) arguments.get(0)).longValue(); + //if is runtime + //pop(name), pop(ns) + Object obj = lda.operandStack.pop();*/ + throw new RuntimeException("getdescendants not working"); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + int multinameIndex = ins.operands[0]; + FullMultinameAVM2Item multiname = resolveMultiname(stack, constants, multinameIndex, ins); + GraphTargetItem obj = stack.pop(); + stack.push(new GetDescendantsAVM2Item(ins, obj, multiname)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + int ret = -1 + 1; + int multinameIndex = ins.operands[0]; + if (abc.constants.getMultiname(multinameIndex).needsName()) { + ret--; + } + if (abc.constants.getMultiname(multinameIndex).needsNs()) { + ret--; + } + return ret; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetGlobalScopeIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetGlobalScopeIns.java index 3dc8865e0..8fc2eace5 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetGlobalScopeIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetGlobalScopeIns.java @@ -1,63 +1,63 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -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.model.ClassAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.ScriptAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class GetGlobalScopeIns extends InstructionDefinition { - - public GetGlobalScopeIns() { - super(0x64, "getglobalscope", new int[]{}, false); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - throw new RuntimeException("getglobalscope not working"); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - if (scopeStack.isEmpty()) { - if (classIndex == -1) { - stack.push(new ScriptAVM2Item(scriptIndex)); - } else { - stack.push(new ClassAVM2Item(abc.instance_info.get(classIndex).getName(constants))); - } - return; - } - stack.push(scopeStack.get(0)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +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.model.ClassAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.ScriptAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class GetGlobalScopeIns extends InstructionDefinition { + + public GetGlobalScopeIns() { + super(0x64, "getglobalscope", new int[]{}, false); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + throw new RuntimeException("getglobalscope not working"); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + if (scopeStack.isEmpty()) { + if (classIndex == -1) { + stack.push(new ScriptAVM2Item(scriptIndex)); + } else { + stack.push(new ClassAVM2Item(abc.instance_info.get(classIndex).getName(constants))); + } + return; + } + stack.push(scopeStack.get(0)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetGlobalSlotIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetGlobalSlotIns.java index 5677bba65..73edd51e9 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetGlobalSlotIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetGlobalSlotIns.java @@ -1,67 +1,67 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.GetSlotAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.clauses.ExceptionAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.flash.abc.types.Multiname; -import com.jpexs.decompiler.flash.abc.types.traits.TraitSlotConst; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class GetGlobalSlotIns extends InstructionDefinition { - - public GetGlobalSlotIns() { - super(0x6e, "getglobalslot", new int[]{AVM2Code.DAT_SLOT_INDEX}, false); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - int slotIndex = ins.operands[0]; - GraphTargetItem obj = scopeStack.get(0); //scope - Multiname slotname = null; - if (obj instanceof ExceptionAVM2Item) { - slotname = constants.getMultiname(((ExceptionAVM2Item) obj).exception.name_index); - } else { - - for (int t = 0; t < body.traits.traits.size(); t++) { - if (body.traits.traits.get(t) instanceof TraitSlotConst) { - if (((TraitSlotConst) body.traits.traits.get(t)).slot_id == slotIndex) { - slotname = body.traits.traits.get(t).getName(abc); - } - } - - } - } - stack.push(new GetSlotAVM2Item(ins, obj, slotname)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.GetSlotAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.clauses.ExceptionAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.flash.abc.types.Multiname; +import com.jpexs.decompiler.flash.abc.types.traits.TraitSlotConst; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class GetGlobalSlotIns extends InstructionDefinition { + + public GetGlobalSlotIns() { + super(0x6e, "getglobalslot", new int[]{AVM2Code.DAT_SLOT_INDEX}, false); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + int slotIndex = ins.operands[0]; + GraphTargetItem obj = scopeStack.get(0); //scope + Multiname slotname = null; + if (obj instanceof ExceptionAVM2Item) { + slotname = constants.getMultiname(((ExceptionAVM2Item) obj).exception.name_index); + } else { + + for (int t = 0; t < body.traits.traits.size(); t++) { + if (body.traits.traits.get(t) instanceof TraitSlotConst) { + if (((TraitSlotConst) body.traits.traits.get(t)).slot_id == slotIndex) { + slotname = body.traits.traits.get(t).getName(abc); + } + } + + } + } + stack.push(new GetSlotAVM2Item(ins, obj, slotname)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetLexIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetLexIns.java index bb75b2b15..4e8f7bf4b 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetLexIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetLexIns.java @@ -1,51 +1,51 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.GetLexAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.flash.abc.types.Multiname; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class GetLexIns extends InstructionDefinition { - - public GetLexIns() { - super(0x60, "getlex", new int[]{AVM2Code.DAT_MULTINAME_INDEX}, true); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - int multinameIndex = ins.operands[0]; - Multiname multiname = constants.getMultiname(multinameIndex); - stack.push(new GetLexAVM2Item(ins, multiname)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.GetLexAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.flash.abc.types.Multiname; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class GetLexIns extends InstructionDefinition { + + public GetLexIns() { + super(0x60, "getlex", new int[]{AVM2Code.DAT_MULTINAME_INDEX}, true); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + int multinameIndex = ins.operands[0]; + Multiname multiname = constants.getMultiname(multinameIndex); + stack.push(new GetLexAVM2Item(ins, multiname)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetPropertyIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetPropertyIns.java index f4470bb00..244274c12 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetPropertyIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetPropertyIns.java @@ -1,65 +1,65 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.FullMultinameAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.GetPropertyAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class GetPropertyIns extends InstructionDefinition { - - public GetPropertyIns() { - super(0x66, "getproperty", new int[]{AVM2Code.DAT_MULTINAME_INDEX}, true); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - int multinameIndex = ins.operands[0]; - FullMultinameAVM2Item multiname = resolveMultiname(stack, constants, multinameIndex, ins); - GraphTargetItem obj = stack.pop(); - stack.push(new GetPropertyAVM2Item(ins, obj, multiname)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - int ret = -1 + 1; - int multinameIndex = ins.operands[0]; - //Note: In official compiler, the stack can be wrong(greater) for some MULTINAMEL/A, e.g. increments - /* - var arr=[1,2,3]; - return arr[2]++; - */ - if (abc.constants.getMultiname(multinameIndex).needsName()) { - ret--; - } - if (abc.constants.getMultiname(multinameIndex).needsNs()) { - ret--; - } - return ret; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.FullMultinameAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.GetPropertyAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class GetPropertyIns extends InstructionDefinition { + + public GetPropertyIns() { + super(0x66, "getproperty", new int[]{AVM2Code.DAT_MULTINAME_INDEX}, true); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + int multinameIndex = ins.operands[0]; + FullMultinameAVM2Item multiname = resolveMultiname(stack, constants, multinameIndex, ins); + GraphTargetItem obj = stack.pop(); + stack.push(new GetPropertyAVM2Item(ins, obj, multiname)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + int ret = -1 + 1; + int multinameIndex = ins.operands[0]; + //Note: In official compiler, the stack can be wrong(greater) for some MULTINAMEL/A, e.g. increments + /* + var arr=[1,2,3]; + return arr[2]++; + */ + if (abc.constants.getMultiname(multinameIndex).needsName()) { + ret--; + } + if (abc.constants.getMultiname(multinameIndex).needsNs()) { + ret--; + } + return ret; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetScopeObjectIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetScopeObjectIns.java index 6c2db4774..d6d563521 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetScopeObjectIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetScopeObjectIns.java @@ -1,48 +1,48 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class GetScopeObjectIns extends InstructionDefinition { - - public GetScopeObjectIns() { - super(0x65, "getscopeobject", new int[]{AVM2Code.DAT_SLOT_SCOPE_INDEX}, false); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - int index = ins.operands[0]; - stack.push(scopeStack.get(index)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class GetScopeObjectIns extends InstructionDefinition { + + public GetScopeObjectIns() { + super(0x65, "getscopeobject", new int[]{AVM2Code.DAT_SLOT_SCOPE_INDEX}, false); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + int index = ins.operands[0]; + stack.push(scopeStack.get(index)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetSlotIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetSlotIns.java index 0236d9560..bdd59b484 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetSlotIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetSlotIns.java @@ -1,86 +1,86 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.ClassAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.GetSlotAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.NewActivationAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.ScriptAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.ThisAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.clauses.ExceptionAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.flash.abc.types.Multiname; -import com.jpexs.decompiler.flash.abc.types.traits.Trait; -import com.jpexs.decompiler.flash.abc.types.traits.TraitWithSlot; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class GetSlotIns extends InstructionDefinition { - - public GetSlotIns() { - super(0x6c, "getslot", new int[]{AVM2Code.DAT_SLOT_INDEX}, true); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - int slotIndex = ins.operands[0]; - GraphTargetItem obj = stack.pop(); //scope - obj = obj.getThroughRegister(); - Multiname slotname = null; - if (obj instanceof ExceptionAVM2Item) { - slotname = constants.getMultiname(((ExceptionAVM2Item) obj).exception.name_index); - } else if (obj instanceof ClassAVM2Item) { - slotname = ((ClassAVM2Item) obj).className; - } else if (obj instanceof ThisAVM2Item) { - slotname = ((ThisAVM2Item) obj).className; - } else if (obj instanceof ScriptAVM2Item) { - for (int t = 0; t < abc.script_info.get(((ScriptAVM2Item) obj).scriptIndex).traits.traits.size(); t++) { - Trait tr = abc.script_info.get(((ScriptAVM2Item) obj).scriptIndex).traits.traits.get(t); - if (tr instanceof TraitWithSlot) { - if (((TraitWithSlot) tr).getSlotIndex() == slotIndex) { - slotname = tr.getName(abc); - } - } - } - } else if (obj instanceof NewActivationAVM2Item) { - - for (int t = 0; t < body.traits.traits.size(); t++) { - if (body.traits.traits.get(t) instanceof TraitWithSlot) { - if (((TraitWithSlot) body.traits.traits.get(t)).getSlotIndex() == slotIndex) { - slotname = body.traits.traits.get(t).getName(abc); - } - } - - } - } - stack.push(new GetSlotAVM2Item(ins, obj, slotname)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -1 + 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.ClassAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.GetSlotAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.NewActivationAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.ScriptAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.ThisAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.clauses.ExceptionAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.flash.abc.types.Multiname; +import com.jpexs.decompiler.flash.abc.types.traits.Trait; +import com.jpexs.decompiler.flash.abc.types.traits.TraitWithSlot; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class GetSlotIns extends InstructionDefinition { + + public GetSlotIns() { + super(0x6c, "getslot", new int[]{AVM2Code.DAT_SLOT_INDEX}, true); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + int slotIndex = ins.operands[0]; + GraphTargetItem obj = stack.pop(); //scope + obj = obj.getThroughRegister(); + Multiname slotname = null; + if (obj instanceof ExceptionAVM2Item) { + slotname = constants.getMultiname(((ExceptionAVM2Item) obj).exception.name_index); + } else if (obj instanceof ClassAVM2Item) { + slotname = ((ClassAVM2Item) obj).className; + } else if (obj instanceof ThisAVM2Item) { + slotname = ((ThisAVM2Item) obj).className; + } else if (obj instanceof ScriptAVM2Item) { + for (int t = 0; t < abc.script_info.get(((ScriptAVM2Item) obj).scriptIndex).traits.traits.size(); t++) { + Trait tr = abc.script_info.get(((ScriptAVM2Item) obj).scriptIndex).traits.traits.get(t); + if (tr instanceof TraitWithSlot) { + if (((TraitWithSlot) tr).getSlotIndex() == slotIndex) { + slotname = tr.getName(abc); + } + } + } + } else if (obj instanceof NewActivationAVM2Item) { + + for (int t = 0; t < body.traits.traits.size(); t++) { + if (body.traits.traits.get(t) instanceof TraitWithSlot) { + if (((TraitWithSlot) body.traits.traits.get(t)).getSlotIndex() == slotIndex) { + slotname = body.traits.traits.get(t).getName(abc); + } + } + + } + } + stack.push(new GetSlotAVM2Item(ins, obj, slotname)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -1 + 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetSuperIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetSuperIns.java index 1ebc0b3c5..8d54469a2 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetSuperIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetSuperIns.java @@ -1,60 +1,60 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.FullMultinameAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.GetSuperAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class GetSuperIns extends InstructionDefinition { - - public GetSuperIns() { - super(0x04, "getsuper", new int[]{AVM2Code.DAT_MULTINAME_INDEX}, true); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - int multinameIndex = ins.operands[0]; - FullMultinameAVM2Item multiname = resolveMultiname(stack, constants, multinameIndex, ins); - GraphTargetItem obj = stack.pop(); - stack.push(new GetSuperAVM2Item(ins, obj, multiname)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - int ret = -1 + 1; - int multinameIndex = ins.operands[0]; - if (abc.constants.getMultiname(multinameIndex).needsName()) { - ret--; - } - if (abc.constants.getMultiname(multinameIndex).needsNs()) { - ret--; - } - return ret; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.FullMultinameAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.GetSuperAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class GetSuperIns extends InstructionDefinition { + + public GetSuperIns() { + super(0x04, "getsuper", new int[]{AVM2Code.DAT_MULTINAME_INDEX}, true); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + int multinameIndex = ins.operands[0]; + FullMultinameAVM2Item multiname = resolveMultiname(stack, constants, multinameIndex, ins); + GraphTargetItem obj = stack.pop(); + stack.push(new GetSuperAVM2Item(ins, obj, multiname)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + int ret = -1 + 1; + int multinameIndex = ins.operands[0]; + if (abc.constants.getMultiname(multinameIndex).needsName()) { + ret--; + } + if (abc.constants.getMultiname(multinameIndex).needsNs()) { + ret--; + } + return ret; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/HasNext2Ins.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/HasNext2Ins.java index 6c3dcffae..0a5d6cba7 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/HasNext2Ins.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/HasNext2Ins.java @@ -1,52 +1,52 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.HasNextAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.LocalRegAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class HasNext2Ins extends InstructionDefinition { - - public HasNext2Ins() { - super(0x32, "hasnext2", new int[]{AVM2Code.DAT_LOCAL_REG_INDEX, AVM2Code.DAT_LOCAL_REG_INDEX}, true); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - int objectReg = ins.operands[0]; - int indexReg = ins.operands[1]; - //stack.push("_loc_" + objectReg + ".hasNext(cnt=_loc_" + indexReg + ")"); - stack.push(new HasNextAVM2Item(ins, new LocalRegAVM2Item(ins, indexReg, localRegs.get(indexReg)), localRegs.get(objectReg))); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.HasNextAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.LocalRegAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class HasNext2Ins extends InstructionDefinition { + + public HasNext2Ins() { + super(0x32, "hasnext2", new int[]{AVM2Code.DAT_LOCAL_REG_INDEX, AVM2Code.DAT_LOCAL_REG_INDEX}, true); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + int objectReg = ins.operands[0]; + int indexReg = ins.operands[1]; + //stack.push("_loc_" + objectReg + ".hasNext(cnt=_loc_" + indexReg + ")"); + stack.push(new HasNextAVM2Item(ins, new LocalRegAVM2Item(ins, indexReg, localRegs.get(indexReg)), localRegs.get(objectReg))); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/HasNextIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/HasNextIns.java index 512fb15c9..bf345aa8e 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/HasNextIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/HasNextIns.java @@ -1,51 +1,51 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.HasNextAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class HasNextIns extends InstructionDefinition { - - public HasNextIns() { - super(0x1f, "hasnext", new int[]{}, true); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem curIndex = stack.pop(); - GraphTargetItem obj = stack.pop(); - stack.push(new HasNextAVM2Item(ins, curIndex, obj)); - - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -2 + 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.HasNextAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class HasNextIns extends InstructionDefinition { + + public HasNextIns() { + super(0x1f, "hasnext", new int[]{}, true); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem curIndex = stack.pop(); + GraphTargetItem obj = stack.pop(); + stack.push(new HasNextAVM2Item(ins, curIndex, obj)); + + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -2 + 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/InIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/InIns.java index 7e52b8aee..1cda4bdf6 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/InIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/InIns.java @@ -1,50 +1,50 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.InAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class InIns extends InstructionDefinition { - - public InIns() { - super(0xb4, "in", new int[]{}, true); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem obj = stack.pop(); - GraphTargetItem name = stack.pop(); - stack.push(new InAVM2Item(ins, name, obj)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -2 + 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.InAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class InIns extends InstructionDefinition { + + public InIns() { + super(0xb4, "in", new int[]{}, true); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem obj = stack.pop(); + GraphTargetItem name = stack.pop(); + stack.push(new InAVM2Item(ins, name, obj)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -2 + 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/InitPropertyIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/InitPropertyIns.java index 9a027f884..b914db3a1 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/InitPropertyIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/InitPropertyIns.java @@ -1,62 +1,62 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.FullMultinameAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.InitPropertyAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class InitPropertyIns extends InstructionDefinition { - - public InitPropertyIns() { - super(0x68, "initproperty", new int[]{AVM2Code.DAT_MULTINAME_INDEX}, true); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - int multinameIndex = ins.operands[0]; - - GraphTargetItem val = stack.pop(); - FullMultinameAVM2Item multiname = resolveMultiname(stack, constants, multinameIndex, ins); - GraphTargetItem obj = stack.pop(); - output.add(new InitPropertyAVM2Item(ins, obj, multiname, val)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - int ret = -2; - int multinameIndex = ins.operands[0]; - if (abc.constants.getMultiname(multinameIndex).needsName()) { - ret--; - } - if (abc.constants.getMultiname(multinameIndex).needsNs()) { - ret--; - } - return ret; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.FullMultinameAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.InitPropertyAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class InitPropertyIns extends InstructionDefinition { + + public InitPropertyIns() { + super(0x68, "initproperty", new int[]{AVM2Code.DAT_MULTINAME_INDEX}, true); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + int multinameIndex = ins.operands[0]; + + GraphTargetItem val = stack.pop(); + FullMultinameAVM2Item multiname = resolveMultiname(stack, constants, multinameIndex, ins); + GraphTargetItem obj = stack.pop(); + output.add(new InitPropertyAVM2Item(ins, obj, multiname, val)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + int ret = -2; + int multinameIndex = ins.operands[0]; + if (abc.constants.getMultiname(multinameIndex).needsName()) { + ret--; + } + if (abc.constants.getMultiname(multinameIndex).needsNs()) { + ret--; + } + return ret; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/LabelIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/LabelIns.java index a27bb2453..093857c74 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/LabelIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/LabelIns.java @@ -1,34 +1,34 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other; - -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; -import java.util.List; - -public class LabelIns extends InstructionDefinition { -//this can be target of branch - - public LabelIns() { - super(0x09, "label", new int[]{}, false); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other; + +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; +import java.util.List; + +public class LabelIns extends InstructionDefinition { +//this can be target of branch + + public LabelIns() { + super(0x09, "label", new int[]{}, false); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/NextNameIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/NextNameIns.java index 76ecbde02..78c7d5eb1 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/NextNameIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/NextNameIns.java @@ -1,50 +1,50 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.NextNameAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class NextNameIns extends InstructionDefinition { - - public NextNameIns() { - super(0x1e, "nextname", new int[]{}, true); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem index = stack.pop(); - GraphTargetItem obj = stack.pop(); - stack.push(new NextNameAVM2Item(ins, index, obj)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -2 + 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.NextNameAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class NextNameIns extends InstructionDefinition { + + public NextNameIns() { + super(0x1e, "nextname", new int[]{}, true); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem index = stack.pop(); + GraphTargetItem obj = stack.pop(); + stack.push(new NextNameAVM2Item(ins, index, obj)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -2 + 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/NextValueIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/NextValueIns.java index 960acad2d..725d7bcbd 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/NextValueIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/NextValueIns.java @@ -1,50 +1,50 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.NextValueAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class NextValueIns extends InstructionDefinition { - - public NextValueIns() { - super(0x23, "nextvalue", new int[]{}, true); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem index = stack.pop(); - GraphTargetItem obj = stack.pop(); - stack.push(new NextValueAVM2Item(ins, index, obj)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -2 + 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.NextValueAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class NextValueIns extends InstructionDefinition { + + public NextValueIns() { + super(0x23, "nextvalue", new int[]{}, true); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem index = stack.pop(); + GraphTargetItem obj = stack.pop(); + stack.push(new NextValueAVM2Item(ins, index, obj)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -2 + 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/NopIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/NopIns.java index aa25a7da6..d4d6ae67b 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/NopIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/NopIns.java @@ -1,33 +1,33 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other; - -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; -import java.util.List; - -public class NopIns extends InstructionDefinition { - - public NopIns() { - super(0x02, "nop", new int[]{}, false); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other; + +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; +import java.util.List; + +public class NopIns extends InstructionDefinition { + + public NopIns() { + super(0x02, "nop", new int[]{}, false); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/ReturnValueIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/ReturnValueIns.java index 03b3ebac0..33ecc14e3 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/ReturnValueIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/ReturnValueIns.java @@ -1,53 +1,53 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.ReturnValueAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class ReturnValueIns extends InstructionDefinition { - - public ReturnValueIns() { - super(0x48, "returnvalue", new int[]{}, true); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - output.add(new ReturnValueAVM2Item(ins, stack.pop())); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -1; - } - - @Override - public boolean isExitInstruction() { - return true; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.ReturnValueAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class ReturnValueIns extends InstructionDefinition { + + public ReturnValueIns() { + super(0x48, "returnvalue", new int[]{}, true); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + output.add(new ReturnValueAVM2Item(ins, stack.pop())); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -1; + } + + @Override + public boolean isExitInstruction() { + return true; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/ReturnVoidIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/ReturnVoidIns.java index f514e2f5c..d5734011f 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/ReturnVoidIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/ReturnVoidIns.java @@ -1,48 +1,48 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.ReturnVoidAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class ReturnVoidIns extends InstructionDefinition { - - public ReturnVoidIns() { - super(0x47, "returnvoid", new int[]{}, false); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - output.add(new ReturnVoidAVM2Item(ins)); - } - - @Override - public boolean isExitInstruction() { - return true; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.ReturnVoidAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class ReturnVoidIns extends InstructionDefinition { + + public ReturnVoidIns() { + super(0x47, "returnvoid", new int[]{}, false); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + output.add(new ReturnVoidAVM2Item(ins)); + } + + @Override + public boolean isExitInstruction() { + return true; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/SetGlobalSlotIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/SetGlobalSlotIns.java index 82931f124..13cc579c9 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/SetGlobalSlotIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/SetGlobalSlotIns.java @@ -1,56 +1,56 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.instructions.SetTypeIns; -import com.jpexs.decompiler.flash.abc.avm2.model.AVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.SetGlobalSlotAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; -import java.util.Stack; - -public class SetGlobalSlotIns extends InstructionDefinition implements SetTypeIns { - - public SetGlobalSlotIns() { - super(0x6f, "setglobalslot", new int[]{AVM2Code.DAT_SLOT_INDEX}, false); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - output.add(new SetGlobalSlotAVM2Item(ins, ins.operands[0], stack.pop())); - } - - @Override - public String getObject(Stack stack, ABC abc, AVM2Instruction ins, List output, MethodBody body, HashMap localRegNames, List fullyQualifiedNames) { - return "globalslot" + ins.operands[0]; - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.instructions.SetTypeIns; +import com.jpexs.decompiler.flash.abc.avm2.model.AVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.SetGlobalSlotAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; +import java.util.Stack; + +public class SetGlobalSlotIns extends InstructionDefinition implements SetTypeIns { + + public SetGlobalSlotIns() { + super(0x6f, "setglobalslot", new int[]{AVM2Code.DAT_SLOT_INDEX}, false); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + output.add(new SetGlobalSlotAVM2Item(ins, ins.operands[0], stack.pop())); + } + + @Override + public String getObject(Stack stack, ABC abc, AVM2Instruction ins, List output, MethodBody body, HashMap localRegNames, List fullyQualifiedNames) { + return "globalslot" + ins.operands[0]; + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/SetPropertyIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/SetPropertyIns.java index b2da78ba5..fd355f26f 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/SetPropertyIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/SetPropertyIns.java @@ -1,173 +1,173 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.instructions.SetTypeIns; -import com.jpexs.decompiler.flash.abc.avm2.model.AVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.ApplyTypeAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.ConstructAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.DecrementAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.FullMultinameAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.GetPropertyAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.IncrementAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.InitVectorAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.LocalRegAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.PostDecrementAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.PostIncrementAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.SetPropertyAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.PreDecrementAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.PreIncrementAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Stack; - -public class SetPropertyIns extends InstructionDefinition implements SetTypeIns { - - public SetPropertyIns() { - super(0x61, "setproperty", new int[]{AVM2Code.DAT_MULTINAME_INDEX}, true); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - int multinameIndex = ins.operands[0]; - GraphTargetItem value = stack.pop(); - FullMultinameAVM2Item multiname = resolveMultiname(stack, constants, multinameIndex, ins); - GraphTargetItem obj = stack.pop(); - if (value.getThroughDuplicate().getThroughRegister().getThroughDuplicate() instanceof IncrementAVM2Item) { - GraphTargetItem inside = ((IncrementAVM2Item) value.getThroughDuplicate().getThroughRegister().getThroughDuplicate()).value.getThroughRegister().getNotCoerced().getThroughDuplicate(); - if (inside instanceof GetPropertyAVM2Item) { - GetPropertyAVM2Item insideProp = ((GetPropertyAVM2Item) inside); - if (((FullMultinameAVM2Item) insideProp.propertyName).compareSame(multiname)) { - GraphTargetItem insideObj = obj.getThroughDuplicate(); - if (insideObj instanceof LocalRegAVM2Item) { - if (((LocalRegAVM2Item) insideObj).computedValue != null) { - insideObj = ((LocalRegAVM2Item) insideObj).computedValue.getThroughNotCompilable().getThroughDuplicate(); - } - } - if (insideProp.object.getThroughDuplicate() == insideObj) { - if (stack.size() > 0) { - GraphTargetItem top = stack.peek().getNotCoerced().getThroughDuplicate(); - if (top == insideProp) { - stack.pop(); - stack.push(new PostIncrementAVM2Item(ins, insideProp)); - } else if ((top instanceof IncrementAVM2Item) && (((IncrementAVM2Item) top).value == inside)) { - stack.pop(); - stack.push(new PreIncrementAVM2Item(ins, insideProp)); - } else { - output.add(new PostIncrementAVM2Item(ins, insideProp)); - } - } else { - output.add(new PostIncrementAVM2Item(ins, insideProp)); - } - return; - } - } - } - } - - if (value.getThroughDuplicate().getThroughRegister().getThroughDuplicate() instanceof DecrementAVM2Item) { - GraphTargetItem inside = ((DecrementAVM2Item) value.getThroughDuplicate().getThroughRegister().getThroughDuplicate()).value.getThroughRegister().getNotCoerced().getThroughDuplicate(); - if (inside instanceof GetPropertyAVM2Item) { - GetPropertyAVM2Item insideProp = ((GetPropertyAVM2Item) inside); - if (((FullMultinameAVM2Item) insideProp.propertyName).compareSame(multiname)) { - GraphTargetItem insideObj = obj.getThroughDuplicate(); - if (insideObj instanceof LocalRegAVM2Item) { - if (((LocalRegAVM2Item) insideObj).computedValue != null) { - insideObj = ((LocalRegAVM2Item) insideObj).computedValue.getThroughNotCompilable().getThroughDuplicate(); - } - } - if (insideProp.object.getThroughDuplicate() == insideObj) { - if (stack.size() > 0) { - GraphTargetItem top = stack.peek().getNotCoerced().getThroughDuplicate(); - if (top == insideProp) { - stack.pop(); - stack.push(new PostDecrementAVM2Item(ins, insideProp)); - } else if ((top instanceof DecrementAVM2Item) && (((DecrementAVM2Item) top).value == inside)) { - stack.pop(); - stack.push(new PreDecrementAVM2Item(ins, insideProp)); - } else { - output.add(new PostDecrementAVM2Item(ins, insideProp)); - } - } else { - output.add(new PostDecrementAVM2Item(ins, insideProp)); - } - return; - } - } - } - } - - if (obj.getThroughDuplicate() instanceof ConstructAVM2Item) { - ConstructAVM2Item c = (ConstructAVM2Item) obj.getThroughDuplicate(); - if (c.object instanceof ApplyTypeAVM2Item) { - ApplyTypeAVM2Item at = (ApplyTypeAVM2Item) c.object; - c.args.clear(); - List vals = new ArrayList<>(); - vals.add(value); - c.object = new InitVectorAVM2Item(c.instruction, at.params.get(0), vals); - return; - } else if (c.object instanceof InitVectorAVM2Item) { - InitVectorAVM2Item iv = (InitVectorAVM2Item) c.object; - iv.arguments.add(value); - return; - } - } - - output.add(new SetPropertyAVM2Item(ins, obj, multiname, value)); - - } - - @Override - public String getObject(Stack stack, ABC abc, AVM2Instruction ins, List output, MethodBody body, HashMap localRegNames, List fullyQualifiedNames) { - int multinameIndex = ins.operands[0]; - String multiname = resolveMultinameNoPop(0, stack, abc.constants, multinameIndex, ins, fullyQualifiedNames); - GraphTargetItem obj = stack.get(1 + resolvedCount(abc.constants, multinameIndex)); //pod vrcholem - if ((!obj.toString().isEmpty())) { - multiname = "." + multiname; - } - return obj + multiname; - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - int ret = -2; - int multinameIndex = ins.operands[0]; - //Note: In official compiler, the stack can be wrong(greater) for some MULTINAMEL/A, e.g. increments - /* - var arr=[1,2,3]; - trace(arr[2]++); - */ - if (abc.constants.getMultiname(multinameIndex).needsName()) { - ret--; - } - if (abc.constants.getMultiname(multinameIndex).needsNs()) { - ret--; - } - return ret; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.instructions.SetTypeIns; +import com.jpexs.decompiler.flash.abc.avm2.model.AVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.ApplyTypeAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.ConstructAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.DecrementAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.FullMultinameAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.GetPropertyAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.IncrementAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.InitVectorAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.LocalRegAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.PostDecrementAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.PostIncrementAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.SetPropertyAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.PreDecrementAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.PreIncrementAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Stack; + +public class SetPropertyIns extends InstructionDefinition implements SetTypeIns { + + public SetPropertyIns() { + super(0x61, "setproperty", new int[]{AVM2Code.DAT_MULTINAME_INDEX}, true); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + int multinameIndex = ins.operands[0]; + GraphTargetItem value = stack.pop(); + FullMultinameAVM2Item multiname = resolveMultiname(stack, constants, multinameIndex, ins); + GraphTargetItem obj = stack.pop(); + if (value.getThroughDuplicate().getThroughRegister().getThroughDuplicate() instanceof IncrementAVM2Item) { + GraphTargetItem inside = ((IncrementAVM2Item) value.getThroughDuplicate().getThroughRegister().getThroughDuplicate()).value.getThroughRegister().getNotCoerced().getThroughDuplicate(); + if (inside instanceof GetPropertyAVM2Item) { + GetPropertyAVM2Item insideProp = ((GetPropertyAVM2Item) inside); + if (((FullMultinameAVM2Item) insideProp.propertyName).compareSame(multiname)) { + GraphTargetItem insideObj = obj.getThroughDuplicate(); + if (insideObj instanceof LocalRegAVM2Item) { + if (((LocalRegAVM2Item) insideObj).computedValue != null) { + insideObj = ((LocalRegAVM2Item) insideObj).computedValue.getThroughNotCompilable().getThroughDuplicate(); + } + } + if (insideProp.object.getThroughDuplicate() == insideObj) { + if (stack.size() > 0) { + GraphTargetItem top = stack.peek().getNotCoerced().getThroughDuplicate(); + if (top == insideProp) { + stack.pop(); + stack.push(new PostIncrementAVM2Item(ins, insideProp)); + } else if ((top instanceof IncrementAVM2Item) && (((IncrementAVM2Item) top).value == inside)) { + stack.pop(); + stack.push(new PreIncrementAVM2Item(ins, insideProp)); + } else { + output.add(new PostIncrementAVM2Item(ins, insideProp)); + } + } else { + output.add(new PostIncrementAVM2Item(ins, insideProp)); + } + return; + } + } + } + } + + if (value.getThroughDuplicate().getThroughRegister().getThroughDuplicate() instanceof DecrementAVM2Item) { + GraphTargetItem inside = ((DecrementAVM2Item) value.getThroughDuplicate().getThroughRegister().getThroughDuplicate()).value.getThroughRegister().getNotCoerced().getThroughDuplicate(); + if (inside instanceof GetPropertyAVM2Item) { + GetPropertyAVM2Item insideProp = ((GetPropertyAVM2Item) inside); + if (((FullMultinameAVM2Item) insideProp.propertyName).compareSame(multiname)) { + GraphTargetItem insideObj = obj.getThroughDuplicate(); + if (insideObj instanceof LocalRegAVM2Item) { + if (((LocalRegAVM2Item) insideObj).computedValue != null) { + insideObj = ((LocalRegAVM2Item) insideObj).computedValue.getThroughNotCompilable().getThroughDuplicate(); + } + } + if (insideProp.object.getThroughDuplicate() == insideObj) { + if (stack.size() > 0) { + GraphTargetItem top = stack.peek().getNotCoerced().getThroughDuplicate(); + if (top == insideProp) { + stack.pop(); + stack.push(new PostDecrementAVM2Item(ins, insideProp)); + } else if ((top instanceof DecrementAVM2Item) && (((DecrementAVM2Item) top).value == inside)) { + stack.pop(); + stack.push(new PreDecrementAVM2Item(ins, insideProp)); + } else { + output.add(new PostDecrementAVM2Item(ins, insideProp)); + } + } else { + output.add(new PostDecrementAVM2Item(ins, insideProp)); + } + return; + } + } + } + } + + if (obj.getThroughDuplicate() instanceof ConstructAVM2Item) { + ConstructAVM2Item c = (ConstructAVM2Item) obj.getThroughDuplicate(); + if (c.object instanceof ApplyTypeAVM2Item) { + ApplyTypeAVM2Item at = (ApplyTypeAVM2Item) c.object; + c.args.clear(); + List vals = new ArrayList<>(); + vals.add(value); + c.object = new InitVectorAVM2Item(c.instruction, at.params.get(0), vals); + return; + } else if (c.object instanceof InitVectorAVM2Item) { + InitVectorAVM2Item iv = (InitVectorAVM2Item) c.object; + iv.arguments.add(value); + return; + } + } + + output.add(new SetPropertyAVM2Item(ins, obj, multiname, value)); + + } + + @Override + public String getObject(Stack stack, ABC abc, AVM2Instruction ins, List output, MethodBody body, HashMap localRegNames, List fullyQualifiedNames) { + int multinameIndex = ins.operands[0]; + String multiname = resolveMultinameNoPop(0, stack, abc.constants, multinameIndex, ins, fullyQualifiedNames); + GraphTargetItem obj = stack.get(1 + resolvedCount(abc.constants, multinameIndex)); //pod vrcholem + if ((!obj.toString().isEmpty())) { + multiname = "." + multiname; + } + return obj + multiname; + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + int ret = -2; + int multinameIndex = ins.operands[0]; + //Note: In official compiler, the stack can be wrong(greater) for some MULTINAMEL/A, e.g. increments + /* + var arr=[1,2,3]; + trace(arr[2]++); + */ + if (abc.constants.getMultiname(multinameIndex).needsName()) { + ret--; + } + if (abc.constants.getMultiname(multinameIndex).needsNs()) { + ret--; + } + return ret; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/SetSlotIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/SetSlotIns.java index 7456f9eea..d1bbc2655 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/SetSlotIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/SetSlotIns.java @@ -1,183 +1,183 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.instructions.SetTypeIns; -import com.jpexs.decompiler.flash.abc.avm2.model.AVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.ClassAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.DecrementAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.GetSlotAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.IncrementAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.LocalRegAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.NewActivationAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.PostDecrementAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.PostIncrementAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.ScriptAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.SetSlotAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.ThisAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.clauses.ExceptionAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.PreDecrementAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.PreIncrementAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.flash.abc.types.Multiname; -import com.jpexs.decompiler.flash.abc.types.traits.Trait; -import com.jpexs.decompiler.flash.abc.types.traits.TraitSlotConst; -import com.jpexs.decompiler.flash.abc.types.traits.TraitWithSlot; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; -import java.util.Stack; - -public class SetSlotIns extends InstructionDefinition implements SetTypeIns { - - public SetSlotIns() { - super(0x6d, "setslot", new int[]{AVM2Code.DAT_SLOT_INDEX}, true); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - int slotIndex = ins.operands[0]; - GraphTargetItem value = stack.pop(); - GraphTargetItem obj = stack.pop(); //scopeId - GraphTargetItem objnoreg = obj; - obj = obj.getThroughRegister(); - Multiname slotname = null; - if (obj instanceof NewActivationAVM2Item) { - ((NewActivationAVM2Item) obj).slots.put(slotIndex, value); - } - - if (obj instanceof ExceptionAVM2Item) { - slotname = constants.getMultiname(((ExceptionAVM2Item) obj).exception.name_index); - } else if (obj instanceof ClassAVM2Item) { - slotname = ((ClassAVM2Item) obj).className; - } else if (obj instanceof ThisAVM2Item) { - slotname = ((ThisAVM2Item) obj).className; - } else if (obj instanceof ScriptAVM2Item) { - for (int t = 0; t < abc.script_info.get(((ScriptAVM2Item) obj).scriptIndex).traits.traits.size(); t++) { - Trait tr = abc.script_info.get(((ScriptAVM2Item) obj).scriptIndex).traits.traits.get(t); - if (tr instanceof TraitWithSlot) { - if (((TraitWithSlot) tr).getSlotIndex() == slotIndex) { - slotname = tr.getName(abc); - } - } - } - } else if (obj instanceof NewActivationAVM2Item) { - - for (int t = 0; t < body.traits.traits.size(); t++) { - if (body.traits.traits.get(t) instanceof TraitWithSlot) { - if (((TraitWithSlot) body.traits.traits.get(t)).getSlotIndex() == slotIndex) { - slotname = body.traits.traits.get(t).getName(abc); - } - } - - } - } - - if (slotname != null) { - if (value instanceof LocalRegAVM2Item) { - LocalRegAVM2Item lr = (LocalRegAVM2Item) value; - String slotNameStr = slotname.getName(constants, fullyQualifiedNames, true); - if (localRegNames.containsKey(lr.regIndex)) { - if (localRegNames.get(lr.regIndex).equals(slotNameStr)) { - return; //Register with same name to slot - } - } - } - } - - if (value.getNotCoerced().getThroughDuplicate() instanceof IncrementAVM2Item) { - GraphTargetItem inside = ((IncrementAVM2Item) value.getNotCoerced()).value.getThroughRegister().getNotCoerced().getThroughDuplicate(); - if (inside instanceof GetSlotAVM2Item) { - GetSlotAVM2Item slotItem = (GetSlotAVM2Item) inside; - if ((slotItem.scope.getThroughRegister() == obj.getThroughRegister()) - && (slotItem.slotName == slotname)) { - if (stack.size() > 0) { - GraphTargetItem top = stack.peek().getNotCoerced().getThroughDuplicate(); - if (top == inside) { - stack.pop(); - stack.push(new PostIncrementAVM2Item(ins, inside)); - } else if ((top instanceof IncrementAVM2Item) && (((IncrementAVM2Item) top).value == inside)) { - stack.pop(); - stack.push(new PreIncrementAVM2Item(ins, inside)); - } else { - output.add(new PostIncrementAVM2Item(ins, inside)); - } - } else { - output.add(new PostIncrementAVM2Item(ins, inside)); - } - return; - } - } - } - - if (value.getNotCoerced().getThroughDuplicate() instanceof DecrementAVM2Item) { - GraphTargetItem inside = ((DecrementAVM2Item) value.getNotCoerced()).value.getThroughRegister().getNotCoerced().getThroughDuplicate(); - if (inside instanceof GetSlotAVM2Item) { - GetSlotAVM2Item slotItem = (GetSlotAVM2Item) inside; - if ((slotItem.scope.getThroughRegister() == obj.getThroughRegister()) - && (slotItem.slotName == slotname)) { - if (stack.size() > 0) { - GraphTargetItem top = stack.peek().getNotCoerced().getThroughDuplicate(); - if (top == inside) { - stack.pop(); - stack.push(new PostDecrementAVM2Item(ins, inside)); - } else if ((top instanceof DecrementAVM2Item) && (((DecrementAVM2Item) top).value == inside)) { - stack.pop(); - stack.push(new PreDecrementAVM2Item(ins, inside)); - } else { - output.add(new PostDecrementAVM2Item(ins, inside)); - } - } else { - output.add(new PostDecrementAVM2Item(ins, inside)); - } - return; - } - } - } - - output.add(new SetSlotAVM2Item(ins, obj, slotname, value)); - } - - @Override - public String getObject(Stack stack, ABC abc, AVM2Instruction ins, List output, MethodBody body, HashMap localRegNames, List fullyQualifiedNames) { - int slotIndex = ins.operands[0]; - ////String obj = stack.get(1); - String slotname = ""; - for (int t = 0; t < body.traits.traits.size(); t++) { - if (body.traits.traits.get(t) instanceof TraitSlotConst) { - if (((TraitSlotConst) body.traits.traits.get(t)).slot_id == slotIndex) { - slotname = body.traits.traits.get(t).getName(abc).getName(abc.constants, fullyQualifiedNames, true); - } - } - - } - return slotname; - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -2; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.instructions.SetTypeIns; +import com.jpexs.decompiler.flash.abc.avm2.model.AVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.ClassAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.DecrementAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.GetSlotAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.IncrementAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.LocalRegAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.NewActivationAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.PostDecrementAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.PostIncrementAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.ScriptAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.SetSlotAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.ThisAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.clauses.ExceptionAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.PreDecrementAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.PreIncrementAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.flash.abc.types.Multiname; +import com.jpexs.decompiler.flash.abc.types.traits.Trait; +import com.jpexs.decompiler.flash.abc.types.traits.TraitSlotConst; +import com.jpexs.decompiler.flash.abc.types.traits.TraitWithSlot; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; +import java.util.Stack; + +public class SetSlotIns extends InstructionDefinition implements SetTypeIns { + + public SetSlotIns() { + super(0x6d, "setslot", new int[]{AVM2Code.DAT_SLOT_INDEX}, true); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + int slotIndex = ins.operands[0]; + GraphTargetItem value = stack.pop(); + GraphTargetItem obj = stack.pop(); //scopeId + GraphTargetItem objnoreg = obj; + obj = obj.getThroughRegister(); + Multiname slotname = null; + if (obj instanceof NewActivationAVM2Item) { + ((NewActivationAVM2Item) obj).slots.put(slotIndex, value); + } + + if (obj instanceof ExceptionAVM2Item) { + slotname = constants.getMultiname(((ExceptionAVM2Item) obj).exception.name_index); + } else if (obj instanceof ClassAVM2Item) { + slotname = ((ClassAVM2Item) obj).className; + } else if (obj instanceof ThisAVM2Item) { + slotname = ((ThisAVM2Item) obj).className; + } else if (obj instanceof ScriptAVM2Item) { + for (int t = 0; t < abc.script_info.get(((ScriptAVM2Item) obj).scriptIndex).traits.traits.size(); t++) { + Trait tr = abc.script_info.get(((ScriptAVM2Item) obj).scriptIndex).traits.traits.get(t); + if (tr instanceof TraitWithSlot) { + if (((TraitWithSlot) tr).getSlotIndex() == slotIndex) { + slotname = tr.getName(abc); + } + } + } + } else if (obj instanceof NewActivationAVM2Item) { + + for (int t = 0; t < body.traits.traits.size(); t++) { + if (body.traits.traits.get(t) instanceof TraitWithSlot) { + if (((TraitWithSlot) body.traits.traits.get(t)).getSlotIndex() == slotIndex) { + slotname = body.traits.traits.get(t).getName(abc); + } + } + + } + } + + if (slotname != null) { + if (value instanceof LocalRegAVM2Item) { + LocalRegAVM2Item lr = (LocalRegAVM2Item) value; + String slotNameStr = slotname.getName(constants, fullyQualifiedNames, true); + if (localRegNames.containsKey(lr.regIndex)) { + if (localRegNames.get(lr.regIndex).equals(slotNameStr)) { + return; //Register with same name to slot + } + } + } + } + + if (value.getNotCoerced().getThroughDuplicate() instanceof IncrementAVM2Item) { + GraphTargetItem inside = ((IncrementAVM2Item) value.getNotCoerced()).value.getThroughRegister().getNotCoerced().getThroughDuplicate(); + if (inside instanceof GetSlotAVM2Item) { + GetSlotAVM2Item slotItem = (GetSlotAVM2Item) inside; + if ((slotItem.scope.getThroughRegister() == obj.getThroughRegister()) + && (slotItem.slotName == slotname)) { + if (stack.size() > 0) { + GraphTargetItem top = stack.peek().getNotCoerced().getThroughDuplicate(); + if (top == inside) { + stack.pop(); + stack.push(new PostIncrementAVM2Item(ins, inside)); + } else if ((top instanceof IncrementAVM2Item) && (((IncrementAVM2Item) top).value == inside)) { + stack.pop(); + stack.push(new PreIncrementAVM2Item(ins, inside)); + } else { + output.add(new PostIncrementAVM2Item(ins, inside)); + } + } else { + output.add(new PostIncrementAVM2Item(ins, inside)); + } + return; + } + } + } + + if (value.getNotCoerced().getThroughDuplicate() instanceof DecrementAVM2Item) { + GraphTargetItem inside = ((DecrementAVM2Item) value.getNotCoerced()).value.getThroughRegister().getNotCoerced().getThroughDuplicate(); + if (inside instanceof GetSlotAVM2Item) { + GetSlotAVM2Item slotItem = (GetSlotAVM2Item) inside; + if ((slotItem.scope.getThroughRegister() == obj.getThroughRegister()) + && (slotItem.slotName == slotname)) { + if (stack.size() > 0) { + GraphTargetItem top = stack.peek().getNotCoerced().getThroughDuplicate(); + if (top == inside) { + stack.pop(); + stack.push(new PostDecrementAVM2Item(ins, inside)); + } else if ((top instanceof DecrementAVM2Item) && (((DecrementAVM2Item) top).value == inside)) { + stack.pop(); + stack.push(new PreDecrementAVM2Item(ins, inside)); + } else { + output.add(new PostDecrementAVM2Item(ins, inside)); + } + } else { + output.add(new PostDecrementAVM2Item(ins, inside)); + } + return; + } + } + } + + output.add(new SetSlotAVM2Item(ins, obj, slotname, value)); + } + + @Override + public String getObject(Stack stack, ABC abc, AVM2Instruction ins, List output, MethodBody body, HashMap localRegNames, List fullyQualifiedNames) { + int slotIndex = ins.operands[0]; + ////String obj = stack.get(1); + String slotname = ""; + for (int t = 0; t < body.traits.traits.size(); t++) { + if (body.traits.traits.get(t) instanceof TraitSlotConst) { + if (((TraitSlotConst) body.traits.traits.get(t)).slot_id == slotIndex) { + slotname = body.traits.traits.get(t).getName(abc).getName(abc.constants, fullyQualifiedNames, true); + } + } + + } + return slotname; + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -2; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/SetSuperIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/SetSuperIns.java index bd26115ce..bafd1f821 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/SetSuperIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/SetSuperIns.java @@ -1,78 +1,78 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.instructions.SetTypeIns; -import com.jpexs.decompiler.flash.abc.avm2.model.AVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.FullMultinameAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.SetSuperAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.flash.configuration.Configuration; -import com.jpexs.decompiler.flash.helpers.HighlightedTextWriter; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import com.jpexs.decompiler.graph.model.LocalData; -import java.util.HashMap; -import java.util.List; -import java.util.Stack; - -public class SetSuperIns extends InstructionDefinition implements SetTypeIns { - - public SetSuperIns() { - super(0x05, "setsuper", new int[]{AVM2Code.DAT_MULTINAME_INDEX}, true); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - int multinameIndex = ins.operands[0]; - - GraphTargetItem value = stack.pop(); - FullMultinameAVM2Item multiname = resolveMultiname(stack, constants, multinameIndex, ins); - GraphTargetItem obj = stack.pop(); - output.add(new SetSuperAVM2Item(ins, value, obj, multiname)); - } - - @Override - public String getObject(Stack stack, ABC abc, AVM2Instruction ins, List output, MethodBody body, HashMap localRegNames, List fullyQualifiedNames) throws InterruptedException { - int multinameIndex = ins.operands[0]; - String multiname = resolveMultinameNoPop(1, stack, abc.constants, multinameIndex, ins, fullyQualifiedNames); - HighlightedTextWriter writer = new HighlightedTextWriter(Configuration.getCodeFormatting(), false); - stack.get(1 + resolvedCount(abc.constants, multinameIndex)).toString(writer, LocalData.create(abc.constants, localRegNames, fullyQualifiedNames)); - String obj = writer.toString(); - return obj + ".super." + multiname; - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - int ret = -2; - int multinameIndex = ins.operands[0]; - if (abc.constants.getMultiname(multinameIndex).needsName()) { - ret--; - } - if (abc.constants.getMultiname(multinameIndex).needsNs()) { - ret--; - } - return ret; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.instructions.SetTypeIns; +import com.jpexs.decompiler.flash.abc.avm2.model.AVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.FullMultinameAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.SetSuperAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.flash.configuration.Configuration; +import com.jpexs.decompiler.flash.helpers.HighlightedTextWriter; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import com.jpexs.decompiler.graph.model.LocalData; +import java.util.HashMap; +import java.util.List; +import java.util.Stack; + +public class SetSuperIns extends InstructionDefinition implements SetTypeIns { + + public SetSuperIns() { + super(0x05, "setsuper", new int[]{AVM2Code.DAT_MULTINAME_INDEX}, true); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + int multinameIndex = ins.operands[0]; + + GraphTargetItem value = stack.pop(); + FullMultinameAVM2Item multiname = resolveMultiname(stack, constants, multinameIndex, ins); + GraphTargetItem obj = stack.pop(); + output.add(new SetSuperAVM2Item(ins, value, obj, multiname)); + } + + @Override + public String getObject(Stack stack, ABC abc, AVM2Instruction ins, List output, MethodBody body, HashMap localRegNames, List fullyQualifiedNames) throws InterruptedException { + int multinameIndex = ins.operands[0]; + String multiname = resolveMultinameNoPop(1, stack, abc.constants, multinameIndex, ins, fullyQualifiedNames); + HighlightedTextWriter writer = new HighlightedTextWriter(Configuration.getCodeFormatting(), false); + stack.get(1 + resolvedCount(abc.constants, multinameIndex)).toString(writer, LocalData.create(abc.constants, localRegNames, fullyQualifiedNames)); + String obj = writer.toString(); + return obj + ".super." + multiname; + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + int ret = -2; + int multinameIndex = ins.operands[0]; + if (abc.constants.getMultiname(multinameIndex).needsName()) { + ret--; + } + if (abc.constants.getMultiname(multinameIndex).needsNs()) { + ret--; + } + return ret; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/ThrowIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/ThrowIns.java index 75fd7d460..93bffd5d8 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/ThrowIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/ThrowIns.java @@ -1,53 +1,53 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.ThrowAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class ThrowIns extends InstructionDefinition { - - public ThrowIns() { - super(0x03, "throw", new int[]{}, true); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - output.add(new ThrowAVM2Item(ins, stack.pop())); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -1; - } - - @Override - public boolean isExitInstruction() { - return true; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.ThrowAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class ThrowIns extends InstructionDefinition { + + public ThrowIns() { + super(0x03, "throw", new int[]{}, true); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + output.add(new ThrowAVM2Item(ins, stack.pop())); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -1; + } + + @Override + public boolean isExitInstruction() { + return true; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/AbsJumpIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/AbsJumpIns.java index ea1a6b987..df9bda204 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/AbsJumpIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/AbsJumpIns.java @@ -1,38 +1,38 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; - -public class AbsJumpIns extends InstructionDefinition { - - public AbsJumpIns() { - super(0xEE, "abs_jump", new int[]{}, false /*?*/); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - throw new UnsupportedOperationException(); - } - - @Override - public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { - throw new UnsupportedOperationException(); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; + +public class AbsJumpIns extends InstructionDefinition { + + public AbsJumpIns() { + super(0xEE, "abs_jump", new int[]{}, false /*?*/); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + throw new UnsupportedOperationException(); + } + + @Override + public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { + throw new UnsupportedOperationException(); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/AddDIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/AddDIns.java index 0bcd2053d..ea212b34c 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/AddDIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/AddDIns.java @@ -1,33 +1,33 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; - -public class AddDIns extends InstructionDefinition { - - public AddDIns() { - super(0x9B, "add_d", new int[]{}, true /*?*/); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -2 + 1; // ? - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; + +public class AddDIns extends InstructionDefinition { + + public AddDIns() { + super(0x9B, "add_d", new int[]{}, true /*?*/); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -2 + 1; // ? + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/AddPIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/AddPIns.java index c6a5da446..036f72612 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/AddPIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/AddPIns.java @@ -1,27 +1,27 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; - -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; - -public class AddPIns extends InstructionDefinition { - - public AddPIns() { - super(0xB5, "add_p", new int[]{AVM2Code.DAT_DECIMAL_PARAMS}, true /*?*/); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; + +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; + +public class AddPIns extends InstructionDefinition { + + public AddPIns() { + super(0xB5, "add_p", new int[]{AVM2Code.DAT_DECIMAL_PARAMS}, true /*?*/); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/AllocIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/AllocIns.java index bdf9a9344..db0627dcc 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/AllocIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/AllocIns.java @@ -1,38 +1,38 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; - -public class AllocIns extends InstructionDefinition { - - public AllocIns() { - super(0xF6, "alloc", new int[]{}, true /*?*/); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - throw new UnsupportedOperationException(); - } - - @Override - public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { - throw new UnsupportedOperationException(); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; + +public class AllocIns extends InstructionDefinition { + + public AllocIns() { + super(0xF6, "alloc", new int[]{}, true /*?*/); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + throw new UnsupportedOperationException(); + } + + @Override + public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { + throw new UnsupportedOperationException(); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/BkptIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/BkptIns.java index e49ae83c5..4c2940e61 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/BkptIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/BkptIns.java @@ -1,26 +1,26 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; - -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; - -public class BkptIns extends InstructionDefinition { - - public BkptIns() { - super(0x01, "bkpt", new int[]{}, false); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; + +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; + +public class BkptIns extends InstructionDefinition { + + public BkptIns() { + super(0x01, "bkpt", new int[]{}, false); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/BkptLineIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/BkptLineIns.java index 17831555e..f1cf496d1 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/BkptLineIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/BkptLineIns.java @@ -1,27 +1,27 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; - -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; - -public class BkptLineIns extends InstructionDefinition { - - public BkptLineIns() { - super(0xF2, "bkptline", new int[]{AVM2Code.OPT_U30}, false /*?*/); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; + +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; + +public class BkptLineIns extends InstructionDefinition { + + public BkptLineIns() { + super(0xF2, "bkptline", new int[]{AVM2Code.OPT_U30}, false /*?*/); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/CallInterfaceIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/CallInterfaceIns.java index 2d0782890..824a1ea69 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/CallInterfaceIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/CallInterfaceIns.java @@ -1,27 +1,27 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; - -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; - -public class CallInterfaceIns extends InstructionDefinition { - - public CallInterfaceIns() { - super(0x4D, "callinterface", new int[]{AVM2Code.OPT_U30}, true); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; + +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; + +public class CallInterfaceIns extends InstructionDefinition { + + public CallInterfaceIns() { + super(0x4D, "callinterface", new int[]{AVM2Code.OPT_U30}, true); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/CallSuperIdIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/CallSuperIdIns.java index 830fa7b03..00d448787 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/CallSuperIdIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/CallSuperIdIns.java @@ -1,26 +1,26 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; - -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; - -public class CallSuperIdIns extends InstructionDefinition { - - public CallSuperIdIns() { - super(0x4B, "callsuperid", new int[]{}, true); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; + +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; + +public class CallSuperIdIns extends InstructionDefinition { + + public CallSuperIdIns() { + super(0x4B, "callsuperid", new int[]{}, true); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/CodeGenOpIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/CodeGenOpIns.java index e8690e252..0de03f444 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/CodeGenOpIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/CodeGenOpIns.java @@ -1,38 +1,38 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; - -public class CodeGenOpIns extends InstructionDefinition { - - public CodeGenOpIns() { - super(0xFD, "codegenop", new int[]{}, false /*?*/); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - throw new UnsupportedOperationException(); - } - - @Override - public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { - throw new UnsupportedOperationException(); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; + +public class CodeGenOpIns extends InstructionDefinition { + + public CodeGenOpIns() { + super(0xFD, "codegenop", new int[]{}, false /*?*/); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + throw new UnsupportedOperationException(); + } + + @Override + public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { + throw new UnsupportedOperationException(); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/CoerceBIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/CoerceBIns.java index e06ff2a14..eb264a857 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/CoerceBIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/CoerceBIns.java @@ -1,26 +1,26 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; - -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; - -public class CoerceBIns extends InstructionDefinition { - - public CoerceBIns() { - super(0x81, "coerce_b", new int[]{}, true); // stack: -1+1 - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; + +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; + +public class CoerceBIns extends InstructionDefinition { + + public CoerceBIns() { + super(0x81, "coerce_b", new int[]{}, true); // stack: -1+1 + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/CoerceDIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/CoerceDIns.java index ed3aaad04..034ef3e53 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/CoerceDIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/CoerceDIns.java @@ -1,26 +1,26 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; - -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; - -public class CoerceDIns extends InstructionDefinition { - - public CoerceDIns() { - super(0x84, "coerce_d", new int[]{}, true); // stack: -1+1 - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; + +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; + +public class CoerceDIns extends InstructionDefinition { + + public CoerceDIns() { + super(0x84, "coerce_d", new int[]{}, true); // stack: -1+1 + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/CoerceIIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/CoerceIIns.java index fcad5a7de..a81cab41d 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/CoerceIIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/CoerceIIns.java @@ -1,26 +1,26 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; - -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; - -public class CoerceIIns extends InstructionDefinition { - - public CoerceIIns() { - super(0x83, "coerce_i", new int[]{}, true); // stack: -1+1 - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; + +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; + +public class CoerceIIns extends InstructionDefinition { + + public CoerceIIns() { + super(0x83, "coerce_i", new int[]{}, true); // stack: -1+1 + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/CoerceOIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/CoerceOIns.java index b6a9d08b4..ed4c58aa3 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/CoerceOIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/CoerceOIns.java @@ -1,26 +1,26 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; - -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; - -public class CoerceOIns extends InstructionDefinition { - - public CoerceOIns() { - super(0x89, "coerce_o", new int[]{}, true); // stack: -1+1 - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; + +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; + +public class CoerceOIns extends InstructionDefinition { + + public CoerceOIns() { + super(0x89, "coerce_o", new int[]{}, true); // stack: -1+1 + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/CoerceUIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/CoerceUIns.java index bee75fc18..abd7e30f9 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/CoerceUIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/CoerceUIns.java @@ -1,26 +1,26 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; - -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; - -public class CoerceUIns extends InstructionDefinition { - - public CoerceUIns() { - super(0x88, "coerce_u", new int[]{}, true); // stack: -1+1 - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; + +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; + +public class CoerceUIns extends InstructionDefinition { + + public CoerceUIns() { + super(0x88, "coerce_u", new int[]{}, true); // stack: -1+1 + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/ConcatIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/ConcatIns.java index 3b60a5779..198eaa59f 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/ConcatIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/ConcatIns.java @@ -1,33 +1,33 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; - -public class ConcatIns extends InstructionDefinition { - - public ConcatIns() { - super(0x9A, "concat", new int[]{}, true /*?*/); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -2 + 1; // ? - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; + +public class ConcatIns extends InstructionDefinition { + + public ConcatIns() { + super(0x9A, "concat", new int[]{}, true /*?*/); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -2 + 1; // ? + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/ConvertF4Ins.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/ConvertF4Ins.java index c4a5d861e..49b95c061 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/ConvertF4Ins.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/ConvertF4Ins.java @@ -1,26 +1,26 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; - -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; - -public class ConvertF4Ins extends InstructionDefinition { - - public ConvertF4Ins() { - super(0x7B, "convert_f4", new int[]{}, true); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; + +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; + +public class ConvertF4Ins extends InstructionDefinition { + + public ConvertF4Ins() { + super(0x7B, "convert_f4", new int[]{}, true); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/ConvertMIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/ConvertMIns.java index 68d529f8a..b18cbb5ac 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/ConvertMIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/ConvertMIns.java @@ -1,26 +1,26 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; - -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; - -public class ConvertMIns extends InstructionDefinition { - - public ConvertMIns() { - super(0x79, "convert_m", new int[]{}, true); // -1 +1 - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; + +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; + +public class ConvertMIns extends InstructionDefinition { + + public ConvertMIns() { + super(0x79, "convert_m", new int[]{}, true); // -1 +1 + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/ConvertMPIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/ConvertMPIns.java index a369cb0b6..8f561985f 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/ConvertMPIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/ConvertMPIns.java @@ -1,34 +1,34 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; - -import com.jpexs.decompiler.flash.abc.ABC; -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; - -public class ConvertMPIns extends InstructionDefinition { - - public ConvertMPIns() { - super(0x7A, "convert_m_p", new int[]{AVM2Code.DAT_DECIMAL_PARAMS}, true); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - throw new UnsupportedOperationException(); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; + +import com.jpexs.decompiler.flash.abc.ABC; +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; + +public class ConvertMPIns extends InstructionDefinition { + + public ConvertMPIns() { + super(0x7A, "convert_m_p", new int[]{AVM2Code.DAT_DECIMAL_PARAMS}, true); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + throw new UnsupportedOperationException(); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/DecLocalPIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/DecLocalPIns.java index 0745fc6e4..008f2e0f4 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/DecLocalPIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/DecLocalPIns.java @@ -1,27 +1,27 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; - -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; - -public class DecLocalPIns extends InstructionDefinition { - - public DecLocalPIns() { - super(0x9F, "declocal_p", new int[]{AVM2Code.DAT_DECIMAL_PARAMS, AVM2Code.DAT_REGISTER_INDEX}, false /*?*/); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; + +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; + +public class DecLocalPIns extends InstructionDefinition { + + public DecLocalPIns() { + super(0x9F, "declocal_p", new int[]{AVM2Code.DAT_DECIMAL_PARAMS, AVM2Code.DAT_REGISTER_INDEX}, false /*?*/); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/DecodeIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/DecodeIns.java index 5f460c949..a2717f5c0 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/DecodeIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/DecodeIns.java @@ -1,38 +1,38 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; - -public class DecodeIns extends InstructionDefinition { - - public DecodeIns() { - super(0xFF, "decode", new int[]{}, false /*?*/); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - throw new UnsupportedOperationException(); - } - - @Override - public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { - throw new UnsupportedOperationException(); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; + +public class DecodeIns extends InstructionDefinition { + + public DecodeIns() { + super(0xFF, "decode", new int[]{}, false /*?*/); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + throw new UnsupportedOperationException(); + } + + @Override + public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { + throw new UnsupportedOperationException(); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/DecrementPIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/DecrementPIns.java index f1b825b9f..eb7e04f3a 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/DecrementPIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/DecrementPIns.java @@ -1,27 +1,27 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; - -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; - -public class DecrementPIns extends InstructionDefinition { - - public DecrementPIns() { - super(0x9E, "decrement_p", new int[]{AVM2Code.DAT_DECIMAL_PARAMS}, true /*?*/); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; + +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; + +public class DecrementPIns extends InstructionDefinition { + + public DecrementPIns() { + super(0x9E, "decrement_p", new int[]{AVM2Code.DAT_DECIMAL_PARAMS}, true /*?*/); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/DelDescendantsIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/DelDescendantsIns.java index ee23750a0..5ef6ece7e 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/DelDescendantsIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/DelDescendantsIns.java @@ -1,33 +1,33 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; - -public class DelDescendantsIns extends InstructionDefinition { - - public DelDescendantsIns() { - super(0x5B, "deldescendants", new int[]{}, true); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - throw new UnsupportedOperationException(); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; + +public class DelDescendantsIns extends InstructionDefinition { + + public DelDescendantsIns() { + super(0x5B, "deldescendants", new int[]{}, true); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + throw new UnsupportedOperationException(); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/DeletePropertyLateIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/DeletePropertyLateIns.java index 75a87974f..93d0e8ab5 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/DeletePropertyLateIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/DeletePropertyLateIns.java @@ -1,33 +1,33 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; - -public class DeletePropertyLateIns extends InstructionDefinition { - - public DeletePropertyLateIns() { - super(0x6B, "deletepropertylate", new int[]{}, true /*?*/); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - throw new UnsupportedOperationException(); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; + +public class DeletePropertyLateIns extends InstructionDefinition { + + public DeletePropertyLateIns() { + super(0x6B, "deletepropertylate", new int[]{}, true /*?*/); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + throw new UnsupportedOperationException(); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/DividePIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/DividePIns.java index 48b2c062f..17ca63005 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/DividePIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/DividePIns.java @@ -1,34 +1,34 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; - -import com.jpexs.decompiler.flash.abc.ABC; -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; - -public class DividePIns extends InstructionDefinition { - - public DividePIns() { - super(0xB8, "divide_p", new int[]{AVM2Code.DAT_DECIMAL_PARAMS}, true /*?*/); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -2 + 1; // ? - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; + +import com.jpexs.decompiler.flash.abc.ABC; +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; + +public class DividePIns extends InstructionDefinition { + + public DividePIns() { + super(0xB8, "divide_p", new int[]{AVM2Code.DAT_DECIMAL_PARAMS}, true /*?*/); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -2 + 1; // ? + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/DoubleToAtomIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/DoubleToAtomIns.java index 9b665008b..3588a09c2 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/DoubleToAtomIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/DoubleToAtomIns.java @@ -1,38 +1,38 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; - -public class DoubleToAtomIns extends InstructionDefinition { - - public DoubleToAtomIns() { - super(0xFB, "doubletoatom", new int[]{}, true /*?*/); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - throw new UnsupportedOperationException(); - } - - @Override - public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { - throw new UnsupportedOperationException(); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; + +public class DoubleToAtomIns extends InstructionDefinition { + + public DoubleToAtomIns() { + super(0xFB, "doubletoatom", new int[]{}, true /*?*/); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + throw new UnsupportedOperationException(); + } + + @Override + public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { + throw new UnsupportedOperationException(); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/FindPropGlobalIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/FindPropGlobalIns.java index e0309a923..fe225fda8 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/FindPropGlobalIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/FindPropGlobalIns.java @@ -1,39 +1,39 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; - -import com.jpexs.decompiler.flash.abc.ABC; -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; - -public class FindPropGlobalIns extends InstructionDefinition { - - public FindPropGlobalIns() { - super(0x5C, "findpropglobal", new int[]{AVM2Code.DAT_MULTINAME_INDEX}, true); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - throw new UnsupportedOperationException(); - } - - @Override - public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { - throw new UnsupportedOperationException(); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; + +import com.jpexs.decompiler.flash.abc.ABC; +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; + +public class FindPropGlobalIns extends InstructionDefinition { + + public FindPropGlobalIns() { + super(0x5C, "findpropglobal", new int[]{AVM2Code.DAT_MULTINAME_INDEX}, true); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + throw new UnsupportedOperationException(); + } + + @Override + public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { + throw new UnsupportedOperationException(); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/FindPropGlobalStrictIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/FindPropGlobalStrictIns.java index c20214063..a2229d089 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/FindPropGlobalStrictIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/FindPropGlobalStrictIns.java @@ -1,39 +1,39 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; - -import com.jpexs.decompiler.flash.abc.ABC; -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; - -public class FindPropGlobalStrictIns extends InstructionDefinition { - - public FindPropGlobalStrictIns() { - super(0x5B, "findpropglobalstrict", new int[]{AVM2Code.DAT_MULTINAME_INDEX}, true); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - throw new UnsupportedOperationException(); - } - - @Override - public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { - throw new UnsupportedOperationException(); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; + +import com.jpexs.decompiler.flash.abc.ABC; +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; + +public class FindPropGlobalStrictIns extends InstructionDefinition { + + public FindPropGlobalStrictIns() { + super(0x5B, "findpropglobalstrict", new int[]{AVM2Code.DAT_MULTINAME_INDEX}, true); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + throw new UnsupportedOperationException(); + } + + @Override + public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { + throw new UnsupportedOperationException(); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/GetOuterScopeIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/GetOuterScopeIns.java index ba5428d57..ebaa82c11 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/GetOuterScopeIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/GetOuterScopeIns.java @@ -1,39 +1,39 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; - -import com.jpexs.decompiler.flash.abc.ABC; -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; - -public class GetOuterScopeIns extends InstructionDefinition { - - public GetOuterScopeIns() { - super(0x67, "getouterscope", new int[]{AVM2Code.DAT_MULTINAME_INDEX}, false); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - throw new UnsupportedOperationException(); - } - - @Override - public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { - throw new UnsupportedOperationException(); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; + +import com.jpexs.decompiler.flash.abc.ABC; +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; + +public class GetOuterScopeIns extends InstructionDefinition { + + public GetOuterScopeIns() { + super(0x67, "getouterscope", new int[]{AVM2Code.DAT_MULTINAME_INDEX}, false); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + throw new UnsupportedOperationException(); + } + + @Override + public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { + throw new UnsupportedOperationException(); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/GetPropertyLateIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/GetPropertyLateIns.java index 60f4b7fba..bc9a4dde0 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/GetPropertyLateIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/GetPropertyLateIns.java @@ -1,33 +1,33 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; - -public class GetPropertyLateIns extends InstructionDefinition { - - public GetPropertyLateIns() { - super(0x67, "getpropertylate", new int[]{}, true /*?*/); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - throw new UnsupportedOperationException(); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; + +public class GetPropertyLateIns extends InstructionDefinition { + + public GetPropertyLateIns() { + super(0x67, "getpropertylate", new int[]{}, true /*?*/); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + throw new UnsupportedOperationException(); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/IncLocalPIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/IncLocalPIns.java index a84c01546..f68491966 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/IncLocalPIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/IncLocalPIns.java @@ -1,27 +1,27 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; - -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; - -public class IncLocalPIns extends InstructionDefinition { - - public IncLocalPIns() { - super(0x9D, "inclocal_p", new int[]{AVM2Code.DAT_DECIMAL_PARAMS, AVM2Code.DAT_REGISTER_INDEX}, true /*?*/); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; + +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; + +public class IncLocalPIns extends InstructionDefinition { + + public IncLocalPIns() { + super(0x9D, "inclocal_p", new int[]{AVM2Code.DAT_DECIMAL_PARAMS, AVM2Code.DAT_REGISTER_INDEX}, true /*?*/); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/IncrementPIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/IncrementPIns.java index 9594e0152..bc3d45fb0 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/IncrementPIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/IncrementPIns.java @@ -1,27 +1,27 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; - -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; - -public class IncrementPIns extends InstructionDefinition { - - public IncrementPIns() { - super(0x9C, "increment_p", new int[]{AVM2Code.DAT_DECIMAL_PARAMS}, true /*?*/); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; + +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; + +public class IncrementPIns extends InstructionDefinition { + + public IncrementPIns() { + super(0x9C, "increment_p", new int[]{AVM2Code.DAT_DECIMAL_PARAMS}, true /*?*/); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/InvalidIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/InvalidIns.java index 207be88ba..6f616f73a 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/InvalidIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/InvalidIns.java @@ -1,26 +1,26 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; - -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; - -public class InvalidIns extends InstructionDefinition { - - public InvalidIns() { - super(0xED, "invalid", new int[]{}, false); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; + +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; + +public class InvalidIns extends InstructionDefinition { + + public InvalidIns() { + super(0xED, "invalid", new int[]{}, false); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/Lf32x4Ins.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/Lf32x4Ins.java index 2c98ef51e..30436d278 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/Lf32x4Ins.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/Lf32x4Ins.java @@ -1,26 +1,26 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; - -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; - -public class Lf32x4Ins extends InstructionDefinition { - - public Lf32x4Ins() { - super(0x0A, "lf32x4", new int[]{}, true); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; + +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; + +public class Lf32x4Ins extends InstructionDefinition { + + public Lf32x4Ins() { + super(0x0A, "lf32x4", new int[]{}, true); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/MarkIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/MarkIns.java index 7012d06f7..5df231689 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/MarkIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/MarkIns.java @@ -1,38 +1,38 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; - -public class MarkIns extends InstructionDefinition { - - public MarkIns() { - super(0xF7, "mark", new int[]{}, false /*?*/); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - throw new UnsupportedOperationException(); - } - - @Override - public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { - throw new UnsupportedOperationException(); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; + +public class MarkIns extends InstructionDefinition { + + public MarkIns() { + super(0xF7, "mark", new int[]{}, false /*?*/); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + throw new UnsupportedOperationException(); + } + + @Override + public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { + throw new UnsupportedOperationException(); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/ModuloPIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/ModuloPIns.java index 306b26220..e23c6afdf 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/ModuloPIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/ModuloPIns.java @@ -1,34 +1,34 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; - -import com.jpexs.decompiler.flash.abc.ABC; -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; - -public class ModuloPIns extends InstructionDefinition { - - public ModuloPIns() { - super(0xB9, "modulo_p", new int[]{AVM2Code.DAT_DECIMAL_PARAMS}, true /*?*/); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -2 + 1; // ? - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; + +import com.jpexs.decompiler.flash.abc.ABC; +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; + +public class ModuloPIns extends InstructionDefinition { + + public ModuloPIns() { + super(0xB9, "modulo_p", new int[]{AVM2Code.DAT_DECIMAL_PARAMS}, true /*?*/); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -2 + 1; // ? + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/MultiplyPIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/MultiplyPIns.java index b05c1f4ea..5833f40a5 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/MultiplyPIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/MultiplyPIns.java @@ -1,34 +1,34 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; - -import com.jpexs.decompiler.flash.abc.ABC; -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; - -public class MultiplyPIns extends InstructionDefinition { - - public MultiplyPIns() { - super(0xB7, "multiply_p", new int[]{AVM2Code.DAT_DECIMAL_PARAMS}, true /*?*/); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -2 + 1; // ? - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; + +import com.jpexs.decompiler.flash.abc.ABC; +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; + +public class MultiplyPIns extends InstructionDefinition { + + public MultiplyPIns() { + super(0xB7, "multiply_p", new int[]{AVM2Code.DAT_DECIMAL_PARAMS}, true /*?*/); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -2 + 1; // ? + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/NegatePIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/NegatePIns.java index bdc27aa05..a5ce3a957 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/NegatePIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/NegatePIns.java @@ -1,39 +1,39 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; - -import com.jpexs.decompiler.flash.abc.ABC; -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; - -public class NegatePIns extends InstructionDefinition { - - public NegatePIns() { - super(0x8F, "negate_p", new int[]{AVM2Code.DAT_DECIMAL_PARAMS}, true /*?*/); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - throw new UnsupportedOperationException(); - } - - @Override - public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { - throw new UnsupportedOperationException(); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; + +import com.jpexs.decompiler.flash.abc.ABC; +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; + +public class NegatePIns extends InstructionDefinition { + + public NegatePIns() { + super(0x8F, "negate_p", new int[]{AVM2Code.DAT_DECIMAL_PARAMS}, true /*?*/); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + throw new UnsupportedOperationException(); + } + + @Override + public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { + throw new UnsupportedOperationException(); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/PrologueIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/PrologueIns.java index 838046280..ee1dbffc7 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/PrologueIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/PrologueIns.java @@ -1,38 +1,38 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; - -public class PrologueIns extends InstructionDefinition { - - public PrologueIns() { - super(0xF9, "prologue", new int[]{}, false /*?*/); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - throw new UnsupportedOperationException(); - } - - @Override - public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { - throw new UnsupportedOperationException(); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; + +public class PrologueIns extends InstructionDefinition { + + public PrologueIns() { + super(0xF9, "prologue", new int[]{}, false /*?*/); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + throw new UnsupportedOperationException(); + } + + @Override + public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { + throw new UnsupportedOperationException(); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/PushConstantIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/PushConstantIns.java index bf9443feb..2b3e99348 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/PushConstantIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/PushConstantIns.java @@ -1,34 +1,34 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; - -import com.jpexs.decompiler.flash.abc.ABC; -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; - -public class PushConstantIns extends InstructionDefinition { - - public PushConstantIns() { - super(0x22, "pushconstant", new int[]{AVM2Code.DAT_STRING_INDEX}, false /*?*/); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return 1; // ? - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; + +import com.jpexs.decompiler.flash.abc.ABC; +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; + +public class PushConstantIns extends InstructionDefinition { + + public PushConstantIns() { + super(0x22, "pushconstant", new int[]{AVM2Code.DAT_STRING_INDEX}, false /*?*/); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return 1; // ? + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/PushDNanIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/PushDNanIns.java index 06cf767b2..2615ccf51 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/PushDNanIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/PushDNanIns.java @@ -1,33 +1,33 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; - -public class PushDNanIns extends InstructionDefinition { - - public PushDNanIns() { - super(0x34, "pushdnan", new int[]{}, true); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return 1; // ? - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; + +public class PushDNanIns extends InstructionDefinition { + + public PushDNanIns() { + super(0x34, "pushdnan", new int[]{}, true); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return 1; // ? + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/PushDecimalIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/PushDecimalIns.java index 9e9018297..8927beb3d 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/PushDecimalIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/PushDecimalIns.java @@ -1,34 +1,34 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; - -import com.jpexs.decompiler.flash.abc.ABC; -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; - -public class PushDecimalIns extends InstructionDefinition { - - public PushDecimalIns() { - super(0x33, "pushdecimal", new int[]{AVM2Code.DAT_DECIMAL_INDEX}, true); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return 1; // ? - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; + +import com.jpexs.decompiler.flash.abc.ABC; +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; + +public class PushDecimalIns extends InstructionDefinition { + + public PushDecimalIns() { + super(0x33, "pushdecimal", new int[]{AVM2Code.DAT_DECIMAL_INDEX}, true); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return 1; // ? + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/PushFloat4Ins.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/PushFloat4Ins.java index aff5f8433..ebe697beb 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/PushFloat4Ins.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/PushFloat4Ins.java @@ -1,26 +1,26 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; - -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; - -public class PushFloat4Ins extends InstructionDefinition { - - public PushFloat4Ins() { - super(0x54, "pushfloat4", new int[]{}, false); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; + +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; + +public class PushFloat4Ins extends InstructionDefinition { + + public PushFloat4Ins() { + super(0x54, "pushfloat4", new int[]{}, false); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/PushUninitializedIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/PushUninitializedIns.java index 5fec60cf1..67c58810f 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/PushUninitializedIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/PushUninitializedIns.java @@ -1,39 +1,39 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; - -import com.jpexs.decompiler.flash.abc.ABC; -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; - -public class PushUninitializedIns extends InstructionDefinition { - - public PushUninitializedIns() { - super(0x22, "pushuninitialized", new int[]{AVM2Code.OPT_U30}, false /*?*/); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - throw new UnsupportedOperationException(); - } - - @Override - public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { - throw new UnsupportedOperationException(); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; + +import com.jpexs.decompiler.flash.abc.ABC; +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; + +public class PushUninitializedIns extends InstructionDefinition { + + public PushUninitializedIns() { + super(0x22, "pushuninitialized", new int[]{AVM2Code.OPT_U30}, false /*?*/); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + throw new UnsupportedOperationException(); + } + + @Override + public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { + throw new UnsupportedOperationException(); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/SendEnterIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/SendEnterIns.java index 4246fca1e..c708598ac 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/SendEnterIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/SendEnterIns.java @@ -1,38 +1,38 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; - -public class SendEnterIns extends InstructionDefinition { - - public SendEnterIns() { - super(0xFA, "sendenter", new int[]{}, false /*?*/); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - throw new UnsupportedOperationException(); - } - - @Override - public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { - throw new UnsupportedOperationException(); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; + +public class SendEnterIns extends InstructionDefinition { + + public SendEnterIns() { + super(0xFA, "sendenter", new int[]{}, false /*?*/); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + throw new UnsupportedOperationException(); + } + + @Override + public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { + throw new UnsupportedOperationException(); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/SetPropertyLateIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/SetPropertyLateIns.java index be22f8145..6196e88e2 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/SetPropertyLateIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/SetPropertyLateIns.java @@ -1,38 +1,38 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; - -public class SetPropertyLateIns extends InstructionDefinition { - - public SetPropertyLateIns() { - super(0x69, "setpropertylate", new int[]{}, true /*?*/); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - throw new UnsupportedOperationException(); - } - - @Override - public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { - throw new UnsupportedOperationException(); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; + +public class SetPropertyLateIns extends InstructionDefinition { + + public SetPropertyLateIns() { + super(0x69, "setpropertylate", new int[]{}, true /*?*/); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + throw new UnsupportedOperationException(); + } + + @Override + public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { + throw new UnsupportedOperationException(); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/Sf32x4Ins.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/Sf32x4Ins.java index 1df138d70..581e8180d 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/Sf32x4Ins.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/Sf32x4Ins.java @@ -1,26 +1,26 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; - -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; - -public class Sf32x4Ins extends InstructionDefinition { - - public Sf32x4Ins() { - super(0x0B, "sf32x4", new int[]{}, true); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; + +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; + +public class Sf32x4Ins extends InstructionDefinition { + + public Sf32x4Ins() { + super(0x0B, "sf32x4", new int[]{}, true); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/SubtractPIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/SubtractPIns.java index f3819770c..6b28990d9 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/SubtractPIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/SubtractPIns.java @@ -1,39 +1,39 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; - -import com.jpexs.decompiler.flash.abc.ABC; -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; - -public class SubtractPIns extends InstructionDefinition { - - public SubtractPIns() { - super(0xB6, "subtract_p", new int[]{AVM2Code.DAT_DECIMAL_PARAMS}, true /*?*/); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - throw new UnsupportedOperationException(); - } - - @Override - public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { - throw new UnsupportedOperationException(); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; + +import com.jpexs.decompiler.flash.abc.ABC; +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; + +public class SubtractPIns extends InstructionDefinition { + + public SubtractPIns() { + super(0xB6, "subtract_p", new int[]{AVM2Code.DAT_DECIMAL_PARAMS}, true /*?*/); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + throw new UnsupportedOperationException(); + } + + @Override + public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { + throw new UnsupportedOperationException(); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/SweepIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/SweepIns.java index e96342fde..ec49435d5 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/SweepIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/SweepIns.java @@ -1,38 +1,38 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; - -public class SweepIns extends InstructionDefinition { - - public SweepIns() { - super(0xFC, "sweep", new int[]{}, false /*?*/); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - throw new UnsupportedOperationException(); - } - - @Override - public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { - throw new UnsupportedOperationException(); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; + +public class SweepIns extends InstructionDefinition { + + public SweepIns() { + super(0xFC, "sweep", new int[]{}, false /*?*/); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + throw new UnsupportedOperationException(); + } + + @Override + public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { + throw new UnsupportedOperationException(); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/TimestampIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/TimestampIns.java index de593af6f..8dcb3529a 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/TimestampIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/TimestampIns.java @@ -1,26 +1,26 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; - -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; - -public class TimestampIns extends InstructionDefinition { - - public TimestampIns() { - super(0xF3, "timestamp", new int[]{}, false /*?*/); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; + +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; + +public class TimestampIns extends InstructionDefinition { + + public TimestampIns() { + super(0xF3, "timestamp", new int[]{}, false /*?*/); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/VerifyOpIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/VerifyOpIns.java index d68eab434..6648b5475 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/VerifyOpIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/VerifyOpIns.java @@ -1,38 +1,38 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; - -public class VerifyOpIns extends InstructionDefinition { - - public VerifyOpIns() { - super(0xFE, "verifyop", new int[]{}, false /*?*/); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - throw new UnsupportedOperationException(); - } - - @Override - public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { - throw new UnsupportedOperationException(); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; + +public class VerifyOpIns extends InstructionDefinition { + + public VerifyOpIns() { + super(0xFE, "verifyop", new int[]{}, false /*?*/); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + throw new UnsupportedOperationException(); + } + + @Override + public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { + throw new UnsupportedOperationException(); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/VerifyPassIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/VerifyPassIns.java index a33154918..53e6e59d2 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/VerifyPassIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/VerifyPassIns.java @@ -1,38 +1,38 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; - -public class VerifyPassIns extends InstructionDefinition { - - public VerifyPassIns() { - super(0xF5, "verifypass", new int[]{}, false /*?*/); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - throw new UnsupportedOperationException(); - } - - @Override - public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { - throw new UnsupportedOperationException(); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; + +public class VerifyPassIns extends InstructionDefinition { + + public VerifyPassIns() { + super(0xF5, "verifypass", new int[]{}, false /*?*/); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + throw new UnsupportedOperationException(); + } + + @Override + public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { + throw new UnsupportedOperationException(); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/WbIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/WbIns.java index 7bee81aa2..e7998fa97 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/WbIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other2/WbIns.java @@ -1,38 +1,38 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; - -public class WbIns extends InstructionDefinition { - - public WbIns() { - super(0xF8, "wb", new int[]{}, false /*?*/); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - throw new UnsupportedOperationException(); - } - - @Override - public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { - throw new UnsupportedOperationException(); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.other2; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; + +public class WbIns extends InstructionDefinition { + + public WbIns() { + super(0xF8, "wb", new int[]{}, false /*?*/); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + throw new UnsupportedOperationException(); + } + + @Override + public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { + throw new UnsupportedOperationException(); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/DupIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/DupIns.java index 9e19c47f2..d5b87f709 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/DupIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/DupIns.java @@ -1,60 +1,60 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.stack; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import com.jpexs.decompiler.graph.model.DuplicateItem; -import java.util.HashMap; -import java.util.List; - -public class DupIns extends InstructionDefinition { - - public DupIns() { - super(0x2a, "dup", new int[]{}, false); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - Object obj = lda.operandStack.pop(); - lda.operandStack.push(obj); - lda.operandStack.push(obj); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem v = stack.pop(); - stack.push(v); - stack.push(new DuplicateItem(ins, v)); - //v.moreSrc.add(new GraphSourceItemPos(ins, 0)); - - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -1 + 2; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.stack; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import com.jpexs.decompiler.graph.model.DuplicateItem; +import java.util.HashMap; +import java.util.List; + +public class DupIns extends InstructionDefinition { + + public DupIns() { + super(0x2a, "dup", new int[]{}, false); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + Object obj = lda.operandStack.pop(); + lda.operandStack.push(obj); + lda.operandStack.push(obj); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem v = stack.pop(); + stack.push(v); + stack.push(new DuplicateItem(ins, v)); + //v.moreSrc.add(new GraphSourceItemPos(ins, 0)); + + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -1 + 2; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PopIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PopIns.java index 3707bd81b..b0466e1bd 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PopIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PopIns.java @@ -1,60 +1,60 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.stack; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -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.model.IntegerValueAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class PopIns extends InstructionDefinition { - - public PopIns() { - super(0x29, "pop", new int[]{}, false); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - lda.operandStack.pop(); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - if (stack.size() > 0) { - GraphTargetItem top = stack.pop(); - //Note: Commands like "5;" - numbers are unsupported as it collide with try..finally block decompilation. TODO: allow this somehow - if (!(top instanceof IntegerValueAVM2Item)) { - output.add(top); - } - } - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.stack; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +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.model.IntegerValueAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class PopIns extends InstructionDefinition { + + public PopIns() { + super(0x29, "pop", new int[]{}, false); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + lda.operandStack.pop(); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + if (stack.size() > 0) { + GraphTargetItem top = stack.pop(); + //Note: Commands like "5;" - numbers are unsupported as it collide with try..finally block decompilation. TODO: allow this somehow + if (!(top instanceof IntegerValueAVM2Item)) { + output.add(top); + } + } + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PopScopeIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PopScopeIns.java index ed07d0cb8..4fd38fe29 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PopScopeIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PopScopeIns.java @@ -1,59 +1,59 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.stack; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -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.model.WithEndAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.WithObjectAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class PopScopeIns extends InstructionDefinition { - - public PopScopeIns() { - super(0x1d, "popscope", new int[]{}, false); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - lda.scopeStack.pop(); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem scope = scopeStack.pop(); - if (scope instanceof WithObjectAVM2Item) { - scope = ((WithObjectAVM2Item) scope).scope; - output.add(new WithEndAVM2Item(ins, scope)); - } - } - - @Override - public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { - return -1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.stack; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +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.model.WithEndAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.WithObjectAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class PopScopeIns extends InstructionDefinition { + + public PopScopeIns() { + super(0x1d, "popscope", new int[]{}, false); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + lda.scopeStack.pop(); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem scope = scopeStack.pop(); + if (scope instanceof WithObjectAVM2Item) { + scope = ((WithObjectAVM2Item) scope).scope; + output.add(new WithEndAVM2Item(ins, scope)); + } + } + + @Override + public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { + return -1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushByteIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushByteIns.java index ecc0610c5..b2b86b4a6 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushByteIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushByteIns.java @@ -1,54 +1,54 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.stack; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -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.model.IntegerValueAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class PushByteIns extends InstructionDefinition implements PushIntegerTypeIns { - - public PushByteIns() { - super(0x24, "pushbyte", new int[]{AVM2Code.OPT_BYTE}, false); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - lda.operandStack.push(arguments.get(0)); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - stack.push(new IntegerValueAVM2Item(ins, (long) ins.operands[0])); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.stack; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +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.model.IntegerValueAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class PushByteIns extends InstructionDefinition implements PushIntegerTypeIns { + + public PushByteIns() { + super(0x24, "pushbyte", new int[]{AVM2Code.OPT_BYTE}, false); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + lda.operandStack.push(arguments.get(0)); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + stack.push(new IntegerValueAVM2Item(ins, (long) ins.operands[0])); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushDoubleIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushDoubleIns.java index 2b2fad241..133ea10b1 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushDoubleIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushDoubleIns.java @@ -1,54 +1,54 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.stack; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -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.model.FloatValueAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class PushDoubleIns extends InstructionDefinition { - - public PushDoubleIns() { - super(0x2f, "pushdouble", new int[]{AVM2Code.DAT_DOUBLE_INDEX}, false); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - lda.operandStack.push(arguments.get(0)); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - stack.push(new FloatValueAVM2Item(ins, constants.getDouble(ins.operands[0]))); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.stack; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +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.model.FloatValueAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class PushDoubleIns extends InstructionDefinition { + + public PushDoubleIns() { + super(0x2f, "pushdouble", new int[]{AVM2Code.DAT_DOUBLE_INDEX}, false); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + lda.operandStack.push(arguments.get(0)); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + stack.push(new FloatValueAVM2Item(ins, constants.getDouble(ins.operands[0]))); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushFalseIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushFalseIns.java index 0578fec9c..8c32f6243 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushFalseIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushFalseIns.java @@ -1,54 +1,54 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.stack; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -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.model.BooleanAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class PushFalseIns extends InstructionDefinition { - - public PushFalseIns() { - super(0x27, "pushfalse", new int[]{}, false); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - lda.operandStack.push(Boolean.FALSE); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - stack.push(new BooleanAVM2Item(ins, Boolean.FALSE)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.stack; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +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.model.BooleanAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class PushFalseIns extends InstructionDefinition { + + public PushFalseIns() { + super(0x27, "pushfalse", new int[]{}, false); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + lda.operandStack.push(Boolean.FALSE); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + stack.push(new BooleanAVM2Item(ins, Boolean.FALSE)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushIntIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushIntIns.java index bbe391022..9a6d065fa 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushIntIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushIntIns.java @@ -1,54 +1,54 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.stack; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -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.model.IntegerValueAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class PushIntIns extends InstructionDefinition implements PushIntegerTypeIns { - - public PushIntIns() { - super(0x2d, "pushint", new int[]{AVM2Code.DAT_INT_INDEX}, false); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - lda.operandStack.push(arguments.get(0)); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - stack.push(new IntegerValueAVM2Item(ins, constants.getInt(ins.operands[0]))); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.stack; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +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.model.IntegerValueAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class PushIntIns extends InstructionDefinition implements PushIntegerTypeIns { + + public PushIntIns() { + super(0x2d, "pushint", new int[]{AVM2Code.DAT_INT_INDEX}, false); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + lda.operandStack.push(arguments.get(0)); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + stack.push(new IntegerValueAVM2Item(ins, constants.getInt(ins.operands[0]))); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushNamespaceIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushNamespaceIns.java index 296666d33..c8eb8d13f 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushNamespaceIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushNamespaceIns.java @@ -1,48 +1,48 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.stack; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.NameSpaceAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class PushNamespaceIns extends InstructionDefinition { - - public PushNamespaceIns() { - super(0x31, "pushnamespace", new int[]{AVM2Code.OPT_U30}, false); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - stack.push(new NameSpaceAVM2Item(ins, ins.operands[0])); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.stack; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.NameSpaceAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class PushNamespaceIns extends InstructionDefinition { + + public PushNamespaceIns() { + super(0x31, "pushnamespace", new int[]{AVM2Code.OPT_U30}, false); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + stack.push(new NameSpaceAVM2Item(ins, ins.operands[0])); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushNanIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushNanIns.java index b7be53959..b691062ae 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushNanIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushNanIns.java @@ -1,48 +1,48 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.stack; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.NanAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class PushNanIns extends InstructionDefinition { - - public PushNanIns() { - super(0x28, "pushnan", new int[]{}, false); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - stack.push(new NanAVM2Item(ins)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.stack; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.NanAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class PushNanIns extends InstructionDefinition { + + public PushNanIns() { + super(0x28, "pushnan", new int[]{}, false); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + stack.push(new NanAVM2Item(ins)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushNullIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushNullIns.java index cbdfa59d0..f78407412 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushNullIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushNullIns.java @@ -1,48 +1,48 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.stack; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.NullAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class PushNullIns extends InstructionDefinition { - - public PushNullIns() { - super(0x20, "pushnull", new int[]{}, false); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - stack.push(new NullAVM2Item(ins)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.stack; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.NullAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class PushNullIns extends InstructionDefinition { + + public PushNullIns() { + super(0x20, "pushnull", new int[]{}, false); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + stack.push(new NullAVM2Item(ins)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushScopeIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushScopeIns.java index d1d8e4ab2..3ef167ace 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushScopeIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushScopeIns.java @@ -1,58 +1,58 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.stack; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class PushScopeIns extends InstructionDefinition { - - public PushScopeIns() { - super(0x30, "pushscope", new int[]{}, false); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - lda.scopeStack.push(lda.operandStack.pop()); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - scopeStack.push(stack.pop()); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -1; - } - - @Override - public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { - return 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.stack; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class PushScopeIns extends InstructionDefinition { + + public PushScopeIns() { + super(0x30, "pushscope", new int[]{}, false); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + lda.scopeStack.push(lda.operandStack.pop()); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + scopeStack.push(stack.pop()); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -1; + } + + @Override + public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { + return 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushShortIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushShortIns.java index e751fdde3..e3f2725d6 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushShortIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushShortIns.java @@ -1,54 +1,54 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.stack; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -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.model.IntegerValueAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class PushShortIns extends InstructionDefinition implements PushIntegerTypeIns { - - public PushShortIns() { - super(0x25, "pushshort", new int[]{AVM2Code.OPT_U30}, false); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - lda.operandStack.push((long) ((Number) arguments.get(0)).shortValue()); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - stack.push(new IntegerValueAVM2Item(ins, (long) (short) ins.operands[0])); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.stack; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +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.model.IntegerValueAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class PushShortIns extends InstructionDefinition implements PushIntegerTypeIns { + + public PushShortIns() { + super(0x25, "pushshort", new int[]{AVM2Code.OPT_U30}, false); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + lda.operandStack.push((long) ((Number) arguments.get(0)).shortValue()); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + stack.push(new IntegerValueAVM2Item(ins, (long) (short) ins.operands[0])); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushStringIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushStringIns.java index 01efeafaf..8fd2686ac 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushStringIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushStringIns.java @@ -1,54 +1,54 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.stack; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -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.model.StringAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class PushStringIns extends InstructionDefinition { - - public PushStringIns() { - super(0x2c, "pushstring", new int[]{AVM2Code.DAT_STRING_INDEX}, false); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - lda.operandStack.push(arguments.get(0)); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - stack.push(new StringAVM2Item(ins, constants.getString(ins.operands[0]))); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.stack; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +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.model.StringAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class PushStringIns extends InstructionDefinition { + + public PushStringIns() { + super(0x2c, "pushstring", new int[]{AVM2Code.DAT_STRING_INDEX}, false); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + lda.operandStack.push(arguments.get(0)); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + stack.push(new StringAVM2Item(ins, constants.getString(ins.operands[0]))); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushTrueIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushTrueIns.java index 7b9d23286..dc86afa3f 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushTrueIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushTrueIns.java @@ -1,54 +1,54 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.stack; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -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.model.BooleanAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class PushTrueIns extends InstructionDefinition { - - public PushTrueIns() { - super(0x26, "pushtrue", new int[]{}, false); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - lda.operandStack.push(Boolean.TRUE); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - stack.push(new BooleanAVM2Item(ins, Boolean.TRUE)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.stack; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +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.model.BooleanAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class PushTrueIns extends InstructionDefinition { + + public PushTrueIns() { + super(0x26, "pushtrue", new int[]{}, false); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + lda.operandStack.push(Boolean.TRUE); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + stack.push(new BooleanAVM2Item(ins, Boolean.TRUE)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushUIntIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushUIntIns.java index dfdc500ec..65e20068e 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushUIntIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushUIntIns.java @@ -1,54 +1,54 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.stack; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -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.model.IntegerValueAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class PushUIntIns extends InstructionDefinition implements PushIntegerTypeIns { - - public PushUIntIns() { - super(0x2e, "pushuint", new int[]{AVM2Code.DAT_UINT_INDEX}, false); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - lda.operandStack.push(arguments.get(0)); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - stack.push(new IntegerValueAVM2Item(ins, constants.getUInt(ins.operands[0]))); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.stack; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +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.model.IntegerValueAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class PushUIntIns extends InstructionDefinition implements PushIntegerTypeIns { + + public PushUIntIns() { + super(0x2e, "pushuint", new int[]{AVM2Code.DAT_UINT_INDEX}, false); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + lda.operandStack.push(arguments.get(0)); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + stack.push(new IntegerValueAVM2Item(ins, constants.getUInt(ins.operands[0]))); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushUndefinedIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushUndefinedIns.java index 61247047c..205919364 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushUndefinedIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushUndefinedIns.java @@ -1,48 +1,48 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.stack; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.UndefinedAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class PushUndefinedIns extends InstructionDefinition { - - public PushUndefinedIns() { - super(0x21, "pushundefined", new int[]{}, false); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - stack.push(new UndefinedAVM2Item(ins)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.stack; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.UndefinedAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class PushUndefinedIns extends InstructionDefinition { + + public PushUndefinedIns() { + super(0x21, "pushundefined", new int[]{}, false); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + stack.push(new UndefinedAVM2Item(ins)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushWithIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushWithIns.java index 4f91c8f3b..4f60eba25 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushWithIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushWithIns.java @@ -1,57 +1,57 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.stack; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.WithAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.WithObjectAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class PushWithIns extends InstructionDefinition { - - public PushWithIns() { - super(0x1c, "pushwith", new int[]{}, false); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem w = stack.pop(); - WithObjectAVM2Item wot = new WithObjectAVM2Item(ins, w); - scopeStack.push(wot); - output.add(new WithAVM2Item(ins, w)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -1; - } - - @Override - public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { - return 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.stack; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.WithAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.WithObjectAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class PushWithIns extends InstructionDefinition { + + public PushWithIns() { + super(0x1c, "pushwith", new int[]{}, false); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem w = stack.pop(); + WithObjectAVM2Item wot = new WithObjectAVM2Item(ins, w); + scopeStack.push(wot); + output.add(new WithAVM2Item(ins, w)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -1; + } + + @Override + public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { + return 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/SwapIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/SwapIns.java index 97bacc4d0..7927dbbc4 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/SwapIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/SwapIns.java @@ -1,63 +1,63 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.stack; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphSourceItemPos; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class SwapIns extends InstructionDefinition { - - public SwapIns() { - super(0x2b, "swap", new int[]{}, false); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - Object obj1 = lda.operandStack.pop(); - Object obj2 = lda.operandStack.pop(); - lda.operandStack.push(obj1); - lda.operandStack.push(obj2); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - - GraphTargetItem o1 = stack.pop(); - GraphTargetItem o2 = stack.pop(); - stack.push(o1); - stack.push(o2); - o1.moreSrc.add(new GraphSourceItemPos(ins, 0)); - o2.moreSrc.add(new GraphSourceItemPos(ins, 0)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -2 + 2; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.stack; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphSourceItemPos; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class SwapIns extends InstructionDefinition { + + public SwapIns() { + super(0x2b, "swap", new int[]{}, false); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + Object obj1 = lda.operandStack.pop(); + Object obj2 = lda.operandStack.pop(); + lda.operandStack.push(obj1); + lda.operandStack.push(obj2); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + + GraphTargetItem o1 = stack.pop(); + GraphTargetItem o2 = stack.pop(); + stack.push(o1); + stack.push(o2); + o1.moreSrc.add(new GraphSourceItemPos(ins, 0)); + o2.moreSrc.add(new GraphSourceItemPos(ins, 0)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -2 + 2; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/ApplyTypeIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/ApplyTypeIns.java index e13042ac6..efcfcb876 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/ApplyTypeIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/ApplyTypeIns.java @@ -1,67 +1,67 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.types; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -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.model.ApplyTypeAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; - -public class ApplyTypeIns extends InstructionDefinition { - - public ApplyTypeIns() { - super(0x53, "applytype", new int[]{AVM2Code.DAT_ARG_COUNT}, true); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - int argCount = (int) ((Long) arguments.get(0)).longValue(); - List params = new ArrayList<>(); - for (int i = 0; i < argCount; i++) { - params.add(lda.operandStack.pop()); - } - Collections.reverse(params); - //TODO: pop type and push type - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - int argCount = ins.operands[0]; - List params = new ArrayList<>(); - for (int i = 0; i < argCount; i++) { - params.add(0, stack.pop()); - } - stack.push(new ApplyTypeAVM2Item(ins, stack.pop(), params)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -ins.operands[0] - 1 + 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.types; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +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.model.ApplyTypeAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; + +public class ApplyTypeIns extends InstructionDefinition { + + public ApplyTypeIns() { + super(0x53, "applytype", new int[]{AVM2Code.DAT_ARG_COUNT}, true); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + int argCount = (int) ((Long) arguments.get(0)).longValue(); + List params = new ArrayList<>(); + for (int i = 0; i < argCount; i++) { + params.add(lda.operandStack.pop()); + } + Collections.reverse(params); + //TODO: pop type and push type + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + int argCount = ins.operands[0]; + List params = new ArrayList<>(); + for (int i = 0; i < argCount; i++) { + params.add(0, stack.pop()); + } + stack.push(new ApplyTypeAVM2Item(ins, stack.pop(), params)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -ins.operands[0] - 1 + 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/AsTypeIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/AsTypeIns.java index ababa2187..4f9383e46 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/AsTypeIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/AsTypeIns.java @@ -1,62 +1,62 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.types; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -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.model.FullMultinameAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.AsTypeAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class AsTypeIns extends InstructionDefinition { - - public AsTypeIns() { - super(0x86, "astype", new int[]{AVM2Code.DAT_MULTINAME_INDEX}, true); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - //Long typeIndex = (Long) arguments.get(0); - Object obj = lda.operandStack.pop(); - //if multiname[typeIndex]==obj - lda.operandStack.push(obj); - //else push null - - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem val = stack.pop(); - - stack.push(new AsTypeAVM2Item(ins, val, new FullMultinameAVM2Item(ins, ins.operands[0]))); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -1 + 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.types; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +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.model.FullMultinameAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.AsTypeAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class AsTypeIns extends InstructionDefinition { + + public AsTypeIns() { + super(0x86, "astype", new int[]{AVM2Code.DAT_MULTINAME_INDEX}, true); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + //Long typeIndex = (Long) arguments.get(0); + Object obj = lda.operandStack.pop(); + //if multiname[typeIndex]==obj + lda.operandStack.push(obj); + //else push null + + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem val = stack.pop(); + + stack.push(new AsTypeAVM2Item(ins, val, new FullMultinameAVM2Item(ins, ins.operands[0]))); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -1 + 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/AsTypeLateIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/AsTypeLateIns.java index 9c31e6a04..e11e04daa 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/AsTypeLateIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/AsTypeLateIns.java @@ -1,60 +1,60 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.types; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -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.model.operations.AsTypeAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class AsTypeLateIns extends InstructionDefinition { - - public AsTypeLateIns() { - super(0x87, "astypelate", new int[]{}, true); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - //Object objClass = lda.operandStack.pop(); - Object obj = lda.operandStack.pop(); - //if obj.class=objClass - lda.operandStack.push(obj); - //else push null - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem cls = stack.pop(); - GraphTargetItem val = stack.pop(); - stack.push(new AsTypeAVM2Item(ins, val, cls)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -2 + 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.types; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +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.model.operations.AsTypeAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class AsTypeLateIns extends InstructionDefinition { + + public AsTypeLateIns() { + super(0x87, "astypelate", new int[]{}, true); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + //Object objClass = lda.operandStack.pop(); + Object obj = lda.operandStack.pop(); + //if obj.class=objClass + lda.operandStack.push(obj); + //else push null + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem cls = stack.pop(); + GraphTargetItem val = stack.pop(); + stack.push(new AsTypeAVM2Item(ins, val, cls)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -2 + 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/CoerceAIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/CoerceAIns.java index 127c3dc53..b6d923de8 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/CoerceAIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/CoerceAIns.java @@ -1,65 +1,65 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.types; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -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.model.CoerceAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import com.jpexs.decompiler.graph.TypeItem; -import java.util.HashMap; -import java.util.List; - -public class CoerceAIns extends InstructionDefinition implements CoerceOrConvertTypeIns { - - public CoerceAIns() { - super(0x82, "coerce_a", new int[]{}, true); - } - - public String getTargetType() { - return "*"; - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - //coerce any type - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - stack.push(new CoerceAVM2Item(ins, stack.pop(), getTargetType(constants, ins, fullyQualifiedNames))); - - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -1 + 1; - } - - @Override - public GraphTargetItem getTargetType(AVM2ConstantPool constants, AVM2Instruction ins, List fullyQualifiedNames) { - return TypeItem.UNBOUNDED; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.types; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +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.model.CoerceAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import com.jpexs.decompiler.graph.TypeItem; +import java.util.HashMap; +import java.util.List; + +public class CoerceAIns extends InstructionDefinition implements CoerceOrConvertTypeIns { + + public CoerceAIns() { + super(0x82, "coerce_a", new int[]{}, true); + } + + public String getTargetType() { + return "*"; + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + //coerce any type + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + stack.push(new CoerceAVM2Item(ins, stack.pop(), getTargetType(constants, ins, fullyQualifiedNames))); + + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -1 + 1; + } + + @Override + public GraphTargetItem getTargetType(AVM2ConstantPool constants, AVM2Instruction ins, List fullyQualifiedNames) { + return TypeItem.UNBOUNDED; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/CoerceIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/CoerceIns.java index c56f48944..c467cf78f 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/CoerceIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/CoerceIns.java @@ -1,63 +1,63 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.types; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -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.model.CoerceAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.parser.script.PropertyAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class CoerceIns extends InstructionDefinition implements CoerceOrConvertTypeIns { - - public CoerceIns() { - super(0x80, "coerce", new int[]{AVM2Code.DAT_MULTINAME_INDEX}, true); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - //int multinameIndex = (int) ((Long) arguments.get(0)).longValue(); - //push and pop coerced value to specified type - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - int multinameIndex = ins.operands[0]; - stack.push(new CoerceAVM2Item(ins, stack.pop(), PropertyAVM2Item.multinameToType(multinameIndex, constants))); - } - - @Override - public GraphTargetItem getTargetType(AVM2ConstantPool constants, AVM2Instruction ins, List fullyQualifiedNames) { - int multinameIndex = ins.operands[0]; - return PropertyAVM2Item.multinameToType(multinameIndex, constants); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -1 + 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.types; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +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.model.CoerceAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.parser.script.PropertyAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class CoerceIns extends InstructionDefinition implements CoerceOrConvertTypeIns { + + public CoerceIns() { + super(0x80, "coerce", new int[]{AVM2Code.DAT_MULTINAME_INDEX}, true); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + //int multinameIndex = (int) ((Long) arguments.get(0)).longValue(); + //push and pop coerced value to specified type + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + int multinameIndex = ins.operands[0]; + stack.push(new CoerceAVM2Item(ins, stack.pop(), PropertyAVM2Item.multinameToType(multinameIndex, constants))); + } + + @Override + public GraphTargetItem getTargetType(AVM2ConstantPool constants, AVM2Instruction ins, List fullyQualifiedNames) { + int multinameIndex = ins.operands[0]; + return PropertyAVM2Item.multinameToType(multinameIndex, constants); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -1 + 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/CoerceSIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/CoerceSIns.java index 4a5803a94..208258e96 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/CoerceSIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/CoerceSIns.java @@ -1,61 +1,61 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.types; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -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.model.CoerceAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import com.jpexs.decompiler.graph.TypeItem; -import java.util.HashMap; -import java.util.List; - -public class CoerceSIns extends InstructionDefinition implements CoerceOrConvertTypeIns { - - public CoerceSIns() { - super(0x85, "coerce_s", new int[]{}, true); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - Object obj = lda.operandStack.pop(); - lda.operandStack.push(obj.toString()); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - stack.push(new CoerceAVM2Item(ins, stack.pop(), getTargetType(constants, ins, fullyQualifiedNames))); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -1 + 1; - } - - @Override - public GraphTargetItem getTargetType(AVM2ConstantPool constants, AVM2Instruction ins, List fullyQualifiedNames) { - return new TypeItem("String"); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.types; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +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.model.CoerceAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import com.jpexs.decompiler.graph.TypeItem; +import java.util.HashMap; +import java.util.List; + +public class CoerceSIns extends InstructionDefinition implements CoerceOrConvertTypeIns { + + public CoerceSIns() { + super(0x85, "coerce_s", new int[]{}, true); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + Object obj = lda.operandStack.pop(); + lda.operandStack.push(obj.toString()); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + stack.push(new CoerceAVM2Item(ins, stack.pop(), getTargetType(constants, ins, fullyQualifiedNames))); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -1 + 1; + } + + @Override + public GraphTargetItem getTargetType(AVM2ConstantPool constants, AVM2Instruction ins, List fullyQualifiedNames) { + return new TypeItem("String"); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/ConvertBIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/ConvertBIns.java index 27aa45ff7..711d63a45 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/ConvertBIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/ConvertBIns.java @@ -1,71 +1,71 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.types; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -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.model.ConvertAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import com.jpexs.decompiler.graph.TypeItem; -import java.util.HashMap; -import java.util.List; - -public class ConvertBIns extends InstructionDefinition implements CoerceOrConvertTypeIns { - - public ConvertBIns() { - super(0x76, "convert_b", new int[]{}, true); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - Object value = lda.operandStack.pop(); - boolean bval; - if (value instanceof Boolean) { - bval = (Boolean) value; - } else if (value instanceof Long) { - bval = (Long) value != 0; - } else if (value instanceof String) { - bval = !((String) value).isEmpty(); - } else { - bval = true; - } - lda.operandStack.push((Boolean) bval); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - stack.push(new ConvertAVM2Item(ins, stack.pop(), getTargetType(constants, ins, fullyQualifiedNames))); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -1 + 1; - } - - @Override - public GraphTargetItem getTargetType(AVM2ConstantPool constants, AVM2Instruction ins, List fullyQualifiedNames) { - return new TypeItem("Boolean"); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.types; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +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.model.ConvertAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import com.jpexs.decompiler.graph.TypeItem; +import java.util.HashMap; +import java.util.List; + +public class ConvertBIns extends InstructionDefinition implements CoerceOrConvertTypeIns { + + public ConvertBIns() { + super(0x76, "convert_b", new int[]{}, true); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + Object value = lda.operandStack.pop(); + boolean bval; + if (value instanceof Boolean) { + bval = (Boolean) value; + } else if (value instanceof Long) { + bval = (Long) value != 0; + } else if (value instanceof String) { + bval = !((String) value).isEmpty(); + } else { + bval = true; + } + lda.operandStack.push((Boolean) bval); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + stack.push(new ConvertAVM2Item(ins, stack.pop(), getTargetType(constants, ins, fullyQualifiedNames))); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -1 + 1; + } + + @Override + public GraphTargetItem getTargetType(AVM2ConstantPool constants, AVM2Instruction ins, List fullyQualifiedNames) { + return new TypeItem("Boolean"); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/ConvertDIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/ConvertDIns.java index bba81267b..9e57af2a7 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/ConvertDIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/ConvertDIns.java @@ -1,79 +1,79 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.types; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -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.model.ConvertAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import com.jpexs.decompiler.graph.TypeItem; -import java.util.HashMap; -import java.util.List; - -public class ConvertDIns extends InstructionDefinition implements CoerceOrConvertTypeIns { - - public ConvertDIns() { - super(0x75, "convert_d", new int[]{}, true); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - Object value = lda.operandStack.pop(); - double ret; - if (value == null) { - ret = 0; - } else if (value instanceof Boolean) { - if ((Boolean) value) { - ret = 1; - } else { - ret = 0; - } - } else if (value instanceof Long) { - ret = (Long) value; - } else if (value instanceof Double) { - ret = (Double) value; - } else if (value instanceof String) { - ret = Double.parseDouble((String) value); - } else { - ret = 1; //must call toPrimitive - } - lda.operandStack.push(ret); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - stack.push(new ConvertAVM2Item(ins, stack.pop(), getTargetType(constants, ins, fullyQualifiedNames))); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -1 + 1; - } - - @Override - public GraphTargetItem getTargetType(AVM2ConstantPool constants, AVM2Instruction ins, List fullyQualifiedNames) { - return new TypeItem("Number"); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.types; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +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.model.ConvertAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import com.jpexs.decompiler.graph.TypeItem; +import java.util.HashMap; +import java.util.List; + +public class ConvertDIns extends InstructionDefinition implements CoerceOrConvertTypeIns { + + public ConvertDIns() { + super(0x75, "convert_d", new int[]{}, true); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + Object value = lda.operandStack.pop(); + double ret; + if (value == null) { + ret = 0; + } else if (value instanceof Boolean) { + if ((Boolean) value) { + ret = 1; + } else { + ret = 0; + } + } else if (value instanceof Long) { + ret = (Long) value; + } else if (value instanceof Double) { + ret = (Double) value; + } else if (value instanceof String) { + ret = Double.parseDouble((String) value); + } else { + ret = 1; //must call toPrimitive + } + lda.operandStack.push(ret); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + stack.push(new ConvertAVM2Item(ins, stack.pop(), getTargetType(constants, ins, fullyQualifiedNames))); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -1 + 1; + } + + @Override + public GraphTargetItem getTargetType(AVM2ConstantPool constants, AVM2Instruction ins, List fullyQualifiedNames) { + return new TypeItem("Number"); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/ConvertIIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/ConvertIIns.java index 0d3a3d6c4..bbf364d64 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/ConvertIIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/ConvertIIns.java @@ -1,77 +1,77 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.types; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -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.model.ConvertAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import com.jpexs.decompiler.graph.TypeItem; -import java.util.HashMap; -import java.util.List; - -public class ConvertIIns extends InstructionDefinition implements CoerceOrConvertTypeIns { - - public ConvertIIns() { - super(0x73, "convert_i", new int[]{}, true); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - Object value = lda.operandStack.pop(); - long ret; - if (value == null) { - ret = 0; - } else if (value instanceof Boolean) { - if ((Boolean) value) { - ret = 1; - } else { - ret = 0; - } - } else if (value instanceof Long) { - ret = (Long) value; - } else if (value instanceof String) { - ret = Long.parseLong((String) value); - } else { - ret = 1; //must call toPrimitive - } - lda.operandStack.push(ret); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - stack.push(new ConvertAVM2Item(ins, stack.pop(), getTargetType(constants, ins, fullyQualifiedNames))); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -1 + 1; - } - - @Override - public GraphTargetItem getTargetType(AVM2ConstantPool constants, AVM2Instruction ins, List fullyQualifiedNames) { - return new TypeItem("int"); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.types; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +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.model.ConvertAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import com.jpexs.decompiler.graph.TypeItem; +import java.util.HashMap; +import java.util.List; + +public class ConvertIIns extends InstructionDefinition implements CoerceOrConvertTypeIns { + + public ConvertIIns() { + super(0x73, "convert_i", new int[]{}, true); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + Object value = lda.operandStack.pop(); + long ret; + if (value == null) { + ret = 0; + } else if (value instanceof Boolean) { + if ((Boolean) value) { + ret = 1; + } else { + ret = 0; + } + } else if (value instanceof Long) { + ret = (Long) value; + } else if (value instanceof String) { + ret = Long.parseLong((String) value); + } else { + ret = 1; //must call toPrimitive + } + lda.operandStack.push(ret); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + stack.push(new ConvertAVM2Item(ins, stack.pop(), getTargetType(constants, ins, fullyQualifiedNames))); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -1 + 1; + } + + @Override + public GraphTargetItem getTargetType(AVM2ConstantPool constants, AVM2Instruction ins, List fullyQualifiedNames) { + return new TypeItem("int"); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/ConvertOIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/ConvertOIns.java index 7464f4856..adf450631 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/ConvertOIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/ConvertOIns.java @@ -1,60 +1,60 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.types; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -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.model.ConvertAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import com.jpexs.decompiler.graph.TypeItem; -import java.util.HashMap; -import java.util.List; - -public class ConvertOIns extends InstructionDefinition implements CoerceOrConvertTypeIns { - - public ConvertOIns() { - super(0x77, "convert_o", new int[]{}, true); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - //throw if pop is not object - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - stack.push(new ConvertAVM2Item(ins, stack.pop(), getTargetType(constants, ins, fullyQualifiedNames))); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -1 + 1; - } - - @Override - public GraphTargetItem getTargetType(AVM2ConstantPool constants, AVM2Instruction ins, List fullyQualifiedNames) { - return new TypeItem("Object"); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.types; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +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.model.ConvertAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import com.jpexs.decompiler.graph.TypeItem; +import java.util.HashMap; +import java.util.List; + +public class ConvertOIns extends InstructionDefinition implements CoerceOrConvertTypeIns { + + public ConvertOIns() { + super(0x77, "convert_o", new int[]{}, true); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + //throw if pop is not object + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + stack.push(new ConvertAVM2Item(ins, stack.pop(), getTargetType(constants, ins, fullyQualifiedNames))); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -1 + 1; + } + + @Override + public GraphTargetItem getTargetType(AVM2ConstantPool constants, AVM2Instruction ins, List fullyQualifiedNames) { + return new TypeItem("Object"); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/ConvertSIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/ConvertSIns.java index 3f0fb7482..73ba8c14a 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/ConvertSIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/ConvertSIns.java @@ -1,61 +1,61 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.types; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -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.model.ConvertAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import com.jpexs.decompiler.graph.TypeItem; -import java.util.HashMap; -import java.util.List; - -public class ConvertSIns extends InstructionDefinition implements CoerceOrConvertTypeIns { - - public ConvertSIns() { - super(0x70, "convert_s", new int[]{}, true); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - Object obj = lda.operandStack.pop(); - lda.operandStack.push(obj.toString()); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - stack.push(new ConvertAVM2Item(ins, stack.pop(), getTargetType(constants, ins, fullyQualifiedNames))); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -1 + 1; - } - - @Override - public GraphTargetItem getTargetType(AVM2ConstantPool constants, AVM2Instruction ins, List fullyQualifiedNames) { - return new TypeItem("String"); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.types; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +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.model.ConvertAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import com.jpexs.decompiler.graph.TypeItem; +import java.util.HashMap; +import java.util.List; + +public class ConvertSIns extends InstructionDefinition implements CoerceOrConvertTypeIns { + + public ConvertSIns() { + super(0x70, "convert_s", new int[]{}, true); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + Object obj = lda.operandStack.pop(); + lda.operandStack.push(obj.toString()); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + stack.push(new ConvertAVM2Item(ins, stack.pop(), getTargetType(constants, ins, fullyQualifiedNames))); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -1 + 1; + } + + @Override + public GraphTargetItem getTargetType(AVM2ConstantPool constants, AVM2Instruction ins, List fullyQualifiedNames) { + return new TypeItem("String"); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/ConvertUIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/ConvertUIns.java index 3fa5636c3..b2ade84d3 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/ConvertUIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/ConvertUIns.java @@ -1,60 +1,60 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.types; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -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.model.ConvertAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import com.jpexs.decompiler.graph.TypeItem; -import java.util.HashMap; -import java.util.List; - -public class ConvertUIns extends InstructionDefinition implements CoerceOrConvertTypeIns { - - public ConvertUIns() { - super(0x74, "convert_u", new int[]{}, true); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - throw new UnsupportedOperationException("Cannot convert to uint "); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - stack.push(new ConvertAVM2Item(ins, stack.pop(), getTargetType(constants, ins, fullyQualifiedNames))); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -1 + 1; - } - - @Override - public GraphTargetItem getTargetType(AVM2ConstantPool constants, AVM2Instruction ins, List fullyQualifiedNames) { - return new TypeItem("uint"); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.types; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +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.model.ConvertAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import com.jpexs.decompiler.graph.TypeItem; +import java.util.HashMap; +import java.util.List; + +public class ConvertUIns extends InstructionDefinition implements CoerceOrConvertTypeIns { + + public ConvertUIns() { + super(0x74, "convert_u", new int[]{}, true); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + throw new UnsupportedOperationException("Cannot convert to uint "); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + stack.push(new ConvertAVM2Item(ins, stack.pop(), getTargetType(constants, ins, fullyQualifiedNames))); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -1 + 1; + } + + @Override + public GraphTargetItem getTargetType(AVM2ConstantPool constants, AVM2Instruction ins, List fullyQualifiedNames) { + return new TypeItem("uint"); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/InstanceOfIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/InstanceOfIns.java index d97a6b3e4..83505db8e 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/InstanceOfIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/InstanceOfIns.java @@ -1,50 +1,50 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.types; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.InstanceOfAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class InstanceOfIns extends InstructionDefinition { - - public InstanceOfIns() { - super(0xb1, "instanceof", new int[]{}, true); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem type = stack.pop(); - GraphTargetItem value = stack.pop(); - stack.push(new InstanceOfAVM2Item(ins, value, type)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -2 + 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.types; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.InstanceOfAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class InstanceOfIns extends InstructionDefinition { + + public InstanceOfIns() { + super(0xb1, "instanceof", new int[]{}, true); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem type = stack.pop(); + GraphTargetItem value = stack.pop(); + stack.push(new InstanceOfAVM2Item(ins, value, type)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -2 + 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/IsTypeIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/IsTypeIns.java index daddc0630..37c5e803b 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/IsTypeIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/IsTypeIns.java @@ -1,51 +1,51 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.types; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.FullMultinameAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.IsTypeAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class IsTypeIns extends InstructionDefinition { - - public IsTypeIns() { - super(0xb2, "istype", new int[]{AVM2Code.DAT_MULTINAME_INDEX}, true); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - int multinameIndex = ins.operands[0]; - GraphTargetItem value = stack.pop(); - stack.push(new IsTypeAVM2Item(ins, value, new FullMultinameAVM2Item(ins, multinameIndex))); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -1 + 1; //may not be runtime multiname - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.types; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.FullMultinameAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.IsTypeAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class IsTypeIns extends InstructionDefinition { + + public IsTypeIns() { + super(0xb2, "istype", new int[]{AVM2Code.DAT_MULTINAME_INDEX}, true); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + int multinameIndex = ins.operands[0]; + GraphTargetItem value = stack.pop(); + stack.push(new IsTypeAVM2Item(ins, value, new FullMultinameAVM2Item(ins, multinameIndex))); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -1 + 1; //may not be runtime multiname + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/IsTypeLateIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/IsTypeLateIns.java index 0b52d7ba4..734f3fc1c 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/IsTypeLateIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/IsTypeLateIns.java @@ -1,50 +1,50 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.types; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.IsTypeAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class IsTypeLateIns extends InstructionDefinition { - - public IsTypeLateIns() { - super(0xb3, "istypelate", new int[]{}, true); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem type = stack.pop(); - GraphTargetItem value = stack.pop(); - stack.push(new IsTypeAVM2Item(ins, value, type)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -2 + 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.types; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.IsTypeAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class IsTypeLateIns extends InstructionDefinition { + + public IsTypeLateIns() { + super(0xb3, "istypelate", new int[]{}, true); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem type = stack.pop(); + GraphTargetItem value = stack.pop(); + stack.push(new IsTypeAVM2Item(ins, value, type)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -2 + 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/TypeOfIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/TypeOfIns.java index 93c390866..c879ba890 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/TypeOfIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/types/TypeOfIns.java @@ -1,48 +1,48 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.types; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -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.InstructionDefinition; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.TypeOfAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class TypeOfIns extends InstructionDefinition { - - public TypeOfIns() { - super(0x95, "typeof", new int[]{}, false); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - stack.push(new TypeOfAVM2Item(ins, stack.pop())); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -1 + 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.types; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +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.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.TypeOfAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class TypeOfIns extends InstructionDefinition { + + public TypeOfIns() { + super(0x95, "typeof", new int[]{}, false); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + stack.push(new TypeOfAVM2Item(ins, stack.pop())); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -1 + 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/xml/CheckFilterIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/xml/CheckFilterIns.java index 890c8e2a6..c2eb0e741 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/xml/CheckFilterIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/xml/CheckFilterIns.java @@ -1,55 +1,55 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.xml; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -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.model.FilteredCheckAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class CheckFilterIns extends InstructionDefinition { - - public CheckFilterIns() { - super(0x78, "checkfilter", new int[]{}, true); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - //if pop() is not XML|XMLList throw - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem obj = stack.pop(); - stack.push(new FilteredCheckAVM2Item(ins, obj)); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -1 + 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.xml; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +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.model.FilteredCheckAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class CheckFilterIns extends InstructionDefinition { + + public CheckFilterIns() { + super(0x78, "checkfilter", new int[]{}, true); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + //if pop() is not XML|XMLList throw + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem obj = stack.pop(); + stack.push(new FilteredCheckAVM2Item(ins, obj)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -1 + 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/xml/DXNSIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/xml/DXNSIns.java index 1554e35a8..a6066933c 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/xml/DXNSIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/xml/DXNSIns.java @@ -1,54 +1,54 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.xml; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -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.model.DefaultXMLNamespace; -import com.jpexs.decompiler.flash.abc.avm2.model.StringAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class DXNSIns extends InstructionDefinition { - - public DXNSIns() { - super(0x06, "dxns", new int[]{AVM2Code.DAT_STRING_INDEX}, true); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - int strIndex = (int) ((Long) arguments.get(0)).longValue(); - String s = constants.getString(strIndex); - System.out.println("Set default XML space " + s); - - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - //FIXME!!! - search namespace - output.add(new DefaultXMLNamespace(ins, new StringAVM2Item(ins, constants.getString(ins.operands[0])))); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.xml; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +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.model.DefaultXMLNamespace; +import com.jpexs.decompiler.flash.abc.avm2.model.StringAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class DXNSIns extends InstructionDefinition { + + public DXNSIns() { + super(0x06, "dxns", new int[]{AVM2Code.DAT_STRING_INDEX}, true); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + int strIndex = (int) ((Long) arguments.get(0)).longValue(); + String s = constants.getString(strIndex); + System.out.println("Set default XML space " + s); + + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + //FIXME!!! - search namespace + output.add(new DefaultXMLNamespace(ins, new StringAVM2Item(ins, constants.getString(ins.operands[0])))); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/xml/DXNSLateIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/xml/DXNSLateIns.java index dec64d8b4..f87ab09af 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/xml/DXNSLateIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/xml/DXNSLateIns.java @@ -1,57 +1,57 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.xml; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -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.model.DefaultXMLNamespace; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class DXNSLateIns extends InstructionDefinition { - - public DXNSLateIns() { - super(0x07, "dxnslate", new int[]{}, true); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - String s = lda.operandStack.pop().toString(); - System.out.println("Set default XML space " + s); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - GraphTargetItem xmlns = stack.pop(); - output.add(new DefaultXMLNamespace(ins, xmlns)); - - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.xml; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +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.model.DefaultXMLNamespace; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class DXNSLateIns extends InstructionDefinition { + + public DXNSLateIns() { + super(0x07, "dxnslate", new int[]{}, true); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + String s = lda.operandStack.pop().toString(); + System.out.println("Set default XML space " + s); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + GraphTargetItem xmlns = stack.pop(); + output.add(new DefaultXMLNamespace(ins, xmlns)); + + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/xml/EscXAttrIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/xml/EscXAttrIns.java index 81949e578..a6ed1b67b 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/xml/EscXAttrIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/xml/EscXAttrIns.java @@ -1,56 +1,56 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.xml; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -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.model.EscapeXAttrAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class EscXAttrIns extends InstructionDefinition { - - public EscXAttrIns() { - super(0x72, "esc_xattr", new int[]{}, true); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - String s = lda.operandStack.pop().toString(); - //escape - lda.operandStack.push(s); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - stack.push(new EscapeXAttrAVM2Item(ins, stack.pop())); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -1 + 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.xml; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +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.model.EscapeXAttrAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class EscXAttrIns extends InstructionDefinition { + + public EscXAttrIns() { + super(0x72, "esc_xattr", new int[]{}, true); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + String s = lda.operandStack.pop().toString(); + //escape + lda.operandStack.push(s); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + stack.push(new EscapeXAttrAVM2Item(ins, stack.pop())); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -1 + 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/xml/EscXElemIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/xml/EscXElemIns.java index 1a00051c6..0aff0f51f 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/xml/EscXElemIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/xml/EscXElemIns.java @@ -1,56 +1,56 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.instructions.xml; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; -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.model.EscapeXElemAVM2Item; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.TranslateStack; -import java.util.HashMap; -import java.util.List; - -public class EscXElemIns extends InstructionDefinition { - - public EscXElemIns() { - super(0x71, "esc_xelem", new int[]{}, true); - } - - @Override - public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { - String s = lda.operandStack.pop().toString(); - //escape - lda.operandStack.push(s); - } - - @Override - public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { - stack.push(new EscapeXElemAVM2Item(ins, stack.pop())); - } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -1 + 1; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.instructions.xml; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; +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.model.EscapeXElemAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.HashMap; +import java.util.List; + +public class EscXElemIns extends InstructionDefinition { + + public EscXElemIns() { + super(0x71, "esc_xelem", new int[]{}, true); + } + + @Override + public void execute(LocalDataArea lda, AVM2ConstantPool constants, List arguments) { + String s = lda.operandStack.pop().toString(); + //escape + lda.operandStack.push(s); + } + + @Override + public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + stack.push(new EscapeXElemAVM2Item(ins, stack.pop())); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -1 + 1; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AVM2SourceGenerator.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AVM2SourceGenerator.java index 3df1f12cf..594f1e793 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AVM2SourceGenerator.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AVM2SourceGenerator.java @@ -1,2499 +1,2499 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -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.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.construction.ConstructIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.construction.ConstructSuperIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.construction.NewActivationIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.construction.NewCatchIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.construction.NewClassIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.construction.NewFunctionIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.construction.NewObjectIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.IfFalseIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.IfStrictNeIns; -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.jumps.LookupSwitchIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.GetLocal0Ins; -import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.KillIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other.FindPropertyIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other.FindPropertyStrictIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetDescendantsIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetGlobalScopeIns; -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.GetSlotIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other.HasNext2Ins; -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.NextNameIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other.NextValueIns; -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.other.SetPropertyIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other.SetSlotIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other.ThrowIns; -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.PopScopeIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushByteIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushNullIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushScopeIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushStringIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushUndefinedIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushWithIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.SwapIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.types.CoerceAIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.types.ConvertBIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.xml.CheckFilterIns; -import com.jpexs.decompiler.flash.abc.avm2.model.AVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.ApplyTypeAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.BooleanAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.FloatValueAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.GetDescendantsAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.IntegerValueAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.LocalRegAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.NanAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.NullAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.ReturnValueAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.ReturnVoidAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.StringAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.ThrowAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.UndefinedAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.WithAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.WithObjectAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.clauses.ForEachInAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.clauses.ForInAVM2Item; -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.AVM2ParseException; -import com.jpexs.decompiler.flash.abc.types.ABCException; -import com.jpexs.decompiler.flash.abc.types.ClassInfo; -import com.jpexs.decompiler.flash.abc.types.InstanceInfo; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.flash.abc.types.Multiname; -import com.jpexs.decompiler.flash.abc.types.Namespace; -import com.jpexs.decompiler.flash.abc.types.NamespaceSet; -import com.jpexs.decompiler.flash.abc.types.ScriptInfo; -import com.jpexs.decompiler.flash.abc.types.ValueKind; -import com.jpexs.decompiler.flash.abc.types.traits.Trait; -import com.jpexs.decompiler.flash.abc.types.traits.TraitClass; -import com.jpexs.decompiler.flash.abc.types.traits.TraitFunction; -import com.jpexs.decompiler.flash.abc.types.traits.TraitMethodGetterSetter; -import com.jpexs.decompiler.flash.abc.types.traits.TraitSlotConst; -import com.jpexs.decompiler.flash.abc.types.traits.Traits; -import com.jpexs.decompiler.flash.configuration.Configuration; -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.Loop; -import com.jpexs.decompiler.graph.SourceGenerator; -import com.jpexs.decompiler.graph.TypeItem; -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.DoWhileItem; -import com.jpexs.decompiler.graph.model.DuplicateItem; -import com.jpexs.decompiler.graph.model.ForItem; -import com.jpexs.decompiler.graph.model.IfItem; -import com.jpexs.decompiler.graph.model.LocalData; -import com.jpexs.decompiler.graph.model.NotItem; -import com.jpexs.decompiler.graph.model.OrItem; -import com.jpexs.decompiler.graph.model.SwitchItem; -import com.jpexs.decompiler.graph.model.TernarOpItem; -import com.jpexs.decompiler.graph.model.UnboundedTypeItem; -import com.jpexs.decompiler.graph.model.WhileItem; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * - * @author JPEXS - */ -public class AVM2SourceGenerator implements SourceGenerator { - - public final ABC abc; - - public List allABCs; - - public static final int MARK_E_START = 0; - - public static final int MARK_E_END = 1; - - public static final int MARK_E_TARGET = 2; - - public static final int MARK_E_FINALLYPART = 3; - - private AVM2Instruction ins(InstructionDefinition def, int... operands) { - return new AVM2Instruction(0, def, operands); - } - - public List generate(SourceGeneratorLocalData localData, GetDescendantsAVM2Item item) throws CompilationException { - int[] nssa = new int[item.openedNamespaces.size()]; - for (int i = 0; i < item.openedNamespaces.size(); i++) { - nssa[i] = item.openedNamespaces.get(i); - } - int nsset = abc.constants.getNamespaceSetId(new NamespaceSet(nssa), true); - - return GraphTargetItem.toSourceMerge(localData, this, - item.object, - ins(new GetDescendantsIns(), abc.constants.getMultinameId(new Multiname(Multiname.MULTINAME, abc.constants.getStringId(item.nameStr, true), 0, nsset, 0, new ArrayList()), true)) - ); - } - - @Override - public List generate(SourceGeneratorLocalData localData, AndItem item) throws CompilationException { - List ret = new ArrayList<>(); - ret.addAll(generateToActionList(localData, item.leftSide)); - if (!("" + item.leftSide.returnType()).equals("Boolean")) { - ret.add(ins(new ConvertBIns())); - } - ret.add(ins(new DupIns())); - List andExpr = generateToActionList(localData, item.rightSide); - andExpr.add(0, ins(new PopIns())); - int andExprLen = insToBytes(andExpr).length; - ret.add(ins(new IfFalseIns(), andExprLen)); - ret.addAll(andExpr); - return ret; - - } - - private byte[] insToBytes(List code) { - try { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - for (AVM2Instruction instruction : code) { - - baos.write(instruction.getBytes()); - - } - return baos.toByteArray(); - } catch (IOException ex) { - Logger.getLogger(AVM2SourceGenerator.class.getName()).log(Level.SEVERE, null, ex); - } - return new byte[0]; - } - - @Override - public List generate(SourceGeneratorLocalData localData, OrItem item) throws CompilationException { - List ret = new ArrayList<>(); - ret.addAll(generateToActionList(localData, item.leftSide)); - if (!("" + item.leftSide.returnType()).equals("Boolean")) { - ret.add(ins(new ConvertBIns())); - } - ret.add(ins(new DupIns())); - List orExpr = generateToActionList(localData, item.rightSide); - orExpr.add(0, ins(new PopIns())); - int orExprLen = insToBytes(orExpr).length; - ret.add(ins(new IfTrueIns(), orExprLen)); - ret.addAll(orExpr); - return ret; - } - - public List toInsList(List items) { - List ret = new ArrayList<>(); - for (GraphSourceItem s : items) { - if (s instanceof AVM2Instruction) { - ret.add((AVM2Instruction) s); - } - } - return ret; - } - - private List nonempty(List list) { - if (list == null) { - return new ArrayList<>(); - } - return list; - } - - private List condition(SourceGeneratorLocalData localData, GraphTargetItem t, int offset) throws CompilationException { - 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) throws CompilationException { - 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) throws CompilationException { - List ret = new ArrayList<>(); - //ret.addAll(notCondition(localData, expression)); - List onTrue = null; - List onFalse = null; - if (ternar) { - onTrue = toInsList(onTrueCmds.get(0).toSource(localData, this)); - } else { - onTrue = generateToInsList(localData, onTrueCmds); - } - - if (onFalseCmds != null && !onFalseCmds.isEmpty()) { - if (ternar) { - onFalse = toInsList(onFalseCmds.get(0).toSource(localData, this)); - } else { - onFalse = generateToInsList(localData, onFalseCmds); - } - } - 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); - onTrue.add(ajmp); - } - } - - 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) { - ajmp.operands[0] = onFalseLen; - } - ret.addAll(onFalse); - } - return ret; - } - - public List generate(SourceGeneratorLocalData localData, XMLFilterAVM2Item item) throws CompilationException { - List ret = new ArrayList<>(); - final Reference counterReg = new Reference<>(0); - final Reference collectionReg = new Reference<>(0); - final Reference xmlListReg = new Reference<>(0); - List xmlListSetTemp = AssignableAVM2Item.setTemp(localData, this, xmlListReg); - ret.addAll(GraphTargetItem.toSourceMerge(localData, this, - ins(new PushByteIns(), 0), - AssignableAVM2Item.setTemp(localData, this, counterReg), - item.object, - ins(new CheckFilterIns()), - NameAVM2Item.generateCoerce(localData, this, TypeItem.UNBOUNDED), - AssignableAVM2Item.setTemp(localData, this, collectionReg), - ins(new GetLexIns(), abc.constants.getMultinameId(new Multiname(Multiname.QNAME, abc.constants.getStringId("XMLList", true), abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abc.constants.getStringId("", true)), 0, true), 0, 0, new ArrayList()), true)), - ins(new PushStringIns(), abc.constants.getStringId("", true)), - ins(new ConstructIns(), 1), - xmlListSetTemp - )); - final Reference tempVal1 = new Reference<>(0); - final Reference tempVal2 = new Reference<>(0); - - List forBody = toInsList(GraphTargetItem.toSourceMerge(localData, this, - ins(new LabelIns()), - AssignableAVM2Item.getTemp(localData, this, collectionReg), - AssignableAVM2Item.getTemp(localData, this, counterReg), - ins(new NextValueIns()), - AssignableAVM2Item.dupSetTemp(localData, this, tempVal1), - AssignableAVM2Item.dupSetTemp(localData, this, tempVal2), - ins(new PushWithIns()) - )); - localData.scopeStack.add(new LocalRegAVM2Item(null, tempVal2.getVal(), null)); - forBody.addAll(toInsList(item.value.toSource(localData, this))); - List trueBody = new ArrayList<>(); - trueBody.addAll(toInsList(AssignableAVM2Item.getTemp(localData, this, xmlListReg))); - trueBody.addAll(toInsList(AssignableAVM2Item.getTemp(localData, this, counterReg))); - trueBody.addAll(toInsList(AssignableAVM2Item.getTemp(localData, this, tempVal1))); - int[] nss = new int[item.openedNamespaces.size()]; - for (int i = 0; i < item.openedNamespaces.size(); i++) { - nss[i] = item.openedNamespaces.get(i); - } - trueBody.add(ins(new SetPropertyIns(), abc.constants.getMultinameId(new Multiname(Multiname.MULTINAMEL, 0, 0, abc.constants.getNamespaceSetId(new NamespaceSet(nss), true), 0, new ArrayList()), true))); - forBody.add(ins(new IfFalseIns(), insToBytes(trueBody).length)); - forBody.addAll(trueBody); - forBody.add(ins(new PopScopeIns())); - localData.scopeStack.remove(localData.scopeStack.size() - 1); - forBody.addAll(toInsList(AssignableAVM2Item.killTemp(localData, this, Arrays.asList(tempVal2, tempVal1)))); - - int forBodyLen = insToBytes(forBody).length; - AVM2Instruction forwardJump = ins(new JumpIns(), forBodyLen); - ret.add(forwardJump); - - List expr = new ArrayList<>(); - expr.add(ins(new HasNext2Ins(), collectionReg.getVal(), counterReg.getVal())); - AVM2Instruction backIf = ins(new IfTrueIns(), 0); - expr.add(backIf); - - int exprLen = insToBytes(expr).length; - backIf.operands[0] = -(exprLen + forBodyLen); - - ret.addAll(forBody); - ret.addAll(expr); - ret.addAll(AssignableAVM2Item.killTemp(localData, this, Arrays.asList(collectionReg, counterReg))); - ret.addAll(AssignableAVM2Item.getTemp(localData, this, xmlListReg)); - ret.addAll(AssignableAVM2Item.killTemp(localData, this, Arrays.asList(xmlListReg))); - return ret; - } - - @Override - public List generate(SourceGeneratorLocalData localData, IfItem item) throws CompilationException { - return generateIf(localData, item.expression, item.onTrue, item.onFalse, false); - } - - private void fixSwitch(List code, int breakOffset, long loopId) { - fixLoop(code, breakOffset, Integer.MAX_VALUE, loopId); - } - - private void fixLoop(List code, int breakOffset, int continueOffset, long loopId) { - int pos = 0; - for (int a = 0; a < code.size(); a++) { - AVM2Instruction ins = code.get(a); - pos += ins.getBytes().length; - if (ins.definition instanceof JumpIns) { - if (ins.definition instanceof ContinueJumpIns) { - if (continueOffset != Integer.MAX_VALUE) { - ins.operands[0] = (-pos + continueOffset); - code.get(a).definition = new JumpIns(); - } - } - if (ins.definition instanceof BreakJumpIns) { - ins.operands[0] = (-pos + breakOffset); - code.get(a).definition = new JumpIns(); - } - } - } - } - - @Override - public List generate(SourceGeneratorLocalData localData, TernarOpItem item) throws CompilationException { - List onTrue = new ArrayList<>(); - onTrue.add(item.onTrue); - List onFalse = new ArrayList<>(); - onFalse.add(item.onFalse); - return generateIf(localData, item.expression, onTrue, onFalse, true); - } - - @Override - public List generate(SourceGeneratorLocalData localData, WhileItem item) throws CompilationException { - List ret = new ArrayList<>(); - List whileExpr = new ArrayList<>(); - - 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(generateToInsList(localData, ex)); - } - List whileBody = generateToInsList(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; - } - - public List generate(SourceGeneratorLocalData localData, ForEachInAVM2Item item) throws CompilationException { - return generateForIn(localData, item.loop, item.expression.collection, (AssignableAVM2Item) item.expression.object, item.commands, true); - } - - public List generate(SourceGeneratorLocalData localData, ForInAVM2Item item) throws CompilationException { - return generateForIn(localData, item.loop, item.expression.collection, (AssignableAVM2Item) item.expression.object, item.commands, false); - } - - public List generateForIn(SourceGeneratorLocalData localData, Loop loop, GraphTargetItem collection, AssignableAVM2Item assignable, List commands, final boolean each) throws CompilationException { - List ret = new ArrayList<>(); - final Reference counterReg = new Reference<>(0); - final Reference collectionReg = new Reference<>(0); - - if (assignable instanceof UnresolvedAVM2Item) { - assignable = (AssignableAVM2Item) ((UnresolvedAVM2Item) assignable).resolved; - } - - ret.addAll(GraphTargetItem.toSourceMerge(localData, this, - ins(new PushByteIns(), 0), - AssignableAVM2Item.setTemp(localData, this, counterReg), - collection, - NameAVM2Item.generateCoerce(localData, this, TypeItem.UNBOUNDED), - AssignableAVM2Item.setTemp(localData, this, collectionReg) - )); - - GraphTargetItem assigned = new GraphTargetItem() { - - @Override - public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException { - return null; - } - - @Override - public boolean hasReturnValue() { - return true; - } - - @Override - public GraphTargetItem returnType() { - return TypeItem.UNBOUNDED; - } - - @Override - public List toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException { - return toSourceMerge(localData, generator, - AssignableAVM2Item.getTemp(localData, generator, collectionReg), - AssignableAVM2Item.getTemp(localData, generator, counterReg), - ins(each ? new NextValueIns() : new NextNameIns()) - ); - } - }; - assignable.setAssignedValue(assigned); - - List forBody = toInsList(GraphTargetItem.toSourceMerge(localData, this, - ins(new LabelIns()), - assignable.toSourceIgnoreReturnValue(localData, this) - )); - - forBody.addAll(generateToInsList(localData, commands)); - int forBodyLen = insToBytes(forBody).length; - - AVM2Instruction forwardJump = ins(new JumpIns(), forBodyLen); - ret.add(forwardJump); - - List expr = new ArrayList<>(); - expr.add(ins(new HasNext2Ins(), collectionReg.getVal(), counterReg.getVal())); - AVM2Instruction backIf = ins(new IfTrueIns(), 0); - expr.add(backIf); - - int exprLen = insToBytes(expr).length; - backIf.operands[0] = -(exprLen + forBodyLen); - - fixLoop(forBody, forBodyLen + exprLen, forBodyLen, loop.id); - ret.addAll(forBody); - ret.addAll(expr); - ret.addAll(AssignableAVM2Item.killTemp(localData, this, Arrays.asList(collectionReg, counterReg))); - return ret; - } - - @Override - public List generate(SourceGeneratorLocalData localData, DoWhileItem item) throws CompilationException { - List ret = new ArrayList<>(); - List whileExpr = new ArrayList<>(); - - 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(generateToInsList(localData, ex)); - } - List dowhileBody = generateToInsList(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; - } - - public List generate(SourceGeneratorLocalData localData, WithAVM2Item item) throws CompilationException { - - List ret = new ArrayList<>(); - ret.addAll(item.scope.toSource(localData, this)); - Reference tempReg = new Reference<>(0); - ret.addAll(AssignableAVM2Item.dupSetTemp(localData, this, tempReg)); - localData.scopeStack.add(new WithObjectAVM2Item(null, new LocalRegAVM2Item(null, tempReg.getVal(), null))); - ret.add(ins(new PushWithIns())); - ret.addAll(generate(localData, item.items)); - ret.add(ins(new PopScopeIns())); - ret.addAll(AssignableAVM2Item.killTemp(localData, this, Arrays.asList(tempReg))); - localData.scopeStack.remove(localData.scopeStack.size() - 1); - return ret; - } - - @Override - public List generate(SourceGeneratorLocalData localData, ForItem item) throws CompilationException { - List ret = new ArrayList<>(); - List forExpr = new ArrayList<>(); - - 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(generateToInsList(localData, ex)); - } - List forBody = generateToInsList(localData, item.commands); - List forFinalCommands = generateToInsList(localData, item.finalCommands); - - ret.addAll(generateToInsList(localData, item.firstCommands)); - - AVM2Instruction forwardJump = ins(new JumpIns(), 0); - ret.add(forwardJump); - forBody.add(0, ins(new LabelIns())); - ret.addAll(forBody); - ret.addAll(forFinalCommands); - 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; - - public String uniqId() { - uniqLast++; - return "" + uniqLast; - } - - @Override - public List generate(SourceGeneratorLocalData localData, SwitchItem item) throws CompilationException { - List ret = new ArrayList<>(); - Reference switchedReg = new Reference<>(0); - AVM2Instruction forwardJump = ins(new JumpIns(), 0); - ret.add(forwardJump); - - List cases = new ArrayList<>(); - cases.addAll(toInsList(new IntegerValueAVM2Item(null, (long) item.caseValues.size()).toSource(localData, this))); - int cLen = insToBytes(cases).length; - List caseLast = new ArrayList<>(); - caseLast.add(0, ins(new JumpIns(), cLen)); - caseLast.addAll(0, toInsList(new IntegerValueAVM2Item(null, (long) item.caseValues.size()).toSource(localData, this))); - int cLastLen = insToBytes(caseLast).length; - caseLast.add(0, ins(new JumpIns(), cLastLen)); - cases.addAll(0, caseLast); - - List preCases = new ArrayList<>(); - preCases.addAll(toInsList(item.switchedObject.toSource(localData, this))); - preCases.addAll(toInsList(AssignableAVM2Item.setTemp(localData, this, switchedReg))); - - for (int i = item.caseValues.size() - 1; i >= 0; i--) { - List sub = new ArrayList<>(); - sub.addAll(toInsList(new IntegerValueAVM2Item(null, (long) i).toSource(localData, this))); - sub.add(ins(new JumpIns(), insToBytes(cases).length)); - int subLen = insToBytes(sub).length; - - cases.addAll(0, sub); - cases.add(0, ins(new IfStrictNeIns(), subLen)); - cases.addAll(0, toInsList(AssignableAVM2Item.getTemp(localData, this, switchedReg))); - cases.addAll(0, toInsList(item.caseValues.get(i).toSource(localData, this))); - } - cases.addAll(0, preCases); - - AVM2Instruction lookupOp = new AVM2Instruction(0, new LookupSwitchIns(), new int[item.caseValues.size() + 1 + 1 + 1]); - cases.addAll(toInsList(AssignableAVM2Item.killTemp(localData, this, Arrays.asList(switchedReg)))); - List bodies = new ArrayList<>(); - List bodiesOffsets = new ArrayList<>(); - int defOffset; - int casesLen = insToBytes(cases).length; - bodies.addAll(generateToInsList(localData, item.defaultCommands)); - bodies.add(0, ins(new LabelIns())); - 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); - for (int i = item.caseCommands.size() - 1; i >= 0; i--) { - bodies.addAll(0, generateToInsList(localData, item.caseCommands.get(i))); - bodies.add(0, ins(new LabelIns())); - bodiesOffsets.add(0, -(insToBytes(bodies).length + casesLen)); - } - 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)); - } - - forwardJump.operands[0] = insToBytes(bodies).length; - ret.addAll(bodies); - ret.addAll(cases); - ret.add(lookupOp); - fixSwitch(toInsList(ret), insToBytes(toInsList(ret)).length, uniqLast); - return ret; - } - - @Override - public List generate(SourceGeneratorLocalData localData, NotItem item) throws CompilationException { - /*if (item.getOriginal() instanceof Inverted) { - GraphTargetItem norig = ((Inverted) item).invert(); - return norig.toSource(localData, this); - }*/ - List ret = new ArrayList<>(); - ret.addAll(item.getOriginal().toSource(localData, this)); - ret.add(ins(new NotIns())); - return ret; - } - - @Override - public List generate(SourceGeneratorLocalData localData, DuplicateItem item) { - List ret = new ArrayList<>(); - ret.add(ins(new DupIns())); - return ret; - } - - @Override - public List generate(SourceGeneratorLocalData localData, BreakItem item) { - List ret = new ArrayList<>(); - AVM2Instruction abreak = ins(new BreakJumpIns(item.loopId), 0); - ret.add(abreak); - return ret; - } - - public List generate(SourceGeneratorLocalData localData, FunctionAVM2Item item) throws CompilationException { - List ret = new ArrayList<>(); - int scope = 0; - if (!item.functionName.isEmpty()) { - ret.add(ins(new NewObjectIns(), 0)); - ret.add(ins(new PushWithIns())); - scope = localData.scopeStack.size(); - localData.scopeStack.add(new PropertyAVM2Item(null, item.functionName, abc, allABCs, new ArrayList(), localData.callStack)); - } - ret.add(ins(new NewFunctionIns(), method(true, false, localData.callStack, localData.pkg, item.needsActivation, item.subvariables, 0 /*Set later*/, item.hasRest, item.line, localData.currentClass, null, false, localData, item.paramTypes, item.paramNames, item.paramValues, item.body, item.retType))); - if (!item.functionName.isEmpty()) { - ret.add(ins(new DupIns())); - ret.add(ins(new GetScopeObjectIns(), scope)); - ret.add(ins(new SwapIns())); - ret.add(ins(new SetPropertyIns(), abc.constants.getMultinameId(new Multiname(Multiname.QNAME, abc.constants.getStringId(item.functionName, true), abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abc.constants.getStringId(localData.pkg, true)), 0, true), 0, 0, new ArrayList()), true))); - ret.add(ins(new PopScopeIns())); - localData.scopeStack.remove(localData.scopeStack.size() - 1); - } - return ret; - } - - private static int currentFinId = 1; - - private static int finId() { - return currentFinId++; - } - - public List generate(SourceGeneratorLocalData localData, TryAVM2Item item) throws CompilationException { - List ret = new ArrayList<>(); - - boolean newFinallyReg = false; - List newex = new ArrayList<>(); - int aloneFinallyEx = -1; - int finallyEx = -1; - for (NameAVM2Item e : item.catchExceptions2) { - ABCException aex = new ABCException(); - aex.name_index = abc.constants.getMultinameId(new Multiname(Multiname.QNAME, abc.constants.getStringId(e.getVariableName(), true), abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abc.constants.getStringId("", true)), 0, true), 0, 0, new ArrayList()), true); - aex.type_index = typeName(localData, e.type); - newex.add(aex); - } - int finId = 0; - if (item.finallyCommands != null) { - if (item.catchExceptions2.isEmpty()) { - ABCException aex = new ABCException(); - aex.name_index = 0; - aex.type_index = 0; - newex.add(aex); - aloneFinallyEx = newex.size() - 1; - } - ABCException aex = new ABCException(); - aex.name_index = 0; - aex.type_index = 0; - newex.add(aex); - finallyEx = newex.size() - 1; - if (localData.finallyRegister == -1) { - localData.finallyRegister = getFreeRegister(localData); - killRegister(localData, localData.finallyRegister); //reuse for catches - newFinallyReg = true; - } - finId = finId(); - } - - if (finallyEx > -1) { - localData.finallyCatches.add(finId); - } - List tryCmds = generateToInsList(localData, item.tryCommands); - - //int i = firstId + item.catchCommands.size() - 1; - List catches = new ArrayList<>(); - Reference tempReg = new Reference<>(0); - - List currentExceptionIds = new ArrayList<>(); - List> catchCmds = new ArrayList<>(); - for (int c = 0; c < item.catchCommands.size(); c++) { - int i = localData.exceptions.size(); - localData.exceptions.add(newex.get(c)); - - currentExceptionIds.add(i); - - //Reference tempReg=new Reference<>(0); - List catchCmd = new ArrayList<>(); - catchCmd.add(ins(new NewCatchIns(), i)); - catchCmd.addAll(toInsList(AssignableAVM2Item.dupSetTemp(localData, this, tempReg))); - catchCmd.add(ins(new DupIns())); - catchCmd.add(ins(new PushScopeIns())); - catchCmd.add(ins(new SwapIns())); - catchCmd.add(ins(new SetSlotIns(), 1)); - - for (AssignableAVM2Item a : item.catchVariables.get(c)) { - GraphTargetItem r = a; - if (r instanceof UnresolvedAVM2Item) { - r = ((UnresolvedAVM2Item) r).resolvedRoot; - } - if (r instanceof NameAVM2Item) { - NameAVM2Item n = (NameAVM2Item) r; - if (item.catchExceptions2.get(c).getVariableName().equals(n.getVariableName())) { - n.setSlotScope(localData.scopeStack.size()); - } - } - } - localData.scopeStack.add(new LocalRegAVM2Item(null, tempReg.getVal(), null)); - catchCmd.addAll(generateToInsList(localData, item.catchCommands.get(c))); - localData.scopeStack.remove(localData.scopeStack.size() - 1); - catchCmd.add(ins(new PopScopeIns())); - catchCmd.addAll(toInsList(AssignableAVM2Item.killTemp(localData, this, Arrays.asList(tempReg)))); - catchCmds.add(catchCmd); - } - for (int c = item.catchCommands.size() - 1; c >= 0; c--) { - List preCatches = new ArrayList<>(); - /*preCatches.add(ins(new GetLocal0Ins())); - preCatches.add(ins(new PushScopeIns())); - preCatches.add(AssignableAVM2Item.generateGetLoc(localData.activationReg)); - preCatches.add(ins(new PushScopeIns()));*/ - for (GraphTargetItem s : localData.scopeStack) { - preCatches.addAll(toInsList(s.toSource(localData, this))); - if (s instanceof WithObjectAVM2Item) { - preCatches.add(ins(new PushWithIns())); - } else { - preCatches.add(ins(new PushScopeIns())); - } - } - - //catchCmds.add(catchCmd); - preCatches.addAll(catchCmds.get(c)); - catches.addAll(0, preCatches); - catches.add(0, new ExceptionMarkAVM2Instruction(currentExceptionIds.get(c), MARK_E_TARGET)); - catches.add(0, ins(new JumpIns(), insToBytes(catches).length)); - } - - if (aloneFinallyEx > -1) { - localData.exceptions.add(newex.get(aloneFinallyEx)); - aloneFinallyEx = localData.exceptions.size() - 1; - - } - if (finallyEx > -1) { - localData.exceptions.add(newex.get(finallyEx)); - finallyEx = localData.exceptions.size() - 1; - } - - for (int i : currentExceptionIds) { - ret.add(new ExceptionMarkAVM2Instruction(i, MARK_E_START)); - } - if (aloneFinallyEx > -1) { - ret.add(new ExceptionMarkAVM2Instruction(aloneFinallyEx, MARK_E_START)); - } - if (finallyEx > -1) { - ret.add(new ExceptionMarkAVM2Instruction(finallyEx, MARK_E_START)); - } - - ret.addAll(tryCmds); - - for (int i : currentExceptionIds) { - ret.add(new ExceptionMarkAVM2Instruction(i, MARK_E_END)); - } - if (aloneFinallyEx > -1) { - ret.add(new ExceptionMarkAVM2Instruction(aloneFinallyEx, MARK_E_END)); - } - - if (aloneFinallyEx > -1) { - List preCatches = new ArrayList<>(); - for (GraphTargetItem s : localData.scopeStack) { - preCatches.addAll(toInsList(s.toSource(localData, this))); - if (s instanceof WithObjectAVM2Item) { - preCatches.add(ins(new PushWithIns())); - } else { - preCatches.add(ins(new PushScopeIns())); - } - } - preCatches.add(ins(new NewCatchIns(), aloneFinallyEx)); - preCatches.addAll(toInsList(AssignableAVM2Item.dupSetTemp(localData, this, tempReg))); - preCatches.add(ins(new PushScopeIns())); - preCatches.add(ins(new ThrowIns())); - preCatches.add(ins(new PopScopeIns())); - preCatches.addAll(toInsList(AssignableAVM2Item.killTemp(localData, this, Arrays.asList(tempReg)))); - catches.add(ins(new JumpIns(), insToBytes(preCatches).length)); - catches.add(new ExceptionMarkAVM2Instruction(aloneFinallyEx, MARK_E_TARGET)); - catches.addAll(preCatches); - } - AVM2Instruction finSwitch = null; - AVM2Instruction pushDefIns = ins(new PushByteIns(), 0); - - int defPos = 0; - if (finallyEx > -1) { - List preCatches = new ArrayList<>(); - preCatches.add(0, new ExceptionMarkAVM2Instruction(finallyEx, MARK_E_TARGET)); - for (GraphTargetItem s : localData.scopeStack) { - preCatches.addAll(toInsList(s.toSource(localData, this))); - if (s instanceof WithObjectAVM2Item) { - preCatches.add(ins(new PushWithIns())); - } else { - preCatches.add(ins(new PushScopeIns())); - } - } - preCatches.add(ins(new NewCatchIns(), finallyEx)); - preCatches.addAll(toInsList(AssignableAVM2Item.dupSetTemp(localData, this, tempReg))); - preCatches.add(ins(new PushScopeIns())); - preCatches.add(ins(new PopScopeIns())); - Reference tempReg2 = new Reference<>(0); - preCatches.add(ins(new KillIns(), tempReg.getVal())); - preCatches.add(ins(new CoerceAIns())); - preCatches.addAll(toInsList(AssignableAVM2Item.setTemp(localData, this, tempReg2))); - preCatches.add(pushDefIns); - - List finallySwitchCmds = new ArrayList<>(); - - finSwitch = new AVM2Instruction(0, new LookupSwitchIns(), new int[1 + 1 + 1]); - finSwitch.operands[0] = finSwitch.getBytes().length; - finSwitch.operands[1] = 0; //switch cnt - - List preFinallySwitch = new ArrayList<>(); - preFinallySwitch.add(ins(new LabelIns())); - preFinallySwitch.add(ins(new PopIns())); - int preFinallySwitchLen = insToBytes(preFinallySwitch).length; - - finallySwitchCmds.add(ins(new LabelIns())); - finallySwitchCmds.addAll(toInsList(AssignableAVM2Item.getTemp(localData, this, tempReg2))); - finallySwitchCmds.add(ins(new KillIns(), tempReg2.getVal())); - finallySwitchCmds.add(ins(new ThrowIns())); - finallySwitchCmds.add(ins(new PushByteIns(), 255)); - finallySwitchCmds.add(ins(new PopScopeIns())); - finallySwitchCmds.add(ins(new KillIns(), tempReg.getVal())); - - int finSwitchLen = insToBytes(finallySwitchCmds).length; - - preCatches.add(ins(new JumpIns(), preFinallySwitchLen + finSwitchLen)); - AVM2Instruction fjump = ins(new JumpIns(), 0); - fjump.operands[0] = insToBytes(preCatches).length + preFinallySwitchLen + finSwitchLen; - - preCatches.add(0, fjump); - preCatches.add(0, new ExceptionMarkAVM2Instruction(finallyEx, MARK_E_END)); - preCatches.add(0, ins(new PushByteIns(), 255)); - - finallySwitchCmds.add(new ExceptionMarkAVM2Instruction(finallyEx, MARK_E_FINALLYPART)); - - int oldReg = localData.finallyRegister; - localData.finallyRegister = getFreeRegister(localData); - Integer cnt = localData.finallyCounter.get(finId); - if (cnt == null) { - cnt = -1; - } - defPos = cnt; - cnt++; //Skip default clause (throw) - localData.finallyCounter.put(finId, cnt); - finallySwitchCmds.addAll(generateToInsList(localData, item.finallyCommands)); - killRegister(localData, localData.finallyRegister); - localData.finallyRegister = oldReg; - finSwitchLen = insToBytes(finallySwitchCmds).length; - - finSwitch.operands[2] = -finSwitchLen; - preCatches.addAll(preFinallySwitch); - preCatches.addAll(finallySwitchCmds); - preCatches.add(finSwitch); - - catches.addAll(preCatches); - AssignableAVM2Item.killTemp(localData, this, Arrays.asList(tempReg, tempReg2)); - } - - ret.addAll(catches); - //localData.exceptions.addAll(newex); - - if (finallyEx > -1) { - localData.finallyCatches.remove(localData.finallyCatches.size() - 1); - } - if (newFinallyReg) { - localData.finallyRegister = -1; - killRegister(localData, localData.finallyRegister); - } - int pos = 0; - int finallyPos = 0; - int switchPos = 0; - for (int s = 0; s < ret.size(); s++) { - GraphSourceItem src = ret.get(s); - if (src == finSwitch) { - switchPos = pos; - } - if (src instanceof AVM2Instruction) { - AVM2Instruction ins = (AVM2Instruction) src; - if (ins instanceof ExceptionMarkAVM2Instruction) { - ExceptionMarkAVM2Instruction em = (ExceptionMarkAVM2Instruction) ins; - if (em.exceptionId == finallyEx && em.markType == MARK_E_FINALLYPART) { - finallyPos = pos; - ret.remove(s); - s--; - continue; - } - } - pos += ins.getBytes().length; - } - - } - - if (finSwitch != null) { - pos = 0; - int defLoc = finSwitch.operands[2]; - List switchLoc = new ArrayList<>(); - boolean wasDef = false; - for (int s = 0; s < ret.size(); s++) { - GraphSourceItem src = ret.get(s); - if (src instanceof AVM2Instruction) { - AVM2Instruction ins = (AVM2Instruction) src; - if (ins.definition instanceof FinallyJumpIns) { - FinallyJumpIns fji = (FinallyJumpIns) ins.definition; - if (fji.getClauseId() == finId) { - List bet = new ArrayList<>(); - bet.add(ins(new LabelIns())); - bet.add(ins(new PopIns())); - int betLen = insToBytes(bet).length; - if (wasDef) { - ins.operands[0] = 0; - } else { - ins.operands[0] = finallyPos - (pos + ins.getBytes().length); - } - ins.definition = new JumpIns(); - switchLoc.add(pos + ins.getBytes().length + betLen - switchPos); - } - } - pos += ins.getBytes().length; - } - if (defPos == switchLoc.size() - 1) { - switchLoc.add(defLoc); - wasDef = true; - } - } - finSwitch.operands = new int[1 + 1 + switchLoc.size()]; - pushDefIns.operands[0] = defPos + 1; - int afterLoc = finSwitch.getBytes().length; - finSwitch.operands[0] = afterLoc; - finSwitch.operands[1] = switchLoc.size() - 1; - for (int j = 0; j < switchLoc.size(); j++) { - finSwitch.operands[2 + j] = switchLoc.get(j); - } - } - - return ret; - } - - @Override - public List generate(SourceGeneratorLocalData localData, ContinueItem item) { - List ret = new ArrayList<>(); - AVM2Instruction acontinue = ins(new ContinueJumpIns(item.loopId), 0); - ret.add(acontinue); - return ret; - } - - public List generate(SourceGeneratorLocalData localData, ReturnValueAVM2Item item) throws CompilationException { - List ret = new ArrayList<>(); - ret.addAll(item.value.toSource(localData, this)); - if (!localData.finallyCatches.isEmpty()) { - ret.add(ins(new CoerceAIns())); - ret.add(AssignableAVM2Item.generateSetLoc(localData.finallyRegister)); - for (int i = localData.finallyCatches.size() - 1; i >= 0; i--) { - if (i < localData.finallyCatches.size() - 1) { - ret.add(ins(new LabelIns())); - } - int clauseId = localData.finallyCatches.get(i); - Integer cnt = localData.finallyCounter.get(clauseId); - if (cnt == null) { - cnt = -1; - } - cnt++; - localData.finallyCounter.put(clauseId, cnt); - ret.addAll(new IntegerValueAVM2Item(null, (long) cnt).toSource(localData, this)); - ret.add(ins(new FinallyJumpIns(clauseId), 0)); - ret.add(ins(new LabelIns())); - ret.add(ins(new PopIns())); - } - ret.add(ins(new LabelIns())); - ret.add(AssignableAVM2Item.generateGetLoc(localData.finallyRegister)); - ret.add(ins(new KillIns(), localData.finallyRegister)); - } - ret.add(ins(new ReturnValueIns())); - return ret; - } - - public List generate(SourceGeneratorLocalData localData, ReturnVoidAVM2Item item) throws CompilationException { - List ret = new ArrayList<>(); - if (!localData.finallyCatches.isEmpty()) { - - for (int i = 0; i < localData.finallyCatches.size(); i++) { - if (i > 0) { - ret.add(ins(new LabelIns())); - } - int clauseId = localData.finallyCatches.get(i); - Integer cnt = localData.finallyCounter.get(clauseId); - if (cnt == null) { - cnt = -1; - } - cnt++; - localData.finallyCounter.put(clauseId, cnt); - ret.addAll(new IntegerValueAVM2Item(null, (long) cnt).toSource(localData, this)); - ret.add(ins(new FinallyJumpIns(clauseId), 0)); - ret.add(ins(new LabelIns())); - ret.add(ins(new PopIns())); - } - ret.add(ins(new LabelIns())); - } - ret.add(ins(new ReturnVoidIns())); - return ret; - } - - public List generate(SourceGeneratorLocalData localData, ThrowAVM2Item item) throws CompilationException { - List ret = new ArrayList<>(); - ret.addAll(item.value.toSource(localData, this)); - ret.add(ins(new ThrowIns())); - return ret; - } - - private List generateToInsList(SourceGeneratorLocalData localData, List commands) throws CompilationException { - return toInsList(generate(localData, commands)); - } - - private List generateToActionList(SourceGeneratorLocalData localData, GraphTargetItem command) throws CompilationException { - return toInsList(command.toSource(localData, this)); - } - - @Override - public List generate(SourceGeneratorLocalData localData, List commands) throws CompilationException { - List ret = new ArrayList<>(); - for (GraphTargetItem item : commands) { - ret.addAll(item.toSourceIgnoreReturnValue(localData, this)); - } - return ret; - } - - public HashMap getRegisterVars(SourceGeneratorLocalData localData) { - return localData.registerVars; - } - - public void setRegisterVars(SourceGeneratorLocalData localData, HashMap value) { - localData.registerVars = value; - } - - public void setInFunction(SourceGeneratorLocalData localData, int value) { - localData.inFunction = value; - } - - public int isInFunction(SourceGeneratorLocalData localData) { - return localData.inFunction; - } - - public boolean isInMethod(SourceGeneratorLocalData localData) { - return localData.inMethod; - } - - public void setInMethod(SourceGeneratorLocalData localData, boolean value) { - localData.inMethod = value; - } - - public int getForInLevel(SourceGeneratorLocalData localData) { - return localData.forInLevel; - } - - public void setForInLevel(SourceGeneratorLocalData localData, int value) { - localData.forInLevel = value; - } - - public int getTempRegister(SourceGeneratorLocalData localData) { - HashMap registerVars = getRegisterVars(localData); - int tmpReg = 0; - for (int i = 0; i < 256; i++) { - if (!registerVars.containsValue(i)) { - tmpReg = i; - break; - } - } - return tmpReg; - } - - public AVM2SourceGenerator(ABC abc, List allABCs) { - this.abc = abc; - this.allABCs = allABCs; - } - - public ABC getABC() { - return abc; - } - - public void generateClass(List importedClasses, List sinitVariables, boolean staticNeedsActivation, List staticInit, List openedNamespaces, int namespace, int initScope, String pkg, ClassInfo classInfo, InstanceInfo instanceInfo, SourceGeneratorLocalData localData, boolean isInterface, String name, String superName, GraphTargetItem extendsVal, List implementsStr, GraphTargetItem constructor, List traitItems, Reference class_index) throws AVM2ParseException, CompilationException { - localData.currentClass = name; - localData.pkg = pkg; - List ret = new ArrayList<>(); - if (extendsVal == null && !isInterface) { - extendsVal = new TypeItem("Object"); - } - ParsedSymbol s = null; - - instanceInfo.name_index = traitName(namespace, name); - - Trait[] it = generateTraitsPhase1(name, superName, false, localData, traitItems, instanceInfo.instance_traits, class_index); - Trait[] st = generateTraitsPhase1(name, superName, true, localData, traitItems, classInfo.static_traits, class_index); - generateTraitsPhase2(importedClasses, pkg, traitItems, it, openedNamespaces, localData); - generateTraitsPhase2(importedClasses, pkg, traitItems, st, openedNamespaces, localData); - generateTraitsPhase3(initScope, isInterface, name, superName, false, localData, traitItems, instanceInfo.instance_traits, it, new HashMap(), class_index); - generateTraitsPhase3(initScope, isInterface, name, superName, true, localData, traitItems, classInfo.static_traits, st, new HashMap(), class_index); - int init = 0; - if (constructor == null || isInterface) { - instanceInfo.iinit_index = init = method(false, isInterface, new ArrayList(), pkg, false, new ArrayList(), initScope + 1, false, 0, isInterface ? null : name, extendsVal != null ? extendsVal.toString() : null, true, localData, new ArrayList(), new ArrayList(), new ArrayList(), new ArrayList(), TypeItem.UNBOUNDED/*?? FIXME*/); - } else { - MethodAVM2Item m = (MethodAVM2Item) constructor; - instanceInfo.iinit_index = init = method(false, false, new ArrayList(), pkg, m.needsActivation, m.subvariables, initScope + 1, m.hasRest, m.line, name, extendsVal != null ? extendsVal.toString() : null, true, localData, m.paramTypes, m.paramNames, m.paramValues, m.body, TypeItem.UNBOUNDED/*?? FIXME*/); - } - - //Class initializer - int staticMi = method(false, false, new ArrayList(), pkg, staticNeedsActivation, sinitVariables, initScope + (implementsStr.isEmpty() ? 0 : 1), false, 0, isInterface ? null : name, superName, false, localData, new ArrayList(), new ArrayList(), new ArrayList(), staticInit, TypeItem.UNBOUNDED); - MethodBody sinitBody = abc.findBody(staticMi); - - List sinitcode = new ArrayList<>(); - List initcode = new ArrayList<>(); - for (GraphTargetItem ti : traitItems) { - if ((ti instanceof SlotAVM2Item) || (ti instanceof ConstAVM2Item)) { - GraphTargetItem val = null; - boolean isStatic = false; - int ns = -1; - String tname = null; - boolean isConst = false; - if (ti instanceof SlotAVM2Item) { - val = ((SlotAVM2Item) ti).value; - isStatic = ((SlotAVM2Item) ti).isStatic(); - ns = ((SlotAVM2Item) ti).getNamespace(); - tname = ((SlotAVM2Item) ti).var; - } - if (ti instanceof ConstAVM2Item) { - val = ((ConstAVM2Item) ti).value; - isStatic = ((ConstAVM2Item) ti).isStatic(); - ns = ((ConstAVM2Item) ti).getNamespace(); - tname = ((ConstAVM2Item) ti).var; - isConst = true; - } - if (isStatic && val != null) { - sinitcode.add(ins(new FindPropertyIns(), traitName(ns, tname))); - sinitcode.addAll(toInsList(val.toSource(localData, this))); - sinitcode.add(ins(isConst ? new InitPropertyIns() : new SetPropertyIns(), traitName(ns, tname))); - } - if (!isStatic && val != null) { - //do not init basic values, that can be stored in trait - if (!(val instanceof IntegerValueAVM2Item) && !(val instanceof StringAVM2Item) && !(val instanceof BooleanAVM2Item) && !(val instanceof NullAVM2Item) && !(val instanceof UndefinedAVM2Item)) { - initcode.add(ins(new GetLocal0Ins())); - initcode.addAll(toInsList(val.toSource(localData, this))); - initcode.add(ins(isConst ? new InitPropertyIns() : new SetPropertyIns(), traitName(ns, tname))); - } - } - } - } - MethodBody initBody = null; - if (!isInterface) { - initBody = abc.findBody(init); - initBody.getCode().code.addAll(constructor == null ? 0 : 2, initcode);//after getlocal0,pushscope - - if (sinitBody.getCode().code.get(sinitBody.getCode().code.size() - 1).definition instanceof ReturnVoidIns) { - sinitBody.getCode().code.addAll(2, sinitcode); //after getlocal0,pushscope - } - } - sinitBody.markOffsets(); - sinitBody.autoFillStats(abc, initScope + (implementsStr.isEmpty() ? 0 : 1), true); - - classInfo.cinit_index = staticMi; - if (!isInterface) { - initBody.autoFillStats(abc, initScope + 1, true); - } - instanceInfo.interfaces = new int[implementsStr.size()]; - for (int i = 0; i < implementsStr.size(); i++) { - instanceInfo.interfaces[i] = superIntName(localData, implementsStr.get(i)); - } - } - - @Override - public List generate(SourceGeneratorLocalData localData, CommaExpressionItem item) throws CompilationException { - if (item.commands.isEmpty()) { - return new ArrayList<>(); - } - - //We need to handle commands and last expression separately, otherwise last expression result will be popped - List cmds = new ArrayList<>(item.commands); - GraphTargetItem lastExpr = cmds.remove(cmds.size() - 1); - List ret = new ArrayList<>(); - ret.addAll(generate(localData, cmds)); - ret.addAll(lastExpr.toSource(localData, this)); - return ret; - } - - public int generateClass(int namespace, ClassInfo ci, InstanceInfo ii, int initScope, String pkg, SourceGeneratorLocalData localData, AVM2Item cls, Reference class_index) throws AVM2ParseException, CompilationException { - /*ClassInfo ci = new ClassInfo(); - InstanceInfo ii = new InstanceInfo(); - abc.class_info.add(ci); - abc.instance_info.add(ii); - */ - if (cls instanceof ClassAVM2Item) { - ClassAVM2Item cai = (ClassAVM2Item) cls; - generateClass(cai.importedClasses, cai.sinitVariables, cai.staticInitActivation, cai.staticInit, cai.openedNamespaces, namespace, initScope, pkg, ci, ii, localData, false, cai.className, cai.extendsOp == null ? "Object" : cai.extendsOp.toString(), cai.extendsOp, cai.implementsOp, cai.constructor, cai.traits, class_index); - if (!cai.isDynamic) { - ii.flags |= InstanceInfo.CLASS_SEALED; - } - if (cai.isFinal) { - ii.flags |= InstanceInfo.CLASS_FINAL; - } - ii.flags |= InstanceInfo.CLASS_PROTECTEDNS; - ii.protectedNS = cai.protectedNs; - } - if (cls instanceof InterfaceAVM2Item) { - InterfaceAVM2Item iai = (InterfaceAVM2Item) cls; - ii.flags |= InstanceInfo.CLASS_INTERFACE; - ii.flags |= InstanceInfo.CLASS_SEALED; - generateClass(iai.importedClasses, new ArrayList(), false, new ArrayList(), iai.openedNamespaces, namespace, initScope, pkg, ci, ii, localData, true, iai.name, null, null, iai.superInterfaces, null, iai.methods, class_index); - } - - return abc.instance_info.size() - 1; - } - - public int traitName(int namespace, String var) { - return abc.constants.getMultinameId(new Multiname(Multiname.QNAME, str(var), namespace, 0, 0, new ArrayList()), true); - } - - public int typeName(SourceGeneratorLocalData localData, GraphTargetItem type) throws CompilationException { - if (type instanceof UnboundedTypeItem) { - return 0; - } - if (("" + type).equals("*")) { - return 0; - } - - return resolveType(localData, type, abc, allABCs); - /* - TypeItem nameItem = (TypeItem) type; - name = nameItem.fullTypeName; - if (name.contains(".")) { - pkg = name.substring(0, name.lastIndexOf('.')); - name = name.substring(name.lastIndexOf('.') + 1); - } - if (!nameItem.subtypes.isEmpty()) { //It's vector => TypeName - List params = new ArrayList<>(); - for (GraphTargetItem p : nameItem.subtypes) { - params.add(typeName(localData, p));//abc.constants.getMultinameId(new Multiname(Multiname.QNAME, str(p), namespace(Namespace.KIND_PACKAGE, ppkg), 0, 0, new ArrayList()), true)); - } - int qname = abc.constants.getMultinameId(new Multiname(Multiname.QNAME, str(name), namespace(Namespace.KIND_PACKAGE, pkg), 0, 0, new ArrayList()), true); - return abc.constants.getMultinameId(new Multiname(Multiname.TYPENAME, 0, 0, 0, qname, params), true); - } else { - return abc.constants.getMultinameId(new Multiname(Multiname.QNAME, str(name), namespace(Namespace.KIND_PACKAGE, pkg), 0, 0, new ArrayList()), true); - }*/ - } - - public int ident(GraphTargetItem name) { - if (name instanceof NameAVM2Item) { - return str(((NameAVM2Item) name).getVariableName()); - } - throw new RuntimeException("no ident"); //FIXME - } - - public int namespace(int nsKind, String name) { - return abc.constants.getNamespaceId(new Namespace(nsKind, str(name)), 0, true); - } - - public int str(String name) { - return abc.constants.getStringId(name, true); - } - - public int propertyName(GraphTargetItem name) { - if (name instanceof NameAVM2Item) { - NameAVM2Item va = (NameAVM2Item) name; - return abc.constants.getMultinameId(new Multiname(Multiname.QNAME, str(va.getVariableName()), namespace(Namespace.KIND_PACKAGE, ""), 0, 0, new ArrayList()), true); - } - throw new RuntimeException("no prop"); //FIXME - } - - public int getFreeRegister(SourceGeneratorLocalData localData) { - for (int i = 0;; i++) { - if (!localData.registerVars.containsValue(i)) { - localData.registerVars.put("__TEMP__" + i, i); - return i; - } - } - } - - public boolean killRegister(SourceGeneratorLocalData localData, int i) { - String key = null; - for (String k : localData.registerVars.keySet()) { - if (localData.registerVars.get(k) == i) { - key = k; - break; - } - } - if (key != null) { - localData.registerVars.remove(key); - return true; - } - return false; - } - - public int method(boolean subMethod, boolean isInterface, List callStack, String pkg, boolean needsActivation, List subvariables, int initScope, boolean hasRest, int line, String className, String superType, boolean constructor, SourceGeneratorLocalData localData, List paramTypes, List paramNames, List paramValues, List body, GraphTargetItem retType) throws CompilationException { - //Reference hasArgs = new Reference<>(Boolean.FALSE); - //calcRegisters(localData,needsActivation,paramNames,subvariables,body, hasArgs); - SourceGeneratorLocalData newlocalData = new SourceGeneratorLocalData(new HashMap(), 1, true, 0); - newlocalData.currentClass = className; - newlocalData.pkg = localData.pkg; - newlocalData.callStack.addAll(localData.callStack); - newlocalData.traitUsages = localData.traitUsages; - newlocalData.currentScript = localData.currentScript; - newlocalData.documentClass = localData.documentClass; - newlocalData.subMethod = subMethod; - localData = newlocalData; - - localData.activationReg = 0; - - for (int i = 0; i < subvariables.size(); i++) { - AssignableAVM2Item an = subvariables.get(i); - if (an instanceof UnresolvedAVM2Item) { - UnresolvedAVM2Item n = (UnresolvedAVM2Item) an; - if (n.resolved == null) { - String fullClass = localData.getFullClass(); - GraphTargetItem res = n.resolve(new TypeItem(fullClass), paramTypes, paramNames, abc, allABCs, callStack, subvariables); - if (res instanceof AssignableAVM2Item) { - subvariables.set(i, (AssignableAVM2Item) res); - } else { - subvariables.remove(i); - i--; - } - } - } - } - - for (int t = 0; t < paramTypes.size(); t++) { - GraphTargetItem an = paramTypes.get(t); - if (an instanceof UnresolvedAVM2Item) { - UnresolvedAVM2Item n = (UnresolvedAVM2Item) an; - if (n.resolved == null) { - String fullClass = localData.getFullClass(); - GraphTargetItem res = n.resolve(new TypeItem(fullClass), paramTypes, paramNames, abc, allABCs, callStack, subvariables); - paramTypes.set(t, res); - } - } - } - - boolean hasArguments = false; - List slotNames = new ArrayList<>(); - List slotTypes = new ArrayList<>(); - slotNames.add("--first"); - slotTypes.add("-"); - - List registerNames = new ArrayList<>(); - List registerTypes = new ArrayList<>(); - if (className != null) { - String fullClassName = pkg == null || pkg.isEmpty() ? className : pkg + "." + className; - registerTypes.add(fullClassName); - localData.scopeStack.add(new LocalRegAVM2Item(null, registerNames.size(), null)); - registerNames.add("this"); - - } else { - registerTypes.add("global"); - registerNames.add("this"); - } - for (GraphTargetItem t : paramTypes) { - registerTypes.add(t.toString()); - slotTypes.add(t.toString()); - } - registerNames.addAll(paramNames); - slotNames.addAll(paramNames); - /*for (GraphTargetItem p : paramTypes) { - slotTypes.add("" + p); - }*/ - if (hasRest) { - slotTypes.add("*"); - } - localData.registerVars.clear(); - for (AssignableAVM2Item an : subvariables) { - if (an instanceof NameAVM2Item) { - NameAVM2Item n = (NameAVM2Item) an; - if (n.getVariableName().equals("arguments") & !n.isDefinition()) { - registerNames.add("arguments"); - registerTypes.add("Object"); - hasArguments = true; - break; - } - } - } - int paramRegCount = registerNames.size(); - - if (needsActivation) { - registerNames.add("+$activation"); - localData.activationReg = registerNames.size() - 1; - registerTypes.add("Object"); - localData.scopeStack.add(new LocalRegAVM2Item(null, localData.activationReg, null)); - } - - String mask = Configuration.registerNameFormat.get(); - mask = mask.replace("%d", "([0-9]+)"); - Pattern pat = Pattern.compile(mask); - - //Two rounds - for (int round = 1; round <= 2; round++) { - for (AssignableAVM2Item an : subvariables) { - if (an instanceof NameAVM2Item) { - NameAVM2Item n = (NameAVM2Item) an; - if (n.isDefinition()) { - if (!needsActivation || (n.getSlotScope() <= 0)) { - String varName = n.getVariableName(); - Matcher m = pat.matcher(varName); - //In first round, make all register that match standard loc_xx register - if ((round == 1) && (m.matches())) { - String regIndexStr = m.group(1); - int regIndex = Integer.parseInt(regIndexStr); - while (registerNames.size() <= regIndex + 1) { - String standardName = String.format(mask, registerNames.size() - 1); - registerNames.add(standardName); - registerTypes.add("*"); - slotNames.add(standardName); - slotTypes.add("*"); - } - registerNames.set(regIndex, varName); - registerTypes.set(regIndex, varName); - slotNames.set(regIndex, varName); - slotTypes.set(regIndex, varName); - } //in second round the rest - else if (round == 2 && !m.matches()) { - registerNames.add(n.getVariableName()); - registerTypes.add(n.type.toString()); - slotNames.add(n.getVariableName()); - slotTypes.add(n.type.toString()); - } - } - } - } - } - } - - int slotScope = subMethod ? 0 : 1; - - for (AssignableAVM2Item an : subvariables) { - if (an instanceof NameAVM2Item) { - NameAVM2Item n = (NameAVM2Item) an; - String variableName = n.getVariableName(); - if (variableName != null) { - boolean isThisOrSuper = variableName.equals("this") || variableName.equals("super"); - if (!isThisOrSuper && needsActivation) { - if (n.getSlotNumber() <= 0) { - n.setSlotNumber(slotNames.indexOf(variableName)); - n.setSlotScope(slotScope); - } - } else { - if (isThisOrSuper) { - n.setRegNumber(0); - } else { - n.setRegNumber(registerNames.indexOf(variableName)); - } - } - } - } - } - - for (int i = 0; i < registerNames.size(); i++) { - if (needsActivation && i > localData.activationReg) { - break; - } - localData.registerVars.put(registerNames.get(i), i); - } - List declarations = new ArrayList<>(); - loopn: - for (AssignableAVM2Item an : subvariables) { - if (an instanceof NameAVM2Item) { - NameAVM2Item n = (NameAVM2Item) an; - - if (needsActivation) { - if (n.getSlotScope() != slotScope) { - continue; - } else { - if (n.getSlotNumber() < paramRegCount) { - continue; - } - } - } - for (NameAVM2Item d : declarations) { - if (n.getVariableName() != null && n.getVariableName().equals(d.getVariableName())) { - continue loopn; - } - } - - for (GraphTargetItem it : body) { //search first level of commands - if (it instanceof NameAVM2Item) { - NameAVM2Item n2 = (NameAVM2Item) it; - if (n2.isDefinition() && n2.getAssignedValue() != null && n2.getVariableName().equals(n.getVariableName())) { - continue loopn; - } - if (!n2.isDefinition() && n2.getVariableName() != null && n2.getVariableName().equals(n.getVariableName())) { //used earlier than defined - break; - } - } - } - if (n.unresolved) { - continue; - } - if (n.redirect != null) { - continue; - } - if (n.getNs() != null) { - continue; - } - - String variableName = n.getVariableName(); - if ("this".equals(variableName) || "super".equals(variableName) || paramNames.contains(variableName) || "arguments".equals(variableName)) { - continue; - } - - NameAVM2Item d = new NameAVM2Item(n.type, n.line, n.getVariableName(), NameAVM2Item.getDefaultValue("" + n.type), true, n.openedNamespaces); - //no index - if (needsActivation) { - if (d.getSlotNumber() <= 0) { - d.setSlotNumber(n.getSlotNumber()); - d.setSlotScope(n.getSlotScope()); - } - } else { - d.setRegNumber(n.getRegNumber()); - } - declarations.add(d); - } - } - - int[] param_types = new int[paramTypes.size()]; - ValueKind[] optional = new ValueKind[paramValues.size()]; - //int[] param_names = new int[paramNames.size()]; - for (int i = 0; i < paramTypes.size(); i++) { - param_types[i] = typeName(localData, paramTypes.get(i)); - //param_names[i] = str(paramNames.get(i)); - } - - for (int i = 0; i < paramValues.size(); i++) { - optional[i] = getValueKind(Namespace.KIND_NAMESPACE/*FIXME*/, paramTypes.get(paramTypes.size() - paramValues.size() + i), paramValues.get(i)); - if (optional[i] == null) { - throw new CompilationException("Default value must be compiletime constant", line); - } - } - - MethodInfo mi = new MethodInfo(param_types, constructor ? 0 : typeName(localData, retType), 0/*name_index*/, 0, optional, new int[0]/*no param_names*/); - if (hasArguments) { - mi.setFlagNeed_Arguments(); - } - //No param names like in official - /* - if (!paramNames.isEmpty()) { - mi.setFlagHas_paramnames(); - }*/ - if (!paramValues.isEmpty()) { - mi.setFlagHas_optional(); - } - if (hasRest) { - mi.setFlagNeed_rest(); - } - - int mindex; - if (!isInterface) { - MethodBody mbody = new MethodBody(); - - if (needsActivation) { - int slotId = 1; - for (int i = 1; i < slotNames.size(); i++) { - TraitSlotConst tsc = new TraitSlotConst(); - tsc.slot_id = slotId++; - tsc.name_index = abc.constants.getMultinameId(new Multiname(Multiname.QNAME, abc.constants.getStringId(slotNames.get(i), true), abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE_INTERNAL, abc.constants.getStringId(pkg, true)), 0, true), 0, 0, new ArrayList()), true); - tsc.type_index = typeName(localData, new TypeItem(slotTypes.get(i))); - mbody.traits.traits.add(tsc); - } - for (int i = 1; i < paramRegCount; i++) { - NameAVM2Item param = new NameAVM2Item(new TypeItem(registerTypes.get(i)), 0, registerNames.get(i), null, false, new ArrayList()); - param.setRegNumber(i); - NameAVM2Item d = new NameAVM2Item(new TypeItem(registerTypes.get(i)), 0, registerNames.get(i), param, true, new ArrayList()); - d.setSlotScope(slotScope); - d.setSlotNumber(slotNames.indexOf(registerNames.get(i))); - declarations.add(d); - } - } - if (body != null) { - body.addAll(0, declarations); - } - - localData.exceptions = new ArrayList<>(); - localData.callStack.add(mbody); - List src = body == null ? new ArrayList() : generate(localData, body); - - mbody.method_info = abc.addMethodInfo(mi); - mi.setBody(mbody); - List mbodyCode = toInsList(src); - mbody.setCode(new AVM2Code()); - mbody.getCode().code = mbodyCode; - - if (needsActivation) { - if (localData.traitUsages.containsKey(mbody)) { - List usages = localData.traitUsages.get(mbody); - for (int i = 0; i < mbody.traits.traits.size(); i++) { - if (usages.contains(i)) { - TraitSlotConst tsc = (TraitSlotConst) mbody.traits.traits.get(i); - GraphTargetItem type = TypeItem.UNBOUNDED; - if (tsc.type_index > 0) { - type = new TypeItem(abc.constants.constant_multiname.get(tsc.type_index).getNameWithNamespace(abc.constants, true)); - } - NameAVM2Item d = new NameAVM2Item(type, 0, tsc.getName(abc).getName(abc.constants, new ArrayList(), true), NameAVM2Item.getDefaultValue("" + type), true, new ArrayList()); - d.setSlotNumber(tsc.slot_id); - d.setSlotScope(slotScope); - mbodyCode.addAll(0, toInsList(d.toSourceIgnoreReturnValue(localData, this))); - } - } - } - - List acts = new ArrayList<>(); - acts.add(ins(new NewActivationIns())); - acts.add(ins(new DupIns())); - acts.add(AssignableAVM2Item.generateSetLoc(localData.activationReg)); - acts.add(ins(new PushScopeIns())); - - mbodyCode.addAll(0, acts); - } - - if (constructor) { - List abcs = new ArrayList<>(); - abcs.add(abc); - abcs.addAll(allABCs); - - int parentConstMinAC = 0; - - for (ABC a : abcs) { - int ci = a.findClassByName(superType); - if (ci > -1) { - MethodInfo pmi = a.method_info.get(a.instance_info.get(ci).iinit_index); - parentConstMinAC = pmi.param_types.length; - if (pmi.flagHas_optional()) { - parentConstMinAC -= pmi.optional.length; - } - - } - } - int ac = -1; - for (AVM2Instruction ins : mbodyCode) { - if (ins.definition instanceof ConstructSuperIns) { - ac = ins.operands[0]; - if (parentConstMinAC > ac) { - throw new CompilationException("Parent constructor call requires different number of arguments", line); - } - - } - } - if (ac == -1) { - if (parentConstMinAC == 0) { - mbodyCode.add(0, new AVM2Instruction(0, new GetLocal0Ins(), null)); - mbodyCode.add(1, new AVM2Instruction(0, new ConstructSuperIns(), new int[]{0})); - - } else { - throw new CompilationException("Parent constructor must be called", line); - } - } - } - if (className != null && !subMethod) { - mbodyCode.add(0, new AVM2Instruction(0, new GetLocal0Ins(), null)); - mbodyCode.add(1, new AVM2Instruction(0, new PushScopeIns(), null)); - } - boolean addRet = false; - if (!mbodyCode.isEmpty()) { - InstructionDefinition lastDef = mbodyCode.get(mbodyCode.size() - 1).definition; - if (!((lastDef instanceof ReturnVoidIns) || (lastDef instanceof ReturnValueIns))) { - addRet = true; - } - } else { - addRet = true; - } - if (addRet) { - if (retType.toString().equals("*") || retType.toString().equals("void") || constructor) { - mbodyCode.add(new AVM2Instruction(0, new ReturnVoidIns(), null)); - } else { - mbodyCode.add(new AVM2Instruction(0, new PushUndefinedIns(), null)); - mbodyCode.add(new AVM2Instruction(0, new ReturnValueIns(), null)); - } - } - mbody.exceptions = localData.exceptions.toArray(new ABCException[localData.exceptions.size()]); - int offset = 0; - for (int i = 0; i < mbodyCode.size(); i++) { - AVM2Instruction ins = mbodyCode.get(i); - if (ins instanceof ExceptionMarkAVM2Instruction) { - ExceptionMarkAVM2Instruction m = (ExceptionMarkAVM2Instruction) ins; - switch (m.markType) { - case MARK_E_START: - mbody.exceptions[m.exceptionId].start = offset; - break; - case MARK_E_END: - mbody.exceptions[m.exceptionId].end = offset; - break; - case MARK_E_TARGET: - mbody.exceptions[m.exceptionId].target = offset; - break; - } - mbodyCode.remove(i); - i--; - continue; - } - offset += ins.getBytes().length; - } - - mbody.markOffsets(); - mbody.autoFillStats(abc, initScope, className != null); - abc.addMethodBody(mbody); - mindex = mbody.method_info; - } else { - mindex = abc.addMethodInfo(mi); - } - - return mindex; - } - - public ValueKind getValueKind(int ns, GraphTargetItem type, GraphTargetItem val) { - - if (val instanceof BooleanAVM2Item) { - BooleanAVM2Item bi = (BooleanAVM2Item) val; - if (bi.value) { - return new ValueKind(0, ValueKind.CONSTANT_True); - } else { - return new ValueKind(0, ValueKind.CONSTANT_False); - } - } - - boolean isNs = false; - if (type instanceof NameAVM2Item) { - if (((NameAVM2Item) type).getVariableName().equals("namespace")) { - isNs = true; - } - } - - if ((type instanceof TypeItem) && (((TypeItem) type).fullTypeName.equals("Namespace"))) { - isNs = true; - } - - if (val instanceof StringAVM2Item) { - StringAVM2Item sval = (StringAVM2Item) val; - if (isNs) { - return new ValueKind(namespace(Namespace.KIND_NAMESPACE, sval.value), ValueKind.CONSTANT_Namespace); - } else { - return new ValueKind(str(sval.value), ValueKind.CONSTANT_Utf8); - } - } - if (val instanceof IntegerValueAVM2Item) { - return new ValueKind(abc.constants.getIntId(((IntegerValueAVM2Item) val).value, true), ValueKind.CONSTANT_Int); - } - if (val instanceof FloatValueAVM2Item) { - return new ValueKind(abc.constants.getDoubleId(((FloatValueAVM2Item) val).value, true), ValueKind.CONSTANT_Double); - } - if (val instanceof NanAVM2Item) { - return new ValueKind(abc.constants.getDoubleId(Double.NaN, true), ValueKind.CONSTANT_Double); - } - if (val instanceof NullAVM2Item) { - return new ValueKind(0, ValueKind.CONSTANT_Null); - } - if (val instanceof UndefinedAVM2Item) { - return new ValueKind(0, ValueKind.CONSTANT_Undefined); - } - return null; - } - - private int genNs(List importedClasses, String pkg, String custom, int namespace, List openedNamespaces, SourceGeneratorLocalData localData, int line) throws CompilationException { - if (custom != null) { - PropertyAVM2Item prop = new PropertyAVM2Item(null, custom, abc, allABCs, openedNamespaces, new ArrayList()); - Reference value = new Reference<>(null); - prop.resolve(localData, new Reference(null), new Reference(null), new Reference<>(0), value); - boolean resolved = true; - if (value.getVal() == null) { - resolved = false; - } - if (!resolved) { - - String customPkg = ""; - String fullCustom = ""; - for (String imp : importedClasses) { - if (imp.endsWith("." + custom)) { - customPkg = imp.substring(0, imp.lastIndexOf('.')); - fullCustom = imp; - break; - } - } - - List aas = new ArrayList<>(); - aas.add(abc); - aas.addAll(allABCs); - for (ABC a : aas) { - for (ScriptInfo si : a.script_info) { - for (Trait t : si.traits.traits) { - Multiname m = t.getName(a); - if (fullCustom.equals(m.getNameWithNamespace(a.constants, true))) { - if (t instanceof TraitSlotConst) { - if (((TraitSlotConst) t).isNamespace()) { - Namespace ns = a.constants.getNamespace(((TraitSlotConst) t).value_index); - return abc.constants.getNamespaceId(new Namespace(ns.kind, abc.constants.getStringId(ns.getName(a.constants, true), true)), 0, true); - } - } - } - } - } - } - - throw new CompilationException("Namespace not defined", line); - } - namespace = value.getVal().value_index; - } - return namespace; - } - - public void generateTraitsPhase2(List importedClasses, String pkg, List items, Trait[] traits, List openedNamespaces, SourceGeneratorLocalData localData) throws CompilationException { - for (int k = 0; k < items.size(); k++) { - GraphTargetItem item = items.get(k); - if (traits[k] == null) { - continue; - } else if (item instanceof InterfaceAVM2Item) { - traits[k].name_index = traitName(((InterfaceAVM2Item) item).namespace, ((InterfaceAVM2Item) item).name); - } else if (item instanceof ClassAVM2Item) { - traits[k].name_index = traitName(((ClassAVM2Item) item).namespace, ((ClassAVM2Item) item).className); - } else if ((item instanceof MethodAVM2Item) || (item instanceof GetterAVM2Item) || (item instanceof SetterAVM2Item)) { - traits[k].name_index = traitName(genNs(importedClasses, pkg, ((MethodAVM2Item) item).customNamespace, ((MethodAVM2Item) item).namespace, openedNamespaces, localData, ((MethodAVM2Item) item).line), ((MethodAVM2Item) item).functionName); - } else if (item instanceof FunctionAVM2Item) { - traits[k].name_index = traitName(((FunctionAVM2Item) item).namespace, ((FunctionAVM2Item) item).functionName); - } else if (item instanceof ConstAVM2Item) { - traits[k].name_index = traitName(genNs(importedClasses, pkg, ((ConstAVM2Item) item).customNamespace, ((ConstAVM2Item) item).getNamespace(), openedNamespaces, localData, ((ConstAVM2Item) item).line), ((ConstAVM2Item) item).var); - } else if (item instanceof SlotAVM2Item) { - traits[k].name_index = traitName(genNs(importedClasses, pkg, ((SlotAVM2Item) item).customNamespace, ((SlotAVM2Item) item).getNamespace(), openedNamespaces, localData, ((SlotAVM2Item) item).line), ((SlotAVM2Item) item).var); - } - } - - for (int k = 0; k < items.size(); k++) { - GraphTargetItem item = items.get(k); - if (traits[k] == null) { - continue; - } - if (item instanceof ClassAVM2Item) { - InstanceInfo instanceInfo = abc.instance_info.get(((TraitClass) traits[k]).class_info); - instanceInfo.name_index = abc.constants.getMultinameId(new Multiname(Multiname.QNAME, abc.constants.getStringId(((ClassAVM2Item) item).className, true), - abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abc.constants.getStringId(pkg, true)), 0, true), 0, 0, new ArrayList()), true); - - if (((ClassAVM2Item) item).extendsOp != null) { - instanceInfo.super_index = typeName(localData, ((ClassAVM2Item) item).extendsOp); - } else { - instanceInfo.super_index = abc.constants.getMultinameId(new Multiname(Multiname.QNAME, str("Object"), namespace(Namespace.KIND_PACKAGE, ""), 0, 0, new ArrayList()), true); - } - instanceInfo.interfaces = new int[((ClassAVM2Item) item).implementsOp.size()]; - for (int i = 0; i < ((ClassAVM2Item) item).implementsOp.size(); i++) { - instanceInfo.interfaces[i] = superIntName(localData, ((ClassAVM2Item) item).implementsOp.get(i)); - } - } - if (item instanceof InterfaceAVM2Item) { - InstanceInfo instanceInfo = abc.instance_info.get(((TraitClass) traits[k]).class_info); - instanceInfo.name_index = abc.constants.getMultinameId(new Multiname(Multiname.QNAME, abc.constants.getStringId(((InterfaceAVM2Item) item).name, true), - abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abc.constants.getStringId(pkg, true)), 0, true), 0, 0, new ArrayList()), true); - - instanceInfo.interfaces = new int[((InterfaceAVM2Item) item).superInterfaces.size()]; - for (int i = 0; i < ((InterfaceAVM2Item) item).superInterfaces.size(); i++) { - GraphTargetItem un = ((InterfaceAVM2Item) item).superInterfaces.get(i); - instanceInfo.interfaces[i] = superIntName(localData, un); - } - } - } - } - - public int superIntName(SourceGeneratorLocalData localData, GraphTargetItem un) throws CompilationException { - if (un instanceof UnresolvedAVM2Item) { - ((UnresolvedAVM2Item) un).resolve(null, new ArrayList(), new ArrayList(), abc, allABCs, new ArrayList(), new ArrayList()); - un = ((UnresolvedAVM2Item) un).resolved; - } - if (!(un instanceof TypeItem)) { //not applyType - throw new CompilationException("Invalid type", 0); - } - TypeItem sup = (TypeItem) un; - int propId = resolveType(localData, sup, abc, allABCs); - int[] nss = new int[]{abc.constants.constant_multiname.get(propId).namespace_index}; - return abc.constants.getMultinameId(new Multiname(Multiname.MULTINAME, abc.constants.constant_multiname.get(propId).name_index, 0, abc.constants.getNamespaceSetId(new NamespaceSet(nss), true), 0, new ArrayList()), true); - - } - - public void generateTraitsPhase3(int methodInitScope, boolean isInterface, String className, String superName, boolean generateStatic, SourceGeneratorLocalData localData, List items, Traits ts, Trait[] traits, Map initScopes, Reference class_index) throws AVM2ParseException, CompilationException { - //Note: Names must be generated first before accesed in inner subs - for (int k = 0; k < items.size(); k++) { - GraphTargetItem item = items.get(k); - if (traits[k] == null) { - continue; - } - if (item instanceof InterfaceAVM2Item) { - generateClass(((InterfaceAVM2Item) item).namespace, abc.class_info.get(((TraitClass) traits[k]).class_info), abc.instance_info.get(((TraitClass) traits[k]).class_info), initScopes.get(traits[k]), ((InterfaceAVM2Item) item).pkg, localData, (InterfaceAVM2Item) item, class_index); - } - - if (item instanceof ClassAVM2Item) { - generateClass(((ClassAVM2Item) item).namespace, abc.class_info.get(((TraitClass) traits[k]).class_info), abc.instance_info.get(((TraitClass) traits[k]).class_info), initScopes.get(traits[k]), ((ClassAVM2Item) item).pkg, localData, (ClassAVM2Item) item, class_index); - } - if ((item instanceof MethodAVM2Item) || (item instanceof GetterAVM2Item) || (item instanceof SetterAVM2Item)) { - MethodAVM2Item mai = (MethodAVM2Item) item; - if (mai.isStatic() != generateStatic) { - continue; - } - ((TraitMethodGetterSetter) traits[k]).method_info = method(false, isInterface, new ArrayList(), mai.pkg, mai.needsActivation, mai.subvariables, methodInitScope + (mai.isStatic() ? 0 : 1), mai.hasRest, mai.line, className, superName, false, localData, mai.paramTypes, mai.paramNames, mai.paramValues, mai.body, mai.retType); - } else if (item instanceof FunctionAVM2Item) { - FunctionAVM2Item fai = (FunctionAVM2Item) item; - ((TraitFunction) traits[k]).method_info = method(false, isInterface, new ArrayList(), fai.pkg, fai.needsActivation, fai.subvariables, methodInitScope, fai.hasRest, fai.line, className, superName, false, localData, fai.paramTypes, fai.paramNames, fai.paramValues, fai.body, fai.retType); - } - } - } - - public Trait[] generateTraitsPhase1(String className, String superName, boolean generateStatic, SourceGeneratorLocalData localData, List items, Traits ts, Reference classIndex) throws AVM2ParseException, CompilationException { - Trait[] traits = new Trait[items.size()]; - int slot_id = 1; - int disp_id = 3; //1 and 2 are for constructor - for (int k = 0; k < items.size(); k++) { - GraphTargetItem item = items.get(k); - if (item instanceof InterfaceAVM2Item) { - TraitClass tc = new TraitClass(); - ClassInfo ci = new ClassInfo(); - InstanceInfo ii = new InstanceInfo(); - /*abc.class_info.add(ci); - abc.instance_info.add(ii);*/ - tc.class_info = classIndex.getVal(); - abc.addClass(ci, ii, classIndex.getVal()); - classIndex.setVal(classIndex.getVal() + 1); - ii.flags |= InstanceInfo.CLASS_INTERFACE; - //tc.class_info = abc.instance_info.size() - 1; - tc.kindType = Trait.TRAIT_CLASS; - //tc.name_index = traitName(((InterfaceAVM2Item) item).namespace, ((InterfaceAVM2Item) item).name); - tc.slot_id = 0; //? - ts.traits.add(tc); - traits[k] = tc; - } - - if (item instanceof ClassAVM2Item) { - TraitClass tc = new TraitClass(); - ClassInfo ci = new ClassInfo(); - InstanceInfo ii = new InstanceInfo(); - /*abc.class_info.add(ci); - abc.instance_info.add(instanceInfo);*/ - tc.class_info = classIndex.getVal(); - abc.addClass(ci, ii, classIndex.getVal()); - classIndex.setVal(classIndex.getVal() + 1); - //tc.class_info = abc.instance_info.size() - 1; - - /*instanceInfo.name_index = abc.constants.addMultiname(new Multiname(Multiname.QNAME, abc.constants.getStringId(((ClassAVM2Item) item).className, true), - abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abc.constants.getStringId(pkg.packageName, true)), 0, true), 0, 0, new ArrayList())); - */ - - /*if (((ClassAVM2Item) item).extendsOp != null) { - instanceInfo.super_index = typeName(localData, ((ClassAVM2Item) item).extendsOp); - } else { - instanceInfo.super_index = abc.constants.getMultinameId(new Multiname(Multiname.QNAME, str("Object"), namespace(Namespace.KIND_PACKAGE, ""), 0, 0, new ArrayList()), true); - }*/ - tc.kindType = Trait.TRAIT_CLASS; - // tc.name_index = traitName(((ClassAVM2Item) item).namespace, ((ClassAVM2Item) item).className); - tc.slot_id = slot_id++; - ts.traits.add(tc); - traits[k] = tc; - - } - if ((item instanceof SlotAVM2Item) || (item instanceof ConstAVM2Item)) { - TraitSlotConst tsc = new TraitSlotConst(); - tsc.kindType = (item instanceof SlotAVM2Item) ? Trait.TRAIT_SLOT : Trait.TRAIT_CONST; - String var = null; - GraphTargetItem val = null; - GraphTargetItem type = null; - boolean isNamespace = false; - int namespace = 0; - boolean isStatic = false; - if (item instanceof SlotAVM2Item) { - SlotAVM2Item sai = (SlotAVM2Item) item; - if (sai.isStatic() != generateStatic) { - continue; - } - var = sai.var; - val = sai.value; - type = sai.type; - isStatic = sai.isStatic(); - namespace = sai.getNamespace(); - } - if (item instanceof ConstAVM2Item) { - ConstAVM2Item cai = (ConstAVM2Item) item; - if (cai.isStatic() != generateStatic) { - continue; - } - var = cai.var; - val = cai.value; - type = cai.type; - namespace = cai.getNamespace(); - isNamespace = type.toString().equals("Namespace"); - isStatic = cai.isStatic(); - } - if (isNamespace) { - tsc.name_index = traitName(namespace, var); - } - tsc.type_index = isNamespace ? 0 : (type == null ? 0 : typeName(localData, type)); - - ValueKind vk = getValueKind(namespace, type, val); - if (vk == null) { - tsc.value_kind = ValueKind.CONSTANT_Undefined; - } else { - tsc.value_kind = vk.value_kind; - tsc.value_index = vk.value_index; - } - tsc.slot_id = isStatic ? slot_id++ : 0; - ts.traits.add(tsc); - traits[k] = tsc; - } - if ((item instanceof MethodAVM2Item) || (item instanceof GetterAVM2Item) || (item instanceof SetterAVM2Item)) { - MethodAVM2Item mai = (MethodAVM2Item) item; - if (mai.isStatic() != generateStatic) { - continue; - } - TraitMethodGetterSetter tmgs = new TraitMethodGetterSetter(); - tmgs.kindType = (item instanceof GetterAVM2Item) ? Trait.TRAIT_GETTER : ((item instanceof SetterAVM2Item) ? Trait.TRAIT_SETTER : Trait.TRAIT_METHOD); - //tmgs.name_index = traitName(((MethodAVM2Item) item).namespace, ((MethodAVM2Item) item).functionName); - tmgs.disp_id = mai.isStatic() ? disp_id++ : 0; //For a reason, there is disp_id only for static methods (or not?) - if (mai.isFinal() || mai.isStatic()) { - tmgs.kindFlags |= Trait.ATTR_Final; - } - if (mai.isOverride()) { - tmgs.kindFlags |= Trait.ATTR_Override; - } - ts.traits.add(tmgs); - - traits[k] = tmgs; - } else if (item instanceof FunctionAVM2Item) { - TraitFunction tf = new TraitFunction(); - tf.slot_id = slot_id++; - tf.kindType = Trait.TRAIT_FUNCTION; - //tf.name_index = traitName(((FunctionAVM2Item) item).namespace, ((FunctionAVM2Item) item).functionName); - ts.traits.add(tf); - traits[k] = tf; - } - } - - return traits; - } - - public ScriptInfo generateScriptInfo(SourceGeneratorLocalData localData, List commands, int classPos) throws AVM2ParseException, CompilationException { - Reference class_index = new Reference<>(classPos); - ScriptInfo si = new ScriptInfo(); - localData.currentScript = si; - Trait[] traitArr = generateTraitsPhase1(null, null, true, localData, commands, si.traits, class_index); - generateTraitsPhase2(new ArrayList(), null/*FIXME*/, commands, traitArr, new ArrayList(), localData); - MethodInfo mi = new MethodInfo(new int[0], 0, 0, 0, new ValueKind[0], new int[0]); - MethodBody mb = new MethodBody(); - mb.method_info = abc.addMethodInfo(mi); - mb.setCode(new AVM2Code()); - List mbCode = mb.getCode().code; - mbCode.add(ins(new GetLocal0Ins())); - mbCode.add(ins(new PushScopeIns())); - - int traitScope = 2; - - Map initScopes = new HashMap<>(); - - for (Trait t : si.traits.traits) { - if (t instanceof TraitClass) { - TraitClass tc = (TraitClass) t; - List parents = new ArrayList<>(); - if (localData.documentClass) { - mbCode.add(ins(new GetScopeObjectIns(), 0)); - traitScope++; - } else { - NamespaceSet nsset = new NamespaceSet(new int[]{abc.constants.constant_multiname.get(tc.name_index).namespace_index}); - mbCode.add(ins(new FindPropertyStrictIns(), abc.constants.getMultinameId(new Multiname(Multiname.MULTINAME, abc.constants.constant_multiname.get(tc.name_index).name_index, 0, abc.constants.getNamespaceSetId(nsset, true), 0, new ArrayList()), true))); - } - if (abc.instance_info.get(tc.class_info).isInterface()) { - mbCode.add(ins(new PushNullIns())); - } else { - - parentNamesAddNames(abc, allABCs, abc.instance_info.get(tc.class_info).name_index, parents, new ArrayList(), new ArrayList()); - for (int i = parents.size() - 1; i >= 1; i--) { - mbCode.add(ins(new GetLexIns(), parents.get(i))); - mbCode.add(ins(new PushScopeIns())); - traitScope++; - } - mbCode.add(ins(new GetLexIns(), parents.get(1))); - } - mbCode.add(ins(new NewClassIns(), tc.class_info)); - if (!abc.instance_info.get(tc.class_info).isInterface()) { - for (int i = parents.size() - 1; i >= 1; i--) { - mbCode.add(ins(new PopScopeIns())); - } - } - mbCode.add(ins(new InitPropertyIns(), tc.name_index)); - initScopes.put(t, traitScope); - traitScope = 1; - } - } - - mbCode.add(ins(new ReturnVoidIns())); - mb.autoFillStats(abc, 1, false); - abc.addMethodBody(mb); - si.init_index = mb.method_info; - localData.pkg = null; //FIXME: pkg.packageName; - generateTraitsPhase3(1/*??*/, false, null, null, true, localData, commands, si.traits, traitArr, initScopes, class_index); - return si; - } - - public static void parentNamesAddNames(ABC abc, List allABCs, int name_index, List indices, List names, List namespaces) { - List cindices = new ArrayList<>(); - - List outABCs = new ArrayList<>(); - parentNames(abc, allABCs, name_index, cindices, names, namespaces, outABCs); - for (int i = 0; i < cindices.size(); i++) { - ABC a = outABCs.get(i); - int m = cindices.get(i); - if (a == abc) { - indices.add(m); - continue; - } - Multiname superName = a.constants.constant_multiname.get(m); - indices.add( - abc.constants.getMultinameId( - new Multiname(Multiname.QNAME, - abc.constants.getStringId(superName.getName(a.constants, new ArrayList(), true), true), - abc.constants.getNamespaceId(new Namespace(superName.getNamespace(a.constants).kind, abc.constants.getStringId(superName.getNamespace(a.constants).getName(a.constants, true), true)), 0, true), 0, 0, new ArrayList()), true) - ); - } - } - - public static GraphTargetItem getTraitReturnType(ABC abc, Trait t) { - if (t instanceof TraitSlotConst) { - TraitSlotConst tsc = (TraitSlotConst) t; - if (tsc.type_index == 0) { - return TypeItem.UNBOUNDED; - } - return PropertyAVM2Item.multinameToType(tsc.type_index, abc.constants); - } - if (t instanceof TraitMethodGetterSetter) { - TraitMethodGetterSetter tmgs = (TraitMethodGetterSetter) t; - if (tmgs.kindType == Trait.TRAIT_GETTER) { - return PropertyAVM2Item.multinameToType(abc.method_info.get(tmgs.method_info).ret_type, abc.constants); - } - if (tmgs.kindType == Trait.TRAIT_SETTER) { - if (abc.method_info.get(tmgs.method_info).param_types.length > 0) { - return PropertyAVM2Item.multinameToType(abc.method_info.get(tmgs.method_info).param_types[0], abc.constants); - } else { - return TypeItem.UNBOUNDED; - } - } - } - if (t instanceof TraitFunction) { - return new TypeItem("Function"); - } - return TypeItem.UNBOUNDED; - } - - private static boolean eq(Object a, Object b) { - if (a == null && b == null) { - return true; - } - if (a == null) { - return false; - } - if (b == null) { - return false; - } - return a.equals(b); - } - - public static boolean searchPrototypeChain(boolean instanceOnly, List abcs, String pkg, String obj, String propertyName, Reference outName, Reference outNs, Reference outPropNs, Reference outPropNsKind, Reference outPropNsIndex, Reference outPropType, Reference outPropValue) { - - for (ABC abc : abcs) { - if (!instanceOnly) { - for (ScriptInfo ii : abc.script_info) { - if (ii.deleted) { - continue; - } - for (Trait t : ii.traits.traits) { - if (eq(pkg, t.getName(abc).getNamespace(abc.constants).getName(abc.constants, true))) { - if (propertyName.equals(t.getName(abc).getName(abc.constants, new ArrayList(), true))) { - outName.setVal(obj); - outNs.setVal(pkg); - outPropNs.setVal(t.getName(abc).getNamespace(abc.constants).getName(abc.constants, true)); - outPropNsKind.setVal(t.getName(abc).getNamespace(abc.constants).kind); - outPropNsIndex.setVal(abc.constants.getNamespaceSubIndex(t.getName(abc).namespace_index)); - outPropType.setVal(getTraitReturnType(abc, t)); - if (t instanceof TraitSlotConst) { - TraitSlotConst tsc = (TraitSlotConst) t; - outPropValue.setVal(new ValueKind(tsc.value_index, tsc.value_kind)); - } - return true; - } - } - } - } - } - for (int i = 0; i < abc.instance_info.size(); i++) { - InstanceInfo ii = abc.instance_info.get(i); - if (ii.deleted) { - continue; - } - Multiname clsName = ii.getName(abc.constants); - if (obj.equals(clsName.getName(abc.constants, new ArrayList(), true))) { - if (eq(pkg, clsName.getNamespace(abc.constants).getName(abc.constants, true))) { - //class found - - for (Trait t : ii.instance_traits.traits) { - if (t.getName(abc) == null) { //in traits phase 2 - continue; - } - if (propertyName.equals(t.getName(abc).getName(abc.constants, new ArrayList(), true))) { - outName.setVal(obj); - outNs.setVal(pkg); - outPropNs.setVal(t.getName(abc).getNamespace(abc.constants).getName(abc.constants, true)); - outPropNsKind.setVal(t.getName(abc).getNamespace(abc.constants).kind); - outPropNsIndex.setVal(abc.constants.getNamespaceSubIndex(t.getName(abc).namespace_index)); - outPropType.setVal(getTraitReturnType(abc, t)); - if (t instanceof TraitSlotConst) { - TraitSlotConst tsc = (TraitSlotConst) t; - outPropValue.setVal(new ValueKind(tsc.value_index, tsc.value_kind)); - } - return true; - } - } - - if (!instanceOnly) { - for (Trait t : abc.class_info.get(i).static_traits.traits) { - if (t.getName(abc) == null) { //in traits phase 2 - continue; - } - if (propertyName.equals(t.getName(abc).getName(abc.constants, new ArrayList(), true))) { - outName.setVal(obj); - outNs.setVal(pkg); - outPropNs.setVal(t.getName(abc).getNamespace(abc.constants).getName(abc.constants, true)); - outPropNsKind.setVal(t.getName(abc).getNamespace(abc.constants).kind); - outPropNsIndex.setVal(abc.constants.getNamespaceSubIndex(t.getName(abc).namespace_index)); - outPropType.setVal(getTraitReturnType(abc, t)); - if (t instanceof TraitSlotConst) { - TraitSlotConst tsc = (TraitSlotConst) t; - outPropValue.setVal(new ValueKind(tsc.value_index, tsc.value_kind)); - } - return true; - } - } - } - - Multiname superName = abc.constants.constant_multiname.get(ii.super_index); - if (superName != null) { - return searchPrototypeChain(instanceOnly, abcs, superName.getNamespace(abc.constants).getName(abc.constants, true), superName.getName(abc.constants, new ArrayList(), true), propertyName, outName, outNs, outPropNs, outPropNsKind, outPropNsIndex, outPropType, outPropValue); - } else { - return false; - } - } - } - } - } - return false; - } - - public static void parentNames(ABC abc, List allABCs, int name_index, List indices, List names, List namespaces, List outABCs) { - indices.add(name_index); - names.add(abc.constants.constant_multiname.get(name_index).getName(abc.constants, new ArrayList(), true)); - namespaces.add(abc.constants.constant_multiname.get(name_index).getNamespace(abc.constants).getName(abc.constants, true)); - Multiname mname = abc.constants.constant_multiname.get(name_index); - - outABCs.add(abc); - - List abcs = new ArrayList<>(); - abcs.add(abc); - abcs.addAll(allABCs); - - for (ABC a : abcs) { - for (int i = 0; i < a.instance_info.size(); i++) { - Multiname m = a.constants.constant_multiname.get(a.instance_info.get(i).name_index); - if (m.getName(a.constants, new ArrayList(), true).equals(mname.getName(abc.constants, new ArrayList(), true))) { - - if (m.getNamespace(a.constants).hasName(mname.getNamespace(abc.constants).getName(abc.constants, true), a.constants)) { - //Multiname superName = a.constants.constant_multiname.get(a.instance_info.get(i).super_index); - abcs.remove(a); - if (a.instance_info.get(i).super_index != 0) { - parentNames(a, abcs, a.instance_info.get(i).super_index, indices, names, namespaces, outABCs); - } - /*parentNames(abc,allABCs,abc.constants.getMultinameId( - new Multiname(superName.kind, - abc.constants.getStringId(superName.getName(a.constants, new ArrayList()),true), - abc.constants.getNamespaceId(new Namespace(superName.getNamespace(a.constants).kind, abc.constants.getStringId(superName.getNamespace(a.constants).getName(a.constants),true)),0,true), 0, 0, new ArrayList()), true),indices,names,namespaces,outABCs);*/ - return; - } - } - } - } - } - - /* public void calcRegisters(Reference activationReg, SourceGeneratorLocalData localData, boolean needsActivation, List funParamNames,List funSubVariables,List funBody, Reference hasArguments) throws ParseException { - - }*/ - /*public int resolveType(String objType) { - if (objType.equals("*")) { - return 0; - } - List abcs = new ArrayList<>(); - abcs.add(abc); - abcs.addAll(allABCs); - for (ABC a : abcs) { - int ci = a.findClassByName(objType); - if (ci != -1) { - Multiname tname = a.instance_info.get(ci).getName(a.constants); - return abc.constants.getMultinameId(new Multiname(tname.kind, - abc.constants.getStringId(tname.getName(a.constants, new ArrayList()), true), - abc.constants.getNamespaceId(new Namespace(tname.getNamespace(a.constants).kind, abc.constants.getStringId(tname.getNamespace(a.constants).getName(a.constants), true)), 0, true), 0, 0, new ArrayList()), true); - } - } - return 0; - }*/ - @Override - public List generate(SourceGeneratorLocalData localData, TypeItem item) throws CompilationException { - String currentFullClassName = localData.getFullClass(); - - if (localData.documentClass && item.toString().equals(currentFullClassName)) { - int slotId = 0; - int c = abc.findClassByName(currentFullClassName); - for (Trait t : localData.currentScript.traits.traits) { - if (t instanceof TraitClass) { - TraitClass tc = (TraitClass) t; - if (tc.class_info == c) { - slotId = tc.slot_id; - break; - } - } - } - return GraphTargetItem.toSourceMerge(localData, this, ins(new GetGlobalScopeIns()), ins(new GetSlotIns(), slotId)); - } else { - return GraphTargetItem.toSourceMerge(localData, this, ins(new GetLexIns(), resolveType(localData, item, abc, allABCs))); - } - } - - public static int resolveType(SourceGeneratorLocalData localData, GraphTargetItem item, ABC abc, List allABCs) throws CompilationException { - int name_index = 0; - GraphTargetItem typeItem = null; - - if (item instanceof UnresolvedAVM2Item) { - String fullClass = localData.getFullClass(); - item = ((UnresolvedAVM2Item) item).resolve(new TypeItem(fullClass), new ArrayList(), new ArrayList(), abc, allABCs, new ArrayList(), new ArrayList()); - } - if (item instanceof TypeItem) { - typeItem = item; - } else if (item instanceof ApplyTypeAVM2Item) { - typeItem = ((ApplyTypeAVM2Item) item).object; - } else { - throw new CompilationException("Invalid type:" + item.getClass().getName(), 0/*??*/); - } - if (typeItem instanceof UnresolvedAVM2Item) { - String fullClass = localData.getFullClass(); - typeItem = ((UnresolvedAVM2Item) typeItem).resolve(new TypeItem(fullClass), new ArrayList(), new ArrayList(), abc, allABCs, new ArrayList(), new ArrayList()); - } - - if (!(typeItem instanceof TypeItem)) { - throw new CompilationException("Invalid type", 0/*??*/); - } - - TypeItem type = (TypeItem) typeItem; - - String name = type.fullTypeName; - String pkg = ""; - if (name.contains(".")) { - pkg = name.substring(0, name.lastIndexOf('.')); - name = name.substring(name.lastIndexOf('.') + 1); - } - for (InstanceInfo ii : abc.instance_info) { - Multiname mname = abc.constants.constant_multiname.get(ii.name_index); - if (mname != null && name.equals(mname.getName(abc.constants, new ArrayList(), true))) { - if (mname.getNamespace(abc.constants).hasName(pkg, abc.constants)) { - name_index = ii.name_index; - break; - } - } - } - for (int i = 1; i < abc.constants.constant_multiname.size(); i++) { - Multiname mname = abc.constants.constant_multiname.get(i); - if (mname != null && name.equals(mname.getName(abc.constants, new ArrayList(), true))) { - if (mname.getNamespace(abc.constants) != null && pkg.equals(mname.getNamespace(abc.constants).getName(abc.constants, true))) { - name_index = i; - break; - } - } - } - if (name_index == 0) { - if (pkg.isEmpty() && localData.currentScript != null /*FIXME!*/) { - for (Trait t : localData.currentScript.traits.traits) { - if (t.getName(abc).getName(abc.constants, new ArrayList(), true).equals(name)) { - name_index = t.name_index; - break; - } - } - } - if (name_index == 0) { - name_index = abc.constants.getMultinameId(new Multiname(Multiname.QNAME, abc.constants.getStringId(name, true), abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abc.constants.getStringId(pkg, true)), 0, true), 0, 0, new ArrayList()), true); - } - } - - if (item instanceof ApplyTypeAVM2Item) { - ApplyTypeAVM2Item atype = (ApplyTypeAVM2Item) item; - List params = new ArrayList<>(); - for (GraphTargetItem s : atype.params) { - params.add(resolveType(localData, s, abc, allABCs)); - } - return abc.constants.getMultinameId(new Multiname(Multiname.TYPENAME, 0, 0, 0, name_index, params), true); - } - - return name_index; - } - - @Override - public List generateDiscardValue(SourceGeneratorLocalData localData, GraphTargetItem item) throws CompilationException { - List ret = item.toSource(localData, this); - ret.add(ins(new PopIns())); - return ret; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +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.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.construction.ConstructIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.construction.ConstructSuperIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.construction.NewActivationIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.construction.NewCatchIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.construction.NewClassIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.construction.NewFunctionIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.construction.NewObjectIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.IfFalseIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.IfStrictNeIns; +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.jumps.LookupSwitchIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.GetLocal0Ins; +import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.KillIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other.FindPropertyIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other.FindPropertyStrictIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetDescendantsIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetGlobalScopeIns; +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.GetSlotIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other.HasNext2Ins; +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.NextNameIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other.NextValueIns; +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.other.SetPropertyIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other.SetSlotIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other.ThrowIns; +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.PopScopeIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushByteIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushNullIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushScopeIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushStringIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushUndefinedIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushWithIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.SwapIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.types.CoerceAIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.types.ConvertBIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.xml.CheckFilterIns; +import com.jpexs.decompiler.flash.abc.avm2.model.AVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.ApplyTypeAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.BooleanAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.FloatValueAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.GetDescendantsAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.IntegerValueAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.LocalRegAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.NanAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.NullAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.ReturnValueAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.ReturnVoidAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.StringAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.ThrowAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.UndefinedAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.WithAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.WithObjectAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.clauses.ForEachInAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.clauses.ForInAVM2Item; +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.AVM2ParseException; +import com.jpexs.decompiler.flash.abc.types.ABCException; +import com.jpexs.decompiler.flash.abc.types.ClassInfo; +import com.jpexs.decompiler.flash.abc.types.InstanceInfo; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.flash.abc.types.Multiname; +import com.jpexs.decompiler.flash.abc.types.Namespace; +import com.jpexs.decompiler.flash.abc.types.NamespaceSet; +import com.jpexs.decompiler.flash.abc.types.ScriptInfo; +import com.jpexs.decompiler.flash.abc.types.ValueKind; +import com.jpexs.decompiler.flash.abc.types.traits.Trait; +import com.jpexs.decompiler.flash.abc.types.traits.TraitClass; +import com.jpexs.decompiler.flash.abc.types.traits.TraitFunction; +import com.jpexs.decompiler.flash.abc.types.traits.TraitMethodGetterSetter; +import com.jpexs.decompiler.flash.abc.types.traits.TraitSlotConst; +import com.jpexs.decompiler.flash.abc.types.traits.Traits; +import com.jpexs.decompiler.flash.configuration.Configuration; +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.Loop; +import com.jpexs.decompiler.graph.SourceGenerator; +import com.jpexs.decompiler.graph.TypeItem; +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.DoWhileItem; +import com.jpexs.decompiler.graph.model.DuplicateItem; +import com.jpexs.decompiler.graph.model.ForItem; +import com.jpexs.decompiler.graph.model.IfItem; +import com.jpexs.decompiler.graph.model.LocalData; +import com.jpexs.decompiler.graph.model.NotItem; +import com.jpexs.decompiler.graph.model.OrItem; +import com.jpexs.decompiler.graph.model.SwitchItem; +import com.jpexs.decompiler.graph.model.TernarOpItem; +import com.jpexs.decompiler.graph.model.UnboundedTypeItem; +import com.jpexs.decompiler.graph.model.WhileItem; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * + * @author JPEXS + */ +public class AVM2SourceGenerator implements SourceGenerator { + + public final ABC abc; + + public List allABCs; + + public static final int MARK_E_START = 0; + + public static final int MARK_E_END = 1; + + public static final int MARK_E_TARGET = 2; + + public static final int MARK_E_FINALLYPART = 3; + + private AVM2Instruction ins(InstructionDefinition def, int... operands) { + return new AVM2Instruction(0, def, operands); + } + + public List generate(SourceGeneratorLocalData localData, GetDescendantsAVM2Item item) throws CompilationException { + int[] nssa = new int[item.openedNamespaces.size()]; + for (int i = 0; i < item.openedNamespaces.size(); i++) { + nssa[i] = item.openedNamespaces.get(i); + } + int nsset = abc.constants.getNamespaceSetId(new NamespaceSet(nssa), true); + + return GraphTargetItem.toSourceMerge(localData, this, + item.object, + ins(new GetDescendantsIns(), abc.constants.getMultinameId(new Multiname(Multiname.MULTINAME, abc.constants.getStringId(item.nameStr, true), 0, nsset, 0, new ArrayList()), true)) + ); + } + + @Override + public List generate(SourceGeneratorLocalData localData, AndItem item) throws CompilationException { + List ret = new ArrayList<>(); + ret.addAll(generateToActionList(localData, item.leftSide)); + if (!("" + item.leftSide.returnType()).equals("Boolean")) { + ret.add(ins(new ConvertBIns())); + } + ret.add(ins(new DupIns())); + List andExpr = generateToActionList(localData, item.rightSide); + andExpr.add(0, ins(new PopIns())); + int andExprLen = insToBytes(andExpr).length; + ret.add(ins(new IfFalseIns(), andExprLen)); + ret.addAll(andExpr); + return ret; + + } + + private byte[] insToBytes(List code) { + try { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + for (AVM2Instruction instruction : code) { + + baos.write(instruction.getBytes()); + + } + return baos.toByteArray(); + } catch (IOException ex) { + Logger.getLogger(AVM2SourceGenerator.class.getName()).log(Level.SEVERE, null, ex); + } + return new byte[0]; + } + + @Override + public List generate(SourceGeneratorLocalData localData, OrItem item) throws CompilationException { + List ret = new ArrayList<>(); + ret.addAll(generateToActionList(localData, item.leftSide)); + if (!("" + item.leftSide.returnType()).equals("Boolean")) { + ret.add(ins(new ConvertBIns())); + } + ret.add(ins(new DupIns())); + List orExpr = generateToActionList(localData, item.rightSide); + orExpr.add(0, ins(new PopIns())); + int orExprLen = insToBytes(orExpr).length; + ret.add(ins(new IfTrueIns(), orExprLen)); + ret.addAll(orExpr); + return ret; + } + + public List toInsList(List items) { + List ret = new ArrayList<>(); + for (GraphSourceItem s : items) { + if (s instanceof AVM2Instruction) { + ret.add((AVM2Instruction) s); + } + } + return ret; + } + + private List nonempty(List list) { + if (list == null) { + return new ArrayList<>(); + } + return list; + } + + private List condition(SourceGeneratorLocalData localData, GraphTargetItem t, int offset) throws CompilationException { + 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) throws CompilationException { + 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) throws CompilationException { + List ret = new ArrayList<>(); + //ret.addAll(notCondition(localData, expression)); + List onTrue = null; + List onFalse = null; + if (ternar) { + onTrue = toInsList(onTrueCmds.get(0).toSource(localData, this)); + } else { + onTrue = generateToInsList(localData, onTrueCmds); + } + + if (onFalseCmds != null && !onFalseCmds.isEmpty()) { + if (ternar) { + onFalse = toInsList(onFalseCmds.get(0).toSource(localData, this)); + } else { + onFalse = generateToInsList(localData, onFalseCmds); + } + } + 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); + onTrue.add(ajmp); + } + } + + 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) { + ajmp.operands[0] = onFalseLen; + } + ret.addAll(onFalse); + } + return ret; + } + + public List generate(SourceGeneratorLocalData localData, XMLFilterAVM2Item item) throws CompilationException { + List ret = new ArrayList<>(); + final Reference counterReg = new Reference<>(0); + final Reference collectionReg = new Reference<>(0); + final Reference xmlListReg = new Reference<>(0); + List xmlListSetTemp = AssignableAVM2Item.setTemp(localData, this, xmlListReg); + ret.addAll(GraphTargetItem.toSourceMerge(localData, this, + ins(new PushByteIns(), 0), + AssignableAVM2Item.setTemp(localData, this, counterReg), + item.object, + ins(new CheckFilterIns()), + NameAVM2Item.generateCoerce(localData, this, TypeItem.UNBOUNDED), + AssignableAVM2Item.setTemp(localData, this, collectionReg), + ins(new GetLexIns(), abc.constants.getMultinameId(new Multiname(Multiname.QNAME, abc.constants.getStringId("XMLList", true), abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abc.constants.getStringId("", true)), 0, true), 0, 0, new ArrayList()), true)), + ins(new PushStringIns(), abc.constants.getStringId("", true)), + ins(new ConstructIns(), 1), + xmlListSetTemp + )); + final Reference tempVal1 = new Reference<>(0); + final Reference tempVal2 = new Reference<>(0); + + List forBody = toInsList(GraphTargetItem.toSourceMerge(localData, this, + ins(new LabelIns()), + AssignableAVM2Item.getTemp(localData, this, collectionReg), + AssignableAVM2Item.getTemp(localData, this, counterReg), + ins(new NextValueIns()), + AssignableAVM2Item.dupSetTemp(localData, this, tempVal1), + AssignableAVM2Item.dupSetTemp(localData, this, tempVal2), + ins(new PushWithIns()) + )); + localData.scopeStack.add(new LocalRegAVM2Item(null, tempVal2.getVal(), null)); + forBody.addAll(toInsList(item.value.toSource(localData, this))); + List trueBody = new ArrayList<>(); + trueBody.addAll(toInsList(AssignableAVM2Item.getTemp(localData, this, xmlListReg))); + trueBody.addAll(toInsList(AssignableAVM2Item.getTemp(localData, this, counterReg))); + trueBody.addAll(toInsList(AssignableAVM2Item.getTemp(localData, this, tempVal1))); + int[] nss = new int[item.openedNamespaces.size()]; + for (int i = 0; i < item.openedNamespaces.size(); i++) { + nss[i] = item.openedNamespaces.get(i); + } + trueBody.add(ins(new SetPropertyIns(), abc.constants.getMultinameId(new Multiname(Multiname.MULTINAMEL, 0, 0, abc.constants.getNamespaceSetId(new NamespaceSet(nss), true), 0, new ArrayList()), true))); + forBody.add(ins(new IfFalseIns(), insToBytes(trueBody).length)); + forBody.addAll(trueBody); + forBody.add(ins(new PopScopeIns())); + localData.scopeStack.remove(localData.scopeStack.size() - 1); + forBody.addAll(toInsList(AssignableAVM2Item.killTemp(localData, this, Arrays.asList(tempVal2, tempVal1)))); + + int forBodyLen = insToBytes(forBody).length; + AVM2Instruction forwardJump = ins(new JumpIns(), forBodyLen); + ret.add(forwardJump); + + List expr = new ArrayList<>(); + expr.add(ins(new HasNext2Ins(), collectionReg.getVal(), counterReg.getVal())); + AVM2Instruction backIf = ins(new IfTrueIns(), 0); + expr.add(backIf); + + int exprLen = insToBytes(expr).length; + backIf.operands[0] = -(exprLen + forBodyLen); + + ret.addAll(forBody); + ret.addAll(expr); + ret.addAll(AssignableAVM2Item.killTemp(localData, this, Arrays.asList(collectionReg, counterReg))); + ret.addAll(AssignableAVM2Item.getTemp(localData, this, xmlListReg)); + ret.addAll(AssignableAVM2Item.killTemp(localData, this, Arrays.asList(xmlListReg))); + return ret; + } + + @Override + public List generate(SourceGeneratorLocalData localData, IfItem item) throws CompilationException { + return generateIf(localData, item.expression, item.onTrue, item.onFalse, false); + } + + private void fixSwitch(List code, int breakOffset, long loopId) { + fixLoop(code, breakOffset, Integer.MAX_VALUE, loopId); + } + + private void fixLoop(List code, int breakOffset, int continueOffset, long loopId) { + int pos = 0; + for (int a = 0; a < code.size(); a++) { + AVM2Instruction ins = code.get(a); + pos += ins.getBytes().length; + if (ins.definition instanceof JumpIns) { + if (ins.definition instanceof ContinueJumpIns) { + if (continueOffset != Integer.MAX_VALUE) { + ins.operands[0] = (-pos + continueOffset); + code.get(a).definition = new JumpIns(); + } + } + if (ins.definition instanceof BreakJumpIns) { + ins.operands[0] = (-pos + breakOffset); + code.get(a).definition = new JumpIns(); + } + } + } + } + + @Override + public List generate(SourceGeneratorLocalData localData, TernarOpItem item) throws CompilationException { + List onTrue = new ArrayList<>(); + onTrue.add(item.onTrue); + List onFalse = new ArrayList<>(); + onFalse.add(item.onFalse); + return generateIf(localData, item.expression, onTrue, onFalse, true); + } + + @Override + public List generate(SourceGeneratorLocalData localData, WhileItem item) throws CompilationException { + List ret = new ArrayList<>(); + List whileExpr = new ArrayList<>(); + + 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(generateToInsList(localData, ex)); + } + List whileBody = generateToInsList(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; + } + + public List generate(SourceGeneratorLocalData localData, ForEachInAVM2Item item) throws CompilationException { + return generateForIn(localData, item.loop, item.expression.collection, (AssignableAVM2Item) item.expression.object, item.commands, true); + } + + public List generate(SourceGeneratorLocalData localData, ForInAVM2Item item) throws CompilationException { + return generateForIn(localData, item.loop, item.expression.collection, (AssignableAVM2Item) item.expression.object, item.commands, false); + } + + public List generateForIn(SourceGeneratorLocalData localData, Loop loop, GraphTargetItem collection, AssignableAVM2Item assignable, List commands, final boolean each) throws CompilationException { + List ret = new ArrayList<>(); + final Reference counterReg = new Reference<>(0); + final Reference collectionReg = new Reference<>(0); + + if (assignable instanceof UnresolvedAVM2Item) { + assignable = (AssignableAVM2Item) ((UnresolvedAVM2Item) assignable).resolved; + } + + ret.addAll(GraphTargetItem.toSourceMerge(localData, this, + ins(new PushByteIns(), 0), + AssignableAVM2Item.setTemp(localData, this, counterReg), + collection, + NameAVM2Item.generateCoerce(localData, this, TypeItem.UNBOUNDED), + AssignableAVM2Item.setTemp(localData, this, collectionReg) + )); + + GraphTargetItem assigned = new GraphTargetItem() { + + @Override + public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException { + return null; + } + + @Override + public boolean hasReturnValue() { + return true; + } + + @Override + public GraphTargetItem returnType() { + return TypeItem.UNBOUNDED; + } + + @Override + public List toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException { + return toSourceMerge(localData, generator, + AssignableAVM2Item.getTemp(localData, generator, collectionReg), + AssignableAVM2Item.getTemp(localData, generator, counterReg), + ins(each ? new NextValueIns() : new NextNameIns()) + ); + } + }; + assignable.setAssignedValue(assigned); + + List forBody = toInsList(GraphTargetItem.toSourceMerge(localData, this, + ins(new LabelIns()), + assignable.toSourceIgnoreReturnValue(localData, this) + )); + + forBody.addAll(generateToInsList(localData, commands)); + int forBodyLen = insToBytes(forBody).length; + + AVM2Instruction forwardJump = ins(new JumpIns(), forBodyLen); + ret.add(forwardJump); + + List expr = new ArrayList<>(); + expr.add(ins(new HasNext2Ins(), collectionReg.getVal(), counterReg.getVal())); + AVM2Instruction backIf = ins(new IfTrueIns(), 0); + expr.add(backIf); + + int exprLen = insToBytes(expr).length; + backIf.operands[0] = -(exprLen + forBodyLen); + + fixLoop(forBody, forBodyLen + exprLen, forBodyLen, loop.id); + ret.addAll(forBody); + ret.addAll(expr); + ret.addAll(AssignableAVM2Item.killTemp(localData, this, Arrays.asList(collectionReg, counterReg))); + return ret; + } + + @Override + public List generate(SourceGeneratorLocalData localData, DoWhileItem item) throws CompilationException { + List ret = new ArrayList<>(); + List whileExpr = new ArrayList<>(); + + 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(generateToInsList(localData, ex)); + } + List dowhileBody = generateToInsList(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; + } + + public List generate(SourceGeneratorLocalData localData, WithAVM2Item item) throws CompilationException { + + List ret = new ArrayList<>(); + ret.addAll(item.scope.toSource(localData, this)); + Reference tempReg = new Reference<>(0); + ret.addAll(AssignableAVM2Item.dupSetTemp(localData, this, tempReg)); + localData.scopeStack.add(new WithObjectAVM2Item(null, new LocalRegAVM2Item(null, tempReg.getVal(), null))); + ret.add(ins(new PushWithIns())); + ret.addAll(generate(localData, item.items)); + ret.add(ins(new PopScopeIns())); + ret.addAll(AssignableAVM2Item.killTemp(localData, this, Arrays.asList(tempReg))); + localData.scopeStack.remove(localData.scopeStack.size() - 1); + return ret; + } + + @Override + public List generate(SourceGeneratorLocalData localData, ForItem item) throws CompilationException { + List ret = new ArrayList<>(); + List forExpr = new ArrayList<>(); + + 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(generateToInsList(localData, ex)); + } + List forBody = generateToInsList(localData, item.commands); + List forFinalCommands = generateToInsList(localData, item.finalCommands); + + ret.addAll(generateToInsList(localData, item.firstCommands)); + + AVM2Instruction forwardJump = ins(new JumpIns(), 0); + ret.add(forwardJump); + forBody.add(0, ins(new LabelIns())); + ret.addAll(forBody); + ret.addAll(forFinalCommands); + 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; + + public String uniqId() { + uniqLast++; + return "" + uniqLast; + } + + @Override + public List generate(SourceGeneratorLocalData localData, SwitchItem item) throws CompilationException { + List ret = new ArrayList<>(); + Reference switchedReg = new Reference<>(0); + AVM2Instruction forwardJump = ins(new JumpIns(), 0); + ret.add(forwardJump); + + List cases = new ArrayList<>(); + cases.addAll(toInsList(new IntegerValueAVM2Item(null, (long) item.caseValues.size()).toSource(localData, this))); + int cLen = insToBytes(cases).length; + List caseLast = new ArrayList<>(); + caseLast.add(0, ins(new JumpIns(), cLen)); + caseLast.addAll(0, toInsList(new IntegerValueAVM2Item(null, (long) item.caseValues.size()).toSource(localData, this))); + int cLastLen = insToBytes(caseLast).length; + caseLast.add(0, ins(new JumpIns(), cLastLen)); + cases.addAll(0, caseLast); + + List preCases = new ArrayList<>(); + preCases.addAll(toInsList(item.switchedObject.toSource(localData, this))); + preCases.addAll(toInsList(AssignableAVM2Item.setTemp(localData, this, switchedReg))); + + for (int i = item.caseValues.size() - 1; i >= 0; i--) { + List sub = new ArrayList<>(); + sub.addAll(toInsList(new IntegerValueAVM2Item(null, (long) i).toSource(localData, this))); + sub.add(ins(new JumpIns(), insToBytes(cases).length)); + int subLen = insToBytes(sub).length; + + cases.addAll(0, sub); + cases.add(0, ins(new IfStrictNeIns(), subLen)); + cases.addAll(0, toInsList(AssignableAVM2Item.getTemp(localData, this, switchedReg))); + cases.addAll(0, toInsList(item.caseValues.get(i).toSource(localData, this))); + } + cases.addAll(0, preCases); + + AVM2Instruction lookupOp = new AVM2Instruction(0, new LookupSwitchIns(), new int[item.caseValues.size() + 1 + 1 + 1]); + cases.addAll(toInsList(AssignableAVM2Item.killTemp(localData, this, Arrays.asList(switchedReg)))); + List bodies = new ArrayList<>(); + List bodiesOffsets = new ArrayList<>(); + int defOffset; + int casesLen = insToBytes(cases).length; + bodies.addAll(generateToInsList(localData, item.defaultCommands)); + bodies.add(0, ins(new LabelIns())); + 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); + for (int i = item.caseCommands.size() - 1; i >= 0; i--) { + bodies.addAll(0, generateToInsList(localData, item.caseCommands.get(i))); + bodies.add(0, ins(new LabelIns())); + bodiesOffsets.add(0, -(insToBytes(bodies).length + casesLen)); + } + 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)); + } + + forwardJump.operands[0] = insToBytes(bodies).length; + ret.addAll(bodies); + ret.addAll(cases); + ret.add(lookupOp); + fixSwitch(toInsList(ret), insToBytes(toInsList(ret)).length, uniqLast); + return ret; + } + + @Override + public List generate(SourceGeneratorLocalData localData, NotItem item) throws CompilationException { + /*if (item.getOriginal() instanceof Inverted) { + GraphTargetItem norig = ((Inverted) item).invert(); + return norig.toSource(localData, this); + }*/ + List ret = new ArrayList<>(); + ret.addAll(item.getOriginal().toSource(localData, this)); + ret.add(ins(new NotIns())); + return ret; + } + + @Override + public List generate(SourceGeneratorLocalData localData, DuplicateItem item) { + List ret = new ArrayList<>(); + ret.add(ins(new DupIns())); + return ret; + } + + @Override + public List generate(SourceGeneratorLocalData localData, BreakItem item) { + List ret = new ArrayList<>(); + AVM2Instruction abreak = ins(new BreakJumpIns(item.loopId), 0); + ret.add(abreak); + return ret; + } + + public List generate(SourceGeneratorLocalData localData, FunctionAVM2Item item) throws CompilationException { + List ret = new ArrayList<>(); + int scope = 0; + if (!item.functionName.isEmpty()) { + ret.add(ins(new NewObjectIns(), 0)); + ret.add(ins(new PushWithIns())); + scope = localData.scopeStack.size(); + localData.scopeStack.add(new PropertyAVM2Item(null, item.functionName, abc, allABCs, new ArrayList(), localData.callStack)); + } + ret.add(ins(new NewFunctionIns(), method(true, false, localData.callStack, localData.pkg, item.needsActivation, item.subvariables, 0 /*Set later*/, item.hasRest, item.line, localData.currentClass, null, false, localData, item.paramTypes, item.paramNames, item.paramValues, item.body, item.retType))); + if (!item.functionName.isEmpty()) { + ret.add(ins(new DupIns())); + ret.add(ins(new GetScopeObjectIns(), scope)); + ret.add(ins(new SwapIns())); + ret.add(ins(new SetPropertyIns(), abc.constants.getMultinameId(new Multiname(Multiname.QNAME, abc.constants.getStringId(item.functionName, true), abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abc.constants.getStringId(localData.pkg, true)), 0, true), 0, 0, new ArrayList()), true))); + ret.add(ins(new PopScopeIns())); + localData.scopeStack.remove(localData.scopeStack.size() - 1); + } + return ret; + } + + private static int currentFinId = 1; + + private static int finId() { + return currentFinId++; + } + + public List generate(SourceGeneratorLocalData localData, TryAVM2Item item) throws CompilationException { + List ret = new ArrayList<>(); + + boolean newFinallyReg = false; + List newex = new ArrayList<>(); + int aloneFinallyEx = -1; + int finallyEx = -1; + for (NameAVM2Item e : item.catchExceptions2) { + ABCException aex = new ABCException(); + aex.name_index = abc.constants.getMultinameId(new Multiname(Multiname.QNAME, abc.constants.getStringId(e.getVariableName(), true), abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abc.constants.getStringId("", true)), 0, true), 0, 0, new ArrayList()), true); + aex.type_index = typeName(localData, e.type); + newex.add(aex); + } + int finId = 0; + if (item.finallyCommands != null) { + if (item.catchExceptions2.isEmpty()) { + ABCException aex = new ABCException(); + aex.name_index = 0; + aex.type_index = 0; + newex.add(aex); + aloneFinallyEx = newex.size() - 1; + } + ABCException aex = new ABCException(); + aex.name_index = 0; + aex.type_index = 0; + newex.add(aex); + finallyEx = newex.size() - 1; + if (localData.finallyRegister == -1) { + localData.finallyRegister = getFreeRegister(localData); + killRegister(localData, localData.finallyRegister); //reuse for catches + newFinallyReg = true; + } + finId = finId(); + } + + if (finallyEx > -1) { + localData.finallyCatches.add(finId); + } + List tryCmds = generateToInsList(localData, item.tryCommands); + + //int i = firstId + item.catchCommands.size() - 1; + List catches = new ArrayList<>(); + Reference tempReg = new Reference<>(0); + + List currentExceptionIds = new ArrayList<>(); + List> catchCmds = new ArrayList<>(); + for (int c = 0; c < item.catchCommands.size(); c++) { + int i = localData.exceptions.size(); + localData.exceptions.add(newex.get(c)); + + currentExceptionIds.add(i); + + //Reference tempReg=new Reference<>(0); + List catchCmd = new ArrayList<>(); + catchCmd.add(ins(new NewCatchIns(), i)); + catchCmd.addAll(toInsList(AssignableAVM2Item.dupSetTemp(localData, this, tempReg))); + catchCmd.add(ins(new DupIns())); + catchCmd.add(ins(new PushScopeIns())); + catchCmd.add(ins(new SwapIns())); + catchCmd.add(ins(new SetSlotIns(), 1)); + + for (AssignableAVM2Item a : item.catchVariables.get(c)) { + GraphTargetItem r = a; + if (r instanceof UnresolvedAVM2Item) { + r = ((UnresolvedAVM2Item) r).resolvedRoot; + } + if (r instanceof NameAVM2Item) { + NameAVM2Item n = (NameAVM2Item) r; + if (item.catchExceptions2.get(c).getVariableName().equals(n.getVariableName())) { + n.setSlotScope(localData.scopeStack.size()); + } + } + } + localData.scopeStack.add(new LocalRegAVM2Item(null, tempReg.getVal(), null)); + catchCmd.addAll(generateToInsList(localData, item.catchCommands.get(c))); + localData.scopeStack.remove(localData.scopeStack.size() - 1); + catchCmd.add(ins(new PopScopeIns())); + catchCmd.addAll(toInsList(AssignableAVM2Item.killTemp(localData, this, Arrays.asList(tempReg)))); + catchCmds.add(catchCmd); + } + for (int c = item.catchCommands.size() - 1; c >= 0; c--) { + List preCatches = new ArrayList<>(); + /*preCatches.add(ins(new GetLocal0Ins())); + preCatches.add(ins(new PushScopeIns())); + preCatches.add(AssignableAVM2Item.generateGetLoc(localData.activationReg)); + preCatches.add(ins(new PushScopeIns()));*/ + for (GraphTargetItem s : localData.scopeStack) { + preCatches.addAll(toInsList(s.toSource(localData, this))); + if (s instanceof WithObjectAVM2Item) { + preCatches.add(ins(new PushWithIns())); + } else { + preCatches.add(ins(new PushScopeIns())); + } + } + + //catchCmds.add(catchCmd); + preCatches.addAll(catchCmds.get(c)); + catches.addAll(0, preCatches); + catches.add(0, new ExceptionMarkAVM2Instruction(currentExceptionIds.get(c), MARK_E_TARGET)); + catches.add(0, ins(new JumpIns(), insToBytes(catches).length)); + } + + if (aloneFinallyEx > -1) { + localData.exceptions.add(newex.get(aloneFinallyEx)); + aloneFinallyEx = localData.exceptions.size() - 1; + + } + if (finallyEx > -1) { + localData.exceptions.add(newex.get(finallyEx)); + finallyEx = localData.exceptions.size() - 1; + } + + for (int i : currentExceptionIds) { + ret.add(new ExceptionMarkAVM2Instruction(i, MARK_E_START)); + } + if (aloneFinallyEx > -1) { + ret.add(new ExceptionMarkAVM2Instruction(aloneFinallyEx, MARK_E_START)); + } + if (finallyEx > -1) { + ret.add(new ExceptionMarkAVM2Instruction(finallyEx, MARK_E_START)); + } + + ret.addAll(tryCmds); + + for (int i : currentExceptionIds) { + ret.add(new ExceptionMarkAVM2Instruction(i, MARK_E_END)); + } + if (aloneFinallyEx > -1) { + ret.add(new ExceptionMarkAVM2Instruction(aloneFinallyEx, MARK_E_END)); + } + + if (aloneFinallyEx > -1) { + List preCatches = new ArrayList<>(); + for (GraphTargetItem s : localData.scopeStack) { + preCatches.addAll(toInsList(s.toSource(localData, this))); + if (s instanceof WithObjectAVM2Item) { + preCatches.add(ins(new PushWithIns())); + } else { + preCatches.add(ins(new PushScopeIns())); + } + } + preCatches.add(ins(new NewCatchIns(), aloneFinallyEx)); + preCatches.addAll(toInsList(AssignableAVM2Item.dupSetTemp(localData, this, tempReg))); + preCatches.add(ins(new PushScopeIns())); + preCatches.add(ins(new ThrowIns())); + preCatches.add(ins(new PopScopeIns())); + preCatches.addAll(toInsList(AssignableAVM2Item.killTemp(localData, this, Arrays.asList(tempReg)))); + catches.add(ins(new JumpIns(), insToBytes(preCatches).length)); + catches.add(new ExceptionMarkAVM2Instruction(aloneFinallyEx, MARK_E_TARGET)); + catches.addAll(preCatches); + } + AVM2Instruction finSwitch = null; + AVM2Instruction pushDefIns = ins(new PushByteIns(), 0); + + int defPos = 0; + if (finallyEx > -1) { + List preCatches = new ArrayList<>(); + preCatches.add(0, new ExceptionMarkAVM2Instruction(finallyEx, MARK_E_TARGET)); + for (GraphTargetItem s : localData.scopeStack) { + preCatches.addAll(toInsList(s.toSource(localData, this))); + if (s instanceof WithObjectAVM2Item) { + preCatches.add(ins(new PushWithIns())); + } else { + preCatches.add(ins(new PushScopeIns())); + } + } + preCatches.add(ins(new NewCatchIns(), finallyEx)); + preCatches.addAll(toInsList(AssignableAVM2Item.dupSetTemp(localData, this, tempReg))); + preCatches.add(ins(new PushScopeIns())); + preCatches.add(ins(new PopScopeIns())); + Reference tempReg2 = new Reference<>(0); + preCatches.add(ins(new KillIns(), tempReg.getVal())); + preCatches.add(ins(new CoerceAIns())); + preCatches.addAll(toInsList(AssignableAVM2Item.setTemp(localData, this, tempReg2))); + preCatches.add(pushDefIns); + + List finallySwitchCmds = new ArrayList<>(); + + finSwitch = new AVM2Instruction(0, new LookupSwitchIns(), new int[1 + 1 + 1]); + finSwitch.operands[0] = finSwitch.getBytes().length; + finSwitch.operands[1] = 0; //switch cnt + + List preFinallySwitch = new ArrayList<>(); + preFinallySwitch.add(ins(new LabelIns())); + preFinallySwitch.add(ins(new PopIns())); + int preFinallySwitchLen = insToBytes(preFinallySwitch).length; + + finallySwitchCmds.add(ins(new LabelIns())); + finallySwitchCmds.addAll(toInsList(AssignableAVM2Item.getTemp(localData, this, tempReg2))); + finallySwitchCmds.add(ins(new KillIns(), tempReg2.getVal())); + finallySwitchCmds.add(ins(new ThrowIns())); + finallySwitchCmds.add(ins(new PushByteIns(), 255)); + finallySwitchCmds.add(ins(new PopScopeIns())); + finallySwitchCmds.add(ins(new KillIns(), tempReg.getVal())); + + int finSwitchLen = insToBytes(finallySwitchCmds).length; + + preCatches.add(ins(new JumpIns(), preFinallySwitchLen + finSwitchLen)); + AVM2Instruction fjump = ins(new JumpIns(), 0); + fjump.operands[0] = insToBytes(preCatches).length + preFinallySwitchLen + finSwitchLen; + + preCatches.add(0, fjump); + preCatches.add(0, new ExceptionMarkAVM2Instruction(finallyEx, MARK_E_END)); + preCatches.add(0, ins(new PushByteIns(), 255)); + + finallySwitchCmds.add(new ExceptionMarkAVM2Instruction(finallyEx, MARK_E_FINALLYPART)); + + int oldReg = localData.finallyRegister; + localData.finallyRegister = getFreeRegister(localData); + Integer cnt = localData.finallyCounter.get(finId); + if (cnt == null) { + cnt = -1; + } + defPos = cnt; + cnt++; //Skip default clause (throw) + localData.finallyCounter.put(finId, cnt); + finallySwitchCmds.addAll(generateToInsList(localData, item.finallyCommands)); + killRegister(localData, localData.finallyRegister); + localData.finallyRegister = oldReg; + finSwitchLen = insToBytes(finallySwitchCmds).length; + + finSwitch.operands[2] = -finSwitchLen; + preCatches.addAll(preFinallySwitch); + preCatches.addAll(finallySwitchCmds); + preCatches.add(finSwitch); + + catches.addAll(preCatches); + AssignableAVM2Item.killTemp(localData, this, Arrays.asList(tempReg, tempReg2)); + } + + ret.addAll(catches); + //localData.exceptions.addAll(newex); + + if (finallyEx > -1) { + localData.finallyCatches.remove(localData.finallyCatches.size() - 1); + } + if (newFinallyReg) { + localData.finallyRegister = -1; + killRegister(localData, localData.finallyRegister); + } + int pos = 0; + int finallyPos = 0; + int switchPos = 0; + for (int s = 0; s < ret.size(); s++) { + GraphSourceItem src = ret.get(s); + if (src == finSwitch) { + switchPos = pos; + } + if (src instanceof AVM2Instruction) { + AVM2Instruction ins = (AVM2Instruction) src; + if (ins instanceof ExceptionMarkAVM2Instruction) { + ExceptionMarkAVM2Instruction em = (ExceptionMarkAVM2Instruction) ins; + if (em.exceptionId == finallyEx && em.markType == MARK_E_FINALLYPART) { + finallyPos = pos; + ret.remove(s); + s--; + continue; + } + } + pos += ins.getBytes().length; + } + + } + + if (finSwitch != null) { + pos = 0; + int defLoc = finSwitch.operands[2]; + List switchLoc = new ArrayList<>(); + boolean wasDef = false; + for (int s = 0; s < ret.size(); s++) { + GraphSourceItem src = ret.get(s); + if (src instanceof AVM2Instruction) { + AVM2Instruction ins = (AVM2Instruction) src; + if (ins.definition instanceof FinallyJumpIns) { + FinallyJumpIns fji = (FinallyJumpIns) ins.definition; + if (fji.getClauseId() == finId) { + List bet = new ArrayList<>(); + bet.add(ins(new LabelIns())); + bet.add(ins(new PopIns())); + int betLen = insToBytes(bet).length; + if (wasDef) { + ins.operands[0] = 0; + } else { + ins.operands[0] = finallyPos - (pos + ins.getBytes().length); + } + ins.definition = new JumpIns(); + switchLoc.add(pos + ins.getBytes().length + betLen - switchPos); + } + } + pos += ins.getBytes().length; + } + if (defPos == switchLoc.size() - 1) { + switchLoc.add(defLoc); + wasDef = true; + } + } + finSwitch.operands = new int[1 + 1 + switchLoc.size()]; + pushDefIns.operands[0] = defPos + 1; + int afterLoc = finSwitch.getBytes().length; + finSwitch.operands[0] = afterLoc; + finSwitch.operands[1] = switchLoc.size() - 1; + for (int j = 0; j < switchLoc.size(); j++) { + finSwitch.operands[2 + j] = switchLoc.get(j); + } + } + + return ret; + } + + @Override + public List generate(SourceGeneratorLocalData localData, ContinueItem item) { + List ret = new ArrayList<>(); + AVM2Instruction acontinue = ins(new ContinueJumpIns(item.loopId), 0); + ret.add(acontinue); + return ret; + } + + public List generate(SourceGeneratorLocalData localData, ReturnValueAVM2Item item) throws CompilationException { + List ret = new ArrayList<>(); + ret.addAll(item.value.toSource(localData, this)); + if (!localData.finallyCatches.isEmpty()) { + ret.add(ins(new CoerceAIns())); + ret.add(AssignableAVM2Item.generateSetLoc(localData.finallyRegister)); + for (int i = localData.finallyCatches.size() - 1; i >= 0; i--) { + if (i < localData.finallyCatches.size() - 1) { + ret.add(ins(new LabelIns())); + } + int clauseId = localData.finallyCatches.get(i); + Integer cnt = localData.finallyCounter.get(clauseId); + if (cnt == null) { + cnt = -1; + } + cnt++; + localData.finallyCounter.put(clauseId, cnt); + ret.addAll(new IntegerValueAVM2Item(null, (long) cnt).toSource(localData, this)); + ret.add(ins(new FinallyJumpIns(clauseId), 0)); + ret.add(ins(new LabelIns())); + ret.add(ins(new PopIns())); + } + ret.add(ins(new LabelIns())); + ret.add(AssignableAVM2Item.generateGetLoc(localData.finallyRegister)); + ret.add(ins(new KillIns(), localData.finallyRegister)); + } + ret.add(ins(new ReturnValueIns())); + return ret; + } + + public List generate(SourceGeneratorLocalData localData, ReturnVoidAVM2Item item) throws CompilationException { + List ret = new ArrayList<>(); + if (!localData.finallyCatches.isEmpty()) { + + for (int i = 0; i < localData.finallyCatches.size(); i++) { + if (i > 0) { + ret.add(ins(new LabelIns())); + } + int clauseId = localData.finallyCatches.get(i); + Integer cnt = localData.finallyCounter.get(clauseId); + if (cnt == null) { + cnt = -1; + } + cnt++; + localData.finallyCounter.put(clauseId, cnt); + ret.addAll(new IntegerValueAVM2Item(null, (long) cnt).toSource(localData, this)); + ret.add(ins(new FinallyJumpIns(clauseId), 0)); + ret.add(ins(new LabelIns())); + ret.add(ins(new PopIns())); + } + ret.add(ins(new LabelIns())); + } + ret.add(ins(new ReturnVoidIns())); + return ret; + } + + public List generate(SourceGeneratorLocalData localData, ThrowAVM2Item item) throws CompilationException { + List ret = new ArrayList<>(); + ret.addAll(item.value.toSource(localData, this)); + ret.add(ins(new ThrowIns())); + return ret; + } + + private List generateToInsList(SourceGeneratorLocalData localData, List commands) throws CompilationException { + return toInsList(generate(localData, commands)); + } + + private List generateToActionList(SourceGeneratorLocalData localData, GraphTargetItem command) throws CompilationException { + return toInsList(command.toSource(localData, this)); + } + + @Override + public List generate(SourceGeneratorLocalData localData, List commands) throws CompilationException { + List ret = new ArrayList<>(); + for (GraphTargetItem item : commands) { + ret.addAll(item.toSourceIgnoreReturnValue(localData, this)); + } + return ret; + } + + public HashMap getRegisterVars(SourceGeneratorLocalData localData) { + return localData.registerVars; + } + + public void setRegisterVars(SourceGeneratorLocalData localData, HashMap value) { + localData.registerVars = value; + } + + public void setInFunction(SourceGeneratorLocalData localData, int value) { + localData.inFunction = value; + } + + public int isInFunction(SourceGeneratorLocalData localData) { + return localData.inFunction; + } + + public boolean isInMethod(SourceGeneratorLocalData localData) { + return localData.inMethod; + } + + public void setInMethod(SourceGeneratorLocalData localData, boolean value) { + localData.inMethod = value; + } + + public int getForInLevel(SourceGeneratorLocalData localData) { + return localData.forInLevel; + } + + public void setForInLevel(SourceGeneratorLocalData localData, int value) { + localData.forInLevel = value; + } + + public int getTempRegister(SourceGeneratorLocalData localData) { + HashMap registerVars = getRegisterVars(localData); + int tmpReg = 0; + for (int i = 0; i < 256; i++) { + if (!registerVars.containsValue(i)) { + tmpReg = i; + break; + } + } + return tmpReg; + } + + public AVM2SourceGenerator(ABC abc, List allABCs) { + this.abc = abc; + this.allABCs = allABCs; + } + + public ABC getABC() { + return abc; + } + + public void generateClass(List importedClasses, List sinitVariables, boolean staticNeedsActivation, List staticInit, List openedNamespaces, int namespace, int initScope, String pkg, ClassInfo classInfo, InstanceInfo instanceInfo, SourceGeneratorLocalData localData, boolean isInterface, String name, String superName, GraphTargetItem extendsVal, List implementsStr, GraphTargetItem constructor, List traitItems, Reference class_index) throws AVM2ParseException, CompilationException { + localData.currentClass = name; + localData.pkg = pkg; + List ret = new ArrayList<>(); + if (extendsVal == null && !isInterface) { + extendsVal = new TypeItem("Object"); + } + ParsedSymbol s = null; + + instanceInfo.name_index = traitName(namespace, name); + + Trait[] it = generateTraitsPhase1(name, superName, false, localData, traitItems, instanceInfo.instance_traits, class_index); + Trait[] st = generateTraitsPhase1(name, superName, true, localData, traitItems, classInfo.static_traits, class_index); + generateTraitsPhase2(importedClasses, pkg, traitItems, it, openedNamespaces, localData); + generateTraitsPhase2(importedClasses, pkg, traitItems, st, openedNamespaces, localData); + generateTraitsPhase3(initScope, isInterface, name, superName, false, localData, traitItems, instanceInfo.instance_traits, it, new HashMap(), class_index); + generateTraitsPhase3(initScope, isInterface, name, superName, true, localData, traitItems, classInfo.static_traits, st, new HashMap(), class_index); + int init = 0; + if (constructor == null || isInterface) { + instanceInfo.iinit_index = init = method(false, isInterface, new ArrayList(), pkg, false, new ArrayList(), initScope + 1, false, 0, isInterface ? null : name, extendsVal != null ? extendsVal.toString() : null, true, localData, new ArrayList(), new ArrayList(), new ArrayList(), new ArrayList(), TypeItem.UNBOUNDED/*?? FIXME*/); + } else { + MethodAVM2Item m = (MethodAVM2Item) constructor; + instanceInfo.iinit_index = init = method(false, false, new ArrayList(), pkg, m.needsActivation, m.subvariables, initScope + 1, m.hasRest, m.line, name, extendsVal != null ? extendsVal.toString() : null, true, localData, m.paramTypes, m.paramNames, m.paramValues, m.body, TypeItem.UNBOUNDED/*?? FIXME*/); + } + + //Class initializer + int staticMi = method(false, false, new ArrayList(), pkg, staticNeedsActivation, sinitVariables, initScope + (implementsStr.isEmpty() ? 0 : 1), false, 0, isInterface ? null : name, superName, false, localData, new ArrayList(), new ArrayList(), new ArrayList(), staticInit, TypeItem.UNBOUNDED); + MethodBody sinitBody = abc.findBody(staticMi); + + List sinitcode = new ArrayList<>(); + List initcode = new ArrayList<>(); + for (GraphTargetItem ti : traitItems) { + if ((ti instanceof SlotAVM2Item) || (ti instanceof ConstAVM2Item)) { + GraphTargetItem val = null; + boolean isStatic = false; + int ns = -1; + String tname = null; + boolean isConst = false; + if (ti instanceof SlotAVM2Item) { + val = ((SlotAVM2Item) ti).value; + isStatic = ((SlotAVM2Item) ti).isStatic(); + ns = ((SlotAVM2Item) ti).getNamespace(); + tname = ((SlotAVM2Item) ti).var; + } + if (ti instanceof ConstAVM2Item) { + val = ((ConstAVM2Item) ti).value; + isStatic = ((ConstAVM2Item) ti).isStatic(); + ns = ((ConstAVM2Item) ti).getNamespace(); + tname = ((ConstAVM2Item) ti).var; + isConst = true; + } + if (isStatic && val != null) { + sinitcode.add(ins(new FindPropertyIns(), traitName(ns, tname))); + sinitcode.addAll(toInsList(val.toSource(localData, this))); + sinitcode.add(ins(isConst ? new InitPropertyIns() : new SetPropertyIns(), traitName(ns, tname))); + } + if (!isStatic && val != null) { + //do not init basic values, that can be stored in trait + if (!(val instanceof IntegerValueAVM2Item) && !(val instanceof StringAVM2Item) && !(val instanceof BooleanAVM2Item) && !(val instanceof NullAVM2Item) && !(val instanceof UndefinedAVM2Item)) { + initcode.add(ins(new GetLocal0Ins())); + initcode.addAll(toInsList(val.toSource(localData, this))); + initcode.add(ins(isConst ? new InitPropertyIns() : new SetPropertyIns(), traitName(ns, tname))); + } + } + } + } + MethodBody initBody = null; + if (!isInterface) { + initBody = abc.findBody(init); + initBody.getCode().code.addAll(constructor == null ? 0 : 2, initcode);//after getlocal0,pushscope + + if (sinitBody.getCode().code.get(sinitBody.getCode().code.size() - 1).definition instanceof ReturnVoidIns) { + sinitBody.getCode().code.addAll(2, sinitcode); //after getlocal0,pushscope + } + } + sinitBody.markOffsets(); + sinitBody.autoFillStats(abc, initScope + (implementsStr.isEmpty() ? 0 : 1), true); + + classInfo.cinit_index = staticMi; + if (!isInterface) { + initBody.autoFillStats(abc, initScope + 1, true); + } + instanceInfo.interfaces = new int[implementsStr.size()]; + for (int i = 0; i < implementsStr.size(); i++) { + instanceInfo.interfaces[i] = superIntName(localData, implementsStr.get(i)); + } + } + + @Override + public List generate(SourceGeneratorLocalData localData, CommaExpressionItem item) throws CompilationException { + if (item.commands.isEmpty()) { + return new ArrayList<>(); + } + + //We need to handle commands and last expression separately, otherwise last expression result will be popped + List cmds = new ArrayList<>(item.commands); + GraphTargetItem lastExpr = cmds.remove(cmds.size() - 1); + List ret = new ArrayList<>(); + ret.addAll(generate(localData, cmds)); + ret.addAll(lastExpr.toSource(localData, this)); + return ret; + } + + public int generateClass(int namespace, ClassInfo ci, InstanceInfo ii, int initScope, String pkg, SourceGeneratorLocalData localData, AVM2Item cls, Reference class_index) throws AVM2ParseException, CompilationException { + /*ClassInfo ci = new ClassInfo(); + InstanceInfo ii = new InstanceInfo(); + abc.class_info.add(ci); + abc.instance_info.add(ii); + */ + if (cls instanceof ClassAVM2Item) { + ClassAVM2Item cai = (ClassAVM2Item) cls; + generateClass(cai.importedClasses, cai.sinitVariables, cai.staticInitActivation, cai.staticInit, cai.openedNamespaces, namespace, initScope, pkg, ci, ii, localData, false, cai.className, cai.extendsOp == null ? "Object" : cai.extendsOp.toString(), cai.extendsOp, cai.implementsOp, cai.constructor, cai.traits, class_index); + if (!cai.isDynamic) { + ii.flags |= InstanceInfo.CLASS_SEALED; + } + if (cai.isFinal) { + ii.flags |= InstanceInfo.CLASS_FINAL; + } + ii.flags |= InstanceInfo.CLASS_PROTECTEDNS; + ii.protectedNS = cai.protectedNs; + } + if (cls instanceof InterfaceAVM2Item) { + InterfaceAVM2Item iai = (InterfaceAVM2Item) cls; + ii.flags |= InstanceInfo.CLASS_INTERFACE; + ii.flags |= InstanceInfo.CLASS_SEALED; + generateClass(iai.importedClasses, new ArrayList(), false, new ArrayList(), iai.openedNamespaces, namespace, initScope, pkg, ci, ii, localData, true, iai.name, null, null, iai.superInterfaces, null, iai.methods, class_index); + } + + return abc.instance_info.size() - 1; + } + + public int traitName(int namespace, String var) { + return abc.constants.getMultinameId(new Multiname(Multiname.QNAME, str(var), namespace, 0, 0, new ArrayList()), true); + } + + public int typeName(SourceGeneratorLocalData localData, GraphTargetItem type) throws CompilationException { + if (type instanceof UnboundedTypeItem) { + return 0; + } + if (("" + type).equals("*")) { + return 0; + } + + return resolveType(localData, type, abc, allABCs); + /* + TypeItem nameItem = (TypeItem) type; + name = nameItem.fullTypeName; + if (name.contains(".")) { + pkg = name.substring(0, name.lastIndexOf('.')); + name = name.substring(name.lastIndexOf('.') + 1); + } + if (!nameItem.subtypes.isEmpty()) { //It's vector => TypeName + List params = new ArrayList<>(); + for (GraphTargetItem p : nameItem.subtypes) { + params.add(typeName(localData, p));//abc.constants.getMultinameId(new Multiname(Multiname.QNAME, str(p), namespace(Namespace.KIND_PACKAGE, ppkg), 0, 0, new ArrayList()), true)); + } + int qname = abc.constants.getMultinameId(new Multiname(Multiname.QNAME, str(name), namespace(Namespace.KIND_PACKAGE, pkg), 0, 0, new ArrayList()), true); + return abc.constants.getMultinameId(new Multiname(Multiname.TYPENAME, 0, 0, 0, qname, params), true); + } else { + return abc.constants.getMultinameId(new Multiname(Multiname.QNAME, str(name), namespace(Namespace.KIND_PACKAGE, pkg), 0, 0, new ArrayList()), true); + }*/ + } + + public int ident(GraphTargetItem name) { + if (name instanceof NameAVM2Item) { + return str(((NameAVM2Item) name).getVariableName()); + } + throw new RuntimeException("no ident"); //FIXME + } + + public int namespace(int nsKind, String name) { + return abc.constants.getNamespaceId(new Namespace(nsKind, str(name)), 0, true); + } + + public int str(String name) { + return abc.constants.getStringId(name, true); + } + + public int propertyName(GraphTargetItem name) { + if (name instanceof NameAVM2Item) { + NameAVM2Item va = (NameAVM2Item) name; + return abc.constants.getMultinameId(new Multiname(Multiname.QNAME, str(va.getVariableName()), namespace(Namespace.KIND_PACKAGE, ""), 0, 0, new ArrayList()), true); + } + throw new RuntimeException("no prop"); //FIXME + } + + public int getFreeRegister(SourceGeneratorLocalData localData) { + for (int i = 0;; i++) { + if (!localData.registerVars.containsValue(i)) { + localData.registerVars.put("__TEMP__" + i, i); + return i; + } + } + } + + public boolean killRegister(SourceGeneratorLocalData localData, int i) { + String key = null; + for (String k : localData.registerVars.keySet()) { + if (localData.registerVars.get(k) == i) { + key = k; + break; + } + } + if (key != null) { + localData.registerVars.remove(key); + return true; + } + return false; + } + + public int method(boolean subMethod, boolean isInterface, List callStack, String pkg, boolean needsActivation, List subvariables, int initScope, boolean hasRest, int line, String className, String superType, boolean constructor, SourceGeneratorLocalData localData, List paramTypes, List paramNames, List paramValues, List body, GraphTargetItem retType) throws CompilationException { + //Reference hasArgs = new Reference<>(Boolean.FALSE); + //calcRegisters(localData,needsActivation,paramNames,subvariables,body, hasArgs); + SourceGeneratorLocalData newlocalData = new SourceGeneratorLocalData(new HashMap(), 1, true, 0); + newlocalData.currentClass = className; + newlocalData.pkg = localData.pkg; + newlocalData.callStack.addAll(localData.callStack); + newlocalData.traitUsages = localData.traitUsages; + newlocalData.currentScript = localData.currentScript; + newlocalData.documentClass = localData.documentClass; + newlocalData.subMethod = subMethod; + localData = newlocalData; + + localData.activationReg = 0; + + for (int i = 0; i < subvariables.size(); i++) { + AssignableAVM2Item an = subvariables.get(i); + if (an instanceof UnresolvedAVM2Item) { + UnresolvedAVM2Item n = (UnresolvedAVM2Item) an; + if (n.resolved == null) { + String fullClass = localData.getFullClass(); + GraphTargetItem res = n.resolve(new TypeItem(fullClass), paramTypes, paramNames, abc, allABCs, callStack, subvariables); + if (res instanceof AssignableAVM2Item) { + subvariables.set(i, (AssignableAVM2Item) res); + } else { + subvariables.remove(i); + i--; + } + } + } + } + + for (int t = 0; t < paramTypes.size(); t++) { + GraphTargetItem an = paramTypes.get(t); + if (an instanceof UnresolvedAVM2Item) { + UnresolvedAVM2Item n = (UnresolvedAVM2Item) an; + if (n.resolved == null) { + String fullClass = localData.getFullClass(); + GraphTargetItem res = n.resolve(new TypeItem(fullClass), paramTypes, paramNames, abc, allABCs, callStack, subvariables); + paramTypes.set(t, res); + } + } + } + + boolean hasArguments = false; + List slotNames = new ArrayList<>(); + List slotTypes = new ArrayList<>(); + slotNames.add("--first"); + slotTypes.add("-"); + + List registerNames = new ArrayList<>(); + List registerTypes = new ArrayList<>(); + if (className != null) { + String fullClassName = pkg == null || pkg.isEmpty() ? className : pkg + "." + className; + registerTypes.add(fullClassName); + localData.scopeStack.add(new LocalRegAVM2Item(null, registerNames.size(), null)); + registerNames.add("this"); + + } else { + registerTypes.add("global"); + registerNames.add("this"); + } + for (GraphTargetItem t : paramTypes) { + registerTypes.add(t.toString()); + slotTypes.add(t.toString()); + } + registerNames.addAll(paramNames); + slotNames.addAll(paramNames); + /*for (GraphTargetItem p : paramTypes) { + slotTypes.add("" + p); + }*/ + if (hasRest) { + slotTypes.add("*"); + } + localData.registerVars.clear(); + for (AssignableAVM2Item an : subvariables) { + if (an instanceof NameAVM2Item) { + NameAVM2Item n = (NameAVM2Item) an; + if (n.getVariableName().equals("arguments") & !n.isDefinition()) { + registerNames.add("arguments"); + registerTypes.add("Object"); + hasArguments = true; + break; + } + } + } + int paramRegCount = registerNames.size(); + + if (needsActivation) { + registerNames.add("+$activation"); + localData.activationReg = registerNames.size() - 1; + registerTypes.add("Object"); + localData.scopeStack.add(new LocalRegAVM2Item(null, localData.activationReg, null)); + } + + String mask = Configuration.registerNameFormat.get(); + mask = mask.replace("%d", "([0-9]+)"); + Pattern pat = Pattern.compile(mask); + + //Two rounds + for (int round = 1; round <= 2; round++) { + for (AssignableAVM2Item an : subvariables) { + if (an instanceof NameAVM2Item) { + NameAVM2Item n = (NameAVM2Item) an; + if (n.isDefinition()) { + if (!needsActivation || (n.getSlotScope() <= 0)) { + String varName = n.getVariableName(); + Matcher m = pat.matcher(varName); + //In first round, make all register that match standard loc_xx register + if ((round == 1) && (m.matches())) { + String regIndexStr = m.group(1); + int regIndex = Integer.parseInt(regIndexStr); + while (registerNames.size() <= regIndex + 1) { + String standardName = String.format(mask, registerNames.size() - 1); + registerNames.add(standardName); + registerTypes.add("*"); + slotNames.add(standardName); + slotTypes.add("*"); + } + registerNames.set(regIndex, varName); + registerTypes.set(regIndex, varName); + slotNames.set(regIndex, varName); + slotTypes.set(regIndex, varName); + } //in second round the rest + else if (round == 2 && !m.matches()) { + registerNames.add(n.getVariableName()); + registerTypes.add(n.type.toString()); + slotNames.add(n.getVariableName()); + slotTypes.add(n.type.toString()); + } + } + } + } + } + } + + int slotScope = subMethod ? 0 : 1; + + for (AssignableAVM2Item an : subvariables) { + if (an instanceof NameAVM2Item) { + NameAVM2Item n = (NameAVM2Item) an; + String variableName = n.getVariableName(); + if (variableName != null) { + boolean isThisOrSuper = variableName.equals("this") || variableName.equals("super"); + if (!isThisOrSuper && needsActivation) { + if (n.getSlotNumber() <= 0) { + n.setSlotNumber(slotNames.indexOf(variableName)); + n.setSlotScope(slotScope); + } + } else { + if (isThisOrSuper) { + n.setRegNumber(0); + } else { + n.setRegNumber(registerNames.indexOf(variableName)); + } + } + } + } + } + + for (int i = 0; i < registerNames.size(); i++) { + if (needsActivation && i > localData.activationReg) { + break; + } + localData.registerVars.put(registerNames.get(i), i); + } + List declarations = new ArrayList<>(); + loopn: + for (AssignableAVM2Item an : subvariables) { + if (an instanceof NameAVM2Item) { + NameAVM2Item n = (NameAVM2Item) an; + + if (needsActivation) { + if (n.getSlotScope() != slotScope) { + continue; + } else { + if (n.getSlotNumber() < paramRegCount) { + continue; + } + } + } + for (NameAVM2Item d : declarations) { + if (n.getVariableName() != null && n.getVariableName().equals(d.getVariableName())) { + continue loopn; + } + } + + for (GraphTargetItem it : body) { //search first level of commands + if (it instanceof NameAVM2Item) { + NameAVM2Item n2 = (NameAVM2Item) it; + if (n2.isDefinition() && n2.getAssignedValue() != null && n2.getVariableName().equals(n.getVariableName())) { + continue loopn; + } + if (!n2.isDefinition() && n2.getVariableName() != null && n2.getVariableName().equals(n.getVariableName())) { //used earlier than defined + break; + } + } + } + if (n.unresolved) { + continue; + } + if (n.redirect != null) { + continue; + } + if (n.getNs() != null) { + continue; + } + + String variableName = n.getVariableName(); + if ("this".equals(variableName) || "super".equals(variableName) || paramNames.contains(variableName) || "arguments".equals(variableName)) { + continue; + } + + NameAVM2Item d = new NameAVM2Item(n.type, n.line, n.getVariableName(), NameAVM2Item.getDefaultValue("" + n.type), true, n.openedNamespaces); + //no index + if (needsActivation) { + if (d.getSlotNumber() <= 0) { + d.setSlotNumber(n.getSlotNumber()); + d.setSlotScope(n.getSlotScope()); + } + } else { + d.setRegNumber(n.getRegNumber()); + } + declarations.add(d); + } + } + + int[] param_types = new int[paramTypes.size()]; + ValueKind[] optional = new ValueKind[paramValues.size()]; + //int[] param_names = new int[paramNames.size()]; + for (int i = 0; i < paramTypes.size(); i++) { + param_types[i] = typeName(localData, paramTypes.get(i)); + //param_names[i] = str(paramNames.get(i)); + } + + for (int i = 0; i < paramValues.size(); i++) { + optional[i] = getValueKind(Namespace.KIND_NAMESPACE/*FIXME*/, paramTypes.get(paramTypes.size() - paramValues.size() + i), paramValues.get(i)); + if (optional[i] == null) { + throw new CompilationException("Default value must be compiletime constant", line); + } + } + + MethodInfo mi = new MethodInfo(param_types, constructor ? 0 : typeName(localData, retType), 0/*name_index*/, 0, optional, new int[0]/*no param_names*/); + if (hasArguments) { + mi.setFlagNeed_Arguments(); + } + //No param names like in official + /* + if (!paramNames.isEmpty()) { + mi.setFlagHas_paramnames(); + }*/ + if (!paramValues.isEmpty()) { + mi.setFlagHas_optional(); + } + if (hasRest) { + mi.setFlagNeed_rest(); + } + + int mindex; + if (!isInterface) { + MethodBody mbody = new MethodBody(); + + if (needsActivation) { + int slotId = 1; + for (int i = 1; i < slotNames.size(); i++) { + TraitSlotConst tsc = new TraitSlotConst(); + tsc.slot_id = slotId++; + tsc.name_index = abc.constants.getMultinameId(new Multiname(Multiname.QNAME, abc.constants.getStringId(slotNames.get(i), true), abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE_INTERNAL, abc.constants.getStringId(pkg, true)), 0, true), 0, 0, new ArrayList()), true); + tsc.type_index = typeName(localData, new TypeItem(slotTypes.get(i))); + mbody.traits.traits.add(tsc); + } + for (int i = 1; i < paramRegCount; i++) { + NameAVM2Item param = new NameAVM2Item(new TypeItem(registerTypes.get(i)), 0, registerNames.get(i), null, false, new ArrayList()); + param.setRegNumber(i); + NameAVM2Item d = new NameAVM2Item(new TypeItem(registerTypes.get(i)), 0, registerNames.get(i), param, true, new ArrayList()); + d.setSlotScope(slotScope); + d.setSlotNumber(slotNames.indexOf(registerNames.get(i))); + declarations.add(d); + } + } + if (body != null) { + body.addAll(0, declarations); + } + + localData.exceptions = new ArrayList<>(); + localData.callStack.add(mbody); + List src = body == null ? new ArrayList() : generate(localData, body); + + mbody.method_info = abc.addMethodInfo(mi); + mi.setBody(mbody); + List mbodyCode = toInsList(src); + mbody.setCode(new AVM2Code()); + mbody.getCode().code = mbodyCode; + + if (needsActivation) { + if (localData.traitUsages.containsKey(mbody)) { + List usages = localData.traitUsages.get(mbody); + for (int i = 0; i < mbody.traits.traits.size(); i++) { + if (usages.contains(i)) { + TraitSlotConst tsc = (TraitSlotConst) mbody.traits.traits.get(i); + GraphTargetItem type = TypeItem.UNBOUNDED; + if (tsc.type_index > 0) { + type = new TypeItem(abc.constants.constant_multiname.get(tsc.type_index).getNameWithNamespace(abc.constants, true)); + } + NameAVM2Item d = new NameAVM2Item(type, 0, tsc.getName(abc).getName(abc.constants, new ArrayList(), true), NameAVM2Item.getDefaultValue("" + type), true, new ArrayList()); + d.setSlotNumber(tsc.slot_id); + d.setSlotScope(slotScope); + mbodyCode.addAll(0, toInsList(d.toSourceIgnoreReturnValue(localData, this))); + } + } + } + + List acts = new ArrayList<>(); + acts.add(ins(new NewActivationIns())); + acts.add(ins(new DupIns())); + acts.add(AssignableAVM2Item.generateSetLoc(localData.activationReg)); + acts.add(ins(new PushScopeIns())); + + mbodyCode.addAll(0, acts); + } + + if (constructor) { + List abcs = new ArrayList<>(); + abcs.add(abc); + abcs.addAll(allABCs); + + int parentConstMinAC = 0; + + for (ABC a : abcs) { + int ci = a.findClassByName(superType); + if (ci > -1) { + MethodInfo pmi = a.method_info.get(a.instance_info.get(ci).iinit_index); + parentConstMinAC = pmi.param_types.length; + if (pmi.flagHas_optional()) { + parentConstMinAC -= pmi.optional.length; + } + + } + } + int ac = -1; + for (AVM2Instruction ins : mbodyCode) { + if (ins.definition instanceof ConstructSuperIns) { + ac = ins.operands[0]; + if (parentConstMinAC > ac) { + throw new CompilationException("Parent constructor call requires different number of arguments", line); + } + + } + } + if (ac == -1) { + if (parentConstMinAC == 0) { + mbodyCode.add(0, new AVM2Instruction(0, new GetLocal0Ins(), null)); + mbodyCode.add(1, new AVM2Instruction(0, new ConstructSuperIns(), new int[]{0})); + + } else { + throw new CompilationException("Parent constructor must be called", line); + } + } + } + if (className != null && !subMethod) { + mbodyCode.add(0, new AVM2Instruction(0, new GetLocal0Ins(), null)); + mbodyCode.add(1, new AVM2Instruction(0, new PushScopeIns(), null)); + } + boolean addRet = false; + if (!mbodyCode.isEmpty()) { + InstructionDefinition lastDef = mbodyCode.get(mbodyCode.size() - 1).definition; + if (!((lastDef instanceof ReturnVoidIns) || (lastDef instanceof ReturnValueIns))) { + addRet = true; + } + } else { + addRet = true; + } + if (addRet) { + if (retType.toString().equals("*") || retType.toString().equals("void") || constructor) { + mbodyCode.add(new AVM2Instruction(0, new ReturnVoidIns(), null)); + } else { + mbodyCode.add(new AVM2Instruction(0, new PushUndefinedIns(), null)); + mbodyCode.add(new AVM2Instruction(0, new ReturnValueIns(), null)); + } + } + mbody.exceptions = localData.exceptions.toArray(new ABCException[localData.exceptions.size()]); + int offset = 0; + for (int i = 0; i < mbodyCode.size(); i++) { + AVM2Instruction ins = mbodyCode.get(i); + if (ins instanceof ExceptionMarkAVM2Instruction) { + ExceptionMarkAVM2Instruction m = (ExceptionMarkAVM2Instruction) ins; + switch (m.markType) { + case MARK_E_START: + mbody.exceptions[m.exceptionId].start = offset; + break; + case MARK_E_END: + mbody.exceptions[m.exceptionId].end = offset; + break; + case MARK_E_TARGET: + mbody.exceptions[m.exceptionId].target = offset; + break; + } + mbodyCode.remove(i); + i--; + continue; + } + offset += ins.getBytes().length; + } + + mbody.markOffsets(); + mbody.autoFillStats(abc, initScope, className != null); + abc.addMethodBody(mbody); + mindex = mbody.method_info; + } else { + mindex = abc.addMethodInfo(mi); + } + + return mindex; + } + + public ValueKind getValueKind(int ns, GraphTargetItem type, GraphTargetItem val) { + + if (val instanceof BooleanAVM2Item) { + BooleanAVM2Item bi = (BooleanAVM2Item) val; + if (bi.value) { + return new ValueKind(0, ValueKind.CONSTANT_True); + } else { + return new ValueKind(0, ValueKind.CONSTANT_False); + } + } + + boolean isNs = false; + if (type instanceof NameAVM2Item) { + if (((NameAVM2Item) type).getVariableName().equals("namespace")) { + isNs = true; + } + } + + if ((type instanceof TypeItem) && (((TypeItem) type).fullTypeName.equals("Namespace"))) { + isNs = true; + } + + if (val instanceof StringAVM2Item) { + StringAVM2Item sval = (StringAVM2Item) val; + if (isNs) { + return new ValueKind(namespace(Namespace.KIND_NAMESPACE, sval.value), ValueKind.CONSTANT_Namespace); + } else { + return new ValueKind(str(sval.value), ValueKind.CONSTANT_Utf8); + } + } + if (val instanceof IntegerValueAVM2Item) { + return new ValueKind(abc.constants.getIntId(((IntegerValueAVM2Item) val).value, true), ValueKind.CONSTANT_Int); + } + if (val instanceof FloatValueAVM2Item) { + return new ValueKind(abc.constants.getDoubleId(((FloatValueAVM2Item) val).value, true), ValueKind.CONSTANT_Double); + } + if (val instanceof NanAVM2Item) { + return new ValueKind(abc.constants.getDoubleId(Double.NaN, true), ValueKind.CONSTANT_Double); + } + if (val instanceof NullAVM2Item) { + return new ValueKind(0, ValueKind.CONSTANT_Null); + } + if (val instanceof UndefinedAVM2Item) { + return new ValueKind(0, ValueKind.CONSTANT_Undefined); + } + return null; + } + + private int genNs(List importedClasses, String pkg, String custom, int namespace, List openedNamespaces, SourceGeneratorLocalData localData, int line) throws CompilationException { + if (custom != null) { + PropertyAVM2Item prop = new PropertyAVM2Item(null, custom, abc, allABCs, openedNamespaces, new ArrayList()); + Reference value = new Reference<>(null); + prop.resolve(localData, new Reference(null), new Reference(null), new Reference<>(0), value); + boolean resolved = true; + if (value.getVal() == null) { + resolved = false; + } + if (!resolved) { + + String customPkg = ""; + String fullCustom = ""; + for (String imp : importedClasses) { + if (imp.endsWith("." + custom)) { + customPkg = imp.substring(0, imp.lastIndexOf('.')); + fullCustom = imp; + break; + } + } + + List aas = new ArrayList<>(); + aas.add(abc); + aas.addAll(allABCs); + for (ABC a : aas) { + for (ScriptInfo si : a.script_info) { + for (Trait t : si.traits.traits) { + Multiname m = t.getName(a); + if (fullCustom.equals(m.getNameWithNamespace(a.constants, true))) { + if (t instanceof TraitSlotConst) { + if (((TraitSlotConst) t).isNamespace()) { + Namespace ns = a.constants.getNamespace(((TraitSlotConst) t).value_index); + return abc.constants.getNamespaceId(new Namespace(ns.kind, abc.constants.getStringId(ns.getName(a.constants, true), true)), 0, true); + } + } + } + } + } + } + + throw new CompilationException("Namespace not defined", line); + } + namespace = value.getVal().value_index; + } + return namespace; + } + + public void generateTraitsPhase2(List importedClasses, String pkg, List items, Trait[] traits, List openedNamespaces, SourceGeneratorLocalData localData) throws CompilationException { + for (int k = 0; k < items.size(); k++) { + GraphTargetItem item = items.get(k); + if (traits[k] == null) { + continue; + } else if (item instanceof InterfaceAVM2Item) { + traits[k].name_index = traitName(((InterfaceAVM2Item) item).namespace, ((InterfaceAVM2Item) item).name); + } else if (item instanceof ClassAVM2Item) { + traits[k].name_index = traitName(((ClassAVM2Item) item).namespace, ((ClassAVM2Item) item).className); + } else if ((item instanceof MethodAVM2Item) || (item instanceof GetterAVM2Item) || (item instanceof SetterAVM2Item)) { + traits[k].name_index = traitName(genNs(importedClasses, pkg, ((MethodAVM2Item) item).customNamespace, ((MethodAVM2Item) item).namespace, openedNamespaces, localData, ((MethodAVM2Item) item).line), ((MethodAVM2Item) item).functionName); + } else if (item instanceof FunctionAVM2Item) { + traits[k].name_index = traitName(((FunctionAVM2Item) item).namespace, ((FunctionAVM2Item) item).functionName); + } else if (item instanceof ConstAVM2Item) { + traits[k].name_index = traitName(genNs(importedClasses, pkg, ((ConstAVM2Item) item).customNamespace, ((ConstAVM2Item) item).getNamespace(), openedNamespaces, localData, ((ConstAVM2Item) item).line), ((ConstAVM2Item) item).var); + } else if (item instanceof SlotAVM2Item) { + traits[k].name_index = traitName(genNs(importedClasses, pkg, ((SlotAVM2Item) item).customNamespace, ((SlotAVM2Item) item).getNamespace(), openedNamespaces, localData, ((SlotAVM2Item) item).line), ((SlotAVM2Item) item).var); + } + } + + for (int k = 0; k < items.size(); k++) { + GraphTargetItem item = items.get(k); + if (traits[k] == null) { + continue; + } + if (item instanceof ClassAVM2Item) { + InstanceInfo instanceInfo = abc.instance_info.get(((TraitClass) traits[k]).class_info); + instanceInfo.name_index = abc.constants.getMultinameId(new Multiname(Multiname.QNAME, abc.constants.getStringId(((ClassAVM2Item) item).className, true), + abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abc.constants.getStringId(pkg, true)), 0, true), 0, 0, new ArrayList()), true); + + if (((ClassAVM2Item) item).extendsOp != null) { + instanceInfo.super_index = typeName(localData, ((ClassAVM2Item) item).extendsOp); + } else { + instanceInfo.super_index = abc.constants.getMultinameId(new Multiname(Multiname.QNAME, str("Object"), namespace(Namespace.KIND_PACKAGE, ""), 0, 0, new ArrayList()), true); + } + instanceInfo.interfaces = new int[((ClassAVM2Item) item).implementsOp.size()]; + for (int i = 0; i < ((ClassAVM2Item) item).implementsOp.size(); i++) { + instanceInfo.interfaces[i] = superIntName(localData, ((ClassAVM2Item) item).implementsOp.get(i)); + } + } + if (item instanceof InterfaceAVM2Item) { + InstanceInfo instanceInfo = abc.instance_info.get(((TraitClass) traits[k]).class_info); + instanceInfo.name_index = abc.constants.getMultinameId(new Multiname(Multiname.QNAME, abc.constants.getStringId(((InterfaceAVM2Item) item).name, true), + abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abc.constants.getStringId(pkg, true)), 0, true), 0, 0, new ArrayList()), true); + + instanceInfo.interfaces = new int[((InterfaceAVM2Item) item).superInterfaces.size()]; + for (int i = 0; i < ((InterfaceAVM2Item) item).superInterfaces.size(); i++) { + GraphTargetItem un = ((InterfaceAVM2Item) item).superInterfaces.get(i); + instanceInfo.interfaces[i] = superIntName(localData, un); + } + } + } + } + + public int superIntName(SourceGeneratorLocalData localData, GraphTargetItem un) throws CompilationException { + if (un instanceof UnresolvedAVM2Item) { + ((UnresolvedAVM2Item) un).resolve(null, new ArrayList(), new ArrayList(), abc, allABCs, new ArrayList(), new ArrayList()); + un = ((UnresolvedAVM2Item) un).resolved; + } + if (!(un instanceof TypeItem)) { //not applyType + throw new CompilationException("Invalid type", 0); + } + TypeItem sup = (TypeItem) un; + int propId = resolveType(localData, sup, abc, allABCs); + int[] nss = new int[]{abc.constants.constant_multiname.get(propId).namespace_index}; + return abc.constants.getMultinameId(new Multiname(Multiname.MULTINAME, abc.constants.constant_multiname.get(propId).name_index, 0, abc.constants.getNamespaceSetId(new NamespaceSet(nss), true), 0, new ArrayList()), true); + + } + + public void generateTraitsPhase3(int methodInitScope, boolean isInterface, String className, String superName, boolean generateStatic, SourceGeneratorLocalData localData, List items, Traits ts, Trait[] traits, Map initScopes, Reference class_index) throws AVM2ParseException, CompilationException { + //Note: Names must be generated first before accesed in inner subs + for (int k = 0; k < items.size(); k++) { + GraphTargetItem item = items.get(k); + if (traits[k] == null) { + continue; + } + if (item instanceof InterfaceAVM2Item) { + generateClass(((InterfaceAVM2Item) item).namespace, abc.class_info.get(((TraitClass) traits[k]).class_info), abc.instance_info.get(((TraitClass) traits[k]).class_info), initScopes.get(traits[k]), ((InterfaceAVM2Item) item).pkg, localData, (InterfaceAVM2Item) item, class_index); + } + + if (item instanceof ClassAVM2Item) { + generateClass(((ClassAVM2Item) item).namespace, abc.class_info.get(((TraitClass) traits[k]).class_info), abc.instance_info.get(((TraitClass) traits[k]).class_info), initScopes.get(traits[k]), ((ClassAVM2Item) item).pkg, localData, (ClassAVM2Item) item, class_index); + } + if ((item instanceof MethodAVM2Item) || (item instanceof GetterAVM2Item) || (item instanceof SetterAVM2Item)) { + MethodAVM2Item mai = (MethodAVM2Item) item; + if (mai.isStatic() != generateStatic) { + continue; + } + ((TraitMethodGetterSetter) traits[k]).method_info = method(false, isInterface, new ArrayList(), mai.pkg, mai.needsActivation, mai.subvariables, methodInitScope + (mai.isStatic() ? 0 : 1), mai.hasRest, mai.line, className, superName, false, localData, mai.paramTypes, mai.paramNames, mai.paramValues, mai.body, mai.retType); + } else if (item instanceof FunctionAVM2Item) { + FunctionAVM2Item fai = (FunctionAVM2Item) item; + ((TraitFunction) traits[k]).method_info = method(false, isInterface, new ArrayList(), fai.pkg, fai.needsActivation, fai.subvariables, methodInitScope, fai.hasRest, fai.line, className, superName, false, localData, fai.paramTypes, fai.paramNames, fai.paramValues, fai.body, fai.retType); + } + } + } + + public Trait[] generateTraitsPhase1(String className, String superName, boolean generateStatic, SourceGeneratorLocalData localData, List items, Traits ts, Reference classIndex) throws AVM2ParseException, CompilationException { + Trait[] traits = new Trait[items.size()]; + int slot_id = 1; + int disp_id = 3; //1 and 2 are for constructor + for (int k = 0; k < items.size(); k++) { + GraphTargetItem item = items.get(k); + if (item instanceof InterfaceAVM2Item) { + TraitClass tc = new TraitClass(); + ClassInfo ci = new ClassInfo(); + InstanceInfo ii = new InstanceInfo(); + /*abc.class_info.add(ci); + abc.instance_info.add(ii);*/ + tc.class_info = classIndex.getVal(); + abc.addClass(ci, ii, classIndex.getVal()); + classIndex.setVal(classIndex.getVal() + 1); + ii.flags |= InstanceInfo.CLASS_INTERFACE; + //tc.class_info = abc.instance_info.size() - 1; + tc.kindType = Trait.TRAIT_CLASS; + //tc.name_index = traitName(((InterfaceAVM2Item) item).namespace, ((InterfaceAVM2Item) item).name); + tc.slot_id = 0; //? + ts.traits.add(tc); + traits[k] = tc; + } + + if (item instanceof ClassAVM2Item) { + TraitClass tc = new TraitClass(); + ClassInfo ci = new ClassInfo(); + InstanceInfo ii = new InstanceInfo(); + /*abc.class_info.add(ci); + abc.instance_info.add(instanceInfo);*/ + tc.class_info = classIndex.getVal(); + abc.addClass(ci, ii, classIndex.getVal()); + classIndex.setVal(classIndex.getVal() + 1); + //tc.class_info = abc.instance_info.size() - 1; + + /*instanceInfo.name_index = abc.constants.addMultiname(new Multiname(Multiname.QNAME, abc.constants.getStringId(((ClassAVM2Item) item).className, true), + abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abc.constants.getStringId(pkg.packageName, true)), 0, true), 0, 0, new ArrayList())); + */ + + /*if (((ClassAVM2Item) item).extendsOp != null) { + instanceInfo.super_index = typeName(localData, ((ClassAVM2Item) item).extendsOp); + } else { + instanceInfo.super_index = abc.constants.getMultinameId(new Multiname(Multiname.QNAME, str("Object"), namespace(Namespace.KIND_PACKAGE, ""), 0, 0, new ArrayList()), true); + }*/ + tc.kindType = Trait.TRAIT_CLASS; + // tc.name_index = traitName(((ClassAVM2Item) item).namespace, ((ClassAVM2Item) item).className); + tc.slot_id = slot_id++; + ts.traits.add(tc); + traits[k] = tc; + + } + if ((item instanceof SlotAVM2Item) || (item instanceof ConstAVM2Item)) { + TraitSlotConst tsc = new TraitSlotConst(); + tsc.kindType = (item instanceof SlotAVM2Item) ? Trait.TRAIT_SLOT : Trait.TRAIT_CONST; + String var = null; + GraphTargetItem val = null; + GraphTargetItem type = null; + boolean isNamespace = false; + int namespace = 0; + boolean isStatic = false; + if (item instanceof SlotAVM2Item) { + SlotAVM2Item sai = (SlotAVM2Item) item; + if (sai.isStatic() != generateStatic) { + continue; + } + var = sai.var; + val = sai.value; + type = sai.type; + isStatic = sai.isStatic(); + namespace = sai.getNamespace(); + } + if (item instanceof ConstAVM2Item) { + ConstAVM2Item cai = (ConstAVM2Item) item; + if (cai.isStatic() != generateStatic) { + continue; + } + var = cai.var; + val = cai.value; + type = cai.type; + namespace = cai.getNamespace(); + isNamespace = type.toString().equals("Namespace"); + isStatic = cai.isStatic(); + } + if (isNamespace) { + tsc.name_index = traitName(namespace, var); + } + tsc.type_index = isNamespace ? 0 : (type == null ? 0 : typeName(localData, type)); + + ValueKind vk = getValueKind(namespace, type, val); + if (vk == null) { + tsc.value_kind = ValueKind.CONSTANT_Undefined; + } else { + tsc.value_kind = vk.value_kind; + tsc.value_index = vk.value_index; + } + tsc.slot_id = isStatic ? slot_id++ : 0; + ts.traits.add(tsc); + traits[k] = tsc; + } + if ((item instanceof MethodAVM2Item) || (item instanceof GetterAVM2Item) || (item instanceof SetterAVM2Item)) { + MethodAVM2Item mai = (MethodAVM2Item) item; + if (mai.isStatic() != generateStatic) { + continue; + } + TraitMethodGetterSetter tmgs = new TraitMethodGetterSetter(); + tmgs.kindType = (item instanceof GetterAVM2Item) ? Trait.TRAIT_GETTER : ((item instanceof SetterAVM2Item) ? Trait.TRAIT_SETTER : Trait.TRAIT_METHOD); + //tmgs.name_index = traitName(((MethodAVM2Item) item).namespace, ((MethodAVM2Item) item).functionName); + tmgs.disp_id = mai.isStatic() ? disp_id++ : 0; //For a reason, there is disp_id only for static methods (or not?) + if (mai.isFinal() || mai.isStatic()) { + tmgs.kindFlags |= Trait.ATTR_Final; + } + if (mai.isOverride()) { + tmgs.kindFlags |= Trait.ATTR_Override; + } + ts.traits.add(tmgs); + + traits[k] = tmgs; + } else if (item instanceof FunctionAVM2Item) { + TraitFunction tf = new TraitFunction(); + tf.slot_id = slot_id++; + tf.kindType = Trait.TRAIT_FUNCTION; + //tf.name_index = traitName(((FunctionAVM2Item) item).namespace, ((FunctionAVM2Item) item).functionName); + ts.traits.add(tf); + traits[k] = tf; + } + } + + return traits; + } + + public ScriptInfo generateScriptInfo(SourceGeneratorLocalData localData, List commands, int classPos) throws AVM2ParseException, CompilationException { + Reference class_index = new Reference<>(classPos); + ScriptInfo si = new ScriptInfo(); + localData.currentScript = si; + Trait[] traitArr = generateTraitsPhase1(null, null, true, localData, commands, si.traits, class_index); + generateTraitsPhase2(new ArrayList(), null/*FIXME*/, commands, traitArr, new ArrayList(), localData); + MethodInfo mi = new MethodInfo(new int[0], 0, 0, 0, new ValueKind[0], new int[0]); + MethodBody mb = new MethodBody(); + mb.method_info = abc.addMethodInfo(mi); + mb.setCode(new AVM2Code()); + List mbCode = mb.getCode().code; + mbCode.add(ins(new GetLocal0Ins())); + mbCode.add(ins(new PushScopeIns())); + + int traitScope = 2; + + Map initScopes = new HashMap<>(); + + for (Trait t : si.traits.traits) { + if (t instanceof TraitClass) { + TraitClass tc = (TraitClass) t; + List parents = new ArrayList<>(); + if (localData.documentClass) { + mbCode.add(ins(new GetScopeObjectIns(), 0)); + traitScope++; + } else { + NamespaceSet nsset = new NamespaceSet(new int[]{abc.constants.constant_multiname.get(tc.name_index).namespace_index}); + mbCode.add(ins(new FindPropertyStrictIns(), abc.constants.getMultinameId(new Multiname(Multiname.MULTINAME, abc.constants.constant_multiname.get(tc.name_index).name_index, 0, abc.constants.getNamespaceSetId(nsset, true), 0, new ArrayList()), true))); + } + if (abc.instance_info.get(tc.class_info).isInterface()) { + mbCode.add(ins(new PushNullIns())); + } else { + + parentNamesAddNames(abc, allABCs, abc.instance_info.get(tc.class_info).name_index, parents, new ArrayList(), new ArrayList()); + for (int i = parents.size() - 1; i >= 1; i--) { + mbCode.add(ins(new GetLexIns(), parents.get(i))); + mbCode.add(ins(new PushScopeIns())); + traitScope++; + } + mbCode.add(ins(new GetLexIns(), parents.get(1))); + } + mbCode.add(ins(new NewClassIns(), tc.class_info)); + if (!abc.instance_info.get(tc.class_info).isInterface()) { + for (int i = parents.size() - 1; i >= 1; i--) { + mbCode.add(ins(new PopScopeIns())); + } + } + mbCode.add(ins(new InitPropertyIns(), tc.name_index)); + initScopes.put(t, traitScope); + traitScope = 1; + } + } + + mbCode.add(ins(new ReturnVoidIns())); + mb.autoFillStats(abc, 1, false); + abc.addMethodBody(mb); + si.init_index = mb.method_info; + localData.pkg = null; //FIXME: pkg.packageName; + generateTraitsPhase3(1/*??*/, false, null, null, true, localData, commands, si.traits, traitArr, initScopes, class_index); + return si; + } + + public static void parentNamesAddNames(ABC abc, List allABCs, int name_index, List indices, List names, List namespaces) { + List cindices = new ArrayList<>(); + + List outABCs = new ArrayList<>(); + parentNames(abc, allABCs, name_index, cindices, names, namespaces, outABCs); + for (int i = 0; i < cindices.size(); i++) { + ABC a = outABCs.get(i); + int m = cindices.get(i); + if (a == abc) { + indices.add(m); + continue; + } + Multiname superName = a.constants.constant_multiname.get(m); + indices.add( + abc.constants.getMultinameId( + new Multiname(Multiname.QNAME, + abc.constants.getStringId(superName.getName(a.constants, new ArrayList(), true), true), + abc.constants.getNamespaceId(new Namespace(superName.getNamespace(a.constants).kind, abc.constants.getStringId(superName.getNamespace(a.constants).getName(a.constants, true), true)), 0, true), 0, 0, new ArrayList()), true) + ); + } + } + + public static GraphTargetItem getTraitReturnType(ABC abc, Trait t) { + if (t instanceof TraitSlotConst) { + TraitSlotConst tsc = (TraitSlotConst) t; + if (tsc.type_index == 0) { + return TypeItem.UNBOUNDED; + } + return PropertyAVM2Item.multinameToType(tsc.type_index, abc.constants); + } + if (t instanceof TraitMethodGetterSetter) { + TraitMethodGetterSetter tmgs = (TraitMethodGetterSetter) t; + if (tmgs.kindType == Trait.TRAIT_GETTER) { + return PropertyAVM2Item.multinameToType(abc.method_info.get(tmgs.method_info).ret_type, abc.constants); + } + if (tmgs.kindType == Trait.TRAIT_SETTER) { + if (abc.method_info.get(tmgs.method_info).param_types.length > 0) { + return PropertyAVM2Item.multinameToType(abc.method_info.get(tmgs.method_info).param_types[0], abc.constants); + } else { + return TypeItem.UNBOUNDED; + } + } + } + if (t instanceof TraitFunction) { + return new TypeItem("Function"); + } + return TypeItem.UNBOUNDED; + } + + private static boolean eq(Object a, Object b) { + if (a == null && b == null) { + return true; + } + if (a == null) { + return false; + } + if (b == null) { + return false; + } + return a.equals(b); + } + + public static boolean searchPrototypeChain(boolean instanceOnly, List abcs, String pkg, String obj, String propertyName, Reference outName, Reference outNs, Reference outPropNs, Reference outPropNsKind, Reference outPropNsIndex, Reference outPropType, Reference outPropValue) { + + for (ABC abc : abcs) { + if (!instanceOnly) { + for (ScriptInfo ii : abc.script_info) { + if (ii.deleted) { + continue; + } + for (Trait t : ii.traits.traits) { + if (eq(pkg, t.getName(abc).getNamespace(abc.constants).getName(abc.constants, true))) { + if (propertyName.equals(t.getName(abc).getName(abc.constants, new ArrayList(), true))) { + outName.setVal(obj); + outNs.setVal(pkg); + outPropNs.setVal(t.getName(abc).getNamespace(abc.constants).getName(abc.constants, true)); + outPropNsKind.setVal(t.getName(abc).getNamespace(abc.constants).kind); + outPropNsIndex.setVal(abc.constants.getNamespaceSubIndex(t.getName(abc).namespace_index)); + outPropType.setVal(getTraitReturnType(abc, t)); + if (t instanceof TraitSlotConst) { + TraitSlotConst tsc = (TraitSlotConst) t; + outPropValue.setVal(new ValueKind(tsc.value_index, tsc.value_kind)); + } + return true; + } + } + } + } + } + for (int i = 0; i < abc.instance_info.size(); i++) { + InstanceInfo ii = abc.instance_info.get(i); + if (ii.deleted) { + continue; + } + Multiname clsName = ii.getName(abc.constants); + if (obj.equals(clsName.getName(abc.constants, new ArrayList(), true))) { + if (eq(pkg, clsName.getNamespace(abc.constants).getName(abc.constants, true))) { + //class found + + for (Trait t : ii.instance_traits.traits) { + if (t.getName(abc) == null) { //in traits phase 2 + continue; + } + if (propertyName.equals(t.getName(abc).getName(abc.constants, new ArrayList(), true))) { + outName.setVal(obj); + outNs.setVal(pkg); + outPropNs.setVal(t.getName(abc).getNamespace(abc.constants).getName(abc.constants, true)); + outPropNsKind.setVal(t.getName(abc).getNamespace(abc.constants).kind); + outPropNsIndex.setVal(abc.constants.getNamespaceSubIndex(t.getName(abc).namespace_index)); + outPropType.setVal(getTraitReturnType(abc, t)); + if (t instanceof TraitSlotConst) { + TraitSlotConst tsc = (TraitSlotConst) t; + outPropValue.setVal(new ValueKind(tsc.value_index, tsc.value_kind)); + } + return true; + } + } + + if (!instanceOnly) { + for (Trait t : abc.class_info.get(i).static_traits.traits) { + if (t.getName(abc) == null) { //in traits phase 2 + continue; + } + if (propertyName.equals(t.getName(abc).getName(abc.constants, new ArrayList(), true))) { + outName.setVal(obj); + outNs.setVal(pkg); + outPropNs.setVal(t.getName(abc).getNamespace(abc.constants).getName(abc.constants, true)); + outPropNsKind.setVal(t.getName(abc).getNamespace(abc.constants).kind); + outPropNsIndex.setVal(abc.constants.getNamespaceSubIndex(t.getName(abc).namespace_index)); + outPropType.setVal(getTraitReturnType(abc, t)); + if (t instanceof TraitSlotConst) { + TraitSlotConst tsc = (TraitSlotConst) t; + outPropValue.setVal(new ValueKind(tsc.value_index, tsc.value_kind)); + } + return true; + } + } + } + + Multiname superName = abc.constants.constant_multiname.get(ii.super_index); + if (superName != null) { + return searchPrototypeChain(instanceOnly, abcs, superName.getNamespace(abc.constants).getName(abc.constants, true), superName.getName(abc.constants, new ArrayList(), true), propertyName, outName, outNs, outPropNs, outPropNsKind, outPropNsIndex, outPropType, outPropValue); + } else { + return false; + } + } + } + } + } + return false; + } + + public static void parentNames(ABC abc, List allABCs, int name_index, List indices, List names, List namespaces, List outABCs) { + indices.add(name_index); + names.add(abc.constants.constant_multiname.get(name_index).getName(abc.constants, new ArrayList(), true)); + namespaces.add(abc.constants.constant_multiname.get(name_index).getNamespace(abc.constants).getName(abc.constants, true)); + Multiname mname = abc.constants.constant_multiname.get(name_index); + + outABCs.add(abc); + + List abcs = new ArrayList<>(); + abcs.add(abc); + abcs.addAll(allABCs); + + for (ABC a : abcs) { + for (int i = 0; i < a.instance_info.size(); i++) { + Multiname m = a.constants.constant_multiname.get(a.instance_info.get(i).name_index); + if (m.getName(a.constants, new ArrayList(), true).equals(mname.getName(abc.constants, new ArrayList(), true))) { + + if (m.getNamespace(a.constants).hasName(mname.getNamespace(abc.constants).getName(abc.constants, true), a.constants)) { + //Multiname superName = a.constants.constant_multiname.get(a.instance_info.get(i).super_index); + abcs.remove(a); + if (a.instance_info.get(i).super_index != 0) { + parentNames(a, abcs, a.instance_info.get(i).super_index, indices, names, namespaces, outABCs); + } + /*parentNames(abc,allABCs,abc.constants.getMultinameId( + new Multiname(superName.kind, + abc.constants.getStringId(superName.getName(a.constants, new ArrayList()),true), + abc.constants.getNamespaceId(new Namespace(superName.getNamespace(a.constants).kind, abc.constants.getStringId(superName.getNamespace(a.constants).getName(a.constants),true)),0,true), 0, 0, new ArrayList()), true),indices,names,namespaces,outABCs);*/ + return; + } + } + } + } + } + + /* public void calcRegisters(Reference activationReg, SourceGeneratorLocalData localData, boolean needsActivation, List funParamNames,List funSubVariables,List funBody, Reference hasArguments) throws ParseException { + + }*/ + /*public int resolveType(String objType) { + if (objType.equals("*")) { + return 0; + } + List abcs = new ArrayList<>(); + abcs.add(abc); + abcs.addAll(allABCs); + for (ABC a : abcs) { + int ci = a.findClassByName(objType); + if (ci != -1) { + Multiname tname = a.instance_info.get(ci).getName(a.constants); + return abc.constants.getMultinameId(new Multiname(tname.kind, + abc.constants.getStringId(tname.getName(a.constants, new ArrayList()), true), + abc.constants.getNamespaceId(new Namespace(tname.getNamespace(a.constants).kind, abc.constants.getStringId(tname.getNamespace(a.constants).getName(a.constants), true)), 0, true), 0, 0, new ArrayList()), true); + } + } + return 0; + }*/ + @Override + public List generate(SourceGeneratorLocalData localData, TypeItem item) throws CompilationException { + String currentFullClassName = localData.getFullClass(); + + if (localData.documentClass && item.toString().equals(currentFullClassName)) { + int slotId = 0; + int c = abc.findClassByName(currentFullClassName); + for (Trait t : localData.currentScript.traits.traits) { + if (t instanceof TraitClass) { + TraitClass tc = (TraitClass) t; + if (tc.class_info == c) { + slotId = tc.slot_id; + break; + } + } + } + return GraphTargetItem.toSourceMerge(localData, this, ins(new GetGlobalScopeIns()), ins(new GetSlotIns(), slotId)); + } else { + return GraphTargetItem.toSourceMerge(localData, this, ins(new GetLexIns(), resolveType(localData, item, abc, allABCs))); + } + } + + public static int resolveType(SourceGeneratorLocalData localData, GraphTargetItem item, ABC abc, List allABCs) throws CompilationException { + int name_index = 0; + GraphTargetItem typeItem = null; + + if (item instanceof UnresolvedAVM2Item) { + String fullClass = localData.getFullClass(); + item = ((UnresolvedAVM2Item) item).resolve(new TypeItem(fullClass), new ArrayList(), new ArrayList(), abc, allABCs, new ArrayList(), new ArrayList()); + } + if (item instanceof TypeItem) { + typeItem = item; + } else if (item instanceof ApplyTypeAVM2Item) { + typeItem = ((ApplyTypeAVM2Item) item).object; + } else { + throw new CompilationException("Invalid type:" + item.getClass().getName(), 0/*??*/); + } + if (typeItem instanceof UnresolvedAVM2Item) { + String fullClass = localData.getFullClass(); + typeItem = ((UnresolvedAVM2Item) typeItem).resolve(new TypeItem(fullClass), new ArrayList(), new ArrayList(), abc, allABCs, new ArrayList(), new ArrayList()); + } + + if (!(typeItem instanceof TypeItem)) { + throw new CompilationException("Invalid type", 0/*??*/); + } + + TypeItem type = (TypeItem) typeItem; + + String name = type.fullTypeName; + String pkg = ""; + if (name.contains(".")) { + pkg = name.substring(0, name.lastIndexOf('.')); + name = name.substring(name.lastIndexOf('.') + 1); + } + for (InstanceInfo ii : abc.instance_info) { + Multiname mname = abc.constants.constant_multiname.get(ii.name_index); + if (mname != null && name.equals(mname.getName(abc.constants, new ArrayList(), true))) { + if (mname.getNamespace(abc.constants).hasName(pkg, abc.constants)) { + name_index = ii.name_index; + break; + } + } + } + for (int i = 1; i < abc.constants.constant_multiname.size(); i++) { + Multiname mname = abc.constants.constant_multiname.get(i); + if (mname != null && name.equals(mname.getName(abc.constants, new ArrayList(), true))) { + if (mname.getNamespace(abc.constants) != null && pkg.equals(mname.getNamespace(abc.constants).getName(abc.constants, true))) { + name_index = i; + break; + } + } + } + if (name_index == 0) { + if (pkg.isEmpty() && localData.currentScript != null /*FIXME!*/) { + for (Trait t : localData.currentScript.traits.traits) { + if (t.getName(abc).getName(abc.constants, new ArrayList(), true).equals(name)) { + name_index = t.name_index; + break; + } + } + } + if (name_index == 0) { + name_index = abc.constants.getMultinameId(new Multiname(Multiname.QNAME, abc.constants.getStringId(name, true), abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abc.constants.getStringId(pkg, true)), 0, true), 0, 0, new ArrayList()), true); + } + } + + if (item instanceof ApplyTypeAVM2Item) { + ApplyTypeAVM2Item atype = (ApplyTypeAVM2Item) item; + List params = new ArrayList<>(); + for (GraphTargetItem s : atype.params) { + params.add(resolveType(localData, s, abc, allABCs)); + } + return abc.constants.getMultinameId(new Multiname(Multiname.TYPENAME, 0, 0, 0, name_index, params), true); + } + + return name_index; + } + + @Override + public List generateDiscardValue(SourceGeneratorLocalData localData, GraphTargetItem item) throws CompilationException { + List ret = item.toSource(localData, this); + ret.add(ins(new PopIns())); + return ret; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScriptLexer.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScriptLexer.java index 1899f32ca..d3d5d869f 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScriptLexer.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScriptLexer.java @@ -1,2344 +1,2344 @@ -/* The following code was generated by JFlex 1.6.0 */ - -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.parser.script; - -import com.jpexs.decompiler.flash.abc.avm2.parser.AVM2ParseException; -import java.io.StringReader; -import java.util.ArrayList; -import java.util.List; -import java.util.Stack; - -/** - * This class is a scanner generated by - * JFlex 1.6.0 - * from the specification file - * C:/Projects/FFDec/jpexs-decompiler/libsrc/ffdec_lib/lexers/actionscript3_script.flex - */ -public final class ActionScriptLexer { - - /** - * This character denotes the end of file - */ - public static final int YYEOF = -1; - - /** - * initial size of the lookahead buffer - */ - private static final int ZZ_BUFFERSIZE = 16384; - - /** - * lexical states - */ - public static final int YYINITIAL = 0; - - public static final int STRING = 2; - - public static final int CHARLITERAL = 4; - - public static final int XMLOPENTAG = 6; - - public static final int XMLOPENTAGATTRIB = 8; - - public static final int XMLINSTROPENTAG = 10; - - public static final int XMLINSTRATTRIB = 12; - - public static final int XMLCDATA = 14; - - public static final int XMLCOMMENT = 16; - - public static final int XML = 18; - - public static final int OIDENTIFIER = 20; - - /** - * ZZ_LEXSTATE[l] is the state in the DFA for the lexical state l - * ZZ_LEXSTATE[l+1] is the state in the DFA for the lexical state l - * at the beginning of a line - * l is of the form l = 2*k, k a non negative integer - */ - private static final int ZZ_LEXSTATE[] = { - 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, - 8, 8, 9, 9, 10, 10 - }; - - /** - * Translates characters to character classes - */ - private static final String ZZ_CMAP_PACKED - = "\11\0\1\13\1\2\1\113\1\3\1\1\22\0\1\13\1\14\1\33" - + "\1\0\1\6\1\110\1\105\1\34\1\76\1\77\1\5\1\45\1\103" - + "\1\15\1\11\1\4\1\35\3\41\4\42\2\21\1\17\1\102\1\12" - + "\1\32\1\16\1\23\1\111\1\27\1\20\1\25\1\26\1\43\1\20" - + "\2\10\1\74\4\10\1\75\5\10\1\30\3\10\1\37\2\10\1\24" - + "\1\46\1\31\1\107\1\10\1\0\1\52\1\50\1\54\1\63\1\44" - + "\1\40\1\73\1\66\1\61\1\10\1\53\1\64\1\71\1\57\1\56" - + "\1\67\1\10\1\51\1\55\1\60\1\62\1\72\1\65\1\36\1\70" - + "\1\10\1\100\1\106\1\101\1\104\6\0\1\113\41\0\1\47\2\0" - + "\1\6\12\0\1\6\1\0\1\22\2\0\1\6\5\0\2\6\1\112" - + "\24\6\1\0\37\6\1\0\u01ca\6\4\0\14\6\16\0\5\6\7\0" - + "\1\6\1\0\1\6\21\0\160\7\5\6\1\0\2\6\2\0\4\6" - + "\1\0\1\6\6\0\1\6\1\0\3\6\1\0\1\6\1\0\24\6" - + "\1\0\123\6\1\0\213\6\1\0\5\7\2\0\246\6\1\0\46\6" - + "\2\0\1\6\7\0\47\6\11\0\55\7\1\0\1\7\1\0\2\7" - + "\1\0\2\7\1\0\1\7\10\0\33\6\5\0\3\6\35\0\13\7" - + "\5\0\53\6\37\7\4\0\2\6\1\7\143\6\1\0\1\6\7\7" - + "\2\0\6\7\2\6\2\7\1\0\4\7\2\6\12\7\3\6\2\0" - + "\1\6\20\0\1\6\1\7\36\6\33\7\2\0\131\6\13\7\1\6" - + "\16\0\12\7\41\6\11\7\2\6\4\0\1\6\5\0\26\6\4\7" - + "\1\6\11\7\1\6\3\7\1\6\5\7\22\0\31\6\3\7\104\0" - + "\23\6\61\0\40\7\66\6\3\7\1\6\22\7\1\6\7\7\12\6" - + "\2\7\2\0\12\7\1\0\20\6\3\7\1\0\10\6\2\0\2\6" - + "\2\0\26\6\1\0\7\6\1\0\1\6\3\0\4\6\2\0\1\7" - + "\1\6\7\7\2\0\2\7\2\0\3\7\1\6\10\0\1\7\4\0" - + "\2\6\1\0\3\6\2\7\2\0\12\7\2\6\17\0\3\7\1\0" - + "\6\6\4\0\2\6\2\0\26\6\1\0\7\6\1\0\2\6\1\0" - + "\2\6\1\0\2\6\2\0\1\7\1\0\5\7\4\0\2\7\2\0" - + "\3\7\3\0\1\7\7\0\4\6\1\0\1\6\7\0\14\7\3\6" - + "\1\7\13\0\3\7\1\0\11\6\1\0\3\6\1\0\26\6\1\0" - + "\7\6\1\0\2\6\1\0\5\6\2\0\1\7\1\6\10\7\1\0" - + "\3\7\1\0\3\7\2\0\1\6\17\0\2\6\2\7\2\0\12\7" - + "\21\0\3\7\1\0\10\6\2\0\2\6\2\0\26\6\1\0\7\6" - + "\1\0\2\6\1\0\5\6\2\0\1\7\1\6\7\7\2\0\2\7" - + "\2\0\3\7\10\0\2\7\4\0\2\6\1\0\3\6\2\7\2\0" - + "\12\7\1\0\1\6\20\0\1\7\1\6\1\0\6\6\3\0\3\6" - + "\1\0\4\6\3\0\2\6\1\0\1\6\1\0\2\6\3\0\2\6" - + "\3\0\3\6\3\0\14\6\4\0\5\7\3\0\3\7\1\0\4\7" - + "\2\0\1\6\6\0\1\7\16\0\12\7\20\0\4\7\1\0\10\6" - + "\1\0\3\6\1\0\27\6\1\0\20\6\3\0\1\6\7\7\1\0" - + "\3\7\1\0\4\7\7\0\2\7\1\0\2\6\6\0\2\6\2\7" - + "\2\0\12\7\21\0\3\7\1\0\10\6\1\0\3\6\1\0\27\6" - + "\1\0\12\6\1\0\5\6\2\0\1\7\1\6\7\7\1\0\3\7" - + "\1\0\4\7\7\0\2\7\7\0\1\6\1\0\2\6\2\7\2\0" - + "\12\7\1\0\2\6\16\0\3\7\1\0\10\6\1\0\3\6\1\0" - + "\51\6\2\0\1\6\7\7\1\0\3\7\1\0\4\7\1\6\10\0" - + "\1\7\10\0\2\6\2\7\2\0\12\7\12\0\6\6\2\0\2\7" - + "\1\0\22\6\3\0\30\6\1\0\11\6\1\0\1\6\2\0\7\6" - + "\3\0\1\7\4\0\6\7\1\0\1\7\1\0\10\7\6\0\12\7" - + "\2\0\2\7\15\0\60\6\1\7\2\6\7\7\5\0\7\6\10\7" - + "\1\0\12\7\47\0\2\6\1\0\1\6\2\0\2\6\1\0\1\6" - + "\2\0\1\6\6\0\4\6\1\0\7\6\1\0\3\6\1\0\1\6" - + "\1\0\1\6\2\0\2\6\1\0\4\6\1\7\2\6\6\7\1\0" - + "\2\7\1\6\2\0\5\6\1\0\1\6\1\0\6\7\2\0\12\7" - + "\2\0\4\6\40\0\1\6\27\0\2\7\6\0\12\7\13\0\1\7" - + "\1\0\1\7\1\0\1\7\4\0\2\7\10\6\1\0\44\6\4\0" - + "\24\7\1\0\2\7\5\6\13\7\1\0\44\7\11\0\1\7\71\0" - + "\53\6\24\7\1\6\12\7\6\0\6\6\4\7\4\6\3\7\1\6" - + "\3\7\2\6\7\7\3\6\4\7\15\6\14\7\1\6\17\7\2\0" - + "\46\6\1\0\1\6\5\0\1\6\2\0\53\6\1\0\u014d\6\1\0" - + "\4\6\2\0\7\6\1\0\1\6\1\0\4\6\2\0\51\6\1\0" - + "\4\6\2\0\41\6\1\0\4\6\2\0\7\6\1\0\1\6\1\0" - + "\4\6\2\0\17\6\1\0\71\6\1\0\4\6\2\0\103\6\2\0" - + "\3\7\40\0\20\6\20\0\125\6\14\0\u026c\6\2\0\21\6\1\0" - + "\32\6\5\0\113\6\3\0\3\7\10\6\7\0\15\6\1\0\4\6" - + "\3\7\13\0\22\6\3\7\13\0\22\6\2\7\14\0\15\6\1\0" - + "\3\6\1\0\2\7\14\0\64\6\40\7\3\0\1\6\4\0\1\6" - + "\1\7\2\0\12\7\41\0\3\7\2\0\12\7\6\0\130\6\10\0" - + "\51\6\1\7\1\6\5\0\106\6\12\0\37\6\1\0\14\7\4\0" - + "\14\7\12\0\12\7\36\6\2\0\5\6\13\0\54\6\4\0\21\7" - + "\7\6\2\7\6\0\12\7\46\0\27\6\5\7\4\0\65\6\12\7" - + "\1\0\35\7\2\0\13\7\6\0\12\7\15\0\1\6\10\0\16\7" - + "\102\0\5\7\57\6\21\7\7\6\4\0\12\7\21\0\11\7\14\0" - + "\3\7\36\6\15\7\2\6\12\7\54\6\16\7\14\0\44\6\24\7" - + "\10\0\12\7\3\0\3\6\12\7\44\6\122\0\3\7\1\0\25\7" - + "\4\6\1\7\4\6\3\7\2\6\1\0\2\7\6\0\300\6\66\7" - + "\6\0\4\7\u0116\6\2\0\6\6\2\0\46\6\2\0\6\6\2\0" - + "\10\6\1\0\1\6\1\0\1\6\1\0\1\6\1\0\37\6\2\0" - + "\65\6\1\0\7\6\1\0\1\6\3\0\3\6\1\0\7\6\3\0" - + "\4\6\2\0\6\6\4\0\15\6\5\0\3\6\1\0\7\6\3\0" - + "\14\0\2\0\32\0\1\113\1\113\25\0\2\7\23\0\1\7\33\0" - + "\1\0\1\6\15\0\1\6\20\0\15\6\63\0\15\7\4\0\1\7" - + "\3\0\14\7\21\0\1\6\4\0\1\6\2\0\12\6\1\0\1\6" - + "\3\0\5\6\6\0\1\6\1\0\1\6\1\0\1\6\1\0\4\6" - + "\1\0\13\6\2\0\4\6\5\0\5\6\4\0\1\6\21\0\43\7" - + "\2\6\4\7\7\0\u0a70\0\57\6\1\0\57\6\1\0\205\6\6\0" - + "\4\6\3\7\2\6\14\0\46\6\1\0\1\6\5\0\1\6\2\0" - + "\70\6\7\0\1\6\17\0\1\7\27\6\11\0\7\6\1\0\7\6" - + "\1\0\7\6\1\0\7\6\1\0\7\6\1\0\7\6\1\0\7\6" - + "\1\0\7\6\1\0\40\7\57\0\1\6\u01c0\0\21\0\4\0\2\6" - + "\1\7\31\0\17\7\1\0\5\6\2\0\3\7\2\6\4\0\126\6" - + "\2\0\2\7\2\0\3\6\1\0\132\6\1\0\4\6\5\0\51\6" - + "\3\0\136\6\21\0\33\6\65\0\20\6\u0200\0\u19b6\6\112\0\u51cd\6" - + "\63\0\u048d\6\103\0\56\6\2\0\u010d\6\3\0\20\6\12\7\2\6" - + "\24\0\57\6\1\7\4\0\12\7\1\0\37\6\1\0\1\7\106\6" - + "\14\7\45\0\11\6\2\0\147\6\2\0\4\6\1\0\36\6\2\0" - + "\2\6\105\0\13\6\1\7\3\6\1\7\4\6\1\7\27\6\5\7" - + "\30\0\64\6\14\0\2\7\62\6\21\7\13\0\12\7\6\0\22\7" - + "\6\6\3\0\1\6\4\0\12\7\34\6\10\7\2\0\27\6\15\7" - + "\14\0\35\6\3\0\4\7\57\6\16\7\16\0\1\6\12\7\6\0" - + "\5\6\1\7\12\6\12\7\5\6\1\0\51\6\16\7\11\0\3\6" - + "\1\7\10\6\2\7\2\0\12\7\6\0\27\6\3\0\1\6\3\7" - + "\62\6\1\7\1\6\3\7\2\6\2\7\5\6\2\7\1\6\1\7" - + "\1\6\30\0\3\6\2\0\13\6\5\7\2\0\3\6\2\7\12\0" - + "\6\6\2\0\6\6\2\0\6\6\11\0\7\6\1\0\7\6\1\0" - + "\53\6\1\0\4\6\4\0\2\6\132\0\43\6\10\7\1\0\2\7" - + "\2\0\12\7\6\0\u2ba4\6\14\0\27\6\4\0\61\6\4\0\u1800\0" - + "\u0900\0\u016e\6\2\0\152\6\46\0\7\6\14\0\5\6\5\0\1\6" - + "\1\7\12\6\1\0\15\6\1\0\5\6\1\0\1\6\1\0\2\6" - + "\1\0\2\6\1\0\154\6\41\0\u016b\6\22\0\100\6\2\0\66\6" - + "\10\0\40\0\14\6\4\0\20\7\20\0\16\7\5\0\2\7\30\0" - + "\3\7\40\0\5\6\1\0\207\6\23\0\12\7\7\0\32\6\4\0" - + "\1\7\1\0\32\6\13\0\131\6\3\0\6\6\2\0\6\6\2\0" - + "\6\6\2\0\3\6\41\0\2\0\14\6\1\0\32\6\1\0\23\6" - + "\1\0\2\6\1\0\17\6\2\0\16\6\42\0\173\6\105\0\65\7" - + "\210\0\1\7\202\0\35\6\3\0\61\6\17\0\1\7\37\0\40\6" - + "\20\0\21\6\1\7\10\6\1\7\5\0\46\6\5\7\5\0\36\6" - + "\2\0\44\6\4\0\10\6\1\0\5\7\52\0\236\6\2\0\12\7" - + "\126\0\50\6\10\0\64\6\234\0\u0137\6\11\0\26\6\12\0\10\6" - + "\230\0\6\6\2\0\1\6\1\0\54\6\1\0\2\6\3\0\1\6" - + "\2\0\27\6\12\0\27\6\11\0\37\6\141\0\26\6\12\0\32\6" - + "\106\0\70\6\6\0\2\6\100\0\1\6\3\7\1\0\2\7\5\0" - + "\4\7\4\6\1\0\3\6\1\0\33\6\4\0\3\7\4\0\1\7" - + "\40\0\35\6\3\0\35\6\43\0\10\6\1\0\34\6\2\7\31\0" - + "\66\6\12\0\26\6\12\0\23\6\15\0\22\6\156\0\111\6\u03b7\0" - + "\3\7\65\6\17\7\37\0\12\7\17\0\4\7\55\6\13\7\25\0" - + "\31\6\7\0\12\7\6\0\3\7\44\6\16\7\1\0\12\7\20\0" - + "\43\6\1\7\2\0\1\6\11\0\3\7\60\6\16\7\4\6\13\0" - + "\12\7\1\6\45\0\22\6\1\0\31\6\14\7\170\0\57\6\14\7" - + "\5\0\12\7\7\0\3\7\1\0\10\6\2\0\2\6\2\0\26\6" - + "\1\0\7\6\1\0\2\6\1\0\5\6\2\0\1\7\1\6\7\7" - + "\2\0\2\7\2\0\3\7\11\0\1\7\5\0\5\6\2\7\2\0" - + "\7\7\3\0\5\7\u010b\0\60\6\24\7\2\6\1\0\1\6\10\0" - + "\12\7\246\0\57\6\7\7\2\0\11\7\77\0\60\6\21\7\3\0" - + "\1\6\13\0\12\7\46\0\53\6\15\7\10\0\12\7\u01d6\0\100\6" - + "\12\7\25\0\1\6\u01c0\0\71\6\u0507\0\u0399\6\147\0\157\7\u0b91\0" - + "\u042f\6\u33d1\0\u0239\6\7\0\37\6\1\0\12\7\146\0\36\6\2\0" - + "\5\7\13\0\60\6\7\7\11\0\4\6\14\0\12\7\11\0\25\6" - + "\5\0\23\6\u0370\0\105\6\13\0\1\6\56\7\20\0\4\7\15\6" - + "\u4060\0\2\6\u0bfe\0\153\6\5\0\15\6\3\0\11\6\7\0\12\6" - + "\3\0\2\7\u14c6\0\5\7\3\0\6\7\10\0\10\7\2\0\7\7" - + "\36\0\4\7\224\0\3\7\u01bb\0\125\6\1\0\107\6\1\0\2\6" - + "\2\0\1\6\2\0\2\6\2\0\4\6\1\0\14\6\1\0\1\6" - + "\1\0\7\6\1\0\101\6\1\0\4\6\2\0\10\6\1\0\7\6" - + "\1\0\34\6\1\0\4\6\1\0\5\6\1\0\1\6\3\0\7\6" - + "\1\0\u0154\6\2\0\31\6\1\0\31\6\1\0\37\6\1\0\31\6" - + "\1\0\37\6\1\0\31\6\1\0\37\6\1\0\31\6\1\0\37\6" - + "\1\0\31\6\1\0\10\6\2\0\62\7\u1000\0\305\6\13\0\7\7" - + "\u0529\0\4\6\1\0\33\6\1\0\2\6\1\0\1\6\2\0\1\6" - + "\1\0\12\6\1\0\4\6\1\0\1\6\1\0\1\6\6\0\1\6" - + "\4\0\1\6\1\0\1\6\1\0\1\6\1\0\3\6\1\0\2\6" - + "\1\0\1\6\2\0\1\6\1\0\1\6\1\0\1\6\1\0\1\6" - + "\1\0\1\6\1\0\2\6\1\0\1\6\2\0\4\6\1\0\7\6" - + "\1\0\4\6\1\0\4\6\1\0\1\6\1\0\12\6\1\0\21\6" - + "\5\0\3\6\1\0\5\6\1\0\21\6\u1144\0\ua6d7\6\51\0\u1035\6" - + "\13\0\336\6\u3fe2\0\u021e\6\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\u06ed\0" - + "\360\7\uffff\0\uffff\0\ufe12\0"; - - /** - * Translates characters to character classes - */ - private static final char[] ZZ_CMAP = zzUnpackCMap(ZZ_CMAP_PACKED); - - /** - * Translates DFA states to action switch labels. - */ - private static final int[] ZZ_ACTION = zzUnpackAction(); - - private static final String ZZ_ACTION_PACKED_0 - = "\13\0\1\1\2\2\1\3\1\4\1\5\1\6\1\7" - + "\1\10\1\11\1\12\1\13\1\14\1\15\1\16\1\17" - + "\1\20\1\21\1\22\1\23\1\15\2\6\1\24\1\25" - + "\21\6\1\26\1\27\1\30\1\31\1\32\1\33\1\34" - + "\1\35\1\36\1\37\1\40\1\41\1\42\2\43\1\44" - + "\1\1\1\42\2\45\2\46\1\42\2\1\1\47\1\50" - + "\1\1\1\51\2\1\1\52\1\1\1\53\2\42\2\54" - + "\2\42\1\55\1\42\1\1\1\56\1\3\1\0\1\57" - + "\1\60\1\61\1\62\1\63\1\64\1\65\1\66\1\67" - + "\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\0" - + "\1\77\1\63\1\100\1\0\2\100\7\6\1\101\1\102" - + "\2\6\1\103\16\6\1\104\1\105\1\106\4\6\1\107" - + "\13\6\1\110\1\111\1\112\1\113\1\114\1\115\1\116" - + "\1\117\1\120\1\116\1\121\1\122\1\123\1\124\1\125" - + "\1\126\1\116\1\127\1\0\1\130\1\0\1\131\1\0" - + "\1\132\1\133\1\0\1\134\4\0\1\135\2\0\1\136" - + "\4\137\2\3\2\0\1\140\1\141\1\142\1\143\1\144" - + "\1\0\1\63\1\145\2\146\1\100\1\6\1\147\13\6" - + "\1\150\4\6\1\151\4\6\1\152\6\6\1\153\12\6" - + "\1\154\1\6\1\155\1\6\1\156\3\0\1\134\1\157" - + "\1\160\1\0\1\161\2\0\1\162\1\163\1\164\1\0" - + "\1\165\1\146\1\100\4\6\1\166\1\167\2\6\1\170" - + "\12\6\1\171\1\172\1\6\1\173\11\6\1\174\5\6" - + "\1\175\1\6\1\176\2\0\1\177\1\200\1\0\1\146" - + "\1\100\1\201\1\202\2\6\1\203\1\6\1\204\1\205" - + "\1\6\1\206\1\6\1\207\4\6\1\210\11\6\1\211" - + "\5\6\1\0\1\146\1\100\3\6\1\212\1\6\1\213" - + "\1\214\1\6\1\215\1\6\1\216\3\6\1\217\3\6" - + "\1\220\4\6\1\221\1\6\1\0\1\146\1\100\1\222" - + "\1\6\1\223\10\6\1\224\1\225\1\6\1\226\1\227" - + "\1\6\1\0\1\146\1\100\1\230\1\231\1\232\3\6" - + "\1\233\3\6\1\234\1\0\1\146\1\100\1\235\1\6" - + "\1\236\1\6\1\237\1\240\1\241\1\146\1\100\1\242" - + "\1\243\6\100"; - - private static int[] zzUnpackAction() { - int[] result = new int[446]; - int offset = 0; - offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result); - return result; - } - - private static int zzUnpackAction(String packed, int offset, int[] result) { - int i = 0; /* index in packed string */ - - int j = offset; /* index in unpacked array */ - - int l = packed.length(); - while (i < l) { - int count = packed.charAt(i++); - int value = packed.charAt(i++); - do { - result[j++] = value; - } while (--count > 0); - } - return j; - } - - /** - * Translates a state to a row index in the transition table - */ - private static final int[] ZZ_ROWMAP = zzUnpackRowMap(); - - private static final String ZZ_ROWMAP_PACKED_0 - = "\0\0\0\114\0\230\0\344\0\u0130\0\u017c\0\u01c8\0\u0214" - + "\0\u0260\0\u02ac\0\u02f8\0\u0344\0\u0390\0\u0344\0\u03dc\0\u0428" - + "\0\u0474\0\u04c0\0\u050c\0\u0558\0\u05a4\0\u05f0\0\u063c\0\u0688" - + "\0\u06d4\0\u0344\0\u0344\0\u0344\0\u0720\0\u0344\0\u0344\0\u076c" - + "\0\u07b8\0\u0804\0\u0850\0\u0344\0\u089c\0\u08e8\0\u0934\0\u0980" - + "\0\u09cc\0\u0a18\0\u0a64\0\u0ab0\0\u0afc\0\u0b48\0\u0b94\0\u0be0" - + "\0\u0c2c\0\u0c78\0\u0cc4\0\u0d10\0\u0d5c\0\u0344\0\u0344\0\u0344" - + "\0\u0344\0\u0344\0\u0344\0\u0344\0\u0da8\0\u0df4\0\u0e40\0\u0e8c" - + "\0\u0344\0\u0ed8\0\u0f24\0\u0344\0\u0344\0\u0f70\0\u0fbc\0\u1008" - + "\0\u0344\0\u1054\0\u0344\0\u10a0\0\u10ec\0\u1138\0\u0344\0\u0344" - + "\0\u1184\0\u0344\0\u11d0\0\u121c\0\u0344\0\u1268\0\u0344\0\u0344" - + "\0\u12b4\0\u1300\0\u0344\0\u134c\0\u1398\0\u0344\0\u13e4\0\u1430" - + "\0\u0344\0\u147c\0\u14c8\0\u0344\0\u0344\0\u1514\0\u0344\0\u1560" - + "\0\u0344\0\u15ac\0\u15f8\0\u0344\0\u0344\0\u1644\0\u0344\0\u0344" - + "\0\u1690\0\u0344\0\u0344\0\u16dc\0\u1728\0\u1774\0\u17c0\0\u180c" - + "\0\u1858\0\u18a4\0\u18f0\0\u193c\0\u1988\0\u19d4\0\u1a20\0\u1a6c" - + "\0\u1ab8\0\u0344\0\u0344\0\u1b04\0\u1b50\0\u04c0\0\u1b9c\0\u1be8" - + "\0\u1c34\0\u1c80\0\u1ccc\0\u1d18\0\u1d64\0\u1db0\0\u1dfc\0\u1e48" - + "\0\u1e94\0\u1ee0\0\u1f2c\0\u1f78\0\u04c0\0\u04c0\0\u1fc4\0\u2010" - + "\0\u205c\0\u20a8\0\u20f4\0\u04c0\0\u2140\0\u218c\0\u21d8\0\u2224" - + "\0\u2270\0\u22bc\0\u2308\0\u2354\0\u23a0\0\u23ec\0\u2438\0\u0344" - + "\0\u0344\0\u0344\0\u0344\0\u0344\0\u0344\0\u0344\0\u0344\0\u0344" - + "\0\u2484\0\u0344\0\u0344\0\u0344\0\u0344\0\u0344\0\u0344\0\u24d0" - + "\0\u0344\0\u1138\0\u0344\0\u1184\0\u0344\0\u11d0\0\u0344\0\u0344" - + "\0\u1268\0\u251c\0\u2568\0\u25b4\0\u2600\0\u264c\0\u2698\0\u26e4" - + "\0\u2730\0\u0344\0\u0344\0\u2484\0\u24d0\0\u277c\0\u27c8\0\u0344" - + "\0\u2814\0\u2860\0\u0344\0\u0344\0\u0344\0\u28ac\0\u0344\0\u28f8" - + "\0\u28f8\0\u0344\0\u2944\0\u180c\0\u2990\0\u29dc\0\u04c0\0\u2a28" - + "\0\u2a74\0\u2ac0\0\u2b0c\0\u2b58\0\u2ba4\0\u2bf0\0\u2c3c\0\u2c88" - + "\0\u2cd4\0\u2d20\0\u04c0\0\u2d6c\0\u2db8\0\u2e04\0\u2e50\0\u04c0" - + "\0\u2e9c\0\u2ee8\0\u2f34\0\u2f80\0\u04c0\0\u2fcc\0\u3018\0\u3064" - + "\0\u30b0\0\u30fc\0\u3148\0\u04c0\0\u3194\0\u31e0\0\u322c\0\u3278" - + "\0\u32c4\0\u3310\0\u335c\0\u33a8\0\u33f4\0\u3440\0\u04c0\0\u348c" - + "\0\u04c0\0\u34d8\0\u04c0\0\u3524\0\u3570\0\u251c\0\u0344\0\u0344" - + "\0\u0344\0\u35bc\0\u0344\0\u3608\0\u3654\0\u36a0\0\u0344\0\u0344" - + "\0\u36ec\0\u0344\0\u3738\0\u3784\0\u37d0\0\u381c\0\u3868\0\u38b4" - + "\0\u04c0\0\u04c0\0\u3900\0\u394c\0\u04c0\0\u3998\0\u39e4\0\u3a30" - + "\0\u3a7c\0\u3ac8\0\u3b14\0\u3b60\0\u3bac\0\u3bf8\0\u3c44\0\u04c0" - + "\0\u04c0\0\u3c90\0\u04c0\0\u3cdc\0\u3d28\0\u3d74\0\u3dc0\0\u3e0c" - + "\0\u3e58\0\u3ea4\0\u3ef0\0\u3f3c\0\u04c0\0\u3f88\0\u3fd4\0\u4020" - + "\0\u406c\0\u40b8\0\u04c0\0\u4104\0\u0344\0\u2484\0\u4150\0\u0344" - + "\0\u0344\0\u419c\0\u41e8\0\u4234\0\u04c0\0\u4280\0\u42cc\0\u4318" - + "\0\u04c0\0\u4364\0\u04c0\0\u04c0\0\u43b0\0\u04c0\0\u43fc\0\u04c0" - + "\0\u4448\0\u4494\0\u44e0\0\u452c\0\u04c0\0\u4578\0\u45c4\0\u4610" - + "\0\u465c\0\u46a8\0\u46f4\0\u4740\0\u478c\0\u47d8\0\u04c0\0\u4824" - + "\0\u4870\0\u48bc\0\u4908\0\u4954\0\u49a0\0\u49ec\0\u4a38\0\u4a84" - + "\0\u4ad0\0\u4b1c\0\u04c0\0\u4b68\0\u04c0\0\u04c0\0\u4bb4\0\u04c0" - + "\0\u4c00\0\u04c0\0\u4c4c\0\u4c98\0\u4ce4\0\u04c0\0\u4d30\0\u4d7c" - + "\0\u4dc8\0\u04c0\0\u4e14\0\u4e60\0\u4eac\0\u4ef8\0\u04c0\0\u4f44" - + "\0\u4f90\0\u4fdc\0\u5028\0\u04c0\0\u5074\0\u04c0\0\u50c0\0\u510c" - + "\0\u5158\0\u51a4\0\u51f0\0\u523c\0\u5288\0\u52d4\0\u04c0\0\u04c0" - + "\0\u5320\0\u04c0\0\u04c0\0\u536c\0\u53b8\0\u5404\0\u5450\0\u04c0" - + "\0\u04c0\0\u04c0\0\u549c\0\u54e8\0\u5534\0\u04c0\0\u5580\0\u55cc" - + "\0\u5618\0\u04c0\0\u5664\0\u56b0\0\u56fc\0\u04c0\0\u5748\0\u04c0" - + "\0\u5794\0\u04c0\0\u04c0\0\u0344\0\u0344\0\u57e0\0\u04c0\0\u04c0" - + "\0\u582c\0\u5878\0\u58c4\0\u5910\0\u595c\0\u1774"; - - private static int[] zzUnpackRowMap() { - int[] result = new int[446]; - int offset = 0; - offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result); - return result; - } - - private static int zzUnpackRowMap(String packed, int offset, int[] result) { - int i = 0; /* index in packed string */ - - int j = offset; /* index in unpacked array */ - - int l = packed.length(); - while (i < l) { - int high = packed.charAt(i++) << 16; - result[j++] = high | packed.charAt(i++); - } - return j; - } - - /** - * The transition table of the DFA - */ - private static final int[] ZZ_TRANS = zzUnpackTrans(); - - private static final String ZZ_TRANS_PACKED_0 - = "\1\14\1\15\1\16\1\17\1\20\1\21\1\22\1\14" - + "\1\22\1\23\1\24\1\17\1\25\1\26\1\27\1\30" - + "\1\22\1\31\1\14\1\32\1\33\4\22\1\34\1\35" - + "\1\36\1\37\1\40\2\22\1\41\2\31\1\22\1\42" - + "\1\43\1\14\1\44\1\45\1\46\1\47\1\22\1\50" - + "\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\22" - + "\1\60\1\22\1\61\2\22\1\62\1\63\1\64\1\65" - + "\1\66\1\67\1\70\1\71\1\72\1\73\1\74\1\75" - + "\1\76\1\77\1\100\1\101\1\22\1\14\1\102\1\103" - + "\1\104\30\102\1\105\12\102\1\106\45\102\1\107\1\110" - + "\1\111\31\107\1\105\11\107\1\106\45\107\1\14\1\112" - + "\1\113\1\114\1\115\3\14\1\116\2\14\1\114\2\14" - + "\1\117\2\116\4\14\4\116\5\14\3\116\2\14\2\116" - + "\3\14\26\116\2\14\1\120\46\14\1\121\44\14\1\122" - + "\14\14\1\112\1\113\1\114\4\14\1\123\2\14\1\114" - + "\3\14\2\123\2\14\1\124\1\14\4\123\5\14\3\123" - + "\2\14\2\123\3\14\26\123\2\14\1\125\46\14\1\126" - + "\44\14\1\127\13\14\1\130\1\112\1\113\26\130\1\131" - + "\63\130\1\132\1\133\12\130\1\134\77\130\1\112\1\113" - + "\7\130\1\135\65\130\1\136\13\130\1\137\1\110\1\111" - + "\43\137\1\140\1\141\44\137\116\0\1\16\114\0\1\17" - + "\7\0\1\17\104\0\1\142\1\143\24\0\1\144\113\0" - + "\1\145\67\0\3\22\7\0\2\22\3\0\4\22\4\0" - + "\10\22\3\0\26\22\14\0\1\22\12\0\1\146\1\147" - + "\6\0\1\150\13\0\1\150\3\0\2\150\33\0\1\151" - + "\25\0\1\152\1\0\1\153\4\0\2\152\4\0\4\152" - + "\1\0\1\154\3\0\3\152\2\0\2\152\3\0\26\152" - + "\2\0\1\155\45\0\1\156\76\0\1\157\14\0\1\160" - + "\77\0\1\161\13\0\1\162\100\0\1\163\105\0\1\150" - + "\7\0\1\31\13\0\1\31\3\0\2\31\2\164\101\0" - + "\1\165\72\0\1\150\7\0\1\166\13\0\1\167\2\170" - + "\1\0\1\171\1\172\2\164\55\0\3\22\7\0\2\22" - + "\3\0\4\22\4\0\10\22\3\0\2\22\1\173\3\22" - + "\1\174\2\22\1\175\1\176\13\22\14\0\1\22\7\0" - + "\3\22\7\0\2\22\3\0\4\22\4\0\1\22\1\177" - + "\6\22\3\0\2\22\1\200\11\22\1\201\11\22\14\0" - + "\1\22\33\0\1\202\12\0\1\203\54\0\3\22\7\0" - + "\2\22\3\0\4\22\4\0\10\22\3\0\1\22\1\204" - + "\24\22\14\0\1\22\7\0\3\22\7\0\2\22\3\0" - + "\4\22\4\0\7\22\1\205\3\0\26\22\14\0\1\22" - + "\7\0\3\22\7\0\2\22\3\0\4\22\4\0\10\22" - + "\3\0\5\22\1\206\20\22\14\0\1\22\7\0\3\22" - + "\7\0\2\22\3\0\4\22\4\0\10\22\3\0\2\22" - + "\1\207\3\22\1\210\5\22\1\211\11\22\14\0\1\22" - + "\7\0\3\22\7\0\2\22\3\0\4\22\4\0\7\22" - + "\1\212\3\0\10\22\1\213\1\22\1\214\2\22\1\215" - + "\10\22\14\0\1\22\7\0\3\22\7\0\2\22\3\0" - + "\4\22\4\0\10\22\3\0\22\22\1\216\3\22\14\0" - + "\1\22\7\0\3\22\7\0\2\22\3\0\4\22\4\0" - + "\7\22\1\217\3\0\2\22\1\220\7\22\1\221\13\22" - + "\14\0\1\22\7\0\3\22\7\0\2\22\3\0\4\22" - + "\4\0\10\22\3\0\1\22\1\222\14\22\1\223\1\22" - + "\1\224\5\22\14\0\1\22\7\0\3\22\7\0\2\22" - + "\3\0\4\22\4\0\3\22\1\225\4\22\3\0\5\22" - + "\1\226\1\22\1\227\11\22\1\230\4\22\14\0\1\22" - + "\7\0\3\22\7\0\2\22\3\0\4\22\4\0\10\22" - + "\3\0\5\22\1\231\1\22\1\232\16\22\14\0\1\22" - + "\7\0\3\22\7\0\2\22\3\0\4\22\4\0\7\22" - + "\1\233\3\0\6\22\1\234\11\22\1\235\5\22\14\0" - + "\1\22\7\0\3\22\7\0\2\22\3\0\4\22\4\0" - + "\10\22\3\0\11\22\1\236\4\22\1\237\7\22\14\0" - + "\1\22\7\0\3\22\7\0\2\22\3\0\4\22\4\0" - + "\10\22\3\0\1\22\1\240\1\241\7\22\1\242\13\22" - + "\14\0\1\22\7\0\3\22\7\0\2\22\3\0\4\22" - + "\4\0\10\22\3\0\2\22\1\243\3\22\1\244\17\22" - + "\14\0\1\22\7\0\3\22\7\0\2\22\3\0\4\22" - + "\4\0\7\22\1\245\3\0\26\22\14\0\1\22\7\0" - + "\3\22\7\0\2\22\3\0\4\22\4\0\10\22\3\0" - + "\7\22\1\246\16\22\14\0\1\22\7\0\3\22\7\0" - + "\2\22\3\0\4\22\4\0\10\22\3\0\2\22\1\247" - + "\23\22\14\0\1\22\33\0\1\250\52\0\1\251\40\0" - + "\1\252\53\0\1\253\37\0\1\254\113\0\1\255\61\0" - + "\1\102\2\0\30\102\1\0\12\102\1\0\45\102\2\0" - + "\1\104\111\0\1\256\3\0\27\256\1\257\1\260\1\256" - + "\1\261\1\256\1\262\5\256\1\263\1\256\1\264\1\265" - + "\5\256\1\266\1\267\1\256\1\270\30\256\1\0\1\107" - + "\2\0\31\107\1\0\11\107\1\0\45\107\2\0\1\111" - + "\113\0\1\113\114\0\1\114\7\0\1\114\116\0\1\271" - + "\105\0\2\272\3\0\1\272\1\0\4\272\2\0\4\272" - + "\1\0\1\273\2\0\10\272\3\0\26\272\16\0\1\274" - + "\2\0\30\274\1\275\60\274\10\0\2\276\3\0\1\276" - + "\1\0\4\276\2\0\4\276\1\0\1\277\2\0\10\276" - + "\3\0\26\276\34\0\1\300\75\0\1\301\2\0\30\301" - + "\1\302\1\303\57\301\31\0\1\304\64\0\1\133\126\0" - + "\1\305\102\0\1\306\3\0\1\307\3\0\1\310\2\0" - + "\2\307\2\0\1\311\1\0\4\307\5\0\3\307\2\0" - + "\2\307\3\0\26\307\2\0\1\312\13\0\1\137\2\0" - + "\43\137\2\0\44\137\1\313\3\0\32\313\1\314\1\313" - + "\1\262\5\313\1\263\1\313\1\264\1\265\5\313\1\266" - + "\1\267\1\313\1\315\27\313\1\316\1\0\1\142\1\317" - + "\1\320\111\142\5\321\1\322\106\321\11\0\1\323\123\0" - + "\1\150\13\0\1\150\3\0\2\150\2\164\57\0\2\152" - + "\3\0\1\152\1\0\4\152\2\0\4\152\4\0\10\152" - + "\3\0\26\152\50\0\1\324\113\0\1\325\77\0\1\326" - + "\13\0\1\327\76\0\1\330\3\0\1\331\13\0\1\331" - + "\3\0\2\331\2\0\1\330\100\0\1\332\72\0\1\150" - + "\7\0\1\166\13\0\1\166\3\0\2\166\2\164\60\0" - + "\1\150\7\0\1\166\13\0\1\167\3\0\1\171\1\172" - + "\2\164\67\0\2\333\3\0\3\333\5\0\1\334\2\0" - + "\5\333\3\0\1\333\1\0\1\333\1\0\1\333\6\0" - + "\1\333\41\0\1\150\7\0\1\166\13\0\1\172\3\0" - + "\2\172\2\164\60\0\1\150\7\0\1\166\13\0\1\335" - + "\3\0\2\335\2\164\55\0\3\22\7\0\2\22\3\0" - + "\4\22\4\0\10\22\3\0\14\22\1\336\11\22\14\0" - + "\1\22\7\0\3\22\7\0\2\22\3\0\4\22\4\0" - + "\10\22\3\0\1\22\1\337\24\22\14\0\1\22\7\0" - + "\3\22\7\0\2\22\3\0\4\22\4\0\10\22\3\0" - + "\7\22\1\340\16\22\14\0\1\22\7\0\3\22\7\0" - + "\2\22\3\0\4\22\4\0\10\22\3\0\7\22\1\341" - + "\16\22\14\0\1\22\7\0\3\22\7\0\2\22\3\0" - + "\4\22\4\0\10\22\3\0\10\22\1\342\15\22\14\0" - + "\1\22\7\0\3\22\7\0\2\22\3\0\4\22\4\0" - + "\10\22\3\0\4\22\1\343\21\22\14\0\1\22\7\0" - + "\3\22\7\0\2\22\3\0\4\22\4\0\10\22\3\0" - + "\5\22\1\344\20\22\14\0\1\22\7\0\3\22\7\0" - + "\2\22\3\0\4\22\4\0\7\22\1\345\3\0\26\22" - + "\14\0\1\22\7\0\3\22\7\0\2\22\3\0\4\22" - + "\4\0\10\22\3\0\10\22\1\346\15\22\14\0\1\22" - + "\7\0\3\22\7\0\2\22\3\0\4\22\4\0\10\22" - + "\3\0\5\22\1\347\2\22\1\350\15\22\14\0\1\22" - + "\7\0\3\22\7\0\2\22\3\0\4\22\4\0\10\22" - + "\3\0\7\22\1\351\16\22\14\0\1\22\7\0\3\22" - + "\7\0\2\22\3\0\4\22\4\0\10\22\3\0\2\22" - + "\1\352\23\22\14\0\1\22\7\0\3\22\7\0\2\22" - + "\3\0\4\22\4\0\10\22\3\0\10\22\1\353\15\22" - + "\14\0\1\22\7\0\3\22\7\0\2\22\3\0\4\22" - + "\4\0\10\22\3\0\2\22\1\354\23\22\14\0\1\22" - + "\7\0\3\22\7\0\2\22\3\0\4\22\4\0\10\22" - + "\3\0\17\22\1\355\6\22\14\0\1\22\7\0\3\22" - + "\7\0\2\22\3\0\4\22\4\0\10\22\3\0\11\22" - + "\1\356\14\22\14\0\1\22\7\0\3\22\7\0\2\22" - + "\3\0\4\22\4\0\7\22\1\357\3\0\26\22\14\0" - + "\1\22\7\0\3\22\7\0\2\22\3\0\4\22\4\0" - + "\10\22\3\0\15\22\1\360\10\22\14\0\1\22\7\0" - + "\3\22\7\0\2\22\3\0\4\22\4\0\10\22\3\0" - + "\10\22\1\361\10\22\1\362\4\22\14\0\1\22\7\0" - + "\3\22\7\0\2\22\3\0\4\22\4\0\10\22\3\0" - + "\14\22\1\363\11\22\14\0\1\22\7\0\3\22\7\0" - + "\2\22\3\0\4\22\4\0\10\22\3\0\12\22\1\364" - + "\5\22\1\365\5\22\14\0\1\22\7\0\3\22\7\0" - + "\2\22\3\0\4\22\4\0\10\22\3\0\1\22\1\366" - + "\7\22\1\367\14\22\14\0\1\22\7\0\3\22\7\0" - + "\2\22\3\0\4\22\4\0\10\22\3\0\17\22\1\370" - + "\6\22\14\0\1\22\7\0\3\22\7\0\2\22\3\0" - + "\4\22\4\0\10\22\3\0\5\22\1\371\2\22\1\372" - + "\15\22\14\0\1\22\7\0\3\22\7\0\2\22\3\0" - + "\4\22\4\0\10\22\3\0\17\22\1\373\6\22\14\0" - + "\1\22\7\0\3\22\7\0\2\22\3\0\4\22\4\0" - + "\7\22\1\374\3\0\26\22\14\0\1\22\7\0\3\22" - + "\7\0\2\22\3\0\4\22\4\0\10\22\3\0\13\22" - + "\1\375\12\22\14\0\1\22\7\0\3\22\7\0\2\22" - + "\3\0\4\22\4\0\3\22\1\376\4\22\3\0\14\22" - + "\1\377\11\22\14\0\1\22\7\0\3\22\7\0\2\22" - + "\3\0\4\22\4\0\10\22\3\0\7\22\1\u0100\16\22" - + "\14\0\1\22\7\0\3\22\7\0\2\22\3\0\4\22" - + "\4\0\10\22\3\0\10\22\1\u0101\15\22\14\0\1\22" - + "\7\0\3\22\7\0\2\22\3\0\4\22\4\0\10\22" - + "\3\0\11\22\1\u0102\14\22\14\0\1\22\7\0\3\22" - + "\7\0\2\22\3\0\4\22\4\0\10\22\3\0\6\22" - + "\1\u0103\2\22\1\u0104\14\22\14\0\1\22\7\0\3\22" - + "\7\0\2\22\3\0\4\22\4\0\10\22\3\0\4\22" - + "\1\u0105\21\22\14\0\1\22\7\0\3\22\7\0\2\22" - + "\3\0\4\22\4\0\10\22\3\0\1\u0106\25\22\14\0" - + "\1\22\7\0\3\22\7\0\2\22\3\0\4\22\4\0" - + "\10\22\3\0\1\22\1\u0107\24\22\14\0\1\22\7\0" - + "\3\22\7\0\2\22\3\0\4\22\4\0\10\22\3\0" - + "\11\22\1\u0108\14\22\14\0\1\22\7\0\3\22\7\0" - + "\2\22\3\0\4\22\4\0\10\22\3\0\10\22\1\u0109" - + "\15\22\14\0\1\22\7\0\3\22\7\0\2\22\3\0" - + "\4\22\4\0\3\22\1\u010a\4\22\3\0\26\22\14\0" - + "\1\22\7\0\3\22\7\0\2\22\3\0\4\22\4\0" - + "\10\22\3\0\25\22\1\u010b\14\0\1\22\21\0\2\u010c" - + "\3\0\3\u010c\5\0\1\u010c\2\0\5\u010c\3\0\1\u010c" - + "\1\0\1\u010c\1\0\1\u010c\6\0\1\u010c\50\0\2\u010d" - + "\3\0\3\u010d\5\0\1\u010d\2\0\5\u010d\3\0\1\u010d" - + "\1\0\1\u010d\1\0\1\u010d\6\0\1\u010d\30\0\1\u010e" - + "\2\0\30\u010e\1\302\1\0\57\u010e\1\303\2\0\30\303" - + "\1\u010f\60\303\16\0\1\u0110\113\0\1\u0111\105\0\1\u0112" - + "\6\0\2\u0112\4\0\4\u0112\5\0\3\u0112\2\0\2\u0112" - + "\3\0\26\u0112\2\0\1\u0113\23\0\2\307\3\0\1\307" - + "\1\0\4\307\2\0\4\307\4\0\10\307\3\0\26\307" - + "\33\0\1\u0114\6\0\1\u0115\77\0\1\u0116\6\0\2\u0116" - + "\4\0\4\u0116\5\0\3\u0116\2\0\2\u0116\3\0\26\u0116" - + "\2\0\1\u0117\62\0\1\u0118\46\0\1\320\111\0\5\321" - + "\1\u0119\106\321\4\0\1\320\1\322\140\0\1\u011a\102\0" - + "\1\331\13\0\1\331\3\0\2\331\71\0\2\u011b\3\0" - + "\3\u011b\5\0\1\u011b\2\0\5\u011b\3\0\1\u011b\1\0" - + "\1\u011b\1\0\1\u011b\6\0\1\u011b\41\0\1\150\7\0" - + "\1\166\13\0\1\u011c\3\0\2\u011c\2\164\55\0\3\22" - + "\7\0\2\22\3\0\4\22\4\0\10\22\3\0\5\22" - + "\1\u011d\20\22\14\0\1\22\7\0\3\22\7\0\2\22" - + "\3\0\4\22\4\0\10\22\3\0\2\22\1\u011e\23\22" - + "\14\0\1\22\7\0\3\22\7\0\2\22\3\0\4\22" - + "\4\0\10\22\3\0\4\22\1\u011f\21\22\14\0\1\22" - + "\7\0\3\22\7\0\2\22\3\0\4\22\4\0\7\22" - + "\1\u0120\3\0\26\22\14\0\1\22\7\0\3\22\7\0" - + "\2\22\3\0\4\22\4\0\10\22\3\0\16\22\1\u0121" - + "\7\22\14\0\1\22\7\0\3\22\7\0\2\22\3\0" - + "\4\22\4\0\7\22\1\u0122\3\0\26\22\14\0\1\22" - + "\7\0\3\22\7\0\2\22\3\0\4\22\4\0\10\22" - + "\3\0\2\22\1\u0123\23\22\14\0\1\22\7\0\3\22" - + "\7\0\2\22\3\0\4\22\4\0\10\22\3\0\12\22" - + "\1\u0124\13\22\14\0\1\22\7\0\3\22\7\0\2\22" - + "\3\0\4\22\4\0\7\22\1\u0125\3\0\26\22\14\0" - + "\1\22\7\0\3\22\7\0\2\22\3\0\4\22\4\0" - + "\10\22\3\0\4\22\1\u0126\21\22\14\0\1\22\7\0" - + "\3\22\7\0\2\22\3\0\4\22\4\0\10\22\3\0" - + "\5\22\1\u0127\2\22\1\u0128\15\22\14\0\1\22\7\0" - + "\3\22\7\0\2\22\3\0\4\22\4\0\10\22\3\0" - + "\5\22\1\u0129\20\22\14\0\1\22\7\0\3\22\7\0" - + "\2\22\3\0\4\22\4\0\10\22\3\0\10\22\1\u012a" - + "\15\22\14\0\1\22\7\0\3\22\7\0\2\22\3\0" - + "\4\22\4\0\7\22\1\u012b\3\0\26\22\14\0\1\22" - + "\7\0\3\22\7\0\2\22\3\0\4\22\4\0\10\22" - + "\3\0\10\22\1\u012c\15\22\14\0\1\22\7\0\3\22" - + "\7\0\2\22\3\0\4\22\4\0\10\22\3\0\1\22" - + "\1\u012d\24\22\14\0\1\22\7\0\3\22\7\0\2\22" - + "\3\0\4\22\4\0\10\22\3\0\11\22\1\u012e\14\22" - + "\14\0\1\22\7\0\3\22\7\0\2\22\3\0\4\22" - + "\4\0\7\22\1\u012f\3\0\26\22\14\0\1\22\7\0" - + "\3\22\7\0\2\22\3\0\4\22\4\0\10\22\3\0" - + "\14\22\1\u0130\11\22\14\0\1\22\7\0\3\22\7\0" - + "\2\22\3\0\4\22\4\0\7\22\1\u0131\3\0\26\22" - + "\14\0\1\22\7\0\3\22\7\0\2\22\3\0\4\22" - + "\4\0\10\22\3\0\6\22\1\u0132\17\22\14\0\1\22" - + "\7\0\3\22\7\0\2\22\3\0\4\22\4\0\10\22" - + "\3\0\5\22\1\u0133\20\22\14\0\1\22\7\0\3\22" - + "\7\0\2\22\3\0\4\22\4\0\7\22\1\u0134\3\0" - + "\26\22\14\0\1\22\7\0\3\22\7\0\2\22\3\0" - + "\4\22\4\0\10\22\3\0\10\22\1\u0135\15\22\14\0" - + "\1\22\7\0\3\22\7\0\2\22\3\0\4\22\4\0" - + "\7\22\1\u0136\3\0\26\22\14\0\1\22\7\0\3\22" - + "\7\0\2\22\3\0\4\22\4\0\10\22\3\0\6\22" - + "\1\u0137\5\22\1\u0138\11\22\14\0\1\22\7\0\3\22" - + "\7\0\2\22\3\0\4\22\4\0\7\22\1\u0139\3\0" - + "\26\22\14\0\1\22\7\0\3\22\7\0\2\22\3\0" - + "\4\22\4\0\10\22\3\0\2\22\1\u013a\23\22\14\0" - + "\1\22\7\0\3\22\7\0\2\22\3\0\4\22\4\0" - + "\7\22\1\u013b\3\0\26\22\14\0\1\22\7\0\3\22" - + "\7\0\2\22\3\0\4\22\4\0\10\22\3\0\2\22" - + "\1\u013c\23\22\14\0\1\22\7\0\3\22\7\0\2\22" - + "\3\0\4\22\4\0\10\22\3\0\16\22\1\u013d\7\22" - + "\14\0\1\22\7\0\3\22\7\0\2\22\3\0\4\22" - + "\4\0\10\22\3\0\14\22\1\u013e\11\22\14\0\1\22" - + "\7\0\3\22\7\0\2\22\3\0\4\22\4\0\10\22" - + "\3\0\10\22\1\u013f\15\22\14\0\1\22\7\0\3\22" - + "\7\0\2\22\3\0\4\22\4\0\10\22\3\0\22\22" - + "\1\u0140\3\22\14\0\1\22\7\0\3\22\7\0\2\22" - + "\3\0\4\22\4\0\10\22\3\0\3\22\1\u0141\22\22" - + "\14\0\1\22\7\0\3\22\7\0\2\22\3\0\4\22" - + "\4\0\10\22\3\0\14\22\1\u0142\11\22\14\0\1\22" - + "\7\0\3\22\7\0\2\22\3\0\4\22\4\0\10\22" - + "\3\0\13\22\1\u0143\12\22\14\0\1\22\7\0\3\22" - + "\7\0\2\22\3\0\4\22\4\0\10\22\3\0\11\22" - + "\1\u0144\14\22\14\0\1\22\21\0\2\u0145\3\0\3\u0145" - + "\5\0\1\u0145\2\0\5\u0145\3\0\1\u0145\1\0\1\u0145" - + "\1\0\1\u0145\6\0\1\u0145\50\0\2\u0146\3\0\3\u0146" - + "\5\0\1\u0146\2\0\5\u0146\3\0\1\u0146\1\0\1\u0146" - + "\1\0\1\u0146\6\0\1\u0146\31\0\2\u0147\5\0\2\u0112" - + "\1\0\1\u0147\1\0\1\u0112\1\u0148\4\u0112\2\0\4\u0112" - + "\4\0\10\u0112\3\0\26\u0112\33\0\1\u0149\123\0\1\u014a" - + "\76\0\2\u0116\3\0\1\u0116\1\0\4\u0116\2\0\4\u0116" - + "\4\0\10\u0116\3\0\26\u0116\16\0\4\321\1\320\1\u0119" - + "\106\321\20\0\2\u014b\3\0\3\u014b\5\0\1\u014b\2\0" - + "\5\u014b\3\0\1\u014b\1\0\1\u014b\1\0\1\u014b\6\0" - + "\1\u014b\41\0\1\150\7\0\1\166\13\0\1\u014c\3\0" - + "\2\u014c\2\164\55\0\3\22\7\0\2\22\3\0\4\22" - + "\4\0\7\22\1\u014d\3\0\26\22\14\0\1\22\7\0" - + "\3\22\7\0\2\22\3\0\4\22\4\0\10\22\3\0" - + "\14\22\1\u014e\11\22\14\0\1\22\7\0\3\22\7\0" - + "\2\22\3\0\4\22\4\0\10\22\3\0\10\22\1\u014f" - + "\15\22\14\0\1\22\7\0\3\22\7\0\2\22\3\0" - + "\4\22\4\0\10\22\3\0\7\22\1\u0150\16\22\14\0" - + "\1\22\7\0\3\22\7\0\2\22\3\0\4\22\4\0" - + "\10\22\3\0\3\22\1\u0151\22\22\14\0\1\22\7\0" - + "\3\22\7\0\2\22\3\0\4\22\4\0\10\22\3\0" - + "\1\22\1\u0152\24\22\14\0\1\22\7\0\3\22\7\0" - + "\2\22\3\0\4\22\4\0\10\22\3\0\16\22\1\u0153" - + "\7\22\14\0\1\22\7\0\3\22\7\0\2\22\3\0" - + "\4\22\4\0\10\22\3\0\10\22\1\u0154\15\22\14\0" - + "\1\22\7\0\3\22\7\0\2\22\3\0\4\22\4\0" - + "\10\22\3\0\11\22\1\u0155\14\22\14\0\1\22\7\0" - + "\3\22\7\0\2\22\3\0\4\22\4\0\10\22\3\0" - + "\5\22\1\u0156\20\22\14\0\1\22\7\0\3\22\7\0" - + "\2\22\3\0\4\22\4\0\10\22\3\0\11\22\1\u0157" - + "\14\22\14\0\1\22\7\0\3\22\7\0\2\22\3\0" - + "\4\22\4\0\10\22\3\0\1\22\1\u0158\24\22\14\0" - + "\1\22\7\0\3\22\7\0\2\22\3\0\4\22\4\0" - + "\10\22\3\0\4\22\1\u0159\21\22\14\0\1\22\7\0" - + "\3\22\7\0\2\22\3\0\4\22\4\0\10\22\3\0" - + "\1\22\1\u015a\24\22\14\0\1\22\7\0\3\22\7\0" - + "\2\22\3\0\4\22\4\0\10\22\3\0\22\22\1\u015b" - + "\3\22\14\0\1\22\7\0\3\22\7\0\2\22\3\0" - + "\4\22\4\0\10\22\3\0\5\22\1\u015c\20\22\14\0" - + "\1\22\7\0\3\22\7\0\2\22\3\0\4\22\4\0" - + "\10\22\3\0\15\22\1\u015d\10\22\14\0\1\22\7\0" - + "\3\22\7\0\2\22\3\0\4\22\4\0\10\22\3\0" - + "\6\22\1\u015e\17\22\14\0\1\22\7\0\3\22\7\0" - + "\2\22\3\0\4\22\4\0\10\22\3\0\2\22\1\u015f" - + "\23\22\14\0\1\22\7\0\3\22\7\0\2\22\3\0" - + "\4\22\4\0\10\22\3\0\1\22\1\u0160\24\22\14\0" - + "\1\22\7\0\3\22\7\0\2\22\3\0\4\22\4\0" - + "\10\22\3\0\1\22\1\u0161\24\22\14\0\1\22\7\0" - + "\3\22\7\0\2\22\3\0\4\22\4\0\7\22\1\u0162" - + "\3\0\26\22\14\0\1\22\7\0\3\22\7\0\2\22" - + "\3\0\4\22\4\0\3\22\1\u0163\4\22\3\0\26\22" - + "\14\0\1\22\7\0\3\22\7\0\2\22\3\0\4\22" - + "\4\0\10\22\3\0\12\22\1\u0164\13\22\14\0\1\22" - + "\7\0\3\22\7\0\2\22\3\0\4\22\4\0\10\22" - + "\3\0\10\22\1\u0165\15\22\14\0\1\22\7\0\3\22" - + "\7\0\2\22\3\0\4\22\4\0\10\22\3\0\21\22" - + "\1\u0166\4\22\14\0\1\22\7\0\3\22\7\0\2\22" - + "\3\0\4\22\4\0\7\22\1\u0167\3\0\26\22\14\0" - + "\1\22\7\0\3\22\7\0\2\22\3\0\4\22\4\0" - + "\7\22\1\u0168\3\0\26\22\14\0\1\22\7\0\3\22" - + "\7\0\2\22\3\0\4\22\4\0\10\22\3\0\2\22" - + "\1\u0169\23\22\14\0\1\22\7\0\3\22\7\0\2\22" - + "\3\0\4\22\4\0\10\22\3\0\2\22\1\u016a\23\22" - + "\14\0\1\22\7\0\3\22\7\0\2\22\3\0\4\22" - + "\4\0\10\22\3\0\11\22\1\u016b\14\22\14\0\1\22" - + "\7\0\3\22\7\0\2\22\3\0\4\22\4\0\10\22" - + "\3\0\7\22\1\u016c\16\22\14\0\1\22\2\0\2\u0147" - + "\10\0\1\u0147\2\0\1\u0148\123\0\1\u016d\105\0\2\u016e" - + "\3\0\3\u016e\5\0\1\u016e\2\0\5\u016e\3\0\1\u016e" - + "\1\0\1\u016e\1\0\1\u016e\6\0\1\u016e\41\0\1\150" - + "\7\0\1\166\13\0\1\u016f\3\0\2\u016f\2\164\55\0" - + "\3\22\7\0\2\22\3\0\4\22\4\0\10\22\3\0" - + "\14\22\1\u0170\11\22\14\0\1\22\7\0\3\22\7\0" - + "\2\22\3\0\4\22\4\0\10\22\3\0\11\22\1\u0171" - + "\14\22\14\0\1\22\7\0\3\22\7\0\2\22\3\0" - + "\4\22\4\0\10\22\3\0\13\22\1\u0172\12\22\14\0" - + "\1\22\7\0\3\22\7\0\2\22\3\0\4\22\4\0" - + "\10\22\3\0\7\22\1\u0173\16\22\14\0\1\22\7\0" - + "\3\22\7\0\2\22\3\0\4\22\4\0\10\22\3\0" - + "\7\22\1\u0174\16\22\14\0\1\22\7\0\3\22\7\0" - + "\2\22\3\0\4\22\4\0\10\22\3\0\4\22\1\u0175" - + "\21\22\14\0\1\22\7\0\3\22\7\0\2\22\3\0" - + "\4\22\4\0\10\22\3\0\16\22\1\u0176\7\22\14\0" - + "\1\22\7\0\3\22\7\0\2\22\3\0\4\22\4\0" - + "\10\22\3\0\11\22\1\u0177\14\22\14\0\1\22\7\0" - + "\3\22\7\0\2\22\3\0\4\22\4\0\7\22\1\u0178" - + "\3\0\26\22\14\0\1\22\7\0\3\22\7\0\2\22" - + "\3\0\4\22\4\0\10\22\3\0\17\22\1\u0179\6\22" - + "\14\0\1\22\7\0\3\22\7\0\2\22\3\0\4\22" - + "\4\0\3\22\1\u017a\4\22\3\0\26\22\14\0\1\22" - + "\7\0\3\22\7\0\2\22\3\0\4\22\4\0\10\22" - + "\3\0\7\22\1\u017b\16\22\14\0\1\22\7\0\3\22" - + "\7\0\2\22\3\0\4\22\4\0\3\22\1\u017c\4\22" - + "\3\0\7\22\1\u017d\16\22\14\0\1\22\7\0\3\22" - + "\7\0\2\22\3\0\4\22\4\0\10\22\3\0\10\22" - + "\1\u017e\15\22\14\0\1\22\7\0\3\22\7\0\2\22" - + "\3\0\4\22\4\0\10\22\3\0\21\22\1\u017f\4\22" - + "\14\0\1\22\7\0\3\22\7\0\2\22\3\0\4\22" - + "\4\0\10\22\3\0\11\22\1\u0180\14\22\14\0\1\22" - + "\7\0\3\22\7\0\2\22\3\0\4\22\4\0\10\22" - + "\3\0\14\22\1\u0181\11\22\14\0\1\22\7\0\3\22" - + "\7\0\2\22\3\0\4\22\4\0\7\22\1\u0182\3\0" - + "\26\22\14\0\1\22\7\0\3\22\7\0\2\22\3\0" - + "\4\22\4\0\10\22\3\0\11\22\1\u0183\14\22\14\0" - + "\1\22\7\0\3\22\7\0\2\22\3\0\4\22\4\0" - + "\10\22\3\0\4\22\1\u0184\21\22\14\0\1\22\7\0" - + "\3\22\7\0\2\22\3\0\4\22\4\0\10\22\3\0" - + "\10\22\1\u0185\15\22\14\0\1\22\7\0\3\22\7\0" - + "\2\22\3\0\4\22\4\0\10\22\3\0\23\22\1\u0186" - + "\2\22\14\0\1\22\7\0\3\22\7\0\2\22\3\0" - + "\4\22\4\0\10\22\3\0\4\22\1\u0187\21\22\14\0" - + "\1\22\7\0\3\22\7\0\2\22\3\0\4\22\4\0" - + "\10\22\3\0\11\22\1\u0188\14\22\14\0\1\22\30\0" - + "\1\u0189\104\0\2\u018a\3\0\3\u018a\5\0\1\u018a\2\0" - + "\5\u018a\3\0\1\u018a\1\0\1\u018a\1\0\1\u018a\6\0" - + "\1\u018a\41\0\1\150\7\0\1\166\13\0\1\u018b\3\0" - + "\2\u018b\2\164\55\0\3\22\7\0\2\22\3\0\4\22" - + "\4\0\10\22\3\0\20\22\1\u018c\5\22\14\0\1\22" - + "\7\0\3\22\7\0\2\22\3\0\4\22\4\0\10\22" - + "\3\0\6\22\1\u018d\17\22\14\0\1\22\7\0\3\22" - + "\7\0\2\22\3\0\4\22\4\0\10\22\3\0\5\22" - + "\1\u018e\20\22\14\0\1\22\7\0\3\22\7\0\2\22" - + "\3\0\4\22\4\0\10\22\3\0\12\22\1\u018f\13\22" - + "\14\0\1\22\7\0\3\22\7\0\2\22\3\0\4\22" - + "\4\0\10\22\3\0\13\22\1\u0190\12\22\14\0\1\22" - + "\7\0\3\22\7\0\2\22\3\0\4\22\4\0\10\22" - + "\3\0\2\22\1\u0191\23\22\14\0\1\22\7\0\3\22" - + "\7\0\2\22\3\0\4\22\4\0\10\22\3\0\4\22" - + "\1\u0192\21\22\14\0\1\22\7\0\3\22\7\0\2\22" - + "\3\0\4\22\4\0\10\22\3\0\2\22\1\u0193\23\22" - + "\14\0\1\22\7\0\3\22\7\0\2\22\3\0\4\22" - + "\4\0\10\22\3\0\2\22\1\u0194\23\22\14\0\1\22" - + "\7\0\3\22\7\0\2\22\3\0\4\22\4\0\7\22" - + "\1\u0195\3\0\26\22\14\0\1\22\7\0\3\22\7\0" - + "\2\22\3\0\4\22\4\0\10\22\3\0\7\22\1\u0196" - + "\16\22\14\0\1\22\7\0\3\22\7\0\2\22\3\0" - + "\4\22\4\0\10\22\3\0\10\22\1\u0197\15\22\14\0" - + "\1\22\7\0\3\22\7\0\2\22\3\0\4\22\4\0" - + "\10\22\3\0\4\22\1\u0198\21\22\14\0\1\22\7\0" - + "\3\22\7\0\2\22\3\0\4\22\4\0\10\22\3\0" - + "\10\22\1\u0199\15\22\14\0\1\22\7\0\3\22\7\0" - + "\2\22\3\0\4\22\4\0\7\22\1\u019a\3\0\26\22" - + "\14\0\1\22\7\0\3\22\7\0\2\22\3\0\4\22" - + "\4\0\7\22\1\u019b\3\0\26\22\14\0\1\22\7\0" - + "\3\22\7\0\2\22\3\0\4\22\4\0\10\22\3\0" - + "\10\22\1\u019c\15\22\14\0\1\22\31\0\1\u019d\103\0" - + "\2\u019e\3\0\3\u019e\5\0\1\u019e\2\0\5\u019e\3\0" - + "\1\u019e\1\0\1\u019e\1\0\1\u019e\6\0\1\u019e\41\0" - + "\1\150\7\0\1\166\13\0\1\u019f\3\0\2\u019f\2\164" - + "\55\0\3\22\7\0\2\22\3\0\4\22\4\0\10\22" - + "\3\0\7\22\1\u01a0\16\22\14\0\1\22\7\0\3\22" - + "\7\0\2\22\3\0\4\22\4\0\7\22\1\u01a1\3\0" - + "\26\22\14\0\1\22\7\0\3\22\7\0\2\22\3\0" - + "\4\22\4\0\7\22\1\u01a2\3\0\26\22\14\0\1\22" - + "\7\0\3\22\7\0\2\22\3\0\4\22\4\0\10\22" - + "\3\0\4\22\1\u01a3\21\22\14\0\1\22\7\0\3\22" - + "\7\0\2\22\3\0\4\22\4\0\7\22\1\u01a4\3\0" - + "\26\22\14\0\1\22\7\0\3\22\7\0\2\22\3\0" - + "\4\22\4\0\10\22\3\0\4\22\1\u01a5\21\22\14\0" - + "\1\22\7\0\3\22\7\0\2\22\3\0\4\22\4\0" - + "\10\22\3\0\14\22\1\u01a6\11\22\14\0\1\22\7\0" - + "\3\22\7\0\2\22\3\0\4\22\4\0\10\22\3\0" - + "\7\22\1\u01a7\16\22\14\0\1\22\7\0\3\22\7\0" - + "\2\22\3\0\4\22\4\0\7\22\1\u01a8\3\0\26\22" - + "\14\0\1\22\7\0\3\22\7\0\2\22\3\0\4\22" - + "\4\0\7\22\1\u01a9\3\0\26\22\14\0\1\22\7\0" - + "\3\22\7\0\2\22\3\0\4\22\4\0\10\22\3\0" - + "\20\22\1\u01aa\5\22\14\0\1\22\30\0\1\u01ab\104\0" - + "\2\u01ac\3\0\3\u01ac\5\0\1\u01ac\2\0\5\u01ac\3\0" - + "\1\u01ac\1\0\1\u01ac\1\0\1\u01ac\6\0\1\u01ac\41\0" - + "\1\150\7\0\1\166\13\0\1\u01ad\3\0\2\u01ad\2\164" - + "\55\0\3\22\7\0\2\22\3\0\4\22\4\0\7\22" - + "\1\u01ae\3\0\26\22\14\0\1\22\7\0\3\22\7\0" - + "\2\22\3\0\4\22\4\0\10\22\3\0\6\22\1\u01af" - + "\17\22\14\0\1\22\7\0\3\22\7\0\2\22\3\0" - + "\4\22\4\0\7\22\1\u01b0\3\0\26\22\14\0\1\22" - + "\7\0\3\22\7\0\2\22\3\0\4\22\4\0\10\22" - + "\3\0\10\22\1\u01b1\15\22\14\0\1\22\7\0\3\22" - + "\7\0\2\22\3\0\4\22\4\0\10\22\3\0\13\22" - + "\1\u01b2\12\22\14\0\1\22\7\0\3\22\7\0\2\22" - + "\3\0\4\22\4\0\10\22\3\0\13\22\1\u01b3\12\22" - + "\14\0\1\22\25\0\1\u01b4\107\0\2\u01b5\3\0\3\u01b5" - + "\5\0\1\u01b5\2\0\5\u01b5\3\0\1\u01b5\1\0\1\u01b5" - + "\1\0\1\u01b5\6\0\1\u01b5\41\0\1\150\7\0\1\166" - + "\13\0\1\u01b6\3\0\2\u01b6\2\164\55\0\3\22\7\0" - + "\2\22\3\0\4\22\4\0\3\22\1\u01b7\4\22\3\0" - + "\26\22\14\0\1\22\7\0\3\22\7\0\2\22\3\0" - + "\4\22\4\0\10\22\3\0\5\22\1\u01b8\20\22\14\0" - + "\1\22\12\0\1\150\7\0\1\166\13\0\1\u01b9\3\0" - + "\2\u01b9\2\164\60\0\1\150\7\0\1\166\13\0\1\u01ba" - + "\3\0\2\u01ba\2\164\60\0\1\150\7\0\1\166\13\0" - + "\1\u01bb\3\0\2\u01bb\2\164\60\0\1\150\7\0\1\166" - + "\13\0\1\u01bc\3\0\2\u01bc\2\164\60\0\1\150\7\0" - + "\1\166\13\0\1\u01bd\3\0\2\u01bd\2\164\60\0\1\150" - + "\7\0\1\166\13\0\1\u01be\3\0\2\u01be\2\164\47\0"; - - private static int[] zzUnpackTrans() { - int[] result = new int[22952]; - int offset = 0; - offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result); - return result; - } - - private static int zzUnpackTrans(String packed, int offset, int[] result) { - int i = 0; /* index in packed string */ - - int j = offset; /* index in unpacked array */ - - int l = packed.length(); - while (i < l) { - int count = packed.charAt(i++); - int value = packed.charAt(i++); - value--; - do { - result[j++] = value; - } while (--count > 0); - } - return j; - } - - - /* error codes */ - private static final int ZZ_UNKNOWN_ERROR = 0; - - private static final int ZZ_NO_MATCH = 1; - - private static final int ZZ_PUSHBACK_2BIG = 2; - - /* error messages for the codes above */ - private static final String ZZ_ERROR_MSG[] = { - "Unkown internal scanner error", - "Error: could not match input", - "Error: pushback value was too large" - }; - - /** - * ZZ_ATTRIBUTE[aState] contains the attributes of state aState - */ - private static final int[] ZZ_ATTRIBUTE = zzUnpackAttribute(); - - private static final String ZZ_ATTRIBUTE_PACKED_0 - = "\13\0\1\11\1\1\1\11\13\1\3\11\1\1\2\11" - + "\4\1\1\11\21\1\7\11\4\1\1\11\2\1\2\11" - + "\3\1\1\11\1\1\1\11\3\1\2\11\1\1\1\11" - + "\2\1\1\11\1\1\2\11\2\1\1\11\2\1\1\11" - + "\2\1\1\11\1\1\1\0\2\11\1\1\1\11\1\1" - + "\1\11\2\1\2\11\1\1\2\11\1\1\2\11\1\0" - + "\3\1\1\0\11\1\2\11\44\1\11\11\1\1\6\11" - + "\1\1\1\11\1\0\1\11\1\0\1\11\1\0\2\11" - + "\1\0\1\1\4\0\1\1\2\0\2\11\4\1\1\11" - + "\2\0\3\11\1\1\1\11\1\0\1\1\1\11\61\1" - + "\3\0\3\11\1\0\1\11\2\0\1\1\2\11\1\0" - + "\1\11\52\1\1\11\2\0\2\11\1\0\42\1\1\0" - + "\33\1\1\0\23\1\1\0\15\1\1\0\10\1\2\11" - + "\11\1"; - - private static int[] zzUnpackAttribute() { - int[] result = new int[446]; - int offset = 0; - offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result); - return result; - } - - private static int zzUnpackAttribute(String packed, int offset, int[] result) { - int i = 0; /* index in packed string */ - - int j = offset; /* index in unpacked array */ - - int l = packed.length(); - while (i < l) { - int count = packed.charAt(i++); - int value = packed.charAt(i++); - do { - result[j++] = value; - } while (--count > 0); - } - return j; - } - - /** - * the input device - */ - private java.io.Reader zzReader; - - /** - * the current state of the DFA - */ - private int zzState; - - /** - * the current lexical state - */ - private int zzLexicalState = YYINITIAL; - - /** - * this buffer contains the current text to be matched and is - * the source of the yytext() string - */ - private char zzBuffer[] = new char[ZZ_BUFFERSIZE]; - - /** - * the textposition at the last accepting state - */ - private int zzMarkedPos; - - /** - * the current text position in the buffer - */ - private int zzCurrentPos; - - /** - * startRead marks the beginning of the yytext() string in the buffer - */ - private int zzStartRead; - - /** - * endRead marks the last character in the buffer, that has been read - * from input - */ - private int zzEndRead; - - /** - * number of newlines encountered up to the start of the matched text - */ - private int yyline; - - /** - * the number of characters up to the start of the matched text - */ - private int yychar; - - /** - * the number of characters from the last newline up to the start of the - * matched text - */ - private int yycolumn; - - /** - * zzAtBOL == true <=> the scanner is currently at the beginning of a line - */ - private boolean zzAtBOL = true; - - /** - * zzAtEOF == true <=> the scanner is at the EOF - */ - private boolean zzAtEOF; - - /** - * denotes if the user-EOF-code has already been executed - */ - private boolean zzEOFDone; - - /** - * The number of occupied positions in zzBuffer beyond zzEndRead. - * When a lead/high surrogate has been read from the input stream - * into the final zzBuffer position, this will have a value of 1; - * otherwise, it will have a value of 0. - */ - private int zzFinalHighSurrogate = 0; - - /* user code: */ - private String sourceCode; - - public ActionScriptLexer(String sourceCode) { - this(new StringReader(sourceCode)); - this.sourceCode = sourceCode; - } - - public void yypushbackstr(String s, int state) { - sourceCode = s + sourceCode.substring(yychar + yylength()); - yyreset(new StringReader(sourceCode)); - yybegin(state); - } - - public void yypushbackstr(String s) { - yypushbackstr(s, YYINITIAL); - } - - StringBuffer string = new StringBuffer(); - - private static String xmlTagName = ""; - - public int yychar() { - return yychar; - } - - private Stack pushedBack = new Stack<>(); - - public int yyline() { - return yyline + 1; - } - - private List listeners = new ArrayList<>(); - - public void addListener(LexListener listener) { - listeners.add(listener); - } - - public void removeListener(LexListener listener) { - listeners.remove(listener); - } - - public void informListenersLex(ParsedSymbol s) { - for (LexListener l : listeners) { - l.onLex(s); - } - } - - public void informListenersPushBack(ParsedSymbol s) { - for (LexListener l : listeners) { - l.onPushBack(s); - } - } - - public void pushback(ParsedSymbol symb) { - pushedBack.push(symb); - last = null; - informListenersPushBack(symb); - } - - ParsedSymbol last; - - public ParsedSymbol lex() throws java.io.IOException, AVM2ParseException { - ParsedSymbol ret = null; - if (!pushedBack.isEmpty()) { - ret = last = pushedBack.pop(); - } else { - ret = last = yylex(); - } - informListenersLex(ret); - return ret; - } - - /** - * Creates a new scanner - * - * @param in the java.io.Reader to read input from. - */ - public ActionScriptLexer(java.io.Reader in) { - this.zzReader = in; - } - - /** - * Unpacks the compressed character translation table. - * - * @param packed the packed character translation table - * @return the unpacked character translation table - */ - private static char[] zzUnpackCMap(String packed) { - char[] map = new char[0x110000]; - int i = 0; /* index in packed string */ - - int j = 0; /* index in unpacked array */ - - while (i < 3140) { - int count = packed.charAt(i++); - char value = packed.charAt(i++); - do { - map[j++] = value; - } while (--count > 0); - } - return map; - } - - /** - * Refills the input buffer. - * - * @return false, iff there was new input. - * - * @exception java.io.IOException if any I/O-Error occurs - */ - private boolean zzRefill() throws java.io.IOException { - - /* first: make room (if you can) */ - if (zzStartRead > 0) { - zzEndRead += zzFinalHighSurrogate; - zzFinalHighSurrogate = 0; - System.arraycopy(zzBuffer, zzStartRead, - zzBuffer, 0, - zzEndRead - zzStartRead); - - /* translate stored positions */ - zzEndRead -= zzStartRead; - zzCurrentPos -= zzStartRead; - zzMarkedPos -= zzStartRead; - zzStartRead = 0; - } - - /* is the buffer big enough? */ - if (zzCurrentPos >= zzBuffer.length - zzFinalHighSurrogate) { - /* if not: blow it up */ - char newBuffer[] = new char[zzBuffer.length * 2]; - System.arraycopy(zzBuffer, 0, newBuffer, 0, zzBuffer.length); - zzBuffer = newBuffer; - zzEndRead += zzFinalHighSurrogate; - zzFinalHighSurrogate = 0; - } - - /* fill the buffer with new input */ - int requested = zzBuffer.length - zzEndRead; - int totalRead = 0; - while (totalRead < requested) { - int numRead = zzReader.read(zzBuffer, zzEndRead + totalRead, requested - totalRead); - if (numRead == -1) { - break; - } - totalRead += numRead; - } - - if (totalRead > 0) { - zzEndRead += totalRead; - if (totalRead == requested) { /* possibly more input available */ - - if (Character.isHighSurrogate(zzBuffer[zzEndRead - 1])) { - --zzEndRead; - zzFinalHighSurrogate = 1; - } - } - return false; - } - - // totalRead = 0: End of stream - return true; - } - - /** - * Closes the input stream. - */ - public final void yyclose() throws java.io.IOException { - zzAtEOF = true; /* indicate end of file */ - - zzEndRead = zzStartRead; /* invalidate buffer */ - - if (zzReader != null) { - zzReader.close(); - } - } - - /** - * Resets the scanner to read from a new input stream. - * Does not close the old reader. - * - * All internal variables are reset, the old input stream - * cannot be reused (internal buffer is discarded and lost). - * Lexical state is set to ZZ_INITIAL. - * - * Internal scan buffer is resized down to its initial length, if it has - * grown. - * - * @param reader the new input stream - */ - public final void yyreset(java.io.Reader reader) { - zzReader = reader; - zzAtBOL = true; - zzAtEOF = false; - zzEOFDone = false; - zzEndRead = zzStartRead = 0; - zzCurrentPos = zzMarkedPos = 0; - zzFinalHighSurrogate = 0; - yyline = yychar = yycolumn = 0; - zzLexicalState = YYINITIAL; - if (zzBuffer.length > ZZ_BUFFERSIZE) { - zzBuffer = new char[ZZ_BUFFERSIZE]; - } - } - - /** - * Returns the current lexical state. - */ - public final int yystate() { - return zzLexicalState; - } - - /** - * Enters a new lexical state - * - * @param newState the new lexical state - */ - public final void yybegin(int newState) { - zzLexicalState = newState; - } - - /** - * Returns the text matched by the current regular expression. - */ - public final String yytext() { - return new String(zzBuffer, zzStartRead, zzMarkedPos - zzStartRead); - } - - /** - * Returns the character at position pos from the - * matched text. - * - * It is equivalent to yytext().charAt(pos), but faster - * - * @param pos the position of the character to fetch. - * A value from 0 to yylength()-1. - * - * @return the character at position pos - */ - public final char yycharat(int pos) { - return zzBuffer[zzStartRead + pos]; - } - - /** - * Returns the length of the matched text region. - */ - public final int yylength() { - return zzMarkedPos - zzStartRead; - } - - /** - * Reports an error that occured while scanning. - * - * In a wellformed scanner (no or only correct usage of - * yypushback(int) and a match-all fallback rule) this method - * will only be called with things that "Can't Possibly Happen". - * If this method is called, something is seriously wrong - * (e.g. a JFlex bug producing a faulty scanner etc.). - * - * Usual syntax/scanner level error handling should be done - * in error fallback rules. - * - * @param errorCode the code of the errormessage to display - */ - private void zzScanError(int errorCode) { - String message; - try { - message = ZZ_ERROR_MSG[errorCode]; - } catch (ArrayIndexOutOfBoundsException e) { - message = ZZ_ERROR_MSG[ZZ_UNKNOWN_ERROR]; - } - - throw new Error(message); - } - - /** - * Pushes the specified amount of characters back into the input stream. - * - * They will be read again by then next call of the scanning method - * - * @param number the number of characters to be read again. - * This number must not be greater than yylength()! - */ - public void yypushback(int number) { - if (number > yylength()) { - zzScanError(ZZ_PUSHBACK_2BIG); - } - - zzMarkedPos -= number; - } - - /** - * Resumes scanning until the next regular expression is matched, - * the end of input is encountered or an I/O-Error occurs. - * - * @return the next token - * @exception java.io.IOException if any I/O-Error occurs - */ - public ParsedSymbol yylex() throws java.io.IOException, AVM2ParseException { - int zzInput; - int zzAction; - - // cached fields: - int zzCurrentPosL; - int zzMarkedPosL; - int zzEndReadL = zzEndRead; - char[] zzBufferL = zzBuffer; - char[] zzCMapL = ZZ_CMAP; - - int[] zzTransL = ZZ_TRANS; - int[] zzRowMapL = ZZ_ROWMAP; - int[] zzAttrL = ZZ_ATTRIBUTE; - - while (true) { - zzMarkedPosL = zzMarkedPos; - - yychar += zzMarkedPosL - zzStartRead; - - zzAction = -1; - - zzCurrentPosL = zzCurrentPos = zzStartRead = zzMarkedPosL; - - zzState = ZZ_LEXSTATE[zzLexicalState]; - - // set up zzAction for empty match case: - int zzAttributes = zzAttrL[zzState]; - if ((zzAttributes & 1) == 1) { - zzAction = zzState; - } - - zzForAction: - { - while (true) { - - if (zzCurrentPosL < zzEndReadL) { - zzInput = Character.codePointAt(zzBufferL, zzCurrentPosL, zzEndReadL); - zzCurrentPosL += Character.charCount(zzInput); - } else if (zzAtEOF) { - zzInput = YYEOF; - break zzForAction; - } else { - // store back cached positions - zzCurrentPos = zzCurrentPosL; - zzMarkedPos = zzMarkedPosL; - boolean eof = zzRefill(); - // get translated positions and possibly new buffer - zzCurrentPosL = zzCurrentPos; - zzMarkedPosL = zzMarkedPos; - zzBufferL = zzBuffer; - zzEndReadL = zzEndRead; - if (eof) { - zzInput = YYEOF; - break zzForAction; - } else { - zzInput = Character.codePointAt(zzBufferL, zzCurrentPosL, zzEndReadL); - zzCurrentPosL += Character.charCount(zzInput); - } - } - int zzNext = zzTransL[zzRowMapL[zzState] + zzCMapL[zzInput]]; - if (zzNext == -1) { - break zzForAction; - } - zzState = zzNext; - - zzAttributes = zzAttrL[zzState]; - if ((zzAttributes & 1) == 1) { - zzAction = zzState; - zzMarkedPosL = zzCurrentPosL; - if ((zzAttributes & 8) == 8) { - break zzForAction; - } - } - - } - } - - // store back cached position - zzMarkedPos = zzMarkedPosL; - - switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) { - case 1: { - } - case 164: - break; - case 2: { - yyline++; - } - case 165: - break; - case 3: { /*ignore*/ - - } - case 166: - break; - case 4: { - return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.DIVIDE, yytext()); - } - case 167: - break; - case 5: { - return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.MULTIPLY, yytext()); - } - case 168: - break; - case 6: { - return new ParsedSymbol(SymbolGroup.IDENTIFIER, SymbolType.IDENTIFIER, yytext()); - } - case 169: - break; - case 7: { - return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.DOT, yytext()); - } - case 170: - break; - case 8: { - return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.LOWER_THAN, yytext()); - } - case 171: - break; - case 9: { - return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.NOT, yytext()); - } - case 172: - break; - case 10: { - return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.MINUS, yytext()); - } - case 173: - break; - case 11: { - return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.GREATER_THAN, yytext()); - } - case 174: - break; - case 12: { - return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.COLON, yytext()); - } - case 175: - break; - case 13: { - return new ParsedSymbol(SymbolGroup.INTEGER, SymbolType.INTEGER, Long.parseLong((yytext()))); - } - case 176: - break; - case 14: { - return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.TERNAR, yytext()); - } - case 177: - break; - case 15: { - return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.BRACKET_OPEN, yytext()); - } - case 178: - break; - case 16: { - return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.BRACKET_CLOSE, yytext()); - } - case 179: - break; - case 17: { - return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN, yytext()); - } - case 180: - break; - case 18: { - string.setLength(0); - yybegin(STRING); - } - case 181: - break; - case 19: { - string.setLength(0); - yybegin(CHARLITERAL); - } - case 182: - break; - case 20: { - return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.PLUS, yytext()); - } - case 183: - break; - case 21: { - string.setLength(0); - yybegin(OIDENTIFIER); - } - case 184: - break; - case 22: { - return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.PARENT_OPEN, yytext()); - } - case 185: - break; - case 23: { - return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.PARENT_CLOSE, yytext()); - } - case 186: - break; - case 24: { - return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.CURLY_OPEN, yytext()); - } - case 187: - break; - case 25: { - return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.CURLY_CLOSE, yytext()); - } - case 188: - break; - case 26: { - return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.SEMICOLON, yytext()); - } - case 189: - break; - case 27: { - return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.COMMA, yytext()); - } - case 190: - break; - case 28: { - return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.NEGATE, yytext()); - } - case 191: - break; - case 29: { - return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.BITAND, yytext()); - } - case 192: - break; - case 30: { - return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.BITOR, yytext()); - } - case 193: - break; - case 31: { - return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.XOR, yytext()); - } - case 194: - break; - case 32: { - return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.MODULO, yytext()); - } - case 195: - break; - case 33: { - return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ATTRIBUTE, yytext()); - } - case 196: - break; - case 34: { - string.append(yytext()); - } - case 197: - break; - case 35: { - yybegin(YYINITIAL); - yyline++; - } - case 198: - break; - case 36: { - yybegin(YYINITIAL); - // length also includes the trailing quote - return new ParsedSymbol(SymbolGroup.STRING, SymbolType.STRING, string.toString()); - } - case 199: - break; - case 37: { - yybegin(YYINITIAL); - yyline++; - } - case 200: - break; - case 38: { - string.append(yytext()); - yyline++; - } - case 201: - break; - case 39: { - yybegin(XML); - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_STARTTAG_END, yytext())); - if (string.length() > 0) { - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); - string.setLength(0); - } - return lex(); - } - case 202: - break; - case 40: { - yybegin(YYINITIAL); - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_ATTRNAMEVAR_BEGIN, yytext())); - if (string.length() > 0) { - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); - string.setLength(0); - } - return lex(); - } - case 203: - break; - case 41: { - yybegin(YYINITIAL); - return new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_ATTRVALVAR_BEGIN, yytext()); - } - case 204: - break; - case 42: { - yybegin(YYINITIAL); - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_INSTRATTRNAMEVAR_BEGIN, yytext())); - if (string.length() > 0) { - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); - string.setLength(0); - } - return lex(); - } - case 205: - break; - case 43: { - yybegin(YYINITIAL); - return new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_INSTRATTRVALVAR_BEGIN, yytext()); - } - case 206: - break; - case 44: { - string.append(yytext()); - yyline++; - } - case 207: - break; - case 45: { - yybegin(YYINITIAL); - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_VAR_BEGIN, yytext())); - if (string.length() > 0) { - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); - string.setLength(0); - } - return lex(); - } - case 208: - break; - case 46: { - yybegin(YYINITIAL); - // length also includes the trailing quote - return new ParsedSymbol(SymbolGroup.IDENTIFIER, SymbolType.IDENTIFIER, string.toString()); - } - case 209: - break; - case 47: { - return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN_DIVIDE, yytext()); - } - case 210: - break; - case 48: { - return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN_MULTIPLY, yytext()); - } - case 211: - break; - case 49: { - return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.DESCENDANTS, yytext()); - } - case 212: - break; - case 50: { - return new ParsedSymbol(SymbolGroup.TYPENAME, SymbolType.TYPENAME, yytext()); - } - case 213: - break; - case 51: { - return new ParsedSymbol(SymbolGroup.DOUBLE, SymbolType.DOUBLE, Double.parseDouble((yytext()))); - } - case 214: - break; - case 52: { - return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.FILTER, yytext()); - } - case 215: - break; - case 53: { - yybegin(XMLOPENTAG); - string.setLength(0); - return new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_STARTTAG_BEGIN, yytext()); - } - case 216: - break; - case 54: { - return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.SHIFT_LEFT, yytext()); - } - case 217: - break; - case 55: { - return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.LOWER_EQUAL, yytext()); - } - case 218: - break; - case 56: { - return new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_STARTVARTAG_BEGIN, yytext()); - } - case 219: - break; - case 57: { - return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.NOT_EQUAL, yytext()); - } - case 220: - break; - case 58: { - return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.DECREMENT, yytext()); - } - case 221: - break; - case 59: { - return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN_MINUS, yytext()); - } - case 222: - break; - case 60: { - return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.SHIFT_RIGHT, yytext()); - } - case 223: - break; - case 61: { - return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.GREATER_EQUAL, yytext()); - } - case 224: - break; - case 62: { - return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.NAMESPACE_OP, yytext()); - } - case 225: - break; - case 63: { - return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.EQUALS, yytext()); - } - case 226: - break; - case 64: { - return new ParsedSymbol(SymbolGroup.INTEGER, SymbolType.INTEGER, Long.parseLong(yytext(), 8)); - } - case 227: - break; - case 65: { - return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN_PLUS, yytext()); - } - case 228: - break; - case 66: { - return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.INCREMENT, yytext()); - } - case 229: - break; - case 67: { - return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.AS, yytext()); - } - case 230: - break; - case 68: { - return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.IF, yytext()); - } - case 231: - break; - case 69: { - return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.IS, yytext()); - } - case 232: - break; - case 70: { - return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.IN, yytext()); - } - case 233: - break; - case 71: { - return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.DO, yytext()); - } - case 234: - break; - case 72: { - return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN_BITAND, yytext()); - } - case 235: - break; - case 73: { - return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.AND, yytext()); - } - case 236: - break; - case 74: { - return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN_BITOR, yytext()); - } - case 237: - break; - case 75: { - return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.OR, yytext()); - } - case 238: - break; - case 76: { - return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN_XOR, yytext()); - } - case 239: - break; - case 77: { - return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN_MODULO, yytext()); - } - case 240: - break; - case 78: { /* ignore illegal character escape */ - - } - case 241: - break; - case 79: { - string.append('\"'); - } - case 242: - break; - case 80: { - string.append('\''); - } - case 243: - break; - case 81: { - string.append('\f'); - } - case 244: - break; - case 82: { - string.append('\\'); - } - case 245: - break; - case 83: { - string.append('\b'); - } - case 246: - break; - case 84: { - string.append('\r'); - } - case 247: - break; - case 85: { - string.append('\n'); - } - case 248: - break; - case 86: { - string.append('\t'); - } - case 249: - break; - case 87: { - yybegin(XML); - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_STARTFINISHTAG_END, yytext())); - if (string.length() > 0) { - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); - string.setLength(0); - } - return lex(); - } - case 250: - break; - case 88: { - yybegin(XMLOPENTAGATTRIB); - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_ATTRIBUTENAME, yytext())); - if (string.length() > 0) { - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); - string.setLength(0); - } - return lex(); - } - case 251: - break; - case 89: { - yybegin(XMLOPENTAG); - return new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_ATTRIBUTEVALUE, yytext()); - } - case 252: - break; - case 90: { - yybegin(XMLINSTRATTRIB); - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_ATTRIBUTENAME, yytext())); - if (string.length() > 0) { - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); - string.setLength(0); - } - return lex(); - } - case 253: - break; - case 91: { - yybegin(XML); - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_INSTR_END, yytext())); - if (string.length() > 0) { - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); - string.setLength(0); - } - return lex(); - } - case 254: - break; - case 92: { - yybegin(XMLINSTROPENTAG); - return new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_ATTRIBUTEVALUE, yytext()); - } - case 255: - break; - case 93: { - yybegin(XMLOPENTAG); - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_STARTTAG_BEGIN, yytext())); - if (string.length() > 0) { - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); - string.setLength(0); - } - return lex(); - } - case 256: - break; - case 94: { - yybegin(YYINITIAL); - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_STARTVARTAG_BEGIN, yytext())); - if (string.length() > 0) { - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); - string.setLength(0); - } - return lex(); - } - case 257: - break; - case 95: { - throw new AVM2ParseException("Illegal escape sequence \"" + yytext() + "\"", yyline + 1); - } - case 258: - break; - case 96: { - return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.REST, yytext()); - } - case 259: - break; - case 97: { - return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN_SHIFT_LEFT, yytext()); - } - case 260: - break; - case 98: { - return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.STRICT_NOT_EQUAL, yytext()); - } - case 261: - break; - case 99: { - return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.USHIFT_RIGHT, yytext()); - } - case 262: - break; - case 100: { - return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN_SHIFT_RIGHT, yytext()); - } - case 263: - break; - case 101: { - return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.STRICT_EQUALS, yytext()); - } - case 264: - break; - case 102: { - return new ParsedSymbol(SymbolGroup.INTEGER, SymbolType.INTEGER, Long.parseLong(yytext().substring(2), 16)); - } - case 265: - break; - case 103: { - return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.FOR, yytext()); - } - case 266: - break; - case 104: { - return new ParsedSymbol(SymbolGroup.IDENTIFIER, SymbolType.SET, yytext()); - } - case 267: - break; - case 105: { - return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.NEW, yytext()); - } - case 268: - break; - case 106: { - return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.TRY, yytext()); - } - case 269: - break; - case 107: { - return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.USE, yytext()); - } - case 270: - break; - case 108: { - return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.VAR, yytext()); - } - case 271: - break; - case 109: { - return new ParsedSymbol(SymbolGroup.IDENTIFIER, SymbolType.GET, yytext()); - } - case 272: - break; - case 110: { - return new ParsedSymbol(SymbolGroup.GLOBALCONST, SymbolType.NAN, yytext()); - } - case 273: - break; - case 111: { - string.append(yytext()); - yybegin(XML); - String ret = string.toString(); - string.setLength(0); - return new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_CDATA, ret); - } - case 274: - break; - case 112: { - string.append(yytext()); - yybegin(XML); - String ret = string.toString(); - string.setLength(0); - return new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_COMMENT, ret); - } - case 275: - break; - case 113: { - yybegin(YYINITIAL); - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_FINISHVARTAG_BEGIN, yytext())); - if (string.length() > 0) { - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); - string.setLength(0); - } - return lex(); - } - case 276: - break; - case 114: { - yybegin(XMLINSTROPENTAG); - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_INSTR_BEGIN, yytext())); - if (string.length() > 0) { - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); - string.setLength(0); - } - return lex(); - } - case 277: - break; - case 115: { - yybegin(YYINITIAL); - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_INSTRVARTAG_BEGIN, yytext())); - if (string.length() > 0) { - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); - string.setLength(0); - } - return lex(); - } - case 278: - break; - case 116: { - string.append('\u00A7'); - } - case 279: - break; - case 117: { - return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN_USHIFT_RIGHT, yytext()); - } - case 280: - break; - case 118: { - return new ParsedSymbol(SymbolGroup.IDENTIFIER, SymbolType.EACH, yytext()); - } - case 281: - break; - case 119: { - return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.ELSE, yytext()); - } - case 282: - break; - case 120: { - return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.CASE, yytext()); - } - case 283: - break; - case 121: { - return new ParsedSymbol(SymbolGroup.GLOBALCONST, SymbolType.NULL, yytext()); - } - case 284: - break; - case 122: { - return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.TRUE, yytext()); - } - case 285: - break; - case 123: { - return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.THIS, yytext()); - } - case 286: - break; - case 124: { - return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.WITH, yytext()); - } - case 287: - break; - case 125: { - return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.VOID, yytext()); - } - case 288: - break; - case 126: { - char val = (char) Integer.parseInt(yytext().substring(2), 16); - string.append(val); - } - case 289: - break; - case 127: { - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_FINISHTAG, yytext())); - if (string.length() > 0) { - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); - string.setLength(0); - } - return lex(); - } - case 290: - break; - case 128: { - String ret = string.toString(); - string.setLength(0); - string.append(yytext()); - yybegin(XMLCOMMENT); - if (!ret.isEmpty()) { - return new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_TEXT, ret); - } - } - case 291: - break; - case 129: { - return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.FALSE, yytext()); - } - case 292: - break; - case 130: { - return new ParsedSymbol(SymbolGroup.IDENTIFIER, SymbolType.FINAL, yytext()); - } - case 293: - break; - case 131: { - return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.BREAK, yytext()); - } - case 294: - break; - case 132: { - return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.CATCH, yytext()); - } - case 295: - break; - case 133: { - return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.CONST, yytext()); - } - case 296: - break; - case 134: { - return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.CLASS, yytext()); - } - case 297: - break; - case 135: { - return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.SUPER, yytext()); - } - case 298: - break; - case 136: { - return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.THROW, yytext()); - } - case 299: - break; - case 137: { - return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.WHILE, yytext()); - } - case 300: - break; - case 138: { - return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.RETURN, yytext()); - } - case 301: - break; - case 139: { - return new ParsedSymbol(SymbolGroup.IDENTIFIER, SymbolType.STATIC, yytext()); - } - case 302: - break; - case 140: { - return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.SWITCH, yytext()); - } - case 303: - break; - case 141: { - return new ParsedSymbol(SymbolGroup.IDENTIFIER, SymbolType.NATIVE, yytext()); - } - case 304: - break; - case 142: { - return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.TYPEOF, yytext()); - } - case 305: - break; - case 143: { - return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.IMPORT, yytext()); - } - case 306: - break; - case 144: { - return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.DELETE, yytext()); - } - case 307: - break; - case 145: { - return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.PUBLIC, yytext()); - } - case 308: - break; - case 146: { - return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.FINALLY, yytext()); - } - case 309: - break; - case 147: { - return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.EXTENDS, yytext()); - } - case 310: - break; - case 148: { - return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.DEFAULT, yytext()); - } - case 311: - break; - case 149: { - return new ParsedSymbol(SymbolGroup.IDENTIFIER, SymbolType.DYNAMIC, yytext()); - } - case 312: - break; - case 150: { - return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.PRIVATE, yytext()); - } - case 313: - break; - case 151: { - return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.PACKAGE, yytext()); - } - case 314: - break; - case 152: { - return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.FUNCTION, yytext()); - } - case 315: - break; - case 153: { - return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.CONTINUE, yytext()); - } - case 316: - break; - case 154: { - return new ParsedSymbol(SymbolGroup.IDENTIFIER, SymbolType.OVERRIDE, yytext()); - } - case 317: - break; - case 155: { - return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.INTERNAL, yytext()); - } - case 318: - break; - case 156: { - return new ParsedSymbol(SymbolGroup.GLOBALCONST, SymbolType.INFINITY, yytext()); - } - case 319: - break; - case 157: { - return new ParsedSymbol(SymbolGroup.IDENTIFIER, SymbolType.NAMESPACE, yytext()); - } - case 320: - break; - case 158: { - return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.INTERFACE, yytext()); - } - case 321: - break; - case 159: { - return new ParsedSymbol(SymbolGroup.GLOBALCONST, SymbolType.UNDEFINED, yytext()); - } - case 322: - break; - case 160: { - return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.PROTECTED, yytext()); - } - case 323: - break; - case 161: { - String ret = string.toString(); - string.setLength(0); - string.append(yytext()); - yybegin(XMLCDATA); - if (!ret.isEmpty()) { - return new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_TEXT, ret); - } - } - case 324: - break; - case 162: { - return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.INSTANCEOF, yytext()); - } - case 325: - break; - case 163: { - return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.IMPLEMENTS, yytext()); - } - case 326: - break; - default: - if (zzInput == YYEOF && zzStartRead == zzCurrentPos) { - zzAtEOF = true; - { - return new ParsedSymbol(SymbolGroup.EOF, SymbolType.EOF, null); - } - } else { - zzScanError(ZZ_NO_MATCH); - } - } - } - } -} +/* The following code was generated by JFlex 1.6.0 */ + +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.parser.script; + +import com.jpexs.decompiler.flash.abc.avm2.parser.AVM2ParseException; +import java.io.StringReader; +import java.util.ArrayList; +import java.util.List; +import java.util.Stack; + +/** + * This class is a scanner generated by + * JFlex 1.6.0 + * from the specification file + * C:/Projects/FFDec/jpexs-decompiler/libsrc/ffdec_lib/lexers/actionscript3_script.flex + */ +public final class ActionScriptLexer { + + /** + * This character denotes the end of file + */ + public static final int YYEOF = -1; + + /** + * initial size of the lookahead buffer + */ + private static final int ZZ_BUFFERSIZE = 16384; + + /** + * lexical states + */ + public static final int YYINITIAL = 0; + + public static final int STRING = 2; + + public static final int CHARLITERAL = 4; + + public static final int XMLOPENTAG = 6; + + public static final int XMLOPENTAGATTRIB = 8; + + public static final int XMLINSTROPENTAG = 10; + + public static final int XMLINSTRATTRIB = 12; + + public static final int XMLCDATA = 14; + + public static final int XMLCOMMENT = 16; + + public static final int XML = 18; + + public static final int OIDENTIFIER = 20; + + /** + * ZZ_LEXSTATE[l] is the state in the DFA for the lexical state l + * ZZ_LEXSTATE[l+1] is the state in the DFA for the lexical state l + * at the beginning of a line + * l is of the form l = 2*k, k a non negative integer + */ + private static final int ZZ_LEXSTATE[] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 9, 9, 10, 10 + }; + + /** + * Translates characters to character classes + */ + private static final String ZZ_CMAP_PACKED + = "\11\0\1\13\1\2\1\113\1\3\1\1\22\0\1\13\1\14\1\33" + + "\1\0\1\6\1\110\1\105\1\34\1\76\1\77\1\5\1\45\1\103" + + "\1\15\1\11\1\4\1\35\3\41\4\42\2\21\1\17\1\102\1\12" + + "\1\32\1\16\1\23\1\111\1\27\1\20\1\25\1\26\1\43\1\20" + + "\2\10\1\74\4\10\1\75\5\10\1\30\3\10\1\37\2\10\1\24" + + "\1\46\1\31\1\107\1\10\1\0\1\52\1\50\1\54\1\63\1\44" + + "\1\40\1\73\1\66\1\61\1\10\1\53\1\64\1\71\1\57\1\56" + + "\1\67\1\10\1\51\1\55\1\60\1\62\1\72\1\65\1\36\1\70" + + "\1\10\1\100\1\106\1\101\1\104\6\0\1\113\41\0\1\47\2\0" + + "\1\6\12\0\1\6\1\0\1\22\2\0\1\6\5\0\2\6\1\112" + + "\24\6\1\0\37\6\1\0\u01ca\6\4\0\14\6\16\0\5\6\7\0" + + "\1\6\1\0\1\6\21\0\160\7\5\6\1\0\2\6\2\0\4\6" + + "\1\0\1\6\6\0\1\6\1\0\3\6\1\0\1\6\1\0\24\6" + + "\1\0\123\6\1\0\213\6\1\0\5\7\2\0\246\6\1\0\46\6" + + "\2\0\1\6\7\0\47\6\11\0\55\7\1\0\1\7\1\0\2\7" + + "\1\0\2\7\1\0\1\7\10\0\33\6\5\0\3\6\35\0\13\7" + + "\5\0\53\6\37\7\4\0\2\6\1\7\143\6\1\0\1\6\7\7" + + "\2\0\6\7\2\6\2\7\1\0\4\7\2\6\12\7\3\6\2\0" + + "\1\6\20\0\1\6\1\7\36\6\33\7\2\0\131\6\13\7\1\6" + + "\16\0\12\7\41\6\11\7\2\6\4\0\1\6\5\0\26\6\4\7" + + "\1\6\11\7\1\6\3\7\1\6\5\7\22\0\31\6\3\7\104\0" + + "\23\6\61\0\40\7\66\6\3\7\1\6\22\7\1\6\7\7\12\6" + + "\2\7\2\0\12\7\1\0\20\6\3\7\1\0\10\6\2\0\2\6" + + "\2\0\26\6\1\0\7\6\1\0\1\6\3\0\4\6\2\0\1\7" + + "\1\6\7\7\2\0\2\7\2\0\3\7\1\6\10\0\1\7\4\0" + + "\2\6\1\0\3\6\2\7\2\0\12\7\2\6\17\0\3\7\1\0" + + "\6\6\4\0\2\6\2\0\26\6\1\0\7\6\1\0\2\6\1\0" + + "\2\6\1\0\2\6\2\0\1\7\1\0\5\7\4\0\2\7\2\0" + + "\3\7\3\0\1\7\7\0\4\6\1\0\1\6\7\0\14\7\3\6" + + "\1\7\13\0\3\7\1\0\11\6\1\0\3\6\1\0\26\6\1\0" + + "\7\6\1\0\2\6\1\0\5\6\2\0\1\7\1\6\10\7\1\0" + + "\3\7\1\0\3\7\2\0\1\6\17\0\2\6\2\7\2\0\12\7" + + "\21\0\3\7\1\0\10\6\2\0\2\6\2\0\26\6\1\0\7\6" + + "\1\0\2\6\1\0\5\6\2\0\1\7\1\6\7\7\2\0\2\7" + + "\2\0\3\7\10\0\2\7\4\0\2\6\1\0\3\6\2\7\2\0" + + "\12\7\1\0\1\6\20\0\1\7\1\6\1\0\6\6\3\0\3\6" + + "\1\0\4\6\3\0\2\6\1\0\1\6\1\0\2\6\3\0\2\6" + + "\3\0\3\6\3\0\14\6\4\0\5\7\3\0\3\7\1\0\4\7" + + "\2\0\1\6\6\0\1\7\16\0\12\7\20\0\4\7\1\0\10\6" + + "\1\0\3\6\1\0\27\6\1\0\20\6\3\0\1\6\7\7\1\0" + + "\3\7\1\0\4\7\7\0\2\7\1\0\2\6\6\0\2\6\2\7" + + "\2\0\12\7\21\0\3\7\1\0\10\6\1\0\3\6\1\0\27\6" + + "\1\0\12\6\1\0\5\6\2\0\1\7\1\6\7\7\1\0\3\7" + + "\1\0\4\7\7\0\2\7\7\0\1\6\1\0\2\6\2\7\2\0" + + "\12\7\1\0\2\6\16\0\3\7\1\0\10\6\1\0\3\6\1\0" + + "\51\6\2\0\1\6\7\7\1\0\3\7\1\0\4\7\1\6\10\0" + + "\1\7\10\0\2\6\2\7\2\0\12\7\12\0\6\6\2\0\2\7" + + "\1\0\22\6\3\0\30\6\1\0\11\6\1\0\1\6\2\0\7\6" + + "\3\0\1\7\4\0\6\7\1\0\1\7\1\0\10\7\6\0\12\7" + + "\2\0\2\7\15\0\60\6\1\7\2\6\7\7\5\0\7\6\10\7" + + "\1\0\12\7\47\0\2\6\1\0\1\6\2\0\2\6\1\0\1\6" + + "\2\0\1\6\6\0\4\6\1\0\7\6\1\0\3\6\1\0\1\6" + + "\1\0\1\6\2\0\2\6\1\0\4\6\1\7\2\6\6\7\1\0" + + "\2\7\1\6\2\0\5\6\1\0\1\6\1\0\6\7\2\0\12\7" + + "\2\0\4\6\40\0\1\6\27\0\2\7\6\0\12\7\13\0\1\7" + + "\1\0\1\7\1\0\1\7\4\0\2\7\10\6\1\0\44\6\4\0" + + "\24\7\1\0\2\7\5\6\13\7\1\0\44\7\11\0\1\7\71\0" + + "\53\6\24\7\1\6\12\7\6\0\6\6\4\7\4\6\3\7\1\6" + + "\3\7\2\6\7\7\3\6\4\7\15\6\14\7\1\6\17\7\2\0" + + "\46\6\1\0\1\6\5\0\1\6\2\0\53\6\1\0\u014d\6\1\0" + + "\4\6\2\0\7\6\1\0\1\6\1\0\4\6\2\0\51\6\1\0" + + "\4\6\2\0\41\6\1\0\4\6\2\0\7\6\1\0\1\6\1\0" + + "\4\6\2\0\17\6\1\0\71\6\1\0\4\6\2\0\103\6\2\0" + + "\3\7\40\0\20\6\20\0\125\6\14\0\u026c\6\2\0\21\6\1\0" + + "\32\6\5\0\113\6\3\0\3\7\10\6\7\0\15\6\1\0\4\6" + + "\3\7\13\0\22\6\3\7\13\0\22\6\2\7\14\0\15\6\1\0" + + "\3\6\1\0\2\7\14\0\64\6\40\7\3\0\1\6\4\0\1\6" + + "\1\7\2\0\12\7\41\0\3\7\2\0\12\7\6\0\130\6\10\0" + + "\51\6\1\7\1\6\5\0\106\6\12\0\37\6\1\0\14\7\4\0" + + "\14\7\12\0\12\7\36\6\2\0\5\6\13\0\54\6\4\0\21\7" + + "\7\6\2\7\6\0\12\7\46\0\27\6\5\7\4\0\65\6\12\7" + + "\1\0\35\7\2\0\13\7\6\0\12\7\15\0\1\6\10\0\16\7" + + "\102\0\5\7\57\6\21\7\7\6\4\0\12\7\21\0\11\7\14\0" + + "\3\7\36\6\15\7\2\6\12\7\54\6\16\7\14\0\44\6\24\7" + + "\10\0\12\7\3\0\3\6\12\7\44\6\122\0\3\7\1\0\25\7" + + "\4\6\1\7\4\6\3\7\2\6\1\0\2\7\6\0\300\6\66\7" + + "\6\0\4\7\u0116\6\2\0\6\6\2\0\46\6\2\0\6\6\2\0" + + "\10\6\1\0\1\6\1\0\1\6\1\0\1\6\1\0\37\6\2\0" + + "\65\6\1\0\7\6\1\0\1\6\3\0\3\6\1\0\7\6\3\0" + + "\4\6\2\0\6\6\4\0\15\6\5\0\3\6\1\0\7\6\3\0" + + "\14\0\2\0\32\0\1\113\1\113\25\0\2\7\23\0\1\7\33\0" + + "\1\0\1\6\15\0\1\6\20\0\15\6\63\0\15\7\4\0\1\7" + + "\3\0\14\7\21\0\1\6\4\0\1\6\2\0\12\6\1\0\1\6" + + "\3\0\5\6\6\0\1\6\1\0\1\6\1\0\1\6\1\0\4\6" + + "\1\0\13\6\2\0\4\6\5\0\5\6\4\0\1\6\21\0\43\7" + + "\2\6\4\7\7\0\u0a70\0\57\6\1\0\57\6\1\0\205\6\6\0" + + "\4\6\3\7\2\6\14\0\46\6\1\0\1\6\5\0\1\6\2\0" + + "\70\6\7\0\1\6\17\0\1\7\27\6\11\0\7\6\1\0\7\6" + + "\1\0\7\6\1\0\7\6\1\0\7\6\1\0\7\6\1\0\7\6" + + "\1\0\7\6\1\0\40\7\57\0\1\6\u01c0\0\21\0\4\0\2\6" + + "\1\7\31\0\17\7\1\0\5\6\2\0\3\7\2\6\4\0\126\6" + + "\2\0\2\7\2\0\3\6\1\0\132\6\1\0\4\6\5\0\51\6" + + "\3\0\136\6\21\0\33\6\65\0\20\6\u0200\0\u19b6\6\112\0\u51cd\6" + + "\63\0\u048d\6\103\0\56\6\2\0\u010d\6\3\0\20\6\12\7\2\6" + + "\24\0\57\6\1\7\4\0\12\7\1\0\37\6\1\0\1\7\106\6" + + "\14\7\45\0\11\6\2\0\147\6\2\0\4\6\1\0\36\6\2\0" + + "\2\6\105\0\13\6\1\7\3\6\1\7\4\6\1\7\27\6\5\7" + + "\30\0\64\6\14\0\2\7\62\6\21\7\13\0\12\7\6\0\22\7" + + "\6\6\3\0\1\6\4\0\12\7\34\6\10\7\2\0\27\6\15\7" + + "\14\0\35\6\3\0\4\7\57\6\16\7\16\0\1\6\12\7\6\0" + + "\5\6\1\7\12\6\12\7\5\6\1\0\51\6\16\7\11\0\3\6" + + "\1\7\10\6\2\7\2\0\12\7\6\0\27\6\3\0\1\6\3\7" + + "\62\6\1\7\1\6\3\7\2\6\2\7\5\6\2\7\1\6\1\7" + + "\1\6\30\0\3\6\2\0\13\6\5\7\2\0\3\6\2\7\12\0" + + "\6\6\2\0\6\6\2\0\6\6\11\0\7\6\1\0\7\6\1\0" + + "\53\6\1\0\4\6\4\0\2\6\132\0\43\6\10\7\1\0\2\7" + + "\2\0\12\7\6\0\u2ba4\6\14\0\27\6\4\0\61\6\4\0\u1800\0" + + "\u0900\0\u016e\6\2\0\152\6\46\0\7\6\14\0\5\6\5\0\1\6" + + "\1\7\12\6\1\0\15\6\1\0\5\6\1\0\1\6\1\0\2\6" + + "\1\0\2\6\1\0\154\6\41\0\u016b\6\22\0\100\6\2\0\66\6" + + "\10\0\40\0\14\6\4\0\20\7\20\0\16\7\5\0\2\7\30\0" + + "\3\7\40\0\5\6\1\0\207\6\23\0\12\7\7\0\32\6\4\0" + + "\1\7\1\0\32\6\13\0\131\6\3\0\6\6\2\0\6\6\2\0" + + "\6\6\2\0\3\6\41\0\2\0\14\6\1\0\32\6\1\0\23\6" + + "\1\0\2\6\1\0\17\6\2\0\16\6\42\0\173\6\105\0\65\7" + + "\210\0\1\7\202\0\35\6\3\0\61\6\17\0\1\7\37\0\40\6" + + "\20\0\21\6\1\7\10\6\1\7\5\0\46\6\5\7\5\0\36\6" + + "\2\0\44\6\4\0\10\6\1\0\5\7\52\0\236\6\2\0\12\7" + + "\126\0\50\6\10\0\64\6\234\0\u0137\6\11\0\26\6\12\0\10\6" + + "\230\0\6\6\2\0\1\6\1\0\54\6\1\0\2\6\3\0\1\6" + + "\2\0\27\6\12\0\27\6\11\0\37\6\141\0\26\6\12\0\32\6" + + "\106\0\70\6\6\0\2\6\100\0\1\6\3\7\1\0\2\7\5\0" + + "\4\7\4\6\1\0\3\6\1\0\33\6\4\0\3\7\4\0\1\7" + + "\40\0\35\6\3\0\35\6\43\0\10\6\1\0\34\6\2\7\31\0" + + "\66\6\12\0\26\6\12\0\23\6\15\0\22\6\156\0\111\6\u03b7\0" + + "\3\7\65\6\17\7\37\0\12\7\17\0\4\7\55\6\13\7\25\0" + + "\31\6\7\0\12\7\6\0\3\7\44\6\16\7\1\0\12\7\20\0" + + "\43\6\1\7\2\0\1\6\11\0\3\7\60\6\16\7\4\6\13\0" + + "\12\7\1\6\45\0\22\6\1\0\31\6\14\7\170\0\57\6\14\7" + + "\5\0\12\7\7\0\3\7\1\0\10\6\2\0\2\6\2\0\26\6" + + "\1\0\7\6\1\0\2\6\1\0\5\6\2\0\1\7\1\6\7\7" + + "\2\0\2\7\2\0\3\7\11\0\1\7\5\0\5\6\2\7\2\0" + + "\7\7\3\0\5\7\u010b\0\60\6\24\7\2\6\1\0\1\6\10\0" + + "\12\7\246\0\57\6\7\7\2\0\11\7\77\0\60\6\21\7\3\0" + + "\1\6\13\0\12\7\46\0\53\6\15\7\10\0\12\7\u01d6\0\100\6" + + "\12\7\25\0\1\6\u01c0\0\71\6\u0507\0\u0399\6\147\0\157\7\u0b91\0" + + "\u042f\6\u33d1\0\u0239\6\7\0\37\6\1\0\12\7\146\0\36\6\2\0" + + "\5\7\13\0\60\6\7\7\11\0\4\6\14\0\12\7\11\0\25\6" + + "\5\0\23\6\u0370\0\105\6\13\0\1\6\56\7\20\0\4\7\15\6" + + "\u4060\0\2\6\u0bfe\0\153\6\5\0\15\6\3\0\11\6\7\0\12\6" + + "\3\0\2\7\u14c6\0\5\7\3\0\6\7\10\0\10\7\2\0\7\7" + + "\36\0\4\7\224\0\3\7\u01bb\0\125\6\1\0\107\6\1\0\2\6" + + "\2\0\1\6\2\0\2\6\2\0\4\6\1\0\14\6\1\0\1\6" + + "\1\0\7\6\1\0\101\6\1\0\4\6\2\0\10\6\1\0\7\6" + + "\1\0\34\6\1\0\4\6\1\0\5\6\1\0\1\6\3\0\7\6" + + "\1\0\u0154\6\2\0\31\6\1\0\31\6\1\0\37\6\1\0\31\6" + + "\1\0\37\6\1\0\31\6\1\0\37\6\1\0\31\6\1\0\37\6" + + "\1\0\31\6\1\0\10\6\2\0\62\7\u1000\0\305\6\13\0\7\7" + + "\u0529\0\4\6\1\0\33\6\1\0\2\6\1\0\1\6\2\0\1\6" + + "\1\0\12\6\1\0\4\6\1\0\1\6\1\0\1\6\6\0\1\6" + + "\4\0\1\6\1\0\1\6\1\0\1\6\1\0\3\6\1\0\2\6" + + "\1\0\1\6\2\0\1\6\1\0\1\6\1\0\1\6\1\0\1\6" + + "\1\0\1\6\1\0\2\6\1\0\1\6\2\0\4\6\1\0\7\6" + + "\1\0\4\6\1\0\4\6\1\0\1\6\1\0\12\6\1\0\21\6" + + "\5\0\3\6\1\0\5\6\1\0\21\6\u1144\0\ua6d7\6\51\0\u1035\6" + + "\13\0\336\6\u3fe2\0\u021e\6\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\u06ed\0" + + "\360\7\uffff\0\uffff\0\ufe12\0"; + + /** + * Translates characters to character classes + */ + private static final char[] ZZ_CMAP = zzUnpackCMap(ZZ_CMAP_PACKED); + + /** + * Translates DFA states to action switch labels. + */ + private static final int[] ZZ_ACTION = zzUnpackAction(); + + private static final String ZZ_ACTION_PACKED_0 + = "\13\0\1\1\2\2\1\3\1\4\1\5\1\6\1\7" + + "\1\10\1\11\1\12\1\13\1\14\1\15\1\16\1\17" + + "\1\20\1\21\1\22\1\23\1\15\2\6\1\24\1\25" + + "\21\6\1\26\1\27\1\30\1\31\1\32\1\33\1\34" + + "\1\35\1\36\1\37\1\40\1\41\1\42\2\43\1\44" + + "\1\1\1\42\2\45\2\46\1\42\2\1\1\47\1\50" + + "\1\1\1\51\2\1\1\52\1\1\1\53\2\42\2\54" + + "\2\42\1\55\1\42\1\1\1\56\1\3\1\0\1\57" + + "\1\60\1\61\1\62\1\63\1\64\1\65\1\66\1\67" + + "\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\0" + + "\1\77\1\63\1\100\1\0\2\100\7\6\1\101\1\102" + + "\2\6\1\103\16\6\1\104\1\105\1\106\4\6\1\107" + + "\13\6\1\110\1\111\1\112\1\113\1\114\1\115\1\116" + + "\1\117\1\120\1\116\1\121\1\122\1\123\1\124\1\125" + + "\1\126\1\116\1\127\1\0\1\130\1\0\1\131\1\0" + + "\1\132\1\133\1\0\1\134\4\0\1\135\2\0\1\136" + + "\4\137\2\3\2\0\1\140\1\141\1\142\1\143\1\144" + + "\1\0\1\63\1\145\2\146\1\100\1\6\1\147\13\6" + + "\1\150\4\6\1\151\4\6\1\152\6\6\1\153\12\6" + + "\1\154\1\6\1\155\1\6\1\156\3\0\1\134\1\157" + + "\1\160\1\0\1\161\2\0\1\162\1\163\1\164\1\0" + + "\1\165\1\146\1\100\4\6\1\166\1\167\2\6\1\170" + + "\12\6\1\171\1\172\1\6\1\173\11\6\1\174\5\6" + + "\1\175\1\6\1\176\2\0\1\177\1\200\1\0\1\146" + + "\1\100\1\201\1\202\2\6\1\203\1\6\1\204\1\205" + + "\1\6\1\206\1\6\1\207\4\6\1\210\11\6\1\211" + + "\5\6\1\0\1\146\1\100\3\6\1\212\1\6\1\213" + + "\1\214\1\6\1\215\1\6\1\216\3\6\1\217\3\6" + + "\1\220\4\6\1\221\1\6\1\0\1\146\1\100\1\222" + + "\1\6\1\223\10\6\1\224\1\225\1\6\1\226\1\227" + + "\1\6\1\0\1\146\1\100\1\230\1\231\1\232\3\6" + + "\1\233\3\6\1\234\1\0\1\146\1\100\1\235\1\6" + + "\1\236\1\6\1\237\1\240\1\241\1\146\1\100\1\242" + + "\1\243\6\100"; + + private static int[] zzUnpackAction() { + int[] result = new int[446]; + int offset = 0; + offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackAction(String packed, int offset, int[] result) { + int i = 0; /* index in packed string */ + + int j = offset; /* index in unpacked array */ + + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + do { + result[j++] = value; + } while (--count > 0); + } + return j; + } + + /** + * Translates a state to a row index in the transition table + */ + private static final int[] ZZ_ROWMAP = zzUnpackRowMap(); + + private static final String ZZ_ROWMAP_PACKED_0 + = "\0\0\0\114\0\230\0\344\0\u0130\0\u017c\0\u01c8\0\u0214" + + "\0\u0260\0\u02ac\0\u02f8\0\u0344\0\u0390\0\u0344\0\u03dc\0\u0428" + + "\0\u0474\0\u04c0\0\u050c\0\u0558\0\u05a4\0\u05f0\0\u063c\0\u0688" + + "\0\u06d4\0\u0344\0\u0344\0\u0344\0\u0720\0\u0344\0\u0344\0\u076c" + + "\0\u07b8\0\u0804\0\u0850\0\u0344\0\u089c\0\u08e8\0\u0934\0\u0980" + + "\0\u09cc\0\u0a18\0\u0a64\0\u0ab0\0\u0afc\0\u0b48\0\u0b94\0\u0be0" + + "\0\u0c2c\0\u0c78\0\u0cc4\0\u0d10\0\u0d5c\0\u0344\0\u0344\0\u0344" + + "\0\u0344\0\u0344\0\u0344\0\u0344\0\u0da8\0\u0df4\0\u0e40\0\u0e8c" + + "\0\u0344\0\u0ed8\0\u0f24\0\u0344\0\u0344\0\u0f70\0\u0fbc\0\u1008" + + "\0\u0344\0\u1054\0\u0344\0\u10a0\0\u10ec\0\u1138\0\u0344\0\u0344" + + "\0\u1184\0\u0344\0\u11d0\0\u121c\0\u0344\0\u1268\0\u0344\0\u0344" + + "\0\u12b4\0\u1300\0\u0344\0\u134c\0\u1398\0\u0344\0\u13e4\0\u1430" + + "\0\u0344\0\u147c\0\u14c8\0\u0344\0\u0344\0\u1514\0\u0344\0\u1560" + + "\0\u0344\0\u15ac\0\u15f8\0\u0344\0\u0344\0\u1644\0\u0344\0\u0344" + + "\0\u1690\0\u0344\0\u0344\0\u16dc\0\u1728\0\u1774\0\u17c0\0\u180c" + + "\0\u1858\0\u18a4\0\u18f0\0\u193c\0\u1988\0\u19d4\0\u1a20\0\u1a6c" + + "\0\u1ab8\0\u0344\0\u0344\0\u1b04\0\u1b50\0\u04c0\0\u1b9c\0\u1be8" + + "\0\u1c34\0\u1c80\0\u1ccc\0\u1d18\0\u1d64\0\u1db0\0\u1dfc\0\u1e48" + + "\0\u1e94\0\u1ee0\0\u1f2c\0\u1f78\0\u04c0\0\u04c0\0\u1fc4\0\u2010" + + "\0\u205c\0\u20a8\0\u20f4\0\u04c0\0\u2140\0\u218c\0\u21d8\0\u2224" + + "\0\u2270\0\u22bc\0\u2308\0\u2354\0\u23a0\0\u23ec\0\u2438\0\u0344" + + "\0\u0344\0\u0344\0\u0344\0\u0344\0\u0344\0\u0344\0\u0344\0\u0344" + + "\0\u2484\0\u0344\0\u0344\0\u0344\0\u0344\0\u0344\0\u0344\0\u24d0" + + "\0\u0344\0\u1138\0\u0344\0\u1184\0\u0344\0\u11d0\0\u0344\0\u0344" + + "\0\u1268\0\u251c\0\u2568\0\u25b4\0\u2600\0\u264c\0\u2698\0\u26e4" + + "\0\u2730\0\u0344\0\u0344\0\u2484\0\u24d0\0\u277c\0\u27c8\0\u0344" + + "\0\u2814\0\u2860\0\u0344\0\u0344\0\u0344\0\u28ac\0\u0344\0\u28f8" + + "\0\u28f8\0\u0344\0\u2944\0\u180c\0\u2990\0\u29dc\0\u04c0\0\u2a28" + + "\0\u2a74\0\u2ac0\0\u2b0c\0\u2b58\0\u2ba4\0\u2bf0\0\u2c3c\0\u2c88" + + "\0\u2cd4\0\u2d20\0\u04c0\0\u2d6c\0\u2db8\0\u2e04\0\u2e50\0\u04c0" + + "\0\u2e9c\0\u2ee8\0\u2f34\0\u2f80\0\u04c0\0\u2fcc\0\u3018\0\u3064" + + "\0\u30b0\0\u30fc\0\u3148\0\u04c0\0\u3194\0\u31e0\0\u322c\0\u3278" + + "\0\u32c4\0\u3310\0\u335c\0\u33a8\0\u33f4\0\u3440\0\u04c0\0\u348c" + + "\0\u04c0\0\u34d8\0\u04c0\0\u3524\0\u3570\0\u251c\0\u0344\0\u0344" + + "\0\u0344\0\u35bc\0\u0344\0\u3608\0\u3654\0\u36a0\0\u0344\0\u0344" + + "\0\u36ec\0\u0344\0\u3738\0\u3784\0\u37d0\0\u381c\0\u3868\0\u38b4" + + "\0\u04c0\0\u04c0\0\u3900\0\u394c\0\u04c0\0\u3998\0\u39e4\0\u3a30" + + "\0\u3a7c\0\u3ac8\0\u3b14\0\u3b60\0\u3bac\0\u3bf8\0\u3c44\0\u04c0" + + "\0\u04c0\0\u3c90\0\u04c0\0\u3cdc\0\u3d28\0\u3d74\0\u3dc0\0\u3e0c" + + "\0\u3e58\0\u3ea4\0\u3ef0\0\u3f3c\0\u04c0\0\u3f88\0\u3fd4\0\u4020" + + "\0\u406c\0\u40b8\0\u04c0\0\u4104\0\u0344\0\u2484\0\u4150\0\u0344" + + "\0\u0344\0\u419c\0\u41e8\0\u4234\0\u04c0\0\u4280\0\u42cc\0\u4318" + + "\0\u04c0\0\u4364\0\u04c0\0\u04c0\0\u43b0\0\u04c0\0\u43fc\0\u04c0" + + "\0\u4448\0\u4494\0\u44e0\0\u452c\0\u04c0\0\u4578\0\u45c4\0\u4610" + + "\0\u465c\0\u46a8\0\u46f4\0\u4740\0\u478c\0\u47d8\0\u04c0\0\u4824" + + "\0\u4870\0\u48bc\0\u4908\0\u4954\0\u49a0\0\u49ec\0\u4a38\0\u4a84" + + "\0\u4ad0\0\u4b1c\0\u04c0\0\u4b68\0\u04c0\0\u04c0\0\u4bb4\0\u04c0" + + "\0\u4c00\0\u04c0\0\u4c4c\0\u4c98\0\u4ce4\0\u04c0\0\u4d30\0\u4d7c" + + "\0\u4dc8\0\u04c0\0\u4e14\0\u4e60\0\u4eac\0\u4ef8\0\u04c0\0\u4f44" + + "\0\u4f90\0\u4fdc\0\u5028\0\u04c0\0\u5074\0\u04c0\0\u50c0\0\u510c" + + "\0\u5158\0\u51a4\0\u51f0\0\u523c\0\u5288\0\u52d4\0\u04c0\0\u04c0" + + "\0\u5320\0\u04c0\0\u04c0\0\u536c\0\u53b8\0\u5404\0\u5450\0\u04c0" + + "\0\u04c0\0\u04c0\0\u549c\0\u54e8\0\u5534\0\u04c0\0\u5580\0\u55cc" + + "\0\u5618\0\u04c0\0\u5664\0\u56b0\0\u56fc\0\u04c0\0\u5748\0\u04c0" + + "\0\u5794\0\u04c0\0\u04c0\0\u0344\0\u0344\0\u57e0\0\u04c0\0\u04c0" + + "\0\u582c\0\u5878\0\u58c4\0\u5910\0\u595c\0\u1774"; + + private static int[] zzUnpackRowMap() { + int[] result = new int[446]; + int offset = 0; + offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackRowMap(String packed, int offset, int[] result) { + int i = 0; /* index in packed string */ + + int j = offset; /* index in unpacked array */ + + int l = packed.length(); + while (i < l) { + int high = packed.charAt(i++) << 16; + result[j++] = high | packed.charAt(i++); + } + return j; + } + + /** + * The transition table of the DFA + */ + private static final int[] ZZ_TRANS = zzUnpackTrans(); + + private static final String ZZ_TRANS_PACKED_0 + = "\1\14\1\15\1\16\1\17\1\20\1\21\1\22\1\14" + + "\1\22\1\23\1\24\1\17\1\25\1\26\1\27\1\30" + + "\1\22\1\31\1\14\1\32\1\33\4\22\1\34\1\35" + + "\1\36\1\37\1\40\2\22\1\41\2\31\1\22\1\42" + + "\1\43\1\14\1\44\1\45\1\46\1\47\1\22\1\50" + + "\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\22" + + "\1\60\1\22\1\61\2\22\1\62\1\63\1\64\1\65" + + "\1\66\1\67\1\70\1\71\1\72\1\73\1\74\1\75" + + "\1\76\1\77\1\100\1\101\1\22\1\14\1\102\1\103" + + "\1\104\30\102\1\105\12\102\1\106\45\102\1\107\1\110" + + "\1\111\31\107\1\105\11\107\1\106\45\107\1\14\1\112" + + "\1\113\1\114\1\115\3\14\1\116\2\14\1\114\2\14" + + "\1\117\2\116\4\14\4\116\5\14\3\116\2\14\2\116" + + "\3\14\26\116\2\14\1\120\46\14\1\121\44\14\1\122" + + "\14\14\1\112\1\113\1\114\4\14\1\123\2\14\1\114" + + "\3\14\2\123\2\14\1\124\1\14\4\123\5\14\3\123" + + "\2\14\2\123\3\14\26\123\2\14\1\125\46\14\1\126" + + "\44\14\1\127\13\14\1\130\1\112\1\113\26\130\1\131" + + "\63\130\1\132\1\133\12\130\1\134\77\130\1\112\1\113" + + "\7\130\1\135\65\130\1\136\13\130\1\137\1\110\1\111" + + "\43\137\1\140\1\141\44\137\116\0\1\16\114\0\1\17" + + "\7\0\1\17\104\0\1\142\1\143\24\0\1\144\113\0" + + "\1\145\67\0\3\22\7\0\2\22\3\0\4\22\4\0" + + "\10\22\3\0\26\22\14\0\1\22\12\0\1\146\1\147" + + "\6\0\1\150\13\0\1\150\3\0\2\150\33\0\1\151" + + "\25\0\1\152\1\0\1\153\4\0\2\152\4\0\4\152" + + "\1\0\1\154\3\0\3\152\2\0\2\152\3\0\26\152" + + "\2\0\1\155\45\0\1\156\76\0\1\157\14\0\1\160" + + "\77\0\1\161\13\0\1\162\100\0\1\163\105\0\1\150" + + "\7\0\1\31\13\0\1\31\3\0\2\31\2\164\101\0" + + "\1\165\72\0\1\150\7\0\1\166\13\0\1\167\2\170" + + "\1\0\1\171\1\172\2\164\55\0\3\22\7\0\2\22" + + "\3\0\4\22\4\0\10\22\3\0\2\22\1\173\3\22" + + "\1\174\2\22\1\175\1\176\13\22\14\0\1\22\7\0" + + "\3\22\7\0\2\22\3\0\4\22\4\0\1\22\1\177" + + "\6\22\3\0\2\22\1\200\11\22\1\201\11\22\14\0" + + "\1\22\33\0\1\202\12\0\1\203\54\0\3\22\7\0" + + "\2\22\3\0\4\22\4\0\10\22\3\0\1\22\1\204" + + "\24\22\14\0\1\22\7\0\3\22\7\0\2\22\3\0" + + "\4\22\4\0\7\22\1\205\3\0\26\22\14\0\1\22" + + "\7\0\3\22\7\0\2\22\3\0\4\22\4\0\10\22" + + "\3\0\5\22\1\206\20\22\14\0\1\22\7\0\3\22" + + "\7\0\2\22\3\0\4\22\4\0\10\22\3\0\2\22" + + "\1\207\3\22\1\210\5\22\1\211\11\22\14\0\1\22" + + "\7\0\3\22\7\0\2\22\3\0\4\22\4\0\7\22" + + "\1\212\3\0\10\22\1\213\1\22\1\214\2\22\1\215" + + "\10\22\14\0\1\22\7\0\3\22\7\0\2\22\3\0" + + "\4\22\4\0\10\22\3\0\22\22\1\216\3\22\14\0" + + "\1\22\7\0\3\22\7\0\2\22\3\0\4\22\4\0" + + "\7\22\1\217\3\0\2\22\1\220\7\22\1\221\13\22" + + "\14\0\1\22\7\0\3\22\7\0\2\22\3\0\4\22" + + "\4\0\10\22\3\0\1\22\1\222\14\22\1\223\1\22" + + "\1\224\5\22\14\0\1\22\7\0\3\22\7\0\2\22" + + "\3\0\4\22\4\0\3\22\1\225\4\22\3\0\5\22" + + "\1\226\1\22\1\227\11\22\1\230\4\22\14\0\1\22" + + "\7\0\3\22\7\0\2\22\3\0\4\22\4\0\10\22" + + "\3\0\5\22\1\231\1\22\1\232\16\22\14\0\1\22" + + "\7\0\3\22\7\0\2\22\3\0\4\22\4\0\7\22" + + "\1\233\3\0\6\22\1\234\11\22\1\235\5\22\14\0" + + "\1\22\7\0\3\22\7\0\2\22\3\0\4\22\4\0" + + "\10\22\3\0\11\22\1\236\4\22\1\237\7\22\14\0" + + "\1\22\7\0\3\22\7\0\2\22\3\0\4\22\4\0" + + "\10\22\3\0\1\22\1\240\1\241\7\22\1\242\13\22" + + "\14\0\1\22\7\0\3\22\7\0\2\22\3\0\4\22" + + "\4\0\10\22\3\0\2\22\1\243\3\22\1\244\17\22" + + "\14\0\1\22\7\0\3\22\7\0\2\22\3\0\4\22" + + "\4\0\7\22\1\245\3\0\26\22\14\0\1\22\7\0" + + "\3\22\7\0\2\22\3\0\4\22\4\0\10\22\3\0" + + "\7\22\1\246\16\22\14\0\1\22\7\0\3\22\7\0" + + "\2\22\3\0\4\22\4\0\10\22\3\0\2\22\1\247" + + "\23\22\14\0\1\22\33\0\1\250\52\0\1\251\40\0" + + "\1\252\53\0\1\253\37\0\1\254\113\0\1\255\61\0" + + "\1\102\2\0\30\102\1\0\12\102\1\0\45\102\2\0" + + "\1\104\111\0\1\256\3\0\27\256\1\257\1\260\1\256" + + "\1\261\1\256\1\262\5\256\1\263\1\256\1\264\1\265" + + "\5\256\1\266\1\267\1\256\1\270\30\256\1\0\1\107" + + "\2\0\31\107\1\0\11\107\1\0\45\107\2\0\1\111" + + "\113\0\1\113\114\0\1\114\7\0\1\114\116\0\1\271" + + "\105\0\2\272\3\0\1\272\1\0\4\272\2\0\4\272" + + "\1\0\1\273\2\0\10\272\3\0\26\272\16\0\1\274" + + "\2\0\30\274\1\275\60\274\10\0\2\276\3\0\1\276" + + "\1\0\4\276\2\0\4\276\1\0\1\277\2\0\10\276" + + "\3\0\26\276\34\0\1\300\75\0\1\301\2\0\30\301" + + "\1\302\1\303\57\301\31\0\1\304\64\0\1\133\126\0" + + "\1\305\102\0\1\306\3\0\1\307\3\0\1\310\2\0" + + "\2\307\2\0\1\311\1\0\4\307\5\0\3\307\2\0" + + "\2\307\3\0\26\307\2\0\1\312\13\0\1\137\2\0" + + "\43\137\2\0\44\137\1\313\3\0\32\313\1\314\1\313" + + "\1\262\5\313\1\263\1\313\1\264\1\265\5\313\1\266" + + "\1\267\1\313\1\315\27\313\1\316\1\0\1\142\1\317" + + "\1\320\111\142\5\321\1\322\106\321\11\0\1\323\123\0" + + "\1\150\13\0\1\150\3\0\2\150\2\164\57\0\2\152" + + "\3\0\1\152\1\0\4\152\2\0\4\152\4\0\10\152" + + "\3\0\26\152\50\0\1\324\113\0\1\325\77\0\1\326" + + "\13\0\1\327\76\0\1\330\3\0\1\331\13\0\1\331" + + "\3\0\2\331\2\0\1\330\100\0\1\332\72\0\1\150" + + "\7\0\1\166\13\0\1\166\3\0\2\166\2\164\60\0" + + "\1\150\7\0\1\166\13\0\1\167\3\0\1\171\1\172" + + "\2\164\67\0\2\333\3\0\3\333\5\0\1\334\2\0" + + "\5\333\3\0\1\333\1\0\1\333\1\0\1\333\6\0" + + "\1\333\41\0\1\150\7\0\1\166\13\0\1\172\3\0" + + "\2\172\2\164\60\0\1\150\7\0\1\166\13\0\1\335" + + "\3\0\2\335\2\164\55\0\3\22\7\0\2\22\3\0" + + "\4\22\4\0\10\22\3\0\14\22\1\336\11\22\14\0" + + "\1\22\7\0\3\22\7\0\2\22\3\0\4\22\4\0" + + "\10\22\3\0\1\22\1\337\24\22\14\0\1\22\7\0" + + "\3\22\7\0\2\22\3\0\4\22\4\0\10\22\3\0" + + "\7\22\1\340\16\22\14\0\1\22\7\0\3\22\7\0" + + "\2\22\3\0\4\22\4\0\10\22\3\0\7\22\1\341" + + "\16\22\14\0\1\22\7\0\3\22\7\0\2\22\3\0" + + "\4\22\4\0\10\22\3\0\10\22\1\342\15\22\14\0" + + "\1\22\7\0\3\22\7\0\2\22\3\0\4\22\4\0" + + "\10\22\3\0\4\22\1\343\21\22\14\0\1\22\7\0" + + "\3\22\7\0\2\22\3\0\4\22\4\0\10\22\3\0" + + "\5\22\1\344\20\22\14\0\1\22\7\0\3\22\7\0" + + "\2\22\3\0\4\22\4\0\7\22\1\345\3\0\26\22" + + "\14\0\1\22\7\0\3\22\7\0\2\22\3\0\4\22" + + "\4\0\10\22\3\0\10\22\1\346\15\22\14\0\1\22" + + "\7\0\3\22\7\0\2\22\3\0\4\22\4\0\10\22" + + "\3\0\5\22\1\347\2\22\1\350\15\22\14\0\1\22" + + "\7\0\3\22\7\0\2\22\3\0\4\22\4\0\10\22" + + "\3\0\7\22\1\351\16\22\14\0\1\22\7\0\3\22" + + "\7\0\2\22\3\0\4\22\4\0\10\22\3\0\2\22" + + "\1\352\23\22\14\0\1\22\7\0\3\22\7\0\2\22" + + "\3\0\4\22\4\0\10\22\3\0\10\22\1\353\15\22" + + "\14\0\1\22\7\0\3\22\7\0\2\22\3\0\4\22" + + "\4\0\10\22\3\0\2\22\1\354\23\22\14\0\1\22" + + "\7\0\3\22\7\0\2\22\3\0\4\22\4\0\10\22" + + "\3\0\17\22\1\355\6\22\14\0\1\22\7\0\3\22" + + "\7\0\2\22\3\0\4\22\4\0\10\22\3\0\11\22" + + "\1\356\14\22\14\0\1\22\7\0\3\22\7\0\2\22" + + "\3\0\4\22\4\0\7\22\1\357\3\0\26\22\14\0" + + "\1\22\7\0\3\22\7\0\2\22\3\0\4\22\4\0" + + "\10\22\3\0\15\22\1\360\10\22\14\0\1\22\7\0" + + "\3\22\7\0\2\22\3\0\4\22\4\0\10\22\3\0" + + "\10\22\1\361\10\22\1\362\4\22\14\0\1\22\7\0" + + "\3\22\7\0\2\22\3\0\4\22\4\0\10\22\3\0" + + "\14\22\1\363\11\22\14\0\1\22\7\0\3\22\7\0" + + "\2\22\3\0\4\22\4\0\10\22\3\0\12\22\1\364" + + "\5\22\1\365\5\22\14\0\1\22\7\0\3\22\7\0" + + "\2\22\3\0\4\22\4\0\10\22\3\0\1\22\1\366" + + "\7\22\1\367\14\22\14\0\1\22\7\0\3\22\7\0" + + "\2\22\3\0\4\22\4\0\10\22\3\0\17\22\1\370" + + "\6\22\14\0\1\22\7\0\3\22\7\0\2\22\3\0" + + "\4\22\4\0\10\22\3\0\5\22\1\371\2\22\1\372" + + "\15\22\14\0\1\22\7\0\3\22\7\0\2\22\3\0" + + "\4\22\4\0\10\22\3\0\17\22\1\373\6\22\14\0" + + "\1\22\7\0\3\22\7\0\2\22\3\0\4\22\4\0" + + "\7\22\1\374\3\0\26\22\14\0\1\22\7\0\3\22" + + "\7\0\2\22\3\0\4\22\4\0\10\22\3\0\13\22" + + "\1\375\12\22\14\0\1\22\7\0\3\22\7\0\2\22" + + "\3\0\4\22\4\0\3\22\1\376\4\22\3\0\14\22" + + "\1\377\11\22\14\0\1\22\7\0\3\22\7\0\2\22" + + "\3\0\4\22\4\0\10\22\3\0\7\22\1\u0100\16\22" + + "\14\0\1\22\7\0\3\22\7\0\2\22\3\0\4\22" + + "\4\0\10\22\3\0\10\22\1\u0101\15\22\14\0\1\22" + + "\7\0\3\22\7\0\2\22\3\0\4\22\4\0\10\22" + + "\3\0\11\22\1\u0102\14\22\14\0\1\22\7\0\3\22" + + "\7\0\2\22\3\0\4\22\4\0\10\22\3\0\6\22" + + "\1\u0103\2\22\1\u0104\14\22\14\0\1\22\7\0\3\22" + + "\7\0\2\22\3\0\4\22\4\0\10\22\3\0\4\22" + + "\1\u0105\21\22\14\0\1\22\7\0\3\22\7\0\2\22" + + "\3\0\4\22\4\0\10\22\3\0\1\u0106\25\22\14\0" + + "\1\22\7\0\3\22\7\0\2\22\3\0\4\22\4\0" + + "\10\22\3\0\1\22\1\u0107\24\22\14\0\1\22\7\0" + + "\3\22\7\0\2\22\3\0\4\22\4\0\10\22\3\0" + + "\11\22\1\u0108\14\22\14\0\1\22\7\0\3\22\7\0" + + "\2\22\3\0\4\22\4\0\10\22\3\0\10\22\1\u0109" + + "\15\22\14\0\1\22\7\0\3\22\7\0\2\22\3\0" + + "\4\22\4\0\3\22\1\u010a\4\22\3\0\26\22\14\0" + + "\1\22\7\0\3\22\7\0\2\22\3\0\4\22\4\0" + + "\10\22\3\0\25\22\1\u010b\14\0\1\22\21\0\2\u010c" + + "\3\0\3\u010c\5\0\1\u010c\2\0\5\u010c\3\0\1\u010c" + + "\1\0\1\u010c\1\0\1\u010c\6\0\1\u010c\50\0\2\u010d" + + "\3\0\3\u010d\5\0\1\u010d\2\0\5\u010d\3\0\1\u010d" + + "\1\0\1\u010d\1\0\1\u010d\6\0\1\u010d\30\0\1\u010e" + + "\2\0\30\u010e\1\302\1\0\57\u010e\1\303\2\0\30\303" + + "\1\u010f\60\303\16\0\1\u0110\113\0\1\u0111\105\0\1\u0112" + + "\6\0\2\u0112\4\0\4\u0112\5\0\3\u0112\2\0\2\u0112" + + "\3\0\26\u0112\2\0\1\u0113\23\0\2\307\3\0\1\307" + + "\1\0\4\307\2\0\4\307\4\0\10\307\3\0\26\307" + + "\33\0\1\u0114\6\0\1\u0115\77\0\1\u0116\6\0\2\u0116" + + "\4\0\4\u0116\5\0\3\u0116\2\0\2\u0116\3\0\26\u0116" + + "\2\0\1\u0117\62\0\1\u0118\46\0\1\320\111\0\5\321" + + "\1\u0119\106\321\4\0\1\320\1\322\140\0\1\u011a\102\0" + + "\1\331\13\0\1\331\3\0\2\331\71\0\2\u011b\3\0" + + "\3\u011b\5\0\1\u011b\2\0\5\u011b\3\0\1\u011b\1\0" + + "\1\u011b\1\0\1\u011b\6\0\1\u011b\41\0\1\150\7\0" + + "\1\166\13\0\1\u011c\3\0\2\u011c\2\164\55\0\3\22" + + "\7\0\2\22\3\0\4\22\4\0\10\22\3\0\5\22" + + "\1\u011d\20\22\14\0\1\22\7\0\3\22\7\0\2\22" + + "\3\0\4\22\4\0\10\22\3\0\2\22\1\u011e\23\22" + + "\14\0\1\22\7\0\3\22\7\0\2\22\3\0\4\22" + + "\4\0\10\22\3\0\4\22\1\u011f\21\22\14\0\1\22" + + "\7\0\3\22\7\0\2\22\3\0\4\22\4\0\7\22" + + "\1\u0120\3\0\26\22\14\0\1\22\7\0\3\22\7\0" + + "\2\22\3\0\4\22\4\0\10\22\3\0\16\22\1\u0121" + + "\7\22\14\0\1\22\7\0\3\22\7\0\2\22\3\0" + + "\4\22\4\0\7\22\1\u0122\3\0\26\22\14\0\1\22" + + "\7\0\3\22\7\0\2\22\3\0\4\22\4\0\10\22" + + "\3\0\2\22\1\u0123\23\22\14\0\1\22\7\0\3\22" + + "\7\0\2\22\3\0\4\22\4\0\10\22\3\0\12\22" + + "\1\u0124\13\22\14\0\1\22\7\0\3\22\7\0\2\22" + + "\3\0\4\22\4\0\7\22\1\u0125\3\0\26\22\14\0" + + "\1\22\7\0\3\22\7\0\2\22\3\0\4\22\4\0" + + "\10\22\3\0\4\22\1\u0126\21\22\14\0\1\22\7\0" + + "\3\22\7\0\2\22\3\0\4\22\4\0\10\22\3\0" + + "\5\22\1\u0127\2\22\1\u0128\15\22\14\0\1\22\7\0" + + "\3\22\7\0\2\22\3\0\4\22\4\0\10\22\3\0" + + "\5\22\1\u0129\20\22\14\0\1\22\7\0\3\22\7\0" + + "\2\22\3\0\4\22\4\0\10\22\3\0\10\22\1\u012a" + + "\15\22\14\0\1\22\7\0\3\22\7\0\2\22\3\0" + + "\4\22\4\0\7\22\1\u012b\3\0\26\22\14\0\1\22" + + "\7\0\3\22\7\0\2\22\3\0\4\22\4\0\10\22" + + "\3\0\10\22\1\u012c\15\22\14\0\1\22\7\0\3\22" + + "\7\0\2\22\3\0\4\22\4\0\10\22\3\0\1\22" + + "\1\u012d\24\22\14\0\1\22\7\0\3\22\7\0\2\22" + + "\3\0\4\22\4\0\10\22\3\0\11\22\1\u012e\14\22" + + "\14\0\1\22\7\0\3\22\7\0\2\22\3\0\4\22" + + "\4\0\7\22\1\u012f\3\0\26\22\14\0\1\22\7\0" + + "\3\22\7\0\2\22\3\0\4\22\4\0\10\22\3\0" + + "\14\22\1\u0130\11\22\14\0\1\22\7\0\3\22\7\0" + + "\2\22\3\0\4\22\4\0\7\22\1\u0131\3\0\26\22" + + "\14\0\1\22\7\0\3\22\7\0\2\22\3\0\4\22" + + "\4\0\10\22\3\0\6\22\1\u0132\17\22\14\0\1\22" + + "\7\0\3\22\7\0\2\22\3\0\4\22\4\0\10\22" + + "\3\0\5\22\1\u0133\20\22\14\0\1\22\7\0\3\22" + + "\7\0\2\22\3\0\4\22\4\0\7\22\1\u0134\3\0" + + "\26\22\14\0\1\22\7\0\3\22\7\0\2\22\3\0" + + "\4\22\4\0\10\22\3\0\10\22\1\u0135\15\22\14\0" + + "\1\22\7\0\3\22\7\0\2\22\3\0\4\22\4\0" + + "\7\22\1\u0136\3\0\26\22\14\0\1\22\7\0\3\22" + + "\7\0\2\22\3\0\4\22\4\0\10\22\3\0\6\22" + + "\1\u0137\5\22\1\u0138\11\22\14\0\1\22\7\0\3\22" + + "\7\0\2\22\3\0\4\22\4\0\7\22\1\u0139\3\0" + + "\26\22\14\0\1\22\7\0\3\22\7\0\2\22\3\0" + + "\4\22\4\0\10\22\3\0\2\22\1\u013a\23\22\14\0" + + "\1\22\7\0\3\22\7\0\2\22\3\0\4\22\4\0" + + "\7\22\1\u013b\3\0\26\22\14\0\1\22\7\0\3\22" + + "\7\0\2\22\3\0\4\22\4\0\10\22\3\0\2\22" + + "\1\u013c\23\22\14\0\1\22\7\0\3\22\7\0\2\22" + + "\3\0\4\22\4\0\10\22\3\0\16\22\1\u013d\7\22" + + "\14\0\1\22\7\0\3\22\7\0\2\22\3\0\4\22" + + "\4\0\10\22\3\0\14\22\1\u013e\11\22\14\0\1\22" + + "\7\0\3\22\7\0\2\22\3\0\4\22\4\0\10\22" + + "\3\0\10\22\1\u013f\15\22\14\0\1\22\7\0\3\22" + + "\7\0\2\22\3\0\4\22\4\0\10\22\3\0\22\22" + + "\1\u0140\3\22\14\0\1\22\7\0\3\22\7\0\2\22" + + "\3\0\4\22\4\0\10\22\3\0\3\22\1\u0141\22\22" + + "\14\0\1\22\7\0\3\22\7\0\2\22\3\0\4\22" + + "\4\0\10\22\3\0\14\22\1\u0142\11\22\14\0\1\22" + + "\7\0\3\22\7\0\2\22\3\0\4\22\4\0\10\22" + + "\3\0\13\22\1\u0143\12\22\14\0\1\22\7\0\3\22" + + "\7\0\2\22\3\0\4\22\4\0\10\22\3\0\11\22" + + "\1\u0144\14\22\14\0\1\22\21\0\2\u0145\3\0\3\u0145" + + "\5\0\1\u0145\2\0\5\u0145\3\0\1\u0145\1\0\1\u0145" + + "\1\0\1\u0145\6\0\1\u0145\50\0\2\u0146\3\0\3\u0146" + + "\5\0\1\u0146\2\0\5\u0146\3\0\1\u0146\1\0\1\u0146" + + "\1\0\1\u0146\6\0\1\u0146\31\0\2\u0147\5\0\2\u0112" + + "\1\0\1\u0147\1\0\1\u0112\1\u0148\4\u0112\2\0\4\u0112" + + "\4\0\10\u0112\3\0\26\u0112\33\0\1\u0149\123\0\1\u014a" + + "\76\0\2\u0116\3\0\1\u0116\1\0\4\u0116\2\0\4\u0116" + + "\4\0\10\u0116\3\0\26\u0116\16\0\4\321\1\320\1\u0119" + + "\106\321\20\0\2\u014b\3\0\3\u014b\5\0\1\u014b\2\0" + + "\5\u014b\3\0\1\u014b\1\0\1\u014b\1\0\1\u014b\6\0" + + "\1\u014b\41\0\1\150\7\0\1\166\13\0\1\u014c\3\0" + + "\2\u014c\2\164\55\0\3\22\7\0\2\22\3\0\4\22" + + "\4\0\7\22\1\u014d\3\0\26\22\14\0\1\22\7\0" + + "\3\22\7\0\2\22\3\0\4\22\4\0\10\22\3\0" + + "\14\22\1\u014e\11\22\14\0\1\22\7\0\3\22\7\0" + + "\2\22\3\0\4\22\4\0\10\22\3\0\10\22\1\u014f" + + "\15\22\14\0\1\22\7\0\3\22\7\0\2\22\3\0" + + "\4\22\4\0\10\22\3\0\7\22\1\u0150\16\22\14\0" + + "\1\22\7\0\3\22\7\0\2\22\3\0\4\22\4\0" + + "\10\22\3\0\3\22\1\u0151\22\22\14\0\1\22\7\0" + + "\3\22\7\0\2\22\3\0\4\22\4\0\10\22\3\0" + + "\1\22\1\u0152\24\22\14\0\1\22\7\0\3\22\7\0" + + "\2\22\3\0\4\22\4\0\10\22\3\0\16\22\1\u0153" + + "\7\22\14\0\1\22\7\0\3\22\7\0\2\22\3\0" + + "\4\22\4\0\10\22\3\0\10\22\1\u0154\15\22\14\0" + + "\1\22\7\0\3\22\7\0\2\22\3\0\4\22\4\0" + + "\10\22\3\0\11\22\1\u0155\14\22\14\0\1\22\7\0" + + "\3\22\7\0\2\22\3\0\4\22\4\0\10\22\3\0" + + "\5\22\1\u0156\20\22\14\0\1\22\7\0\3\22\7\0" + + "\2\22\3\0\4\22\4\0\10\22\3\0\11\22\1\u0157" + + "\14\22\14\0\1\22\7\0\3\22\7\0\2\22\3\0" + + "\4\22\4\0\10\22\3\0\1\22\1\u0158\24\22\14\0" + + "\1\22\7\0\3\22\7\0\2\22\3\0\4\22\4\0" + + "\10\22\3\0\4\22\1\u0159\21\22\14\0\1\22\7\0" + + "\3\22\7\0\2\22\3\0\4\22\4\0\10\22\3\0" + + "\1\22\1\u015a\24\22\14\0\1\22\7\0\3\22\7\0" + + "\2\22\3\0\4\22\4\0\10\22\3\0\22\22\1\u015b" + + "\3\22\14\0\1\22\7\0\3\22\7\0\2\22\3\0" + + "\4\22\4\0\10\22\3\0\5\22\1\u015c\20\22\14\0" + + "\1\22\7\0\3\22\7\0\2\22\3\0\4\22\4\0" + + "\10\22\3\0\15\22\1\u015d\10\22\14\0\1\22\7\0" + + "\3\22\7\0\2\22\3\0\4\22\4\0\10\22\3\0" + + "\6\22\1\u015e\17\22\14\0\1\22\7\0\3\22\7\0" + + "\2\22\3\0\4\22\4\0\10\22\3\0\2\22\1\u015f" + + "\23\22\14\0\1\22\7\0\3\22\7\0\2\22\3\0" + + "\4\22\4\0\10\22\3\0\1\22\1\u0160\24\22\14\0" + + "\1\22\7\0\3\22\7\0\2\22\3\0\4\22\4\0" + + "\10\22\3\0\1\22\1\u0161\24\22\14\0\1\22\7\0" + + "\3\22\7\0\2\22\3\0\4\22\4\0\7\22\1\u0162" + + "\3\0\26\22\14\0\1\22\7\0\3\22\7\0\2\22" + + "\3\0\4\22\4\0\3\22\1\u0163\4\22\3\0\26\22" + + "\14\0\1\22\7\0\3\22\7\0\2\22\3\0\4\22" + + "\4\0\10\22\3\0\12\22\1\u0164\13\22\14\0\1\22" + + "\7\0\3\22\7\0\2\22\3\0\4\22\4\0\10\22" + + "\3\0\10\22\1\u0165\15\22\14\0\1\22\7\0\3\22" + + "\7\0\2\22\3\0\4\22\4\0\10\22\3\0\21\22" + + "\1\u0166\4\22\14\0\1\22\7\0\3\22\7\0\2\22" + + "\3\0\4\22\4\0\7\22\1\u0167\3\0\26\22\14\0" + + "\1\22\7\0\3\22\7\0\2\22\3\0\4\22\4\0" + + "\7\22\1\u0168\3\0\26\22\14\0\1\22\7\0\3\22" + + "\7\0\2\22\3\0\4\22\4\0\10\22\3\0\2\22" + + "\1\u0169\23\22\14\0\1\22\7\0\3\22\7\0\2\22" + + "\3\0\4\22\4\0\10\22\3\0\2\22\1\u016a\23\22" + + "\14\0\1\22\7\0\3\22\7\0\2\22\3\0\4\22" + + "\4\0\10\22\3\0\11\22\1\u016b\14\22\14\0\1\22" + + "\7\0\3\22\7\0\2\22\3\0\4\22\4\0\10\22" + + "\3\0\7\22\1\u016c\16\22\14\0\1\22\2\0\2\u0147" + + "\10\0\1\u0147\2\0\1\u0148\123\0\1\u016d\105\0\2\u016e" + + "\3\0\3\u016e\5\0\1\u016e\2\0\5\u016e\3\0\1\u016e" + + "\1\0\1\u016e\1\0\1\u016e\6\0\1\u016e\41\0\1\150" + + "\7\0\1\166\13\0\1\u016f\3\0\2\u016f\2\164\55\0" + + "\3\22\7\0\2\22\3\0\4\22\4\0\10\22\3\0" + + "\14\22\1\u0170\11\22\14\0\1\22\7\0\3\22\7\0" + + "\2\22\3\0\4\22\4\0\10\22\3\0\11\22\1\u0171" + + "\14\22\14\0\1\22\7\0\3\22\7\0\2\22\3\0" + + "\4\22\4\0\10\22\3\0\13\22\1\u0172\12\22\14\0" + + "\1\22\7\0\3\22\7\0\2\22\3\0\4\22\4\0" + + "\10\22\3\0\7\22\1\u0173\16\22\14\0\1\22\7\0" + + "\3\22\7\0\2\22\3\0\4\22\4\0\10\22\3\0" + + "\7\22\1\u0174\16\22\14\0\1\22\7\0\3\22\7\0" + + "\2\22\3\0\4\22\4\0\10\22\3\0\4\22\1\u0175" + + "\21\22\14\0\1\22\7\0\3\22\7\0\2\22\3\0" + + "\4\22\4\0\10\22\3\0\16\22\1\u0176\7\22\14\0" + + "\1\22\7\0\3\22\7\0\2\22\3\0\4\22\4\0" + + "\10\22\3\0\11\22\1\u0177\14\22\14\0\1\22\7\0" + + "\3\22\7\0\2\22\3\0\4\22\4\0\7\22\1\u0178" + + "\3\0\26\22\14\0\1\22\7\0\3\22\7\0\2\22" + + "\3\0\4\22\4\0\10\22\3\0\17\22\1\u0179\6\22" + + "\14\0\1\22\7\0\3\22\7\0\2\22\3\0\4\22" + + "\4\0\3\22\1\u017a\4\22\3\0\26\22\14\0\1\22" + + "\7\0\3\22\7\0\2\22\3\0\4\22\4\0\10\22" + + "\3\0\7\22\1\u017b\16\22\14\0\1\22\7\0\3\22" + + "\7\0\2\22\3\0\4\22\4\0\3\22\1\u017c\4\22" + + "\3\0\7\22\1\u017d\16\22\14\0\1\22\7\0\3\22" + + "\7\0\2\22\3\0\4\22\4\0\10\22\3\0\10\22" + + "\1\u017e\15\22\14\0\1\22\7\0\3\22\7\0\2\22" + + "\3\0\4\22\4\0\10\22\3\0\21\22\1\u017f\4\22" + + "\14\0\1\22\7\0\3\22\7\0\2\22\3\0\4\22" + + "\4\0\10\22\3\0\11\22\1\u0180\14\22\14\0\1\22" + + "\7\0\3\22\7\0\2\22\3\0\4\22\4\0\10\22" + + "\3\0\14\22\1\u0181\11\22\14\0\1\22\7\0\3\22" + + "\7\0\2\22\3\0\4\22\4\0\7\22\1\u0182\3\0" + + "\26\22\14\0\1\22\7\0\3\22\7\0\2\22\3\0" + + "\4\22\4\0\10\22\3\0\11\22\1\u0183\14\22\14\0" + + "\1\22\7\0\3\22\7\0\2\22\3\0\4\22\4\0" + + "\10\22\3\0\4\22\1\u0184\21\22\14\0\1\22\7\0" + + "\3\22\7\0\2\22\3\0\4\22\4\0\10\22\3\0" + + "\10\22\1\u0185\15\22\14\0\1\22\7\0\3\22\7\0" + + "\2\22\3\0\4\22\4\0\10\22\3\0\23\22\1\u0186" + + "\2\22\14\0\1\22\7\0\3\22\7\0\2\22\3\0" + + "\4\22\4\0\10\22\3\0\4\22\1\u0187\21\22\14\0" + + "\1\22\7\0\3\22\7\0\2\22\3\0\4\22\4\0" + + "\10\22\3\0\11\22\1\u0188\14\22\14\0\1\22\30\0" + + "\1\u0189\104\0\2\u018a\3\0\3\u018a\5\0\1\u018a\2\0" + + "\5\u018a\3\0\1\u018a\1\0\1\u018a\1\0\1\u018a\6\0" + + "\1\u018a\41\0\1\150\7\0\1\166\13\0\1\u018b\3\0" + + "\2\u018b\2\164\55\0\3\22\7\0\2\22\3\0\4\22" + + "\4\0\10\22\3\0\20\22\1\u018c\5\22\14\0\1\22" + + "\7\0\3\22\7\0\2\22\3\0\4\22\4\0\10\22" + + "\3\0\6\22\1\u018d\17\22\14\0\1\22\7\0\3\22" + + "\7\0\2\22\3\0\4\22\4\0\10\22\3\0\5\22" + + "\1\u018e\20\22\14\0\1\22\7\0\3\22\7\0\2\22" + + "\3\0\4\22\4\0\10\22\3\0\12\22\1\u018f\13\22" + + "\14\0\1\22\7\0\3\22\7\0\2\22\3\0\4\22" + + "\4\0\10\22\3\0\13\22\1\u0190\12\22\14\0\1\22" + + "\7\0\3\22\7\0\2\22\3\0\4\22\4\0\10\22" + + "\3\0\2\22\1\u0191\23\22\14\0\1\22\7\0\3\22" + + "\7\0\2\22\3\0\4\22\4\0\10\22\3\0\4\22" + + "\1\u0192\21\22\14\0\1\22\7\0\3\22\7\0\2\22" + + "\3\0\4\22\4\0\10\22\3\0\2\22\1\u0193\23\22" + + "\14\0\1\22\7\0\3\22\7\0\2\22\3\0\4\22" + + "\4\0\10\22\3\0\2\22\1\u0194\23\22\14\0\1\22" + + "\7\0\3\22\7\0\2\22\3\0\4\22\4\0\7\22" + + "\1\u0195\3\0\26\22\14\0\1\22\7\0\3\22\7\0" + + "\2\22\3\0\4\22\4\0\10\22\3\0\7\22\1\u0196" + + "\16\22\14\0\1\22\7\0\3\22\7\0\2\22\3\0" + + "\4\22\4\0\10\22\3\0\10\22\1\u0197\15\22\14\0" + + "\1\22\7\0\3\22\7\0\2\22\3\0\4\22\4\0" + + "\10\22\3\0\4\22\1\u0198\21\22\14\0\1\22\7\0" + + "\3\22\7\0\2\22\3\0\4\22\4\0\10\22\3\0" + + "\10\22\1\u0199\15\22\14\0\1\22\7\0\3\22\7\0" + + "\2\22\3\0\4\22\4\0\7\22\1\u019a\3\0\26\22" + + "\14\0\1\22\7\0\3\22\7\0\2\22\3\0\4\22" + + "\4\0\7\22\1\u019b\3\0\26\22\14\0\1\22\7\0" + + "\3\22\7\0\2\22\3\0\4\22\4\0\10\22\3\0" + + "\10\22\1\u019c\15\22\14\0\1\22\31\0\1\u019d\103\0" + + "\2\u019e\3\0\3\u019e\5\0\1\u019e\2\0\5\u019e\3\0" + + "\1\u019e\1\0\1\u019e\1\0\1\u019e\6\0\1\u019e\41\0" + + "\1\150\7\0\1\166\13\0\1\u019f\3\0\2\u019f\2\164" + + "\55\0\3\22\7\0\2\22\3\0\4\22\4\0\10\22" + + "\3\0\7\22\1\u01a0\16\22\14\0\1\22\7\0\3\22" + + "\7\0\2\22\3\0\4\22\4\0\7\22\1\u01a1\3\0" + + "\26\22\14\0\1\22\7\0\3\22\7\0\2\22\3\0" + + "\4\22\4\0\7\22\1\u01a2\3\0\26\22\14\0\1\22" + + "\7\0\3\22\7\0\2\22\3\0\4\22\4\0\10\22" + + "\3\0\4\22\1\u01a3\21\22\14\0\1\22\7\0\3\22" + + "\7\0\2\22\3\0\4\22\4\0\7\22\1\u01a4\3\0" + + "\26\22\14\0\1\22\7\0\3\22\7\0\2\22\3\0" + + "\4\22\4\0\10\22\3\0\4\22\1\u01a5\21\22\14\0" + + "\1\22\7\0\3\22\7\0\2\22\3\0\4\22\4\0" + + "\10\22\3\0\14\22\1\u01a6\11\22\14\0\1\22\7\0" + + "\3\22\7\0\2\22\3\0\4\22\4\0\10\22\3\0" + + "\7\22\1\u01a7\16\22\14\0\1\22\7\0\3\22\7\0" + + "\2\22\3\0\4\22\4\0\7\22\1\u01a8\3\0\26\22" + + "\14\0\1\22\7\0\3\22\7\0\2\22\3\0\4\22" + + "\4\0\7\22\1\u01a9\3\0\26\22\14\0\1\22\7\0" + + "\3\22\7\0\2\22\3\0\4\22\4\0\10\22\3\0" + + "\20\22\1\u01aa\5\22\14\0\1\22\30\0\1\u01ab\104\0" + + "\2\u01ac\3\0\3\u01ac\5\0\1\u01ac\2\0\5\u01ac\3\0" + + "\1\u01ac\1\0\1\u01ac\1\0\1\u01ac\6\0\1\u01ac\41\0" + + "\1\150\7\0\1\166\13\0\1\u01ad\3\0\2\u01ad\2\164" + + "\55\0\3\22\7\0\2\22\3\0\4\22\4\0\7\22" + + "\1\u01ae\3\0\26\22\14\0\1\22\7\0\3\22\7\0" + + "\2\22\3\0\4\22\4\0\10\22\3\0\6\22\1\u01af" + + "\17\22\14\0\1\22\7\0\3\22\7\0\2\22\3\0" + + "\4\22\4\0\7\22\1\u01b0\3\0\26\22\14\0\1\22" + + "\7\0\3\22\7\0\2\22\3\0\4\22\4\0\10\22" + + "\3\0\10\22\1\u01b1\15\22\14\0\1\22\7\0\3\22" + + "\7\0\2\22\3\0\4\22\4\0\10\22\3\0\13\22" + + "\1\u01b2\12\22\14\0\1\22\7\0\3\22\7\0\2\22" + + "\3\0\4\22\4\0\10\22\3\0\13\22\1\u01b3\12\22" + + "\14\0\1\22\25\0\1\u01b4\107\0\2\u01b5\3\0\3\u01b5" + + "\5\0\1\u01b5\2\0\5\u01b5\3\0\1\u01b5\1\0\1\u01b5" + + "\1\0\1\u01b5\6\0\1\u01b5\41\0\1\150\7\0\1\166" + + "\13\0\1\u01b6\3\0\2\u01b6\2\164\55\0\3\22\7\0" + + "\2\22\3\0\4\22\4\0\3\22\1\u01b7\4\22\3\0" + + "\26\22\14\0\1\22\7\0\3\22\7\0\2\22\3\0" + + "\4\22\4\0\10\22\3\0\5\22\1\u01b8\20\22\14\0" + + "\1\22\12\0\1\150\7\0\1\166\13\0\1\u01b9\3\0" + + "\2\u01b9\2\164\60\0\1\150\7\0\1\166\13\0\1\u01ba" + + "\3\0\2\u01ba\2\164\60\0\1\150\7\0\1\166\13\0" + + "\1\u01bb\3\0\2\u01bb\2\164\60\0\1\150\7\0\1\166" + + "\13\0\1\u01bc\3\0\2\u01bc\2\164\60\0\1\150\7\0" + + "\1\166\13\0\1\u01bd\3\0\2\u01bd\2\164\60\0\1\150" + + "\7\0\1\166\13\0\1\u01be\3\0\2\u01be\2\164\47\0"; + + private static int[] zzUnpackTrans() { + int[] result = new int[22952]; + int offset = 0; + offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackTrans(String packed, int offset, int[] result) { + int i = 0; /* index in packed string */ + + int j = offset; /* index in unpacked array */ + + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + value--; + do { + result[j++] = value; + } while (--count > 0); + } + return j; + } + + + /* error codes */ + private static final int ZZ_UNKNOWN_ERROR = 0; + + private static final int ZZ_NO_MATCH = 1; + + private static final int ZZ_PUSHBACK_2BIG = 2; + + /* error messages for the codes above */ + private static final String ZZ_ERROR_MSG[] = { + "Unkown internal scanner error", + "Error: could not match input", + "Error: pushback value was too large" + }; + + /** + * ZZ_ATTRIBUTE[aState] contains the attributes of state aState + */ + private static final int[] ZZ_ATTRIBUTE = zzUnpackAttribute(); + + private static final String ZZ_ATTRIBUTE_PACKED_0 + = "\13\0\1\11\1\1\1\11\13\1\3\11\1\1\2\11" + + "\4\1\1\11\21\1\7\11\4\1\1\11\2\1\2\11" + + "\3\1\1\11\1\1\1\11\3\1\2\11\1\1\1\11" + + "\2\1\1\11\1\1\2\11\2\1\1\11\2\1\1\11" + + "\2\1\1\11\1\1\1\0\2\11\1\1\1\11\1\1" + + "\1\11\2\1\2\11\1\1\2\11\1\1\2\11\1\0" + + "\3\1\1\0\11\1\2\11\44\1\11\11\1\1\6\11" + + "\1\1\1\11\1\0\1\11\1\0\1\11\1\0\2\11" + + "\1\0\1\1\4\0\1\1\2\0\2\11\4\1\1\11" + + "\2\0\3\11\1\1\1\11\1\0\1\1\1\11\61\1" + + "\3\0\3\11\1\0\1\11\2\0\1\1\2\11\1\0" + + "\1\11\52\1\1\11\2\0\2\11\1\0\42\1\1\0" + + "\33\1\1\0\23\1\1\0\15\1\1\0\10\1\2\11" + + "\11\1"; + + private static int[] zzUnpackAttribute() { + int[] result = new int[446]; + int offset = 0; + offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackAttribute(String packed, int offset, int[] result) { + int i = 0; /* index in packed string */ + + int j = offset; /* index in unpacked array */ + + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + do { + result[j++] = value; + } while (--count > 0); + } + return j; + } + + /** + * the input device + */ + private java.io.Reader zzReader; + + /** + * the current state of the DFA + */ + private int zzState; + + /** + * the current lexical state + */ + private int zzLexicalState = YYINITIAL; + + /** + * this buffer contains the current text to be matched and is + * the source of the yytext() string + */ + private char zzBuffer[] = new char[ZZ_BUFFERSIZE]; + + /** + * the textposition at the last accepting state + */ + private int zzMarkedPos; + + /** + * the current text position in the buffer + */ + private int zzCurrentPos; + + /** + * startRead marks the beginning of the yytext() string in the buffer + */ + private int zzStartRead; + + /** + * endRead marks the last character in the buffer, that has been read + * from input + */ + private int zzEndRead; + + /** + * number of newlines encountered up to the start of the matched text + */ + private int yyline; + + /** + * the number of characters up to the start of the matched text + */ + private int yychar; + + /** + * the number of characters from the last newline up to the start of the + * matched text + */ + private int yycolumn; + + /** + * zzAtBOL == true <=> the scanner is currently at the beginning of a line + */ + private boolean zzAtBOL = true; + + /** + * zzAtEOF == true <=> the scanner is at the EOF + */ + private boolean zzAtEOF; + + /** + * denotes if the user-EOF-code has already been executed + */ + private boolean zzEOFDone; + + /** + * The number of occupied positions in zzBuffer beyond zzEndRead. + * When a lead/high surrogate has been read from the input stream + * into the final zzBuffer position, this will have a value of 1; + * otherwise, it will have a value of 0. + */ + private int zzFinalHighSurrogate = 0; + + /* user code: */ + private String sourceCode; + + public ActionScriptLexer(String sourceCode) { + this(new StringReader(sourceCode)); + this.sourceCode = sourceCode; + } + + public void yypushbackstr(String s, int state) { + sourceCode = s + sourceCode.substring(yychar + yylength()); + yyreset(new StringReader(sourceCode)); + yybegin(state); + } + + public void yypushbackstr(String s) { + yypushbackstr(s, YYINITIAL); + } + + StringBuffer string = new StringBuffer(); + + private static String xmlTagName = ""; + + public int yychar() { + return yychar; + } + + private Stack pushedBack = new Stack<>(); + + public int yyline() { + return yyline + 1; + } + + private List listeners = new ArrayList<>(); + + public void addListener(LexListener listener) { + listeners.add(listener); + } + + public void removeListener(LexListener listener) { + listeners.remove(listener); + } + + public void informListenersLex(ParsedSymbol s) { + for (LexListener l : listeners) { + l.onLex(s); + } + } + + public void informListenersPushBack(ParsedSymbol s) { + for (LexListener l : listeners) { + l.onPushBack(s); + } + } + + public void pushback(ParsedSymbol symb) { + pushedBack.push(symb); + last = null; + informListenersPushBack(symb); + } + + ParsedSymbol last; + + public ParsedSymbol lex() throws java.io.IOException, AVM2ParseException { + ParsedSymbol ret = null; + if (!pushedBack.isEmpty()) { + ret = last = pushedBack.pop(); + } else { + ret = last = yylex(); + } + informListenersLex(ret); + return ret; + } + + /** + * Creates a new scanner + * + * @param in the java.io.Reader to read input from. + */ + public ActionScriptLexer(java.io.Reader in) { + this.zzReader = in; + } + + /** + * Unpacks the compressed character translation table. + * + * @param packed the packed character translation table + * @return the unpacked character translation table + */ + private static char[] zzUnpackCMap(String packed) { + char[] map = new char[0x110000]; + int i = 0; /* index in packed string */ + + int j = 0; /* index in unpacked array */ + + while (i < 3140) { + int count = packed.charAt(i++); + char value = packed.charAt(i++); + do { + map[j++] = value; + } while (--count > 0); + } + return map; + } + + /** + * Refills the input buffer. + * + * @return false, iff there was new input. + * + * @exception java.io.IOException if any I/O-Error occurs + */ + private boolean zzRefill() throws java.io.IOException { + + /* first: make room (if you can) */ + if (zzStartRead > 0) { + zzEndRead += zzFinalHighSurrogate; + zzFinalHighSurrogate = 0; + System.arraycopy(zzBuffer, zzStartRead, + zzBuffer, 0, + zzEndRead - zzStartRead); + + /* translate stored positions */ + zzEndRead -= zzStartRead; + zzCurrentPos -= zzStartRead; + zzMarkedPos -= zzStartRead; + zzStartRead = 0; + } + + /* is the buffer big enough? */ + if (zzCurrentPos >= zzBuffer.length - zzFinalHighSurrogate) { + /* if not: blow it up */ + char newBuffer[] = new char[zzBuffer.length * 2]; + System.arraycopy(zzBuffer, 0, newBuffer, 0, zzBuffer.length); + zzBuffer = newBuffer; + zzEndRead += zzFinalHighSurrogate; + zzFinalHighSurrogate = 0; + } + + /* fill the buffer with new input */ + int requested = zzBuffer.length - zzEndRead; + int totalRead = 0; + while (totalRead < requested) { + int numRead = zzReader.read(zzBuffer, zzEndRead + totalRead, requested - totalRead); + if (numRead == -1) { + break; + } + totalRead += numRead; + } + + if (totalRead > 0) { + zzEndRead += totalRead; + if (totalRead == requested) { /* possibly more input available */ + + if (Character.isHighSurrogate(zzBuffer[zzEndRead - 1])) { + --zzEndRead; + zzFinalHighSurrogate = 1; + } + } + return false; + } + + // totalRead = 0: End of stream + return true; + } + + /** + * Closes the input stream. + */ + public final void yyclose() throws java.io.IOException { + zzAtEOF = true; /* indicate end of file */ + + zzEndRead = zzStartRead; /* invalidate buffer */ + + if (zzReader != null) { + zzReader.close(); + } + } + + /** + * Resets the scanner to read from a new input stream. + * Does not close the old reader. + * + * All internal variables are reset, the old input stream + * cannot be reused (internal buffer is discarded and lost). + * Lexical state is set to ZZ_INITIAL. + * + * Internal scan buffer is resized down to its initial length, if it has + * grown. + * + * @param reader the new input stream + */ + public final void yyreset(java.io.Reader reader) { + zzReader = reader; + zzAtBOL = true; + zzAtEOF = false; + zzEOFDone = false; + zzEndRead = zzStartRead = 0; + zzCurrentPos = zzMarkedPos = 0; + zzFinalHighSurrogate = 0; + yyline = yychar = yycolumn = 0; + zzLexicalState = YYINITIAL; + if (zzBuffer.length > ZZ_BUFFERSIZE) { + zzBuffer = new char[ZZ_BUFFERSIZE]; + } + } + + /** + * Returns the current lexical state. + */ + public final int yystate() { + return zzLexicalState; + } + + /** + * Enters a new lexical state + * + * @param newState the new lexical state + */ + public final void yybegin(int newState) { + zzLexicalState = newState; + } + + /** + * Returns the text matched by the current regular expression. + */ + public final String yytext() { + return new String(zzBuffer, zzStartRead, zzMarkedPos - zzStartRead); + } + + /** + * Returns the character at position pos from the + * matched text. + * + * It is equivalent to yytext().charAt(pos), but faster + * + * @param pos the position of the character to fetch. + * A value from 0 to yylength()-1. + * + * @return the character at position pos + */ + public final char yycharat(int pos) { + return zzBuffer[zzStartRead + pos]; + } + + /** + * Returns the length of the matched text region. + */ + public final int yylength() { + return zzMarkedPos - zzStartRead; + } + + /** + * Reports an error that occured while scanning. + * + * In a wellformed scanner (no or only correct usage of + * yypushback(int) and a match-all fallback rule) this method + * will only be called with things that "Can't Possibly Happen". + * If this method is called, something is seriously wrong + * (e.g. a JFlex bug producing a faulty scanner etc.). + * + * Usual syntax/scanner level error handling should be done + * in error fallback rules. + * + * @param errorCode the code of the errormessage to display + */ + private void zzScanError(int errorCode) { + String message; + try { + message = ZZ_ERROR_MSG[errorCode]; + } catch (ArrayIndexOutOfBoundsException e) { + message = ZZ_ERROR_MSG[ZZ_UNKNOWN_ERROR]; + } + + throw new Error(message); + } + + /** + * Pushes the specified amount of characters back into the input stream. + * + * They will be read again by then next call of the scanning method + * + * @param number the number of characters to be read again. + * This number must not be greater than yylength()! + */ + public void yypushback(int number) { + if (number > yylength()) { + zzScanError(ZZ_PUSHBACK_2BIG); + } + + zzMarkedPos -= number; + } + + /** + * Resumes scanning until the next regular expression is matched, + * the end of input is encountered or an I/O-Error occurs. + * + * @return the next token + * @exception java.io.IOException if any I/O-Error occurs + */ + public ParsedSymbol yylex() throws java.io.IOException, AVM2ParseException { + int zzInput; + int zzAction; + + // cached fields: + int zzCurrentPosL; + int zzMarkedPosL; + int zzEndReadL = zzEndRead; + char[] zzBufferL = zzBuffer; + char[] zzCMapL = ZZ_CMAP; + + int[] zzTransL = ZZ_TRANS; + int[] zzRowMapL = ZZ_ROWMAP; + int[] zzAttrL = ZZ_ATTRIBUTE; + + while (true) { + zzMarkedPosL = zzMarkedPos; + + yychar += zzMarkedPosL - zzStartRead; + + zzAction = -1; + + zzCurrentPosL = zzCurrentPos = zzStartRead = zzMarkedPosL; + + zzState = ZZ_LEXSTATE[zzLexicalState]; + + // set up zzAction for empty match case: + int zzAttributes = zzAttrL[zzState]; + if ((zzAttributes & 1) == 1) { + zzAction = zzState; + } + + zzForAction: + { + while (true) { + + if (zzCurrentPosL < zzEndReadL) { + zzInput = Character.codePointAt(zzBufferL, zzCurrentPosL, zzEndReadL); + zzCurrentPosL += Character.charCount(zzInput); + } else if (zzAtEOF) { + zzInput = YYEOF; + break zzForAction; + } else { + // store back cached positions + zzCurrentPos = zzCurrentPosL; + zzMarkedPos = zzMarkedPosL; + boolean eof = zzRefill(); + // get translated positions and possibly new buffer + zzCurrentPosL = zzCurrentPos; + zzMarkedPosL = zzMarkedPos; + zzBufferL = zzBuffer; + zzEndReadL = zzEndRead; + if (eof) { + zzInput = YYEOF; + break zzForAction; + } else { + zzInput = Character.codePointAt(zzBufferL, zzCurrentPosL, zzEndReadL); + zzCurrentPosL += Character.charCount(zzInput); + } + } + int zzNext = zzTransL[zzRowMapL[zzState] + zzCMapL[zzInput]]; + if (zzNext == -1) { + break zzForAction; + } + zzState = zzNext; + + zzAttributes = zzAttrL[zzState]; + if ((zzAttributes & 1) == 1) { + zzAction = zzState; + zzMarkedPosL = zzCurrentPosL; + if ((zzAttributes & 8) == 8) { + break zzForAction; + } + } + + } + } + + // store back cached position + zzMarkedPos = zzMarkedPosL; + + switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) { + case 1: { + } + case 164: + break; + case 2: { + yyline++; + } + case 165: + break; + case 3: { /*ignore*/ + + } + case 166: + break; + case 4: { + return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.DIVIDE, yytext()); + } + case 167: + break; + case 5: { + return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.MULTIPLY, yytext()); + } + case 168: + break; + case 6: { + return new ParsedSymbol(SymbolGroup.IDENTIFIER, SymbolType.IDENTIFIER, yytext()); + } + case 169: + break; + case 7: { + return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.DOT, yytext()); + } + case 170: + break; + case 8: { + return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.LOWER_THAN, yytext()); + } + case 171: + break; + case 9: { + return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.NOT, yytext()); + } + case 172: + break; + case 10: { + return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.MINUS, yytext()); + } + case 173: + break; + case 11: { + return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.GREATER_THAN, yytext()); + } + case 174: + break; + case 12: { + return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.COLON, yytext()); + } + case 175: + break; + case 13: { + return new ParsedSymbol(SymbolGroup.INTEGER, SymbolType.INTEGER, Long.parseLong((yytext()))); + } + case 176: + break; + case 14: { + return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.TERNAR, yytext()); + } + case 177: + break; + case 15: { + return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.BRACKET_OPEN, yytext()); + } + case 178: + break; + case 16: { + return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.BRACKET_CLOSE, yytext()); + } + case 179: + break; + case 17: { + return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN, yytext()); + } + case 180: + break; + case 18: { + string.setLength(0); + yybegin(STRING); + } + case 181: + break; + case 19: { + string.setLength(0); + yybegin(CHARLITERAL); + } + case 182: + break; + case 20: { + return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.PLUS, yytext()); + } + case 183: + break; + case 21: { + string.setLength(0); + yybegin(OIDENTIFIER); + } + case 184: + break; + case 22: { + return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.PARENT_OPEN, yytext()); + } + case 185: + break; + case 23: { + return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.PARENT_CLOSE, yytext()); + } + case 186: + break; + case 24: { + return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.CURLY_OPEN, yytext()); + } + case 187: + break; + case 25: { + return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.CURLY_CLOSE, yytext()); + } + case 188: + break; + case 26: { + return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.SEMICOLON, yytext()); + } + case 189: + break; + case 27: { + return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.COMMA, yytext()); + } + case 190: + break; + case 28: { + return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.NEGATE, yytext()); + } + case 191: + break; + case 29: { + return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.BITAND, yytext()); + } + case 192: + break; + case 30: { + return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.BITOR, yytext()); + } + case 193: + break; + case 31: { + return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.XOR, yytext()); + } + case 194: + break; + case 32: { + return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.MODULO, yytext()); + } + case 195: + break; + case 33: { + return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ATTRIBUTE, yytext()); + } + case 196: + break; + case 34: { + string.append(yytext()); + } + case 197: + break; + case 35: { + yybegin(YYINITIAL); + yyline++; + } + case 198: + break; + case 36: { + yybegin(YYINITIAL); + // length also includes the trailing quote + return new ParsedSymbol(SymbolGroup.STRING, SymbolType.STRING, string.toString()); + } + case 199: + break; + case 37: { + yybegin(YYINITIAL); + yyline++; + } + case 200: + break; + case 38: { + string.append(yytext()); + yyline++; + } + case 201: + break; + case 39: { + yybegin(XML); + pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_STARTTAG_END, yytext())); + if (string.length() > 0) { + pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); + string.setLength(0); + } + return lex(); + } + case 202: + break; + case 40: { + yybegin(YYINITIAL); + pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_ATTRNAMEVAR_BEGIN, yytext())); + if (string.length() > 0) { + pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); + string.setLength(0); + } + return lex(); + } + case 203: + break; + case 41: { + yybegin(YYINITIAL); + return new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_ATTRVALVAR_BEGIN, yytext()); + } + case 204: + break; + case 42: { + yybegin(YYINITIAL); + pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_INSTRATTRNAMEVAR_BEGIN, yytext())); + if (string.length() > 0) { + pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); + string.setLength(0); + } + return lex(); + } + case 205: + break; + case 43: { + yybegin(YYINITIAL); + return new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_INSTRATTRVALVAR_BEGIN, yytext()); + } + case 206: + break; + case 44: { + string.append(yytext()); + yyline++; + } + case 207: + break; + case 45: { + yybegin(YYINITIAL); + pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_VAR_BEGIN, yytext())); + if (string.length() > 0) { + pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); + string.setLength(0); + } + return lex(); + } + case 208: + break; + case 46: { + yybegin(YYINITIAL); + // length also includes the trailing quote + return new ParsedSymbol(SymbolGroup.IDENTIFIER, SymbolType.IDENTIFIER, string.toString()); + } + case 209: + break; + case 47: { + return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN_DIVIDE, yytext()); + } + case 210: + break; + case 48: { + return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN_MULTIPLY, yytext()); + } + case 211: + break; + case 49: { + return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.DESCENDANTS, yytext()); + } + case 212: + break; + case 50: { + return new ParsedSymbol(SymbolGroup.TYPENAME, SymbolType.TYPENAME, yytext()); + } + case 213: + break; + case 51: { + return new ParsedSymbol(SymbolGroup.DOUBLE, SymbolType.DOUBLE, Double.parseDouble((yytext()))); + } + case 214: + break; + case 52: { + return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.FILTER, yytext()); + } + case 215: + break; + case 53: { + yybegin(XMLOPENTAG); + string.setLength(0); + return new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_STARTTAG_BEGIN, yytext()); + } + case 216: + break; + case 54: { + return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.SHIFT_LEFT, yytext()); + } + case 217: + break; + case 55: { + return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.LOWER_EQUAL, yytext()); + } + case 218: + break; + case 56: { + return new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_STARTVARTAG_BEGIN, yytext()); + } + case 219: + break; + case 57: { + return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.NOT_EQUAL, yytext()); + } + case 220: + break; + case 58: { + return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.DECREMENT, yytext()); + } + case 221: + break; + case 59: { + return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN_MINUS, yytext()); + } + case 222: + break; + case 60: { + return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.SHIFT_RIGHT, yytext()); + } + case 223: + break; + case 61: { + return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.GREATER_EQUAL, yytext()); + } + case 224: + break; + case 62: { + return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.NAMESPACE_OP, yytext()); + } + case 225: + break; + case 63: { + return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.EQUALS, yytext()); + } + case 226: + break; + case 64: { + return new ParsedSymbol(SymbolGroup.INTEGER, SymbolType.INTEGER, Long.parseLong(yytext(), 8)); + } + case 227: + break; + case 65: { + return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN_PLUS, yytext()); + } + case 228: + break; + case 66: { + return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.INCREMENT, yytext()); + } + case 229: + break; + case 67: { + return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.AS, yytext()); + } + case 230: + break; + case 68: { + return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.IF, yytext()); + } + case 231: + break; + case 69: { + return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.IS, yytext()); + } + case 232: + break; + case 70: { + return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.IN, yytext()); + } + case 233: + break; + case 71: { + return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.DO, yytext()); + } + case 234: + break; + case 72: { + return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN_BITAND, yytext()); + } + case 235: + break; + case 73: { + return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.AND, yytext()); + } + case 236: + break; + case 74: { + return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN_BITOR, yytext()); + } + case 237: + break; + case 75: { + return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.OR, yytext()); + } + case 238: + break; + case 76: { + return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN_XOR, yytext()); + } + case 239: + break; + case 77: { + return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN_MODULO, yytext()); + } + case 240: + break; + case 78: { /* ignore illegal character escape */ + + } + case 241: + break; + case 79: { + string.append('\"'); + } + case 242: + break; + case 80: { + string.append('\''); + } + case 243: + break; + case 81: { + string.append('\f'); + } + case 244: + break; + case 82: { + string.append('\\'); + } + case 245: + break; + case 83: { + string.append('\b'); + } + case 246: + break; + case 84: { + string.append('\r'); + } + case 247: + break; + case 85: { + string.append('\n'); + } + case 248: + break; + case 86: { + string.append('\t'); + } + case 249: + break; + case 87: { + yybegin(XML); + pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_STARTFINISHTAG_END, yytext())); + if (string.length() > 0) { + pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); + string.setLength(0); + } + return lex(); + } + case 250: + break; + case 88: { + yybegin(XMLOPENTAGATTRIB); + pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_ATTRIBUTENAME, yytext())); + if (string.length() > 0) { + pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); + string.setLength(0); + } + return lex(); + } + case 251: + break; + case 89: { + yybegin(XMLOPENTAG); + return new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_ATTRIBUTEVALUE, yytext()); + } + case 252: + break; + case 90: { + yybegin(XMLINSTRATTRIB); + pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_ATTRIBUTENAME, yytext())); + if (string.length() > 0) { + pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); + string.setLength(0); + } + return lex(); + } + case 253: + break; + case 91: { + yybegin(XML); + pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_INSTR_END, yytext())); + if (string.length() > 0) { + pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); + string.setLength(0); + } + return lex(); + } + case 254: + break; + case 92: { + yybegin(XMLINSTROPENTAG); + return new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_ATTRIBUTEVALUE, yytext()); + } + case 255: + break; + case 93: { + yybegin(XMLOPENTAG); + pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_STARTTAG_BEGIN, yytext())); + if (string.length() > 0) { + pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); + string.setLength(0); + } + return lex(); + } + case 256: + break; + case 94: { + yybegin(YYINITIAL); + pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_STARTVARTAG_BEGIN, yytext())); + if (string.length() > 0) { + pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); + string.setLength(0); + } + return lex(); + } + case 257: + break; + case 95: { + throw new AVM2ParseException("Illegal escape sequence \"" + yytext() + "\"", yyline + 1); + } + case 258: + break; + case 96: { + return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.REST, yytext()); + } + case 259: + break; + case 97: { + return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN_SHIFT_LEFT, yytext()); + } + case 260: + break; + case 98: { + return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.STRICT_NOT_EQUAL, yytext()); + } + case 261: + break; + case 99: { + return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.USHIFT_RIGHT, yytext()); + } + case 262: + break; + case 100: { + return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN_SHIFT_RIGHT, yytext()); + } + case 263: + break; + case 101: { + return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.STRICT_EQUALS, yytext()); + } + case 264: + break; + case 102: { + return new ParsedSymbol(SymbolGroup.INTEGER, SymbolType.INTEGER, Long.parseLong(yytext().substring(2), 16)); + } + case 265: + break; + case 103: { + return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.FOR, yytext()); + } + case 266: + break; + case 104: { + return new ParsedSymbol(SymbolGroup.IDENTIFIER, SymbolType.SET, yytext()); + } + case 267: + break; + case 105: { + return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.NEW, yytext()); + } + case 268: + break; + case 106: { + return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.TRY, yytext()); + } + case 269: + break; + case 107: { + return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.USE, yytext()); + } + case 270: + break; + case 108: { + return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.VAR, yytext()); + } + case 271: + break; + case 109: { + return new ParsedSymbol(SymbolGroup.IDENTIFIER, SymbolType.GET, yytext()); + } + case 272: + break; + case 110: { + return new ParsedSymbol(SymbolGroup.GLOBALCONST, SymbolType.NAN, yytext()); + } + case 273: + break; + case 111: { + string.append(yytext()); + yybegin(XML); + String ret = string.toString(); + string.setLength(0); + return new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_CDATA, ret); + } + case 274: + break; + case 112: { + string.append(yytext()); + yybegin(XML); + String ret = string.toString(); + string.setLength(0); + return new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_COMMENT, ret); + } + case 275: + break; + case 113: { + yybegin(YYINITIAL); + pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_FINISHVARTAG_BEGIN, yytext())); + if (string.length() > 0) { + pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); + string.setLength(0); + } + return lex(); + } + case 276: + break; + case 114: { + yybegin(XMLINSTROPENTAG); + pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_INSTR_BEGIN, yytext())); + if (string.length() > 0) { + pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); + string.setLength(0); + } + return lex(); + } + case 277: + break; + case 115: { + yybegin(YYINITIAL); + pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_INSTRVARTAG_BEGIN, yytext())); + if (string.length() > 0) { + pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); + string.setLength(0); + } + return lex(); + } + case 278: + break; + case 116: { + string.append('\u00A7'); + } + case 279: + break; + case 117: { + return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN_USHIFT_RIGHT, yytext()); + } + case 280: + break; + case 118: { + return new ParsedSymbol(SymbolGroup.IDENTIFIER, SymbolType.EACH, yytext()); + } + case 281: + break; + case 119: { + return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.ELSE, yytext()); + } + case 282: + break; + case 120: { + return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.CASE, yytext()); + } + case 283: + break; + case 121: { + return new ParsedSymbol(SymbolGroup.GLOBALCONST, SymbolType.NULL, yytext()); + } + case 284: + break; + case 122: { + return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.TRUE, yytext()); + } + case 285: + break; + case 123: { + return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.THIS, yytext()); + } + case 286: + break; + case 124: { + return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.WITH, yytext()); + } + case 287: + break; + case 125: { + return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.VOID, yytext()); + } + case 288: + break; + case 126: { + char val = (char) Integer.parseInt(yytext().substring(2), 16); + string.append(val); + } + case 289: + break; + case 127: { + pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_FINISHTAG, yytext())); + if (string.length() > 0) { + pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); + string.setLength(0); + } + return lex(); + } + case 290: + break; + case 128: { + String ret = string.toString(); + string.setLength(0); + string.append(yytext()); + yybegin(XMLCOMMENT); + if (!ret.isEmpty()) { + return new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_TEXT, ret); + } + } + case 291: + break; + case 129: { + return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.FALSE, yytext()); + } + case 292: + break; + case 130: { + return new ParsedSymbol(SymbolGroup.IDENTIFIER, SymbolType.FINAL, yytext()); + } + case 293: + break; + case 131: { + return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.BREAK, yytext()); + } + case 294: + break; + case 132: { + return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.CATCH, yytext()); + } + case 295: + break; + case 133: { + return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.CONST, yytext()); + } + case 296: + break; + case 134: { + return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.CLASS, yytext()); + } + case 297: + break; + case 135: { + return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.SUPER, yytext()); + } + case 298: + break; + case 136: { + return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.THROW, yytext()); + } + case 299: + break; + case 137: { + return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.WHILE, yytext()); + } + case 300: + break; + case 138: { + return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.RETURN, yytext()); + } + case 301: + break; + case 139: { + return new ParsedSymbol(SymbolGroup.IDENTIFIER, SymbolType.STATIC, yytext()); + } + case 302: + break; + case 140: { + return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.SWITCH, yytext()); + } + case 303: + break; + case 141: { + return new ParsedSymbol(SymbolGroup.IDENTIFIER, SymbolType.NATIVE, yytext()); + } + case 304: + break; + case 142: { + return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.TYPEOF, yytext()); + } + case 305: + break; + case 143: { + return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.IMPORT, yytext()); + } + case 306: + break; + case 144: { + return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.DELETE, yytext()); + } + case 307: + break; + case 145: { + return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.PUBLIC, yytext()); + } + case 308: + break; + case 146: { + return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.FINALLY, yytext()); + } + case 309: + break; + case 147: { + return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.EXTENDS, yytext()); + } + case 310: + break; + case 148: { + return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.DEFAULT, yytext()); + } + case 311: + break; + case 149: { + return new ParsedSymbol(SymbolGroup.IDENTIFIER, SymbolType.DYNAMIC, yytext()); + } + case 312: + break; + case 150: { + return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.PRIVATE, yytext()); + } + case 313: + break; + case 151: { + return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.PACKAGE, yytext()); + } + case 314: + break; + case 152: { + return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.FUNCTION, yytext()); + } + case 315: + break; + case 153: { + return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.CONTINUE, yytext()); + } + case 316: + break; + case 154: { + return new ParsedSymbol(SymbolGroup.IDENTIFIER, SymbolType.OVERRIDE, yytext()); + } + case 317: + break; + case 155: { + return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.INTERNAL, yytext()); + } + case 318: + break; + case 156: { + return new ParsedSymbol(SymbolGroup.GLOBALCONST, SymbolType.INFINITY, yytext()); + } + case 319: + break; + case 157: { + return new ParsedSymbol(SymbolGroup.IDENTIFIER, SymbolType.NAMESPACE, yytext()); + } + case 320: + break; + case 158: { + return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.INTERFACE, yytext()); + } + case 321: + break; + case 159: { + return new ParsedSymbol(SymbolGroup.GLOBALCONST, SymbolType.UNDEFINED, yytext()); + } + case 322: + break; + case 160: { + return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.PROTECTED, yytext()); + } + case 323: + break; + case 161: { + String ret = string.toString(); + string.setLength(0); + string.append(yytext()); + yybegin(XMLCDATA); + if (!ret.isEmpty()) { + return new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_TEXT, ret); + } + } + case 324: + break; + case 162: { + return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.INSTANCEOF, yytext()); + } + case 325: + break; + case 163: { + return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.IMPLEMENTS, yytext()); + } + case 326: + break; + default: + if (zzInput == YYEOF && zzStartRead == zzCurrentPos) { + zzAtEOF = true; + { + return new ParsedSymbol(SymbolGroup.EOF, SymbolType.EOF, null); + } + } else { + zzScanError(ZZ_NO_MATCH); + } + } + } + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScriptParser.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScriptParser.java index 1e2e222aa..700a8854b 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScriptParser.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScriptParser.java @@ -1,2442 +1,2442 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.parser.script; - -import com.jpexs.decompiler.flash.SWC; -import com.jpexs.decompiler.flash.SWF; -import com.jpexs.decompiler.flash.SourceGeneratorLocalData; -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.model.ApplyTypeAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.BooleanAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.CoerceAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.ConstructSuperAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.DefaultXMLNamespace; -import com.jpexs.decompiler.flash.abc.avm2.model.EscapeXAttrAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.EscapeXElemAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.FloatValueAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.GetDescendantsAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.GetPropertyAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.InAVM2Item; -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.LocalRegAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.NameValuePair; -import com.jpexs.decompiler.flash.abc.avm2.model.NanAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.NewArrayAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.NewObjectAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.NullAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.PostDecrementAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.PostIncrementAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.ReturnValueAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.ReturnVoidAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.StringAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.ThrowAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.UndefinedAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.WithAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.clauses.ExceptionAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.clauses.ForEachInAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.clauses.ForInAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.clauses.TryAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.AddAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.AsTypeAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.BitAndAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.BitOrAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.BitXorAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.DeletePropertyAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.DivideAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.EqAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.GeAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.GtAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.InstanceOfAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.IsTypeAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.LShiftAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.LeAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.LtAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.ModuloAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.MultiplyAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.NegAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.NeqAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.PreDecrementAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.PreIncrementAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.RShiftAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.StrictEqAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.StrictNeqAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.SubtractAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.TypeOfAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.operations.URShiftAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.parser.AVM2ParseException; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.Namespace; -import com.jpexs.decompiler.flash.action.swf4.ActionIf; -import com.jpexs.decompiler.flash.configuration.Configuration; -import com.jpexs.decompiler.flash.tags.ABCContainerTag; -import com.jpexs.decompiler.flash.tags.Tag; -import com.jpexs.decompiler.graph.CompilationException; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.Loop; -import com.jpexs.decompiler.graph.TypeItem; -import com.jpexs.decompiler.graph.model.AndItem; -import com.jpexs.decompiler.graph.model.BinaryOp; -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.DoWhileItem; -import com.jpexs.decompiler.graph.model.ForItem; -import com.jpexs.decompiler.graph.model.IfItem; -import com.jpexs.decompiler.graph.model.NotItem; -import com.jpexs.decompiler.graph.model.OrItem; -import com.jpexs.decompiler.graph.model.ParenthesisItem; -import com.jpexs.decompiler.graph.model.SwitchItem; -import com.jpexs.decompiler.graph.model.TernarOpItem; -import com.jpexs.decompiler.graph.model.UnboundedTypeItem; -import com.jpexs.decompiler.graph.model.WhileItem; -import com.jpexs.helpers.Helper; -import java.io.BufferedOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Stack; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * - * @author JPEXS - */ -public class ActionScriptParser { - - private long uniqLast = 0; - - private final boolean debugMode = false; - - private static final String AS3_NAMESPACE = "http://adobe.com/AS3/2006/builtin"; - - private final ABC abc; - - private final List otherABCs; - - private static final List playerABCs = new ArrayList<>(); - - private long uniqId() { - uniqLast++; - return uniqLast; - } - - private List commands(TypeItem thisType, String pkg, Reference needsActivation, List importedClasses, List openedNamespaces, Stack loops, Map loopLabels, HashMap registerVars, boolean inFunction, boolean inMethod, int forinlevel, List variables) throws IOException, AVM2ParseException { - List ret = new ArrayList<>(); - if (debugMode) { - System.out.println("commands:"); - } - GraphTargetItem cmd = null; - while ((cmd = command(thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables)) != null) { - ret.add(cmd); - } - if (debugMode) { - System.out.println("/commands"); - } - return ret; - } - - private GraphTargetItem type(TypeItem thisType, String pkg, Reference needsActivation, List importedClasses, List openedNamespaces, List variables) throws IOException, AVM2ParseException { - ParsedSymbol s = lex(); - if (s.type == SymbolType.MULTIPLY) { - return new UnboundedTypeItem(); - } else if (s.type == SymbolType.VOID) { - return new TypeItem("void"); - } else { - lexer.pushback(s); - } - - GraphTargetItem t = name(thisType, pkg, needsActivation, true, openedNamespaces, null, false, false, variables, importedClasses); - t = applyType(thisType, pkg, needsActivation, importedClasses, openedNamespaces, t, new HashMap(), false, false, variables); - return t; - } - - private GraphTargetItem memberOrCall(TypeItem thisType, String pkg, Reference needsActivation, List importedClasses, List openedNamespaces, GraphTargetItem newcmds, HashMap registerVars, boolean inFunction, boolean inMethod, List variables) throws IOException, AVM2ParseException { - if (debugMode) { - System.out.println("memberOrCall:"); - } - ParsedSymbol s = lex(); - GraphTargetItem ret = newcmds; - while (s.isType(SymbolType.DOT, SymbolType.PARENT_OPEN, SymbolType.BRACKET_OPEN, SymbolType.TYPENAME, SymbolType.FILTER)) { - switch (s.type) { - case BRACKET_OPEN: - case DOT: - case TYPENAME: - lexer.pushback(s); - ret = member(thisType, pkg, needsActivation, importedClasses, openedNamespaces, ret, registerVars, inFunction, inMethod, variables); - break; - case FILTER: - needsActivation.setVal(true); - ret = new XMLFilterAVM2Item(ret, expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, inMethod, variables), openedNamespaces); - expectedType(SymbolType.PARENT_CLOSE); - break; - case PARENT_OPEN: - ret = new CallAVM2Item(lexer.yyline(), ret, call(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, variables)); - break; - - } - s = lex(); - } - if (s.type == SymbolType.INCREMENT) { - if (!isNameOrProp(ret)) { - throw new AVM2ParseException("Invalid assignment", lexer.yyline()); - } - ret = new PostIncrementAVM2Item(null, ret); - s = lex(); - - } else if (s.type == SymbolType.DECREMENT) { - if (!isNameOrProp(ret)) { - throw new AVM2ParseException("Invalid assignment", lexer.yyline()); - } - ret = new PostDecrementAVM2Item(null, ret); - s = lex(); - } - - lexer.pushback(s); - - if (debugMode) { - System.out.println("/memberOrCall"); - } - return ret; - } - - private GraphTargetItem applyType(TypeItem thisType, String pkg, Reference needsActivation, List importedClasses, List openedNamespaces, GraphTargetItem obj, HashMap registerVars, boolean inFunction, boolean inMethod, List variables) throws IOException, AVM2ParseException { - GraphTargetItem ret = obj; - ParsedSymbol s = lex(); - if (s.type == SymbolType.TYPENAME) { - List params = new ArrayList<>(); - do { - params.add(expressionPrimary(thisType, pkg, needsActivation, importedClasses, openedNamespaces, false, registerVars, inFunction, inMethod, false, variables) - ); - s = lex(); - } while (s.type == SymbolType.COMMA); - if (s.type == SymbolType.USHIFT_RIGHT) { - s = new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.GREATER_THAN); - lexer.pushback(s); - lexer.pushback(s); - } - if (s.type == SymbolType.SHIFT_RIGHT) { - s = new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.GREATER_THAN); - lexer.pushback(s); - } - expected(s, lexer.yyline(), SymbolType.GREATER_THAN); - ret = new ApplyTypeAVM2Item(null, ret, params); - } else { - lexer.pushback(s); - } - return ret; - } - - private GraphTargetItem member(TypeItem thisType, String pkg, Reference needsActivation, List importedClasses, List openedNamespaces, GraphTargetItem obj, HashMap registerVars, boolean inFunction, boolean inMethod, List variables) throws IOException, AVM2ParseException { - if (debugMode) { - System.out.println("member:"); - } - GraphTargetItem ret = obj; - ParsedSymbol s = lex(); - while (s.isType(SymbolType.DOT, SymbolType.BRACKET_OPEN, SymbolType.TYPENAME)) { - ParsedSymbol s2 = lex(); - boolean attr = false; - if (s.type == SymbolType.DOT) { - if (s2.type == SymbolType.ATTRIBUTE) { - attr = true; - } else { - lexer.pushback(s2); - } - - } else { - lexer.pushback(s2); - } - if (s.type == SymbolType.TYPENAME) { - lexer.pushback(s); - ret = applyType(thisType, pkg, needsActivation, importedClasses, openedNamespaces, ret, registerVars, inFunction, inMethod, variables); - s = lex(); - } else if (s.type == SymbolType.BRACKET_OPEN) { - GraphTargetItem index = expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables); - expectedType(SymbolType.BRACKET_CLOSE); - ret = new IndexAVM2Item(attr, ret, index, null, openedNamespaces); - s = lex(); - } else { - s = lex(); - expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); - String propName = s.value.toString(); - GraphTargetItem propItem = null; - s = lex(); - GraphTargetItem ns = null; - if (s.type == SymbolType.NAMESPACE_OP) { - ns = new UnresolvedAVM2Item(new ArrayList(), importedClasses, false, null, lexer.yyline(), propName, null, openedNamespaces); - variables.add((UnresolvedAVM2Item) ns); - s = lex(); - if (s.type == SymbolType.BRACKET_OPEN) { - propItem = expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables); - expectedType(SymbolType.BRACKET_CLOSE); - propName = null; - } else { - expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); - propName = s.value.toString(); - propItem = null; - } - } else { - lexer.pushback(s); - } - if (ns != null) { - ret = new NamespacedAVM2Item(ns, propName, propItem, ret, attr, openedNamespaces, null); - } else { - ret = new PropertyAVM2Item(ret, (attr ? "@" : "") + propName, abc, otherABCs, openedNamespaces, new ArrayList()); - } - s = lex(); - } - } - if (s.type.getPrecedence() == GraphTargetItem.PRECEDENCE_ASSIGMENT) { - ret = expression1(ret, s.type.getPrecedence(), thisType, pkg, needsActivation, importedClasses, openedNamespaces, inMethod, registerVars, inFunction, inMethod, false, variables); - } else { - lexer.pushback(s); - } - - if (debugMode) { - System.out.println("/member"); - } - return ret; - } - - private GraphTargetItem name(TypeItem thisType, String pkg, Reference needsActivation, boolean typeOnly, List openedNamespaces, HashMap registerVars, boolean inFunction, boolean inMethod, List variables, List importedClasses) throws IOException, AVM2ParseException { - ParsedSymbol s = lex(); - String name = ""; - if (s.type == SymbolType.ATTRIBUTE) { - name += "@"; - s = lex(); - } - expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER, SymbolType.THIS, SymbolType.SUPER, SymbolType.STRING_OP); - name += s.value.toString(); - s = lex(); - boolean attrBracket = false; - - while (s.isType(SymbolType.DOT)) { - name += s.value.toString(); //. or :: - s = lex(); - if (s.type == SymbolType.ATTRIBUTE) { - name += "@"; - s = lex(); - if (s.type == SymbolType.MULTIPLY) { - name += s.value.toString(); - } else if (s.group == SymbolGroup.IDENTIFIER) { - name += s.value.toString(); - } else { - if (s.type != SymbolType.BRACKET_OPEN) { - throw new AVM2ParseException("Attribute identifier or bracket expected", lexer.yyline()); - } - attrBracket = true; - continue; - } - } else { - expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER, SymbolType.NAMESPACE); - name += s.value.toString(); - } - s = lex(); - } - String nsname = null; - String nsprop = null; - GraphTargetItem nspropItem = null; - if (s.type == SymbolType.NAMESPACE_OP) { - if (name.contains(".")) { - nsname = name.substring(name.lastIndexOf('.') + 1); - } else { - nsname = name; - } - s = lex(); - if (s.group == SymbolGroup.IDENTIFIER) { - nsprop = s.value.toString(); - } else if (s.type == SymbolType.BRACKET_OPEN) { - nspropItem = expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables); - expectedType(SymbolType.BRACKET_CLOSE); - } - if (name.contains(".")) { - name = name.substring(0, name.lastIndexOf('.')); - } else { - name = null; - } - s = lex(); - } - - GraphTargetItem ret = null; - if (name != null) { - UnresolvedAVM2Item unr = new UnresolvedAVM2Item(new ArrayList(), importedClasses, typeOnly, null, lexer.yyline(), name, null, openedNamespaces); - //unr.setIndex(index); - variables.add(unr); - ret = unr; - } - if (nsname != null) { - boolean attr = nsname.startsWith("@"); - if (attr) { - nsname = nsname.substring(1); - } - UnresolvedAVM2Item ns = new UnresolvedAVM2Item(new ArrayList(), importedClasses, typeOnly, null, lexer.yyline(), nsname, null, openedNamespaces); - variables.add(ns); - ret = new NamespacedAVM2Item(ns, nsprop, nspropItem, ret, attr, openedNamespaces, null); - } - if (s.type == SymbolType.BRACKET_OPEN) { - lexer.pushback(s); - if (attrBracket) { - lexer.pushback(new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ATTRIBUTE, "@")); - lexer.pushback(new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.DOT, ".")); - } - ret = member(thisType, pkg, needsActivation, importedClasses, openedNamespaces, ret, registerVars, inFunction, inMethod, variables); - } else { - lexer.pushback(s); - } - return ret; - } - - private void expected(ParsedSymbol symb, int line, Object... expected) throws IOException, AVM2ParseException { - boolean found = false; - for (Object t : expected) { - if (symb.type == t) { - found = true; - } - if (symb.group == t) { - found = true; - } - } - if (!found) { - String expStr = ""; - boolean first = true; - for (Object e : expected) { - if (!first) { - expStr += " or "; - } - expStr += e; - first = false; - } - throw new AVM2ParseException("" + expStr + " expected but " + symb.type + " found", line); - } - } - - private ParsedSymbol expectedType(Object... type) throws IOException, AVM2ParseException { - ParsedSymbol symb = lex(); - expected(symb, lexer.yyline(), type); - return symb; - } - - private ParsedSymbol lex() throws IOException, AVM2ParseException { - ParsedSymbol ret = lexer.lex(); - if (debugMode) { - System.out.println(ret); - } - return ret; - } - - private List call(TypeItem thisType, String pkg, Reference needsActivation, List importedClasses, List openedNamespaces, HashMap registerVars, boolean inFunction, boolean inMethod, List variables) throws IOException, AVM2ParseException { - List ret = new ArrayList<>(); - //expected(SymbolType.PARENT_OPEN); //MUST BE HANDLED BY CALLER - ParsedSymbol s = lex(); - while (s.type != SymbolType.PARENT_CLOSE) { - if (s.type != SymbolType.COMMA) { - lexer.pushback(s); - } - ret.add(expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables)); - s = lex(); - expected(s, lexer.yyline(), SymbolType.COMMA, SymbolType.PARENT_CLOSE); - } - return ret; - } - - private MethodAVM2Item method(String pkg, boolean isInterface, String customAccess, Reference needsActivation, List importedClasses, boolean override, boolean isFinal, TypeItem thisType, List openedNamespaces, boolean isStatic, int namespace, String functionName, boolean isMethod, List variables) throws IOException, AVM2ParseException { - FunctionAVM2Item f = function(pkg, isInterface, needsActivation, importedClasses, namespace, thisType, openedNamespaces, functionName, isMethod, variables); - return new MethodAVM2Item(f.pkg, f.isInterface, customAccess, f.needsActivation, f.hasRest, f.line, override, isFinal, isStatic, f.namespace, functionName, f.paramTypes, f.paramNames, f.paramValues, f.body, f.subvariables, f.retType); - } - - private FunctionAVM2Item function(String pkg, boolean isInterface, Reference needsActivation, List importedClasses, int namespace, TypeItem thisType, List openedNamespaces, String functionName, boolean isMethod, List variables) throws IOException, AVM2ParseException { - openedNamespaces = new ArrayList<>(openedNamespaces); //local copy - int line = lexer.yyline(); - ParsedSymbol s; - expectedType(SymbolType.PARENT_OPEN); - s = lex(); - List paramNames = new ArrayList<>(); - List paramTypes = new ArrayList<>(); - List paramValues = new ArrayList<>(); - boolean hasRest = false; - while (s.type != SymbolType.PARENT_CLOSE) { - if (s.type != SymbolType.COMMA) { - lexer.pushback(s); - } - s = lex(); - if (s.type == SymbolType.REST) { - hasRest = true; - s = lex(); - } - expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); - - paramNames.add(s.value.toString()); - s = lex(); - if (!hasRest) { - if (s.type == SymbolType.COLON) { - paramTypes.add(type(thisType, pkg, needsActivation, importedClasses, openedNamespaces, variables)); - s = lex(); - } else { - paramTypes.add(new UnboundedTypeItem()); - } - if (s.type == SymbolType.ASSIGN) { - paramValues.add(expression(thisType, pkg, new Reference<>(false), importedClasses, openedNamespaces, null, isMethod, isMethod, isMethod, variables)); - s = lex(); - } else { - if (!paramValues.isEmpty()) { - throw new AVM2ParseException("Some of parameters do not have default values", lexer.yyline()); - } - } - } - - if (!s.isType(SymbolType.COMMA, SymbolType.PARENT_CLOSE)) { - expected(s, lexer.yyline(), SymbolType.COMMA, SymbolType.PARENT_CLOSE); - } - if (hasRest) { - expected(s, lexer.yyline(), SymbolType.PARENT_CLOSE); - } - } - s = lex(); - GraphTargetItem retType; - if (s.type == SymbolType.COLON) { - retType = type(thisType, pkg, needsActivation, importedClasses, openedNamespaces, variables); - } else { - retType = new UnboundedTypeItem(); - lexer.pushback(s); - } - List body = null; - List subvariables = new ArrayList<>(); - subvariables.add(new NameAVM2Item(thisType, lexer.yyline(), "this", null, true, openedNamespaces)); - for (int i = 0; i < paramNames.size() - (hasRest ? 1 : 0); i++) { - subvariables.add(new NameAVM2Item(paramTypes.get(i), lexer.yyline(), paramNames.get(i), null, true, openedNamespaces)); - } - if (hasRest) { - subvariables.add(new NameAVM2Item(TypeItem.UNBOUNDED, lexer.yyline(), paramNames.get(paramNames.size() - 1), null, true, openedNamespaces)); - } - subvariables.add(new NameAVM2Item(thisType, lexer.yyline(), "arguments", null, true, openedNamespaces)); - int parCnt = subvariables.size(); - Reference needsActivation2 = new Reference<>(false); - if (!isInterface) { - expectedType(SymbolType.CURLY_OPEN); - body = commands(thisType, pkg, needsActivation2, importedClasses, openedNamespaces, new Stack(), new HashMap(), new HashMap(), true, isMethod, 0, subvariables); - expectedType(SymbolType.CURLY_CLOSE); - } else { - expectedType(SymbolType.SEMICOLON); - } - - for (int i = 0; i < parCnt; i++) { - subvariables.remove(0); - } - return new FunctionAVM2Item(pkg, isInterface, needsActivation2.getVal(), namespace, hasRest, line, functionName, paramTypes, paramNames, paramValues, body, subvariables, retType); - } - - private GraphTargetItem traits(String scriptName, boolean scriptTraits, List sinitVariables, Reference sinitNeedsActivation, List staticInitializer, List importedClasses, int privateNs, int protectedNs, int publicNs, int packageInternalNs, int protectedStaticNs, List openedNamespaces, String pkg, String classNameStr, boolean isInterface, List traits) throws AVM2ParseException, IOException, CompilationException { - ParsedSymbol s; - GraphTargetItem constr = null; - TypeItem thisType = pkg == null && classNameStr == null ? null : new TypeItem(pkg == null || "".equals(pkg) ? classNameStr : pkg + "." + classNameStr); - List constrVariables = new ArrayList<>(); - List originalOpenedNamespaces = openedNamespaces; - int originalPrivateNs = privateNs; - boolean inPkg = pkg != null; - looptrait: - while (true) { - s = lex(); - boolean isStatic = false; - int namespace = -1; - boolean isGetter = false; - boolean isSetter = false; - boolean isOverride = false; - boolean isFinal = false; - boolean isDynamic = false; - String customAccess = null; - - if (scriptTraits && s.type == SymbolType.PACKAGE) { - if (inPkg) { - throw new AVM2ParseException("No subpackages allowed", lexer.yyline()); - } - openedNamespaces = new ArrayList<>(); - lexer.pushback(s); - PackageAVM2Item p = parsePackage(openedNamespaces); - pkg = p.packageName; - inPkg = true; - publicNs = p.publicNs; - importedClasses = p.importedClasses; - s = lex(); - } - if (inPkg || classNameStr != null) { - if (s.type == SymbolType.CURLY_OPEN) { - staticInitializer.addAll(commands(thisType, pkg, sinitNeedsActivation, importedClasses, openedNamespaces, new Stack(), new HashMap(), new HashMap(), true, false, 0, sinitVariables)); - expectedType(SymbolType.CURLY_CLOSE); - s = lex(); - } - - while (s.isType(SymbolType.STATIC, SymbolType.PUBLIC, SymbolType.PRIVATE, SymbolType.PROTECTED, SymbolType.OVERRIDE, SymbolType.FINAL, SymbolType.DYNAMIC, SymbolGroup.IDENTIFIER)) { - if (s.type == SymbolType.FINAL) { - if (isFinal) { - throw new AVM2ParseException("Only one final keyword allowed", lexer.yyline()); - } - isFinal = true; - } else if (s.type == SymbolType.DYNAMIC) { - if (isDynamic) { - throw new AVM2ParseException("Only one dynamic keyword allowed", lexer.yyline()); - } - isDynamic = true; - } else if (s.type == SymbolType.OVERRIDE) { - if (isOverride) { - throw new AVM2ParseException("Only one override keyword allowed", lexer.yyline()); - } - isOverride = true; - } else if (s.type == SymbolType.STATIC) { - if (isInterface) { - throw new AVM2ParseException("Interface cannot have static traits", lexer.yyline()); - } - if (classNameStr == null) { - throw new AVM2ParseException("No static keyword allowed here", lexer.yyline()); - } - if (isStatic) { - throw new AVM2ParseException("Only one static keyword allowed", lexer.yyline()); - } - isStatic = true; - } else if (s.type == SymbolType.NAMESPACE) { - break; - } else if (s.type == SymbolType.NATIVE) { - throw new AVM2ParseException("Cannot compile native code", lexer.yyline()); - } else if (s.group == SymbolGroup.IDENTIFIER) { - customAccess = s.value.toString(); - namespace = -2; - } else { - if (namespace != -1) { - throw new AVM2ParseException("Only one access identifier allowed", lexer.yyline()); - } - } - switch (s.type) { - case PUBLIC: - namespace = publicNs; - if (isInterface) { - throw new AVM2ParseException("Interface cannot have public, private or protected modifier", lexer.yyline()); - } - break; - case PRIVATE: - namespace = privateNs; - if (isInterface) { - throw new AVM2ParseException("Interface cannot have public, private or protected modifier", lexer.yyline()); - } - break; - case PROTECTED: - namespace = protectedNs; - if (isInterface) { - throw new AVM2ParseException("Interface cannot have public, private or protected modifier", lexer.yyline()); - } - break; - } - s = lex(); - } - } else { - namespace = privateNs; - } - if (namespace == -1) { - if (isInterface) { - namespace = abc.constants.getNamespaceId(new Namespace(Namespace.KIND_NAMESPACE, abc.constants.getStringId(pkg == null || pkg.isEmpty() ? classNameStr : pkg + ":" + classNameStr, true)), 0, true); - } else { - namespace = packageInternalNs; - } - } - if (namespace == protectedNs && isStatic) { - namespace = protectedStaticNs; - } - switch (s.type) { - /*case PACKAGE: - lexer.pushback(s); - traits.add(parsePackage(openedNamespaces)); - break;*/ - case CLASS: - List subNamespaces = new ArrayList<>(openedNamespaces); - if (classNameStr != null) { - throw new AVM2ParseException("Nested classes not supported", lexer.yyline()); - } - if (isOverride) { - throw new AVM2ParseException("Override flag not allowed for classes", lexer.yyline()); - } - - //GraphTargetItem classTypeStr = type(thisType,pkg,needsActivation, importedClasses, openedNamespaces, variables); - s = lex(); - expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); - String classTypeStr = s.value.toString(); - GraphTargetItem extendsTypeStr = null; - s = lex(); - if (s.type == SymbolType.EXTENDS) { - extendsTypeStr = type(thisType, pkg, new Reference<>(false), importedClasses, subNamespaces, new ArrayList()); - s = lex(); - } - List implementsTypeStrs = new ArrayList<>(); - if (s.type == SymbolType.IMPLEMENTS) { - do { - GraphTargetItem implementsTypeStr = type(thisType, pkg, new Reference<>(false), importedClasses, subNamespaces, new ArrayList()); - implementsTypeStrs.add(implementsTypeStr); - s = lex(); - } while (s.type == SymbolType.COMMA); - } - expected(s, lexer.yyline(), SymbolType.CURLY_OPEN); - if (customAccess != null) { - throw new AVM2ParseException("Class cannot have custom namespace", lexer.yyline()); - } - traits.add((classTraits(scriptName, publicNs, pkg, importedClasses, isDynamic, isFinal, subNamespaces, pkg, namespace, false, classTypeStr, extendsTypeStr, implementsTypeStrs, new ArrayList()))); - expectedType(SymbolType.CURLY_CLOSE); - break; - case INTERFACE: - if (classNameStr != null) { - throw new AVM2ParseException("Nested interfaces not supported", lexer.yyline()); - } - if (isOverride) { - throw new AVM2ParseException("Override flag not allowed for interfaces", lexer.yyline()); - } - if (isFinal) { - throw new AVM2ParseException("Final flag not allowed for interfaces", lexer.yyline()); - } - if (isDynamic) { - throw new AVM2ParseException("Dynamic flag not allowed for interfaces", lexer.yyline()); - } - //GraphTargetItem interfaceTypeStr = type(thisType,pkg,needsActivation, importedClasses, openedNamespaces, variables); - s = lex(); - expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); - String intTypeStr = s.value.toString(); - s = lex(); - List intExtendsTypeStrs = new ArrayList<>(); - - if (s.type == SymbolType.EXTENDS) { - do { - GraphTargetItem intExtendsTypeStr = type(thisType, pkg, new Reference<>(false), importedClasses, openedNamespaces, new ArrayList()); - intExtendsTypeStrs.add(intExtendsTypeStr); - s = lex(); - } while (s.type == SymbolType.COMMA); - } - expected(s, lexer.yyline(), SymbolType.CURLY_OPEN); - if (customAccess != null) { - throw new AVM2ParseException("Interface cannot have custom namespace", lexer.yyline()); - } - traits.add((classTraits(scriptName, publicNs, pkg, importedClasses, false, isFinal, openedNamespaces, pkg, namespace, true, intTypeStr, null, intExtendsTypeStrs, new ArrayList()))); - expectedType(SymbolType.CURLY_CLOSE); - break; - - case FUNCTION: - - if (isDynamic) { - throw new AVM2ParseException("Dynamic flag not allowed for methods", lexer.yyline()); - } - s = lex(); - if (s.type == SymbolType.GET) { - if (classNameStr == null) { - throw new AVM2ParseException("No get keyword allowed here", lexer.yyline()); - } - isGetter = true; - s = lex(); - } else if (s.type == SymbolType.SET) { - if (classNameStr == null) { - throw new AVM2ParseException("No set keyword allowed here", lexer.yyline()); - } - isSetter = true; - s = lex(); - } - - expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); - String fname = s.value.toString(); - if (classNameStr != null && fname.equals(classNameStr)) { //constructor - if (isStatic) { - throw new AVM2ParseException("Constructor cannot be static", lexer.yyline()); - } - if (isStatic) { - throw new AVM2ParseException("Constructor cannot be static", lexer.yyline()); - } - if (isOverride) { - throw new AVM2ParseException("Override flag not allowed for constructor", lexer.yyline()); - } - if (isFinal) { - throw new AVM2ParseException("Final flag not allowed for constructor", lexer.yyline()); - } - if (isInterface) { - throw new AVM2ParseException("Interface cannot have constructor", lexer.yyline()); - } - constr = (method(pkg, false, customAccess, new Reference<>(false), importedClasses, false, false, thisType, openedNamespaces, false, namespace, "", true, constrVariables)); - } else { - MethodAVM2Item ft = method(pkg, isInterface, customAccess, new Reference<>(false), importedClasses, isOverride, isFinal, thisType, openedNamespaces, isStatic, namespace, fname, true, new ArrayList()); - - if (isGetter) { - if (!ft.paramTypes.isEmpty()) { - throw new AVM2ParseException("Getter can't have any parameters", lexer.yyline()); - } - } - - if (isSetter) { - if (ft.paramTypes.size() != 1) { - throw new AVM2ParseException("Getter must have exactly one parameter", lexer.yyline()); - } - } - - if (isStatic && isInterface) { - if (isInterface) { - throw new AVM2ParseException("Interface cannot have static fields", lexer.yyline()); - } - } - GraphTargetItem t; - if (isGetter) { - GetterAVM2Item g = new GetterAVM2Item(ft.pkg, isInterface, customAccess, ft.needsActivation, ft.hasRest, ft.line, ft.isOverride(), ft.isFinal(), isStatic, ft.namespace, ft.functionName, ft.paramTypes, ft.paramNames, ft.paramValues, ft.body, ft.subvariables, ft.retType); - t = g; - } else if (isSetter) { - SetterAVM2Item st = new SetterAVM2Item(ft.pkg, isInterface, customAccess, ft.needsActivation, ft.hasRest, ft.line, ft.isOverride(), ft.isFinal(), isStatic, ft.namespace, ft.functionName, ft.paramTypes, ft.paramNames, ft.paramValues, ft.body, ft.subvariables, ft.retType); - t = st; - } else { - t = ft; - } - - traits.add(t); - } - //} - break; - case NAMESPACE: - if (isInterface) { - throw new AVM2ParseException("Interface cannot have namespace fields", lexer.yyline()); - } - s = lex(); - expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); - String nname = s.value.toString(); - String nval = ""; - s = lex(); - - if (s.type == SymbolType.ASSIGN) { - s = lex(); - expected(s, lexer.yyline(), SymbolType.STRING); - nval = s.value.toString(); - s = lex(); - } else { - nval = (pkg == null || pkg.isEmpty() ? classNameStr : pkg + ":" + classNameStr) + "/" + nname; - } - if (s.type != SymbolType.SEMICOLON) { - lexer.pushback(s); - } - - ConstAVM2Item ns = new ConstAVM2Item(pkg, customAccess, true, namespace, nname, new TypeItem("Namespace"), new StringAVM2Item(null, nval), lexer.yyline()); - traits.add(ns); - break; - case CONST: - case VAR: - boolean isConst = s.type == SymbolType.CONST; - if (isOverride) { - throw new AVM2ParseException("Override flag not allowed for " + (isConst ? "consts" : "vars"), lexer.yyline()); - } - if (isFinal) { - throw new AVM2ParseException("Final flag not allowed for " + (isConst ? "consts" : "vars"), lexer.yyline()); - } - if (isDynamic) { - throw new AVM2ParseException("Dynamic flag not allowed for " + (isConst ? "consts" : "vars"), lexer.yyline()); - } - if (isInterface) { - throw new AVM2ParseException("Interface cannot have variable/const fields", lexer.yyline()); - } - - s = lex(); - expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); - String vcname = s.value.toString(); - s = lex(); - GraphTargetItem type = null; - if (s.type == SymbolType.COLON) { - type = type(thisType, pkg, new Reference<>(false), importedClasses, openedNamespaces, new ArrayList()); - s = lex(); - } else { - type = TypeItem.UNBOUNDED; - } - - GraphTargetItem value = null; - - if (s.type == SymbolType.ASSIGN) { - value = expression(thisType, pkg, new Reference<>(false), importedClasses, openedNamespaces, new HashMap(), false, false, true, isStatic || isConst ? sinitVariables : constrVariables); - s = lex(); - } - GraphTargetItem tar; - if (isConst) { - tar = new ConstAVM2Item(pkg, customAccess, isStatic, namespace, vcname, type, value, lexer.yyline()); - } else { - tar = new SlotAVM2Item(pkg, customAccess, isStatic, namespace, vcname, type, value, lexer.yyline()); - } - traits.add(tar); - if (s.type != SymbolType.SEMICOLON) { - lexer.pushback(s); - } - break; - default: - if (s.type == SymbolType.CURLY_CLOSE && inPkg && classNameStr == null) { - inPkg = false; - pkg = null; - openedNamespaces = originalOpenedNamespaces; - privateNs = originalPrivateNs; - } else { - lexer.pushback(s); - break looptrait; - } - - } - } - return constr; - } - - private GraphTargetItem classTraits(String scriptName, int gpublicNs, String pkg, List importedClasses, boolean isDynamic, boolean isFinal, List openedNamespaces, String packageName, int namespace, boolean isInterface, String nameStr, GraphTargetItem extendsStr, List implementsStr, List variables) throws IOException, AVM2ParseException, CompilationException { - - GraphTargetItem ret = null; - - ParsedSymbol s = null; - List traits = new ArrayList<>(); - - String classNameStr = nameStr; - - openedNamespaces = new ArrayList<>(openedNamespaces); - - int publicNs = 0; - int privateNs = 0; - int packageInternalNs = 0; - if (pkg != null) { - openedNamespaces.add(packageInternalNs = abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE_INTERNAL, abc.constants.getStringId(pkg, true)), 0, true)); - } - if (pkg != null && !pkg.isEmpty()) { - openedNamespaces.add(publicNs = abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abc.constants.getStringId("", true)), 0, true)); - } else { - publicNs = gpublicNs; - } - - openedNamespaces.add(privateNs = abc.constants.addNamespace(new Namespace(Namespace.KIND_PRIVATE, 0))); //abc.constants.getStringId(fileName + "$", true) - - openedNamespaces.add(abc.constants.getNamespaceId(new Namespace(Namespace.KIND_NAMESPACE, abc.constants.getStringId(AS3_NAMESPACE, true)), 0, true)); - - //int privateNs = 0; - int protectedNs = 0; - //int publicNs = namespace; - int protectedStaticNs = 0; - - openedNamespaces.add(protectedNs = abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PROTECTED, abc.constants.getStringId(packageName == null ? (scriptName + "$0:"/*FIXME?*/ + classNameStr) : packageName.isEmpty() ? classNameStr : packageName + ":" + classNameStr, true)), 0, true)); - openedNamespaces.add(protectedStaticNs = abc.constants.getNamespaceId(new Namespace(Namespace.KIND_STATIC_PROTECTED, abc.constants.getStringId(packageName == null || packageName.isEmpty() ? classNameStr : packageName + ":" + classNameStr, true)), 0, true)); - - if (extendsStr != null) { - List indices = new ArrayList<>(); - List names = new ArrayList<>(); - List namespaces = new ArrayList<>(); - //FIXME for Private classes in script!!! - AVM2SourceGenerator.parentNamesAddNames(abc, otherABCs, AVM2SourceGenerator.resolveType(new SourceGeneratorLocalData(new HashMap(), 0, false, 0), ((TypeItem) ((UnresolvedAVM2Item) extendsStr).resolve(null, new ArrayList(), new ArrayList(), abc, otherABCs, new ArrayList(), new ArrayList())), abc, otherABCs), indices, names, namespaces); - for (int i = 0; i < names.size(); i++) { - if (namespaces.get(i).isEmpty()) { - continue; - } - openedNamespaces.add(abc.constants.getNamespaceId(new Namespace(Namespace.KIND_STATIC_PROTECTED, abc.constants.getStringId(namespaces.get(i) + ":" + names.get(i), true)), 0, true)); - } - } - - Reference staticNeedsActivation = new Reference<>(false); - List staticInit = new ArrayList<>(); - List sinitVariables = new ArrayList<>(); - GraphTargetItem constr = traits(scriptName, false, sinitVariables, staticNeedsActivation, staticInit, importedClasses, privateNs, protectedNs, publicNs, packageInternalNs, protectedStaticNs, openedNamespaces, packageName, classNameStr, isInterface, traits); - - if (isInterface) { - return new InterfaceAVM2Item(importedClasses, packageName, openedNamespaces, isFinal, namespace, classNameStr, implementsStr, traits); - } else { - return new ClassAVM2Item(importedClasses, packageName, openedNamespaces, protectedNs, isDynamic, isFinal, namespace, classNameStr, extendsStr, implementsStr, staticInit, staticNeedsActivation.getVal(), sinitVariables, constr, traits); - } - } - - private GraphTargetItem expressionCommands(ParsedSymbol s, HashMap registerVars, boolean inFunction, boolean inMethod, int forinlevel, List variables) throws IOException, AVM2ParseException { - GraphTargetItem ret = null; - switch (s.type) { - /*case INT: - expectedType(SymbolType.PARENT_OPEN); - ret = new ToIntegerAVM2Item(null, expression(thisType,pkg,needsActivation, importedClasses, openedNamespaces,openedNamespacesKinds,registerVars, inFunction, inMethod, true, variables)); - expectedType(SymbolType.PARENT_CLOSE); - break; - case NUMBER_OP: - s = lex(); - if (s.type == SymbolType.DOT) { - VariableAVM2Item vi = new VariableAVM2Item(s.value.toString(), null, false); - variables.add(vi); - ret = memberOrCall(thisType,vi, registerVars, inFunction, inMethod, variables); - } else { - expected(s, lexer.yyline(), SymbolType.PARENT_OPEN); - ret = new ToNumberAVM2Item(null, expression(thisType,pkg,needsActivation, importedClasses, openedNamespaces,openedNamespacesKinds,registerVars, inFunction, inMethod, true, variables)); - expectedType(SymbolType.PARENT_CLOSE); - } - break; - case STRING_OP: - ParsedSymbol sop = s; - s = lex(); - if (s.type == SymbolType.DOT) { - lexer.pushback(s); - VariableAVM2Item vi2 = new VariableAVM2Item(sop.value.toString(), null, false); - variables.add(vi2); - ret = memberOrCall(thisType,vi2, registerVars, inFunction, inMethod, variables); - } else { - expected(s, lexer.yyline(), SymbolType.PARENT_OPEN); - ret = new ToStringAVM2Item(null, expression(thisType,pkg,needsActivation, importedClasses, openedNamespaces,openedNamespacesKinds,registerVars, inFunction, inMethod, true, variables)); - expectedType(SymbolType.PARENT_CLOSE); - ret = memberOrCall(thisType,ret, registerVars, inFunction, inMethod, variables); - } - break;*/ - default: - return null; - } - //return ret; - } - - private GraphTargetItem add(Object a) { - if (a instanceof List) { - List l = (List) a; - if (l.isEmpty()) { - return null; - } - GraphTargetItem o = add(l.get(0)); - for (int i = 1; i < l.size(); i++) { - o = add(o, l.get(i)); - } - return o; - } - if (a instanceof StringBuilder) { - if (((StringBuilder) a).length() == 0) { - return null; - } - GraphTargetItem ret = new StringAVM2Item(null, a.toString()); - ((StringBuilder) a).setLength(0); - return ret; - } - if (a instanceof String) { - return new StringAVM2Item(null, (String) a); - } - if (a instanceof GraphTargetItem) { - return (GraphTargetItem) a; - } - return null; - } - - private GraphTargetItem add(Object a, Object b) { - GraphTargetItem ta = add(a); - GraphTargetItem tb = add(b); - if (ta == null && tb == null) { - return null; - } - if (ta == null) { - return tb; - } - if (tb == null) { - return ta; - } - return new AddAVM2Item(null, ta, tb); - } - - private void addS(List rets, StringBuilder sb) { - if (sb.length() > 0) { - if (!rets.isEmpty() && (rets.get(rets.size() - 1) instanceof StringAVM2Item)) { - ((StringAVM2Item) rets.get(rets.size() - 1)).value += sb.toString(); - } else { - rets.add(new StringAVM2Item(null, sb.toString())); - } - sb.setLength(0); - } - } - - private List xmltag(TypeItem thisType, String pkg, Reference usesVars, List openedTags, Reference closedVarTags, Reference needsActivation, List importedClasses, List openedNamespaces, HashMap registerVars, boolean inFunction, boolean inMethod, List variables) throws IOException, AVM2ParseException { - ParsedSymbol s = null; - List rets = new ArrayList<>(); - //GraphTargetItem ret = null; - StringBuilder sb = new StringBuilder(); - loop: - do { - s = lex(); - List sub = new ArrayList<>(); - Reference subclose = new Reference<>(0); - Reference subusesvars = new Reference<>(false); - switch (s.type) { - case XML_ATTRNAMEVAR_BEGIN: //add - usesVars.setVal(true); - addS(rets, sb); - rets.add(expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables)); - expectedType(SymbolType.CURLY_CLOSE); - expectedType(SymbolType.ASSIGN); - sb.append("="); - lexer.yybegin(ActionScriptLexer.XMLOPENTAGATTRIB); - break; - case XML_ATTRVALVAR_BEGIN: //esc_xattr - usesVars.setVal(true); - sb.append("\""); - addS(rets, sb); - rets.add(new EscapeXAttrAVM2Item(null, expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables))); - sb.append("\""); - expectedType(SymbolType.CURLY_CLOSE); - lexer.yybegin(ActionScriptLexer.XMLOPENTAG); - break; - case XML_INSTRATTRNAMEVAR_BEGIN: //add - usesVars.setVal(true); - addS(rets, sb); - rets.add(expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables)); - expectedType(SymbolType.CURLY_CLOSE); - expectedType(SymbolType.ASSIGN); - sb.append("="); - lexer.yybegin(ActionScriptLexer.XMLOPENTAGATTRIB); - break; - case XML_INSTRATTRVALVAR_BEGIN: //esc_xattr - usesVars.setVal(true); - sb.append("\""); - addS(rets, sb); - rets.add(new EscapeXAttrAVM2Item(null, expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables))); - sb.append("\""); - expectedType(SymbolType.CURLY_CLOSE); - lexer.yybegin(ActionScriptLexer.XMLOPENTAG); - break; - case XML_VAR_BEGIN: //esc_xelem - usesVars.setVal(true); - addS(rets, sb); - rets.add(new EscapeXElemAVM2Item(null, expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables))); - expectedType(SymbolType.CURLY_CLOSE); - lexer.yybegin(ActionScriptLexer.XML); - break; - case XML_FINISHVARTAG_BEGIN: //add - usesVars.setVal(true); - closedVarTags.setVal(closedVarTags.getVal() + 1); - sb.append(""); - addS(rets, sb); - lexer.yybegin(ActionScriptLexer.XML); - break; - case XML_STARTVARTAG_BEGIN: //add - //openedTags.add("*"); - - //ret = add(ret, ); - GraphTargetItem ex = expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables); - expectedType(SymbolType.CURLY_CLOSE); - lexer.yybegin(ActionScriptLexer.XMLOPENTAG); - sub.add("*"); - sb.append("<"); - addS(rets, sb); - rets.add(ex); - rets.addAll(xmltag(thisType, pkg, subusesvars, sub, subclose, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, variables)); - closedVarTags.setVal(subclose.getVal() + subclose.getVal()); - break; - case XML_INSTRVARTAG_BEGIN: //add - usesVars.setVal(true); - addS(rets, sb); - sb.append(" st = xmltag(thisType, pkg, subusesvars, sub, closedVarTags, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, variables); - sb.append(s.value.toString()); - addS(rets, sb); - rets.addAll(st); - closedVarTags.setVal(subclose.getVal() + subclose.getVal()); - break; - /*case XML_STARTTAG_END: - sb.append(s.value.toString()); - ret = addstr(ret,sb); - break;*/ - case XML_FINISHTAG: - String tname = s.value.toString().substring(2, s.value.toString().length() - 1).trim(); - if (openedTags.contains(tname)) { - openedTags.remove(tname); - } else if (openedTags.contains("*")) { - openedTags.remove("*"); - } else { - throw new AVM2ParseException("XML : Closing unopened tag", lexer.yyline()); - } - sb.append(s.value.toString()); - break; - case XML_STARTFINISHTAG_END: - openedTags.remove(openedTags.size() - 1); //close last tag - sb.append(s.value.toString()); - break; - case EOF: - throw new AVM2ParseException("End of file before XML finish", lexer.yyline()); - default: - sb.append(s.value.toString()); - break; - } - } while (!(openedTags.isEmpty() || closedVarTags.getVal() >= openedTags.size())); - addS(rets, sb); - return rets; - } - - private GraphTargetItem xml(TypeItem thisType, String pkg, Reference needsActivation, List importedClasses, List openedNamespaces, HashMap registerVars, boolean inFunction, boolean inMethod, List variables) throws IOException, AVM2ParseException { - List openedTags = new ArrayList<>(); - int closedVarTags = 0; - - GraphTargetItem ret = add(xmltag(thisType, pkg, new Reference<>(false), openedTags, new Reference<>(closedVarTags), needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, variables)); - ret = new XMLAVM2Item(ret); - lexer.yybegin(ActionScriptLexer.YYINITIAL); - //TODO: Order of additions as in official compiler - return ret; - } - - private GraphTargetItem command(TypeItem thisType, String pkg, Reference needsActivation, List importedClasses, List openedNamespaces, Stack loops, Map loopLabels, HashMap registerVars, boolean inFunction, boolean inMethod, int forinlevel, boolean mustBeCommand, List variables) throws IOException, AVM2ParseException { - LexBufferer buf = new LexBufferer(); - lexer.addListener(buf); - GraphTargetItem ret = null; - if (debugMode) { - System.out.println("command:"); - } - ParsedSymbol s = lex(); - if (s.type == SymbolType.EOF) { - return null; - } - String loopLabel = null; - - if (s.group == SymbolGroup.IDENTIFIER) { - ParsedSymbol sc = lex(); - if (sc.type == SymbolType.COLON) { - loopLabel = s.value.toString(); - s = lex(); - } else { - lexer.pushback(sc); - } - } - - if (s.type == SymbolType.DEFAULT) { - ParsedSymbol sx = lex(); - if (sx.group != SymbolGroup.IDENTIFIER) { - lexer.pushback(sx); - } else { - if (!sx.value.equals("xml")) { - lexer.pushback(sx); - } else { - expectedType(SymbolType.NAMESPACE); - expectedType(SymbolType.ASSIGN); - GraphTargetItem ns = expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables); - ret = new DefaultXMLNamespace(null, ns); - //TODO: use dxns for attribute namespaces instead of dxnslate - } - } - } - if (ret == null) { - switch (s.type) { - case USE: - expectedType(SymbolType.NAMESPACE); - GraphTargetItem ns = type(thisType, pkg, needsActivation, importedClasses, openedNamespaces, variables); - openedNamespaces.add(abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE /*FIXME?*/, abc.constants.getStringId(ns.toString(), true)), 0, true)); - break; - case WITH: - needsActivation.setVal(true); - expectedType(SymbolType.PARENT_OPEN); - GraphTargetItem wvar = expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables);//(name(thisType,false, openedNamespaces, registerVars, inFunction, inMethod, variables)); - if (!isNameOrProp(wvar)) { - throw new AVM2ParseException("Not a property or name", lexer.yyline()); - } - expectedType(SymbolType.PARENT_CLOSE); - expectedType(SymbolType.CURLY_OPEN); - List withVars = new ArrayList<>(); - List wcmd = commands(thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, withVars); - variables.addAll(withVars); - for (AssignableAVM2Item a : withVars) { - if (a instanceof UnresolvedAVM2Item) { - UnresolvedAVM2Item ua = (UnresolvedAVM2Item) a; - ua.scopeStack.add(0, wvar); - } - } - expectedType(SymbolType.CURLY_CLOSE); - ret = new WithAVM2Item(null, wvar, wcmd); - ((WithAVM2Item) ret).subvariables = withVars; - break; - /*case DELETE: - GraphTargetItem varDel = expression(thisType,pkg,needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables);//name(thisType,false, openedNamespaces, registerVars, inFunction, inMethod, variables); - if(!isNameOrProp(varDel)){ - throw new ParseException("Not a property or name", lexer.yyline()); - } - if (varDel instanceof GetPropertyAVM2Item) { - GetPropertyAVM2Item gm = (GetPropertyAVM2Item) varDel; - ret = new DeletePropertyAVM2Item(null, gm.object, gm.propertyName); - } else if (varDel instanceof NameAVM2Item) { - variables.remove(varDel); - ret = new DeletePropertyAVM2Item(null, null, (NameAVM2Item) varDel); - } else { - throw new ParseException("Not a property", lexer.yyline()); - } - break;*/ - case FUNCTION: - s = lexer.lex(); - expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); - needsActivation.setVal(true); - ret = (function(pkg, false, needsActivation, importedClasses, 0/*?*/, thisType, openedNamespaces, s.value.toString(), false, variables)); - break; - case VAR: - s = lex(); - expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); - String varIdentifier = s.value.toString(); - s = lex(); - GraphTargetItem type; - if (s.type == SymbolType.COLON) { - type = type(thisType, pkg, needsActivation, importedClasses, openedNamespaces, variables); - s = lex(); - } else { - type = new UnboundedTypeItem(); - } - - if (s.type == SymbolType.ASSIGN) { - GraphTargetItem varval = (expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables)); - ret = new NameAVM2Item(type, lexer.yyline(), varIdentifier, varval, true, openedNamespaces); - variables.add((NameAVM2Item) ret); - } else { - ret = new NameAVM2Item(type, lexer.yyline(), varIdentifier, null, true, openedNamespaces); - variables.add((NameAVM2Item) ret); - lexer.pushback(s); - } - break; - case CURLY_OPEN: - ret = new BlockItem(null, commands(thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, variables)); - expectedType(SymbolType.CURLY_CLOSE); - break; - /*case INCREMENT: //preincrement - case DECREMENT: //predecrement - GraphTargetItem varincdec = expression(thisType,pkg,needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables);//name(thisType,false, openedNamespaces, registerVars, inFunction, inMethod, variables); - if(!isNameOrProp(varincdec)){ - throw new ParseException("Not a property or name", lexer.yyline()); - } - if (s.type == SymbolType.INCREMENT) { - ret = new PreIncrementAVM2Item(null, varincdec); - } else if (s.type == SymbolType.DECREMENT) { - ret = new PreDecrementAVM2Item(null, varincdec); - } - break;*/ - case SUPER: //constructor call - ParsedSymbol ss2 = lex(); - if (ss2.type == SymbolType.PARENT_OPEN) { - List args = call(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, variables); - ret = new ConstructSuperAVM2Item(null, new LocalRegAVM2Item(null, 0, null), args); - } else {//no costructor call, but it could be calling parent methods... => handle in expression - lexer.pushback(ss2); - lexer.pushback(s); - } - break; - case IF: - expectedType(SymbolType.PARENT_OPEN); - GraphTargetItem ifExpr = (expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables)); - expectedType(SymbolType.PARENT_CLOSE); - GraphTargetItem onTrue = command(thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables); - List onTrueList = new ArrayList<>(); - onTrueList.add(onTrue); - s = lex(); - List onFalseList = null; - if (s.type == SymbolType.ELSE) { - onFalseList = new ArrayList<>(); - onFalseList.add(command(thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables)); - } else { - lexer.pushback(s); - } - ret = new IfItem(null, ifExpr, onTrueList, onFalseList); - break; - case WHILE: - expectedType(SymbolType.PARENT_OPEN); - List whileExpr = new ArrayList<>(); - whileExpr.add(commaExpression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, variables)); - expectedType(SymbolType.PARENT_CLOSE); - List whileBody = new ArrayList<>(); - Loop wloop = new Loop(uniqId(), null, null); - if (loopLabel != null) { - loopLabels.put(wloop, loopLabel); - } - loops.push(wloop); - whileBody.add(command(thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables)); - ret = new WhileItem(null, wloop, whileExpr, whileBody); - break; - case DO: - List doBody = new ArrayList<>(); - Loop dloop = new Loop(uniqId(), null, null); - loops.push(dloop); - if (loopLabel != null) { - loopLabels.put(dloop, loopLabel); - } - doBody.add(command(thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables)); - expectedType(SymbolType.WHILE); - expectedType(SymbolType.PARENT_OPEN); - List doExpr = new ArrayList<>(); - doExpr.add(commaExpression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, variables)); - expectedType(SymbolType.PARENT_CLOSE); - ret = new DoWhileItem(null, dloop, doBody, doExpr); - break; - case FOR: - s = lex(); - boolean forin = false; - boolean each = false; - GraphTargetItem collection = null; - if (s.type == SymbolType.EACH) { - each = true; - forin = true; - s = lex(); - } - expected(s, lexer.yyline(), SymbolType.PARENT_OPEN); - GraphTargetItem firstCommand = command(thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, false, variables); - if (firstCommand instanceof NameAVM2Item) { - NameAVM2Item nai = (NameAVM2Item) firstCommand; - if (nai.isDefinition() && nai.getAssignedValue() == null) { //??? WUT - firstCommand = expression1(firstCommand, firstCommand.getPrecedence(), thisType, pkg, needsActivation, importedClasses, openedNamespaces, true, registerVars, inFunction, inMethod, true, variables); - } - } - InAVM2Item inexpr = null; - if (firstCommand instanceof InAVM2Item) { - forin = true; - inexpr = (InAVM2Item) firstCommand; - } else { - if (forin) { - throw new AVM2ParseException("In expression required", lexer.yyline()); - } - } - - Loop floop = new Loop(uniqId(), null, null); - loops.push(floop); - if (loopLabel != null) { - loopLabels.put(floop, loopLabel); - } - List forFinalCommands = new ArrayList<>(); - GraphTargetItem forExpr = null; - List forFirstCommands = new ArrayList<>(); - if (!forin) { - //GraphTargetItem firstCommand = command(thisType,pkg,needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables); - if (firstCommand != null) { //can be empty command - forFirstCommands.add(firstCommand); - } - forExpr = (expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables)); - expectedType(SymbolType.SEMICOLON); - forFinalCommands.add(command(thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables)); - } - expectedType(SymbolType.PARENT_CLOSE); - List forBody = new ArrayList<>(); - forBody.add(command(thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forin ? forinlevel + 1 : forinlevel, true, variables)); - if (forin) { - if (each) { - ret = new ForEachInAVM2Item(null, floop, inexpr, forBody); - } else { - - ret = new ForInAVM2Item(null, floop, inexpr, forBody); - } - } else { - ret = new ForItem(null, floop, forFirstCommands, forExpr, forFinalCommands, forBody); - } - break; - case SWITCH: - Loop sloop = new Loop(-uniqId(), null, null); //negative id marks switch = no continue - loops.push(sloop); - if (loopLabel != null) { - loopLabels.put(sloop, loopLabel); - } - expectedType(SymbolType.PARENT_OPEN); - GraphTargetItem switchExpr = expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables); - expectedType(SymbolType.PARENT_CLOSE); - expectedType(SymbolType.CURLY_OPEN); - s = lex(); - //ret.addAll(switchExpr); - int exprReg = 0; - for (int i = 0; i < 256; i++) { - if (!registerVars.containsValue(i)) { - registerVars.put("__switch" + uniqId(), i); - exprReg = i; - break; - } - } - List> caseIfs = new ArrayList<>(); - List> caseCmds = new ArrayList<>(); - List caseExprsAll = new ArrayList<>(); - List valueMapping = new ArrayList<>(); - int pos = 0; - while (s.type == SymbolType.CASE) { - List caseExprs = new ArrayList<>(); - while (s.type == SymbolType.CASE) { - GraphTargetItem curCaseExpr = expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables); - caseExprs.add(curCaseExpr); - expectedType(SymbolType.COLON); - s = lex(); - caseExprsAll.add(curCaseExpr); - valueMapping.add(pos); - } - pos++; - lexer.pushback(s); - List caseCmd = commands(thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, variables); - caseCmds.add(caseCmd); - s = lex(); - } - List defCmd = new ArrayList<>(); - if (s.type == SymbolType.DEFAULT) { - expectedType(SymbolType.COLON); - defCmd = commands(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, sloop, switchExpr, caseExprsAll, caseCmds, defCmd, valueMapping); - break; - case BREAK: - s = lex(); - long bloopId = 0; - if (loops.isEmpty()) { - throw new AVM2ParseException("No loop to break", lexer.yyline()); - } - if (s.group == SymbolGroup.IDENTIFIER) { - String breakLabel = s.value.toString(); - for (Loop l : loops) { - if (breakLabel.equals(loopLabels.get(l))) { - bloopId = l.id; - break; - } - } - if (bloopId == 0) { - throw new AVM2ParseException("Identifier of loop expected", lexer.yyline()); - } - } else { - lexer.pushback(s); - bloopId = loops.peek().id; - } - ret = new BreakItem(null, bloopId); - break; - case CONTINUE: - s = lex(); - long cloopId = 0; - if (loops.isEmpty()) { - throw new AVM2ParseException("No loop to continue", lexer.yyline()); - } - if (s.group == SymbolGroup.IDENTIFIER) { - String continueLabel = s.value.toString(); - for (Loop l : loops) { - if (l.id < 0) { //negative id marks switch => no continue - continue; - } - if (continueLabel.equals(loopLabels.get(l))) { - cloopId = l.id; - break; - } - } - if (cloopId == -1) { - throw new AVM2ParseException("Identifier of loop expected", lexer.yyline()); - } - } else { - lexer.pushback(s); - for (int i = loops.size() - 1; i >= 0; i--) { - if (loops.get(i).id >= 0) {//no switches - cloopId = loops.get(i).id; - break; - } - } - if (cloopId <= 0) { - throw new AVM2ParseException("No loop to continue", lexer.yyline()); - } - } - //TODO: handle switch - ret = new ContinueItem(null, cloopId); - break; - case RETURN: - GraphTargetItem retexpr = expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, true, registerVars, inFunction, inMethod, true, variables); - if (retexpr == null) { - ret = new ReturnVoidAVM2Item(null); - } else { - ret = new ReturnValueAVM2Item(null, retexpr); - } - break; - case TRY: - needsActivation.setVal(true); - List tryCommands = new ArrayList<>(); - tryCommands.add(command(thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables)); - s = lex(); - boolean found = false; - List> catchCommands = new ArrayList<>(); - List catchExceptions = new ArrayList<>(); - int varCnt = variables.size(); - List> catchesVars = new ArrayList<>(); - while (s.type == SymbolType.CATCH) { - expectedType(SymbolType.PARENT_OPEN); - s = lex(); - expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER, SymbolType.THIS, SymbolType.SUPER, SymbolType.STRING_OP); - - String enamestr = s.value.toString(); - expectedType(SymbolType.COLON); - GraphTargetItem etype = type(thisType, pkg, needsActivation, importedClasses, openedNamespaces, variables); - NameAVM2Item e = new NameAVM2Item(etype, lexer.yyline(), enamestr, new ExceptionAVM2Item(null)/*?*/, true/*?*/, openedNamespaces); - variables.add(e); - catchExceptions.add(e); - e.setSlotNumber(1); - e.setSlotScope(Integer.MAX_VALUE); //will be changed later - expectedType(SymbolType.PARENT_CLOSE); - List cc = new ArrayList<>(); - List catchVars = new ArrayList<>(); - cc.add(command(thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, catchVars)); - catchesVars.add(catchVars); - variables.addAll(catchVars); - - for (AssignableAVM2Item a : catchVars) { - if (a instanceof UnresolvedAVM2Item) { - UnresolvedAVM2Item ui = (UnresolvedAVM2Item) a; - if (ui.getVariableName().equals(e.getVariableName())) { - try { - ui.resolve(null, new ArrayList(), new ArrayList(), abc, otherABCs, new ArrayList(), variables); - } catch (CompilationException ex) { - // ignore - } - ui.setSlotNumber(e.getSlotNumber()); - ui.setSlotScope(e.getSlotScope()); - } - - } - } - - catchCommands.add(cc); - s = lex(); - found = true; - } - //TODO: - for (int i = varCnt; i < variables.size(); i++) { - AssignableAVM2Item av = variables.get(i); - if (av instanceof UnresolvedAVM2Item) { - UnresolvedAVM2Item ui = (UnresolvedAVM2Item) av; - for (NameAVM2Item e : catchExceptions) { - if (ui.getVariableName().equals(e.getVariableName())) { - try { - ui.resolve(null, new ArrayList(), new ArrayList(), abc, otherABCs, new ArrayList(), variables); - } catch (CompilationException ex) { - // ignore - } - ui.setSlotNumber(e.getSlotNumber()); - ui.setSlotScope(e.getSlotScope()); - } - } - } - } - - List finallyCommands = null; - if (s.type == SymbolType.FINALLY) { - finallyCommands = new ArrayList<>(); - finallyCommands.add(command(thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables)); - found = true; - s = lex(); - } - if (!found) { - expected(s, lexer.yyline(), SymbolType.CATCH, SymbolType.FINALLY); - } - lexer.pushback(s); - TryAVM2Item tai = new TryAVM2Item(tryCommands, null, catchCommands, finallyCommands); - tai.catchVariables = catchesVars; - tai.catchExceptions2 = catchExceptions; - ret = tai; - break; - case THROW: - ret = new ThrowAVM2Item(null, expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables)); - break; - default: - GraphTargetItem valcmd = expressionCommands(s, registerVars, inFunction, inMethod, forinlevel, variables); - if (valcmd != null) { - ret = valcmd; - break; - } - if (s.type == SymbolType.SEMICOLON) { - return null; - } - lexer.pushback(s); - ret = expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables); - if (debugMode) { - System.out.println("/command"); - } - } - } - if (debugMode) { - System.out.println("/command"); - } - lexer.removeListener(buf); - if (ret == null) { //can be popped expression - buf.pushAllBack(lexer); - ret = expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables); - } - s = lex(); - if ((s != null) && (s.type != SymbolType.SEMICOLON)) { - lexer.pushback(s); - } - - return ret; - - } - - private GraphTargetItem expression(TypeItem thisType, String pkg, Reference needsActivation, List importedClasses, List openedNamespaces, HashMap registerVars, boolean inFunction, boolean inMethod, boolean allowRemainder, List variables) throws IOException, AVM2ParseException { - return expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, false, registerVars, inFunction, inMethod, allowRemainder, variables); - } - - private GraphTargetItem fixPrecedence(GraphTargetItem expr) { - System.out.println("Fixing " + expr); - GraphTargetItem ret = expr; - - /* - fix > : - a || b > c => a || (b > c) - - a < 0 || (b > c) + 1 - - */ - if (expr instanceof BinaryOp) { - BinaryOp bo = (BinaryOp) expr; - GraphTargetItem left = bo.getLeftSide(); - GraphTargetItem right = bo.getRightSide(); - if (left.getPrecedence() > bo.getPrecedence()) { - if (left instanceof BinaryOp) { - BinaryOp leftBo = (BinaryOp) left; - bo.setLeftSide(leftBo.getRightSide()); - leftBo.setRightSide(expr); - System.out.println("fixed"); - return left; - } - } - } - return ret; - } - - /*private GraphTargetItem expressionRemainder(TypeItem thisType, String pkg, Reference needsActivation, List openedNamespaces, GraphTargetItem expr, HashMap registerVars, boolean inFunction, boolean inMethod, boolean allowRemainder, List variables, List importedClasses) throws IOException, AVM2ParseException { - GraphTargetItem ret = null; - ParsedSymbol s = lex(); - - ret = fixPrecedence(ret); - return ret; - }*/ - private boolean isNameOrProp(GraphTargetItem item) { - if (item instanceof UnresolvedAVM2Item) { - return true; //we don't know yet - } - if (item instanceof NameAVM2Item) { - return true; - } - if (item instanceof PropertyAVM2Item) { - return true; - } - if (item instanceof IndexAVM2Item) { - return true; - } - return false; - } - - private boolean isType(GraphTargetItem item) { - if (item == null) { - return false; - } - while (item instanceof GetPropertyAVM2Item) { - item = ((GetPropertyAVM2Item) item).object; - } - if (item instanceof NameAVM2Item) { - return true; - } - return false; - } - - private int brackets(TypeItem thisType, String pkg, Reference needsActivation, List importedClasses, List openedNamespaces, List ret, HashMap registerVars, boolean inFunction, boolean inMethod, List variables) throws IOException, AVM2ParseException { - ParsedSymbol s = lex(); - int arrCnt = 0; - if (s.type == SymbolType.BRACKET_OPEN) { - s = lex(); - - while (s.type != SymbolType.BRACKET_CLOSE) { - if (s.type != SymbolType.COMMA) { - lexer.pushback(s); - } - arrCnt++; - ret.add(expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables)); - s = lex(); - if (!s.isType(SymbolType.COMMA, SymbolType.BRACKET_CLOSE)) { - expected(s, lexer.yyline(), SymbolType.COMMA, SymbolType.BRACKET_CLOSE); - } - } - } else { - lexer.pushback(s); - return -1; - } - return arrCnt; - } - - private GraphTargetItem commaExpression(TypeItem thisType, String pkg, Reference needsActivation, List importedClasses, List openedNamespaces, Stack loops, Map loopLabels, HashMap registerVars, boolean inFunction, boolean inMethod, int forInLevel, List variables) throws IOException, AVM2ParseException { - GraphTargetItem cmd = null; - List expr = new ArrayList<>(); - ParsedSymbol s; - do { - cmd = command(thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forInLevel, false, variables); - if (cmd != null) { - expr.add(cmd); - } - s = lex(); - } while (s.type == SymbolType.COMMA && cmd != null); - lexer.pushback(s); - if (cmd == null) { - expr.add(expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables)); - } else { - if (!cmd.hasReturnValue()) { - throw new AVM2ParseException("Expression expected", lexer.yyline()); - } - } - return new CommaExpressionItem(null, expr); - } - - private GraphTargetItem expression(TypeItem thisType, String pkg, Reference needsActivation, List importedClasses, List openedNamespaces, boolean allowEmpty, HashMap registerVars, boolean inFunction, boolean inMethod, boolean allowRemainder, List variables) throws IOException, AVM2ParseException { - GraphTargetItem prim = expressionPrimary(thisType, pkg, needsActivation, importedClasses, openedNamespaces, allowEmpty, registerVars, inFunction, inMethod, allowRemainder, variables); - if (prim == null) { - return null; - } - return expression1(prim, GraphTargetItem.NOPRECEDENCE, thisType, pkg, needsActivation, importedClasses, openedNamespaces, allowEmpty, registerVars, inFunction, inMethod, allowRemainder, variables); - } - - /** - * Lexer can return XML opentags instead of greater. In expression, we need - * greater sign only - * - * @param symb - */ - private void xmlToGreaterFix(ParsedSymbol symb) { - if (symb.isType(SymbolType.XML_STARTVARTAG_BEGIN, SymbolType.XML_STARTTAG_BEGIN)) { - lexer.yypushbackstr(symb.value.toString().substring(1)); //parse again as GREATER_THAN - symb.type = SymbolType.GREATER_THAN; - symb.group = SymbolGroup.OPERATOR; - } - } - - private ParsedSymbol peekExprToken() throws IOException, AVM2ParseException { - ParsedSymbol lookahead = lex(); - xmlToGreaterFix(lookahead); - - lexer.pushback(lookahead); - return lookahead; - } - - private GraphTargetItem expression1(GraphTargetItem lhs, int min_precedence, TypeItem thisType, String pkg, Reference needsActivation, List importedClasses, List openedNamespaces, boolean allowEmpty, HashMap registerVars, boolean inFunction, boolean inMethod, boolean allowRemainder, List variables) throws IOException, AVM2ParseException { - if (debugMode) { - System.out.println("expression1:"); - } - ParsedSymbol lookahead = peekExprToken(); - - ParsedSymbol op; - GraphTargetItem rhs; - GraphTargetItem mhs = null; - - //Note: algorithm from http://en.wikipedia.org/wiki/Operator-precedence_parser - //with relation operators reversed as we have precedence in reverse order - while (lookahead.type.isBinary() && lookahead.type.getPrecedence() <= /* >= on wiki */ min_precedence) { - op = lookahead; - lex(); - - //Note: Handle ternar operator as Binary - //http://stackoverflow.com/questions/13681293/how-can-i-incorporate-ternary-operators-into-a-precedence-climbing-algorithm - if (op.type == SymbolType.TERNAR) { - if (debugMode) { - System.out.println("ternar-middle:"); - } - mhs = expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, allowRemainder, variables); - expectedType(SymbolType.COLON); - if (debugMode) { - System.out.println("/ternar-middle"); - } - } - - rhs = expressionPrimary(thisType, pkg, needsActivation, importedClasses, openedNamespaces, allowEmpty, registerVars, inFunction, inMethod, allowRemainder, variables); - if (rhs == null) { - lexer.pushback(op); - break; - } - - lookahead = peekExprToken(); - while ((lookahead.type.isBinary() && lookahead.type.getPrecedence() < /* > on wiki */ op.type.getPrecedence()) - || (lookahead.type.isRightAssociative() && lookahead.type.getPrecedence() == op.type.getPrecedence())) { - rhs = expression1(rhs, lookahead.type.getPrecedence(), thisType, pkg, needsActivation, importedClasses, openedNamespaces, allowEmpty, registerVars, inFunction, inMethod, allowRemainder, variables); - lookahead = peekExprToken(); - } - - switch (op.type) { - case AS: - //GraphTargetItem type = type(thisType, pkg, needsActivation, importedClasses, openedNamespaces, variables); - - lhs = new AsTypeAVM2Item(null, lhs, rhs); //??? - allowRemainder = false; - break; - - case IN: - lhs = new InAVM2Item(null, lhs, rhs); - break; - - case TERNAR: //??? - lhs = new TernarOpItem(null, lhs, mhs, rhs); - break; - case SHIFT_LEFT: - lhs = new LShiftAVM2Item(null, lhs, rhs); - break; - case SHIFT_RIGHT: - lhs = new RShiftAVM2Item(null, lhs, rhs); - break; - case USHIFT_RIGHT: - lhs = new URShiftAVM2Item(null, lhs, rhs); - break; - case BITAND: - lhs = new BitAndAVM2Item(null, lhs, rhs); - break; - case BITOR: - lhs = new BitOrAVM2Item(null, lhs, rhs); - break; - case DIVIDE: - lhs = new DivideAVM2Item(null, lhs, rhs); - break; - case MODULO: - lhs = new ModuloAVM2Item(null, lhs, rhs); - break; - case EQUALS: - lhs = new EqAVM2Item(null, lhs, rhs); - break; - case STRICT_EQUALS: - lhs = new StrictEqAVM2Item(null, lhs, rhs); - break; - case NOT_EQUAL: - lhs = new NeqAVM2Item(null, lhs, rhs); - break; - case STRICT_NOT_EQUAL: - lhs = new StrictNeqAVM2Item(null, lhs, rhs); - break; - case LOWER_THAN: - lhs = new LtAVM2Item(null, lhs, rhs); - break; - case LOWER_EQUAL: - lhs = new LeAVM2Item(null, lhs, rhs); - break; - case GREATER_THAN: - lhs = new GtAVM2Item(null, lhs, rhs); - break; - case GREATER_EQUAL: - lhs = new GeAVM2Item(null, lhs, rhs); - break; - case AND: - lhs = new AndItem(null, lhs, rhs); - break; - case OR: - lhs = new OrItem(null, lhs, rhs); - break; - case MINUS: - lhs = new SubtractAVM2Item(null, lhs, rhs); - break; - case MULTIPLY: - lhs = new MultiplyAVM2Item(null, lhs, rhs); - break; - case PLUS: - lhs = new AddAVM2Item(null, lhs, rhs); - break; - case XOR: - lhs = new BitXorAVM2Item(null, lhs, rhs); - break; - case INSTANCEOF: - lhs = new InstanceOfAVM2Item(null, lhs, rhs); - break; - case IS: - GraphTargetItem istype = rhs;//type(thisType,pkg,needsActivation, importedClasses, openedNamespaces, variables); - lhs = new IsTypeAVM2Item(null, lhs, istype); - break; - case ASSIGN: - case ASSIGN_BITAND: - case ASSIGN_BITOR: - case ASSIGN_DIVIDE: - case ASSIGN_MINUS: - case ASSIGN_MODULO: - case ASSIGN_MULTIPLY: - case ASSIGN_PLUS: - case ASSIGN_SHIFT_LEFT: - case ASSIGN_SHIFT_RIGHT: - case ASSIGN_USHIFT_RIGHT: - case ASSIGN_XOR: - GraphTargetItem assigned = rhs; - switch (op.type) { - case ASSIGN: - //assigned = assigned; - break; - case ASSIGN_BITAND: - assigned = new BitAndAVM2Item(null, lhs, assigned); - break; - case ASSIGN_BITOR: - assigned = new BitOrAVM2Item(null, lhs, assigned); - break; - case ASSIGN_DIVIDE: - assigned = new DivideAVM2Item(null, lhs, assigned); - break; - case ASSIGN_MINUS: - assigned = new SubtractAVM2Item(null, lhs, assigned); - break; - case ASSIGN_MODULO: - assigned = new ModuloAVM2Item(null, lhs, assigned); - break; - case ASSIGN_MULTIPLY: - assigned = new MultiplyAVM2Item(null, lhs, assigned); - break; - case ASSIGN_PLUS: - assigned = new AddAVM2Item(null, lhs, assigned); - break; - case ASSIGN_SHIFT_LEFT: - assigned = new LShiftAVM2Item(null, lhs, assigned); - break; - case ASSIGN_SHIFT_RIGHT: - assigned = new RShiftAVM2Item(null, lhs, assigned); - break; - case ASSIGN_USHIFT_RIGHT: - assigned = new URShiftAVM2Item(null, lhs, assigned); - break; - case ASSIGN_XOR: - assigned = new BitXorAVM2Item(null, lhs, assigned); - break; - } - - if (!(lhs instanceof AssignableAVM2Item)) { - throw new AVM2ParseException("Invalid assignment", lexer.yyline()); - } - AssignableAVM2Item as = ((AssignableAVM2Item) lhs).copy(); - if ((as instanceof UnresolvedAVM2Item) || (as instanceof NameAVM2Item)) { - variables.add(as); - } - as.setAssignedValue(assigned); - if (lhs instanceof NameAVM2Item) { - ((NameAVM2Item) lhs).setDefinition(false); - } - lhs = as; - break; - case DESCENDANTS: - expected(lookahead, lexer.yyline(), SymbolGroup.IDENTIFIER, SymbolType.MULTIPLY); - lookahead = lex(); - lhs = new GetDescendantsAVM2Item(lhs, lookahead.type == SymbolType.MULTIPLY ? null : lookahead.value.toString(), openedNamespaces); - allowRemainder = true; - break; - } - } - - switch (lookahead.type) { - case DOT: //member - case BRACKET_OPEN: //member - case PARENT_OPEN: //function call - case FILTER: - lhs = memberOrCall(thisType, pkg, needsActivation, importedClasses, openedNamespaces, lhs, registerVars, inFunction, inMethod, variables); - break; - - default: - if (lhs instanceof ParenthesisItem) { - GraphTargetItem coerced = expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, allowRemainder, variables); - if (coerced != null && isType(((ParenthesisItem) lhs).value)) { - lhs = new CoerceAVM2Item(null, ((ParenthesisItem) lhs).value, coerced); - } - } - } - - if (debugMode) { - System.out.println("/expression1"); - } - return lhs; - } - - private GraphTargetItem expressionPrimary(TypeItem thisType, String pkg, Reference needsActivation, List importedClasses, List openedNamespaces, boolean allowEmpty, HashMap registerVars, boolean inFunction, boolean inMethod, boolean allowRemainder, List variables) throws IOException, AVM2ParseException { - if (debugMode) { - System.out.println("primary:"); - } - GraphTargetItem ret = null; - ParsedSymbol s = lex(); - switch (s.type) { - case XML_STARTTAG_BEGIN: - lexer.pushback(s); - ret = xml(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, variables); - - break; - case STRING: - ret = new StringAVM2Item(null, s.value.toString()); - - break; - case NEGATE: - ret = expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, false, variables); - ret = new NegAVM2Item(null, ret); - - break; - case MINUS: - s = lex(); - if (s.isType(SymbolType.DOUBLE)) { - ret = new FloatValueAVM2Item(null, -(Double) s.value); - - } else if (s.isType(SymbolType.INTEGER)) { - ret = new IntegerValueAVM2Item(null, -(Long) s.value); - - } else { - lexer.pushback(s); - GraphTargetItem num = expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables); - if (num instanceof IntegerValueAVM2Item) { - ((IntegerValueAVM2Item) num).value = -((IntegerValueAVM2Item) num).value; - ret = num; - } else if (num instanceof FloatValueAVM2Item) { - Double d = ((FloatValueAVM2Item) num).value; - if (d.isInfinite()) { - ((FloatValueAVM2Item) num).value = Double.NEGATIVE_INFINITY; - } else { - ((FloatValueAVM2Item) num).value = -d; - } - ret = (num); - } else { - ret = (new SubtractAVM2Item(null, new IntegerValueAVM2Item(null, 0L), num)); - } - } - break; - case TYPEOF: - ret = new TypeOfAVM2Item(null, expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, false, variables)); - - break; - case TRUE: - ret = new BooleanAVM2Item(null, true); - - break; - case NULL: - ret = new NullAVM2Item(null); - - break; - case UNDEFINED: - ret = new UndefinedAVM2Item(null); - break; - case FALSE: - ret = new BooleanAVM2Item(null, false); - - break; - case CURLY_OPEN: //Object literal - s = lex(); - List nvs = new ArrayList<>(); - - while (s.type != SymbolType.CURLY_CLOSE) { - if (s.type != SymbolType.COMMA) { - lexer.pushback(s); - } - s = lex(); - expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER, SymbolType.STRING); - - GraphTargetItem n = new StringAVM2Item(null, s.value.toString()); -//expression(thisType,pkg,needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, allowRemainder, variables); - expectedType(SymbolType.COLON); - GraphTargetItem v = expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, allowRemainder, variables); - - NameValuePair nv = new NameValuePair(n, v); - nvs.add(nv); - s = lex(); - if (!s.isType(SymbolType.COMMA, SymbolType.CURLY_CLOSE)) { - expected(s, lexer.yyline(), SymbolType.COMMA, SymbolType.CURLY_CLOSE); - } - } - ret = new NewObjectAVM2Item(null, nvs); - ret = memberOrCall(thisType, pkg, needsActivation, importedClasses, openedNamespaces, ret, registerVars, inFunction, inMethod, variables); - break; - case BRACKET_OPEN: //Array literal or just brackets - lexer.pushback(s); - List inBrackets = new ArrayList<>(); - int arrCnt = brackets(thisType, pkg, needsActivation, importedClasses, openedNamespaces, inBrackets, registerVars, inFunction, inMethod, variables); - ret = new NewArrayAVM2Item(null, inBrackets); - ret = memberOrCall(thisType, pkg, needsActivation, importedClasses, openedNamespaces, ret, registerVars, inFunction, inMethod, variables); - - break; - case FUNCTION: - s = lexer.lex(); - String fname = ""; - if (s.isType(SymbolGroup.IDENTIFIER)) { - fname = s.value.toString(); - } else { - lexer.pushback(s); - } - needsActivation.setVal(true); - ret = function(pkg, false, needsActivation, importedClasses, 0/*?*/, thisType, openedNamespaces, fname, false, variables); - ret = memberOrCall(thisType, pkg, needsActivation, importedClasses, openedNamespaces, ret, registerVars, inFunction, inMethod, variables); - break; - case NAN: - ret = new NanAVM2Item(null); - - break; - case INFINITY: - ret = new FloatValueAVM2Item(null, Double.POSITIVE_INFINITY); - - break; - case INTEGER: - ret = new IntegerValueAVM2Item(null, (Long) s.value); - - break; - case DOUBLE: - ret = new FloatValueAVM2Item(null, (Double) s.value); - - break; - case DELETE: - GraphTargetItem varDel = expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables);//name(thisType,false, openedNamespaces, registerVars, inFunction, inMethod, variables); - if (!isNameOrProp(varDel)) { - throw new AVM2ParseException("Not a property or name", lexer.yyline()); - } - ret = new DeletePropertyAVM2Item(varDel, lexer.yyline()); - break; - case INCREMENT: - case DECREMENT: //preincrement - GraphTargetItem varincdec = expressionPrimary(thisType, pkg, needsActivation, importedClasses, openedNamespaces, false, registerVars, inFunction, inMethod, false/*?*/, variables);//name(thisType,false, openedNamespaces, registerVars, inFunction, inMethod, variables); - if (!isNameOrProp(varincdec)) { - throw new AVM2ParseException("Not a property or name", lexer.yyline()); - } - if (s.type == SymbolType.INCREMENT) { - ret = new PreIncrementAVM2Item(null, varincdec); - } - if (s.type == SymbolType.DECREMENT) { - ret = new PreDecrementAVM2Item(null, varincdec); - } - - break; - case NOT: - ret = new NotItem(null, expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, false, variables)); - - break; - case PARENT_OPEN: - ret = new ParenthesisItem(null, expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables)); - expectedType(SymbolType.PARENT_CLOSE); - ret = memberOrCall(thisType, pkg, needsActivation, importedClasses, openedNamespaces, ret, registerVars, inFunction, inMethod, variables); - - break; - case NEW: - s = lex(); - if (s.type == SymbolType.XML_STARTTAG_BEGIN) { - lexer.yypushbackstr(s.value.toString().substring(1), ActionScriptLexer.YYINITIAL); - s = new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.LOWER_THAN); - } - if (s.type == SymbolType.FUNCTION) { - s = lexer.lex(); - String ffname = ""; - if (s.isType(SymbolGroup.IDENTIFIER)) { - ffname = s.value.toString(); - } else { - lexer.pushback(s); - } - needsActivation.setVal(true); - ret = function(pkg, false, needsActivation, importedClasses, 0/*?*/, thisType, openedNamespaces, ffname, false, variables); - } else if (s.type == SymbolType.LOWER_THAN) { - GraphTargetItem subtype = type(thisType, pkg, needsActivation, importedClasses, openedNamespaces, variables); - expectedType(SymbolType.GREATER_THAN); - s = lex(); - expected(s, lexer.yyline(), SymbolType.BRACKET_OPEN); - lexer.pushback(s); - List params = new ArrayList<>(); - brackets(thisType, pkg, needsActivation, importedClasses, openedNamespaces, params, registerVars, inFunction, inMethod, variables); - ret = new InitVectorAVM2Item(subtype, params, openedNamespaces); - } else if (s.type == SymbolType.PARENT_OPEN) { - GraphTargetItem newvar = expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables); - newvar = applyType(thisType, pkg, needsActivation, importedClasses, openedNamespaces, newvar, registerVars, inFunction, inMethod, variables); - expectedType(SymbolType.PARENT_CLOSE); - expectedType(SymbolType.PARENT_OPEN); - ret = new ConstructSomethingAVM2Item(lexer.yyline(), openedNamespaces, newvar, call(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, variables)); - - } else { - lexer.pushback(s); - GraphTargetItem newvar = name(thisType, pkg, needsActivation, false /*?*/, openedNamespaces, registerVars, inFunction, inMethod, variables, importedClasses); - newvar = applyType(thisType, pkg, needsActivation, importedClasses, openedNamespaces, newvar, registerVars, inFunction, inMethod, variables); - expectedType(SymbolType.PARENT_OPEN); - ret = new ConstructSomethingAVM2Item(lexer.yyline(), openedNamespaces, newvar, call(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, variables)); - } - - break; - case IDENTIFIER: - case THIS: - case SUPER: - case ATTRIBUTE: - lexer.pushback(s); - GraphTargetItem var = name(thisType, pkg, needsActivation, false, openedNamespaces, registerVars, inFunction, inMethod, variables, importedClasses); - var = memberOrCall(thisType, pkg, needsActivation, importedClasses, openedNamespaces, var, registerVars, inFunction, inMethod, variables); - ret = var; - - break; - default: - GraphTargetItem excmd = expressionCommands(s, registerVars, inFunction, inMethod, -1, variables); - if (excmd != null) { - //? - ret = excmd; - break; - } - lexer.pushback(s); - } - /*if (allowRemainder && existsRemainder) { - GraphTargetItem rem = ret; - do { - rem = expressionRemainder(thisType, pkg, needsActivation, openedNamespaces, rem, registerVars, inFunction, inMethod, assocRight, variables, importedClasses); - if (rem != null) { - ret = rem; - } - } while ((!assocRight) && (rem != null)); - ret = fixPrecedence(ret); - }*/ - if (debugMode) { - System.out.println("/primary"); - } - return ret; - } - - private ActionScriptLexer lexer = null; - - private List constantPool; - - private PackageAVM2Item parsePackage(List openedNamespaces) throws IOException, AVM2ParseException, CompilationException { - List items = new ArrayList<>(); - expectedType(SymbolType.PACKAGE); - String name = ""; - ParsedSymbol s = lex(); - if (s.type != SymbolType.CURLY_OPEN) { - expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); - name = s.value.toString(); - s = lex(); - } - while (s.type != SymbolType.CURLY_OPEN) { - expected(s, lexer.yyline(), SymbolType.DOT); - s = lex(); - expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); - name += "." + s.value.toString(); - s = lex(); - } - - List importedClasses = new ArrayList<>(); - - s = lex(); - while (s.type == SymbolType.IMPORT) { - String impPackage = ""; - String impName = null; - boolean all = false; - s = lex(); - expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); - impName = s.value.toString(); - s = lex(); - while (s.type == SymbolType.DOT) { - if (!"".equals(impPackage)) { - impPackage += "."; - } - impPackage += impName; - - s = lex(); - if (s.type == SymbolType.MULTIPLY) { - impName = null; - s = lex(); - break; - } - expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); - - impName = s.value.toString(); - s = lex(); - } - - if (impName == null) { - openedNamespaces.add(abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abc.constants.getStringId(impPackage, true)), 0, true)); - } else { - importedClasses.add(impPackage + "." + impName); - } - - expected(s, lexer.yyline(), SymbolType.SEMICOLON); - s = lex(); - } - lexer.pushback(s); - - int publicNs; - openedNamespaces.add(publicNs = abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abc.constants.getStringId(name, true)), 0, true)); - - //traits(false, new ArrayList(), new Reference(false), new ArrayList(), importedClasses, privateNs, 0, publicNs, packageInternalNs, 0, openedNamespaces, name, null, false, items); - //expectedType(SymbolType.CURLY_CLOSE); - return new PackageAVM2Item(publicNs, importedClasses, name, items); - } - - private List parseScript(String fileName) throws IOException, AVM2ParseException, CompilationException { - - List openedNamespaces = new ArrayList<>(); - - int scriptPrivateNs = 0; - - if (fileName.contains("/")) { - fileName = fileName.substring(fileName.lastIndexOf('/') + 1); - } - if (fileName.contains("\\")) { - fileName = fileName.substring(fileName.lastIndexOf('\\') + 1); - } - String className = fileName; - if (className.endsWith(".as")) { - className = className.substring(0, className.length() - 3); - } - openedNamespaces.add(scriptPrivateNs = abc.constants.addNamespace(new Namespace(Namespace.KIND_PRIVATE, 0))); //abc.constants.getStringId(name + ":" + className, true) - - int publicNs; - openedNamespaces.add(publicNs = abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abc.constants.getStringId("", true)), 0, true)); - - List items = new ArrayList<>(); - traits(fileName, true, new ArrayList(), new Reference<>(false), new ArrayList(), new ArrayList(), scriptPrivateNs, 0, publicNs, 0, 0, openedNamespaces, null, null, false, items); - return items; - } - - public List scriptTraitsFromString(String str, String fileName) throws AVM2ParseException, IOException, CompilationException { - lexer = new ActionScriptLexer(str); - - List ret = parseScript(fileName); - if (lexer.lex().type != SymbolType.EOF) { - throw new AVM2ParseException("Parsing finisned before end of the file", lexer.yyline()); - } - return ret; - } - - public void addScriptFromTree(List items, boolean documentClass, int classPos) throws AVM2ParseException, CompilationException { - AVM2SourceGenerator gen = new AVM2SourceGenerator(abc, otherABCs); - SourceGeneratorLocalData localData = new SourceGeneratorLocalData( - new HashMap(), 0, Boolean.FALSE, 0); - localData.documentClass = documentClass; - abc.script_info.add(gen.generateScriptInfo(localData, items, classPos)); - } - - public void addScript(String s, boolean documentClass, String fileName, int classPos) throws AVM2ParseException, IOException, CompilationException { - List traits = scriptTraitsFromString(s, fileName); - addScriptFromTree(traits, documentClass, classPos); - } - - public ActionScriptParser(ABC abc, List otherABCs) { - this.abc = abc; - this.otherABCs = otherABCs; - } - - private static void initPlayer() throws IOException, InterruptedException { - if (playerABCs.isEmpty()) { - if (Configuration.getPlayerSWC() == null) { - throw new IOException("Player SWC library not found, please place it to " + Configuration.getFlashLibPath()); - } - SWC swc = new SWC(new FileInputStream(Configuration.getPlayerSWC())); - SWF swf = new SWF(swc.getSWF("library.swf"), true); - for (Tag t : swf.tags) { - if (t instanceof ABCContainerTag) { - playerABCs.add(((ABCContainerTag) t).getABC()); - } - } - } - } - - public static void compile(String src, ABC abc, List otherABCs, boolean documentClass, String fileName, int classPos) throws AVM2ParseException, IOException, InterruptedException, CompilationException { - List parABCs = new ArrayList<>(); - initPlayer(); - parABCs.addAll(playerABCs); - parABCs.addAll(otherABCs); - ActionScriptParser parser = new ActionScriptParser(abc, parABCs); - parser.addScript(src, documentClass, fileName, classPos); - } - - public static void compile(SWF swf, String src, String dst, int classPos) { - System.err.println("WARNING: AS3 compiler is not finished yet. This is only used for debuggging!"); - try { - initPlayer(); - ABC abc = new ABC(null); - ActionScriptParser parser = new ActionScriptParser(abc, playerABCs); - parser.addScript(new String(Helper.readFile(src), "UTF-8"), true, src, classPos); - try (OutputStream fos = new BufferedOutputStream(new FileOutputStream(new File(dst)))) { - abc.saveToStream(fos); - } - } catch (Exception ex) { - Logger.getLogger(ActionScriptParser.class.getName()).log(Level.SEVERE, null, ex); - } - System.exit(0); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.parser.script; + +import com.jpexs.decompiler.flash.SWC; +import com.jpexs.decompiler.flash.SWF; +import com.jpexs.decompiler.flash.SourceGeneratorLocalData; +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.model.ApplyTypeAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.BooleanAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.CoerceAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.ConstructSuperAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.DefaultXMLNamespace; +import com.jpexs.decompiler.flash.abc.avm2.model.EscapeXAttrAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.EscapeXElemAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.FloatValueAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.GetDescendantsAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.GetPropertyAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.InAVM2Item; +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.LocalRegAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.NameValuePair; +import com.jpexs.decompiler.flash.abc.avm2.model.NanAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.NewArrayAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.NewObjectAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.NullAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.PostDecrementAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.PostIncrementAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.ReturnValueAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.ReturnVoidAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.StringAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.ThrowAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.UndefinedAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.WithAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.clauses.ExceptionAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.clauses.ForEachInAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.clauses.ForInAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.clauses.TryAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.AddAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.AsTypeAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.BitAndAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.BitOrAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.BitXorAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.DeletePropertyAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.DivideAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.EqAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.GeAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.GtAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.InstanceOfAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.IsTypeAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.LShiftAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.LeAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.LtAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.ModuloAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.MultiplyAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.NegAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.NeqAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.PreDecrementAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.PreIncrementAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.RShiftAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.StrictEqAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.StrictNeqAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.SubtractAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.TypeOfAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.URShiftAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.parser.AVM2ParseException; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.Namespace; +import com.jpexs.decompiler.flash.action.swf4.ActionIf; +import com.jpexs.decompiler.flash.configuration.Configuration; +import com.jpexs.decompiler.flash.tags.ABCContainerTag; +import com.jpexs.decompiler.flash.tags.Tag; +import com.jpexs.decompiler.graph.CompilationException; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.Loop; +import com.jpexs.decompiler.graph.TypeItem; +import com.jpexs.decompiler.graph.model.AndItem; +import com.jpexs.decompiler.graph.model.BinaryOp; +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.DoWhileItem; +import com.jpexs.decompiler.graph.model.ForItem; +import com.jpexs.decompiler.graph.model.IfItem; +import com.jpexs.decompiler.graph.model.NotItem; +import com.jpexs.decompiler.graph.model.OrItem; +import com.jpexs.decompiler.graph.model.ParenthesisItem; +import com.jpexs.decompiler.graph.model.SwitchItem; +import com.jpexs.decompiler.graph.model.TernarOpItem; +import com.jpexs.decompiler.graph.model.UnboundedTypeItem; +import com.jpexs.decompiler.graph.model.WhileItem; +import com.jpexs.helpers.Helper; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Stack; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * + * @author JPEXS + */ +public class ActionScriptParser { + + private long uniqLast = 0; + + private final boolean debugMode = false; + + private static final String AS3_NAMESPACE = "http://adobe.com/AS3/2006/builtin"; + + private final ABC abc; + + private final List otherABCs; + + private static final List playerABCs = new ArrayList<>(); + + private long uniqId() { + uniqLast++; + return uniqLast; + } + + private List commands(TypeItem thisType, String pkg, Reference needsActivation, List importedClasses, List openedNamespaces, Stack loops, Map loopLabels, HashMap registerVars, boolean inFunction, boolean inMethod, int forinlevel, List variables) throws IOException, AVM2ParseException { + List ret = new ArrayList<>(); + if (debugMode) { + System.out.println("commands:"); + } + GraphTargetItem cmd = null; + while ((cmd = command(thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables)) != null) { + ret.add(cmd); + } + if (debugMode) { + System.out.println("/commands"); + } + return ret; + } + + private GraphTargetItem type(TypeItem thisType, String pkg, Reference needsActivation, List importedClasses, List openedNamespaces, List variables) throws IOException, AVM2ParseException { + ParsedSymbol s = lex(); + if (s.type == SymbolType.MULTIPLY) { + return new UnboundedTypeItem(); + } else if (s.type == SymbolType.VOID) { + return new TypeItem("void"); + } else { + lexer.pushback(s); + } + + GraphTargetItem t = name(thisType, pkg, needsActivation, true, openedNamespaces, null, false, false, variables, importedClasses); + t = applyType(thisType, pkg, needsActivation, importedClasses, openedNamespaces, t, new HashMap(), false, false, variables); + return t; + } + + private GraphTargetItem memberOrCall(TypeItem thisType, String pkg, Reference needsActivation, List importedClasses, List openedNamespaces, GraphTargetItem newcmds, HashMap registerVars, boolean inFunction, boolean inMethod, List variables) throws IOException, AVM2ParseException { + if (debugMode) { + System.out.println("memberOrCall:"); + } + ParsedSymbol s = lex(); + GraphTargetItem ret = newcmds; + while (s.isType(SymbolType.DOT, SymbolType.PARENT_OPEN, SymbolType.BRACKET_OPEN, SymbolType.TYPENAME, SymbolType.FILTER)) { + switch (s.type) { + case BRACKET_OPEN: + case DOT: + case TYPENAME: + lexer.pushback(s); + ret = member(thisType, pkg, needsActivation, importedClasses, openedNamespaces, ret, registerVars, inFunction, inMethod, variables); + break; + case FILTER: + needsActivation.setVal(true); + ret = new XMLFilterAVM2Item(ret, expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, inMethod, variables), openedNamespaces); + expectedType(SymbolType.PARENT_CLOSE); + break; + case PARENT_OPEN: + ret = new CallAVM2Item(lexer.yyline(), ret, call(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, variables)); + break; + + } + s = lex(); + } + if (s.type == SymbolType.INCREMENT) { + if (!isNameOrProp(ret)) { + throw new AVM2ParseException("Invalid assignment", lexer.yyline()); + } + ret = new PostIncrementAVM2Item(null, ret); + s = lex(); + + } else if (s.type == SymbolType.DECREMENT) { + if (!isNameOrProp(ret)) { + throw new AVM2ParseException("Invalid assignment", lexer.yyline()); + } + ret = new PostDecrementAVM2Item(null, ret); + s = lex(); + } + + lexer.pushback(s); + + if (debugMode) { + System.out.println("/memberOrCall"); + } + return ret; + } + + private GraphTargetItem applyType(TypeItem thisType, String pkg, Reference needsActivation, List importedClasses, List openedNamespaces, GraphTargetItem obj, HashMap registerVars, boolean inFunction, boolean inMethod, List variables) throws IOException, AVM2ParseException { + GraphTargetItem ret = obj; + ParsedSymbol s = lex(); + if (s.type == SymbolType.TYPENAME) { + List params = new ArrayList<>(); + do { + params.add(expressionPrimary(thisType, pkg, needsActivation, importedClasses, openedNamespaces, false, registerVars, inFunction, inMethod, false, variables) + ); + s = lex(); + } while (s.type == SymbolType.COMMA); + if (s.type == SymbolType.USHIFT_RIGHT) { + s = new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.GREATER_THAN); + lexer.pushback(s); + lexer.pushback(s); + } + if (s.type == SymbolType.SHIFT_RIGHT) { + s = new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.GREATER_THAN); + lexer.pushback(s); + } + expected(s, lexer.yyline(), SymbolType.GREATER_THAN); + ret = new ApplyTypeAVM2Item(null, ret, params); + } else { + lexer.pushback(s); + } + return ret; + } + + private GraphTargetItem member(TypeItem thisType, String pkg, Reference needsActivation, List importedClasses, List openedNamespaces, GraphTargetItem obj, HashMap registerVars, boolean inFunction, boolean inMethod, List variables) throws IOException, AVM2ParseException { + if (debugMode) { + System.out.println("member:"); + } + GraphTargetItem ret = obj; + ParsedSymbol s = lex(); + while (s.isType(SymbolType.DOT, SymbolType.BRACKET_OPEN, SymbolType.TYPENAME)) { + ParsedSymbol s2 = lex(); + boolean attr = false; + if (s.type == SymbolType.DOT) { + if (s2.type == SymbolType.ATTRIBUTE) { + attr = true; + } else { + lexer.pushback(s2); + } + + } else { + lexer.pushback(s2); + } + if (s.type == SymbolType.TYPENAME) { + lexer.pushback(s); + ret = applyType(thisType, pkg, needsActivation, importedClasses, openedNamespaces, ret, registerVars, inFunction, inMethod, variables); + s = lex(); + } else if (s.type == SymbolType.BRACKET_OPEN) { + GraphTargetItem index = expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables); + expectedType(SymbolType.BRACKET_CLOSE); + ret = new IndexAVM2Item(attr, ret, index, null, openedNamespaces); + s = lex(); + } else { + s = lex(); + expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); + String propName = s.value.toString(); + GraphTargetItem propItem = null; + s = lex(); + GraphTargetItem ns = null; + if (s.type == SymbolType.NAMESPACE_OP) { + ns = new UnresolvedAVM2Item(new ArrayList(), importedClasses, false, null, lexer.yyline(), propName, null, openedNamespaces); + variables.add((UnresolvedAVM2Item) ns); + s = lex(); + if (s.type == SymbolType.BRACKET_OPEN) { + propItem = expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables); + expectedType(SymbolType.BRACKET_CLOSE); + propName = null; + } else { + expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); + propName = s.value.toString(); + propItem = null; + } + } else { + lexer.pushback(s); + } + if (ns != null) { + ret = new NamespacedAVM2Item(ns, propName, propItem, ret, attr, openedNamespaces, null); + } else { + ret = new PropertyAVM2Item(ret, (attr ? "@" : "") + propName, abc, otherABCs, openedNamespaces, new ArrayList()); + } + s = lex(); + } + } + if (s.type.getPrecedence() == GraphTargetItem.PRECEDENCE_ASSIGMENT) { + ret = expression1(ret, s.type.getPrecedence(), thisType, pkg, needsActivation, importedClasses, openedNamespaces, inMethod, registerVars, inFunction, inMethod, false, variables); + } else { + lexer.pushback(s); + } + + if (debugMode) { + System.out.println("/member"); + } + return ret; + } + + private GraphTargetItem name(TypeItem thisType, String pkg, Reference needsActivation, boolean typeOnly, List openedNamespaces, HashMap registerVars, boolean inFunction, boolean inMethod, List variables, List importedClasses) throws IOException, AVM2ParseException { + ParsedSymbol s = lex(); + String name = ""; + if (s.type == SymbolType.ATTRIBUTE) { + name += "@"; + s = lex(); + } + expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER, SymbolType.THIS, SymbolType.SUPER, SymbolType.STRING_OP); + name += s.value.toString(); + s = lex(); + boolean attrBracket = false; + + while (s.isType(SymbolType.DOT)) { + name += s.value.toString(); //. or :: + s = lex(); + if (s.type == SymbolType.ATTRIBUTE) { + name += "@"; + s = lex(); + if (s.type == SymbolType.MULTIPLY) { + name += s.value.toString(); + } else if (s.group == SymbolGroup.IDENTIFIER) { + name += s.value.toString(); + } else { + if (s.type != SymbolType.BRACKET_OPEN) { + throw new AVM2ParseException("Attribute identifier or bracket expected", lexer.yyline()); + } + attrBracket = true; + continue; + } + } else { + expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER, SymbolType.NAMESPACE); + name += s.value.toString(); + } + s = lex(); + } + String nsname = null; + String nsprop = null; + GraphTargetItem nspropItem = null; + if (s.type == SymbolType.NAMESPACE_OP) { + if (name.contains(".")) { + nsname = name.substring(name.lastIndexOf('.') + 1); + } else { + nsname = name; + } + s = lex(); + if (s.group == SymbolGroup.IDENTIFIER) { + nsprop = s.value.toString(); + } else if (s.type == SymbolType.BRACKET_OPEN) { + nspropItem = expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables); + expectedType(SymbolType.BRACKET_CLOSE); + } + if (name.contains(".")) { + name = name.substring(0, name.lastIndexOf('.')); + } else { + name = null; + } + s = lex(); + } + + GraphTargetItem ret = null; + if (name != null) { + UnresolvedAVM2Item unr = new UnresolvedAVM2Item(new ArrayList(), importedClasses, typeOnly, null, lexer.yyline(), name, null, openedNamespaces); + //unr.setIndex(index); + variables.add(unr); + ret = unr; + } + if (nsname != null) { + boolean attr = nsname.startsWith("@"); + if (attr) { + nsname = nsname.substring(1); + } + UnresolvedAVM2Item ns = new UnresolvedAVM2Item(new ArrayList(), importedClasses, typeOnly, null, lexer.yyline(), nsname, null, openedNamespaces); + variables.add(ns); + ret = new NamespacedAVM2Item(ns, nsprop, nspropItem, ret, attr, openedNamespaces, null); + } + if (s.type == SymbolType.BRACKET_OPEN) { + lexer.pushback(s); + if (attrBracket) { + lexer.pushback(new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ATTRIBUTE, "@")); + lexer.pushback(new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.DOT, ".")); + } + ret = member(thisType, pkg, needsActivation, importedClasses, openedNamespaces, ret, registerVars, inFunction, inMethod, variables); + } else { + lexer.pushback(s); + } + return ret; + } + + private void expected(ParsedSymbol symb, int line, Object... expected) throws IOException, AVM2ParseException { + boolean found = false; + for (Object t : expected) { + if (symb.type == t) { + found = true; + } + if (symb.group == t) { + found = true; + } + } + if (!found) { + String expStr = ""; + boolean first = true; + for (Object e : expected) { + if (!first) { + expStr += " or "; + } + expStr += e; + first = false; + } + throw new AVM2ParseException("" + expStr + " expected but " + symb.type + " found", line); + } + } + + private ParsedSymbol expectedType(Object... type) throws IOException, AVM2ParseException { + ParsedSymbol symb = lex(); + expected(symb, lexer.yyline(), type); + return symb; + } + + private ParsedSymbol lex() throws IOException, AVM2ParseException { + ParsedSymbol ret = lexer.lex(); + if (debugMode) { + System.out.println(ret); + } + return ret; + } + + private List call(TypeItem thisType, String pkg, Reference needsActivation, List importedClasses, List openedNamespaces, HashMap registerVars, boolean inFunction, boolean inMethod, List variables) throws IOException, AVM2ParseException { + List ret = new ArrayList<>(); + //expected(SymbolType.PARENT_OPEN); //MUST BE HANDLED BY CALLER + ParsedSymbol s = lex(); + while (s.type != SymbolType.PARENT_CLOSE) { + if (s.type != SymbolType.COMMA) { + lexer.pushback(s); + } + ret.add(expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables)); + s = lex(); + expected(s, lexer.yyline(), SymbolType.COMMA, SymbolType.PARENT_CLOSE); + } + return ret; + } + + private MethodAVM2Item method(String pkg, boolean isInterface, String customAccess, Reference needsActivation, List importedClasses, boolean override, boolean isFinal, TypeItem thisType, List openedNamespaces, boolean isStatic, int namespace, String functionName, boolean isMethod, List variables) throws IOException, AVM2ParseException { + FunctionAVM2Item f = function(pkg, isInterface, needsActivation, importedClasses, namespace, thisType, openedNamespaces, functionName, isMethod, variables); + return new MethodAVM2Item(f.pkg, f.isInterface, customAccess, f.needsActivation, f.hasRest, f.line, override, isFinal, isStatic, f.namespace, functionName, f.paramTypes, f.paramNames, f.paramValues, f.body, f.subvariables, f.retType); + } + + private FunctionAVM2Item function(String pkg, boolean isInterface, Reference needsActivation, List importedClasses, int namespace, TypeItem thisType, List openedNamespaces, String functionName, boolean isMethod, List variables) throws IOException, AVM2ParseException { + openedNamespaces = new ArrayList<>(openedNamespaces); //local copy + int line = lexer.yyline(); + ParsedSymbol s; + expectedType(SymbolType.PARENT_OPEN); + s = lex(); + List paramNames = new ArrayList<>(); + List paramTypes = new ArrayList<>(); + List paramValues = new ArrayList<>(); + boolean hasRest = false; + while (s.type != SymbolType.PARENT_CLOSE) { + if (s.type != SymbolType.COMMA) { + lexer.pushback(s); + } + s = lex(); + if (s.type == SymbolType.REST) { + hasRest = true; + s = lex(); + } + expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); + + paramNames.add(s.value.toString()); + s = lex(); + if (!hasRest) { + if (s.type == SymbolType.COLON) { + paramTypes.add(type(thisType, pkg, needsActivation, importedClasses, openedNamespaces, variables)); + s = lex(); + } else { + paramTypes.add(new UnboundedTypeItem()); + } + if (s.type == SymbolType.ASSIGN) { + paramValues.add(expression(thisType, pkg, new Reference<>(false), importedClasses, openedNamespaces, null, isMethod, isMethod, isMethod, variables)); + s = lex(); + } else { + if (!paramValues.isEmpty()) { + throw new AVM2ParseException("Some of parameters do not have default values", lexer.yyline()); + } + } + } + + if (!s.isType(SymbolType.COMMA, SymbolType.PARENT_CLOSE)) { + expected(s, lexer.yyline(), SymbolType.COMMA, SymbolType.PARENT_CLOSE); + } + if (hasRest) { + expected(s, lexer.yyline(), SymbolType.PARENT_CLOSE); + } + } + s = lex(); + GraphTargetItem retType; + if (s.type == SymbolType.COLON) { + retType = type(thisType, pkg, needsActivation, importedClasses, openedNamespaces, variables); + } else { + retType = new UnboundedTypeItem(); + lexer.pushback(s); + } + List body = null; + List subvariables = new ArrayList<>(); + subvariables.add(new NameAVM2Item(thisType, lexer.yyline(), "this", null, true, openedNamespaces)); + for (int i = 0; i < paramNames.size() - (hasRest ? 1 : 0); i++) { + subvariables.add(new NameAVM2Item(paramTypes.get(i), lexer.yyline(), paramNames.get(i), null, true, openedNamespaces)); + } + if (hasRest) { + subvariables.add(new NameAVM2Item(TypeItem.UNBOUNDED, lexer.yyline(), paramNames.get(paramNames.size() - 1), null, true, openedNamespaces)); + } + subvariables.add(new NameAVM2Item(thisType, lexer.yyline(), "arguments", null, true, openedNamespaces)); + int parCnt = subvariables.size(); + Reference needsActivation2 = new Reference<>(false); + if (!isInterface) { + expectedType(SymbolType.CURLY_OPEN); + body = commands(thisType, pkg, needsActivation2, importedClasses, openedNamespaces, new Stack(), new HashMap(), new HashMap(), true, isMethod, 0, subvariables); + expectedType(SymbolType.CURLY_CLOSE); + } else { + expectedType(SymbolType.SEMICOLON); + } + + for (int i = 0; i < parCnt; i++) { + subvariables.remove(0); + } + return new FunctionAVM2Item(pkg, isInterface, needsActivation2.getVal(), namespace, hasRest, line, functionName, paramTypes, paramNames, paramValues, body, subvariables, retType); + } + + private GraphTargetItem traits(String scriptName, boolean scriptTraits, List sinitVariables, Reference sinitNeedsActivation, List staticInitializer, List importedClasses, int privateNs, int protectedNs, int publicNs, int packageInternalNs, int protectedStaticNs, List openedNamespaces, String pkg, String classNameStr, boolean isInterface, List traits) throws AVM2ParseException, IOException, CompilationException { + ParsedSymbol s; + GraphTargetItem constr = null; + TypeItem thisType = pkg == null && classNameStr == null ? null : new TypeItem(pkg == null || "".equals(pkg) ? classNameStr : pkg + "." + classNameStr); + List constrVariables = new ArrayList<>(); + List originalOpenedNamespaces = openedNamespaces; + int originalPrivateNs = privateNs; + boolean inPkg = pkg != null; + looptrait: + while (true) { + s = lex(); + boolean isStatic = false; + int namespace = -1; + boolean isGetter = false; + boolean isSetter = false; + boolean isOverride = false; + boolean isFinal = false; + boolean isDynamic = false; + String customAccess = null; + + if (scriptTraits && s.type == SymbolType.PACKAGE) { + if (inPkg) { + throw new AVM2ParseException("No subpackages allowed", lexer.yyline()); + } + openedNamespaces = new ArrayList<>(); + lexer.pushback(s); + PackageAVM2Item p = parsePackage(openedNamespaces); + pkg = p.packageName; + inPkg = true; + publicNs = p.publicNs; + importedClasses = p.importedClasses; + s = lex(); + } + if (inPkg || classNameStr != null) { + if (s.type == SymbolType.CURLY_OPEN) { + staticInitializer.addAll(commands(thisType, pkg, sinitNeedsActivation, importedClasses, openedNamespaces, new Stack(), new HashMap(), new HashMap(), true, false, 0, sinitVariables)); + expectedType(SymbolType.CURLY_CLOSE); + s = lex(); + } + + while (s.isType(SymbolType.STATIC, SymbolType.PUBLIC, SymbolType.PRIVATE, SymbolType.PROTECTED, SymbolType.OVERRIDE, SymbolType.FINAL, SymbolType.DYNAMIC, SymbolGroup.IDENTIFIER)) { + if (s.type == SymbolType.FINAL) { + if (isFinal) { + throw new AVM2ParseException("Only one final keyword allowed", lexer.yyline()); + } + isFinal = true; + } else if (s.type == SymbolType.DYNAMIC) { + if (isDynamic) { + throw new AVM2ParseException("Only one dynamic keyword allowed", lexer.yyline()); + } + isDynamic = true; + } else if (s.type == SymbolType.OVERRIDE) { + if (isOverride) { + throw new AVM2ParseException("Only one override keyword allowed", lexer.yyline()); + } + isOverride = true; + } else if (s.type == SymbolType.STATIC) { + if (isInterface) { + throw new AVM2ParseException("Interface cannot have static traits", lexer.yyline()); + } + if (classNameStr == null) { + throw new AVM2ParseException("No static keyword allowed here", lexer.yyline()); + } + if (isStatic) { + throw new AVM2ParseException("Only one static keyword allowed", lexer.yyline()); + } + isStatic = true; + } else if (s.type == SymbolType.NAMESPACE) { + break; + } else if (s.type == SymbolType.NATIVE) { + throw new AVM2ParseException("Cannot compile native code", lexer.yyline()); + } else if (s.group == SymbolGroup.IDENTIFIER) { + customAccess = s.value.toString(); + namespace = -2; + } else { + if (namespace != -1) { + throw new AVM2ParseException("Only one access identifier allowed", lexer.yyline()); + } + } + switch (s.type) { + case PUBLIC: + namespace = publicNs; + if (isInterface) { + throw new AVM2ParseException("Interface cannot have public, private or protected modifier", lexer.yyline()); + } + break; + case PRIVATE: + namespace = privateNs; + if (isInterface) { + throw new AVM2ParseException("Interface cannot have public, private or protected modifier", lexer.yyline()); + } + break; + case PROTECTED: + namespace = protectedNs; + if (isInterface) { + throw new AVM2ParseException("Interface cannot have public, private or protected modifier", lexer.yyline()); + } + break; + } + s = lex(); + } + } else { + namespace = privateNs; + } + if (namespace == -1) { + if (isInterface) { + namespace = abc.constants.getNamespaceId(new Namespace(Namespace.KIND_NAMESPACE, abc.constants.getStringId(pkg == null || pkg.isEmpty() ? classNameStr : pkg + ":" + classNameStr, true)), 0, true); + } else { + namespace = packageInternalNs; + } + } + if (namespace == protectedNs && isStatic) { + namespace = protectedStaticNs; + } + switch (s.type) { + /*case PACKAGE: + lexer.pushback(s); + traits.add(parsePackage(openedNamespaces)); + break;*/ + case CLASS: + List subNamespaces = new ArrayList<>(openedNamespaces); + if (classNameStr != null) { + throw new AVM2ParseException("Nested classes not supported", lexer.yyline()); + } + if (isOverride) { + throw new AVM2ParseException("Override flag not allowed for classes", lexer.yyline()); + } + + //GraphTargetItem classTypeStr = type(thisType,pkg,needsActivation, importedClasses, openedNamespaces, variables); + s = lex(); + expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); + String classTypeStr = s.value.toString(); + GraphTargetItem extendsTypeStr = null; + s = lex(); + if (s.type == SymbolType.EXTENDS) { + extendsTypeStr = type(thisType, pkg, new Reference<>(false), importedClasses, subNamespaces, new ArrayList()); + s = lex(); + } + List implementsTypeStrs = new ArrayList<>(); + if (s.type == SymbolType.IMPLEMENTS) { + do { + GraphTargetItem implementsTypeStr = type(thisType, pkg, new Reference<>(false), importedClasses, subNamespaces, new ArrayList()); + implementsTypeStrs.add(implementsTypeStr); + s = lex(); + } while (s.type == SymbolType.COMMA); + } + expected(s, lexer.yyline(), SymbolType.CURLY_OPEN); + if (customAccess != null) { + throw new AVM2ParseException("Class cannot have custom namespace", lexer.yyline()); + } + traits.add((classTraits(scriptName, publicNs, pkg, importedClasses, isDynamic, isFinal, subNamespaces, pkg, namespace, false, classTypeStr, extendsTypeStr, implementsTypeStrs, new ArrayList()))); + expectedType(SymbolType.CURLY_CLOSE); + break; + case INTERFACE: + if (classNameStr != null) { + throw new AVM2ParseException("Nested interfaces not supported", lexer.yyline()); + } + if (isOverride) { + throw new AVM2ParseException("Override flag not allowed for interfaces", lexer.yyline()); + } + if (isFinal) { + throw new AVM2ParseException("Final flag not allowed for interfaces", lexer.yyline()); + } + if (isDynamic) { + throw new AVM2ParseException("Dynamic flag not allowed for interfaces", lexer.yyline()); + } + //GraphTargetItem interfaceTypeStr = type(thisType,pkg,needsActivation, importedClasses, openedNamespaces, variables); + s = lex(); + expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); + String intTypeStr = s.value.toString(); + s = lex(); + List intExtendsTypeStrs = new ArrayList<>(); + + if (s.type == SymbolType.EXTENDS) { + do { + GraphTargetItem intExtendsTypeStr = type(thisType, pkg, new Reference<>(false), importedClasses, openedNamespaces, new ArrayList()); + intExtendsTypeStrs.add(intExtendsTypeStr); + s = lex(); + } while (s.type == SymbolType.COMMA); + } + expected(s, lexer.yyline(), SymbolType.CURLY_OPEN); + if (customAccess != null) { + throw new AVM2ParseException("Interface cannot have custom namespace", lexer.yyline()); + } + traits.add((classTraits(scriptName, publicNs, pkg, importedClasses, false, isFinal, openedNamespaces, pkg, namespace, true, intTypeStr, null, intExtendsTypeStrs, new ArrayList()))); + expectedType(SymbolType.CURLY_CLOSE); + break; + + case FUNCTION: + + if (isDynamic) { + throw new AVM2ParseException("Dynamic flag not allowed for methods", lexer.yyline()); + } + s = lex(); + if (s.type == SymbolType.GET) { + if (classNameStr == null) { + throw new AVM2ParseException("No get keyword allowed here", lexer.yyline()); + } + isGetter = true; + s = lex(); + } else if (s.type == SymbolType.SET) { + if (classNameStr == null) { + throw new AVM2ParseException("No set keyword allowed here", lexer.yyline()); + } + isSetter = true; + s = lex(); + } + + expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); + String fname = s.value.toString(); + if (classNameStr != null && fname.equals(classNameStr)) { //constructor + if (isStatic) { + throw new AVM2ParseException("Constructor cannot be static", lexer.yyline()); + } + if (isStatic) { + throw new AVM2ParseException("Constructor cannot be static", lexer.yyline()); + } + if (isOverride) { + throw new AVM2ParseException("Override flag not allowed for constructor", lexer.yyline()); + } + if (isFinal) { + throw new AVM2ParseException("Final flag not allowed for constructor", lexer.yyline()); + } + if (isInterface) { + throw new AVM2ParseException("Interface cannot have constructor", lexer.yyline()); + } + constr = (method(pkg, false, customAccess, new Reference<>(false), importedClasses, false, false, thisType, openedNamespaces, false, namespace, "", true, constrVariables)); + } else { + MethodAVM2Item ft = method(pkg, isInterface, customAccess, new Reference<>(false), importedClasses, isOverride, isFinal, thisType, openedNamespaces, isStatic, namespace, fname, true, new ArrayList()); + + if (isGetter) { + if (!ft.paramTypes.isEmpty()) { + throw new AVM2ParseException("Getter can't have any parameters", lexer.yyline()); + } + } + + if (isSetter) { + if (ft.paramTypes.size() != 1) { + throw new AVM2ParseException("Getter must have exactly one parameter", lexer.yyline()); + } + } + + if (isStatic && isInterface) { + if (isInterface) { + throw new AVM2ParseException("Interface cannot have static fields", lexer.yyline()); + } + } + GraphTargetItem t; + if (isGetter) { + GetterAVM2Item g = new GetterAVM2Item(ft.pkg, isInterface, customAccess, ft.needsActivation, ft.hasRest, ft.line, ft.isOverride(), ft.isFinal(), isStatic, ft.namespace, ft.functionName, ft.paramTypes, ft.paramNames, ft.paramValues, ft.body, ft.subvariables, ft.retType); + t = g; + } else if (isSetter) { + SetterAVM2Item st = new SetterAVM2Item(ft.pkg, isInterface, customAccess, ft.needsActivation, ft.hasRest, ft.line, ft.isOverride(), ft.isFinal(), isStatic, ft.namespace, ft.functionName, ft.paramTypes, ft.paramNames, ft.paramValues, ft.body, ft.subvariables, ft.retType); + t = st; + } else { + t = ft; + } + + traits.add(t); + } + //} + break; + case NAMESPACE: + if (isInterface) { + throw new AVM2ParseException("Interface cannot have namespace fields", lexer.yyline()); + } + s = lex(); + expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); + String nname = s.value.toString(); + String nval = ""; + s = lex(); + + if (s.type == SymbolType.ASSIGN) { + s = lex(); + expected(s, lexer.yyline(), SymbolType.STRING); + nval = s.value.toString(); + s = lex(); + } else { + nval = (pkg == null || pkg.isEmpty() ? classNameStr : pkg + ":" + classNameStr) + "/" + nname; + } + if (s.type != SymbolType.SEMICOLON) { + lexer.pushback(s); + } + + ConstAVM2Item ns = new ConstAVM2Item(pkg, customAccess, true, namespace, nname, new TypeItem("Namespace"), new StringAVM2Item(null, nval), lexer.yyline()); + traits.add(ns); + break; + case CONST: + case VAR: + boolean isConst = s.type == SymbolType.CONST; + if (isOverride) { + throw new AVM2ParseException("Override flag not allowed for " + (isConst ? "consts" : "vars"), lexer.yyline()); + } + if (isFinal) { + throw new AVM2ParseException("Final flag not allowed for " + (isConst ? "consts" : "vars"), lexer.yyline()); + } + if (isDynamic) { + throw new AVM2ParseException("Dynamic flag not allowed for " + (isConst ? "consts" : "vars"), lexer.yyline()); + } + if (isInterface) { + throw new AVM2ParseException("Interface cannot have variable/const fields", lexer.yyline()); + } + + s = lex(); + expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); + String vcname = s.value.toString(); + s = lex(); + GraphTargetItem type = null; + if (s.type == SymbolType.COLON) { + type = type(thisType, pkg, new Reference<>(false), importedClasses, openedNamespaces, new ArrayList()); + s = lex(); + } else { + type = TypeItem.UNBOUNDED; + } + + GraphTargetItem value = null; + + if (s.type == SymbolType.ASSIGN) { + value = expression(thisType, pkg, new Reference<>(false), importedClasses, openedNamespaces, new HashMap(), false, false, true, isStatic || isConst ? sinitVariables : constrVariables); + s = lex(); + } + GraphTargetItem tar; + if (isConst) { + tar = new ConstAVM2Item(pkg, customAccess, isStatic, namespace, vcname, type, value, lexer.yyline()); + } else { + tar = new SlotAVM2Item(pkg, customAccess, isStatic, namespace, vcname, type, value, lexer.yyline()); + } + traits.add(tar); + if (s.type != SymbolType.SEMICOLON) { + lexer.pushback(s); + } + break; + default: + if (s.type == SymbolType.CURLY_CLOSE && inPkg && classNameStr == null) { + inPkg = false; + pkg = null; + openedNamespaces = originalOpenedNamespaces; + privateNs = originalPrivateNs; + } else { + lexer.pushback(s); + break looptrait; + } + + } + } + return constr; + } + + private GraphTargetItem classTraits(String scriptName, int gpublicNs, String pkg, List importedClasses, boolean isDynamic, boolean isFinal, List openedNamespaces, String packageName, int namespace, boolean isInterface, String nameStr, GraphTargetItem extendsStr, List implementsStr, List variables) throws IOException, AVM2ParseException, CompilationException { + + GraphTargetItem ret = null; + + ParsedSymbol s = null; + List traits = new ArrayList<>(); + + String classNameStr = nameStr; + + openedNamespaces = new ArrayList<>(openedNamespaces); + + int publicNs = 0; + int privateNs = 0; + int packageInternalNs = 0; + if (pkg != null) { + openedNamespaces.add(packageInternalNs = abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE_INTERNAL, abc.constants.getStringId(pkg, true)), 0, true)); + } + if (pkg != null && !pkg.isEmpty()) { + openedNamespaces.add(publicNs = abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abc.constants.getStringId("", true)), 0, true)); + } else { + publicNs = gpublicNs; + } + + openedNamespaces.add(privateNs = abc.constants.addNamespace(new Namespace(Namespace.KIND_PRIVATE, 0))); //abc.constants.getStringId(fileName + "$", true) + + openedNamespaces.add(abc.constants.getNamespaceId(new Namespace(Namespace.KIND_NAMESPACE, abc.constants.getStringId(AS3_NAMESPACE, true)), 0, true)); + + //int privateNs = 0; + int protectedNs = 0; + //int publicNs = namespace; + int protectedStaticNs = 0; + + openedNamespaces.add(protectedNs = abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PROTECTED, abc.constants.getStringId(packageName == null ? (scriptName + "$0:"/*FIXME?*/ + classNameStr) : packageName.isEmpty() ? classNameStr : packageName + ":" + classNameStr, true)), 0, true)); + openedNamespaces.add(protectedStaticNs = abc.constants.getNamespaceId(new Namespace(Namespace.KIND_STATIC_PROTECTED, abc.constants.getStringId(packageName == null || packageName.isEmpty() ? classNameStr : packageName + ":" + classNameStr, true)), 0, true)); + + if (extendsStr != null) { + List indices = new ArrayList<>(); + List names = new ArrayList<>(); + List namespaces = new ArrayList<>(); + //FIXME for Private classes in script!!! + AVM2SourceGenerator.parentNamesAddNames(abc, otherABCs, AVM2SourceGenerator.resolveType(new SourceGeneratorLocalData(new HashMap(), 0, false, 0), ((TypeItem) ((UnresolvedAVM2Item) extendsStr).resolve(null, new ArrayList(), new ArrayList(), abc, otherABCs, new ArrayList(), new ArrayList())), abc, otherABCs), indices, names, namespaces); + for (int i = 0; i < names.size(); i++) { + if (namespaces.get(i).isEmpty()) { + continue; + } + openedNamespaces.add(abc.constants.getNamespaceId(new Namespace(Namespace.KIND_STATIC_PROTECTED, abc.constants.getStringId(namespaces.get(i) + ":" + names.get(i), true)), 0, true)); + } + } + + Reference staticNeedsActivation = new Reference<>(false); + List staticInit = new ArrayList<>(); + List sinitVariables = new ArrayList<>(); + GraphTargetItem constr = traits(scriptName, false, sinitVariables, staticNeedsActivation, staticInit, importedClasses, privateNs, protectedNs, publicNs, packageInternalNs, protectedStaticNs, openedNamespaces, packageName, classNameStr, isInterface, traits); + + if (isInterface) { + return new InterfaceAVM2Item(importedClasses, packageName, openedNamespaces, isFinal, namespace, classNameStr, implementsStr, traits); + } else { + return new ClassAVM2Item(importedClasses, packageName, openedNamespaces, protectedNs, isDynamic, isFinal, namespace, classNameStr, extendsStr, implementsStr, staticInit, staticNeedsActivation.getVal(), sinitVariables, constr, traits); + } + } + + private GraphTargetItem expressionCommands(ParsedSymbol s, HashMap registerVars, boolean inFunction, boolean inMethod, int forinlevel, List variables) throws IOException, AVM2ParseException { + GraphTargetItem ret = null; + switch (s.type) { + /*case INT: + expectedType(SymbolType.PARENT_OPEN); + ret = new ToIntegerAVM2Item(null, expression(thisType,pkg,needsActivation, importedClasses, openedNamespaces,openedNamespacesKinds,registerVars, inFunction, inMethod, true, variables)); + expectedType(SymbolType.PARENT_CLOSE); + break; + case NUMBER_OP: + s = lex(); + if (s.type == SymbolType.DOT) { + VariableAVM2Item vi = new VariableAVM2Item(s.value.toString(), null, false); + variables.add(vi); + ret = memberOrCall(thisType,vi, registerVars, inFunction, inMethod, variables); + } else { + expected(s, lexer.yyline(), SymbolType.PARENT_OPEN); + ret = new ToNumberAVM2Item(null, expression(thisType,pkg,needsActivation, importedClasses, openedNamespaces,openedNamespacesKinds,registerVars, inFunction, inMethod, true, variables)); + expectedType(SymbolType.PARENT_CLOSE); + } + break; + case STRING_OP: + ParsedSymbol sop = s; + s = lex(); + if (s.type == SymbolType.DOT) { + lexer.pushback(s); + VariableAVM2Item vi2 = new VariableAVM2Item(sop.value.toString(), null, false); + variables.add(vi2); + ret = memberOrCall(thisType,vi2, registerVars, inFunction, inMethod, variables); + } else { + expected(s, lexer.yyline(), SymbolType.PARENT_OPEN); + ret = new ToStringAVM2Item(null, expression(thisType,pkg,needsActivation, importedClasses, openedNamespaces,openedNamespacesKinds,registerVars, inFunction, inMethod, true, variables)); + expectedType(SymbolType.PARENT_CLOSE); + ret = memberOrCall(thisType,ret, registerVars, inFunction, inMethod, variables); + } + break;*/ + default: + return null; + } + //return ret; + } + + private GraphTargetItem add(Object a) { + if (a instanceof List) { + List l = (List) a; + if (l.isEmpty()) { + return null; + } + GraphTargetItem o = add(l.get(0)); + for (int i = 1; i < l.size(); i++) { + o = add(o, l.get(i)); + } + return o; + } + if (a instanceof StringBuilder) { + if (((StringBuilder) a).length() == 0) { + return null; + } + GraphTargetItem ret = new StringAVM2Item(null, a.toString()); + ((StringBuilder) a).setLength(0); + return ret; + } + if (a instanceof String) { + return new StringAVM2Item(null, (String) a); + } + if (a instanceof GraphTargetItem) { + return (GraphTargetItem) a; + } + return null; + } + + private GraphTargetItem add(Object a, Object b) { + GraphTargetItem ta = add(a); + GraphTargetItem tb = add(b); + if (ta == null && tb == null) { + return null; + } + if (ta == null) { + return tb; + } + if (tb == null) { + return ta; + } + return new AddAVM2Item(null, ta, tb); + } + + private void addS(List rets, StringBuilder sb) { + if (sb.length() > 0) { + if (!rets.isEmpty() && (rets.get(rets.size() - 1) instanceof StringAVM2Item)) { + ((StringAVM2Item) rets.get(rets.size() - 1)).value += sb.toString(); + } else { + rets.add(new StringAVM2Item(null, sb.toString())); + } + sb.setLength(0); + } + } + + private List xmltag(TypeItem thisType, String pkg, Reference usesVars, List openedTags, Reference closedVarTags, Reference needsActivation, List importedClasses, List openedNamespaces, HashMap registerVars, boolean inFunction, boolean inMethod, List variables) throws IOException, AVM2ParseException { + ParsedSymbol s = null; + List rets = new ArrayList<>(); + //GraphTargetItem ret = null; + StringBuilder sb = new StringBuilder(); + loop: + do { + s = lex(); + List sub = new ArrayList<>(); + Reference subclose = new Reference<>(0); + Reference subusesvars = new Reference<>(false); + switch (s.type) { + case XML_ATTRNAMEVAR_BEGIN: //add + usesVars.setVal(true); + addS(rets, sb); + rets.add(expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables)); + expectedType(SymbolType.CURLY_CLOSE); + expectedType(SymbolType.ASSIGN); + sb.append("="); + lexer.yybegin(ActionScriptLexer.XMLOPENTAGATTRIB); + break; + case XML_ATTRVALVAR_BEGIN: //esc_xattr + usesVars.setVal(true); + sb.append("\""); + addS(rets, sb); + rets.add(new EscapeXAttrAVM2Item(null, expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables))); + sb.append("\""); + expectedType(SymbolType.CURLY_CLOSE); + lexer.yybegin(ActionScriptLexer.XMLOPENTAG); + break; + case XML_INSTRATTRNAMEVAR_BEGIN: //add + usesVars.setVal(true); + addS(rets, sb); + rets.add(expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables)); + expectedType(SymbolType.CURLY_CLOSE); + expectedType(SymbolType.ASSIGN); + sb.append("="); + lexer.yybegin(ActionScriptLexer.XMLOPENTAGATTRIB); + break; + case XML_INSTRATTRVALVAR_BEGIN: //esc_xattr + usesVars.setVal(true); + sb.append("\""); + addS(rets, sb); + rets.add(new EscapeXAttrAVM2Item(null, expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables))); + sb.append("\""); + expectedType(SymbolType.CURLY_CLOSE); + lexer.yybegin(ActionScriptLexer.XMLOPENTAG); + break; + case XML_VAR_BEGIN: //esc_xelem + usesVars.setVal(true); + addS(rets, sb); + rets.add(new EscapeXElemAVM2Item(null, expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables))); + expectedType(SymbolType.CURLY_CLOSE); + lexer.yybegin(ActionScriptLexer.XML); + break; + case XML_FINISHVARTAG_BEGIN: //add + usesVars.setVal(true); + closedVarTags.setVal(closedVarTags.getVal() + 1); + sb.append(""); + addS(rets, sb); + lexer.yybegin(ActionScriptLexer.XML); + break; + case XML_STARTVARTAG_BEGIN: //add + //openedTags.add("*"); + + //ret = add(ret, ); + GraphTargetItem ex = expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables); + expectedType(SymbolType.CURLY_CLOSE); + lexer.yybegin(ActionScriptLexer.XMLOPENTAG); + sub.add("*"); + sb.append("<"); + addS(rets, sb); + rets.add(ex); + rets.addAll(xmltag(thisType, pkg, subusesvars, sub, subclose, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, variables)); + closedVarTags.setVal(subclose.getVal() + subclose.getVal()); + break; + case XML_INSTRVARTAG_BEGIN: //add + usesVars.setVal(true); + addS(rets, sb); + sb.append(" st = xmltag(thisType, pkg, subusesvars, sub, closedVarTags, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, variables); + sb.append(s.value.toString()); + addS(rets, sb); + rets.addAll(st); + closedVarTags.setVal(subclose.getVal() + subclose.getVal()); + break; + /*case XML_STARTTAG_END: + sb.append(s.value.toString()); + ret = addstr(ret,sb); + break;*/ + case XML_FINISHTAG: + String tname = s.value.toString().substring(2, s.value.toString().length() - 1).trim(); + if (openedTags.contains(tname)) { + openedTags.remove(tname); + } else if (openedTags.contains("*")) { + openedTags.remove("*"); + } else { + throw new AVM2ParseException("XML : Closing unopened tag", lexer.yyline()); + } + sb.append(s.value.toString()); + break; + case XML_STARTFINISHTAG_END: + openedTags.remove(openedTags.size() - 1); //close last tag + sb.append(s.value.toString()); + break; + case EOF: + throw new AVM2ParseException("End of file before XML finish", lexer.yyline()); + default: + sb.append(s.value.toString()); + break; + } + } while (!(openedTags.isEmpty() || closedVarTags.getVal() >= openedTags.size())); + addS(rets, sb); + return rets; + } + + private GraphTargetItem xml(TypeItem thisType, String pkg, Reference needsActivation, List importedClasses, List openedNamespaces, HashMap registerVars, boolean inFunction, boolean inMethod, List variables) throws IOException, AVM2ParseException { + List openedTags = new ArrayList<>(); + int closedVarTags = 0; + + GraphTargetItem ret = add(xmltag(thisType, pkg, new Reference<>(false), openedTags, new Reference<>(closedVarTags), needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, variables)); + ret = new XMLAVM2Item(ret); + lexer.yybegin(ActionScriptLexer.YYINITIAL); + //TODO: Order of additions as in official compiler + return ret; + } + + private GraphTargetItem command(TypeItem thisType, String pkg, Reference needsActivation, List importedClasses, List openedNamespaces, Stack loops, Map loopLabels, HashMap registerVars, boolean inFunction, boolean inMethod, int forinlevel, boolean mustBeCommand, List variables) throws IOException, AVM2ParseException { + LexBufferer buf = new LexBufferer(); + lexer.addListener(buf); + GraphTargetItem ret = null; + if (debugMode) { + System.out.println("command:"); + } + ParsedSymbol s = lex(); + if (s.type == SymbolType.EOF) { + return null; + } + String loopLabel = null; + + if (s.group == SymbolGroup.IDENTIFIER) { + ParsedSymbol sc = lex(); + if (sc.type == SymbolType.COLON) { + loopLabel = s.value.toString(); + s = lex(); + } else { + lexer.pushback(sc); + } + } + + if (s.type == SymbolType.DEFAULT) { + ParsedSymbol sx = lex(); + if (sx.group != SymbolGroup.IDENTIFIER) { + lexer.pushback(sx); + } else { + if (!sx.value.equals("xml")) { + lexer.pushback(sx); + } else { + expectedType(SymbolType.NAMESPACE); + expectedType(SymbolType.ASSIGN); + GraphTargetItem ns = expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables); + ret = new DefaultXMLNamespace(null, ns); + //TODO: use dxns for attribute namespaces instead of dxnslate + } + } + } + if (ret == null) { + switch (s.type) { + case USE: + expectedType(SymbolType.NAMESPACE); + GraphTargetItem ns = type(thisType, pkg, needsActivation, importedClasses, openedNamespaces, variables); + openedNamespaces.add(abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE /*FIXME?*/, abc.constants.getStringId(ns.toString(), true)), 0, true)); + break; + case WITH: + needsActivation.setVal(true); + expectedType(SymbolType.PARENT_OPEN); + GraphTargetItem wvar = expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables);//(name(thisType,false, openedNamespaces, registerVars, inFunction, inMethod, variables)); + if (!isNameOrProp(wvar)) { + throw new AVM2ParseException("Not a property or name", lexer.yyline()); + } + expectedType(SymbolType.PARENT_CLOSE); + expectedType(SymbolType.CURLY_OPEN); + List withVars = new ArrayList<>(); + List wcmd = commands(thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, withVars); + variables.addAll(withVars); + for (AssignableAVM2Item a : withVars) { + if (a instanceof UnresolvedAVM2Item) { + UnresolvedAVM2Item ua = (UnresolvedAVM2Item) a; + ua.scopeStack.add(0, wvar); + } + } + expectedType(SymbolType.CURLY_CLOSE); + ret = new WithAVM2Item(null, wvar, wcmd); + ((WithAVM2Item) ret).subvariables = withVars; + break; + /*case DELETE: + GraphTargetItem varDel = expression(thisType,pkg,needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables);//name(thisType,false, openedNamespaces, registerVars, inFunction, inMethod, variables); + if(!isNameOrProp(varDel)){ + throw new ParseException("Not a property or name", lexer.yyline()); + } + if (varDel instanceof GetPropertyAVM2Item) { + GetPropertyAVM2Item gm = (GetPropertyAVM2Item) varDel; + ret = new DeletePropertyAVM2Item(null, gm.object, gm.propertyName); + } else if (varDel instanceof NameAVM2Item) { + variables.remove(varDel); + ret = new DeletePropertyAVM2Item(null, null, (NameAVM2Item) varDel); + } else { + throw new ParseException("Not a property", lexer.yyline()); + } + break;*/ + case FUNCTION: + s = lexer.lex(); + expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); + needsActivation.setVal(true); + ret = (function(pkg, false, needsActivation, importedClasses, 0/*?*/, thisType, openedNamespaces, s.value.toString(), false, variables)); + break; + case VAR: + s = lex(); + expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); + String varIdentifier = s.value.toString(); + s = lex(); + GraphTargetItem type; + if (s.type == SymbolType.COLON) { + type = type(thisType, pkg, needsActivation, importedClasses, openedNamespaces, variables); + s = lex(); + } else { + type = new UnboundedTypeItem(); + } + + if (s.type == SymbolType.ASSIGN) { + GraphTargetItem varval = (expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables)); + ret = new NameAVM2Item(type, lexer.yyline(), varIdentifier, varval, true, openedNamespaces); + variables.add((NameAVM2Item) ret); + } else { + ret = new NameAVM2Item(type, lexer.yyline(), varIdentifier, null, true, openedNamespaces); + variables.add((NameAVM2Item) ret); + lexer.pushback(s); + } + break; + case CURLY_OPEN: + ret = new BlockItem(null, commands(thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, variables)); + expectedType(SymbolType.CURLY_CLOSE); + break; + /*case INCREMENT: //preincrement + case DECREMENT: //predecrement + GraphTargetItem varincdec = expression(thisType,pkg,needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables);//name(thisType,false, openedNamespaces, registerVars, inFunction, inMethod, variables); + if(!isNameOrProp(varincdec)){ + throw new ParseException("Not a property or name", lexer.yyline()); + } + if (s.type == SymbolType.INCREMENT) { + ret = new PreIncrementAVM2Item(null, varincdec); + } else if (s.type == SymbolType.DECREMENT) { + ret = new PreDecrementAVM2Item(null, varincdec); + } + break;*/ + case SUPER: //constructor call + ParsedSymbol ss2 = lex(); + if (ss2.type == SymbolType.PARENT_OPEN) { + List args = call(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, variables); + ret = new ConstructSuperAVM2Item(null, new LocalRegAVM2Item(null, 0, null), args); + } else {//no costructor call, but it could be calling parent methods... => handle in expression + lexer.pushback(ss2); + lexer.pushback(s); + } + break; + case IF: + expectedType(SymbolType.PARENT_OPEN); + GraphTargetItem ifExpr = (expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables)); + expectedType(SymbolType.PARENT_CLOSE); + GraphTargetItem onTrue = command(thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables); + List onTrueList = new ArrayList<>(); + onTrueList.add(onTrue); + s = lex(); + List onFalseList = null; + if (s.type == SymbolType.ELSE) { + onFalseList = new ArrayList<>(); + onFalseList.add(command(thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables)); + } else { + lexer.pushback(s); + } + ret = new IfItem(null, ifExpr, onTrueList, onFalseList); + break; + case WHILE: + expectedType(SymbolType.PARENT_OPEN); + List whileExpr = new ArrayList<>(); + whileExpr.add(commaExpression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, variables)); + expectedType(SymbolType.PARENT_CLOSE); + List whileBody = new ArrayList<>(); + Loop wloop = new Loop(uniqId(), null, null); + if (loopLabel != null) { + loopLabels.put(wloop, loopLabel); + } + loops.push(wloop); + whileBody.add(command(thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables)); + ret = new WhileItem(null, wloop, whileExpr, whileBody); + break; + case DO: + List doBody = new ArrayList<>(); + Loop dloop = new Loop(uniqId(), null, null); + loops.push(dloop); + if (loopLabel != null) { + loopLabels.put(dloop, loopLabel); + } + doBody.add(command(thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables)); + expectedType(SymbolType.WHILE); + expectedType(SymbolType.PARENT_OPEN); + List doExpr = new ArrayList<>(); + doExpr.add(commaExpression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, variables)); + expectedType(SymbolType.PARENT_CLOSE); + ret = new DoWhileItem(null, dloop, doBody, doExpr); + break; + case FOR: + s = lex(); + boolean forin = false; + boolean each = false; + GraphTargetItem collection = null; + if (s.type == SymbolType.EACH) { + each = true; + forin = true; + s = lex(); + } + expected(s, lexer.yyline(), SymbolType.PARENT_OPEN); + GraphTargetItem firstCommand = command(thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, false, variables); + if (firstCommand instanceof NameAVM2Item) { + NameAVM2Item nai = (NameAVM2Item) firstCommand; + if (nai.isDefinition() && nai.getAssignedValue() == null) { //??? WUT + firstCommand = expression1(firstCommand, firstCommand.getPrecedence(), thisType, pkg, needsActivation, importedClasses, openedNamespaces, true, registerVars, inFunction, inMethod, true, variables); + } + } + InAVM2Item inexpr = null; + if (firstCommand instanceof InAVM2Item) { + forin = true; + inexpr = (InAVM2Item) firstCommand; + } else { + if (forin) { + throw new AVM2ParseException("In expression required", lexer.yyline()); + } + } + + Loop floop = new Loop(uniqId(), null, null); + loops.push(floop); + if (loopLabel != null) { + loopLabels.put(floop, loopLabel); + } + List forFinalCommands = new ArrayList<>(); + GraphTargetItem forExpr = null; + List forFirstCommands = new ArrayList<>(); + if (!forin) { + //GraphTargetItem firstCommand = command(thisType,pkg,needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables); + if (firstCommand != null) { //can be empty command + forFirstCommands.add(firstCommand); + } + forExpr = (expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables)); + expectedType(SymbolType.SEMICOLON); + forFinalCommands.add(command(thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables)); + } + expectedType(SymbolType.PARENT_CLOSE); + List forBody = new ArrayList<>(); + forBody.add(command(thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forin ? forinlevel + 1 : forinlevel, true, variables)); + if (forin) { + if (each) { + ret = new ForEachInAVM2Item(null, floop, inexpr, forBody); + } else { + + ret = new ForInAVM2Item(null, floop, inexpr, forBody); + } + } else { + ret = new ForItem(null, floop, forFirstCommands, forExpr, forFinalCommands, forBody); + } + break; + case SWITCH: + Loop sloop = new Loop(-uniqId(), null, null); //negative id marks switch = no continue + loops.push(sloop); + if (loopLabel != null) { + loopLabels.put(sloop, loopLabel); + } + expectedType(SymbolType.PARENT_OPEN); + GraphTargetItem switchExpr = expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables); + expectedType(SymbolType.PARENT_CLOSE); + expectedType(SymbolType.CURLY_OPEN); + s = lex(); + //ret.addAll(switchExpr); + int exprReg = 0; + for (int i = 0; i < 256; i++) { + if (!registerVars.containsValue(i)) { + registerVars.put("__switch" + uniqId(), i); + exprReg = i; + break; + } + } + List> caseIfs = new ArrayList<>(); + List> caseCmds = new ArrayList<>(); + List caseExprsAll = new ArrayList<>(); + List valueMapping = new ArrayList<>(); + int pos = 0; + while (s.type == SymbolType.CASE) { + List caseExprs = new ArrayList<>(); + while (s.type == SymbolType.CASE) { + GraphTargetItem curCaseExpr = expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables); + caseExprs.add(curCaseExpr); + expectedType(SymbolType.COLON); + s = lex(); + caseExprsAll.add(curCaseExpr); + valueMapping.add(pos); + } + pos++; + lexer.pushback(s); + List caseCmd = commands(thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, variables); + caseCmds.add(caseCmd); + s = lex(); + } + List defCmd = new ArrayList<>(); + if (s.type == SymbolType.DEFAULT) { + expectedType(SymbolType.COLON); + defCmd = commands(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, sloop, switchExpr, caseExprsAll, caseCmds, defCmd, valueMapping); + break; + case BREAK: + s = lex(); + long bloopId = 0; + if (loops.isEmpty()) { + throw new AVM2ParseException("No loop to break", lexer.yyline()); + } + if (s.group == SymbolGroup.IDENTIFIER) { + String breakLabel = s.value.toString(); + for (Loop l : loops) { + if (breakLabel.equals(loopLabels.get(l))) { + bloopId = l.id; + break; + } + } + if (bloopId == 0) { + throw new AVM2ParseException("Identifier of loop expected", lexer.yyline()); + } + } else { + lexer.pushback(s); + bloopId = loops.peek().id; + } + ret = new BreakItem(null, bloopId); + break; + case CONTINUE: + s = lex(); + long cloopId = 0; + if (loops.isEmpty()) { + throw new AVM2ParseException("No loop to continue", lexer.yyline()); + } + if (s.group == SymbolGroup.IDENTIFIER) { + String continueLabel = s.value.toString(); + for (Loop l : loops) { + if (l.id < 0) { //negative id marks switch => no continue + continue; + } + if (continueLabel.equals(loopLabels.get(l))) { + cloopId = l.id; + break; + } + } + if (cloopId == -1) { + throw new AVM2ParseException("Identifier of loop expected", lexer.yyline()); + } + } else { + lexer.pushback(s); + for (int i = loops.size() - 1; i >= 0; i--) { + if (loops.get(i).id >= 0) {//no switches + cloopId = loops.get(i).id; + break; + } + } + if (cloopId <= 0) { + throw new AVM2ParseException("No loop to continue", lexer.yyline()); + } + } + //TODO: handle switch + ret = new ContinueItem(null, cloopId); + break; + case RETURN: + GraphTargetItem retexpr = expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, true, registerVars, inFunction, inMethod, true, variables); + if (retexpr == null) { + ret = new ReturnVoidAVM2Item(null); + } else { + ret = new ReturnValueAVM2Item(null, retexpr); + } + break; + case TRY: + needsActivation.setVal(true); + List tryCommands = new ArrayList<>(); + tryCommands.add(command(thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables)); + s = lex(); + boolean found = false; + List> catchCommands = new ArrayList<>(); + List catchExceptions = new ArrayList<>(); + int varCnt = variables.size(); + List> catchesVars = new ArrayList<>(); + while (s.type == SymbolType.CATCH) { + expectedType(SymbolType.PARENT_OPEN); + s = lex(); + expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER, SymbolType.THIS, SymbolType.SUPER, SymbolType.STRING_OP); + + String enamestr = s.value.toString(); + expectedType(SymbolType.COLON); + GraphTargetItem etype = type(thisType, pkg, needsActivation, importedClasses, openedNamespaces, variables); + NameAVM2Item e = new NameAVM2Item(etype, lexer.yyline(), enamestr, new ExceptionAVM2Item(null)/*?*/, true/*?*/, openedNamespaces); + variables.add(e); + catchExceptions.add(e); + e.setSlotNumber(1); + e.setSlotScope(Integer.MAX_VALUE); //will be changed later + expectedType(SymbolType.PARENT_CLOSE); + List cc = new ArrayList<>(); + List catchVars = new ArrayList<>(); + cc.add(command(thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, catchVars)); + catchesVars.add(catchVars); + variables.addAll(catchVars); + + for (AssignableAVM2Item a : catchVars) { + if (a instanceof UnresolvedAVM2Item) { + UnresolvedAVM2Item ui = (UnresolvedAVM2Item) a; + if (ui.getVariableName().equals(e.getVariableName())) { + try { + ui.resolve(null, new ArrayList(), new ArrayList(), abc, otherABCs, new ArrayList(), variables); + } catch (CompilationException ex) { + // ignore + } + ui.setSlotNumber(e.getSlotNumber()); + ui.setSlotScope(e.getSlotScope()); + } + + } + } + + catchCommands.add(cc); + s = lex(); + found = true; + } + //TODO: + for (int i = varCnt; i < variables.size(); i++) { + AssignableAVM2Item av = variables.get(i); + if (av instanceof UnresolvedAVM2Item) { + UnresolvedAVM2Item ui = (UnresolvedAVM2Item) av; + for (NameAVM2Item e : catchExceptions) { + if (ui.getVariableName().equals(e.getVariableName())) { + try { + ui.resolve(null, new ArrayList(), new ArrayList(), abc, otherABCs, new ArrayList(), variables); + } catch (CompilationException ex) { + // ignore + } + ui.setSlotNumber(e.getSlotNumber()); + ui.setSlotScope(e.getSlotScope()); + } + } + } + } + + List finallyCommands = null; + if (s.type == SymbolType.FINALLY) { + finallyCommands = new ArrayList<>(); + finallyCommands.add(command(thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables)); + found = true; + s = lex(); + } + if (!found) { + expected(s, lexer.yyline(), SymbolType.CATCH, SymbolType.FINALLY); + } + lexer.pushback(s); + TryAVM2Item tai = new TryAVM2Item(tryCommands, null, catchCommands, finallyCommands); + tai.catchVariables = catchesVars; + tai.catchExceptions2 = catchExceptions; + ret = tai; + break; + case THROW: + ret = new ThrowAVM2Item(null, expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables)); + break; + default: + GraphTargetItem valcmd = expressionCommands(s, registerVars, inFunction, inMethod, forinlevel, variables); + if (valcmd != null) { + ret = valcmd; + break; + } + if (s.type == SymbolType.SEMICOLON) { + return null; + } + lexer.pushback(s); + ret = expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables); + if (debugMode) { + System.out.println("/command"); + } + } + } + if (debugMode) { + System.out.println("/command"); + } + lexer.removeListener(buf); + if (ret == null) { //can be popped expression + buf.pushAllBack(lexer); + ret = expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables); + } + s = lex(); + if ((s != null) && (s.type != SymbolType.SEMICOLON)) { + lexer.pushback(s); + } + + return ret; + + } + + private GraphTargetItem expression(TypeItem thisType, String pkg, Reference needsActivation, List importedClasses, List openedNamespaces, HashMap registerVars, boolean inFunction, boolean inMethod, boolean allowRemainder, List variables) throws IOException, AVM2ParseException { + return expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, false, registerVars, inFunction, inMethod, allowRemainder, variables); + } + + private GraphTargetItem fixPrecedence(GraphTargetItem expr) { + System.out.println("Fixing " + expr); + GraphTargetItem ret = expr; + + /* + fix > : + a || b > c => a || (b > c) + + a < 0 || (b > c) + 1 + + */ + if (expr instanceof BinaryOp) { + BinaryOp bo = (BinaryOp) expr; + GraphTargetItem left = bo.getLeftSide(); + GraphTargetItem right = bo.getRightSide(); + if (left.getPrecedence() > bo.getPrecedence()) { + if (left instanceof BinaryOp) { + BinaryOp leftBo = (BinaryOp) left; + bo.setLeftSide(leftBo.getRightSide()); + leftBo.setRightSide(expr); + System.out.println("fixed"); + return left; + } + } + } + return ret; + } + + /*private GraphTargetItem expressionRemainder(TypeItem thisType, String pkg, Reference needsActivation, List openedNamespaces, GraphTargetItem expr, HashMap registerVars, boolean inFunction, boolean inMethod, boolean allowRemainder, List variables, List importedClasses) throws IOException, AVM2ParseException { + GraphTargetItem ret = null; + ParsedSymbol s = lex(); + + ret = fixPrecedence(ret); + return ret; + }*/ + private boolean isNameOrProp(GraphTargetItem item) { + if (item instanceof UnresolvedAVM2Item) { + return true; //we don't know yet + } + if (item instanceof NameAVM2Item) { + return true; + } + if (item instanceof PropertyAVM2Item) { + return true; + } + if (item instanceof IndexAVM2Item) { + return true; + } + return false; + } + + private boolean isType(GraphTargetItem item) { + if (item == null) { + return false; + } + while (item instanceof GetPropertyAVM2Item) { + item = ((GetPropertyAVM2Item) item).object; + } + if (item instanceof NameAVM2Item) { + return true; + } + return false; + } + + private int brackets(TypeItem thisType, String pkg, Reference needsActivation, List importedClasses, List openedNamespaces, List ret, HashMap registerVars, boolean inFunction, boolean inMethod, List variables) throws IOException, AVM2ParseException { + ParsedSymbol s = lex(); + int arrCnt = 0; + if (s.type == SymbolType.BRACKET_OPEN) { + s = lex(); + + while (s.type != SymbolType.BRACKET_CLOSE) { + if (s.type != SymbolType.COMMA) { + lexer.pushback(s); + } + arrCnt++; + ret.add(expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables)); + s = lex(); + if (!s.isType(SymbolType.COMMA, SymbolType.BRACKET_CLOSE)) { + expected(s, lexer.yyline(), SymbolType.COMMA, SymbolType.BRACKET_CLOSE); + } + } + } else { + lexer.pushback(s); + return -1; + } + return arrCnt; + } + + private GraphTargetItem commaExpression(TypeItem thisType, String pkg, Reference needsActivation, List importedClasses, List openedNamespaces, Stack loops, Map loopLabels, HashMap registerVars, boolean inFunction, boolean inMethod, int forInLevel, List variables) throws IOException, AVM2ParseException { + GraphTargetItem cmd = null; + List expr = new ArrayList<>(); + ParsedSymbol s; + do { + cmd = command(thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forInLevel, false, variables); + if (cmd != null) { + expr.add(cmd); + } + s = lex(); + } while (s.type == SymbolType.COMMA && cmd != null); + lexer.pushback(s); + if (cmd == null) { + expr.add(expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables)); + } else { + if (!cmd.hasReturnValue()) { + throw new AVM2ParseException("Expression expected", lexer.yyline()); + } + } + return new CommaExpressionItem(null, expr); + } + + private GraphTargetItem expression(TypeItem thisType, String pkg, Reference needsActivation, List importedClasses, List openedNamespaces, boolean allowEmpty, HashMap registerVars, boolean inFunction, boolean inMethod, boolean allowRemainder, List variables) throws IOException, AVM2ParseException { + GraphTargetItem prim = expressionPrimary(thisType, pkg, needsActivation, importedClasses, openedNamespaces, allowEmpty, registerVars, inFunction, inMethod, allowRemainder, variables); + if (prim == null) { + return null; + } + return expression1(prim, GraphTargetItem.NOPRECEDENCE, thisType, pkg, needsActivation, importedClasses, openedNamespaces, allowEmpty, registerVars, inFunction, inMethod, allowRemainder, variables); + } + + /** + * Lexer can return XML opentags instead of greater. In expression, we need + * greater sign only + * + * @param symb + */ + private void xmlToGreaterFix(ParsedSymbol symb) { + if (symb.isType(SymbolType.XML_STARTVARTAG_BEGIN, SymbolType.XML_STARTTAG_BEGIN)) { + lexer.yypushbackstr(symb.value.toString().substring(1)); //parse again as GREATER_THAN + symb.type = SymbolType.GREATER_THAN; + symb.group = SymbolGroup.OPERATOR; + } + } + + private ParsedSymbol peekExprToken() throws IOException, AVM2ParseException { + ParsedSymbol lookahead = lex(); + xmlToGreaterFix(lookahead); + + lexer.pushback(lookahead); + return lookahead; + } + + private GraphTargetItem expression1(GraphTargetItem lhs, int min_precedence, TypeItem thisType, String pkg, Reference needsActivation, List importedClasses, List openedNamespaces, boolean allowEmpty, HashMap registerVars, boolean inFunction, boolean inMethod, boolean allowRemainder, List variables) throws IOException, AVM2ParseException { + if (debugMode) { + System.out.println("expression1:"); + } + ParsedSymbol lookahead = peekExprToken(); + + ParsedSymbol op; + GraphTargetItem rhs; + GraphTargetItem mhs = null; + + //Note: algorithm from http://en.wikipedia.org/wiki/Operator-precedence_parser + //with relation operators reversed as we have precedence in reverse order + while (lookahead.type.isBinary() && lookahead.type.getPrecedence() <= /* >= on wiki */ min_precedence) { + op = lookahead; + lex(); + + //Note: Handle ternar operator as Binary + //http://stackoverflow.com/questions/13681293/how-can-i-incorporate-ternary-operators-into-a-precedence-climbing-algorithm + if (op.type == SymbolType.TERNAR) { + if (debugMode) { + System.out.println("ternar-middle:"); + } + mhs = expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, allowRemainder, variables); + expectedType(SymbolType.COLON); + if (debugMode) { + System.out.println("/ternar-middle"); + } + } + + rhs = expressionPrimary(thisType, pkg, needsActivation, importedClasses, openedNamespaces, allowEmpty, registerVars, inFunction, inMethod, allowRemainder, variables); + if (rhs == null) { + lexer.pushback(op); + break; + } + + lookahead = peekExprToken(); + while ((lookahead.type.isBinary() && lookahead.type.getPrecedence() < /* > on wiki */ op.type.getPrecedence()) + || (lookahead.type.isRightAssociative() && lookahead.type.getPrecedence() == op.type.getPrecedence())) { + rhs = expression1(rhs, lookahead.type.getPrecedence(), thisType, pkg, needsActivation, importedClasses, openedNamespaces, allowEmpty, registerVars, inFunction, inMethod, allowRemainder, variables); + lookahead = peekExprToken(); + } + + switch (op.type) { + case AS: + //GraphTargetItem type = type(thisType, pkg, needsActivation, importedClasses, openedNamespaces, variables); + + lhs = new AsTypeAVM2Item(null, lhs, rhs); //??? + allowRemainder = false; + break; + + case IN: + lhs = new InAVM2Item(null, lhs, rhs); + break; + + case TERNAR: //??? + lhs = new TernarOpItem(null, lhs, mhs, rhs); + break; + case SHIFT_LEFT: + lhs = new LShiftAVM2Item(null, lhs, rhs); + break; + case SHIFT_RIGHT: + lhs = new RShiftAVM2Item(null, lhs, rhs); + break; + case USHIFT_RIGHT: + lhs = new URShiftAVM2Item(null, lhs, rhs); + break; + case BITAND: + lhs = new BitAndAVM2Item(null, lhs, rhs); + break; + case BITOR: + lhs = new BitOrAVM2Item(null, lhs, rhs); + break; + case DIVIDE: + lhs = new DivideAVM2Item(null, lhs, rhs); + break; + case MODULO: + lhs = new ModuloAVM2Item(null, lhs, rhs); + break; + case EQUALS: + lhs = new EqAVM2Item(null, lhs, rhs); + break; + case STRICT_EQUALS: + lhs = new StrictEqAVM2Item(null, lhs, rhs); + break; + case NOT_EQUAL: + lhs = new NeqAVM2Item(null, lhs, rhs); + break; + case STRICT_NOT_EQUAL: + lhs = new StrictNeqAVM2Item(null, lhs, rhs); + break; + case LOWER_THAN: + lhs = new LtAVM2Item(null, lhs, rhs); + break; + case LOWER_EQUAL: + lhs = new LeAVM2Item(null, lhs, rhs); + break; + case GREATER_THAN: + lhs = new GtAVM2Item(null, lhs, rhs); + break; + case GREATER_EQUAL: + lhs = new GeAVM2Item(null, lhs, rhs); + break; + case AND: + lhs = new AndItem(null, lhs, rhs); + break; + case OR: + lhs = new OrItem(null, lhs, rhs); + break; + case MINUS: + lhs = new SubtractAVM2Item(null, lhs, rhs); + break; + case MULTIPLY: + lhs = new MultiplyAVM2Item(null, lhs, rhs); + break; + case PLUS: + lhs = new AddAVM2Item(null, lhs, rhs); + break; + case XOR: + lhs = new BitXorAVM2Item(null, lhs, rhs); + break; + case INSTANCEOF: + lhs = new InstanceOfAVM2Item(null, lhs, rhs); + break; + case IS: + GraphTargetItem istype = rhs;//type(thisType,pkg,needsActivation, importedClasses, openedNamespaces, variables); + lhs = new IsTypeAVM2Item(null, lhs, istype); + break; + case ASSIGN: + case ASSIGN_BITAND: + case ASSIGN_BITOR: + case ASSIGN_DIVIDE: + case ASSIGN_MINUS: + case ASSIGN_MODULO: + case ASSIGN_MULTIPLY: + case ASSIGN_PLUS: + case ASSIGN_SHIFT_LEFT: + case ASSIGN_SHIFT_RIGHT: + case ASSIGN_USHIFT_RIGHT: + case ASSIGN_XOR: + GraphTargetItem assigned = rhs; + switch (op.type) { + case ASSIGN: + //assigned = assigned; + break; + case ASSIGN_BITAND: + assigned = new BitAndAVM2Item(null, lhs, assigned); + break; + case ASSIGN_BITOR: + assigned = new BitOrAVM2Item(null, lhs, assigned); + break; + case ASSIGN_DIVIDE: + assigned = new DivideAVM2Item(null, lhs, assigned); + break; + case ASSIGN_MINUS: + assigned = new SubtractAVM2Item(null, lhs, assigned); + break; + case ASSIGN_MODULO: + assigned = new ModuloAVM2Item(null, lhs, assigned); + break; + case ASSIGN_MULTIPLY: + assigned = new MultiplyAVM2Item(null, lhs, assigned); + break; + case ASSIGN_PLUS: + assigned = new AddAVM2Item(null, lhs, assigned); + break; + case ASSIGN_SHIFT_LEFT: + assigned = new LShiftAVM2Item(null, lhs, assigned); + break; + case ASSIGN_SHIFT_RIGHT: + assigned = new RShiftAVM2Item(null, lhs, assigned); + break; + case ASSIGN_USHIFT_RIGHT: + assigned = new URShiftAVM2Item(null, lhs, assigned); + break; + case ASSIGN_XOR: + assigned = new BitXorAVM2Item(null, lhs, assigned); + break; + } + + if (!(lhs instanceof AssignableAVM2Item)) { + throw new AVM2ParseException("Invalid assignment", lexer.yyline()); + } + AssignableAVM2Item as = ((AssignableAVM2Item) lhs).copy(); + if ((as instanceof UnresolvedAVM2Item) || (as instanceof NameAVM2Item)) { + variables.add(as); + } + as.setAssignedValue(assigned); + if (lhs instanceof NameAVM2Item) { + ((NameAVM2Item) lhs).setDefinition(false); + } + lhs = as; + break; + case DESCENDANTS: + expected(lookahead, lexer.yyline(), SymbolGroup.IDENTIFIER, SymbolType.MULTIPLY); + lookahead = lex(); + lhs = new GetDescendantsAVM2Item(lhs, lookahead.type == SymbolType.MULTIPLY ? null : lookahead.value.toString(), openedNamespaces); + allowRemainder = true; + break; + } + } + + switch (lookahead.type) { + case DOT: //member + case BRACKET_OPEN: //member + case PARENT_OPEN: //function call + case FILTER: + lhs = memberOrCall(thisType, pkg, needsActivation, importedClasses, openedNamespaces, lhs, registerVars, inFunction, inMethod, variables); + break; + + default: + if (lhs instanceof ParenthesisItem) { + GraphTargetItem coerced = expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, allowRemainder, variables); + if (coerced != null && isType(((ParenthesisItem) lhs).value)) { + lhs = new CoerceAVM2Item(null, ((ParenthesisItem) lhs).value, coerced); + } + } + } + + if (debugMode) { + System.out.println("/expression1"); + } + return lhs; + } + + private GraphTargetItem expressionPrimary(TypeItem thisType, String pkg, Reference needsActivation, List importedClasses, List openedNamespaces, boolean allowEmpty, HashMap registerVars, boolean inFunction, boolean inMethod, boolean allowRemainder, List variables) throws IOException, AVM2ParseException { + if (debugMode) { + System.out.println("primary:"); + } + GraphTargetItem ret = null; + ParsedSymbol s = lex(); + switch (s.type) { + case XML_STARTTAG_BEGIN: + lexer.pushback(s); + ret = xml(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, variables); + + break; + case STRING: + ret = new StringAVM2Item(null, s.value.toString()); + + break; + case NEGATE: + ret = expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, false, variables); + ret = new NegAVM2Item(null, ret); + + break; + case MINUS: + s = lex(); + if (s.isType(SymbolType.DOUBLE)) { + ret = new FloatValueAVM2Item(null, -(Double) s.value); + + } else if (s.isType(SymbolType.INTEGER)) { + ret = new IntegerValueAVM2Item(null, -(Long) s.value); + + } else { + lexer.pushback(s); + GraphTargetItem num = expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables); + if (num instanceof IntegerValueAVM2Item) { + ((IntegerValueAVM2Item) num).value = -((IntegerValueAVM2Item) num).value; + ret = num; + } else if (num instanceof FloatValueAVM2Item) { + Double d = ((FloatValueAVM2Item) num).value; + if (d.isInfinite()) { + ((FloatValueAVM2Item) num).value = Double.NEGATIVE_INFINITY; + } else { + ((FloatValueAVM2Item) num).value = -d; + } + ret = (num); + } else { + ret = (new SubtractAVM2Item(null, new IntegerValueAVM2Item(null, 0L), num)); + } + } + break; + case TYPEOF: + ret = new TypeOfAVM2Item(null, expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, false, variables)); + + break; + case TRUE: + ret = new BooleanAVM2Item(null, true); + + break; + case NULL: + ret = new NullAVM2Item(null); + + break; + case UNDEFINED: + ret = new UndefinedAVM2Item(null); + break; + case FALSE: + ret = new BooleanAVM2Item(null, false); + + break; + case CURLY_OPEN: //Object literal + s = lex(); + List nvs = new ArrayList<>(); + + while (s.type != SymbolType.CURLY_CLOSE) { + if (s.type != SymbolType.COMMA) { + lexer.pushback(s); + } + s = lex(); + expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER, SymbolType.STRING); + + GraphTargetItem n = new StringAVM2Item(null, s.value.toString()); +//expression(thisType,pkg,needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, allowRemainder, variables); + expectedType(SymbolType.COLON); + GraphTargetItem v = expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, allowRemainder, variables); + + NameValuePair nv = new NameValuePair(n, v); + nvs.add(nv); + s = lex(); + if (!s.isType(SymbolType.COMMA, SymbolType.CURLY_CLOSE)) { + expected(s, lexer.yyline(), SymbolType.COMMA, SymbolType.CURLY_CLOSE); + } + } + ret = new NewObjectAVM2Item(null, nvs); + ret = memberOrCall(thisType, pkg, needsActivation, importedClasses, openedNamespaces, ret, registerVars, inFunction, inMethod, variables); + break; + case BRACKET_OPEN: //Array literal or just brackets + lexer.pushback(s); + List inBrackets = new ArrayList<>(); + int arrCnt = brackets(thisType, pkg, needsActivation, importedClasses, openedNamespaces, inBrackets, registerVars, inFunction, inMethod, variables); + ret = new NewArrayAVM2Item(null, inBrackets); + ret = memberOrCall(thisType, pkg, needsActivation, importedClasses, openedNamespaces, ret, registerVars, inFunction, inMethod, variables); + + break; + case FUNCTION: + s = lexer.lex(); + String fname = ""; + if (s.isType(SymbolGroup.IDENTIFIER)) { + fname = s.value.toString(); + } else { + lexer.pushback(s); + } + needsActivation.setVal(true); + ret = function(pkg, false, needsActivation, importedClasses, 0/*?*/, thisType, openedNamespaces, fname, false, variables); + ret = memberOrCall(thisType, pkg, needsActivation, importedClasses, openedNamespaces, ret, registerVars, inFunction, inMethod, variables); + break; + case NAN: + ret = new NanAVM2Item(null); + + break; + case INFINITY: + ret = new FloatValueAVM2Item(null, Double.POSITIVE_INFINITY); + + break; + case INTEGER: + ret = new IntegerValueAVM2Item(null, (Long) s.value); + + break; + case DOUBLE: + ret = new FloatValueAVM2Item(null, (Double) s.value); + + break; + case DELETE: + GraphTargetItem varDel = expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables);//name(thisType,false, openedNamespaces, registerVars, inFunction, inMethod, variables); + if (!isNameOrProp(varDel)) { + throw new AVM2ParseException("Not a property or name", lexer.yyline()); + } + ret = new DeletePropertyAVM2Item(varDel, lexer.yyline()); + break; + case INCREMENT: + case DECREMENT: //preincrement + GraphTargetItem varincdec = expressionPrimary(thisType, pkg, needsActivation, importedClasses, openedNamespaces, false, registerVars, inFunction, inMethod, false/*?*/, variables);//name(thisType,false, openedNamespaces, registerVars, inFunction, inMethod, variables); + if (!isNameOrProp(varincdec)) { + throw new AVM2ParseException("Not a property or name", lexer.yyline()); + } + if (s.type == SymbolType.INCREMENT) { + ret = new PreIncrementAVM2Item(null, varincdec); + } + if (s.type == SymbolType.DECREMENT) { + ret = new PreDecrementAVM2Item(null, varincdec); + } + + break; + case NOT: + ret = new NotItem(null, expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, false, variables)); + + break; + case PARENT_OPEN: + ret = new ParenthesisItem(null, expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables)); + expectedType(SymbolType.PARENT_CLOSE); + ret = memberOrCall(thisType, pkg, needsActivation, importedClasses, openedNamespaces, ret, registerVars, inFunction, inMethod, variables); + + break; + case NEW: + s = lex(); + if (s.type == SymbolType.XML_STARTTAG_BEGIN) { + lexer.yypushbackstr(s.value.toString().substring(1), ActionScriptLexer.YYINITIAL); + s = new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.LOWER_THAN); + } + if (s.type == SymbolType.FUNCTION) { + s = lexer.lex(); + String ffname = ""; + if (s.isType(SymbolGroup.IDENTIFIER)) { + ffname = s.value.toString(); + } else { + lexer.pushback(s); + } + needsActivation.setVal(true); + ret = function(pkg, false, needsActivation, importedClasses, 0/*?*/, thisType, openedNamespaces, ffname, false, variables); + } else if (s.type == SymbolType.LOWER_THAN) { + GraphTargetItem subtype = type(thisType, pkg, needsActivation, importedClasses, openedNamespaces, variables); + expectedType(SymbolType.GREATER_THAN); + s = lex(); + expected(s, lexer.yyline(), SymbolType.BRACKET_OPEN); + lexer.pushback(s); + List params = new ArrayList<>(); + brackets(thisType, pkg, needsActivation, importedClasses, openedNamespaces, params, registerVars, inFunction, inMethod, variables); + ret = new InitVectorAVM2Item(subtype, params, openedNamespaces); + } else if (s.type == SymbolType.PARENT_OPEN) { + GraphTargetItem newvar = expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables); + newvar = applyType(thisType, pkg, needsActivation, importedClasses, openedNamespaces, newvar, registerVars, inFunction, inMethod, variables); + expectedType(SymbolType.PARENT_CLOSE); + expectedType(SymbolType.PARENT_OPEN); + ret = new ConstructSomethingAVM2Item(lexer.yyline(), openedNamespaces, newvar, call(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, variables)); + + } else { + lexer.pushback(s); + GraphTargetItem newvar = name(thisType, pkg, needsActivation, false /*?*/, openedNamespaces, registerVars, inFunction, inMethod, variables, importedClasses); + newvar = applyType(thisType, pkg, needsActivation, importedClasses, openedNamespaces, newvar, registerVars, inFunction, inMethod, variables); + expectedType(SymbolType.PARENT_OPEN); + ret = new ConstructSomethingAVM2Item(lexer.yyline(), openedNamespaces, newvar, call(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, variables)); + } + + break; + case IDENTIFIER: + case THIS: + case SUPER: + case ATTRIBUTE: + lexer.pushback(s); + GraphTargetItem var = name(thisType, pkg, needsActivation, false, openedNamespaces, registerVars, inFunction, inMethod, variables, importedClasses); + var = memberOrCall(thisType, pkg, needsActivation, importedClasses, openedNamespaces, var, registerVars, inFunction, inMethod, variables); + ret = var; + + break; + default: + GraphTargetItem excmd = expressionCommands(s, registerVars, inFunction, inMethod, -1, variables); + if (excmd != null) { + //? + ret = excmd; + break; + } + lexer.pushback(s); + } + /*if (allowRemainder && existsRemainder) { + GraphTargetItem rem = ret; + do { + rem = expressionRemainder(thisType, pkg, needsActivation, openedNamespaces, rem, registerVars, inFunction, inMethod, assocRight, variables, importedClasses); + if (rem != null) { + ret = rem; + } + } while ((!assocRight) && (rem != null)); + ret = fixPrecedence(ret); + }*/ + if (debugMode) { + System.out.println("/primary"); + } + return ret; + } + + private ActionScriptLexer lexer = null; + + private List constantPool; + + private PackageAVM2Item parsePackage(List openedNamespaces) throws IOException, AVM2ParseException, CompilationException { + List items = new ArrayList<>(); + expectedType(SymbolType.PACKAGE); + String name = ""; + ParsedSymbol s = lex(); + if (s.type != SymbolType.CURLY_OPEN) { + expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); + name = s.value.toString(); + s = lex(); + } + while (s.type != SymbolType.CURLY_OPEN) { + expected(s, lexer.yyline(), SymbolType.DOT); + s = lex(); + expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); + name += "." + s.value.toString(); + s = lex(); + } + + List importedClasses = new ArrayList<>(); + + s = lex(); + while (s.type == SymbolType.IMPORT) { + String impPackage = ""; + String impName = null; + boolean all = false; + s = lex(); + expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); + impName = s.value.toString(); + s = lex(); + while (s.type == SymbolType.DOT) { + if (!"".equals(impPackage)) { + impPackage += "."; + } + impPackage += impName; + + s = lex(); + if (s.type == SymbolType.MULTIPLY) { + impName = null; + s = lex(); + break; + } + expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); + + impName = s.value.toString(); + s = lex(); + } + + if (impName == null) { + openedNamespaces.add(abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abc.constants.getStringId(impPackage, true)), 0, true)); + } else { + importedClasses.add(impPackage + "." + impName); + } + + expected(s, lexer.yyline(), SymbolType.SEMICOLON); + s = lex(); + } + lexer.pushback(s); + + int publicNs; + openedNamespaces.add(publicNs = abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abc.constants.getStringId(name, true)), 0, true)); + + //traits(false, new ArrayList(), new Reference(false), new ArrayList(), importedClasses, privateNs, 0, publicNs, packageInternalNs, 0, openedNamespaces, name, null, false, items); + //expectedType(SymbolType.CURLY_CLOSE); + return new PackageAVM2Item(publicNs, importedClasses, name, items); + } + + private List parseScript(String fileName) throws IOException, AVM2ParseException, CompilationException { + + List openedNamespaces = new ArrayList<>(); + + int scriptPrivateNs = 0; + + if (fileName.contains("/")) { + fileName = fileName.substring(fileName.lastIndexOf('/') + 1); + } + if (fileName.contains("\\")) { + fileName = fileName.substring(fileName.lastIndexOf('\\') + 1); + } + String className = fileName; + if (className.endsWith(".as")) { + className = className.substring(0, className.length() - 3); + } + openedNamespaces.add(scriptPrivateNs = abc.constants.addNamespace(new Namespace(Namespace.KIND_PRIVATE, 0))); //abc.constants.getStringId(name + ":" + className, true) + + int publicNs; + openedNamespaces.add(publicNs = abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abc.constants.getStringId("", true)), 0, true)); + + List items = new ArrayList<>(); + traits(fileName, true, new ArrayList(), new Reference<>(false), new ArrayList(), new ArrayList(), scriptPrivateNs, 0, publicNs, 0, 0, openedNamespaces, null, null, false, items); + return items; + } + + public List scriptTraitsFromString(String str, String fileName) throws AVM2ParseException, IOException, CompilationException { + lexer = new ActionScriptLexer(str); + + List ret = parseScript(fileName); + if (lexer.lex().type != SymbolType.EOF) { + throw new AVM2ParseException("Parsing finisned before end of the file", lexer.yyline()); + } + return ret; + } + + public void addScriptFromTree(List items, boolean documentClass, int classPos) throws AVM2ParseException, CompilationException { + AVM2SourceGenerator gen = new AVM2SourceGenerator(abc, otherABCs); + SourceGeneratorLocalData localData = new SourceGeneratorLocalData( + new HashMap(), 0, Boolean.FALSE, 0); + localData.documentClass = documentClass; + abc.script_info.add(gen.generateScriptInfo(localData, items, classPos)); + } + + public void addScript(String s, boolean documentClass, String fileName, int classPos) throws AVM2ParseException, IOException, CompilationException { + List traits = scriptTraitsFromString(s, fileName); + addScriptFromTree(traits, documentClass, classPos); + } + + public ActionScriptParser(ABC abc, List otherABCs) { + this.abc = abc; + this.otherABCs = otherABCs; + } + + private static void initPlayer() throws IOException, InterruptedException { + if (playerABCs.isEmpty()) { + if (Configuration.getPlayerSWC() == null) { + throw new IOException("Player SWC library not found, please place it to " + Configuration.getFlashLibPath()); + } + SWC swc = new SWC(new FileInputStream(Configuration.getPlayerSWC())); + SWF swf = new SWF(swc.getSWF("library.swf"), true); + for (Tag t : swf.tags) { + if (t instanceof ABCContainerTag) { + playerABCs.add(((ABCContainerTag) t).getABC()); + } + } + } + } + + public static void compile(String src, ABC abc, List otherABCs, boolean documentClass, String fileName, int classPos) throws AVM2ParseException, IOException, InterruptedException, CompilationException { + List parABCs = new ArrayList<>(); + initPlayer(); + parABCs.addAll(playerABCs); + parABCs.addAll(otherABCs); + ActionScriptParser parser = new ActionScriptParser(abc, parABCs); + parser.addScript(src, documentClass, fileName, classPos); + } + + public static void compile(SWF swf, String src, String dst, int classPos) { + System.err.println("WARNING: AS3 compiler is not finished yet. This is only used for debuggging!"); + try { + initPlayer(); + ABC abc = new ABC(null); + ActionScriptParser parser = new ActionScriptParser(abc, playerABCs); + parser.addScript(new String(Helper.readFile(src), "UTF-8"), true, src, classPos); + try (OutputStream fos = new BufferedOutputStream(new FileOutputStream(new File(dst)))) { + abc.saveToStream(fos); + } + } catch (Exception ex) { + Logger.getLogger(ActionScriptParser.class.getName()).log(Level.SEVERE, null, ex); + } + System.exit(0); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ExceptionMarkAVM2Instruction.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ExceptionMarkAVM2Instruction.java index 8ca8ea88c..303cc74fc 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ExceptionMarkAVM2Instruction.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ExceptionMarkAVM2Instruction.java @@ -1,43 +1,43 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.parser.script; - -import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; - -/** - * - * @author JPEXS - */ -public class ExceptionMarkAVM2Instruction extends AVM2Instruction { - - public int markType; - - public int exceptionId; - - public ExceptionMarkAVM2Instruction(int exceptionId, int markType) { - super(0, null, null); - this.markType = markType; - this.exceptionId = exceptionId; - this.definition = new InstructionDefinition(0, "--mark", new int[0], false /*?*/); - } - - @Override - public byte[] getBytes() { - return new byte[0]; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.parser.script; + +import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; + +/** + * + * @author JPEXS + */ +public class ExceptionMarkAVM2Instruction extends AVM2Instruction { + + public int markType; + + public int exceptionId; + + public ExceptionMarkAVM2Instruction(int exceptionId, int markType) { + super(0, null, null); + this.markType = markType; + this.exceptionId = exceptionId; + this.definition = new InstructionDefinition(0, "--mark", new int[0], false /*?*/); + } + + @Override + public byte[] getBytes() { + return new byte[0]; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/NameAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/NameAVM2Item.java index 2f37ccd59..1d0d66740 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/NameAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/NameAVM2Item.java @@ -1,355 +1,355 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -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.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.DecLocalIIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.DecLocalIns; -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.GetScopeObjectIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other.SetSlotIns; -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.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.ConvertBIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.types.ConvertIIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.types.ConvertUIns; -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.avm2.model.UndefinedAVM2Item; -import com.jpexs.decompiler.flash.abc.types.NamespaceSet; -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.SourceGenerator; -import com.jpexs.decompiler.graph.TypeItem; -import com.jpexs.decompiler.graph.model.LocalData; -import com.jpexs.decompiler.graph.model.UnboundedTypeItem; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -/** - * - * @author JPEXS - */ -public class NameAVM2Item extends AssignableAVM2Item { - - private String variableName; - - private boolean definition; - - private int nsKind = -1; - - public List openedNamespaces; - - public int line; - - public GraphTargetItem type; - - private GraphTargetItem ns = null; - - private int regNumber = -1; - - public boolean unresolved = false; - - private int slotNumber = -1; - - private int slotScope = 0; - - public GraphTargetItem redirect; - - @Override - public AssignableAVM2Item copy() { - NameAVM2Item c = new NameAVM2Item(type, line, variableName, assignedValue, definition, openedNamespaces); - c.setNs(ns); - c.regNumber = regNumber; - c.unresolved = unresolved; - c.nsKind = nsKind; - return c; - } - - public void setSlotScope(int slotScope) { - this.slotScope = slotScope; - } - - public int getSlotScope() { - return slotScope; - } - - public void setNs(GraphTargetItem ns) { - this.ns = ns; - } - - public void setRegNumber(int regNumber) { - this.regNumber = regNumber; - } - - public int getSlotNumber() { - return slotNumber; - } - - public void setSlotNumber(int slotNumber) { - this.slotNumber = slotNumber; - } - - public int getRegNumber() { - return regNumber; - } - - public GraphTargetItem getNs() { - return ns; - } - - public void appendName(String name) { - this.variableName += "." + name; - } - - public void setDefinition(boolean definition) { - this.definition = definition; - } - - public void setNsKind(int nsKind) { - this.nsKind = nsKind; - } - - public int getNsKind() { - return nsKind; - } - - public String getVariableName() { - return variableName; - } - - public NameAVM2Item(GraphTargetItem type, int line, String variableName, GraphTargetItem storeValue, boolean definition, List openedNamespaces) { - super(storeValue); - this.variableName = variableName; - this.assignedValue = storeValue; - this.definition = definition; - this.line = line; - this.type = type; - this.openedNamespaces = openedNamespaces; - } - - public boolean isDefinition() { - return definition; - } - - public GraphTargetItem getStoreValue() { - return assignedValue; - } - - @Override - public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException { - return writer; - } - - private int allNsSet(ABC abc) { - int[] nssa = new int[openedNamespaces.size()]; - for (int i = 0; i < openedNamespaces.size(); i++) { - nssa[i] = openedNamespaces.get(i); - } - return abc.constants.getNamespaceSetId(new NamespaceSet(nssa), true); - } - - public static GraphTargetItem getDefaultValue(String type) { - switch (type) { - case "*": - return new UndefinedAVM2Item(null); - case "int": - return new IntegerValueAVM2Item(null, 0L); - case "Number": - return new NanAVM2Item(null); - default: - return new NullAVM2Item(null); - } - } - - public static AVM2Instruction generateCoerce(SourceGeneratorLocalData localData, SourceGenerator generator, GraphTargetItem ttype) throws CompilationException { - if (ttype instanceof UnresolvedAVM2Item) { - ttype = ((UnresolvedAVM2Item) ttype).resolved; - } - AVM2Instruction ins; - if (ttype instanceof UnboundedTypeItem) { - ins = ins(new CoerceAIns()); - } else { - switch (ttype.toString()) { - case "int": - ins = ins(new ConvertIIns()); - break; - case "*": - ins = ins(new CoerceAIns()); - break; - case "String": - ins = ins(new CoerceSIns()); - break; - case "Boolean": - ins = ins(new ConvertBIns()); - break; - case "uint": - ins = ins(new ConvertUIns()); - break; - default: - int type_index = AVM2SourceGenerator.resolveType(localData, ttype, ((AVM2SourceGenerator) generator).abc, ((AVM2SourceGenerator) generator).allABCs); - ins = ins(new CoerceIns(), type_index); - break; - } - } - return ins; - } - - private List toSource(SourceGeneratorLocalData localData, SourceGenerator generator, boolean needsReturn) throws CompilationException { - if (variableName != null && regNumber == -1 && slotNumber == -1 && ns == null) { - throw new CompilationException("No register or slot set for " + variableName, line); - } - if (definition && assignedValue == null) { - return new ArrayList<>(); - } - String name = variableName; - boolean attr = false; - if (name != null && name.startsWith("@")) { - name = name.substring(1); - attr = true; - } - AVM2SourceGenerator g = (AVM2SourceGenerator) generator; - Reference ns_temp = new Reference<>(-1); - Reference index_temp = new Reference<>(-1); - Reference ret_temp = new Reference<>(-1); - - if (assignedValue != null) { - List basicTypes = Arrays.asList("int", "Number"); - if (slotNumber > -1) { - return toSourceMerge(localData, generator, - ins(new GetScopeObjectIns(), slotScope), - assignedValue, !(("" + assignedValue.returnType()).equals("" + type) && (basicTypes.contains("" + type))) ? generateCoerce(localData, generator, type) : null, needsReturn - ? dupSetTemp(localData, generator, ret_temp) : null, generateSetLoc(regNumber), slotNumber > -1 - ? ins(new SetSlotIns(), slotNumber) - : null, - needsReturn ? getTemp(localData, generator, ret_temp) : null, - killTemp(localData, generator, Arrays.asList(ret_temp))); - } else { - - return toSourceMerge(localData, generator, assignedValue, !(("" + assignedValue.returnType()).equals("" + type) && (basicTypes.contains("" + type))) ? generateCoerce(localData, generator, type) : null, needsReturn - ? ins(new DupIns()) : null, generateSetLoc(regNumber)); - } - } else { - return toSourceMerge(localData, generator, generateGetLoc(regNumber), generateGetSlot(slotScope, slotNumber), - needsReturn ? null : ins(new PopIns())); - } - } - - @Override - public List toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException { - if (redirect != null) { - return redirect.toSource(localData, generator); - } - return toSource(localData, generator, true); - - } - - @Override - public List toSourceIgnoreReturnValue(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException { - if (redirect != null) { - return redirect.toSourceIgnoreReturnValue(localData, generator); - } - return toSource(localData, generator, false); - } - - @Override - public boolean hasReturnValue() { - if (definition) { - return false; - } - return true; - } - - @Override - public boolean needsSemicolon() { - if (definition) { - return true; - } - return false; - } - - @Override - public String toString() { - return variableName; - } - - @Override - public GraphTargetItem returnType() { - if (type == null) { - return TypeItem.UNBOUNDED; - } - return type; - } - - @Override - public List toSourceChange(SourceGeneratorLocalData localData, SourceGenerator generator, boolean post, boolean decrement, boolean needsReturn) throws CompilationException { - if (redirect != null) { - return ((AssignableAVM2Item) redirect).toSourceChange(localData, generator, post, decrement, needsReturn); - } - AVM2SourceGenerator g = (AVM2SourceGenerator) generator; - Reference ns_temp = new Reference<>(-1); - Reference name_temp = new Reference<>(-1); - Reference index_temp = new Reference<>(-1); - Reference ret_temp = new Reference<>(-1); - boolean isInteger = returnType().toString().equals("int"); - /* - - - */ - if (!needsReturn) { - if (slotNumber > -1) { - return toSourceMerge(localData, generator, - ins(new GetScopeObjectIns(), slotScope), - generateGetSlot(slotScope, slotNumber), - (decrement ? ins(isInteger ? new DecrementIIns() : new DecrementIns()) : ins(isInteger ? new IncrementIIns() : new IncrementIns())), - ins(new SetSlotIns(), slotNumber) - ); - } else { - return toSourceMerge(localData, generator, - (decrement ? ins(isInteger ? new DecLocalIIns() : new DecLocalIns(), regNumber) : ins(isInteger ? new IncLocalIIns() : new IncLocalIns(), regNumber))); - } - } - return toSourceMerge(localData, generator, - slotNumber > -1 ? ins(new GetScopeObjectIns(), slotScope) : null, - //Start get original - generateGetLoc(regNumber), generateGetSlot(slotScope, slotNumber), - //End get original - //!isInteger ? ins(new ConvertDIns()) : null, - //End get original - (!post) ? (decrement ? ins(isInteger ? new DecrementIIns() : new DecrementIns()) : ins(isInteger ? new IncrementIIns() : new IncrementIns())) : null, - needsReturn ? ins(new DupIns()) : null, - (post) ? (decrement ? ins(isInteger ? new DecrementIIns() : new DecrementIns()) : ins(isInteger ? new IncrementIIns() : new IncrementIns())) : null, - generateCoerce(localData, generator, returnType()), - generateSetLoc(regNumber), - slotNumber > -1 ? ins(new SetSlotIns(), slotNumber) : null - ); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +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.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.DecLocalIIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.DecLocalIns; +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.GetScopeObjectIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other.SetSlotIns; +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.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.ConvertBIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.types.ConvertIIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.types.ConvertUIns; +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.avm2.model.UndefinedAVM2Item; +import com.jpexs.decompiler.flash.abc.types.NamespaceSet; +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.SourceGenerator; +import com.jpexs.decompiler.graph.TypeItem; +import com.jpexs.decompiler.graph.model.LocalData; +import com.jpexs.decompiler.graph.model.UnboundedTypeItem; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * + * @author JPEXS + */ +public class NameAVM2Item extends AssignableAVM2Item { + + private String variableName; + + private boolean definition; + + private int nsKind = -1; + + public List openedNamespaces; + + public int line; + + public GraphTargetItem type; + + private GraphTargetItem ns = null; + + private int regNumber = -1; + + public boolean unresolved = false; + + private int slotNumber = -1; + + private int slotScope = 0; + + public GraphTargetItem redirect; + + @Override + public AssignableAVM2Item copy() { + NameAVM2Item c = new NameAVM2Item(type, line, variableName, assignedValue, definition, openedNamespaces); + c.setNs(ns); + c.regNumber = regNumber; + c.unresolved = unresolved; + c.nsKind = nsKind; + return c; + } + + public void setSlotScope(int slotScope) { + this.slotScope = slotScope; + } + + public int getSlotScope() { + return slotScope; + } + + public void setNs(GraphTargetItem ns) { + this.ns = ns; + } + + public void setRegNumber(int regNumber) { + this.regNumber = regNumber; + } + + public int getSlotNumber() { + return slotNumber; + } + + public void setSlotNumber(int slotNumber) { + this.slotNumber = slotNumber; + } + + public int getRegNumber() { + return regNumber; + } + + public GraphTargetItem getNs() { + return ns; + } + + public void appendName(String name) { + this.variableName += "." + name; + } + + public void setDefinition(boolean definition) { + this.definition = definition; + } + + public void setNsKind(int nsKind) { + this.nsKind = nsKind; + } + + public int getNsKind() { + return nsKind; + } + + public String getVariableName() { + return variableName; + } + + public NameAVM2Item(GraphTargetItem type, int line, String variableName, GraphTargetItem storeValue, boolean definition, List openedNamespaces) { + super(storeValue); + this.variableName = variableName; + this.assignedValue = storeValue; + this.definition = definition; + this.line = line; + this.type = type; + this.openedNamespaces = openedNamespaces; + } + + public boolean isDefinition() { + return definition; + } + + public GraphTargetItem getStoreValue() { + return assignedValue; + } + + @Override + public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException { + return writer; + } + + private int allNsSet(ABC abc) { + int[] nssa = new int[openedNamespaces.size()]; + for (int i = 0; i < openedNamespaces.size(); i++) { + nssa[i] = openedNamespaces.get(i); + } + return abc.constants.getNamespaceSetId(new NamespaceSet(nssa), true); + } + + public static GraphTargetItem getDefaultValue(String type) { + switch (type) { + case "*": + return new UndefinedAVM2Item(null); + case "int": + return new IntegerValueAVM2Item(null, 0L); + case "Number": + return new NanAVM2Item(null); + default: + return new NullAVM2Item(null); + } + } + + public static AVM2Instruction generateCoerce(SourceGeneratorLocalData localData, SourceGenerator generator, GraphTargetItem ttype) throws CompilationException { + if (ttype instanceof UnresolvedAVM2Item) { + ttype = ((UnresolvedAVM2Item) ttype).resolved; + } + AVM2Instruction ins; + if (ttype instanceof UnboundedTypeItem) { + ins = ins(new CoerceAIns()); + } else { + switch (ttype.toString()) { + case "int": + ins = ins(new ConvertIIns()); + break; + case "*": + ins = ins(new CoerceAIns()); + break; + case "String": + ins = ins(new CoerceSIns()); + break; + case "Boolean": + ins = ins(new ConvertBIns()); + break; + case "uint": + ins = ins(new ConvertUIns()); + break; + default: + int type_index = AVM2SourceGenerator.resolveType(localData, ttype, ((AVM2SourceGenerator) generator).abc, ((AVM2SourceGenerator) generator).allABCs); + ins = ins(new CoerceIns(), type_index); + break; + } + } + return ins; + } + + private List toSource(SourceGeneratorLocalData localData, SourceGenerator generator, boolean needsReturn) throws CompilationException { + if (variableName != null && regNumber == -1 && slotNumber == -1 && ns == null) { + throw new CompilationException("No register or slot set for " + variableName, line); + } + if (definition && assignedValue == null) { + return new ArrayList<>(); + } + String name = variableName; + boolean attr = false; + if (name != null && name.startsWith("@")) { + name = name.substring(1); + attr = true; + } + AVM2SourceGenerator g = (AVM2SourceGenerator) generator; + Reference ns_temp = new Reference<>(-1); + Reference index_temp = new Reference<>(-1); + Reference ret_temp = new Reference<>(-1); + + if (assignedValue != null) { + List basicTypes = Arrays.asList("int", "Number"); + if (slotNumber > -1) { + return toSourceMerge(localData, generator, + ins(new GetScopeObjectIns(), slotScope), + assignedValue, !(("" + assignedValue.returnType()).equals("" + type) && (basicTypes.contains("" + type))) ? generateCoerce(localData, generator, type) : null, needsReturn + ? dupSetTemp(localData, generator, ret_temp) : null, generateSetLoc(regNumber), slotNumber > -1 + ? ins(new SetSlotIns(), slotNumber) + : null, + needsReturn ? getTemp(localData, generator, ret_temp) : null, + killTemp(localData, generator, Arrays.asList(ret_temp))); + } else { + + return toSourceMerge(localData, generator, assignedValue, !(("" + assignedValue.returnType()).equals("" + type) && (basicTypes.contains("" + type))) ? generateCoerce(localData, generator, type) : null, needsReturn + ? ins(new DupIns()) : null, generateSetLoc(regNumber)); + } + } else { + return toSourceMerge(localData, generator, generateGetLoc(regNumber), generateGetSlot(slotScope, slotNumber), + needsReturn ? null : ins(new PopIns())); + } + } + + @Override + public List toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException { + if (redirect != null) { + return redirect.toSource(localData, generator); + } + return toSource(localData, generator, true); + + } + + @Override + public List toSourceIgnoreReturnValue(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException { + if (redirect != null) { + return redirect.toSourceIgnoreReturnValue(localData, generator); + } + return toSource(localData, generator, false); + } + + @Override + public boolean hasReturnValue() { + if (definition) { + return false; + } + return true; + } + + @Override + public boolean needsSemicolon() { + if (definition) { + return true; + } + return false; + } + + @Override + public String toString() { + return variableName; + } + + @Override + public GraphTargetItem returnType() { + if (type == null) { + return TypeItem.UNBOUNDED; + } + return type; + } + + @Override + public List toSourceChange(SourceGeneratorLocalData localData, SourceGenerator generator, boolean post, boolean decrement, boolean needsReturn) throws CompilationException { + if (redirect != null) { + return ((AssignableAVM2Item) redirect).toSourceChange(localData, generator, post, decrement, needsReturn); + } + AVM2SourceGenerator g = (AVM2SourceGenerator) generator; + Reference ns_temp = new Reference<>(-1); + Reference name_temp = new Reference<>(-1); + Reference index_temp = new Reference<>(-1); + Reference ret_temp = new Reference<>(-1); + boolean isInteger = returnType().toString().equals("int"); + /* + + + */ + if (!needsReturn) { + if (slotNumber > -1) { + return toSourceMerge(localData, generator, + ins(new GetScopeObjectIns(), slotScope), + generateGetSlot(slotScope, slotNumber), + (decrement ? ins(isInteger ? new DecrementIIns() : new DecrementIns()) : ins(isInteger ? new IncrementIIns() : new IncrementIns())), + ins(new SetSlotIns(), slotNumber) + ); + } else { + return toSourceMerge(localData, generator, + (decrement ? ins(isInteger ? new DecLocalIIns() : new DecLocalIns(), regNumber) : ins(isInteger ? new IncLocalIIns() : new IncLocalIns(), regNumber))); + } + } + return toSourceMerge(localData, generator, + slotNumber > -1 ? ins(new GetScopeObjectIns(), slotScope) : null, + //Start get original + generateGetLoc(regNumber), generateGetSlot(slotScope, slotNumber), + //End get original + //!isInteger ? ins(new ConvertDIns()) : null, + //End get original + (!post) ? (decrement ? ins(isInteger ? new DecrementIIns() : new DecrementIns()) : ins(isInteger ? new IncrementIIns() : new IncrementIns())) : null, + needsReturn ? ins(new DupIns()) : null, + (post) ? (decrement ? ins(isInteger ? new DecrementIIns() : new DecrementIns()) : ins(isInteger ? new IncrementIIns() : new IncrementIns())) : null, + generateCoerce(localData, generator, returnType()), + generateSetLoc(regNumber), + slotNumber > -1 ? ins(new SetSlotIns(), slotNumber) : null + ); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/SymbolType.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/SymbolType.java index 6e7b0a173..4b06b8220 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/SymbolType.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/SymbolType.java @@ -1,242 +1,242 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.avm2.parser.script; - -import com.jpexs.decompiler.graph.GraphTargetItem; - -/** - * - * @author JPEXS - */ -public enum SymbolType { - //Keywords - - BREAK, - CASE, - CONTINUE, - DEFAULT, - DO, - WHILE, - ELSE, - FOR, - EACH, - IN(GraphTargetItem.PRECEDENCE_RELATIONAL, true), - IF, - RETURN, - SUPER(GraphTargetItem.PRECEDENCE_PRIMARY, false), - SWITCH, - THROW, - TRY, - CATCH, - FINALLY, - WITH, - DYNAMIC, - INTERNAL, - OVERRIDE, - PRIVATE, - PROTECTED, - PUBLIC, - STATIC, - CLASS, - CONST, - EXTENDS, - FUNCTION(GraphTargetItem.PRECEDENCE_PRIMARY, false), - GET, - IMPLEMENTS, - INTERFACE, - NAMESPACE, - PACKAGE, - SET, - VAR, - IMPORT, - USE, - FALSE(GraphTargetItem.PRECEDENCE_PRIMARY, false), - NULL(GraphTargetItem.PRECEDENCE_PRIMARY, false), - THIS(GraphTargetItem.PRECEDENCE_PRIMARY, false), - TRUE(GraphTargetItem.PRECEDENCE_PRIMARY, false), - //Operators - PARENT_OPEN(GraphTargetItem.PRECEDENCE_PRIMARY, false), - PARENT_CLOSE(GraphTargetItem.PRECEDENCE_PRIMARY, false), - CURLY_OPEN(GraphTargetItem.PRECEDENCE_PRIMARY, false), - CURLY_CLOSE(GraphTargetItem.PRECEDENCE_PRIMARY, false), - BRACKET_OPEN(GraphTargetItem.PRECEDENCE_PRIMARY, false), - BRACKET_CLOSE(GraphTargetItem.PRECEDENCE_PRIMARY, false), - SEMICOLON, - COMMA(GraphTargetItem.PRECEDENCE_COMMA, false), - REST, - DOT(GraphTargetItem.PRECEDENCE_PRIMARY, false), - ASSIGN(GraphTargetItem.PRECEDENCE_ASSIGMENT, true, true), - GREATER_THAN(GraphTargetItem.PRECEDENCE_RELATIONAL, true), - LOWER_THAN(GraphTargetItem.PRECEDENCE_RELATIONAL, true), - NOT(GraphTargetItem.PRECEDENCE_UNARY, false), - NEGATE(GraphTargetItem.PRECEDENCE_UNARY, false), - TERNAR(GraphTargetItem.PRECEDENCE_CONDITIONAL, true, true), /*!! ternar !!!*/ - COLON(GraphTargetItem.PRECEDENCE_CONDITIONAL, false),/*!! ternar !!!*/ - EQUALS(GraphTargetItem.PRECEDENCE_EQUALITY, true), - STRICT_EQUALS(GraphTargetItem.PRECEDENCE_EQUALITY, true), - LOWER_EQUAL(GraphTargetItem.PRECEDENCE_RELATIONAL, true), - GREATER_EQUAL(GraphTargetItem.PRECEDENCE_RELATIONAL, true), - NOT_EQUAL(GraphTargetItem.PRECEDENCE_EQUALITY, true), - STRICT_NOT_EQUAL(GraphTargetItem.PRECEDENCE_EQUALITY, true), - AND(GraphTargetItem.PRECEDENCE_LOGICALAND, true), - OR(GraphTargetItem.PRECEDENCE_LOGICALOR, true), - INCREMENT(GraphTargetItem.PRECEDENCE_POSTFIX, false),//OR Unary - DECREMENT(GraphTargetItem.PRECEDENCE_POSTFIX, false), //OR Unary - PLUS(GraphTargetItem.PRECEDENCE_ADDITIVE, true), - MINUS(GraphTargetItem.PRECEDENCE_ADDITIVE, true), //OR Unary - MULTIPLY(GraphTargetItem.PRECEDENCE_MULTIPLICATIVE, true), - DIVIDE(GraphTargetItem.PRECEDENCE_MULTIPLICATIVE, true), - BITAND(GraphTargetItem.PRECEDENCE_BITWISEAND, true), - BITOR(GraphTargetItem.PRECEDENCE_BITWISEOR, true), - XOR(GraphTargetItem.PRECEDENCE_BITWISEXOR, true), - MODULO(GraphTargetItem.PRECEDENCE_BITWISESHIFT, true), - SHIFT_LEFT(GraphTargetItem.PRECEDENCE_BITWISESHIFT, true), - SHIFT_RIGHT(GraphTargetItem.PRECEDENCE_BITWISESHIFT, true), - USHIFT_RIGHT(GraphTargetItem.PRECEDENCE_BITWISESHIFT, true), - ASSIGN_PLUS(GraphTargetItem.PRECEDENCE_ASSIGMENT, true, true), - ASSIGN_MINUS(GraphTargetItem.PRECEDENCE_ASSIGMENT, true, true), - ASSIGN_MULTIPLY(GraphTargetItem.PRECEDENCE_ASSIGMENT, true, true), - ASSIGN_DIVIDE(GraphTargetItem.PRECEDENCE_ASSIGMENT, true, true), - ASSIGN_BITAND(GraphTargetItem.PRECEDENCE_ASSIGMENT, true, true), - ASSIGN_BITOR(GraphTargetItem.PRECEDENCE_ASSIGMENT, true, true), - ASSIGN_XOR(GraphTargetItem.PRECEDENCE_ASSIGMENT, true, true), - ASSIGN_MODULO(GraphTargetItem.PRECEDENCE_ASSIGMENT, true, true), - ASSIGN_SHIFT_LEFT(GraphTargetItem.PRECEDENCE_ASSIGMENT, true, true), - ASSIGN_SHIFT_RIGHT(GraphTargetItem.PRECEDENCE_ASSIGMENT, true, true), - ASSIGN_USHIFT_RIGHT(GraphTargetItem.PRECEDENCE_ASSIGMENT, true, true), - AS(GraphTargetItem.PRECEDENCE_RELATIONAL, true), - DELETE(GraphTargetItem.PRECEDENCE_UNARY, false), - INSTANCEOF(GraphTargetItem.PRECEDENCE_RELATIONAL, true), - IS(GraphTargetItem.PRECEDENCE_RELATIONAL, true), - NAMESPACE_OP(GraphTargetItem.PRECEDENCE_PRIMARY, false), - NEW(GraphTargetItem.PRECEDENCE_PRIMARY, false), - TYPEOF(GraphTargetItem.PRECEDENCE_UNARY, false), - VOID, - ATTRIBUTE, - //Other - STRING(GraphTargetItem.PRECEDENCE_PRIMARY, false), - COMMENT, - //XML, - IDENTIFIER(GraphTargetItem.PRECEDENCE_PRIMARY, false), - INTEGER(GraphTargetItem.PRECEDENCE_PRIMARY, false), - DOUBLE(GraphTargetItem.PRECEDENCE_PRIMARY, false), - TYPENAME(GraphTargetItem.PRECEDENCE_PRIMARY, false), - EOF, - //TRACE, - //GETURL, - //GOTOANDSTOP, - //NEXTFRAME, - //PLAY, - //PREVFRAME, - //TELLTARGET, - //STOP, - //STOPALLSOUNDS, - //TOGGLEHIGHQUALITY, - //ORD, - //CHR, - //DUPLICATEMOVIECLIP, - //STOPDRAG, - //GETTIMER, - //LOADVARIABLES, - //LOADMOVIE, - //GOTOANDPLAY, - //MBORD, - //MBCHR, - //MBLENGTH, - //MBSUBSTRING, - //RANDOM, - //REMOVEMOVIECLIP, - //STARTDRAG, - //SUBSTR, - //LENGTH, //string.length - INT(GraphTargetItem.PRECEDENCE_PRIMARY, false), - //TARGETPATH, - NUMBER_OP(GraphTargetItem.PRECEDENCE_PRIMARY, false), - STRING_OP(GraphTargetItem.PRECEDENCE_PRIMARY, false), - //IFFRAMELOADED, - INFINITY(GraphTargetItem.PRECEDENCE_PRIMARY, false), - //EVAL, - UNDEFINED(GraphTargetItem.PRECEDENCE_PRIMARY, false), - //NEWLINE, - NAN(GraphTargetItem.PRECEDENCE_PRIMARY, false), - //GETVERSION, - //CALL, - //LOADMOVIENUM, - //LOADVARIABLESNUM, - //PRINT, - //PRINTNUM, - //PRINTASBITMAP, - //PRINTASBITMAPNUM, - //UNLOADMOVIE, - //UNLOADMOVIENUM, - FINAL, - XML_STARTTAG_BEGIN(GraphTargetItem.PRECEDENCE_PRIMARY, false), // - XML_FINISHVARTAG_BEGIN(GraphTargetItem.PRECEDENCE_PRIMARY, false), // - XML_STARTFINISHTAG_END(GraphTargetItem.PRECEDENCE_PRIMARY, false), // /> - XML_COMMENT(GraphTargetItem.PRECEDENCE_PRIMARY, false), // - XML_CDATA(GraphTargetItem.PRECEDENCE_PRIMARY, false), // - XML_INSTR_BEGIN(GraphTargetItem.PRECEDENCE_PRIMARY, false), // - XML_VAR_BEGIN(GraphTargetItem.PRECEDENCE_PRIMARY, false), // { - XML_ATTRIBUTENAME(GraphTargetItem.PRECEDENCE_PRIMARY, false), // aaa= - XML_ATTRIBUTEVALUE(GraphTargetItem.PRECEDENCE_PRIMARY, false), // "vvv" - XML_TEXT(GraphTargetItem.PRECEDENCE_PRIMARY, false), - XML_ATTRNAMEVAR_BEGIN(GraphTargetItem.PRECEDENCE_PRIMARY, false), // {...}= - XML_ATTRVALVAR_BEGIN(GraphTargetItem.PRECEDENCE_PRIMARY, false), // aaa={ - XML_INSTRATTRNAMEVAR_BEGIN(GraphTargetItem.PRECEDENCE_PRIMARY, false), // {...}= - XML_INSTRATTRVALVAR_BEGIN(GraphTargetItem.PRECEDENCE_PRIMARY, false), // aaa={ - XML_INSTRVARTAG_BEGIN(GraphTargetItem.PRECEDENCE_PRIMARY, false), // + XML_FINISHVARTAG_BEGIN(GraphTargetItem.PRECEDENCE_PRIMARY, false), // + XML_STARTFINISHTAG_END(GraphTargetItem.PRECEDENCE_PRIMARY, false), // /> + XML_COMMENT(GraphTargetItem.PRECEDENCE_PRIMARY, false), // + XML_CDATA(GraphTargetItem.PRECEDENCE_PRIMARY, false), // + XML_INSTR_BEGIN(GraphTargetItem.PRECEDENCE_PRIMARY, false), // + XML_VAR_BEGIN(GraphTargetItem.PRECEDENCE_PRIMARY, false), // { + XML_ATTRIBUTENAME(GraphTargetItem.PRECEDENCE_PRIMARY, false), // aaa= + XML_ATTRIBUTEVALUE(GraphTargetItem.PRECEDENCE_PRIMARY, false), // "vvv" + XML_TEXT(GraphTargetItem.PRECEDENCE_PRIMARY, false), + XML_ATTRNAMEVAR_BEGIN(GraphTargetItem.PRECEDENCE_PRIMARY, false), // {...}= + XML_ATTRVALVAR_BEGIN(GraphTargetItem.PRECEDENCE_PRIMARY, false), // aaa={ + XML_INSTRATTRNAMEVAR_BEGIN(GraphTargetItem.PRECEDENCE_PRIMARY, false), // {...}= + XML_INSTRATTRVALVAR_BEGIN(GraphTargetItem.PRECEDENCE_PRIMARY, false), // aaa={ + XML_INSTRVARTAG_BEGIN(GraphTargetItem.PRECEDENCE_PRIMARY, false), // fullyQualifiedNames) { - return "method_index=" + cinit_index + "\r\n" + static_traits.toString(abc, fullyQualifiedNames); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.types; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.types.traits.Traits; +import com.jpexs.decompiler.flash.types.annotations.Internal; +import java.util.List; + +public class ClassInfo { + + public int cinit_index; //MethodInfo - static initializer + + public Traits static_traits; + + @Internal + public boolean deleted; + + public ClassInfo() { + static_traits = new Traits(); + } + + public ClassInfo(Traits traits) { + static_traits = traits; + } + + @Override + public String toString() { + return "method_index=" + cinit_index + "\r\n" + static_traits.toString(); + } + + public String toString(ABC abc, List fullyQualifiedNames) { + return "method_index=" + cinit_index + "\r\n" + static_traits.toString(abc, fullyQualifiedNames); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/InstanceInfo.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/InstanceInfo.java index b34f44f09..aa4c969ce 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/InstanceInfo.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/InstanceInfo.java @@ -1,140 +1,140 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.types; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.types.traits.Traits; -import com.jpexs.decompiler.flash.helpers.GraphTextWriter; -import com.jpexs.decompiler.flash.helpers.hilight.HighlightSpecialType; -import com.jpexs.decompiler.flash.types.annotations.Internal; -import com.jpexs.helpers.Helper; -import java.util.ArrayList; -import java.util.List; - -public class InstanceInfo { - - public int name_index; - - public int super_index; - - public int flags; // 1 = sealed, 0 = dynamic, 2 = final, 4 = interface, 8 = ProtectedNs - - public int protectedNS; //if flags & 8 - - public int[] interfaces; - - public int iinit_index; // MethodInfo - constructor - - public Traits instance_traits; - - public static final int CLASS_SEALED = 1; //not dynamic - - public static final int CLASS_FINAL = 2; - - public static final int CLASS_INTERFACE = 4; - - public static final int CLASS_PROTECTEDNS = 8; - - @Internal - public boolean deleted; - - public InstanceInfo() { - instance_traits = new Traits(); - } - - public InstanceInfo(Traits traits) { - instance_traits = traits; - } - - @Override - public String toString() { - return "name_index=" + name_index + " super_index=" + super_index + " flags=" + flags + " protectedNS=" + protectedNS + " interfaces=" + Helper.intArrToString(interfaces) + " method_index=" + iinit_index + "\r\n" + instance_traits.toString(); - } - - public String toString(ABC abc, List fullyQualifiedNames) { - String supIndexStr = "[nothing]"; - if (super_index > 0) { - supIndexStr = abc.constants.getMultiname(super_index).toString(abc.constants, fullyQualifiedNames); - } - return "name_index=" + abc.constants.getMultiname(name_index).toString(abc.constants, fullyQualifiedNames) + " super_index=" + supIndexStr + " flags=" + flags + " protectedNS=" + protectedNS + " interfaces=" + Helper.intArrToString(interfaces) + " method_index=" + iinit_index + "\r\n" + instance_traits.toString(abc, fullyQualifiedNames); - } - - public GraphTextWriter getClassHeaderStr(GraphTextWriter writer, ABC abc, List fullyQualifiedNames, boolean allowPrivate) { - String modifiers; - Namespace ns = abc.constants.getMultiname(name_index).getNamespace(abc.constants); - modifiers = ns.getPrefix(abc); - if (!allowPrivate && modifiers.equals("private")) { - modifiers = ""; - } - if (!modifiers.isEmpty()) { - modifiers += " "; - } - - if (isFinal()) { - modifiers += "final "; - } - if (!isInterface() && isDynamic()) { - modifiers += "dynamic "; - } - String objType = "class "; - if (isInterface()) { - objType = "interface "; - } - - writer.appendNoHilight(modifiers + objType); - writer.hilightSpecial(abc.constants.getMultiname(name_index).getName(abc.constants, new ArrayList()/* No full names here*/, false), HighlightSpecialType.CLASS_NAME); - - if (super_index > 0) { - String typeName = abc.constants.getMultiname(super_index).getNameWithNamespace(abc.constants, true); - writer.appendNoHilight(" extends "); - writer.hilightSpecial(abc.constants.getMultiname(super_index).getName(abc.constants, fullyQualifiedNames, false), HighlightSpecialType.TYPE_NAME, typeName); - } - if (interfaces.length > 0) { - if (isInterface()) { - writer.appendNoHilight(" extends "); - } else { - writer.appendNoHilight(" implements "); - } - for (int i = 0; i < interfaces.length; i++) { - if (i > 0) { - writer.append(", "); - } - String typeName = abc.constants.getMultiname(interfaces[i]).getNameWithNamespace(abc.constants, true); - writer.hilightSpecial(abc.constants.getMultiname(interfaces[i]).getName(abc.constants, fullyQualifiedNames, false), HighlightSpecialType.TYPE_NAME, typeName); - } - } - - return writer; - } - - public Multiname getName(AVM2ConstantPool constants) { - return constants.getMultiname(name_index); - } - - public boolean isInterface() { - return ((flags & CLASS_INTERFACE) == CLASS_INTERFACE); - } - - public boolean isDynamic() { - return (flags & CLASS_SEALED) == 0; - } - - public boolean isFinal() { - return (flags & CLASS_FINAL) == CLASS_FINAL; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.types; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.types.traits.Traits; +import com.jpexs.decompiler.flash.helpers.GraphTextWriter; +import com.jpexs.decompiler.flash.helpers.hilight.HighlightSpecialType; +import com.jpexs.decompiler.flash.types.annotations.Internal; +import com.jpexs.helpers.Helper; +import java.util.ArrayList; +import java.util.List; + +public class InstanceInfo { + + public int name_index; + + public int super_index; + + public int flags; // 1 = sealed, 0 = dynamic, 2 = final, 4 = interface, 8 = ProtectedNs + + public int protectedNS; //if flags & 8 + + public int[] interfaces; + + public int iinit_index; // MethodInfo - constructor + + public Traits instance_traits; + + public static final int CLASS_SEALED = 1; //not dynamic + + public static final int CLASS_FINAL = 2; + + public static final int CLASS_INTERFACE = 4; + + public static final int CLASS_PROTECTEDNS = 8; + + @Internal + public boolean deleted; + + public InstanceInfo() { + instance_traits = new Traits(); + } + + public InstanceInfo(Traits traits) { + instance_traits = traits; + } + + @Override + public String toString() { + return "name_index=" + name_index + " super_index=" + super_index + " flags=" + flags + " protectedNS=" + protectedNS + " interfaces=" + Helper.intArrToString(interfaces) + " method_index=" + iinit_index + "\r\n" + instance_traits.toString(); + } + + public String toString(ABC abc, List fullyQualifiedNames) { + String supIndexStr = "[nothing]"; + if (super_index > 0) { + supIndexStr = abc.constants.getMultiname(super_index).toString(abc.constants, fullyQualifiedNames); + } + return "name_index=" + abc.constants.getMultiname(name_index).toString(abc.constants, fullyQualifiedNames) + " super_index=" + supIndexStr + " flags=" + flags + " protectedNS=" + protectedNS + " interfaces=" + Helper.intArrToString(interfaces) + " method_index=" + iinit_index + "\r\n" + instance_traits.toString(abc, fullyQualifiedNames); + } + + public GraphTextWriter getClassHeaderStr(GraphTextWriter writer, ABC abc, List fullyQualifiedNames, boolean allowPrivate) { + String modifiers; + Namespace ns = abc.constants.getMultiname(name_index).getNamespace(abc.constants); + modifiers = ns.getPrefix(abc); + if (!allowPrivate && modifiers.equals("private")) { + modifiers = ""; + } + if (!modifiers.isEmpty()) { + modifiers += " "; + } + + if (isFinal()) { + modifiers += "final "; + } + if (!isInterface() && isDynamic()) { + modifiers += "dynamic "; + } + String objType = "class "; + if (isInterface()) { + objType = "interface "; + } + + writer.appendNoHilight(modifiers + objType); + writer.hilightSpecial(abc.constants.getMultiname(name_index).getName(abc.constants, new ArrayList()/* No full names here*/, false), HighlightSpecialType.CLASS_NAME); + + if (super_index > 0) { + String typeName = abc.constants.getMultiname(super_index).getNameWithNamespace(abc.constants, true); + writer.appendNoHilight(" extends "); + writer.hilightSpecial(abc.constants.getMultiname(super_index).getName(abc.constants, fullyQualifiedNames, false), HighlightSpecialType.TYPE_NAME, typeName); + } + if (interfaces.length > 0) { + if (isInterface()) { + writer.appendNoHilight(" extends "); + } else { + writer.appendNoHilight(" implements "); + } + for (int i = 0; i < interfaces.length; i++) { + if (i > 0) { + writer.append(", "); + } + String typeName = abc.constants.getMultiname(interfaces[i]).getNameWithNamespace(abc.constants, true); + writer.hilightSpecial(abc.constants.getMultiname(interfaces[i]).getName(abc.constants, fullyQualifiedNames, false), HighlightSpecialType.TYPE_NAME, typeName); + } + } + + return writer; + } + + public Multiname getName(AVM2ConstantPool constants) { + return constants.getMultiname(name_index); + } + + public boolean isInterface() { + return ((flags & CLASS_INTERFACE) == CLASS_INTERFACE); + } + + public boolean isDynamic() { + return (flags & CLASS_SEALED) == 0; + } + + public boolean isFinal() { + return (flags & CLASS_FINAL) == CLASS_FINAL; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/MethodBody.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/MethodBody.java index ffb82d8cc..d453841d5 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/MethodBody.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/MethodBody.java @@ -1,325 +1,325 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.types; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.ABCInputStream; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.CodeStats; -import com.jpexs.decompiler.flash.abc.avm2.UnknownInstructionCode; -import com.jpexs.decompiler.flash.abc.types.traits.Trait; -import com.jpexs.decompiler.flash.abc.types.traits.Traits; -import com.jpexs.decompiler.flash.configuration.Configuration; -import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; -import com.jpexs.decompiler.flash.helpers.GraphTextWriter; -import com.jpexs.decompiler.flash.types.annotations.Internal; -import com.jpexs.decompiler.flash.types.annotations.SWFField; -import com.jpexs.decompiler.graph.Graph; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.decompiler.graph.model.LocalData; -import com.jpexs.helpers.CancellableWorker; -import com.jpexs.helpers.Helper; -import com.jpexs.helpers.MemoryInputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import java.util.logging.Level; -import java.util.logging.Logger; - -public final class MethodBody implements Cloneable { - - @Internal - public boolean deleted; - - boolean debugMode = false; - - public int method_info; - - public int max_stack; - - public int max_regs; - - public int init_scope_depth; - - public int max_scope_depth; - - @SWFField - private byte[] codeBytes; - - private AVM2Code code; - - public ABCException[] exceptions; - - public Traits traits; - - @Internal - public transient List convertedItems; - - @Internal - public transient Throwable convertException; - - public MethodBody() { - this.traits = new Traits(); - this.codeBytes = new byte[0]; - this.exceptions = new ABCException[0]; - } - - public MethodBody(Traits traits, byte[] codeBytes, ABCException[] exceptions) { - this.traits = traits; - this.codeBytes = codeBytes; - this.exceptions = exceptions; - } - - public synchronized void setCodeBytes(byte codeBytes[]) { - this.codeBytes = codeBytes; - this.code = null; - } - - public synchronized byte[] getCodeBytes() { - if (code == null) { - return codeBytes; - } else { - return code.getBytes(); - } - } - - public synchronized AVM2Code getCode() { - if (code == null) { - AVM2Code avm2Code; - try { - ABCInputStream ais = new ABCInputStream(new MemoryInputStream(codeBytes)); - avm2Code = new AVM2Code(ais); - } catch (UnknownInstructionCode | IOException ex) { - avm2Code = new AVM2Code(); - Logger.getLogger(MethodBody.class.getName()).log(Level.SEVERE, null, ex); - } - avm2Code.compact(); - code = avm2Code; - } - return code; - } - - public void setCode(AVM2Code code) { - this.code = code; - } - - public List getExceptionEntries() { - List ret = new ArrayList<>(); - for (ABCException e : exceptions) { - ret.add(getCode().adr2pos(e.start)); - ret.add(getCode().adr2pos(e.end)); - ret.add(getCode().adr2pos(e.target)); - } - return ret; - } - - public void markOffsets() { - long offset = 0; - for (int i = 0; i < getCode().code.size(); i++) { - getCode().code.get(i).offset = offset; - offset += getCode().code.get(i).getBytes().length; - } - } - - @Override - public String toString() { - String s = ""; - s += "method_info=" + method_info + " max_stack=" + max_stack + " max_regs=" + max_regs + " scope_depth=" + init_scope_depth + " max_scope=" + max_scope_depth; - s += "\r\nCode:\r\n" + getCode().toString(); - return s; - } - - public int removeDeadCode(AVM2ConstantPool constants, Trait trait, MethodInfo info) throws InterruptedException { - return getCode().removeDeadCode(constants, trait, info, this); - } - - public void restoreControlFlow(AVM2ConstantPool constants, Trait trait, MethodInfo info) throws InterruptedException { - getCode().restoreControlFlow(constants, trait, info, this); - } - - public int removeTraps(AVM2ConstantPool constants, ABC abc, Trait trait, int scriptIndex, int classIndex, boolean isStatic, String path) throws InterruptedException { - return getCode().removeTraps(constants, trait, abc.method_info.get(method_info), this, abc, scriptIndex, classIndex, isStatic, path); - } - - public HashMap getLocalRegNames(ABC abc) { - HashMap ret = new HashMap<>(); - for (int i = 1; i <= abc.method_info.get(this.method_info).param_types.length; i++) { - String paramName = "param" + i; - if (abc.method_info.get(this.method_info).flagHas_paramnames() && Configuration.paramNamesEnable.get()) { - paramName = abc.constants.getString(abc.method_info.get(this.method_info).paramNames[i - 1]); - } - ret.put(i, paramName); - } - int pos = abc.method_info.get(this.method_info).param_types.length + 1; - if (abc.method_info.get(this.method_info).flagNeed_arguments()) { - ret.put(pos, "arguments"); - pos++; - } - if (abc.method_info.get(this.method_info).flagNeed_rest()) { - ret.put(pos, "rest"); - pos++; - } - - if (Configuration.getLocalNamesFromDebugInfo.get()) { - Map debugRegNames = getCode().getLocalRegNamesFromDebug(abc); - for (int k : debugRegNames.keySet()) { - ret.put(k, debugRegNames.get(k)); - } - } - return ret; - } - - public void convert(final String path, ScriptExportMode exportMode, final boolean isStatic, final int scriptIndex, final int classIndex, final ABC abc, final Trait trait, final AVM2ConstantPool constants, final List method_info, final ScopeStack scopeStack, final boolean isStaticInitializer, final GraphTextWriter writer, final List fullyQualifiedNames, final Traits initTraits, boolean firstLevel) throws InterruptedException { - if (debugMode) { - System.err.println("Decompiling " + path); - } - if (exportMode != ScriptExportMode.AS) { - getCode().toASMSource(constants, trait, method_info.get(this.method_info), this, exportMode, writer); - } else { - if (!Configuration.decompile.get()) { - writer.appendNoHilight(Helper.getDecompilationSkippedComment()).newLine(); - return; - } - int timeout = Configuration.decompilationTimeoutSingleMethod.get(); - convertException = null; - try { - Callable callable = new Callable() { - @Override - public Void call() throws InterruptedException { - MethodBody converted = convertMethodBody(path, isStatic, scriptIndex, classIndex, abc, trait, constants, method_info, scopeStack, isStaticInitializer, fullyQualifiedNames, initTraits); - HashMap localRegNames = getLocalRegNames(abc); - convertedItems = converted.getCode().toGraphTargetItems(path, isStatic, scriptIndex, classIndex, abc, constants, method_info, converted, localRegNames, scopeStack, isStaticInitializer, fullyQualifiedNames, initTraits, Graph.SOP_USE_STATIC, new HashMap(), converted.getCode().visitCode(converted)); - Graph.graphToString(convertedItems, writer, LocalData.create(constants, localRegNames, fullyQualifiedNames)); - return null; - } - }; - if (firstLevel) { - CancellableWorker.call(callable, timeout, TimeUnit.SECONDS); - } else { - callable.call(); - } - } catch (InterruptedException ex) { - throw ex; - } catch (Exception | OutOfMemoryError | StackOverflowError ex) { - if (ex instanceof TimeoutException) { - Logger.getLogger(MethodBody.class.getName()).log(Level.SEVERE, "Decompilation timeout in " + path, ex); - } else { - Logger.getLogger(MethodBody.class.getName()).log(Level.SEVERE, "Decompilation error in " + path, ex); - } - convertException = ex; - Throwable cause = ex.getCause(); - if (ex instanceof ExecutionException && cause instanceof Exception) { - convertException = (Exception) cause; - } - } - } - } - - public GraphTextWriter toString(final String path, ScriptExportMode exportMode, final ABC abc, final Trait trait, final AVM2ConstantPool constants, final List method_info, final GraphTextWriter writer, final List fullyQualifiedNames) throws InterruptedException { - if (exportMode != ScriptExportMode.AS) { - getCode().toASMSource(constants, trait, method_info.get(this.method_info), this, exportMode, writer); - } else { - if (!Configuration.decompile.get()) { - //writer.startMethod(this.method_info); - writer.appendNoHilight(Helper.getDecompilationSkippedComment()).newLine(); - //writer.endMethod(); - return writer; - } - int timeout = Configuration.decompilationTimeoutSingleMethod.get(); - - if (convertException == null) { - HashMap localRegNames = getLocalRegNames(abc); - //writer.startMethod(this.method_info); - if (Configuration.showMethodBodyId.get()) { - writer.appendNoHilight("// method body id: "); - writer.appendNoHilight(abc.findBodyIndex(this.method_info)); - writer.newLine(); - } - Graph.graphToString(convertedItems, writer, LocalData.create(constants, localRegNames, fullyQualifiedNames)); - //writer.endMethod(); - } else if (convertException instanceof TimeoutException) { - // exception was logged in convert method - Helper.appendTimeoutComment(writer, timeout); - } else { - // exception was logged in convert method - Helper.appendErrorComment(writer, convertException); - } - } - return writer; - } - - public MethodBody convertMethodBody(String path, boolean isStatic, int scriptIndex, int classIndex, ABC abc, Trait trait, AVM2ConstantPool constants, List method_info, ScopeStack scopeStack, boolean isStaticInitializer, List fullyQualifiedNames, Traits initTraits) throws InterruptedException { - MethodBody b = clone(); - AVM2Code deobfuscated = b.getCode(); - deobfuscated.markMappedOffsets(); - if (Configuration.autoDeobfuscate.get()) { - try { - deobfuscated.removeTraps(constants, trait, method_info.get(this.method_info), b, abc, scriptIndex, classIndex, isStatic, path); - } catch (StackOverflowError ex) { - Logger.getLogger(MethodBody.class.getName()).log(Level.SEVERE, "Error during remove traps in " + path, ex); - } - } - //deobfuscated.restoreControlFlow(constants, b); - - return b; - } - - @Override - public MethodBody clone() { - try { - MethodBody ret = (MethodBody) super.clone(); - if (code != null) { - ret.code = code.clone(); - } - //maybe deep clone traits - return ret; - } catch (CloneNotSupportedException ex) { - throw new RuntimeException(); - } - } - - public boolean autoFillStats(ABC abc, int initScope, boolean hasThis) { - //System.out.println("--------------"); - CodeStats stats = getCode().getStats(abc, this, initScope); - if (stats == null) { - return false; - } - if (stats.has_activation) { - initScope++; - } - max_stack = stats.maxstack; - max_scope_depth = stats.maxscope + (stats.has_activation ? 1 : 0); - max_regs = stats.maxlocal; - init_scope_depth = initScope; - abc.method_info.get(method_info).setFlagSetsdxns(stats.has_set_dxns); - abc.method_info.get(method_info).setFlagNeed_activation(stats.has_activation); - MethodInfo mi = abc.method_info.get(method_info); - int min_regs = mi.param_types.length + 1 + (mi.flagNeed_rest() ? 1 : 0); - if (max_regs < min_regs) { - max_regs = min_regs; - } - return true; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.types; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.ABCInputStream; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.CodeStats; +import com.jpexs.decompiler.flash.abc.avm2.UnknownInstructionCode; +import com.jpexs.decompiler.flash.abc.types.traits.Trait; +import com.jpexs.decompiler.flash.abc.types.traits.Traits; +import com.jpexs.decompiler.flash.configuration.Configuration; +import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; +import com.jpexs.decompiler.flash.helpers.GraphTextWriter; +import com.jpexs.decompiler.flash.types.annotations.Internal; +import com.jpexs.decompiler.flash.types.annotations.SWFField; +import com.jpexs.decompiler.graph.Graph; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.model.LocalData; +import com.jpexs.helpers.CancellableWorker; +import com.jpexs.helpers.Helper; +import com.jpexs.helpers.MemoryInputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.logging.Level; +import java.util.logging.Logger; + +public final class MethodBody implements Cloneable { + + @Internal + public boolean deleted; + + boolean debugMode = false; + + public int method_info; + + public int max_stack; + + public int max_regs; + + public int init_scope_depth; + + public int max_scope_depth; + + @SWFField + private byte[] codeBytes; + + private AVM2Code code; + + public ABCException[] exceptions; + + public Traits traits; + + @Internal + public transient List convertedItems; + + @Internal + public transient Throwable convertException; + + public MethodBody() { + this.traits = new Traits(); + this.codeBytes = new byte[0]; + this.exceptions = new ABCException[0]; + } + + public MethodBody(Traits traits, byte[] codeBytes, ABCException[] exceptions) { + this.traits = traits; + this.codeBytes = codeBytes; + this.exceptions = exceptions; + } + + public synchronized void setCodeBytes(byte codeBytes[]) { + this.codeBytes = codeBytes; + this.code = null; + } + + public synchronized byte[] getCodeBytes() { + if (code == null) { + return codeBytes; + } else { + return code.getBytes(); + } + } + + public synchronized AVM2Code getCode() { + if (code == null) { + AVM2Code avm2Code; + try { + ABCInputStream ais = new ABCInputStream(new MemoryInputStream(codeBytes)); + avm2Code = new AVM2Code(ais); + } catch (UnknownInstructionCode | IOException ex) { + avm2Code = new AVM2Code(); + Logger.getLogger(MethodBody.class.getName()).log(Level.SEVERE, null, ex); + } + avm2Code.compact(); + code = avm2Code; + } + return code; + } + + public void setCode(AVM2Code code) { + this.code = code; + } + + public List getExceptionEntries() { + List ret = new ArrayList<>(); + for (ABCException e : exceptions) { + ret.add(getCode().adr2pos(e.start)); + ret.add(getCode().adr2pos(e.end)); + ret.add(getCode().adr2pos(e.target)); + } + return ret; + } + + public void markOffsets() { + long offset = 0; + for (int i = 0; i < getCode().code.size(); i++) { + getCode().code.get(i).offset = offset; + offset += getCode().code.get(i).getBytes().length; + } + } + + @Override + public String toString() { + String s = ""; + s += "method_info=" + method_info + " max_stack=" + max_stack + " max_regs=" + max_regs + " scope_depth=" + init_scope_depth + " max_scope=" + max_scope_depth; + s += "\r\nCode:\r\n" + getCode().toString(); + return s; + } + + public int removeDeadCode(AVM2ConstantPool constants, Trait trait, MethodInfo info) throws InterruptedException { + return getCode().removeDeadCode(constants, trait, info, this); + } + + public void restoreControlFlow(AVM2ConstantPool constants, Trait trait, MethodInfo info) throws InterruptedException { + getCode().restoreControlFlow(constants, trait, info, this); + } + + public int removeTraps(AVM2ConstantPool constants, ABC abc, Trait trait, int scriptIndex, int classIndex, boolean isStatic, String path) throws InterruptedException { + return getCode().removeTraps(constants, trait, abc.method_info.get(method_info), this, abc, scriptIndex, classIndex, isStatic, path); + } + + public HashMap getLocalRegNames(ABC abc) { + HashMap ret = new HashMap<>(); + for (int i = 1; i <= abc.method_info.get(this.method_info).param_types.length; i++) { + String paramName = "param" + i; + if (abc.method_info.get(this.method_info).flagHas_paramnames() && Configuration.paramNamesEnable.get()) { + paramName = abc.constants.getString(abc.method_info.get(this.method_info).paramNames[i - 1]); + } + ret.put(i, paramName); + } + int pos = abc.method_info.get(this.method_info).param_types.length + 1; + if (abc.method_info.get(this.method_info).flagNeed_arguments()) { + ret.put(pos, "arguments"); + pos++; + } + if (abc.method_info.get(this.method_info).flagNeed_rest()) { + ret.put(pos, "rest"); + pos++; + } + + if (Configuration.getLocalNamesFromDebugInfo.get()) { + Map debugRegNames = getCode().getLocalRegNamesFromDebug(abc); + for (int k : debugRegNames.keySet()) { + ret.put(k, debugRegNames.get(k)); + } + } + return ret; + } + + public void convert(final String path, ScriptExportMode exportMode, final boolean isStatic, final int scriptIndex, final int classIndex, final ABC abc, final Trait trait, final AVM2ConstantPool constants, final List method_info, final ScopeStack scopeStack, final boolean isStaticInitializer, final GraphTextWriter writer, final List fullyQualifiedNames, final Traits initTraits, boolean firstLevel) throws InterruptedException { + if (debugMode) { + System.err.println("Decompiling " + path); + } + if (exportMode != ScriptExportMode.AS) { + getCode().toASMSource(constants, trait, method_info.get(this.method_info), this, exportMode, writer); + } else { + if (!Configuration.decompile.get()) { + writer.appendNoHilight(Helper.getDecompilationSkippedComment()).newLine(); + return; + } + int timeout = Configuration.decompilationTimeoutSingleMethod.get(); + convertException = null; + try { + Callable callable = new Callable() { + @Override + public Void call() throws InterruptedException { + MethodBody converted = convertMethodBody(path, isStatic, scriptIndex, classIndex, abc, trait, constants, method_info, scopeStack, isStaticInitializer, fullyQualifiedNames, initTraits); + HashMap localRegNames = getLocalRegNames(abc); + convertedItems = converted.getCode().toGraphTargetItems(path, isStatic, scriptIndex, classIndex, abc, constants, method_info, converted, localRegNames, scopeStack, isStaticInitializer, fullyQualifiedNames, initTraits, Graph.SOP_USE_STATIC, new HashMap(), converted.getCode().visitCode(converted)); + Graph.graphToString(convertedItems, writer, LocalData.create(constants, localRegNames, fullyQualifiedNames)); + return null; + } + }; + if (firstLevel) { + CancellableWorker.call(callable, timeout, TimeUnit.SECONDS); + } else { + callable.call(); + } + } catch (InterruptedException ex) { + throw ex; + } catch (Exception | OutOfMemoryError | StackOverflowError ex) { + if (ex instanceof TimeoutException) { + Logger.getLogger(MethodBody.class.getName()).log(Level.SEVERE, "Decompilation timeout in " + path, ex); + } else { + Logger.getLogger(MethodBody.class.getName()).log(Level.SEVERE, "Decompilation error in " + path, ex); + } + convertException = ex; + Throwable cause = ex.getCause(); + if (ex instanceof ExecutionException && cause instanceof Exception) { + convertException = (Exception) cause; + } + } + } + } + + public GraphTextWriter toString(final String path, ScriptExportMode exportMode, final ABC abc, final Trait trait, final AVM2ConstantPool constants, final List method_info, final GraphTextWriter writer, final List fullyQualifiedNames) throws InterruptedException { + if (exportMode != ScriptExportMode.AS) { + getCode().toASMSource(constants, trait, method_info.get(this.method_info), this, exportMode, writer); + } else { + if (!Configuration.decompile.get()) { + //writer.startMethod(this.method_info); + writer.appendNoHilight(Helper.getDecompilationSkippedComment()).newLine(); + //writer.endMethod(); + return writer; + } + int timeout = Configuration.decompilationTimeoutSingleMethod.get(); + + if (convertException == null) { + HashMap localRegNames = getLocalRegNames(abc); + //writer.startMethod(this.method_info); + if (Configuration.showMethodBodyId.get()) { + writer.appendNoHilight("// method body id: "); + writer.appendNoHilight(abc.findBodyIndex(this.method_info)); + writer.newLine(); + } + Graph.graphToString(convertedItems, writer, LocalData.create(constants, localRegNames, fullyQualifiedNames)); + //writer.endMethod(); + } else if (convertException instanceof TimeoutException) { + // exception was logged in convert method + Helper.appendTimeoutComment(writer, timeout); + } else { + // exception was logged in convert method + Helper.appendErrorComment(writer, convertException); + } + } + return writer; + } + + public MethodBody convertMethodBody(String path, boolean isStatic, int scriptIndex, int classIndex, ABC abc, Trait trait, AVM2ConstantPool constants, List method_info, ScopeStack scopeStack, boolean isStaticInitializer, List fullyQualifiedNames, Traits initTraits) throws InterruptedException { + MethodBody b = clone(); + AVM2Code deobfuscated = b.getCode(); + deobfuscated.markMappedOffsets(); + if (Configuration.autoDeobfuscate.get()) { + try { + deobfuscated.removeTraps(constants, trait, method_info.get(this.method_info), b, abc, scriptIndex, classIndex, isStatic, path); + } catch (StackOverflowError ex) { + Logger.getLogger(MethodBody.class.getName()).log(Level.SEVERE, "Error during remove traps in " + path, ex); + } + } + //deobfuscated.restoreControlFlow(constants, b); + + return b; + } + + @Override + public MethodBody clone() { + try { + MethodBody ret = (MethodBody) super.clone(); + if (code != null) { + ret.code = code.clone(); + } + //maybe deep clone traits + return ret; + } catch (CloneNotSupportedException ex) { + throw new RuntimeException(); + } + } + + public boolean autoFillStats(ABC abc, int initScope, boolean hasThis) { + //System.out.println("--------------"); + CodeStats stats = getCode().getStats(abc, this, initScope); + if (stats == null) { + return false; + } + if (stats.has_activation) { + initScope++; + } + max_stack = stats.maxstack; + max_scope_depth = stats.maxscope + (stats.has_activation ? 1 : 0); + max_regs = stats.maxlocal; + init_scope_depth = initScope; + abc.method_info.get(method_info).setFlagSetsdxns(stats.has_set_dxns); + abc.method_info.get(method_info).setFlagNeed_activation(stats.has_activation); + MethodInfo mi = abc.method_info.get(method_info); + int min_regs = mi.param_types.length + 1 + (mi.flagNeed_rest() ? 1 : 0); + if (max_regs < min_regs) { + max_regs = min_regs; + } + return true; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/ScriptInfo.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/ScriptInfo.java index 3192619b5..da02dad95 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/ScriptInfo.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/ScriptInfo.java @@ -1,112 +1,112 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.types; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.ClassPath; -import com.jpexs.decompiler.flash.abc.ScriptPack; -import com.jpexs.decompiler.flash.abc.types.traits.Trait; -import com.jpexs.decompiler.flash.abc.types.traits.Traits; -import com.jpexs.decompiler.flash.types.annotations.Internal; -import java.util.ArrayList; -import java.util.List; - -public class ScriptInfo { - - @Internal - private boolean modified = true; - - public void setModified(boolean modified) { - this.modified = modified; - } - - public boolean isModified() { - return modified; - } - - @Internal - public boolean deleted; - - public int init_index; //MethodInfo - - public Traits traits; - - public ScriptInfo() { - traits = new Traits(); - } - - public ScriptInfo(Traits traits) { - this.traits = traits; - } - - public List getPacks(ABC abc, int scriptIndex, String packagePrefix) { - List ret = new ArrayList<>(); - - List otherTraits = new ArrayList<>(); - for (int j = 0; j < traits.traits.size(); j++) { - Trait t = traits.traits.get(j); - Multiname name = t.getName(abc); - Namespace ns = name.getNamespace(abc.constants); - if (!((ns.kind == Namespace.KIND_PACKAGE_INTERNAL) - || (ns.kind == Namespace.KIND_PACKAGE))) { - otherTraits.add(j); - } - } - for (int j = 0; j < traits.traits.size(); j++) { - Trait t = traits.traits.get(j); - Multiname name = t.getName(abc); - Namespace ns = name.getNamespace(abc.constants); - if ((ns.kind == Namespace.KIND_PACKAGE_INTERNAL) - || (ns.kind == Namespace.KIND_PACKAGE)) { - String packageName = ns.getName(abc.constants, false); // assume not null package - String objectName = name.getName(abc.constants, null, false); - List traitIndices = new ArrayList<>(); - - traitIndices.add(j); - if (!otherTraits.isEmpty()) { - traitIndices.addAll(otherTraits); - otherTraits.clear(); - } - - if (packagePrefix == null || packageName.startsWith(packagePrefix)) { - ClassPath cp = new ClassPath(packageName, objectName); - ret.add(new ScriptPack(cp, abc, scriptIndex, traitIndices)); - } - } - } - return ret; - } - - public int removeTraps(int scriptIndex, ABC abc, String path) throws InterruptedException { - return traits.removeTraps(scriptIndex, -1, true, abc, path); - } - - @Override - public String toString() { - return "method_index=" + init_index + "\r\n" + traits.toString(); - } - - public String toString(ABC abc, List fullyQualifiedNames) { - return "method_index=" + init_index + "\r\n" + traits.toString(abc, fullyQualifiedNames); - } - - public void delete(ABC abc, boolean d) { - deleted = d; - abc.method_info.get(init_index).delete(abc, d); - traits.delete(abc, d); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.types; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.ClassPath; +import com.jpexs.decompiler.flash.abc.ScriptPack; +import com.jpexs.decompiler.flash.abc.types.traits.Trait; +import com.jpexs.decompiler.flash.abc.types.traits.Traits; +import com.jpexs.decompiler.flash.types.annotations.Internal; +import java.util.ArrayList; +import java.util.List; + +public class ScriptInfo { + + @Internal + private boolean modified = true; + + public void setModified(boolean modified) { + this.modified = modified; + } + + public boolean isModified() { + return modified; + } + + @Internal + public boolean deleted; + + public int init_index; //MethodInfo + + public Traits traits; + + public ScriptInfo() { + traits = new Traits(); + } + + public ScriptInfo(Traits traits) { + this.traits = traits; + } + + public List getPacks(ABC abc, int scriptIndex, String packagePrefix) { + List ret = new ArrayList<>(); + + List otherTraits = new ArrayList<>(); + for (int j = 0; j < traits.traits.size(); j++) { + Trait t = traits.traits.get(j); + Multiname name = t.getName(abc); + Namespace ns = name.getNamespace(abc.constants); + if (!((ns.kind == Namespace.KIND_PACKAGE_INTERNAL) + || (ns.kind == Namespace.KIND_PACKAGE))) { + otherTraits.add(j); + } + } + for (int j = 0; j < traits.traits.size(); j++) { + Trait t = traits.traits.get(j); + Multiname name = t.getName(abc); + Namespace ns = name.getNamespace(abc.constants); + if ((ns.kind == Namespace.KIND_PACKAGE_INTERNAL) + || (ns.kind == Namespace.KIND_PACKAGE)) { + String packageName = ns.getName(abc.constants, false); // assume not null package + String objectName = name.getName(abc.constants, null, false); + List traitIndices = new ArrayList<>(); + + traitIndices.add(j); + if (!otherTraits.isEmpty()) { + traitIndices.addAll(otherTraits); + otherTraits.clear(); + } + + if (packagePrefix == null || packageName.startsWith(packagePrefix)) { + ClassPath cp = new ClassPath(packageName, objectName); + ret.add(new ScriptPack(cp, abc, scriptIndex, traitIndices)); + } + } + } + return ret; + } + + public int removeTraps(int scriptIndex, ABC abc, String path) throws InterruptedException { + return traits.removeTraps(scriptIndex, -1, true, abc, path); + } + + @Override + public String toString() { + return "method_index=" + init_index + "\r\n" + traits.toString(); + } + + public String toString(ABC abc, List fullyQualifiedNames) { + return "method_index=" + init_index + "\r\n" + traits.toString(abc, fullyQualifiedNames); + } + + public void delete(ABC abc, boolean d) { + deleted = d; + abc.method_info.get(init_index).delete(abc, d); + traits.delete(abc, d); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/Trait.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/Trait.java index 3a46e6aab..632faa6e0 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/Trait.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/Trait.java @@ -1,200 +1,200 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.types.traits; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.ClassPath; -import com.jpexs.decompiler.flash.abc.types.Multiname; -import com.jpexs.decompiler.flash.abc.types.Namespace; -import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; -import com.jpexs.decompiler.flash.helpers.GraphTextWriter; -import com.jpexs.decompiler.flash.helpers.NulWriter; -import com.jpexs.decompiler.flash.tags.ABCContainerTag; -import com.jpexs.helpers.Helper; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; - -public abstract class Trait implements Serializable { - - private static final int[] EMPTY_METADATA_ARRAY = new int[0]; - - public int name_index; - - public int kindType; - - public int kindFlags; - - public int[] metadata = EMPTY_METADATA_ARRAY; - - public long fileOffset; - - public byte[] bytes; - - public static final int ATTR_Final = 0x1; - - public static final int ATTR_Override = 0x2; - - public static final int ATTR_Metadata = 0x4; - - public static final int TRAIT_SLOT = 0; - - public static final int TRAIT_METHOD = 1; - - public static final int TRAIT_GETTER = 2; - - public static final int TRAIT_SETTER = 3; - - public static final int TRAIT_CLASS = 4; - - public static final int TRAIT_FUNCTION = 5; - - public static final int TRAIT_CONST = 6; - - public abstract void delete(ABC abc, boolean d); - - public String getModifiers(ABC abc, boolean isStatic) { - String ret = ""; - if ((kindFlags & ATTR_Override) > 0) { - ret += "override"; - } - Multiname m = getName(abc); - if (m != null) { - String nsname = ""; - //if (abc.constants.getNamespace(m.namespace_index).kind == Namespace.KIND_NAMESPACE) { - { - for (ABCContainerTag abcTag : abc.getAbcTags()) { - if (m.namespace_index == -1) { - break; - } - nsname = abcTag.getABC().nsValueToName(abc.constants.getNamespace(m.namespace_index).getName(abc.constants, true)); - if (nsname == null) { - break; - } - if (nsname.contains(".")) { - nsname = nsname.substring(nsname.lastIndexOf('.') + 1); - } - if (!nsname.isEmpty()) { - break; - } - } - } - Namespace ns = m.getNamespace(abc.constants); - - if (nsname.contains(":")) { - nsname = ""; - } - - if ((!nsname.isEmpty()) && (!nsname.equals("-"))) { - } else { - if (ns != null) { - if (ns.kind == Namespace.KIND_NAMESPACE) { - nsname = ns.getName(abc.constants, true); - } - } - } - - if (nsname != null && (!nsname.contains(":")) && (!nsname.isEmpty())) { - ret += " " + nsname; - } - if (ns != null) { - ret += " " + ns.getPrefix(abc); - } - } - if (isStatic) { - if ((this instanceof TraitSlotConst) && ((TraitSlotConst) this).isNamespace()) { - //static is automatic - } else { - ret += " static"; - } - } - if ((kindFlags & ATTR_Final) > 0) { - if (!isStatic) { - ret += " final"; - } - } - return ret.trim(); - } - - @Override - public String toString() { - return "name_index=" + name_index + " kind=" + kindType + " metadata=" + Helper.intArrToString(metadata); - } - - public String toString(ABC abc, List fullyQualifiedNames) { - return abc.constants.getMultiname(name_index).toString(abc.constants, fullyQualifiedNames) + " kind=" + kindType + " metadata=" + Helper.intArrToString(metadata); - } - - public GraphTextWriter toString(Trait parent, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, GraphTextWriter writer, List fullyQualifiedNames, boolean parallel) throws InterruptedException { - writer.appendNoHilight(abc.constants.getMultiname(name_index).toString(abc.constants, fullyQualifiedNames) + " kind=" + kindType + " metadata=" + Helper.intArrToString(metadata)); - return writer; - } - - public void convert(Trait parent, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List fullyQualifiedNames, boolean parallel) throws InterruptedException { - } - - public GraphTextWriter toStringPackaged(Trait parent, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, GraphTextWriter writer, List fullyQualifiedNames, boolean parallel) throws InterruptedException { - Namespace ns = abc.constants.getMultiname(name_index).getNamespace(abc.constants); - if ((ns.kind == Namespace.KIND_PACKAGE) || (ns.kind == Namespace.KIND_PACKAGE_INTERNAL)) { - String nsname = ns.getName(abc.constants, false); - writer.appendNoHilight("package"); - if (!nsname.isEmpty()) { - writer.appendNoHilight(" " + nsname); //assume not null name - } - writer.startBlock(); - toString(parent, path, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, parallel); - writer.endBlock(); - writer.newLine(); - } - return writer; - } - - public void convertPackaged(Trait parent, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List fullyQualifiedNames, boolean parallel) throws InterruptedException { - Namespace ns = abc.constants.getMultiname(name_index).getNamespace(abc.constants); - if ((ns.kind == Namespace.KIND_PACKAGE) || (ns.kind == Namespace.KIND_PACKAGE_INTERNAL)) { - String nsname = ns.getName(abc.constants, false); - convert(parent, path + nsname, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, parallel); - } - } - - public GraphTextWriter toStringHeader(Trait parent, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, GraphTextWriter writer, List fullyQualifiedNames, boolean parallel) throws InterruptedException { - toString(parent, path, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, parallel); - return writer; - } - - public void convertHeader(Trait parent, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List fullyQualifiedNames, boolean parallel) throws InterruptedException { - convert(parent, path, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, parallel); - } - - public Multiname getName(ABC abc) { - if (name_index == 0) { - return null; - } else { - return abc.constants.getMultiname(name_index); - } - } - - public abstract int removeTraps(int scriptIndex, int classIndex, boolean isStatic, ABC abc, String path) throws InterruptedException; - - public ClassPath getPath(ABC abc) { - Multiname name = getName(abc); - Namespace ns = name.getNamespace(abc.constants); - String packageName = ns.getName(abc.constants, false); - String objectName = name.getName(abc.constants, new ArrayList(), false); - return new ClassPath(packageName, objectName); //assume not null name - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.types.traits; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.ClassPath; +import com.jpexs.decompiler.flash.abc.types.Multiname; +import com.jpexs.decompiler.flash.abc.types.Namespace; +import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; +import com.jpexs.decompiler.flash.helpers.GraphTextWriter; +import com.jpexs.decompiler.flash.helpers.NulWriter; +import com.jpexs.decompiler.flash.tags.ABCContainerTag; +import com.jpexs.helpers.Helper; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +public abstract class Trait implements Serializable { + + private static final int[] EMPTY_METADATA_ARRAY = new int[0]; + + public int name_index; + + public int kindType; + + public int kindFlags; + + public int[] metadata = EMPTY_METADATA_ARRAY; + + public long fileOffset; + + public byte[] bytes; + + public static final int ATTR_Final = 0x1; + + public static final int ATTR_Override = 0x2; + + public static final int ATTR_Metadata = 0x4; + + public static final int TRAIT_SLOT = 0; + + public static final int TRAIT_METHOD = 1; + + public static final int TRAIT_GETTER = 2; + + public static final int TRAIT_SETTER = 3; + + public static final int TRAIT_CLASS = 4; + + public static final int TRAIT_FUNCTION = 5; + + public static final int TRAIT_CONST = 6; + + public abstract void delete(ABC abc, boolean d); + + public String getModifiers(ABC abc, boolean isStatic) { + String ret = ""; + if ((kindFlags & ATTR_Override) > 0) { + ret += "override"; + } + Multiname m = getName(abc); + if (m != null) { + String nsname = ""; + //if (abc.constants.getNamespace(m.namespace_index).kind == Namespace.KIND_NAMESPACE) { + { + for (ABCContainerTag abcTag : abc.getAbcTags()) { + if (m.namespace_index == -1) { + break; + } + nsname = abcTag.getABC().nsValueToName(abc.constants.getNamespace(m.namespace_index).getName(abc.constants, true)); + if (nsname == null) { + break; + } + if (nsname.contains(".")) { + nsname = nsname.substring(nsname.lastIndexOf('.') + 1); + } + if (!nsname.isEmpty()) { + break; + } + } + } + Namespace ns = m.getNamespace(abc.constants); + + if (nsname.contains(":")) { + nsname = ""; + } + + if ((!nsname.isEmpty()) && (!nsname.equals("-"))) { + } else { + if (ns != null) { + if (ns.kind == Namespace.KIND_NAMESPACE) { + nsname = ns.getName(abc.constants, true); + } + } + } + + if (nsname != null && (!nsname.contains(":")) && (!nsname.isEmpty())) { + ret += " " + nsname; + } + if (ns != null) { + ret += " " + ns.getPrefix(abc); + } + } + if (isStatic) { + if ((this instanceof TraitSlotConst) && ((TraitSlotConst) this).isNamespace()) { + //static is automatic + } else { + ret += " static"; + } + } + if ((kindFlags & ATTR_Final) > 0) { + if (!isStatic) { + ret += " final"; + } + } + return ret.trim(); + } + + @Override + public String toString() { + return "name_index=" + name_index + " kind=" + kindType + " metadata=" + Helper.intArrToString(metadata); + } + + public String toString(ABC abc, List fullyQualifiedNames) { + return abc.constants.getMultiname(name_index).toString(abc.constants, fullyQualifiedNames) + " kind=" + kindType + " metadata=" + Helper.intArrToString(metadata); + } + + public GraphTextWriter toString(Trait parent, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, GraphTextWriter writer, List fullyQualifiedNames, boolean parallel) throws InterruptedException { + writer.appendNoHilight(abc.constants.getMultiname(name_index).toString(abc.constants, fullyQualifiedNames) + " kind=" + kindType + " metadata=" + Helper.intArrToString(metadata)); + return writer; + } + + public void convert(Trait parent, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List fullyQualifiedNames, boolean parallel) throws InterruptedException { + } + + public GraphTextWriter toStringPackaged(Trait parent, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, GraphTextWriter writer, List fullyQualifiedNames, boolean parallel) throws InterruptedException { + Namespace ns = abc.constants.getMultiname(name_index).getNamespace(abc.constants); + if ((ns.kind == Namespace.KIND_PACKAGE) || (ns.kind == Namespace.KIND_PACKAGE_INTERNAL)) { + String nsname = ns.getName(abc.constants, false); + writer.appendNoHilight("package"); + if (!nsname.isEmpty()) { + writer.appendNoHilight(" " + nsname); //assume not null name + } + writer.startBlock(); + toString(parent, path, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, parallel); + writer.endBlock(); + writer.newLine(); + } + return writer; + } + + public void convertPackaged(Trait parent, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List fullyQualifiedNames, boolean parallel) throws InterruptedException { + Namespace ns = abc.constants.getMultiname(name_index).getNamespace(abc.constants); + if ((ns.kind == Namespace.KIND_PACKAGE) || (ns.kind == Namespace.KIND_PACKAGE_INTERNAL)) { + String nsname = ns.getName(abc.constants, false); + convert(parent, path + nsname, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, parallel); + } + } + + public GraphTextWriter toStringHeader(Trait parent, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, GraphTextWriter writer, List fullyQualifiedNames, boolean parallel) throws InterruptedException { + toString(parent, path, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, parallel); + return writer; + } + + public void convertHeader(Trait parent, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List fullyQualifiedNames, boolean parallel) throws InterruptedException { + convert(parent, path, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, parallel); + } + + public Multiname getName(ABC abc) { + if (name_index == 0) { + return null; + } else { + return abc.constants.getMultiname(name_index); + } + } + + public abstract int removeTraps(int scriptIndex, int classIndex, boolean isStatic, ABC abc, String path) throws InterruptedException; + + public ClassPath getPath(ABC abc) { + Multiname name = getName(abc); + Namespace ns = name.getNamespace(abc.constants); + String packageName = ns.getName(abc.constants, false); + String objectName = name.getName(abc.constants, new ArrayList(), false); + return new ClassPath(packageName, objectName); //assume not null name + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitClass.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitClass.java index 2a58044db..8609085cd 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitClass.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitClass.java @@ -1,572 +1,572 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.types.traits; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.ClassPath; -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.construction.NewFunctionIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other.FindPropertyIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other.FindPropertyStrictIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetLexIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.types.AsTypeIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.types.CoerceIns; -import com.jpexs.decompiler.flash.abc.types.ABCException; -import com.jpexs.decompiler.flash.abc.types.MethodBody; -import com.jpexs.decompiler.flash.abc.types.Multiname; -import com.jpexs.decompiler.flash.abc.types.Namespace; -import com.jpexs.decompiler.flash.abc.types.NamespaceSet; -import com.jpexs.decompiler.flash.abc.types.ScriptInfo; -import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; -import com.jpexs.decompiler.flash.helpers.GraphTextWriter; -import com.jpexs.decompiler.flash.helpers.NulWriter; -import com.jpexs.decompiler.flash.tags.ABCContainerTag; -import com.jpexs.decompiler.graph.ScopeStack; -import com.jpexs.helpers.Helper; -import java.util.ArrayList; -import java.util.List; - -public class TraitClass extends Trait implements TraitWithSlot { - - public int slot_id; - - public int class_info; - - private static final String[] builtInClasses = {"ArgumentError", "arguments", "Array", "Boolean", "Class", "Date", "DefinitionError", "Error", "EvalError", "Function", "int", "JSON", "Math", "Namespace", "Number", "Object", "QName", "RangeError", "ReferenceError", "RegExp", "SecurityError", "String", "SyntaxError", "TypeError", "uint", "URIError", "VerifyError", "XML", "XMLList"}; - - private boolean classInitializerIsEmpty; - - @Override - public void delete(ABC abc, boolean d) { - abc.class_info.get(class_info).deleted = d; - abc.instance_info.get(class_info).deleted = d; - - abc.class_info.get(class_info).static_traits.delete(abc, d); - abc.method_info.get(abc.class_info.get(class_info).cinit_index).delete(abc, d); - - abc.instance_info.get(class_info).instance_traits.delete(abc, d); - abc.method_info.get(abc.instance_info.get(class_info).iinit_index).delete(abc, d); - - int protectedNS = abc.instance_info.get(class_info).protectedNS; - if (protectedNS != 0) { - abc.constants.constant_namespace.get(protectedNS).deleted = d; - } - - abc.constants.constant_multiname.get(name_index).deleted = d; - } - - @Override - public int getSlotIndex() { - return slot_id; - } - - private static boolean isBuiltInClass(String name) { - for (String g : builtInClasses) { - if (g.equals(name)) { - return true; - } - } - return false; - } - - @Override - public String toString(ABC abc, List fullyQualifiedNames) { - return "Class " + abc.constants.getMultiname(name_index).toString(abc.constants, fullyQualifiedNames) + " slot=" + slot_id + " class_info=" + class_info + " metadata=" + Helper.intArrToString(metadata); - } - - private boolean parseUsagesFromNS(ABC abc, List imports, List uses, int namespace_index, String ignorePackage, String name) { - Namespace ns = abc.constants.getNamespace(namespace_index); - if (name.isEmpty()) { - name = "*"; - } - String newimport = ns.getName(abc.constants, ns.kind == Namespace.KIND_NAMESPACE); - /*if ((ns.kind != Namespace.KIND_PACKAGE) - && (ns.kind != Namespace.KIND_NAMESPACE) - && (ns.kind != Namespace.KIND_STATIC_PROTECTED)) { - return false; - }*/ - /*if (ns.kind == Namespace.KIND_NAMESPACE)*/ { - String oldimport = newimport; - newimport = null; - for (ABCContainerTag abcTag : abc.getAbcTags()) { - String newname = abcTag.getABC().nsValueToName(oldimport); - if (newname.equals("-")) { - return true; - } - if (!newname.isEmpty()) { - newimport = newname; - break; - } - } - if (newimport == null) { - newimport = oldimport; - newimport += "." + name; - } - if (newimport != null && newimport.isEmpty()) { - newimport = null; - } - if (newimport != null) { - /* if(ns.kind==Namespace.KIND_PACKAGE){ - newimport+=".*"; - }*/ - - if (!imports.contains(newimport)) { - if (newimport.contains(":")) { - return true; - } - String pkg = ""; - if (newimport.contains(".")) { - pkg = newimport.substring(0, newimport.lastIndexOf('.')); - } - String usname = newimport; - if (usname.contains(".")) { - usname = usname.substring(usname.lastIndexOf('.') + 1); - } - if (ns.kind == Namespace.KIND_PACKAGE) { - if (!pkg.equals(ignorePackage)) { - if (!pkg.equals("__AS3__.vec")) { //Automatic import - imports.add(newimport); - } - } - } - if (ns.kind == Namespace.KIND_NAMESPACE) { - if (!usname.equals("*")) { - /*if (!uses.contains(usname)) { - uses.add(usname); - }*/ - if (!pkg.equals(ignorePackage)) { - imports.add(newimport); - } - } - } - } - return true; - } - } - return false; - } - - private void parseImportsUsagesFromNS(ABC abc, List imports, List uses, int namespace_index, String ignorePackage, String name) { - Namespace ns = abc.constants.getNamespace(namespace_index); - if (name.isEmpty()) { - name = "*"; - } - String newimport = ns.getName(abc.constants, false); - if (parseUsagesFromNS(abc, imports, uses, namespace_index, ignorePackage, name)) { - return; - } else if ((ns.kind != Namespace.KIND_PACKAGE) && (ns.kind != Namespace.KIND_PACKAGE_INTERNAL)) { - return; - } - if (newimport == null) { - newimport = ""; - } - //if (!newimport.equals("")) { - newimport += "." + name; - if (newimport.contains(":")) { - return; - } - if (!imports.contains(newimport)) { - String pkg = newimport.substring(0, newimport.lastIndexOf('.')); - if (pkg.equals("__AS3__.vec")) { //special case - is imported always - return; - } - if (!pkg.equals(ignorePackage)) { - imports.add(newimport); - } - } - //} - } - - private void parseUsagesFromMultiname(ABC abc, List imports, List uses, Multiname m, String ignorePackage, List fullyQualifiedNames) { - if (m != null) { - if (m.kind == Multiname.TYPENAME) { - if (m.qname_index != 0) { - parseUsagesFromMultiname(abc, imports, uses, abc.constants.getMultiname(m.qname_index), ignorePackage, fullyQualifiedNames); - } - for (Integer i : m.params) { - if (i != 0) { - parseUsagesFromMultiname(abc, imports, uses, abc.constants.getMultiname(i), ignorePackage, fullyQualifiedNames); - } - } - return; - } - Namespace ns = m.getNamespace(abc.constants); - String name = m.getName(abc.constants, fullyQualifiedNames, false); - NamespaceSet nss = m.getNamespaceSet(abc.constants); - if (ns != null) { - parseUsagesFromNS(abc, imports, uses, m.namespace_index, ignorePackage, name); - } - if (nss != null) { - if (nss.namespaces.length == 1) { - parseUsagesFromNS(abc, imports, uses, nss.namespaces[0], ignorePackage, name); - } else { - for (int n : nss.namespaces) { - parseUsagesFromNS(abc, imports, uses, n, ignorePackage, ""); - } - } - } - } - } - - private void parseImportsUsagesFromMultiname(ABC abc, List imports, List uses, Multiname m, String ignorePackage, List fullyQualifiedNames) { - if (m != null) { - if (m.kind == Multiname.TYPENAME) { - if (m.qname_index != 0) { - parseImportsUsagesFromMultiname(abc, imports, uses, abc.constants.getMultiname(m.qname_index), ignorePackage, fullyQualifiedNames); - } - for (Integer i : m.params) { - if (i != 0) { - parseImportsUsagesFromMultiname(abc, imports, uses, abc.constants.getMultiname(i), ignorePackage, fullyQualifiedNames); - } - } - return; - } - Namespace ns = m.getNamespace(abc.constants); - String name = m.getName(abc.constants, fullyQualifiedNames, false); - NamespaceSet nss = m.getNamespaceSet(abc.constants); - if (ns != null) { - parseImportsUsagesFromNS(abc, imports, uses, m.namespace_index, ignorePackage, name); - } - if (nss != null) { - for (int n : nss.namespaces) { - parseImportsUsagesFromNS(abc, imports, uses, n, ignorePackage, nss.namespaces.length > 1 ? "" : name); - } - } - } - } - - private void parseImportsUsagesFromMethodInfo(ABC abc, int method_index, List imports, List uses, String ignorePackage, List fullyQualifiedNames, List visitedMethods) { - if ((method_index < 0) || (method_index >= abc.method_info.size())) { - return; - } - visitedMethods.add(method_index); - if (abc.method_info.get(method_index).ret_type != 0) { - parseImportsUsagesFromMultiname(abc, imports, uses, abc.constants.getMultiname(abc.method_info.get(method_index).ret_type), ignorePackage, fullyQualifiedNames); - } - for (int t : abc.method_info.get(method_index).param_types) { - if (t != 0) { - parseImportsUsagesFromMultiname(abc, imports, uses, abc.constants.getMultiname(t), ignorePackage, fullyQualifiedNames); - } - } - MethodBody body = abc.findBody(method_index); - if (body != null) { - parseImportsUsagesFromTraits(abc, body.traits, imports, uses, ignorePackage, fullyQualifiedNames); - for (ABCException ex : body.exceptions) { - parseImportsUsagesFromMultiname(abc, imports, uses, abc.constants.getMultiname(ex.type_index), ignorePackage, fullyQualifiedNames); - } - for (AVM2Instruction ins : body.getCode().code) { - if (ins.definition instanceof NewFunctionIns) { - if (ins.operands[0] != method_index) { - if (!visitedMethods.contains(ins.operands[0])) { - parseImportsUsagesFromMethodInfo(abc, ins.operands[0], imports, uses, ignorePackage, fullyQualifiedNames, visitedMethods); - } - } - } - if ((ins.definition instanceof FindPropertyStrictIns) - || (ins.definition instanceof FindPropertyIns) - || (ins.definition instanceof GetLexIns) - || (ins.definition instanceof CoerceIns) - || (ins.definition instanceof AsTypeIns)) { - int m = ins.operands[0]; - if (m != 0) { - parseImportsUsagesFromMultiname(abc, imports, uses, abc.constants.getMultiname(m), ignorePackage, fullyQualifiedNames); - } - } else { - for (int k = 0; k < ins.definition.operands.length; k++) { - - if (ins.definition.operands[k] == AVM2Code.DAT_MULTINAME_INDEX) { - int multinameIndex = ins.operands[k]; - parseUsagesFromMultiname(abc, imports, uses, abc.constants.getMultiname(multinameIndex), ignorePackage, fullyQualifiedNames); - } - } - } - } - } - } - - private void parseImportsUsagesFromTraits(ABC abc, Traits ts, List imports, List uses, String ignorePackage, List fullyQualifiedNames) { - for (Trait t : ts.traits) { - parseImportsUsagesFromTrait(abc, t, imports, uses, ignorePackage, fullyQualifiedNames); - } - } - - private void parseImportsUsagesFromTrait(ABC abc, Trait t, List imports, List uses, String ignorePackage, List fullyQualifiedNames) { - if (t instanceof TraitMethodGetterSetter) { - TraitMethodGetterSetter tm = (TraitMethodGetterSetter) t; - parseImportsUsagesFromMultiname(abc, imports, uses, abc.constants.getMultiname(tm.name_index), ignorePackage, fullyQualifiedNames); - if (tm.method_info != 0) { - parseImportsUsagesFromMethodInfo(abc, tm.method_info, imports, uses, ignorePackage, fullyQualifiedNames, new ArrayList()); - } - } - parseImportsUsagesFromMultiname(abc, imports, uses, t.getName(abc), ignorePackage, fullyQualifiedNames); - if (t instanceof TraitSlotConst) { - TraitSlotConst ts = (TraitSlotConst) t; - parseImportsUsagesFromMultiname(abc, imports, uses, abc.constants.getMultiname(ts.name_index), ignorePackage, fullyQualifiedNames); - parseImportsUsagesFromMultiname(abc, imports, uses, abc.constants.getMultiname(ts.type_index), ignorePackage, fullyQualifiedNames); - } - } - - private List getImportsUsages(ABC abc, List imports, List uses, List fullyQualifiedNames) { - //constructor - - String packageName = abc.instance_info.get(class_info).getName(abc.constants).getNamespace(abc.constants).getName(abc.constants, false); //assume not null name - - parseImportsUsagesFromMultiname(abc, imports, uses, abc.constants.getMultiname(abc.instance_info.get(class_info).name_index), packageName, fullyQualifiedNames); - - if (abc.instance_info.get(class_info).super_index > 0) { - parseImportsUsagesFromMultiname(abc, imports, uses, abc.constants.getMultiname(abc.instance_info.get(class_info).super_index), packageName, fullyQualifiedNames); - } - for (int i : abc.instance_info.get(class_info).interfaces) { - parseImportsUsagesFromMultiname(abc, imports, uses, abc.constants.getMultiname(i), packageName, fullyQualifiedNames); - } - - //static - parseImportsUsagesFromTraits(abc, abc.class_info.get(class_info).static_traits, imports, uses, packageName, fullyQualifiedNames); - - //static initializer - parseImportsUsagesFromMethodInfo(abc, abc.class_info.get(class_info).cinit_index, imports, uses, packageName, fullyQualifiedNames, new ArrayList()); - - //instance - parseImportsUsagesFromTraits(abc, abc.instance_info.get(class_info).instance_traits, imports, uses, packageName, fullyQualifiedNames); - - //instance initializer - parseImportsUsagesFromMethodInfo(abc, abc.instance_info.get(class_info).iinit_index, imports, uses, packageName, fullyQualifiedNames, new ArrayList()); - return imports; - } - - @Override - public GraphTextWriter toStringHeader(Trait parent, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, GraphTextWriter writer, List fullyQualifiedNames, boolean parallel) { - abc.instance_info.get(class_info).getClassHeaderStr(writer, abc, fullyQualifiedNames, false); - return writer; - } - - @Override - public void convertHeader(Trait parent, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List fullyQualifiedNames, boolean parallel) { - } - - @Override - public GraphTextWriter toString(Trait parent, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, GraphTextWriter writer, List fullyQualifiedNames, boolean parallel) throws InterruptedException { - - String packageName = abc.instance_info.get(class_info).getName(abc.constants).getNamespace(abc.constants).getName(abc.constants, false); //assume not null name - List namesInThisPackage = new ArrayList<>(); - for (ABCContainerTag tag : abc.getAbcTags()) { - for (ScriptInfo si : tag.getABC().script_info) { - for (Trait t : si.traits.traits) { - ClassPath classPath = t.getPath(tag.getABC()); - String pkg = classPath.packageStr == null ? "" : classPath.packageStr; - if (pkg.equals(packageName)) { - namesInThisPackage.add(classPath.className); - } - } - } - } - - //imports - List imports = new ArrayList<>(); - List uses = new ArrayList<>(); - getImportsUsages(abc, imports, uses, new ArrayList()); - - fullyQualifiedNames = new ArrayList<>(); - - List importnames = new ArrayList<>(); - importnames.addAll(namesInThisPackage); - for (String ipath : imports) { - String name = ipath; - String pkg = ""; - if (name.contains(".")) { - pkg = name.substring(0, name.lastIndexOf('.')); - name = name.substring(name.lastIndexOf('.') + 1); - } - if (importnames.contains(name) || ((!pkg.isEmpty()) && isBuiltInClass(name))) { - fullyQualifiedNames.add(name); - } else { - importnames.add(name); - } - } - /*List imports2 = new ArrayList(); - for (String path : imports) { - String name = path; - String pkg = ""; - if (name.contains(".")) { - pkg = name.substring(0, name.lastIndexOf(".")); - name = name.substring(name.lastIndexOf(".") + 1); - } - - if ((!packageName.equals(pkg)) && (!fullyQualifiedNames.contains(name))) { - imports2.add(path); - } - } - imports = imports2;*/ - - for (int i = 0; i < imports.size(); i++) { - String imp = imports.get(i); - String pkg = imp.substring(0, imp.lastIndexOf('.')); - String name = imp.substring(imp.lastIndexOf('.') + 1); - if (name.equals("*")) { - continue; - } - if (imports.contains(pkg + ".*")) { - imports.remove(i); - i--; - } - } - - boolean hasImport = false; - for (String imp : imports) { - if (!imp.startsWith(".")) { - writer.appendNoHilight("import " + imp + ";").newLine(); - hasImport = true; - } - } - if (hasImport) { - writer.newLine(); - } - for (String us : uses) { - writer.appendNoHilight("use namespace " + us + ";").newLine(); - } - if (uses.size() > 0) { - writer.newLine(); - } - - writer.startClass(class_info); - - //class header - abc.instance_info.get(class_info).getClassHeaderStr(writer, abc, fullyQualifiedNames, false); - writer.startBlock(); - - //static variables & constants - abc.class_info.get(class_info).static_traits.toString(new Class[]{TraitSlotConst.class}, this, path +/*packageName +*/ "/" + abc.instance_info.get(class_info).getName(abc.constants).getName(abc.constants, fullyQualifiedNames, false), abc, true, exportMode, false, scriptIndex, class_info, writer, fullyQualifiedNames, parallel); - - //static initializer - int bodyIndex = abc.findBodyIndex(abc.class_info.get(class_info).cinit_index); - if (bodyIndex != -1) { - if (!classInitializerIsEmpty) { - writer.startTrait(abc.class_info.get(class_info).static_traits.traits.size() + abc.instance_info.get(class_info).instance_traits.traits.size() + 1); - writer.startMethod(abc.class_info.get(class_info).cinit_index); - writer.startBlock(); - abc.bodies.get(bodyIndex).toString(path +/*packageName +*/ "/" + abc.instance_info.get(class_info).getName(abc.constants).getName(abc.constants, fullyQualifiedNames, false) + ".staticinitializer", exportMode, abc, this, abc.constants, abc.method_info, writer, fullyQualifiedNames); - writer.endBlock(); - writer.endMethod(); - writer.endTrait(); - writer.newLine(); - } - } else { - //"/*classInitializer*/"; - } - - //instance variables - abc.instance_info.get(class_info).instance_traits.toString(new Class[]{TraitSlotConst.class}, this, path +/*packageName +*/ "/" + abc.instance_info.get(class_info).getName(abc.constants).getName(abc.constants, fullyQualifiedNames, false), abc, false, exportMode, false, scriptIndex, class_info, writer, fullyQualifiedNames, parallel); - - //instance initializer - constructor - if (!abc.instance_info.get(class_info).isInterface()) { - String modifier = ""; - Multiname m = abc.constants.getMultiname(abc.instance_info.get(class_info).name_index); - if (m != null) { - Namespace ns = m.getNamespace(abc.constants); - if (ns != null) { - modifier = ns.getPrefix(abc) + " "; - if (modifier.equals(" ")) { - modifier = ""; - } - if (modifier.startsWith("private")) { //cannot have private constuctor - modifier = ""; - } - } - } - - writer.newLine(); - writer.startTrait(abc.class_info.get(class_info).static_traits.traits.size() + abc.instance_info.get(class_info).instance_traits.traits.size()); - writer.startMethod(abc.instance_info.get(class_info).iinit_index); - writer.appendNoHilight(modifier); - writer.appendNoHilight("function "); - writer.appendNoHilight(abc.constants.getMultiname(abc.instance_info.get(class_info).name_index).getName(abc.constants, new ArrayList()/*do not want full names here*/, false)); - writer.appendNoHilight("("); - bodyIndex = abc.findBodyIndex(abc.instance_info.get(class_info).iinit_index); - if (bodyIndex != -1) { - abc.method_info.get(abc.instance_info.get(class_info).iinit_index).getParamStr(writer, abc.constants, abc.bodies.get(bodyIndex), abc, fullyQualifiedNames); - } else { - abc.method_info.get(abc.instance_info.get(class_info).iinit_index).getParamStr(writer, abc.constants, null, abc, fullyQualifiedNames); - } - writer.appendNoHilight(")").startBlock(); - if (bodyIndex != -1) { - abc.bodies.get(bodyIndex).toString(path +/*packageName +*/ "/" + abc.instance_info.get(class_info).getName(abc.constants).getName(abc.constants, fullyQualifiedNames, false) + ".initializer", exportMode, abc, this, abc.constants, abc.method_info, writer, fullyQualifiedNames); - } - writer.endBlock().newLine(); - writer.endMethod(); - writer.endTrait(); - } - - //static methods - abc.class_info.get(class_info).static_traits.toString(new Class[]{TraitClass.class, TraitFunction.class, TraitMethodGetterSetter.class}, this, path +/*packageName +*/ "/" + abc.instance_info.get(class_info).getName(abc.constants).getName(abc.constants, fullyQualifiedNames, false), abc, true, exportMode, false, scriptIndex, class_info, writer, fullyQualifiedNames, parallel); - - //instance methods - abc.instance_info.get(class_info).instance_traits.toString(new Class[]{TraitClass.class, TraitFunction.class, TraitMethodGetterSetter.class}, this, path +/*packageName +*/ "/" + abc.instance_info.get(class_info).getName(abc.constants).getName(abc.constants, fullyQualifiedNames, false), abc, false, exportMode, false, scriptIndex, class_info, writer, fullyQualifiedNames, parallel); - - writer.endBlock(); // class - writer.endClass(); - writer.newLine(); - return writer; - } - - @Override - public void convert(Trait parent, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List fullyQualifiedNames, boolean parallel) throws InterruptedException { - - fullyQualifiedNames = new ArrayList<>(); - - int bodyIndex = abc.findBodyIndex(abc.class_info.get(class_info).cinit_index); - if (bodyIndex != -1) { - writer.mark(); - abc.bodies.get(bodyIndex).convert(path +/*packageName +*/ "/" + abc.instance_info.get(class_info).getName(abc.constants).getName(abc.constants, fullyQualifiedNames, false) + ".staticinitializer", exportMode, true, scriptIndex, class_info, abc, this, abc.constants, abc.method_info, new ScopeStack(), true, writer, fullyQualifiedNames, abc.class_info.get(class_info).static_traits, true); - classInitializerIsEmpty = !writer.getMark(); - } - - //constructor - if (!abc.instance_info.get(class_info).isInterface()) { - bodyIndex = abc.findBodyIndex(abc.instance_info.get(class_info).iinit_index); - if (bodyIndex != -1) { - abc.bodies.get(bodyIndex).convert(path +/*packageName +*/ "/" + abc.instance_info.get(class_info).getName(abc.constants).getName(abc.constants, fullyQualifiedNames, false) + ".initializer", exportMode, false, scriptIndex, class_info, abc, this, abc.constants, abc.method_info, new ScopeStack(), false, writer, fullyQualifiedNames, abc.instance_info.get(class_info).instance_traits, true); - } - } - - //static variables,constants & methods - abc.class_info.get(class_info).static_traits.convert(this, path +/*packageName +*/ "/" + abc.instance_info.get(class_info).getName(abc.constants).getName(abc.constants, fullyQualifiedNames, false), abc, true, exportMode, false, scriptIndex, class_info, writer, fullyQualifiedNames, parallel); - - abc.instance_info.get(class_info).instance_traits.convert(this, path +/*packageName +*/ "/" + abc.instance_info.get(class_info).getName(abc.constants).getName(abc.constants, fullyQualifiedNames, false), abc, false, exportMode, false, scriptIndex, class_info, writer, fullyQualifiedNames, parallel); - } - - @Override - public Multiname getName(ABC abc) { - return abc.constants.getMultiname(abc.instance_info.get(class_info).name_index); - } - - @Override - public int removeTraps(int scriptIndex, int classIndex, boolean isStatic, ABC abc, String path) throws InterruptedException { - int iInitializer = abc.findBodyIndex(abc.instance_info.get(class_info).iinit_index); - int ret = 0; - if (iInitializer != -1) { - ret += abc.bodies.get(iInitializer).removeTraps(abc.constants, abc, this, scriptIndex, class_info, false, path); - } - int sInitializer = abc.findBodyIndex(abc.class_info.get(class_info).cinit_index); - if (sInitializer != -1) { - ret += abc.bodies.get(sInitializer).removeTraps(abc.constants, abc, this, scriptIndex, class_info, true, path); - } - ret += abc.instance_info.get(class_info).instance_traits.removeTraps(scriptIndex, class_info, false, abc, path); - ret += abc.class_info.get(class_info).static_traits.removeTraps(scriptIndex, class_info, true, abc, path); - return ret; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.types.traits; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.ClassPath; +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.construction.NewFunctionIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other.FindPropertyIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other.FindPropertyStrictIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetLexIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.types.AsTypeIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.types.CoerceIns; +import com.jpexs.decompiler.flash.abc.types.ABCException; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.Multiname; +import com.jpexs.decompiler.flash.abc.types.Namespace; +import com.jpexs.decompiler.flash.abc.types.NamespaceSet; +import com.jpexs.decompiler.flash.abc.types.ScriptInfo; +import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; +import com.jpexs.decompiler.flash.helpers.GraphTextWriter; +import com.jpexs.decompiler.flash.helpers.NulWriter; +import com.jpexs.decompiler.flash.tags.ABCContainerTag; +import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.helpers.Helper; +import java.util.ArrayList; +import java.util.List; + +public class TraitClass extends Trait implements TraitWithSlot { + + public int slot_id; + + public int class_info; + + private static final String[] builtInClasses = {"ArgumentError", "arguments", "Array", "Boolean", "Class", "Date", "DefinitionError", "Error", "EvalError", "Function", "int", "JSON", "Math", "Namespace", "Number", "Object", "QName", "RangeError", "ReferenceError", "RegExp", "SecurityError", "String", "SyntaxError", "TypeError", "uint", "URIError", "VerifyError", "XML", "XMLList"}; + + private boolean classInitializerIsEmpty; + + @Override + public void delete(ABC abc, boolean d) { + abc.class_info.get(class_info).deleted = d; + abc.instance_info.get(class_info).deleted = d; + + abc.class_info.get(class_info).static_traits.delete(abc, d); + abc.method_info.get(abc.class_info.get(class_info).cinit_index).delete(abc, d); + + abc.instance_info.get(class_info).instance_traits.delete(abc, d); + abc.method_info.get(abc.instance_info.get(class_info).iinit_index).delete(abc, d); + + int protectedNS = abc.instance_info.get(class_info).protectedNS; + if (protectedNS != 0) { + abc.constants.constant_namespace.get(protectedNS).deleted = d; + } + + abc.constants.constant_multiname.get(name_index).deleted = d; + } + + @Override + public int getSlotIndex() { + return slot_id; + } + + private static boolean isBuiltInClass(String name) { + for (String g : builtInClasses) { + if (g.equals(name)) { + return true; + } + } + return false; + } + + @Override + public String toString(ABC abc, List fullyQualifiedNames) { + return "Class " + abc.constants.getMultiname(name_index).toString(abc.constants, fullyQualifiedNames) + " slot=" + slot_id + " class_info=" + class_info + " metadata=" + Helper.intArrToString(metadata); + } + + private boolean parseUsagesFromNS(ABC abc, List imports, List uses, int namespace_index, String ignorePackage, String name) { + Namespace ns = abc.constants.getNamespace(namespace_index); + if (name.isEmpty()) { + name = "*"; + } + String newimport = ns.getName(abc.constants, ns.kind == Namespace.KIND_NAMESPACE); + /*if ((ns.kind != Namespace.KIND_PACKAGE) + && (ns.kind != Namespace.KIND_NAMESPACE) + && (ns.kind != Namespace.KIND_STATIC_PROTECTED)) { + return false; + }*/ + /*if (ns.kind == Namespace.KIND_NAMESPACE)*/ { + String oldimport = newimport; + newimport = null; + for (ABCContainerTag abcTag : abc.getAbcTags()) { + String newname = abcTag.getABC().nsValueToName(oldimport); + if (newname.equals("-")) { + return true; + } + if (!newname.isEmpty()) { + newimport = newname; + break; + } + } + if (newimport == null) { + newimport = oldimport; + newimport += "." + name; + } + if (newimport != null && newimport.isEmpty()) { + newimport = null; + } + if (newimport != null) { + /* if(ns.kind==Namespace.KIND_PACKAGE){ + newimport+=".*"; + }*/ + + if (!imports.contains(newimport)) { + if (newimport.contains(":")) { + return true; + } + String pkg = ""; + if (newimport.contains(".")) { + pkg = newimport.substring(0, newimport.lastIndexOf('.')); + } + String usname = newimport; + if (usname.contains(".")) { + usname = usname.substring(usname.lastIndexOf('.') + 1); + } + if (ns.kind == Namespace.KIND_PACKAGE) { + if (!pkg.equals(ignorePackage)) { + if (!pkg.equals("__AS3__.vec")) { //Automatic import + imports.add(newimport); + } + } + } + if (ns.kind == Namespace.KIND_NAMESPACE) { + if (!usname.equals("*")) { + /*if (!uses.contains(usname)) { + uses.add(usname); + }*/ + if (!pkg.equals(ignorePackage)) { + imports.add(newimport); + } + } + } + } + return true; + } + } + return false; + } + + private void parseImportsUsagesFromNS(ABC abc, List imports, List uses, int namespace_index, String ignorePackage, String name) { + Namespace ns = abc.constants.getNamespace(namespace_index); + if (name.isEmpty()) { + name = "*"; + } + String newimport = ns.getName(abc.constants, false); + if (parseUsagesFromNS(abc, imports, uses, namespace_index, ignorePackage, name)) { + return; + } else if ((ns.kind != Namespace.KIND_PACKAGE) && (ns.kind != Namespace.KIND_PACKAGE_INTERNAL)) { + return; + } + if (newimport == null) { + newimport = ""; + } + //if (!newimport.equals("")) { + newimport += "." + name; + if (newimport.contains(":")) { + return; + } + if (!imports.contains(newimport)) { + String pkg = newimport.substring(0, newimport.lastIndexOf('.')); + if (pkg.equals("__AS3__.vec")) { //special case - is imported always + return; + } + if (!pkg.equals(ignorePackage)) { + imports.add(newimport); + } + } + //} + } + + private void parseUsagesFromMultiname(ABC abc, List imports, List uses, Multiname m, String ignorePackage, List fullyQualifiedNames) { + if (m != null) { + if (m.kind == Multiname.TYPENAME) { + if (m.qname_index != 0) { + parseUsagesFromMultiname(abc, imports, uses, abc.constants.getMultiname(m.qname_index), ignorePackage, fullyQualifiedNames); + } + for (Integer i : m.params) { + if (i != 0) { + parseUsagesFromMultiname(abc, imports, uses, abc.constants.getMultiname(i), ignorePackage, fullyQualifiedNames); + } + } + return; + } + Namespace ns = m.getNamespace(abc.constants); + String name = m.getName(abc.constants, fullyQualifiedNames, false); + NamespaceSet nss = m.getNamespaceSet(abc.constants); + if (ns != null) { + parseUsagesFromNS(abc, imports, uses, m.namespace_index, ignorePackage, name); + } + if (nss != null) { + if (nss.namespaces.length == 1) { + parseUsagesFromNS(abc, imports, uses, nss.namespaces[0], ignorePackage, name); + } else { + for (int n : nss.namespaces) { + parseUsagesFromNS(abc, imports, uses, n, ignorePackage, ""); + } + } + } + } + } + + private void parseImportsUsagesFromMultiname(ABC abc, List imports, List uses, Multiname m, String ignorePackage, List fullyQualifiedNames) { + if (m != null) { + if (m.kind == Multiname.TYPENAME) { + if (m.qname_index != 0) { + parseImportsUsagesFromMultiname(abc, imports, uses, abc.constants.getMultiname(m.qname_index), ignorePackage, fullyQualifiedNames); + } + for (Integer i : m.params) { + if (i != 0) { + parseImportsUsagesFromMultiname(abc, imports, uses, abc.constants.getMultiname(i), ignorePackage, fullyQualifiedNames); + } + } + return; + } + Namespace ns = m.getNamespace(abc.constants); + String name = m.getName(abc.constants, fullyQualifiedNames, false); + NamespaceSet nss = m.getNamespaceSet(abc.constants); + if (ns != null) { + parseImportsUsagesFromNS(abc, imports, uses, m.namespace_index, ignorePackage, name); + } + if (nss != null) { + for (int n : nss.namespaces) { + parseImportsUsagesFromNS(abc, imports, uses, n, ignorePackage, nss.namespaces.length > 1 ? "" : name); + } + } + } + } + + private void parseImportsUsagesFromMethodInfo(ABC abc, int method_index, List imports, List uses, String ignorePackage, List fullyQualifiedNames, List visitedMethods) { + if ((method_index < 0) || (method_index >= abc.method_info.size())) { + return; + } + visitedMethods.add(method_index); + if (abc.method_info.get(method_index).ret_type != 0) { + parseImportsUsagesFromMultiname(abc, imports, uses, abc.constants.getMultiname(abc.method_info.get(method_index).ret_type), ignorePackage, fullyQualifiedNames); + } + for (int t : abc.method_info.get(method_index).param_types) { + if (t != 0) { + parseImportsUsagesFromMultiname(abc, imports, uses, abc.constants.getMultiname(t), ignorePackage, fullyQualifiedNames); + } + } + MethodBody body = abc.findBody(method_index); + if (body != null) { + parseImportsUsagesFromTraits(abc, body.traits, imports, uses, ignorePackage, fullyQualifiedNames); + for (ABCException ex : body.exceptions) { + parseImportsUsagesFromMultiname(abc, imports, uses, abc.constants.getMultiname(ex.type_index), ignorePackage, fullyQualifiedNames); + } + for (AVM2Instruction ins : body.getCode().code) { + if (ins.definition instanceof NewFunctionIns) { + if (ins.operands[0] != method_index) { + if (!visitedMethods.contains(ins.operands[0])) { + parseImportsUsagesFromMethodInfo(abc, ins.operands[0], imports, uses, ignorePackage, fullyQualifiedNames, visitedMethods); + } + } + } + if ((ins.definition instanceof FindPropertyStrictIns) + || (ins.definition instanceof FindPropertyIns) + || (ins.definition instanceof GetLexIns) + || (ins.definition instanceof CoerceIns) + || (ins.definition instanceof AsTypeIns)) { + int m = ins.operands[0]; + if (m != 0) { + parseImportsUsagesFromMultiname(abc, imports, uses, abc.constants.getMultiname(m), ignorePackage, fullyQualifiedNames); + } + } else { + for (int k = 0; k < ins.definition.operands.length; k++) { + + if (ins.definition.operands[k] == AVM2Code.DAT_MULTINAME_INDEX) { + int multinameIndex = ins.operands[k]; + parseUsagesFromMultiname(abc, imports, uses, abc.constants.getMultiname(multinameIndex), ignorePackage, fullyQualifiedNames); + } + } + } + } + } + } + + private void parseImportsUsagesFromTraits(ABC abc, Traits ts, List imports, List uses, String ignorePackage, List fullyQualifiedNames) { + for (Trait t : ts.traits) { + parseImportsUsagesFromTrait(abc, t, imports, uses, ignorePackage, fullyQualifiedNames); + } + } + + private void parseImportsUsagesFromTrait(ABC abc, Trait t, List imports, List uses, String ignorePackage, List fullyQualifiedNames) { + if (t instanceof TraitMethodGetterSetter) { + TraitMethodGetterSetter tm = (TraitMethodGetterSetter) t; + parseImportsUsagesFromMultiname(abc, imports, uses, abc.constants.getMultiname(tm.name_index), ignorePackage, fullyQualifiedNames); + if (tm.method_info != 0) { + parseImportsUsagesFromMethodInfo(abc, tm.method_info, imports, uses, ignorePackage, fullyQualifiedNames, new ArrayList()); + } + } + parseImportsUsagesFromMultiname(abc, imports, uses, t.getName(abc), ignorePackage, fullyQualifiedNames); + if (t instanceof TraitSlotConst) { + TraitSlotConst ts = (TraitSlotConst) t; + parseImportsUsagesFromMultiname(abc, imports, uses, abc.constants.getMultiname(ts.name_index), ignorePackage, fullyQualifiedNames); + parseImportsUsagesFromMultiname(abc, imports, uses, abc.constants.getMultiname(ts.type_index), ignorePackage, fullyQualifiedNames); + } + } + + private List getImportsUsages(ABC abc, List imports, List uses, List fullyQualifiedNames) { + //constructor + + String packageName = abc.instance_info.get(class_info).getName(abc.constants).getNamespace(abc.constants).getName(abc.constants, false); //assume not null name + + parseImportsUsagesFromMultiname(abc, imports, uses, abc.constants.getMultiname(abc.instance_info.get(class_info).name_index), packageName, fullyQualifiedNames); + + if (abc.instance_info.get(class_info).super_index > 0) { + parseImportsUsagesFromMultiname(abc, imports, uses, abc.constants.getMultiname(abc.instance_info.get(class_info).super_index), packageName, fullyQualifiedNames); + } + for (int i : abc.instance_info.get(class_info).interfaces) { + parseImportsUsagesFromMultiname(abc, imports, uses, abc.constants.getMultiname(i), packageName, fullyQualifiedNames); + } + + //static + parseImportsUsagesFromTraits(abc, abc.class_info.get(class_info).static_traits, imports, uses, packageName, fullyQualifiedNames); + + //static initializer + parseImportsUsagesFromMethodInfo(abc, abc.class_info.get(class_info).cinit_index, imports, uses, packageName, fullyQualifiedNames, new ArrayList()); + + //instance + parseImportsUsagesFromTraits(abc, abc.instance_info.get(class_info).instance_traits, imports, uses, packageName, fullyQualifiedNames); + + //instance initializer + parseImportsUsagesFromMethodInfo(abc, abc.instance_info.get(class_info).iinit_index, imports, uses, packageName, fullyQualifiedNames, new ArrayList()); + return imports; + } + + @Override + public GraphTextWriter toStringHeader(Trait parent, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, GraphTextWriter writer, List fullyQualifiedNames, boolean parallel) { + abc.instance_info.get(class_info).getClassHeaderStr(writer, abc, fullyQualifiedNames, false); + return writer; + } + + @Override + public void convertHeader(Trait parent, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List fullyQualifiedNames, boolean parallel) { + } + + @Override + public GraphTextWriter toString(Trait parent, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, GraphTextWriter writer, List fullyQualifiedNames, boolean parallel) throws InterruptedException { + + String packageName = abc.instance_info.get(class_info).getName(abc.constants).getNamespace(abc.constants).getName(abc.constants, false); //assume not null name + List namesInThisPackage = new ArrayList<>(); + for (ABCContainerTag tag : abc.getAbcTags()) { + for (ScriptInfo si : tag.getABC().script_info) { + for (Trait t : si.traits.traits) { + ClassPath classPath = t.getPath(tag.getABC()); + String pkg = classPath.packageStr == null ? "" : classPath.packageStr; + if (pkg.equals(packageName)) { + namesInThisPackage.add(classPath.className); + } + } + } + } + + //imports + List imports = new ArrayList<>(); + List uses = new ArrayList<>(); + getImportsUsages(abc, imports, uses, new ArrayList()); + + fullyQualifiedNames = new ArrayList<>(); + + List importnames = new ArrayList<>(); + importnames.addAll(namesInThisPackage); + for (String ipath : imports) { + String name = ipath; + String pkg = ""; + if (name.contains(".")) { + pkg = name.substring(0, name.lastIndexOf('.')); + name = name.substring(name.lastIndexOf('.') + 1); + } + if (importnames.contains(name) || ((!pkg.isEmpty()) && isBuiltInClass(name))) { + fullyQualifiedNames.add(name); + } else { + importnames.add(name); + } + } + /*List imports2 = new ArrayList(); + for (String path : imports) { + String name = path; + String pkg = ""; + if (name.contains(".")) { + pkg = name.substring(0, name.lastIndexOf(".")); + name = name.substring(name.lastIndexOf(".") + 1); + } + + if ((!packageName.equals(pkg)) && (!fullyQualifiedNames.contains(name))) { + imports2.add(path); + } + } + imports = imports2;*/ + + for (int i = 0; i < imports.size(); i++) { + String imp = imports.get(i); + String pkg = imp.substring(0, imp.lastIndexOf('.')); + String name = imp.substring(imp.lastIndexOf('.') + 1); + if (name.equals("*")) { + continue; + } + if (imports.contains(pkg + ".*")) { + imports.remove(i); + i--; + } + } + + boolean hasImport = false; + for (String imp : imports) { + if (!imp.startsWith(".")) { + writer.appendNoHilight("import " + imp + ";").newLine(); + hasImport = true; + } + } + if (hasImport) { + writer.newLine(); + } + for (String us : uses) { + writer.appendNoHilight("use namespace " + us + ";").newLine(); + } + if (uses.size() > 0) { + writer.newLine(); + } + + writer.startClass(class_info); + + //class header + abc.instance_info.get(class_info).getClassHeaderStr(writer, abc, fullyQualifiedNames, false); + writer.startBlock(); + + //static variables & constants + abc.class_info.get(class_info).static_traits.toString(new Class[]{TraitSlotConst.class}, this, path +/*packageName +*/ "/" + abc.instance_info.get(class_info).getName(abc.constants).getName(abc.constants, fullyQualifiedNames, false), abc, true, exportMode, false, scriptIndex, class_info, writer, fullyQualifiedNames, parallel); + + //static initializer + int bodyIndex = abc.findBodyIndex(abc.class_info.get(class_info).cinit_index); + if (bodyIndex != -1) { + if (!classInitializerIsEmpty) { + writer.startTrait(abc.class_info.get(class_info).static_traits.traits.size() + abc.instance_info.get(class_info).instance_traits.traits.size() + 1); + writer.startMethod(abc.class_info.get(class_info).cinit_index); + writer.startBlock(); + abc.bodies.get(bodyIndex).toString(path +/*packageName +*/ "/" + abc.instance_info.get(class_info).getName(abc.constants).getName(abc.constants, fullyQualifiedNames, false) + ".staticinitializer", exportMode, abc, this, abc.constants, abc.method_info, writer, fullyQualifiedNames); + writer.endBlock(); + writer.endMethod(); + writer.endTrait(); + writer.newLine(); + } + } else { + //"/*classInitializer*/"; + } + + //instance variables + abc.instance_info.get(class_info).instance_traits.toString(new Class[]{TraitSlotConst.class}, this, path +/*packageName +*/ "/" + abc.instance_info.get(class_info).getName(abc.constants).getName(abc.constants, fullyQualifiedNames, false), abc, false, exportMode, false, scriptIndex, class_info, writer, fullyQualifiedNames, parallel); + + //instance initializer - constructor + if (!abc.instance_info.get(class_info).isInterface()) { + String modifier = ""; + Multiname m = abc.constants.getMultiname(abc.instance_info.get(class_info).name_index); + if (m != null) { + Namespace ns = m.getNamespace(abc.constants); + if (ns != null) { + modifier = ns.getPrefix(abc) + " "; + if (modifier.equals(" ")) { + modifier = ""; + } + if (modifier.startsWith("private")) { //cannot have private constuctor + modifier = ""; + } + } + } + + writer.newLine(); + writer.startTrait(abc.class_info.get(class_info).static_traits.traits.size() + abc.instance_info.get(class_info).instance_traits.traits.size()); + writer.startMethod(abc.instance_info.get(class_info).iinit_index); + writer.appendNoHilight(modifier); + writer.appendNoHilight("function "); + writer.appendNoHilight(abc.constants.getMultiname(abc.instance_info.get(class_info).name_index).getName(abc.constants, new ArrayList()/*do not want full names here*/, false)); + writer.appendNoHilight("("); + bodyIndex = abc.findBodyIndex(abc.instance_info.get(class_info).iinit_index); + if (bodyIndex != -1) { + abc.method_info.get(abc.instance_info.get(class_info).iinit_index).getParamStr(writer, abc.constants, abc.bodies.get(bodyIndex), abc, fullyQualifiedNames); + } else { + abc.method_info.get(abc.instance_info.get(class_info).iinit_index).getParamStr(writer, abc.constants, null, abc, fullyQualifiedNames); + } + writer.appendNoHilight(")").startBlock(); + if (bodyIndex != -1) { + abc.bodies.get(bodyIndex).toString(path +/*packageName +*/ "/" + abc.instance_info.get(class_info).getName(abc.constants).getName(abc.constants, fullyQualifiedNames, false) + ".initializer", exportMode, abc, this, abc.constants, abc.method_info, writer, fullyQualifiedNames); + } + writer.endBlock().newLine(); + writer.endMethod(); + writer.endTrait(); + } + + //static methods + abc.class_info.get(class_info).static_traits.toString(new Class[]{TraitClass.class, TraitFunction.class, TraitMethodGetterSetter.class}, this, path +/*packageName +*/ "/" + abc.instance_info.get(class_info).getName(abc.constants).getName(abc.constants, fullyQualifiedNames, false), abc, true, exportMode, false, scriptIndex, class_info, writer, fullyQualifiedNames, parallel); + + //instance methods + abc.instance_info.get(class_info).instance_traits.toString(new Class[]{TraitClass.class, TraitFunction.class, TraitMethodGetterSetter.class}, this, path +/*packageName +*/ "/" + abc.instance_info.get(class_info).getName(abc.constants).getName(abc.constants, fullyQualifiedNames, false), abc, false, exportMode, false, scriptIndex, class_info, writer, fullyQualifiedNames, parallel); + + writer.endBlock(); // class + writer.endClass(); + writer.newLine(); + return writer; + } + + @Override + public void convert(Trait parent, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List fullyQualifiedNames, boolean parallel) throws InterruptedException { + + fullyQualifiedNames = new ArrayList<>(); + + int bodyIndex = abc.findBodyIndex(abc.class_info.get(class_info).cinit_index); + if (bodyIndex != -1) { + writer.mark(); + abc.bodies.get(bodyIndex).convert(path +/*packageName +*/ "/" + abc.instance_info.get(class_info).getName(abc.constants).getName(abc.constants, fullyQualifiedNames, false) + ".staticinitializer", exportMode, true, scriptIndex, class_info, abc, this, abc.constants, abc.method_info, new ScopeStack(), true, writer, fullyQualifiedNames, abc.class_info.get(class_info).static_traits, true); + classInitializerIsEmpty = !writer.getMark(); + } + + //constructor + if (!abc.instance_info.get(class_info).isInterface()) { + bodyIndex = abc.findBodyIndex(abc.instance_info.get(class_info).iinit_index); + if (bodyIndex != -1) { + abc.bodies.get(bodyIndex).convert(path +/*packageName +*/ "/" + abc.instance_info.get(class_info).getName(abc.constants).getName(abc.constants, fullyQualifiedNames, false) + ".initializer", exportMode, false, scriptIndex, class_info, abc, this, abc.constants, abc.method_info, new ScopeStack(), false, writer, fullyQualifiedNames, abc.instance_info.get(class_info).instance_traits, true); + } + } + + //static variables,constants & methods + abc.class_info.get(class_info).static_traits.convert(this, path +/*packageName +*/ "/" + abc.instance_info.get(class_info).getName(abc.constants).getName(abc.constants, fullyQualifiedNames, false), abc, true, exportMode, false, scriptIndex, class_info, writer, fullyQualifiedNames, parallel); + + abc.instance_info.get(class_info).instance_traits.convert(this, path +/*packageName +*/ "/" + abc.instance_info.get(class_info).getName(abc.constants).getName(abc.constants, fullyQualifiedNames, false), abc, false, exportMode, false, scriptIndex, class_info, writer, fullyQualifiedNames, parallel); + } + + @Override + public Multiname getName(ABC abc) { + return abc.constants.getMultiname(abc.instance_info.get(class_info).name_index); + } + + @Override + public int removeTraps(int scriptIndex, int classIndex, boolean isStatic, ABC abc, String path) throws InterruptedException { + int iInitializer = abc.findBodyIndex(abc.instance_info.get(class_info).iinit_index); + int ret = 0; + if (iInitializer != -1) { + ret += abc.bodies.get(iInitializer).removeTraps(abc.constants, abc, this, scriptIndex, class_info, false, path); + } + int sInitializer = abc.findBodyIndex(abc.class_info.get(class_info).cinit_index); + if (sInitializer != -1) { + ret += abc.bodies.get(sInitializer).removeTraps(abc.constants, abc, this, scriptIndex, class_info, true, path); + } + ret += abc.instance_info.get(class_info).instance_traits.removeTraps(scriptIndex, class_info, false, abc, path); + ret += abc.class_info.get(class_info).static_traits.removeTraps(scriptIndex, class_info, true, abc, path); + return ret; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/Traits.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/Traits.java index f1fd02df6..69d40bc0c 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/Traits.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/Traits.java @@ -1,216 +1,216 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.abc.types.traits; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.configuration.Configuration; -import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; -import com.jpexs.decompiler.flash.helpers.GraphTextWriter; -import com.jpexs.decompiler.flash.helpers.NulWriter; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.logging.Level; -import java.util.logging.Logger; - -public class Traits implements Serializable { - - public List traits; - - public Traits() { - traits = new ArrayList<>(); - } - - public Traits(int initialCapacity) { - traits = new ArrayList<>(initialCapacity); - } - - public void delete(ABC abc, boolean d) { - for (Trait t : traits) { - t.delete(abc, d); - } - } - - public int addTrait(Trait t) { - traits.add(t); - return traits.size() - 1; - } - - public int removeTraps(int scriptIndex, int classIndex, boolean isStatic, ABC abc, String path) throws InterruptedException { - int ret = 0; - for (Trait t : traits) { - ret += t.removeTraps(scriptIndex, classIndex, isStatic, abc, path); - } - return ret; - } - - @Override - public String toString() { - String s = ""; - for (int t = 0; t < traits.size(); t++) { - if (t > 0) { - s += "\r\n"; - } - s += traits.get(t).toString(); - } - return s; - } - - public String toString(ABC abc, List fullyQualifiedNames) { - String s = ""; - for (int t = 0; t < traits.size(); t++) { - if (t > 0) { - s += "\r\n"; - } - s += traits.get(t).toString(abc, fullyQualifiedNames); - } - return s; - } - - private class TraitConvertTask implements Callable { - - Trait trait; - - boolean makePackages; - - String path; - - ABC abc; - - boolean isStatic; - - ScriptExportMode exportMode; - - int scriptIndex; - - int classIndex; - - NulWriter writer; - - List fullyQualifiedNames; - - int traitIndex; - - boolean parallel; - - Trait parent; - - public TraitConvertTask(Trait trait, Trait parent, boolean makePackages, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List fullyQualifiedNames, int traitIndex, boolean parallel) { - this.trait = trait; - this.parent = parent; - this.makePackages = makePackages; - this.path = path; - this.abc = abc; - this.isStatic = isStatic; - this.exportMode = exportMode; - this.scriptIndex = scriptIndex; - this.classIndex = classIndex; - this.writer = writer; - this.fullyQualifiedNames = fullyQualifiedNames; - this.traitIndex = traitIndex; - this.parallel = parallel; - } - - @Override - public Void call() throws InterruptedException { - if (makePackages) { - trait.convertPackaged(parent, path, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, parallel); - } else { - trait.convert(parent, path, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, parallel); - } - return null; - } - } - - public GraphTextWriter toString(Class[] traitTypes, Trait parent, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, boolean makePackages, int scriptIndex, int classIndex, GraphTextWriter writer, List fullyQualifiedNames, boolean parallel) throws InterruptedException { - for (int t = 0; t < traits.size(); t++) { - Trait trait = traits.get(t); - if (traitTypes != null) { - boolean found = false; - for (Class c : traitTypes) { - if (c.isInstance(trait)) { - found = true; - break; - } - } - if (!found) { - continue; - } - } - writer.newLine(); - int h = t; - if (classIndex != -1) { - if (!isStatic) { - h += abc.class_info.get(classIndex).static_traits.traits.size(); - } - } - if (trait instanceof TraitClass) { - writer.startClass(((TraitClass) trait).class_info); - } else { - writer.startTrait(h); - } - if (makePackages) { - trait.toStringPackaged(parent, path, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, parallel); - } else { - trait.toString(parent, path, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, parallel); - } - if (trait instanceof TraitClass) { - writer.endClass(); - } else { - writer.endTrait(); - } - } - return writer; - } - - public void convert(Trait parent, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, boolean makePackages, int scriptIndex, int classIndex, NulWriter writer, List fullyQualifiedNames, boolean parallel) throws InterruptedException { - if (!parallel || traits.size() < 2) { - for (int t = 0; t < traits.size(); t++) { - TraitConvertTask task = new TraitConvertTask(traits.get(t), parent, makePackages, path, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, t, parallel); - task.call(); - } - } else { - ExecutorService executor = Executors.newFixedThreadPool(Configuration.getParallelThreadCount()); - List> futureResults = null; - - futureResults = new ArrayList<>(); - for (int t = 0; t < traits.size(); t++) { - // each convert task needs a separate NulWriter, because they are executed parallel - TraitConvertTask task = new TraitConvertTask(traits.get(t), parent, makePackages, path, abc, isStatic, exportMode, scriptIndex, classIndex, new NulWriter(), fullyQualifiedNames, t, parallel); - Future future = executor.submit(task); - futureResults.add(future); - } - - for (int f = 0; f < futureResults.size(); f++) { - try { - futureResults.get(f).get(); - } catch (InterruptedException ex) { - executor.shutdownNow(); - throw ex; - } catch (ExecutionException ex) { - Logger.getLogger(Traits.class.getName()).log(Level.SEVERE, "Error during traits converting", ex); - } - } - executor.shutdown(); - } - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.types.traits; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.configuration.Configuration; +import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; +import com.jpexs.decompiler.flash.helpers.GraphTextWriter; +import com.jpexs.decompiler.flash.helpers.NulWriter; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class Traits implements Serializable { + + public List traits; + + public Traits() { + traits = new ArrayList<>(); + } + + public Traits(int initialCapacity) { + traits = new ArrayList<>(initialCapacity); + } + + public void delete(ABC abc, boolean d) { + for (Trait t : traits) { + t.delete(abc, d); + } + } + + public int addTrait(Trait t) { + traits.add(t); + return traits.size() - 1; + } + + public int removeTraps(int scriptIndex, int classIndex, boolean isStatic, ABC abc, String path) throws InterruptedException { + int ret = 0; + for (Trait t : traits) { + ret += t.removeTraps(scriptIndex, classIndex, isStatic, abc, path); + } + return ret; + } + + @Override + public String toString() { + String s = ""; + for (int t = 0; t < traits.size(); t++) { + if (t > 0) { + s += "\r\n"; + } + s += traits.get(t).toString(); + } + return s; + } + + public String toString(ABC abc, List fullyQualifiedNames) { + String s = ""; + for (int t = 0; t < traits.size(); t++) { + if (t > 0) { + s += "\r\n"; + } + s += traits.get(t).toString(abc, fullyQualifiedNames); + } + return s; + } + + private class TraitConvertTask implements Callable { + + Trait trait; + + boolean makePackages; + + String path; + + ABC abc; + + boolean isStatic; + + ScriptExportMode exportMode; + + int scriptIndex; + + int classIndex; + + NulWriter writer; + + List fullyQualifiedNames; + + int traitIndex; + + boolean parallel; + + Trait parent; + + public TraitConvertTask(Trait trait, Trait parent, boolean makePackages, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List fullyQualifiedNames, int traitIndex, boolean parallel) { + this.trait = trait; + this.parent = parent; + this.makePackages = makePackages; + this.path = path; + this.abc = abc; + this.isStatic = isStatic; + this.exportMode = exportMode; + this.scriptIndex = scriptIndex; + this.classIndex = classIndex; + this.writer = writer; + this.fullyQualifiedNames = fullyQualifiedNames; + this.traitIndex = traitIndex; + this.parallel = parallel; + } + + @Override + public Void call() throws InterruptedException { + if (makePackages) { + trait.convertPackaged(parent, path, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, parallel); + } else { + trait.convert(parent, path, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, parallel); + } + return null; + } + } + + public GraphTextWriter toString(Class[] traitTypes, Trait parent, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, boolean makePackages, int scriptIndex, int classIndex, GraphTextWriter writer, List fullyQualifiedNames, boolean parallel) throws InterruptedException { + for (int t = 0; t < traits.size(); t++) { + Trait trait = traits.get(t); + if (traitTypes != null) { + boolean found = false; + for (Class c : traitTypes) { + if (c.isInstance(trait)) { + found = true; + break; + } + } + if (!found) { + continue; + } + } + writer.newLine(); + int h = t; + if (classIndex != -1) { + if (!isStatic) { + h += abc.class_info.get(classIndex).static_traits.traits.size(); + } + } + if (trait instanceof TraitClass) { + writer.startClass(((TraitClass) trait).class_info); + } else { + writer.startTrait(h); + } + if (makePackages) { + trait.toStringPackaged(parent, path, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, parallel); + } else { + trait.toString(parent, path, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, parallel); + } + if (trait instanceof TraitClass) { + writer.endClass(); + } else { + writer.endTrait(); + } + } + return writer; + } + + public void convert(Trait parent, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, boolean makePackages, int scriptIndex, int classIndex, NulWriter writer, List fullyQualifiedNames, boolean parallel) throws InterruptedException { + if (!parallel || traits.size() < 2) { + for (int t = 0; t < traits.size(); t++) { + TraitConvertTask task = new TraitConvertTask(traits.get(t), parent, makePackages, path, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, t, parallel); + task.call(); + } + } else { + ExecutorService executor = Executors.newFixedThreadPool(Configuration.getParallelThreadCount()); + List> futureResults = null; + + futureResults = new ArrayList<>(); + for (int t = 0; t < traits.size(); t++) { + // each convert task needs a separate NulWriter, because they are executed parallel + TraitConvertTask task = new TraitConvertTask(traits.get(t), parent, makePackages, path, abc, isStatic, exportMode, scriptIndex, classIndex, new NulWriter(), fullyQualifiedNames, t, parallel); + Future future = executor.submit(task); + futureResults.add(future); + } + + for (int f = 0; f < futureResults.size(); f++) { + try { + futureResults.get(f).get(); + } catch (InterruptedException ex) { + executor.shutdownNow(); + throw ex; + } catch (ExecutionException ex) { + Logger.getLogger(Traits.class.getName()).log(Level.SEVERE, "Error during traits converting", ex); + } + } + executor.shutdown(); + } + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/Action.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/Action.java index 254c39771..774f4d3de 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/Action.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/Action.java @@ -1,1334 +1,1334 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.action; - -import com.jpexs.decompiler.flash.AppResources; -import com.jpexs.decompiler.flash.BaseLocalData; -import com.jpexs.decompiler.flash.DisassemblyListener; -import com.jpexs.decompiler.flash.SWF; -import com.jpexs.decompiler.flash.SWFOutputStream; -import com.jpexs.decompiler.flash.action.model.ActionItem; -import com.jpexs.decompiler.flash.action.model.ConstantPool; -import com.jpexs.decompiler.flash.action.model.DirectValueActionItem; -import com.jpexs.decompiler.flash.action.model.ExtendsActionItem; -import com.jpexs.decompiler.flash.action.model.FunctionActionItem; -import com.jpexs.decompiler.flash.action.model.GetMemberActionItem; -import com.jpexs.decompiler.flash.action.model.GetPropertyActionItem; -import com.jpexs.decompiler.flash.action.model.GetVariableActionItem; -import com.jpexs.decompiler.flash.action.model.ImplementsOpActionItem; -import com.jpexs.decompiler.flash.action.model.NewObjectActionItem; -import com.jpexs.decompiler.flash.action.model.SetMemberActionItem; -import com.jpexs.decompiler.flash.action.model.SetPropertyActionItem; -import com.jpexs.decompiler.flash.action.model.SetVariableActionItem; -import com.jpexs.decompiler.flash.action.model.StoreRegisterActionItem; -import com.jpexs.decompiler.flash.action.model.TemporaryRegister; -import com.jpexs.decompiler.flash.action.model.UnsupportedActionItem; -import com.jpexs.decompiler.flash.action.model.clauses.ClassActionItem; -import com.jpexs.decompiler.flash.action.model.clauses.InterfaceActionItem; -import com.jpexs.decompiler.flash.action.parser.ActionParseException; -import com.jpexs.decompiler.flash.action.parser.pcode.ASMParsedSymbol; -import com.jpexs.decompiler.flash.action.parser.pcode.FlasmLexer; -import com.jpexs.decompiler.flash.action.parser.script.VariableActionItem; -import com.jpexs.decompiler.flash.action.special.ActionEnd; -import com.jpexs.decompiler.flash.action.special.ActionStore; -import com.jpexs.decompiler.flash.action.swf4.ActionEquals; -import com.jpexs.decompiler.flash.action.swf4.ActionIf; -import com.jpexs.decompiler.flash.action.swf4.ActionNot; -import com.jpexs.decompiler.flash.action.swf4.ActionPush; -import com.jpexs.decompiler.flash.action.swf4.RegisterNumber; -import com.jpexs.decompiler.flash.action.swf5.ActionConstantPool; -import com.jpexs.decompiler.flash.action.swf5.ActionDefineFunction; -import com.jpexs.decompiler.flash.action.swf5.ActionEquals2; -import com.jpexs.decompiler.flash.action.swf7.ActionDefineFunction2; -import com.jpexs.decompiler.flash.configuration.Configuration; -import com.jpexs.decompiler.flash.ecma.Null; -import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; -import com.jpexs.decompiler.flash.helpers.CodeFormatting; -import com.jpexs.decompiler.flash.helpers.GraphTextWriter; -import com.jpexs.decompiler.flash.helpers.HighlightedTextWriter; -import com.jpexs.decompiler.flash.helpers.NulWriter; -import com.jpexs.decompiler.flash.helpers.collections.MyEntry; -import com.jpexs.decompiler.flash.tags.base.ASMSource; -import com.jpexs.decompiler.graph.Graph; -import com.jpexs.decompiler.graph.GraphSource; -import com.jpexs.decompiler.graph.GraphSourceItem; -import com.jpexs.decompiler.graph.GraphSourceItemContainer; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.TranslateException; -import com.jpexs.decompiler.graph.TranslateStack; -import com.jpexs.decompiler.graph.model.CommentItem; -import com.jpexs.decompiler.graph.model.IfItem; -import com.jpexs.decompiler.graph.model.LocalData; -import com.jpexs.decompiler.graph.model.NotItem; -import com.jpexs.decompiler.graph.model.ScriptEndItem; -import com.jpexs.helpers.CancellableWorker; -import com.jpexs.helpers.Helper; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.EmptyStackException; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * Represents one ACTIONRECORD, also has some static method to work with Actions - */ -public abstract class Action implements GraphSourceItem { - - private static final int INFORM_LISTENER_RESOLUTION = 100; - - private boolean ignored = false; - - /** - * Action type identifier - */ - public int actionCode; - - /** - * Length of action data - */ - public int actionLength; - - private long address; - - /** - * Names of ActionScript properties - */ - public static final String[] propertyNames = new String[]{ - "_X", - "_Y", - "_xscale", - "_yscale", - "_currentframe", - "_totalframes", - "_alpha", - "_visible", - "_width", - "_height", - "_rotation", - "_target", - "_framesloaded", - "_name", - "_droptarget", - "_url", - "_highquality", - "_focusrect", - "_soundbuftime", - "_quality", - "_xmouse", - "_ymouse" - }; - - public static final List propertyNamesList = Arrays.asList(propertyNames); - - private static final Logger logger = Logger.getLogger(Action.class.getName()); - - /** - * Constructor - * - * @param actionCode Action type identifier - * @param actionLength Length of action data - */ - public Action(int actionCode, int actionLength) { - this.actionCode = actionCode; - this.actionLength = actionLength; - } - - public Action() { - } - - /** - * Returns address of this action - * - * @return address of this action - */ - public long getAddress() { - return address; - } - - /** - * Gets all addresses which are referenced from this action and/or - * subactions - * - * @param refs list of addresses - */ - public void getRef(Set refs) { - } - - /** - * Gets all addresses which are referenced from the list of actions - * - * @param list List of actions - * @return List of addresses - */ - public static Set getActionsAllRefs(List list) { - Set ret = new HashSet<>(); - for (Action a : list) { - a.getRef(ret); - } - return ret; - } - - public int getTotalActionLength() { - return actionLength + 1 + ((actionCode >= 0x80) ? 2 : 0); - } - - /** - * Sets address of this instruction - * - * @param address Address - */ - public void setAddress(long address) { - this.address = address; - } - - /** - * Returns a string representation of the object - * - * @return a string representation of the object. - */ - @Override - public String toString() { - return "Action" + actionCode; - } - - /** - * Reads String from FlasmLexer - * - * @param lex FlasmLexer - * @return String value - * @throws IOException - * @throws ActionParseException When read object is not String - */ - protected String lexString(FlasmLexer lex) throws IOException, ActionParseException { - ASMParsedSymbol symb = lex.yylex(); - if (symb.type != ASMParsedSymbol.TYPE_STRING) { - throw new ActionParseException("String expected", lex.yyline()); - } - return (String) symb.value; - } - - /** - * Reads Block startServer from FlasmLexer - * - * @param lex FlasmLexer - * @throws IOException - * @throws ActionParseException When read object is not Block startServer - */ - protected void lexBlockOpen(FlasmLexer lex) throws IOException, ActionParseException { - ASMParsedSymbol symb = lex.yylex(); - if (symb.type != ASMParsedSymbol.TYPE_BLOCK_START) { - throw new ActionParseException("Block startServer ", lex.yyline()); - } - } - - /** - * Reads Identifier from FlasmLexer - * - * @param lex FlasmLexer - * @return Identifier name - * @throws IOException - * @throws ActionParseException When read object is not Identifier - */ - protected String lexIdentifier(FlasmLexer lex) throws IOException, ActionParseException { - ASMParsedSymbol symb = lex.yylex(); - if (symb.type != ASMParsedSymbol.TYPE_IDENTIFIER) { - throw new ActionParseException("Identifier expected", lex.yyline()); - } - return (String) symb.value; - } - - /** - * Reads long value from FlasmLexer - * - * @param lex FlasmLexer - * @return long value - * @throws IOException - * @throws ActionParseException When read object is not long value - */ - protected long lexLong(FlasmLexer lex) throws IOException, ActionParseException { - ASMParsedSymbol symb = lex.yylex(); - if (symb.type != ASMParsedSymbol.TYPE_INTEGER) { - throw new ActionParseException("Integer expected", lex.yyline()); - } - return (Long) symb.value; - } - - /** - * Reads boolean value from FlasmLexer - * - * @param lex FlasmLexer - * @return boolean value - * @throws IOException - * @throws ActionParseException When read object is not boolean value - */ - protected boolean lexBoolean(FlasmLexer lex) throws IOException, ActionParseException { - ASMParsedSymbol symb = lex.yylex(); - if (symb.type != ASMParsedSymbol.TYPE_BOOLEAN) { - throw new ActionParseException("Boolean expected", lex.yyline()); - } - return (Boolean) symb.value; - } - - /** - * Gets action converted to bytes - * - * @param version SWF version - * @return Array of bytes - */ - public byte[] getBytes(int version) { - return surroundWithAction(new byte[0], version); - } - - /** - * Gets the length of action converted to bytes - * - * @param version SWF version - * @return Length - */ - public int getBytesLength(int version) { - return getBytes(version).length; - } - - /** - * Uptates the action length to the length calculated from action bytes - * - * @param version SWF version - */ - public void updateLength(int version) { - int length = getBytes(version).length; - actionLength = length - 1 - ((actionCode >= 0x80) ? 2 : 0); - } - - /** - * Surrounds byte array with Action header - * - * @param data Byte array - * @param version SWF version - * @return Byte array - */ - protected byte[] surroundWithAction(byte[] data, int version) { - ByteArrayOutputStream baos2 = new ByteArrayOutputStream(); - SWFOutputStream sos2 = new SWFOutputStream(baos2, version); - try { - sos2.writeUI8(actionCode); - if (actionCode >= 0x80) { - sos2.writeUI16(data.length); - } - sos2.write(data); - sos2.close(); - } catch (IOException e) { - throw new Error("This should never happen.", e); - } - return baos2.toByteArray(); - } - - /** - * Converts list of Actions to bytes - * - * @param list List of actions - * @param addZero Whether or not to add 0 UI8 value to the end - * @param version SWF version - * @return Array of bytes - */ - public static byte[] actionsToBytes(List list, boolean addZero, int version) { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - Action lastAction = null; - for (Action a : list) { - try { - lastAction = a; - baos.write(a.getBytes(version)); - } catch (IOException e) { - } - } - if (addZero && (lastAction == null || !(lastAction instanceof ActionEnd))) { - baos.write(0); - } - return baos.toByteArray(); - } - - /** - * Set addresses of actions in the list - * - * @param list List of actions - * @param baseAddress Address of first action in the list - */ - public static void setActionsAddresses(List list, long baseAddress) { - long offset = baseAddress; - for (Action a : list) { - a.setAddress(offset); - offset += a.getTotalActionLength(); - } - } - - /** - * Converts list of actions to ASM source - * - * @param listeners - * @param address - * @param list List of actions - * @param version SWF version - * @param exportMode PCode or hex? - * @return source ASM - * - */ - public static String actionsToString(List listeners, long address, ActionList list, int version, ScriptExportMode exportMode) { - HighlightedTextWriter writer = new HighlightedTextWriter(new CodeFormatting(), false); - actionsToString(listeners, address, list, version, exportMode, writer); - return writer.toString(); - } - - /** - * Converts list of actions to ASM source - * - * @param listeners - * @param address - * @param list List of actions - * @param version SWF version - * @param exportMode PCode or hex? - * @param writer - * @return GraphTextWriter - */ - public static GraphTextWriter actionsToString(List listeners, long address, ActionList list, int version, ScriptExportMode exportMode, GraphTextWriter writer) { - if (exportMode == ScriptExportMode.CONSTANTS) { - return constantPoolActionsToString(listeners, address, list, version, exportMode, writer); - } - - long offset; - Set importantOffsets = getActionsAllRefs(list); - /*List cps = SWFInputStream.getConstantPool(new ArrayList(), new ActionGraphSource(list, version, new HashMap(), new HashMap(), new HashMap()), 0, version, path); - if (!cps.isEmpty()) { - setConstantPool(list, cps.get(cps.size() - 1)); - }*/ - HashMap> containers = new HashMap<>(); - HashMap containersPos = new HashMap<>(); - offset = address; - int pos = 0; - boolean lastPush = false; - for (Action a : list) { - if (pos % INFORM_LISTENER_RESOLUTION == 0) { - for (DisassemblyListener listener : listeners) { - listener.progressToString(pos + 1, list.size()); - } - } - - if (exportMode == ScriptExportMode.PCODE_HEX) { - if (lastPush) { - writer.newLine(); - lastPush = false; - } - writer.appendNoHilight("; "); - writer.appendNoHilight(Helper.bytesToHexString(a.getBytes(version))); - writer.newLine(); - } - - offset = a.getAddress(); - - if ((!(a.isIgnored())) && (a instanceof GraphSourceItemContainer)) { - GraphSourceItemContainer cnt = (GraphSourceItemContainer) a; - containersPos.put(cnt, 0); - List sizes = cnt.getContainerSizes(); - long addr = ((Action) cnt).getAddress() + cnt.getHeaderSize(); - for (Long size : sizes) { - addr += size; - if (size == 0) { - continue; - } - if (!containers.containsKey(addr)) { - containers.put(addr, new ArrayList()); - } - containers.get(addr).add(cnt); - } - } - - if (containers.containsKey(offset)) { - for (int i = 0; i < containers.get(offset).size(); i++) { - if (lastPush) { - writer.newLine(); - lastPush = false; - } - writer.appendNoHilight("}").newLine(); - GraphSourceItemContainer cnt = containers.get(offset).get(i); - int cntPos = containersPos.get(cnt); - writer.appendNoHilight(cnt.getASMSourceBetween(cntPos)); - cntPos++; - containersPos.put(cnt, cntPos); - } - } - - if (Configuration.showAllAddresses.get() || importantOffsets.contains(offset)) { - if (lastPush) { - writer.newLine(); - lastPush = false; - } - writer.appendNoHilight("loc"); - writer.appendNoHilight(Helper.formatAddress(offset)); - writer.appendNoHilight(":"); - } - - if (a.isIgnored()) { - if (lastPush) { - writer.newLine(); - lastPush = false; - } - if (!(a instanceof ActionEnd)) { - int len = a.getTotalActionLength(); - for (int i = 0; i < len; i++) { - writer.appendNoHilight("Nop").newLine(); - } - } - } else { - //if (!(a instanceof ActionNop)) { - String add = ""; - // honfika: commented out the following lines, because it makes no sense - /*if (a instanceof ActionIf) { - add = " change: " + ((ActionIf) a).getJumpOffset(); - } - if (a instanceof ActionJump) { - add = " change: " + ((ActionJump) a).getJumpOffset(); - } - add = "; ofs" + Helper.formatAddress(offset) + add; - add = "";*/ - if ((a instanceof ActionPush) && lastPush) { - writer.appendNoHilight(" "); - ((ActionPush) a).paramsToStringReplaced(list, importantOffsets, exportMode, writer); - } else { - if (lastPush) { - writer.newLine(); - lastPush = false; - } - - writer.append("", offset); - - int fixBranch = -1; - if (a instanceof ActionIf) { - ActionIf aif = (ActionIf) a; - if (aif.jumpUsed && !aif.ignoreUsed) { - fixBranch = 0; - } - if (!aif.jumpUsed && aif.ignoreUsed) { - fixBranch = 1; - } - } - - if (fixBranch > -1) { - writer.appendNoHilight("FFDec_DeobfuscatePop"); - if (fixBranch == 0) { //jump - writer.newLine(); - writer.appendNoHilight("Jump loc"); - writer.appendNoHilight(Helper.formatAddress(a.getAddress() + a.getTotalActionLength() + ((ActionIf) a).getJumpOffset())); - } else { - //nojump, ignore - } - } else { - a.getASMSourceReplaced(list, importantOffsets, exportMode, writer); - } - writer.appendNoHilight(a.isIgnored() ? "; ignored" : ""); - writer.appendNoHilight(add); - if (!(a instanceof ActionPush)) { - writer.newLine(); - } - } - if (a instanceof ActionPush) { - lastPush = true; - } else { - lastPush = false; - } - //} - } - - offset += a.getTotalActionLength(); - pos++; - } - if (lastPush) { - writer.newLine(); - } - - if (containers.containsKey(offset)) { - for (int i = 0; i < containers.get(offset).size(); i++) { - writer.appendNoHilight("}"); - writer.newLine(); - GraphSourceItemContainer cnt = containers.get(offset).get(i); - int cntPos = containersPos.get(cnt); - writer.appendNoHilight(cnt.getASMSourceBetween(cntPos)); - cntPos++; - containersPos.put(cnt, cntPos); - } - } - - if (importantOffsets.contains(offset)) { - writer.appendNoHilight("loc"); - writer.appendNoHilight(Helper.formatAddress(offset)); - writer.appendNoHilight(":"); - writer.newLine(); - } - - return writer; - } - - public static GraphTextWriter constantPoolActionsToString(List listeners, long address, ActionList list, int version, ScriptExportMode exportMode, GraphTextWriter writer) { - int poolIdx = 0; - writer.appendNoHilight(Helper.constants).newLine(); - for (Action a : list) { - if (a instanceof ActionConstantPool) { - if (poolIdx > 0) { - writer.appendNoHilight("---").newLine(); - } - - ActionConstantPool cPool = (ActionConstantPool) a; - int constIdx = 0; - for (String c : cPool.constantPool) { - writer.appendNoHilight(constIdx); - writer.appendNoHilight("|"); - writer.appendNoHilight(c); - writer.newLine(); - constIdx++; - } - - poolIdx++; - } - } - - return writer; - } - - /** - * Convert action to ASM source - * - * @param container - * @param knownAddreses List of important offsets to mark as labels - * @param exportMode PCode or hex? - * @return String of P-code source - */ - public String getASMSource(ActionList container, Set knownAddreses, ScriptExportMode exportMode) { - return toString(); - } - - /** - * Translates this function to stack and output. - * - * @param stack Stack - * @param output Output - * @param regNames Register names - * @param variables Variables - * @param functions Functions - * @param staticOperation the value of staticOperation - * @param path the value of path - * @throws java.lang.InterruptedException - */ - public void translate(TranslateStack stack, List output, HashMap regNames, HashMap variables, HashMap functions, int staticOperation, String path) throws InterruptedException { - } - - /** - * Pops long value off the stack - * - * @param stack Stack - * @return long value - */ - protected long popLong(TranslateStack stack) { - GraphTargetItem item = stack.pop(); - if (item instanceof DirectValueActionItem) { - if (((DirectValueActionItem) item).value instanceof Long) { - return (long) (Long) ((DirectValueActionItem) item).value; - } - } - return 0; - } - - /** - * Converts action index to address in the specified list of actions - * - * @param actions List of actions - * @param ip Action index - * @return address - */ - public static long ip2adr(List actions, int ip) { - /* List actions=new ArrayList(); - for(GraphSourceItem s:sources){ - if(s instanceof Action){ - actions.add((Action)s); - } - }*/ - if (ip >= actions.size()) { - if (actions.isEmpty()) { - return 0; - } - return actions.get(actions.size() - 1).getAddress() + actions.get(actions.size() - 1).getTotalActionLength(); - } - if (ip == -1) { - return 0; - } - return actions.get(ip).getAddress(); - } - - /** - * Converts address to action index in the specified list of actions - * - * @param actions List of actions - * @param addr Address - * @return action index - */ - public static int adr2ip(List actions, long addr) { - for (int ip = 0; ip < actions.size(); ip++) { - if (actions.get(ip).getAddress() == addr) { - return ip; - } - } - if (actions.size() > 0) { - long outpos = actions.get(actions.size() - 1).getAddress() + actions.get(actions.size() - 1).getTotalActionLength(); - if (addr == outpos) { - return actions.size(); - } - } - return -1; - } - - public static List actionsToTree(List actions, int version, int staticOperation, String path) throws InterruptedException { - return actionsToTree(new HashMap(), new HashMap(), new HashMap(), actions, version, staticOperation, path); - } - - /** - * Converts list of actions to ActionScript source code - * - * @param asm - * @param actions List of actions - * @param path - * @return source - * @throws java.lang.InterruptedException - */ - public static String actionsToSource(final ASMSource asm, final List actions, final String path) throws InterruptedException { - HighlightedTextWriter writer = new HighlightedTextWriter(new CodeFormatting(), false); - actionsToSource(asm, actions, path, writer); - return writer.toString(); - } - - /** - * Converts list of actions to ActionScript source code - * - * @param asm - * @param actions List of actions - * @param path - * @param writer - * @throws java.lang.InterruptedException - */ - public static void actionsToSource(final ASMSource asm, final List actions, final String path, GraphTextWriter writer) throws InterruptedException { - writer.suspendMeasure(); - List tree = null; - Throwable convertException = null; - int timeout = Configuration.decompilationTimeoutSingleMethod.get(); - final int version = asm == null ? SWF.DEFAULT_VERSION : asm.getSwf().version; - try { - tree = CancellableWorker.call(new Callable>() { - @Override - public List call() throws Exception { - int staticOperation = Graph.SOP_USE_STATIC; //(Boolean) Configuration.getConfig("autoDeobfuscate", true) ? Graph.SOP_SKIP_STATIC : Graph.SOP_USE_STATIC; - List tree = actionsToTree(new HashMap(), new HashMap(), new HashMap(), actions, version, staticOperation, path); - Graph.graphToString(tree, new NulWriter(), new LocalData()); - return tree; - } - }, timeout, TimeUnit.SECONDS); - } catch (InterruptedException ex) { - throw ex; - } catch (Exception | OutOfMemoryError | StackOverflowError ex) { - if (ex instanceof TimeoutException) { - logger.log(Level.SEVERE, "Decompilation timeout in: " + path, ex); - } else { - logger.log(Level.SEVERE, "Decompilation error in: " + path, ex); - } - convertException = ex; - Throwable cause = ex.getCause(); - if (ex instanceof ExecutionException && cause instanceof Exception) { - convertException = cause; - } - } - writer.continueMeasure(); - - if (asm != null) { - asm.getActionSourcePrefix(writer); - } - if (convertException == null) { - Graph.graphToString(tree, writer, new LocalData()); - } else if (convertException instanceof TimeoutException) { - Helper.appendTimeoutComment(writer, timeout); - } else { - Helper.appendErrorComment(writer, convertException); - } - if (asm != null) { - asm.getActionSourceSuffix(writer); - } - } - - /** - * Converts list of actions to List of treeItems - * - * @param regNames Register names - * @param variables - * @param functions - * @param actions List of actions - * @param version SWF version - * @param staticOperation - * @param path - * @return List of treeItems - * @throws java.lang.InterruptedException - */ - public static List actionsToTree(HashMap regNames, HashMap variables, HashMap functions, List actions, int version, int staticOperation, String path) throws InterruptedException { - return ActionGraph.translateViaGraph(regNames, variables, functions, actions, version, staticOperation, path); - } - - @Override - public void translate(BaseLocalData localData, TranslateStack stack, List output, int staticOperation, String path) throws InterruptedException { - ActionLocalData aLocalData = (ActionLocalData) localData; - translate(stack, output, aLocalData.regNames, aLocalData.variables, aLocalData.functions, staticOperation, path); - } - - @Override - public boolean isJump() { - return false; - } - - @Override - public boolean isBranch() { - return false; - } - - @Override - public boolean isExit() { - return false; - } - - @Override - public long getOffset() { - return getAddress(); - } - - @Override - public List getBranches(GraphSource code) { - return new ArrayList<>(); - } - - @Override - public boolean isIgnored() { - return ignored; - } - - @Override - public void setIgnored(boolean ignored, int pos) { - this.ignored = ignored; - } - - private static class Loop { - - public long loopContinue; - - public long loopBreak; - - public int continueCount = 0; - - public int breakCount = 0; - - public Loop(long loopContinue, long loopBreak) { - this.loopContinue = loopContinue; - this.loopBreak = loopBreak; - } - - @Override - public String toString() { - return "[Loop continue:" + loopContinue + ", break:" + loopBreak + "]"; - } - } - - private static void log(String s) { - logger.fine(s); - } - - public static List actionsPartToTree(HashMap registerNames, HashMap variables, HashMap functions, TranslateStack stack, List actions, int start, int end, int version, int staticOperation, String path) throws InterruptedException { - if (start < actions.size() && (end > 0) && (start > 0)) { - log("Entering " + start + "-" + end + (actions.size() > 0 ? (" (" + actions.get(start).toString() + " - " + actions.get(end == actions.size() ? end - 1 : end) + ")") : "")); - } - ActionLocalData localData = new ActionLocalData(registerNames, variables, functions); - List output = new ArrayList<>(); - int ip = start; - boolean isWhile = false; - boolean isForIn = false; - GraphTargetItem inItem = null; - int loopStart = 0; - loopip: - while (ip <= end) { - - long addr = ip2adr(actions, ip); - if (ip > end) { - break; - } - if (ip >= actions.size()) { - output.add(new ScriptEndItem()); - break; - } - Action action = actions.get(ip); - if (action.isIgnored()) { - ip++; - continue; - } - if (action instanceof GraphSourceItemContainer) { - GraphSourceItemContainer cnt = (GraphSourceItemContainer) action; - //List out=actionsPartToTree(new HashMap(), new HashMap(),new HashMap(), new TranslateStack(), src, ip+1,endip-1 , version); - long endAddr = action.getAddress() + cnt.getHeaderSize(); - String cntName = cnt.getName(); - List> outs = new ArrayList<>(); - HashMap variables2 = Helper.deepCopy(variables); - if (cnt instanceof ActionDefineFunction || cnt instanceof ActionDefineFunction2) { - for (int r = 0; r < 256; r++) { - if (variables2.containsKey("__register" + r)) { - variables2.remove("__register" + r); - } - } - } - for (long size : cnt.getContainerSizes()) { - if (size == 0) { - outs.add(new ArrayList()); - continue; - } - List out; - try { - out = ActionGraph.translateViaGraph(cnt.getRegNames(), variables2, functions, actions.subList(adr2ip(actions, endAddr), adr2ip(actions, endAddr + size)), version, staticOperation, path + (cntName == null ? "" : "/" + cntName)); - } catch (OutOfMemoryError | TranslateException | StackOverflowError ex2) { - logger.log(Level.SEVERE, "Decompilation error in: " + path, ex2); - if (ex2 instanceof OutOfMemoryError) { - Helper.freeMem(); - } - out = new ArrayList<>(); - out.add(new CommentItem(new String[]{ - "", - " * " + AppResources.translate("decompilationError"), - " * " + AppResources.translate("decompilationError.obfuscated"), - Helper.decompilationErrorAdd == null ? null : " * " + Helper.decompilationErrorAdd, - " * " + AppResources.translate("decompilationError.errorType") + ": " - + ex2.getClass().getSimpleName(), - ""})); - } - outs.add(out); - endAddr += size; - } - ((GraphSourceItemContainer) action).translateContainer(outs, stack, output, registerNames, variables, functions); - ip = adr2ip(actions, endAddr); - continue; - } - - //return in for..in - if ((action instanceof ActionPush) && (((ActionPush) action).values.size() == 1) && (((ActionPush) action).values.get(0) instanceof Null)) { - if (ip + 3 <= end) { - if ((actions.get(ip + 1) instanceof ActionEquals) || (actions.get(ip + 1) instanceof ActionEquals2)) { - if (actions.get(ip + 2) instanceof ActionNot) { - if (actions.get(ip + 3) instanceof ActionIf) { - ActionIf aif = (ActionIf) actions.get(ip + 3); - if (adr2ip(actions, ip2adr(actions, ip + 4) + aif.getJumpOffset()) == ip) { - ip += 4; - continue; - } - } - } - } - } - } - - /*ActionJump && ActionIf removed*/ - /*if ((action instanceof ActionEnumerate2) || (action instanceof ActionEnumerate)) { - loopStart = ip + 1; - isForIn = true; - ip += 4; - action.translate(localData, stack, output); - EnumerateActionItem en = (EnumerateActionItem) stack.peek(); - inItem = en.object; - continue; - } else*/ /*if (action instanceof ActionTry) { - ActionTry atry = (ActionTry) action; - List tryCommands = ActionGraph.translateViaGraph(registerNames, variables, functions, atry.tryBody, version); - ActionItem catchName; - if (atry.catchInRegisterFlag) { - catchName = new DirectValueActionItem(atry, -1, new RegisterNumber(atry.catchRegister), new ArrayList()); - } else { - catchName = new DirectValueActionItem(atry, -1, atry.catchName, new ArrayList()); - } - List catchExceptions = new ArrayList(); - catchExceptions.add(catchName); - List> catchCommands = new ArrayList>(); - catchCommands.add(ActionGraph.translateViaGraph(registerNames, variables, functions, atry.catchBody, version)); - List finallyCommands = ActionGraph.translateViaGraph(registerNames, variables, functions, atry.finallyBody, version); - output.add(new TryActionItem(tryCommands, catchExceptions, catchCommands, finallyCommands)); - } else if (action instanceof ActionWith) { - ActionWith awith = (ActionWith) action; - List withCommands = ActionGraph.translateViaGraph(registerNames, variables, functions,new ArrayList() , version); //TODO:parse with actions - output.add(new WithActionItem(action, stack.pop(), withCommands)); - } else */ if (false) { - } /*if (action instanceof ActionStoreRegister) { - if ((ip + 1 <= end) && (actions.get(ip + 1) instanceof ActionPop)) { - action.translate(localData, stack, output); - stack.pop(); - ip++; - } else { - try { - action.translate(localData, stack, output); - } catch (Exception ex) { - // ignore - } - } - } */ /*else if (action instanceof ActionStrictEquals) { - if ((ip + 1 < actions.size()) && (actions.get(ip + 1) instanceof ActionIf)) { - List caseValues = new ArrayList(); - List> caseCommands = new ArrayList>(); - caseValues.add(stack.pop()); - ActionItem switchedObject = stack.pop(); - if (output.size() > 0) { - if (output.get(output.size() - 1) instanceof StoreRegisterActionItem) { - output.remove(output.size() - 1); - } - } - int caseStart = ip + 2; - List caseBodyIps = new ArrayList(); - long defaultAddr = 0; - caseBodyIps.add(adr2ip(actions, ((ActionIf) actions.get(ip + 1)).getRef(version), version)); - ip++; - do { - ip++; - if ((actions.get(ip - 1) instanceof ActionStrictEquals) && (actions.get(ip) instanceof ActionIf)) { - caseValues.add(actionsToStackTree(registerNames, jumpsOrIfs, actions, constants, caseStart, ip - 2, version).pop()); - caseStart = ip + 1; - caseBodyIps.add(adr2ip(actions, ((ActionIf) actions.get(ip)).getRef(version), version)); - if (actions.get(ip + 1) instanceof ActionJump) { - defaultAddr = ((ActionJump) actions.get(ip + 1)).getRef(version); - ip = adr2ip(actions, defaultAddr, version); - break; - } - } - } while (ip < end); - - for (int i = 0; i < caseBodyIps.size(); i++) { - int caseEnd = ip - 1; - if (i < caseBodyIps.size() - 1) { - caseEnd = caseBodyIps.get(i + 1) - 1; - } - caseCommands.add(actionsToTree(registerNames, unknownJumps, loopList, jumpsOrIfs, stack, constants, actions, caseBodyIps.get(i), caseEnd, version)); - } - output.add(new SwitchActionItem(action, defaultAddr, switchedObject, caseValues, caseCommands, null)); - continue; - } else { - action.translate(stack, constants, output, registerNames); - } - } */ else { - - if (action instanceof ActionStore) { - ActionStore store = (ActionStore) action; - store.setStore(actions.subList(ip + 1, ip + 1 + store.getStoreSize())); - ip = ip + 1 + store.getStoreSize() - 1/*ip++ will be next*/; - } - - try { - action.translate(localData, stack, output, staticOperation, path); - } catch (EmptyStackException ese) { - logger.log(Level.SEVERE, "Decompilation error in: " + path, ese); - output.add(new UnsupportedActionItem(action, "Empty stack")); - } - - } - - ip++; - } - //output = checkClass(output); - log("Leaving " + start + "-" + end); - return output; - } - - public static GraphTargetItem getWithoutGlobal(GraphTargetItem ti) { - GraphTargetItem t = ti; - if (!(t instanceof GetMemberActionItem)) { - return ti; - } - GetMemberActionItem lastMember = null; - while (((GetMemberActionItem) t).object instanceof GetMemberActionItem) { - lastMember = (GetMemberActionItem) t; - t = ((GetMemberActionItem) t).object; - } - if (((GetMemberActionItem) t).object instanceof GetVariableActionItem) { - GetVariableActionItem v = (GetVariableActionItem) ((GetMemberActionItem) t).object; - if (v.name instanceof DirectValueActionItem) { - if (((DirectValueActionItem) v.name).value instanceof String) { - if (((DirectValueActionItem) v.name).value.equals("_global")) { - GetVariableActionItem gvt = new GetVariableActionItem(null, ((GetMemberActionItem) t).memberName); - if (lastMember == null) { - return gvt; - } else { - lastMember.object = gvt; - } - } - } - } - } - return ti; - } - - public static List checkClass(List output) { - if (true) { - //return output; - } - List ret = new ArrayList<>(); - List functions = new ArrayList<>(); - List staticFunctions = new ArrayList<>(); - List> vars = new ArrayList<>(); - List> staticVars = new ArrayList<>(); - GraphTargetItem className; - GraphTargetItem extendsOp = null; - List implementsOp = new ArrayList<>(); - boolean ok = true; - int prevCount = 0; - for (GraphTargetItem t : output) { - if (t instanceof IfItem) { - IfItem it = (IfItem) t; - if (it.expression instanceof NotItem) { - NotItem nti = (NotItem) it.expression; - if ((nti.value instanceof GetMemberActionItem) || (nti.value instanceof GetVariableActionItem)) { - if (true) { //it.onFalse.isEmpty()){ //||(it.onFalse.get(0) instanceof UnsupportedActionItem)) { - if ((it.onTrue.size() == 1) && (it.onTrue.get(0) instanceof SetMemberActionItem) && (((SetMemberActionItem) it.onTrue.get(0)).value instanceof NewObjectActionItem)) { - // ignore - } else { - List parts = it.onTrue; - className = getWithoutGlobal(nti.value); - if (parts.size() >= 1) { - int ipos = 0; - while ((parts.get(ipos) instanceof IfItem) - && ((((IfItem) parts.get(ipos)).onTrue.size() == 1) && (((IfItem) parts.get(ipos)).onTrue.get(0) instanceof SetMemberActionItem) && (((SetMemberActionItem) ((IfItem) parts.get(ipos)).onTrue.get(0)).value instanceof NewObjectActionItem))) { - - ipos++; - } - if (parts.get(ipos) instanceof ExtendsActionItem) { - ExtendsActionItem et = (ExtendsActionItem) parts.get(ipos); - extendsOp = getWithoutGlobal(et.superclass); - ipos++; - } - if (parts.get(ipos) instanceof StoreRegisterActionItem) { - StoreRegisterActionItem sr = (StoreRegisterActionItem) parts.get(ipos); - int instanceReg = sr.register.number; - if (sr.value instanceof GetMemberActionItem) { - GetMemberActionItem gm = (GetMemberActionItem) sr.value; - //gm.memberName should be "prototype" - if (gm.object instanceof TemporaryRegister) { - TemporaryRegister tm = (TemporaryRegister) gm.object; - int classReg = tm.getRegId(); - if (tm.value instanceof SetMemberActionItem) { - SetMemberActionItem sm = (SetMemberActionItem) tm.value; - if (sm.value instanceof StoreRegisterActionItem) { - sr = (StoreRegisterActionItem) sm.value; - if (sr.value instanceof FunctionActionItem) { - ((FunctionActionItem) (sr.value)).calculatedFunctionName = (className instanceof GetMemberActionItem) ? ((GetMemberActionItem) className).memberName : className; - functions.add((FunctionActionItem) sr.value); - - for (; ipos < parts.size(); ipos++) { - if (parts.get(ipos) instanceof ImplementsOpActionItem) { - ImplementsOpActionItem io = (ImplementsOpActionItem) parts.get(ipos); - implementsOp = io.superclasses; - continue; - } - if (parts.get(ipos) instanceof SetMemberActionItem) { - sm = (SetMemberActionItem) parts.get(ipos); - int rnum = -1; - if (sm.object instanceof DirectValueActionItem) { - DirectValueActionItem dv = (DirectValueActionItem) sm.object; - if (dv.value instanceof RegisterNumber) { - RegisterNumber rn = (RegisterNumber) dv.value; - rnum = rn.number; - } - } - if (sm.object instanceof TemporaryRegister) { - rnum = ((TemporaryRegister) sm.object).getRegId(); - } - if (rnum == instanceReg) { - if (sm.value instanceof FunctionActionItem) { - ((FunctionActionItem) sm.value).calculatedFunctionName = sm.objectName; - functions.add((FunctionActionItem) sm.value); - } else { - vars.add(new MyEntry<>(sm.objectName, sm.value)); - } - } else if (rnum == classReg) { - if (sm.value instanceof FunctionActionItem) { - ((FunctionActionItem) sm.value).calculatedFunctionName = sm.objectName; - staticFunctions.add((FunctionActionItem) sm.value); - } else { - staticVars.add(new MyEntry<>(sm.objectName, sm.value)); - } - } - - } - } - - } - - } - } - List output2 = new ArrayList<>(); - for (int i = 0; i < prevCount; i++) { - output2.add(output.get(i)); - } - output2.add(new ClassActionItem(className, extendsOp, implementsOp, null/*FIXME*/, functions, vars, staticFunctions, staticVars)); - return output2; - } - } - } else if (parts.get(ipos) instanceof SetMemberActionItem) { - SetMemberActionItem sm = (SetMemberActionItem) parts.get(0); - if (sm.value instanceof FunctionActionItem) { - FunctionActionItem f = (FunctionActionItem) sm.value; - if (f.actions.isEmpty()) { - if (parts.size() == 2) { - if (parts.get(1) instanceof ImplementsOpActionItem) { - ImplementsOpActionItem iot = (ImplementsOpActionItem) parts.get(1); - implementsOp = iot.superclasses; - } else { - ok = false; - break; - } - } - List output2 = new ArrayList<>(); - for (int i = 0; i < prevCount; i++) { - output2.add(output.get(i)); - } - output2.add(new InterfaceActionItem(sm.objectName, implementsOp)); - return output2; - } - } - } - } - } - } else { - ok = false; - } - } else { - ok = false; - } - } else { - ok = false; - } - } else { - prevCount++; - //ok = false; - } - if (!ok) { - break; - } - } - return output; - } - - @Override - public boolean ignoredLoops() { - return false; - } - - public static void setConstantPool(List actions, ConstantPool cpool) { - for (GraphSourceItem a : actions) { - if (a instanceof ActionPush) { - if (cpool != null) { - ((ActionPush) a).constantPool = cpool.constants; - } - } - if (a instanceof ActionDefineFunction) { - if (cpool != null) { - //((ActionDefineFunction) a).setConstantPool(cpool.constants,actions); - } - } - if (a instanceof ActionDefineFunction2) { - if (cpool != null) { - //((ActionDefineFunction2) a).setConstantPool(cpool.constants,actions); - } - } - } - } - - public GraphTextWriter getASMSourceReplaced(ActionList container, Set knownAddreses, ScriptExportMode exportMode, GraphTextWriter writer) { - writer.appendNoHilight(getASMSource(container, knownAddreses, exportMode)); - return writer; - } - - public static double toFloatPoint(Object o) { - if (o instanceof Double) { - return (Double) o; - } - if (o instanceof Integer) { - return (Integer) o; - } - if (o instanceof Long) { - return (Long) o; - } - if (o instanceof String) { - try { - return Double.parseDouble((String) o); - } catch (NumberFormatException nfe) { - return 0; - } - } - return 0; - } - - public static GraphTargetItem gettoset(GraphTargetItem get, GraphTargetItem value, List variables) { - GraphTargetItem ret = get; - boolean boxed = false; - if (get instanceof VariableActionItem) { - boxed = true; - ret = ((VariableActionItem) ret).getBoxedValue(); - } - if (ret instanceof GetVariableActionItem) { - GetVariableActionItem gv = (GetVariableActionItem) ret; - ret = new SetVariableActionItem(null, gv.name, value); - } else if (ret instanceof GetMemberActionItem) { - GetMemberActionItem mem = (GetMemberActionItem) ret; - ret = new SetMemberActionItem(null, mem.object, mem.memberName, value); - } else if ((ret instanceof DirectValueActionItem) && ((DirectValueActionItem) ret).value instanceof RegisterNumber) { - ret = new StoreRegisterActionItem(null, (RegisterNumber) ((DirectValueActionItem) ret).value, value, false); - } else if (ret instanceof GetPropertyActionItem) { - GetPropertyActionItem gp = (GetPropertyActionItem) ret; - ret = new SetPropertyActionItem(null, gp.target, gp.propertyIndex, value); - } - if (boxed) { - GraphTargetItem b = ret; - ret = new VariableActionItem(((VariableActionItem) get).getVariableName(), value, ((VariableActionItem) get).isDefinition()); - ((VariableActionItem) ret).setBoxedValue((ActionItem) b); - variables.remove((VariableActionItem) get); - variables.add((VariableActionItem) ret); - } - return ret; - } - - @Override - public boolean isDeobfuscatePop() { - return false; - } - - @Override - public int getLine() { - return 0; - } - - @Override - public String getFile() { - return null; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.action; + +import com.jpexs.decompiler.flash.AppResources; +import com.jpexs.decompiler.flash.BaseLocalData; +import com.jpexs.decompiler.flash.DisassemblyListener; +import com.jpexs.decompiler.flash.SWF; +import com.jpexs.decompiler.flash.SWFOutputStream; +import com.jpexs.decompiler.flash.action.model.ActionItem; +import com.jpexs.decompiler.flash.action.model.ConstantPool; +import com.jpexs.decompiler.flash.action.model.DirectValueActionItem; +import com.jpexs.decompiler.flash.action.model.ExtendsActionItem; +import com.jpexs.decompiler.flash.action.model.FunctionActionItem; +import com.jpexs.decompiler.flash.action.model.GetMemberActionItem; +import com.jpexs.decompiler.flash.action.model.GetPropertyActionItem; +import com.jpexs.decompiler.flash.action.model.GetVariableActionItem; +import com.jpexs.decompiler.flash.action.model.ImplementsOpActionItem; +import com.jpexs.decompiler.flash.action.model.NewObjectActionItem; +import com.jpexs.decompiler.flash.action.model.SetMemberActionItem; +import com.jpexs.decompiler.flash.action.model.SetPropertyActionItem; +import com.jpexs.decompiler.flash.action.model.SetVariableActionItem; +import com.jpexs.decompiler.flash.action.model.StoreRegisterActionItem; +import com.jpexs.decompiler.flash.action.model.TemporaryRegister; +import com.jpexs.decompiler.flash.action.model.UnsupportedActionItem; +import com.jpexs.decompiler.flash.action.model.clauses.ClassActionItem; +import com.jpexs.decompiler.flash.action.model.clauses.InterfaceActionItem; +import com.jpexs.decompiler.flash.action.parser.ActionParseException; +import com.jpexs.decompiler.flash.action.parser.pcode.ASMParsedSymbol; +import com.jpexs.decompiler.flash.action.parser.pcode.FlasmLexer; +import com.jpexs.decompiler.flash.action.parser.script.VariableActionItem; +import com.jpexs.decompiler.flash.action.special.ActionEnd; +import com.jpexs.decompiler.flash.action.special.ActionStore; +import com.jpexs.decompiler.flash.action.swf4.ActionEquals; +import com.jpexs.decompiler.flash.action.swf4.ActionIf; +import com.jpexs.decompiler.flash.action.swf4.ActionNot; +import com.jpexs.decompiler.flash.action.swf4.ActionPush; +import com.jpexs.decompiler.flash.action.swf4.RegisterNumber; +import com.jpexs.decompiler.flash.action.swf5.ActionConstantPool; +import com.jpexs.decompiler.flash.action.swf5.ActionDefineFunction; +import com.jpexs.decompiler.flash.action.swf5.ActionEquals2; +import com.jpexs.decompiler.flash.action.swf7.ActionDefineFunction2; +import com.jpexs.decompiler.flash.configuration.Configuration; +import com.jpexs.decompiler.flash.ecma.Null; +import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; +import com.jpexs.decompiler.flash.helpers.CodeFormatting; +import com.jpexs.decompiler.flash.helpers.GraphTextWriter; +import com.jpexs.decompiler.flash.helpers.HighlightedTextWriter; +import com.jpexs.decompiler.flash.helpers.NulWriter; +import com.jpexs.decompiler.flash.helpers.collections.MyEntry; +import com.jpexs.decompiler.flash.tags.base.ASMSource; +import com.jpexs.decompiler.graph.Graph; +import com.jpexs.decompiler.graph.GraphSource; +import com.jpexs.decompiler.graph.GraphSourceItem; +import com.jpexs.decompiler.graph.GraphSourceItemContainer; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.TranslateException; +import com.jpexs.decompiler.graph.TranslateStack; +import com.jpexs.decompiler.graph.model.CommentItem; +import com.jpexs.decompiler.graph.model.IfItem; +import com.jpexs.decompiler.graph.model.LocalData; +import com.jpexs.decompiler.graph.model.NotItem; +import com.jpexs.decompiler.graph.model.ScriptEndItem; +import com.jpexs.helpers.CancellableWorker; +import com.jpexs.helpers.Helper; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.EmptyStackException; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Represents one ACTIONRECORD, also has some static method to work with Actions + */ +public abstract class Action implements GraphSourceItem { + + private static final int INFORM_LISTENER_RESOLUTION = 100; + + private boolean ignored = false; + + /** + * Action type identifier + */ + public int actionCode; + + /** + * Length of action data + */ + public int actionLength; + + private long address; + + /** + * Names of ActionScript properties + */ + public static final String[] propertyNames = new String[]{ + "_X", + "_Y", + "_xscale", + "_yscale", + "_currentframe", + "_totalframes", + "_alpha", + "_visible", + "_width", + "_height", + "_rotation", + "_target", + "_framesloaded", + "_name", + "_droptarget", + "_url", + "_highquality", + "_focusrect", + "_soundbuftime", + "_quality", + "_xmouse", + "_ymouse" + }; + + public static final List propertyNamesList = Arrays.asList(propertyNames); + + private static final Logger logger = Logger.getLogger(Action.class.getName()); + + /** + * Constructor + * + * @param actionCode Action type identifier + * @param actionLength Length of action data + */ + public Action(int actionCode, int actionLength) { + this.actionCode = actionCode; + this.actionLength = actionLength; + } + + public Action() { + } + + /** + * Returns address of this action + * + * @return address of this action + */ + public long getAddress() { + return address; + } + + /** + * Gets all addresses which are referenced from this action and/or + * subactions + * + * @param refs list of addresses + */ + public void getRef(Set refs) { + } + + /** + * Gets all addresses which are referenced from the list of actions + * + * @param list List of actions + * @return List of addresses + */ + public static Set getActionsAllRefs(List list) { + Set ret = new HashSet<>(); + for (Action a : list) { + a.getRef(ret); + } + return ret; + } + + public int getTotalActionLength() { + return actionLength + 1 + ((actionCode >= 0x80) ? 2 : 0); + } + + /** + * Sets address of this instruction + * + * @param address Address + */ + public void setAddress(long address) { + this.address = address; + } + + /** + * Returns a string representation of the object + * + * @return a string representation of the object. + */ + @Override + public String toString() { + return "Action" + actionCode; + } + + /** + * Reads String from FlasmLexer + * + * @param lex FlasmLexer + * @return String value + * @throws IOException + * @throws ActionParseException When read object is not String + */ + protected String lexString(FlasmLexer lex) throws IOException, ActionParseException { + ASMParsedSymbol symb = lex.yylex(); + if (symb.type != ASMParsedSymbol.TYPE_STRING) { + throw new ActionParseException("String expected", lex.yyline()); + } + return (String) symb.value; + } + + /** + * Reads Block startServer from FlasmLexer + * + * @param lex FlasmLexer + * @throws IOException + * @throws ActionParseException When read object is not Block startServer + */ + protected void lexBlockOpen(FlasmLexer lex) throws IOException, ActionParseException { + ASMParsedSymbol symb = lex.yylex(); + if (symb.type != ASMParsedSymbol.TYPE_BLOCK_START) { + throw new ActionParseException("Block startServer ", lex.yyline()); + } + } + + /** + * Reads Identifier from FlasmLexer + * + * @param lex FlasmLexer + * @return Identifier name + * @throws IOException + * @throws ActionParseException When read object is not Identifier + */ + protected String lexIdentifier(FlasmLexer lex) throws IOException, ActionParseException { + ASMParsedSymbol symb = lex.yylex(); + if (symb.type != ASMParsedSymbol.TYPE_IDENTIFIER) { + throw new ActionParseException("Identifier expected", lex.yyline()); + } + return (String) symb.value; + } + + /** + * Reads long value from FlasmLexer + * + * @param lex FlasmLexer + * @return long value + * @throws IOException + * @throws ActionParseException When read object is not long value + */ + protected long lexLong(FlasmLexer lex) throws IOException, ActionParseException { + ASMParsedSymbol symb = lex.yylex(); + if (symb.type != ASMParsedSymbol.TYPE_INTEGER) { + throw new ActionParseException("Integer expected", lex.yyline()); + } + return (Long) symb.value; + } + + /** + * Reads boolean value from FlasmLexer + * + * @param lex FlasmLexer + * @return boolean value + * @throws IOException + * @throws ActionParseException When read object is not boolean value + */ + protected boolean lexBoolean(FlasmLexer lex) throws IOException, ActionParseException { + ASMParsedSymbol symb = lex.yylex(); + if (symb.type != ASMParsedSymbol.TYPE_BOOLEAN) { + throw new ActionParseException("Boolean expected", lex.yyline()); + } + return (Boolean) symb.value; + } + + /** + * Gets action converted to bytes + * + * @param version SWF version + * @return Array of bytes + */ + public byte[] getBytes(int version) { + return surroundWithAction(new byte[0], version); + } + + /** + * Gets the length of action converted to bytes + * + * @param version SWF version + * @return Length + */ + public int getBytesLength(int version) { + return getBytes(version).length; + } + + /** + * Uptates the action length to the length calculated from action bytes + * + * @param version SWF version + */ + public void updateLength(int version) { + int length = getBytes(version).length; + actionLength = length - 1 - ((actionCode >= 0x80) ? 2 : 0); + } + + /** + * Surrounds byte array with Action header + * + * @param data Byte array + * @param version SWF version + * @return Byte array + */ + protected byte[] surroundWithAction(byte[] data, int version) { + ByteArrayOutputStream baos2 = new ByteArrayOutputStream(); + SWFOutputStream sos2 = new SWFOutputStream(baos2, version); + try { + sos2.writeUI8(actionCode); + if (actionCode >= 0x80) { + sos2.writeUI16(data.length); + } + sos2.write(data); + sos2.close(); + } catch (IOException e) { + throw new Error("This should never happen.", e); + } + return baos2.toByteArray(); + } + + /** + * Converts list of Actions to bytes + * + * @param list List of actions + * @param addZero Whether or not to add 0 UI8 value to the end + * @param version SWF version + * @return Array of bytes + */ + public static byte[] actionsToBytes(List list, boolean addZero, int version) { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + Action lastAction = null; + for (Action a : list) { + try { + lastAction = a; + baos.write(a.getBytes(version)); + } catch (IOException e) { + } + } + if (addZero && (lastAction == null || !(lastAction instanceof ActionEnd))) { + baos.write(0); + } + return baos.toByteArray(); + } + + /** + * Set addresses of actions in the list + * + * @param list List of actions + * @param baseAddress Address of first action in the list + */ + public static void setActionsAddresses(List list, long baseAddress) { + long offset = baseAddress; + for (Action a : list) { + a.setAddress(offset); + offset += a.getTotalActionLength(); + } + } + + /** + * Converts list of actions to ASM source + * + * @param listeners + * @param address + * @param list List of actions + * @param version SWF version + * @param exportMode PCode or hex? + * @return source ASM + * + */ + public static String actionsToString(List listeners, long address, ActionList list, int version, ScriptExportMode exportMode) { + HighlightedTextWriter writer = new HighlightedTextWriter(new CodeFormatting(), false); + actionsToString(listeners, address, list, version, exportMode, writer); + return writer.toString(); + } + + /** + * Converts list of actions to ASM source + * + * @param listeners + * @param address + * @param list List of actions + * @param version SWF version + * @param exportMode PCode or hex? + * @param writer + * @return GraphTextWriter + */ + public static GraphTextWriter actionsToString(List listeners, long address, ActionList list, int version, ScriptExportMode exportMode, GraphTextWriter writer) { + if (exportMode == ScriptExportMode.CONSTANTS) { + return constantPoolActionsToString(listeners, address, list, version, exportMode, writer); + } + + long offset; + Set importantOffsets = getActionsAllRefs(list); + /*List cps = SWFInputStream.getConstantPool(new ArrayList(), new ActionGraphSource(list, version, new HashMap(), new HashMap(), new HashMap()), 0, version, path); + if (!cps.isEmpty()) { + setConstantPool(list, cps.get(cps.size() - 1)); + }*/ + HashMap> containers = new HashMap<>(); + HashMap containersPos = new HashMap<>(); + offset = address; + int pos = 0; + boolean lastPush = false; + for (Action a : list) { + if (pos % INFORM_LISTENER_RESOLUTION == 0) { + for (DisassemblyListener listener : listeners) { + listener.progressToString(pos + 1, list.size()); + } + } + + if (exportMode == ScriptExportMode.PCODE_HEX) { + if (lastPush) { + writer.newLine(); + lastPush = false; + } + writer.appendNoHilight("; "); + writer.appendNoHilight(Helper.bytesToHexString(a.getBytes(version))); + writer.newLine(); + } + + offset = a.getAddress(); + + if ((!(a.isIgnored())) && (a instanceof GraphSourceItemContainer)) { + GraphSourceItemContainer cnt = (GraphSourceItemContainer) a; + containersPos.put(cnt, 0); + List sizes = cnt.getContainerSizes(); + long addr = ((Action) cnt).getAddress() + cnt.getHeaderSize(); + for (Long size : sizes) { + addr += size; + if (size == 0) { + continue; + } + if (!containers.containsKey(addr)) { + containers.put(addr, new ArrayList()); + } + containers.get(addr).add(cnt); + } + } + + if (containers.containsKey(offset)) { + for (int i = 0; i < containers.get(offset).size(); i++) { + if (lastPush) { + writer.newLine(); + lastPush = false; + } + writer.appendNoHilight("}").newLine(); + GraphSourceItemContainer cnt = containers.get(offset).get(i); + int cntPos = containersPos.get(cnt); + writer.appendNoHilight(cnt.getASMSourceBetween(cntPos)); + cntPos++; + containersPos.put(cnt, cntPos); + } + } + + if (Configuration.showAllAddresses.get() || importantOffsets.contains(offset)) { + if (lastPush) { + writer.newLine(); + lastPush = false; + } + writer.appendNoHilight("loc"); + writer.appendNoHilight(Helper.formatAddress(offset)); + writer.appendNoHilight(":"); + } + + if (a.isIgnored()) { + if (lastPush) { + writer.newLine(); + lastPush = false; + } + if (!(a instanceof ActionEnd)) { + int len = a.getTotalActionLength(); + for (int i = 0; i < len; i++) { + writer.appendNoHilight("Nop").newLine(); + } + } + } else { + //if (!(a instanceof ActionNop)) { + String add = ""; + // honfika: commented out the following lines, because it makes no sense + /*if (a instanceof ActionIf) { + add = " change: " + ((ActionIf) a).getJumpOffset(); + } + if (a instanceof ActionJump) { + add = " change: " + ((ActionJump) a).getJumpOffset(); + } + add = "; ofs" + Helper.formatAddress(offset) + add; + add = "";*/ + if ((a instanceof ActionPush) && lastPush) { + writer.appendNoHilight(" "); + ((ActionPush) a).paramsToStringReplaced(list, importantOffsets, exportMode, writer); + } else { + if (lastPush) { + writer.newLine(); + lastPush = false; + } + + writer.append("", offset); + + int fixBranch = -1; + if (a instanceof ActionIf) { + ActionIf aif = (ActionIf) a; + if (aif.jumpUsed && !aif.ignoreUsed) { + fixBranch = 0; + } + if (!aif.jumpUsed && aif.ignoreUsed) { + fixBranch = 1; + } + } + + if (fixBranch > -1) { + writer.appendNoHilight("FFDec_DeobfuscatePop"); + if (fixBranch == 0) { //jump + writer.newLine(); + writer.appendNoHilight("Jump loc"); + writer.appendNoHilight(Helper.formatAddress(a.getAddress() + a.getTotalActionLength() + ((ActionIf) a).getJumpOffset())); + } else { + //nojump, ignore + } + } else { + a.getASMSourceReplaced(list, importantOffsets, exportMode, writer); + } + writer.appendNoHilight(a.isIgnored() ? "; ignored" : ""); + writer.appendNoHilight(add); + if (!(a instanceof ActionPush)) { + writer.newLine(); + } + } + if (a instanceof ActionPush) { + lastPush = true; + } else { + lastPush = false; + } + //} + } + + offset += a.getTotalActionLength(); + pos++; + } + if (lastPush) { + writer.newLine(); + } + + if (containers.containsKey(offset)) { + for (int i = 0; i < containers.get(offset).size(); i++) { + writer.appendNoHilight("}"); + writer.newLine(); + GraphSourceItemContainer cnt = containers.get(offset).get(i); + int cntPos = containersPos.get(cnt); + writer.appendNoHilight(cnt.getASMSourceBetween(cntPos)); + cntPos++; + containersPos.put(cnt, cntPos); + } + } + + if (importantOffsets.contains(offset)) { + writer.appendNoHilight("loc"); + writer.appendNoHilight(Helper.formatAddress(offset)); + writer.appendNoHilight(":"); + writer.newLine(); + } + + return writer; + } + + public static GraphTextWriter constantPoolActionsToString(List listeners, long address, ActionList list, int version, ScriptExportMode exportMode, GraphTextWriter writer) { + int poolIdx = 0; + writer.appendNoHilight(Helper.constants).newLine(); + for (Action a : list) { + if (a instanceof ActionConstantPool) { + if (poolIdx > 0) { + writer.appendNoHilight("---").newLine(); + } + + ActionConstantPool cPool = (ActionConstantPool) a; + int constIdx = 0; + for (String c : cPool.constantPool) { + writer.appendNoHilight(constIdx); + writer.appendNoHilight("|"); + writer.appendNoHilight(c); + writer.newLine(); + constIdx++; + } + + poolIdx++; + } + } + + return writer; + } + + /** + * Convert action to ASM source + * + * @param container + * @param knownAddreses List of important offsets to mark as labels + * @param exportMode PCode or hex? + * @return String of P-code source + */ + public String getASMSource(ActionList container, Set knownAddreses, ScriptExportMode exportMode) { + return toString(); + } + + /** + * Translates this function to stack and output. + * + * @param stack Stack + * @param output Output + * @param regNames Register names + * @param variables Variables + * @param functions Functions + * @param staticOperation the value of staticOperation + * @param path the value of path + * @throws java.lang.InterruptedException + */ + public void translate(TranslateStack stack, List output, HashMap regNames, HashMap variables, HashMap functions, int staticOperation, String path) throws InterruptedException { + } + + /** + * Pops long value off the stack + * + * @param stack Stack + * @return long value + */ + protected long popLong(TranslateStack stack) { + GraphTargetItem item = stack.pop(); + if (item instanceof DirectValueActionItem) { + if (((DirectValueActionItem) item).value instanceof Long) { + return (long) (Long) ((DirectValueActionItem) item).value; + } + } + return 0; + } + + /** + * Converts action index to address in the specified list of actions + * + * @param actions List of actions + * @param ip Action index + * @return address + */ + public static long ip2adr(List actions, int ip) { + /* List actions=new ArrayList(); + for(GraphSourceItem s:sources){ + if(s instanceof Action){ + actions.add((Action)s); + } + }*/ + if (ip >= actions.size()) { + if (actions.isEmpty()) { + return 0; + } + return actions.get(actions.size() - 1).getAddress() + actions.get(actions.size() - 1).getTotalActionLength(); + } + if (ip == -1) { + return 0; + } + return actions.get(ip).getAddress(); + } + + /** + * Converts address to action index in the specified list of actions + * + * @param actions List of actions + * @param addr Address + * @return action index + */ + public static int adr2ip(List actions, long addr) { + for (int ip = 0; ip < actions.size(); ip++) { + if (actions.get(ip).getAddress() == addr) { + return ip; + } + } + if (actions.size() > 0) { + long outpos = actions.get(actions.size() - 1).getAddress() + actions.get(actions.size() - 1).getTotalActionLength(); + if (addr == outpos) { + return actions.size(); + } + } + return -1; + } + + public static List actionsToTree(List actions, int version, int staticOperation, String path) throws InterruptedException { + return actionsToTree(new HashMap(), new HashMap(), new HashMap(), actions, version, staticOperation, path); + } + + /** + * Converts list of actions to ActionScript source code + * + * @param asm + * @param actions List of actions + * @param path + * @return source + * @throws java.lang.InterruptedException + */ + public static String actionsToSource(final ASMSource asm, final List actions, final String path) throws InterruptedException { + HighlightedTextWriter writer = new HighlightedTextWriter(new CodeFormatting(), false); + actionsToSource(asm, actions, path, writer); + return writer.toString(); + } + + /** + * Converts list of actions to ActionScript source code + * + * @param asm + * @param actions List of actions + * @param path + * @param writer + * @throws java.lang.InterruptedException + */ + public static void actionsToSource(final ASMSource asm, final List actions, final String path, GraphTextWriter writer) throws InterruptedException { + writer.suspendMeasure(); + List tree = null; + Throwable convertException = null; + int timeout = Configuration.decompilationTimeoutSingleMethod.get(); + final int version = asm == null ? SWF.DEFAULT_VERSION : asm.getSwf().version; + try { + tree = CancellableWorker.call(new Callable>() { + @Override + public List call() throws Exception { + int staticOperation = Graph.SOP_USE_STATIC; //(Boolean) Configuration.getConfig("autoDeobfuscate", true) ? Graph.SOP_SKIP_STATIC : Graph.SOP_USE_STATIC; + List tree = actionsToTree(new HashMap(), new HashMap(), new HashMap(), actions, version, staticOperation, path); + Graph.graphToString(tree, new NulWriter(), new LocalData()); + return tree; + } + }, timeout, TimeUnit.SECONDS); + } catch (InterruptedException ex) { + throw ex; + } catch (Exception | OutOfMemoryError | StackOverflowError ex) { + if (ex instanceof TimeoutException) { + logger.log(Level.SEVERE, "Decompilation timeout in: " + path, ex); + } else { + logger.log(Level.SEVERE, "Decompilation error in: " + path, ex); + } + convertException = ex; + Throwable cause = ex.getCause(); + if (ex instanceof ExecutionException && cause instanceof Exception) { + convertException = cause; + } + } + writer.continueMeasure(); + + if (asm != null) { + asm.getActionSourcePrefix(writer); + } + if (convertException == null) { + Graph.graphToString(tree, writer, new LocalData()); + } else if (convertException instanceof TimeoutException) { + Helper.appendTimeoutComment(writer, timeout); + } else { + Helper.appendErrorComment(writer, convertException); + } + if (asm != null) { + asm.getActionSourceSuffix(writer); + } + } + + /** + * Converts list of actions to List of treeItems + * + * @param regNames Register names + * @param variables + * @param functions + * @param actions List of actions + * @param version SWF version + * @param staticOperation + * @param path + * @return List of treeItems + * @throws java.lang.InterruptedException + */ + public static List actionsToTree(HashMap regNames, HashMap variables, HashMap functions, List actions, int version, int staticOperation, String path) throws InterruptedException { + return ActionGraph.translateViaGraph(regNames, variables, functions, actions, version, staticOperation, path); + } + + @Override + public void translate(BaseLocalData localData, TranslateStack stack, List output, int staticOperation, String path) throws InterruptedException { + ActionLocalData aLocalData = (ActionLocalData) localData; + translate(stack, output, aLocalData.regNames, aLocalData.variables, aLocalData.functions, staticOperation, path); + } + + @Override + public boolean isJump() { + return false; + } + + @Override + public boolean isBranch() { + return false; + } + + @Override + public boolean isExit() { + return false; + } + + @Override + public long getOffset() { + return getAddress(); + } + + @Override + public List getBranches(GraphSource code) { + return new ArrayList<>(); + } + + @Override + public boolean isIgnored() { + return ignored; + } + + @Override + public void setIgnored(boolean ignored, int pos) { + this.ignored = ignored; + } + + private static class Loop { + + public long loopContinue; + + public long loopBreak; + + public int continueCount = 0; + + public int breakCount = 0; + + public Loop(long loopContinue, long loopBreak) { + this.loopContinue = loopContinue; + this.loopBreak = loopBreak; + } + + @Override + public String toString() { + return "[Loop continue:" + loopContinue + ", break:" + loopBreak + "]"; + } + } + + private static void log(String s) { + logger.fine(s); + } + + public static List actionsPartToTree(HashMap registerNames, HashMap variables, HashMap functions, TranslateStack stack, List actions, int start, int end, int version, int staticOperation, String path) throws InterruptedException { + if (start < actions.size() && (end > 0) && (start > 0)) { + log("Entering " + start + "-" + end + (actions.size() > 0 ? (" (" + actions.get(start).toString() + " - " + actions.get(end == actions.size() ? end - 1 : end) + ")") : "")); + } + ActionLocalData localData = new ActionLocalData(registerNames, variables, functions); + List output = new ArrayList<>(); + int ip = start; + boolean isWhile = false; + boolean isForIn = false; + GraphTargetItem inItem = null; + int loopStart = 0; + loopip: + while (ip <= end) { + + long addr = ip2adr(actions, ip); + if (ip > end) { + break; + } + if (ip >= actions.size()) { + output.add(new ScriptEndItem()); + break; + } + Action action = actions.get(ip); + if (action.isIgnored()) { + ip++; + continue; + } + if (action instanceof GraphSourceItemContainer) { + GraphSourceItemContainer cnt = (GraphSourceItemContainer) action; + //List out=actionsPartToTree(new HashMap(), new HashMap(),new HashMap(), new TranslateStack(), src, ip+1,endip-1 , version); + long endAddr = action.getAddress() + cnt.getHeaderSize(); + String cntName = cnt.getName(); + List> outs = new ArrayList<>(); + HashMap variables2 = Helper.deepCopy(variables); + if (cnt instanceof ActionDefineFunction || cnt instanceof ActionDefineFunction2) { + for (int r = 0; r < 256; r++) { + if (variables2.containsKey("__register" + r)) { + variables2.remove("__register" + r); + } + } + } + for (long size : cnt.getContainerSizes()) { + if (size == 0) { + outs.add(new ArrayList()); + continue; + } + List out; + try { + out = ActionGraph.translateViaGraph(cnt.getRegNames(), variables2, functions, actions.subList(adr2ip(actions, endAddr), adr2ip(actions, endAddr + size)), version, staticOperation, path + (cntName == null ? "" : "/" + cntName)); + } catch (OutOfMemoryError | TranslateException | StackOverflowError ex2) { + logger.log(Level.SEVERE, "Decompilation error in: " + path, ex2); + if (ex2 instanceof OutOfMemoryError) { + Helper.freeMem(); + } + out = new ArrayList<>(); + out.add(new CommentItem(new String[]{ + "", + " * " + AppResources.translate("decompilationError"), + " * " + AppResources.translate("decompilationError.obfuscated"), + Helper.decompilationErrorAdd == null ? null : " * " + Helper.decompilationErrorAdd, + " * " + AppResources.translate("decompilationError.errorType") + ": " + + ex2.getClass().getSimpleName(), + ""})); + } + outs.add(out); + endAddr += size; + } + ((GraphSourceItemContainer) action).translateContainer(outs, stack, output, registerNames, variables, functions); + ip = adr2ip(actions, endAddr); + continue; + } + + //return in for..in + if ((action instanceof ActionPush) && (((ActionPush) action).values.size() == 1) && (((ActionPush) action).values.get(0) instanceof Null)) { + if (ip + 3 <= end) { + if ((actions.get(ip + 1) instanceof ActionEquals) || (actions.get(ip + 1) instanceof ActionEquals2)) { + if (actions.get(ip + 2) instanceof ActionNot) { + if (actions.get(ip + 3) instanceof ActionIf) { + ActionIf aif = (ActionIf) actions.get(ip + 3); + if (adr2ip(actions, ip2adr(actions, ip + 4) + aif.getJumpOffset()) == ip) { + ip += 4; + continue; + } + } + } + } + } + } + + /*ActionJump && ActionIf removed*/ + /*if ((action instanceof ActionEnumerate2) || (action instanceof ActionEnumerate)) { + loopStart = ip + 1; + isForIn = true; + ip += 4; + action.translate(localData, stack, output); + EnumerateActionItem en = (EnumerateActionItem) stack.peek(); + inItem = en.object; + continue; + } else*/ /*if (action instanceof ActionTry) { + ActionTry atry = (ActionTry) action; + List tryCommands = ActionGraph.translateViaGraph(registerNames, variables, functions, atry.tryBody, version); + ActionItem catchName; + if (atry.catchInRegisterFlag) { + catchName = new DirectValueActionItem(atry, -1, new RegisterNumber(atry.catchRegister), new ArrayList()); + } else { + catchName = new DirectValueActionItem(atry, -1, atry.catchName, new ArrayList()); + } + List catchExceptions = new ArrayList(); + catchExceptions.add(catchName); + List> catchCommands = new ArrayList>(); + catchCommands.add(ActionGraph.translateViaGraph(registerNames, variables, functions, atry.catchBody, version)); + List finallyCommands = ActionGraph.translateViaGraph(registerNames, variables, functions, atry.finallyBody, version); + output.add(new TryActionItem(tryCommands, catchExceptions, catchCommands, finallyCommands)); + } else if (action instanceof ActionWith) { + ActionWith awith = (ActionWith) action; + List withCommands = ActionGraph.translateViaGraph(registerNames, variables, functions,new ArrayList() , version); //TODO:parse with actions + output.add(new WithActionItem(action, stack.pop(), withCommands)); + } else */ if (false) { + } /*if (action instanceof ActionStoreRegister) { + if ((ip + 1 <= end) && (actions.get(ip + 1) instanceof ActionPop)) { + action.translate(localData, stack, output); + stack.pop(); + ip++; + } else { + try { + action.translate(localData, stack, output); + } catch (Exception ex) { + // ignore + } + } + } */ /*else if (action instanceof ActionStrictEquals) { + if ((ip + 1 < actions.size()) && (actions.get(ip + 1) instanceof ActionIf)) { + List caseValues = new ArrayList(); + List> caseCommands = new ArrayList>(); + caseValues.add(stack.pop()); + ActionItem switchedObject = stack.pop(); + if (output.size() > 0) { + if (output.get(output.size() - 1) instanceof StoreRegisterActionItem) { + output.remove(output.size() - 1); + } + } + int caseStart = ip + 2; + List caseBodyIps = new ArrayList(); + long defaultAddr = 0; + caseBodyIps.add(adr2ip(actions, ((ActionIf) actions.get(ip + 1)).getRef(version), version)); + ip++; + do { + ip++; + if ((actions.get(ip - 1) instanceof ActionStrictEquals) && (actions.get(ip) instanceof ActionIf)) { + caseValues.add(actionsToStackTree(registerNames, jumpsOrIfs, actions, constants, caseStart, ip - 2, version).pop()); + caseStart = ip + 1; + caseBodyIps.add(adr2ip(actions, ((ActionIf) actions.get(ip)).getRef(version), version)); + if (actions.get(ip + 1) instanceof ActionJump) { + defaultAddr = ((ActionJump) actions.get(ip + 1)).getRef(version); + ip = adr2ip(actions, defaultAddr, version); + break; + } + } + } while (ip < end); + + for (int i = 0; i < caseBodyIps.size(); i++) { + int caseEnd = ip - 1; + if (i < caseBodyIps.size() - 1) { + caseEnd = caseBodyIps.get(i + 1) - 1; + } + caseCommands.add(actionsToTree(registerNames, unknownJumps, loopList, jumpsOrIfs, stack, constants, actions, caseBodyIps.get(i), caseEnd, version)); + } + output.add(new SwitchActionItem(action, defaultAddr, switchedObject, caseValues, caseCommands, null)); + continue; + } else { + action.translate(stack, constants, output, registerNames); + } + } */ else { + + if (action instanceof ActionStore) { + ActionStore store = (ActionStore) action; + store.setStore(actions.subList(ip + 1, ip + 1 + store.getStoreSize())); + ip = ip + 1 + store.getStoreSize() - 1/*ip++ will be next*/; + } + + try { + action.translate(localData, stack, output, staticOperation, path); + } catch (EmptyStackException ese) { + logger.log(Level.SEVERE, "Decompilation error in: " + path, ese); + output.add(new UnsupportedActionItem(action, "Empty stack")); + } + + } + + ip++; + } + //output = checkClass(output); + log("Leaving " + start + "-" + end); + return output; + } + + public static GraphTargetItem getWithoutGlobal(GraphTargetItem ti) { + GraphTargetItem t = ti; + if (!(t instanceof GetMemberActionItem)) { + return ti; + } + GetMemberActionItem lastMember = null; + while (((GetMemberActionItem) t).object instanceof GetMemberActionItem) { + lastMember = (GetMemberActionItem) t; + t = ((GetMemberActionItem) t).object; + } + if (((GetMemberActionItem) t).object instanceof GetVariableActionItem) { + GetVariableActionItem v = (GetVariableActionItem) ((GetMemberActionItem) t).object; + if (v.name instanceof DirectValueActionItem) { + if (((DirectValueActionItem) v.name).value instanceof String) { + if (((DirectValueActionItem) v.name).value.equals("_global")) { + GetVariableActionItem gvt = new GetVariableActionItem(null, ((GetMemberActionItem) t).memberName); + if (lastMember == null) { + return gvt; + } else { + lastMember.object = gvt; + } + } + } + } + } + return ti; + } + + public static List checkClass(List output) { + if (true) { + //return output; + } + List ret = new ArrayList<>(); + List functions = new ArrayList<>(); + List staticFunctions = new ArrayList<>(); + List> vars = new ArrayList<>(); + List> staticVars = new ArrayList<>(); + GraphTargetItem className; + GraphTargetItem extendsOp = null; + List implementsOp = new ArrayList<>(); + boolean ok = true; + int prevCount = 0; + for (GraphTargetItem t : output) { + if (t instanceof IfItem) { + IfItem it = (IfItem) t; + if (it.expression instanceof NotItem) { + NotItem nti = (NotItem) it.expression; + if ((nti.value instanceof GetMemberActionItem) || (nti.value instanceof GetVariableActionItem)) { + if (true) { //it.onFalse.isEmpty()){ //||(it.onFalse.get(0) instanceof UnsupportedActionItem)) { + if ((it.onTrue.size() == 1) && (it.onTrue.get(0) instanceof SetMemberActionItem) && (((SetMemberActionItem) it.onTrue.get(0)).value instanceof NewObjectActionItem)) { + // ignore + } else { + List parts = it.onTrue; + className = getWithoutGlobal(nti.value); + if (parts.size() >= 1) { + int ipos = 0; + while ((parts.get(ipos) instanceof IfItem) + && ((((IfItem) parts.get(ipos)).onTrue.size() == 1) && (((IfItem) parts.get(ipos)).onTrue.get(0) instanceof SetMemberActionItem) && (((SetMemberActionItem) ((IfItem) parts.get(ipos)).onTrue.get(0)).value instanceof NewObjectActionItem))) { + + ipos++; + } + if (parts.get(ipos) instanceof ExtendsActionItem) { + ExtendsActionItem et = (ExtendsActionItem) parts.get(ipos); + extendsOp = getWithoutGlobal(et.superclass); + ipos++; + } + if (parts.get(ipos) instanceof StoreRegisterActionItem) { + StoreRegisterActionItem sr = (StoreRegisterActionItem) parts.get(ipos); + int instanceReg = sr.register.number; + if (sr.value instanceof GetMemberActionItem) { + GetMemberActionItem gm = (GetMemberActionItem) sr.value; + //gm.memberName should be "prototype" + if (gm.object instanceof TemporaryRegister) { + TemporaryRegister tm = (TemporaryRegister) gm.object; + int classReg = tm.getRegId(); + if (tm.value instanceof SetMemberActionItem) { + SetMemberActionItem sm = (SetMemberActionItem) tm.value; + if (sm.value instanceof StoreRegisterActionItem) { + sr = (StoreRegisterActionItem) sm.value; + if (sr.value instanceof FunctionActionItem) { + ((FunctionActionItem) (sr.value)).calculatedFunctionName = (className instanceof GetMemberActionItem) ? ((GetMemberActionItem) className).memberName : className; + functions.add((FunctionActionItem) sr.value); + + for (; ipos < parts.size(); ipos++) { + if (parts.get(ipos) instanceof ImplementsOpActionItem) { + ImplementsOpActionItem io = (ImplementsOpActionItem) parts.get(ipos); + implementsOp = io.superclasses; + continue; + } + if (parts.get(ipos) instanceof SetMemberActionItem) { + sm = (SetMemberActionItem) parts.get(ipos); + int rnum = -1; + if (sm.object instanceof DirectValueActionItem) { + DirectValueActionItem dv = (DirectValueActionItem) sm.object; + if (dv.value instanceof RegisterNumber) { + RegisterNumber rn = (RegisterNumber) dv.value; + rnum = rn.number; + } + } + if (sm.object instanceof TemporaryRegister) { + rnum = ((TemporaryRegister) sm.object).getRegId(); + } + if (rnum == instanceReg) { + if (sm.value instanceof FunctionActionItem) { + ((FunctionActionItem) sm.value).calculatedFunctionName = sm.objectName; + functions.add((FunctionActionItem) sm.value); + } else { + vars.add(new MyEntry<>(sm.objectName, sm.value)); + } + } else if (rnum == classReg) { + if (sm.value instanceof FunctionActionItem) { + ((FunctionActionItem) sm.value).calculatedFunctionName = sm.objectName; + staticFunctions.add((FunctionActionItem) sm.value); + } else { + staticVars.add(new MyEntry<>(sm.objectName, sm.value)); + } + } + + } + } + + } + + } + } + List output2 = new ArrayList<>(); + for (int i = 0; i < prevCount; i++) { + output2.add(output.get(i)); + } + output2.add(new ClassActionItem(className, extendsOp, implementsOp, null/*FIXME*/, functions, vars, staticFunctions, staticVars)); + return output2; + } + } + } else if (parts.get(ipos) instanceof SetMemberActionItem) { + SetMemberActionItem sm = (SetMemberActionItem) parts.get(0); + if (sm.value instanceof FunctionActionItem) { + FunctionActionItem f = (FunctionActionItem) sm.value; + if (f.actions.isEmpty()) { + if (parts.size() == 2) { + if (parts.get(1) instanceof ImplementsOpActionItem) { + ImplementsOpActionItem iot = (ImplementsOpActionItem) parts.get(1); + implementsOp = iot.superclasses; + } else { + ok = false; + break; + } + } + List output2 = new ArrayList<>(); + for (int i = 0; i < prevCount; i++) { + output2.add(output.get(i)); + } + output2.add(new InterfaceActionItem(sm.objectName, implementsOp)); + return output2; + } + } + } + } + } + } else { + ok = false; + } + } else { + ok = false; + } + } else { + ok = false; + } + } else { + prevCount++; + //ok = false; + } + if (!ok) { + break; + } + } + return output; + } + + @Override + public boolean ignoredLoops() { + return false; + } + + public static void setConstantPool(List actions, ConstantPool cpool) { + for (GraphSourceItem a : actions) { + if (a instanceof ActionPush) { + if (cpool != null) { + ((ActionPush) a).constantPool = cpool.constants; + } + } + if (a instanceof ActionDefineFunction) { + if (cpool != null) { + //((ActionDefineFunction) a).setConstantPool(cpool.constants,actions); + } + } + if (a instanceof ActionDefineFunction2) { + if (cpool != null) { + //((ActionDefineFunction2) a).setConstantPool(cpool.constants,actions); + } + } + } + } + + public GraphTextWriter getASMSourceReplaced(ActionList container, Set knownAddreses, ScriptExportMode exportMode, GraphTextWriter writer) { + writer.appendNoHilight(getASMSource(container, knownAddreses, exportMode)); + return writer; + } + + public static double toFloatPoint(Object o) { + if (o instanceof Double) { + return (Double) o; + } + if (o instanceof Integer) { + return (Integer) o; + } + if (o instanceof Long) { + return (Long) o; + } + if (o instanceof String) { + try { + return Double.parseDouble((String) o); + } catch (NumberFormatException nfe) { + return 0; + } + } + return 0; + } + + public static GraphTargetItem gettoset(GraphTargetItem get, GraphTargetItem value, List variables) { + GraphTargetItem ret = get; + boolean boxed = false; + if (get instanceof VariableActionItem) { + boxed = true; + ret = ((VariableActionItem) ret).getBoxedValue(); + } + if (ret instanceof GetVariableActionItem) { + GetVariableActionItem gv = (GetVariableActionItem) ret; + ret = new SetVariableActionItem(null, gv.name, value); + } else if (ret instanceof GetMemberActionItem) { + GetMemberActionItem mem = (GetMemberActionItem) ret; + ret = new SetMemberActionItem(null, mem.object, mem.memberName, value); + } else if ((ret instanceof DirectValueActionItem) && ((DirectValueActionItem) ret).value instanceof RegisterNumber) { + ret = new StoreRegisterActionItem(null, (RegisterNumber) ((DirectValueActionItem) ret).value, value, false); + } else if (ret instanceof GetPropertyActionItem) { + GetPropertyActionItem gp = (GetPropertyActionItem) ret; + ret = new SetPropertyActionItem(null, gp.target, gp.propertyIndex, value); + } + if (boxed) { + GraphTargetItem b = ret; + ret = new VariableActionItem(((VariableActionItem) get).getVariableName(), value, ((VariableActionItem) get).isDefinition()); + ((VariableActionItem) ret).setBoxedValue((ActionItem) b); + variables.remove((VariableActionItem) get); + variables.add((VariableActionItem) ret); + } + return ret; + } + + @Override + public boolean isDeobfuscatePop() { + return false; + } + + @Override + public int getLine() { + return 0; + } + + @Override + public String getFile() { + return null; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/ActionGraph.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/ActionGraph.java index 4b726c89c..f0cda222a 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/ActionGraph.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/ActionGraph.java @@ -1,487 +1,487 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.action; - -import com.jpexs.decompiler.flash.BaseLocalData; -import com.jpexs.decompiler.flash.FinalProcessLocalData; -import com.jpexs.decompiler.flash.action.model.DirectValueActionItem; -import com.jpexs.decompiler.flash.action.model.EnumerateActionItem; -import com.jpexs.decompiler.flash.action.model.FunctionActionItem; -import com.jpexs.decompiler.flash.action.model.SetTarget2ActionItem; -import com.jpexs.decompiler.flash.action.model.SetTargetActionItem; -import com.jpexs.decompiler.flash.action.model.SetTypeActionItem; -import com.jpexs.decompiler.flash.action.model.StoreRegisterActionItem; -import com.jpexs.decompiler.flash.action.model.clauses.ForInActionItem; -import com.jpexs.decompiler.flash.action.model.clauses.TellTargetActionItem; -import com.jpexs.decompiler.flash.action.model.operations.NeqActionItem; -import com.jpexs.decompiler.flash.action.model.operations.StrictEqActionItem; -import com.jpexs.decompiler.flash.action.swf4.ActionEquals; -import com.jpexs.decompiler.flash.action.swf4.ActionIf; -import com.jpexs.decompiler.flash.action.swf4.ActionNot; -import com.jpexs.decompiler.flash.action.swf4.ActionPush; -import com.jpexs.decompiler.flash.action.swf4.RegisterNumber; -import com.jpexs.decompiler.flash.action.swf5.ActionEquals2; -import com.jpexs.decompiler.flash.action.swf5.ActionStoreRegister; -import com.jpexs.decompiler.flash.action.swf6.ActionStrictEquals; -import com.jpexs.decompiler.flash.ecma.Null; -import com.jpexs.decompiler.graph.Graph; -import com.jpexs.decompiler.graph.GraphPart; -import com.jpexs.decompiler.graph.GraphSource; -import com.jpexs.decompiler.graph.GraphSourceItem; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.Loop; -import com.jpexs.decompiler.graph.TranslateStack; -import com.jpexs.decompiler.graph.model.BreakItem; -import com.jpexs.decompiler.graph.model.ContinueItem; -import com.jpexs.decompiler.graph.model.SwitchItem; -import com.jpexs.decompiler.graph.model.WhileItem; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; - -/** - * - * @author JPEXS - */ -public class ActionGraph extends Graph { - - public ActionGraph(List code, HashMap registerNames, HashMap variables, HashMap functions, int version) { - super(new ActionGraphSource(code, version, registerNames, variables, functions), new ArrayList()); - //this.version = version; - /*heads = makeGraph(code, new ArrayList()); - for (GraphPart head : heads) { - fixGraph(head); - makeMulti(head, new ArrayList()); - }*/ - } - - public static List translateViaGraph(HashMap registerNames, HashMap variables, HashMap functions, List code, int version, int staticOperation, String path) throws InterruptedException { - - ActionGraph g = new ActionGraph(code, registerNames, variables, functions, version); - ActionLocalData localData = new ActionLocalData(registerNames); - g.init(localData); - return g.translate(localData, staticOperation, path); - } - - @Override - public void finalProcessStack(TranslateStack stack, List output) { - if (stack.size() > 0) { - for (int i = stack.size() - 1; i >= 0; i--) { - //System.err.println(stack.get(i)); - if (stack.get(i) instanceof FunctionActionItem) { - FunctionActionItem f = (FunctionActionItem) stack.remove(i); - if (!output.contains(f)) { - output.add(0, f); - } - } - } - } - } - - @Override - protected void finalProcess(List list, int level, FinalProcessLocalData localData) { - super.finalProcess(list, level, localData); - List ret = Action.checkClass(list); - if (ret != list) { - list.clear(); - list.addAll(ret); - } - int targetStart; - int targetEnd; - - boolean again; - do { - again = false; - targetStart = -1; - targetEnd = -1; - GraphTargetItem targetStartItem = null; - GraphTargetItem target = null; - for (int t = 0; t < list.size(); t++) { - GraphTargetItem it = list.get(t); - if (it instanceof SetTargetActionItem) { - SetTargetActionItem st = (SetTargetActionItem) it; - if (st.target.isEmpty()) { - if (targetStart > -1) { - targetEnd = t; - break; - } - } else { - target = new DirectValueActionItem(null, 0, st.target, new ArrayList()); - targetStart = t; - targetStartItem = it; - } - } - if (it instanceof SetTarget2ActionItem) { - SetTarget2ActionItem st = (SetTarget2ActionItem) it; - if ((st.target instanceof DirectValueActionItem) && st.target.getResult().equals("")) { - if (targetStart > -1) { - targetEnd = t; - break; - } - } else { - targetStart = t; - target = st.target; - targetStartItem = it; - } - } - } - if ((targetStart > -1) && (targetEnd > -1)) { - List newlist = new ArrayList<>(); - for (int i = 0; i < targetStart; i++) { - newlist.add(list.get(i)); - } - List tellist = new ArrayList<>(); - for (int i = targetStart + 1; i < targetEnd; i++) { - tellist.add(list.get(i)); - } - newlist.add(new TellTargetActionItem(targetStartItem.src, target, tellist)); - for (int i = targetEnd + 1; i < list.size(); i++) { - newlist.add(list.get(i)); - } - list.clear(); - list.addAll(newlist); - again = true; - } - } while (again); - for (int t = 0; t < list.size(); t++) { - GraphTargetItem it = list.get(t); - - if (it instanceof WhileItem) { - WhileItem wi = (WhileItem) it; - if ((!wi.commands.isEmpty()) && (wi.commands.get(0) instanceof SetTypeActionItem)) { - SetTypeActionItem sti = (SetTypeActionItem) wi.commands.get(0); - if (wi.expression.get(wi.expression.size() - 1) instanceof NeqActionItem) { - NeqActionItem ne = (NeqActionItem) wi.expression.get(wi.expression.size() - 1); - if (ne.rightSide instanceof DirectValueActionItem) { - DirectValueActionItem dv = (DirectValueActionItem) ne.rightSide; - if (dv.value instanceof Null) { - GraphTargetItem en = ne.leftSide; - if (en instanceof StoreRegisterActionItem) { - en = ((StoreRegisterActionItem) en).value; - } - if (en instanceof EnumerateActionItem) { - EnumerateActionItem eti = (EnumerateActionItem) en; - list.remove(t); - wi.commands.remove(0); - list.add(t, new ForInActionItem(null, wi.loop, sti.getObject(), eti.object, wi.commands)); - } - } - } - } - } - - } - } - //detectChained(list, temporaryRegisters); - } - - @Override - protected List checkPrecoNextParts(GraphPart part) { - List items = getPartItems(part); - part = makeMultiPart(part); - if (items.size() > 1) { - if (items.get(items.size() - 1) instanceof ActionIf) { - if (items.get(items.size() - 2) instanceof ActionStrictEquals) { - List storeRegisters = new ArrayList<>(); - for (GraphSourceItem s : items) { - if (s instanceof ActionStoreRegister) { - ActionStoreRegister sr = (ActionStoreRegister) s; - storeRegisters.add(sr.registerNumber); - } - } - if (!storeRegisters.isEmpty()) { - List caseBodies = new ArrayList<>(); - boolean proceed = false; - do { - proceed = false; - caseBodies.add(part.nextParts.get(0)); //jump - part = part.nextParts.get(1); //nojump - items = getPartItems(part); - part = makeMultiPart(part); - if (!items.isEmpty()) { - if (items.get(0) instanceof ActionPush) { - ActionPush pu = (ActionPush) items.get(0); - if (!pu.values.isEmpty()) { - if (pu.values.get(0) instanceof RegisterNumber) { - RegisterNumber rn = (RegisterNumber) pu.values.get(0); - if (storeRegisters.contains(rn.number)) { - storeRegisters.clear(); - storeRegisters.add(rn.number); - if (items.get(items.size() - 1) instanceof ActionIf) { - if (items.size() > 1) { - if (items.get(items.size() - 2) instanceof ActionStrictEquals) { - proceed = true; - } - } - } - } - } - } - } - } - } while (proceed); - - if (caseBodies.size() > 1) { - caseBodies.add(part); //TODO: properly detect default clause (?) - return caseBodies; - } - } - } - } - } - return null; - } - - @Override - protected List check(GraphSource code, BaseLocalData localData, List allParts, TranslateStack stack, GraphPart parent, GraphPart part, List stopPart, List loops, List output, Loop currentLoop, int staticOperation, String path) throws InterruptedException { - if (!output.isEmpty()) { - if (output.get(output.size() - 1) instanceof StoreRegisterActionItem) { - StoreRegisterActionItem str = (StoreRegisterActionItem) output.get(output.size() - 1); - if (str.value instanceof EnumerateActionItem) { - output.remove(output.size() - 1); - } - } - } - List ret = null; - if ((part.nextParts.size() == 2) && (!stack.isEmpty()) && (stack.peek() instanceof StrictEqActionItem)) { - - GraphTargetItem switchedObject = null; - if (!output.isEmpty()) { - if (output.get(output.size() - 1) instanceof StoreRegisterActionItem) { - switchedObject = ((StoreRegisterActionItem) output.get(output.size() - 1)).value; - } - } - if (switchedObject == null) { - switchedObject = new DirectValueActionItem(null, -1, new Null(), null); - } - HashMap caseValuesMap = new HashMap<>(); - - int pos = 0; - StrictEqActionItem set = (StrictEqActionItem) stack.pop(); - caseValuesMap.put(pos, set.rightSide); - if (set.leftSide instanceof StoreRegisterActionItem) { - switchedObject = ((StoreRegisterActionItem) set.leftSide).value; - } - //GraphPart switchLoc = part.nextParts.get(1).nextParts.get(0); - List caseBodyParts = new ArrayList<>(); - caseBodyParts.add(part.nextParts.get(0)); - GraphTargetItem top = null; - int cnt = 1; - while (part.nextParts.size() > 1 - && part.nextParts.get(1).getHeight() > 1 - && code.get(part.nextParts.get(1).end >= code.size() ? code.size() - 1 : part.nextParts.get(1).end) instanceof ActionIf - && ((top = translatePartGetStack(localData, part.nextParts.get(1), stack, staticOperation)) instanceof StrictEqActionItem)) { - cnt++; - part = part.nextParts.get(1); - pos++; - caseBodyParts.add(part.nextParts.get(0)); - - set = (StrictEqActionItem) top; - caseValuesMap.put(pos, set.rightSide); - } - if (cnt == 1) { - stack.push(set); - } else { - part = part.nextParts.get(1); - - GraphPart defaultPart = part; //21-21 - //caseBodyParts.add(defaultPart); - - List defaultAndLastPart = new ArrayList<>(); - defaultAndLastPart.add(defaultPart); - defaultAndLastPart.add(caseBodyParts.get(caseBodyParts.size() - 1)); - - GraphPart defaultPart2 = getCommonPart(localData, defaultAndLastPart, loops);//34-37 - - List defaultCommands = new ArrayList<>(); - List stopPart2 = new ArrayList<>(stopPart); - stopPart2.add(defaultPart2); - defaultCommands = printGraph(localData, stack, allParts, null, defaultPart, stopPart2, loops, staticOperation, path); - - List loopContinues = new ArrayList<>(); - for (Loop l : loops) { - if (l.loopContinue != null) { - loopContinues.add(l.loopContinue); - } - } - - List breakParts = new ArrayList<>(); - /*for (int g = 0; g < caseBodyParts.size(); g++) { - if (g < caseBodyParts.size() - 1) { - if (caseBodyParts.get(g).leadsTo(code, caseBodyParts.get(g + 1), loops)) { - continue; - } - } - GraphPart nsp = caseBodyParts.get(g).getNextSuperPartPath(loopContinues); - if (nsp != null) { - breakParts.add(nsp); - } - } - Collections.sort(breakParts, new Comparator() { - @Override - public int compare(GraphPart o1, GraphPart o2) { - return o2.path.length() - o1.path.length(); - } - });*/ - - //GraphPart breakPart = breakParts.isEmpty() ? null : breakParts.get(0); - List mcp = new ArrayList<>(); - mcp.addAll(caseBodyParts); - if (defaultPart2 != null) { - mcp.add(defaultPart2); - } - GraphPart breakPart = getMostCommonPart(localData, mcp, loops); - if ((defaultPart2 != breakPart) && (defaultCommands.isEmpty())) { - defaultPart = defaultPart2; - } - - List caseValues = new ArrayList<>(); - for (int i = 0; i < caseBodyParts.size(); i++) { - if (caseValuesMap.containsKey(i)) { - caseValues.add(caseValuesMap.get(i)); - } else { - continue; - } - } - - List> caseCommands = new ArrayList<>(); - GraphPart next = null; - - next = breakPart; - - GraphTargetItem ti = checkLoop(next, stopPart, loops); - currentLoop = new Loop(loops.size(), null, next); - currentLoop.phase = 1; - loops.add(currentLoop); - //switchLoc.getNextPartPath(new ArrayList()); - List valuesMapping = new ArrayList<>(); - List caseBodies = new ArrayList<>(); - for (int i = 0; i < caseValues.size(); i++) { - GraphPart cur = caseBodyParts.get(i); - if (!caseBodies.contains(cur)) { - caseBodies.add(cur); - } - valuesMapping.add(caseBodies.indexOf(cur)); - } - - if (defaultPart == breakPart) { - defaultPart = null; - } - if ((defaultPart != null) && (defaultCommands.isEmpty())) { - List stopPart2x = new ArrayList<>(stopPart); - stopPart2x.add(next); - defaultCommands = printGraph(localData, stack, allParts, null, defaultPart, stopPart2x, loops, staticOperation, path); - } - - if (!defaultCommands.isEmpty()) { - if (defaultCommands.get(defaultCommands.size() - 1) instanceof BreakItem) { - BreakItem bi = (BreakItem) defaultCommands.get(defaultCommands.size() - 1); - if (bi.loopId == currentLoop.id) { - defaultCommands.remove(defaultCommands.size() - 1); - } - } - } - - List ignored = new ArrayList<>(); - for (Loop l : loops) { - ignored.add(l.loopContinue); - } - - for (int i = 0; i < caseBodies.size(); i++) { - List cc = new ArrayList<>(); - GraphPart nextCase = null; - nextCase = next; - if (next != null) { - if (i < caseBodies.size() - 1) { - if (!caseBodies.get(i).leadsTo(localData, this, code, caseBodies.get(i + 1), loops)) { - cc.add(new BreakItem(null, currentLoop.id)); - } else { - nextCase = caseBodies.get(i + 1); - } - } else if (!defaultCommands.isEmpty()) { - if (!caseBodies.get(i).leadsTo(localData, this, code, defaultPart, loops)) { - cc.add(new BreakItem(null, currentLoop.id)); - } else { - nextCase = defaultPart; - } - } - } - List stopPart2x = new ArrayList<>(stopPart); - //stopPart2.add(nextCase); - for (GraphPart b : caseBodies) { - if (b != caseBodies.get(i)) { - stopPart2x.add(b); - } - } - if (defaultPart != null) { - stopPart2x.add(defaultPart); - } - if (breakPart != null) { - stopPart2x.add(breakPart); - } - cc.addAll(0, printGraph(localData, stack, allParts, null, caseBodies.get(i), stopPart2x, loops, staticOperation, path)); - if (cc.size() >= 2) { - if (cc.get(cc.size() - 1) instanceof BreakItem) { - if ((cc.get(cc.size() - 2) instanceof ContinueItem) || (cc.get(cc.size() - 2) instanceof BreakItem)) { - cc.remove(cc.size() - 1); - } - } - } - caseCommands.add(cc); - } - ret = new ArrayList<>(); - ret.addAll(output); - SwitchItem sti = new SwitchItem(null, currentLoop, switchedObject, caseValues, caseCommands, defaultCommands, valuesMapping); - ret.add(sti); - currentLoop.phase = 2; - if (next != null) { - if (ti != null) { - ret.add(ti); - } else { - ret.addAll(printGraph(localData, stack, allParts, null, next, stopPart, loops, staticOperation, path)); - } - } - } - } - return ret; - } - - @Override - protected int checkIp(int ip) { - int oldIp = ip; - //return in for..in - GraphSourceItem action = code.get(ip); - if ((action instanceof ActionPush) && (((ActionPush) action).values.size() == 1) && (((ActionPush) action).values.get(0) instanceof Null)) { - if (ip + 3 < code.size()) { - if ((code.get(ip + 1) instanceof ActionEquals) || (code.get(ip + 1) instanceof ActionEquals2)) { - if (code.get(ip + 2) instanceof ActionNot) { - if (code.get(ip + 3) instanceof ActionIf) { - ActionIf aif = (ActionIf) code.get(ip + 3); - if (code.adr2pos(code.pos2adr(ip + 4) + aif.getJumpOffset()) == ip) { - ip += 4; - } - } - } - } - } - } - if (oldIp != ip) { - return checkIp(ip); - } - return ip; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.action; + +import com.jpexs.decompiler.flash.BaseLocalData; +import com.jpexs.decompiler.flash.FinalProcessLocalData; +import com.jpexs.decompiler.flash.action.model.DirectValueActionItem; +import com.jpexs.decompiler.flash.action.model.EnumerateActionItem; +import com.jpexs.decompiler.flash.action.model.FunctionActionItem; +import com.jpexs.decompiler.flash.action.model.SetTarget2ActionItem; +import com.jpexs.decompiler.flash.action.model.SetTargetActionItem; +import com.jpexs.decompiler.flash.action.model.SetTypeActionItem; +import com.jpexs.decompiler.flash.action.model.StoreRegisterActionItem; +import com.jpexs.decompiler.flash.action.model.clauses.ForInActionItem; +import com.jpexs.decompiler.flash.action.model.clauses.TellTargetActionItem; +import com.jpexs.decompiler.flash.action.model.operations.NeqActionItem; +import com.jpexs.decompiler.flash.action.model.operations.StrictEqActionItem; +import com.jpexs.decompiler.flash.action.swf4.ActionEquals; +import com.jpexs.decompiler.flash.action.swf4.ActionIf; +import com.jpexs.decompiler.flash.action.swf4.ActionNot; +import com.jpexs.decompiler.flash.action.swf4.ActionPush; +import com.jpexs.decompiler.flash.action.swf4.RegisterNumber; +import com.jpexs.decompiler.flash.action.swf5.ActionEquals2; +import com.jpexs.decompiler.flash.action.swf5.ActionStoreRegister; +import com.jpexs.decompiler.flash.action.swf6.ActionStrictEquals; +import com.jpexs.decompiler.flash.ecma.Null; +import com.jpexs.decompiler.graph.Graph; +import com.jpexs.decompiler.graph.GraphPart; +import com.jpexs.decompiler.graph.GraphSource; +import com.jpexs.decompiler.graph.GraphSourceItem; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.Loop; +import com.jpexs.decompiler.graph.TranslateStack; +import com.jpexs.decompiler.graph.model.BreakItem; +import com.jpexs.decompiler.graph.model.ContinueItem; +import com.jpexs.decompiler.graph.model.SwitchItem; +import com.jpexs.decompiler.graph.model.WhileItem; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +/** + * + * @author JPEXS + */ +public class ActionGraph extends Graph { + + public ActionGraph(List code, HashMap registerNames, HashMap variables, HashMap functions, int version) { + super(new ActionGraphSource(code, version, registerNames, variables, functions), new ArrayList()); + //this.version = version; + /*heads = makeGraph(code, new ArrayList()); + for (GraphPart head : heads) { + fixGraph(head); + makeMulti(head, new ArrayList()); + }*/ + } + + public static List translateViaGraph(HashMap registerNames, HashMap variables, HashMap functions, List code, int version, int staticOperation, String path) throws InterruptedException { + + ActionGraph g = new ActionGraph(code, registerNames, variables, functions, version); + ActionLocalData localData = new ActionLocalData(registerNames); + g.init(localData); + return g.translate(localData, staticOperation, path); + } + + @Override + public void finalProcessStack(TranslateStack stack, List output) { + if (stack.size() > 0) { + for (int i = stack.size() - 1; i >= 0; i--) { + //System.err.println(stack.get(i)); + if (stack.get(i) instanceof FunctionActionItem) { + FunctionActionItem f = (FunctionActionItem) stack.remove(i); + if (!output.contains(f)) { + output.add(0, f); + } + } + } + } + } + + @Override + protected void finalProcess(List list, int level, FinalProcessLocalData localData) { + super.finalProcess(list, level, localData); + List ret = Action.checkClass(list); + if (ret != list) { + list.clear(); + list.addAll(ret); + } + int targetStart; + int targetEnd; + + boolean again; + do { + again = false; + targetStart = -1; + targetEnd = -1; + GraphTargetItem targetStartItem = null; + GraphTargetItem target = null; + for (int t = 0; t < list.size(); t++) { + GraphTargetItem it = list.get(t); + if (it instanceof SetTargetActionItem) { + SetTargetActionItem st = (SetTargetActionItem) it; + if (st.target.isEmpty()) { + if (targetStart > -1) { + targetEnd = t; + break; + } + } else { + target = new DirectValueActionItem(null, 0, st.target, new ArrayList()); + targetStart = t; + targetStartItem = it; + } + } + if (it instanceof SetTarget2ActionItem) { + SetTarget2ActionItem st = (SetTarget2ActionItem) it; + if ((st.target instanceof DirectValueActionItem) && st.target.getResult().equals("")) { + if (targetStart > -1) { + targetEnd = t; + break; + } + } else { + targetStart = t; + target = st.target; + targetStartItem = it; + } + } + } + if ((targetStart > -1) && (targetEnd > -1)) { + List newlist = new ArrayList<>(); + for (int i = 0; i < targetStart; i++) { + newlist.add(list.get(i)); + } + List tellist = new ArrayList<>(); + for (int i = targetStart + 1; i < targetEnd; i++) { + tellist.add(list.get(i)); + } + newlist.add(new TellTargetActionItem(targetStartItem.src, target, tellist)); + for (int i = targetEnd + 1; i < list.size(); i++) { + newlist.add(list.get(i)); + } + list.clear(); + list.addAll(newlist); + again = true; + } + } while (again); + for (int t = 0; t < list.size(); t++) { + GraphTargetItem it = list.get(t); + + if (it instanceof WhileItem) { + WhileItem wi = (WhileItem) it; + if ((!wi.commands.isEmpty()) && (wi.commands.get(0) instanceof SetTypeActionItem)) { + SetTypeActionItem sti = (SetTypeActionItem) wi.commands.get(0); + if (wi.expression.get(wi.expression.size() - 1) instanceof NeqActionItem) { + NeqActionItem ne = (NeqActionItem) wi.expression.get(wi.expression.size() - 1); + if (ne.rightSide instanceof DirectValueActionItem) { + DirectValueActionItem dv = (DirectValueActionItem) ne.rightSide; + if (dv.value instanceof Null) { + GraphTargetItem en = ne.leftSide; + if (en instanceof StoreRegisterActionItem) { + en = ((StoreRegisterActionItem) en).value; + } + if (en instanceof EnumerateActionItem) { + EnumerateActionItem eti = (EnumerateActionItem) en; + list.remove(t); + wi.commands.remove(0); + list.add(t, new ForInActionItem(null, wi.loop, sti.getObject(), eti.object, wi.commands)); + } + } + } + } + } + + } + } + //detectChained(list, temporaryRegisters); + } + + @Override + protected List checkPrecoNextParts(GraphPart part) { + List items = getPartItems(part); + part = makeMultiPart(part); + if (items.size() > 1) { + if (items.get(items.size() - 1) instanceof ActionIf) { + if (items.get(items.size() - 2) instanceof ActionStrictEquals) { + List storeRegisters = new ArrayList<>(); + for (GraphSourceItem s : items) { + if (s instanceof ActionStoreRegister) { + ActionStoreRegister sr = (ActionStoreRegister) s; + storeRegisters.add(sr.registerNumber); + } + } + if (!storeRegisters.isEmpty()) { + List caseBodies = new ArrayList<>(); + boolean proceed = false; + do { + proceed = false; + caseBodies.add(part.nextParts.get(0)); //jump + part = part.nextParts.get(1); //nojump + items = getPartItems(part); + part = makeMultiPart(part); + if (!items.isEmpty()) { + if (items.get(0) instanceof ActionPush) { + ActionPush pu = (ActionPush) items.get(0); + if (!pu.values.isEmpty()) { + if (pu.values.get(0) instanceof RegisterNumber) { + RegisterNumber rn = (RegisterNumber) pu.values.get(0); + if (storeRegisters.contains(rn.number)) { + storeRegisters.clear(); + storeRegisters.add(rn.number); + if (items.get(items.size() - 1) instanceof ActionIf) { + if (items.size() > 1) { + if (items.get(items.size() - 2) instanceof ActionStrictEquals) { + proceed = true; + } + } + } + } + } + } + } + } + } while (proceed); + + if (caseBodies.size() > 1) { + caseBodies.add(part); //TODO: properly detect default clause (?) + return caseBodies; + } + } + } + } + } + return null; + } + + @Override + protected List check(GraphSource code, BaseLocalData localData, List allParts, TranslateStack stack, GraphPart parent, GraphPart part, List stopPart, List loops, List output, Loop currentLoop, int staticOperation, String path) throws InterruptedException { + if (!output.isEmpty()) { + if (output.get(output.size() - 1) instanceof StoreRegisterActionItem) { + StoreRegisterActionItem str = (StoreRegisterActionItem) output.get(output.size() - 1); + if (str.value instanceof EnumerateActionItem) { + output.remove(output.size() - 1); + } + } + } + List ret = null; + if ((part.nextParts.size() == 2) && (!stack.isEmpty()) && (stack.peek() instanceof StrictEqActionItem)) { + + GraphTargetItem switchedObject = null; + if (!output.isEmpty()) { + if (output.get(output.size() - 1) instanceof StoreRegisterActionItem) { + switchedObject = ((StoreRegisterActionItem) output.get(output.size() - 1)).value; + } + } + if (switchedObject == null) { + switchedObject = new DirectValueActionItem(null, -1, new Null(), null); + } + HashMap caseValuesMap = new HashMap<>(); + + int pos = 0; + StrictEqActionItem set = (StrictEqActionItem) stack.pop(); + caseValuesMap.put(pos, set.rightSide); + if (set.leftSide instanceof StoreRegisterActionItem) { + switchedObject = ((StoreRegisterActionItem) set.leftSide).value; + } + //GraphPart switchLoc = part.nextParts.get(1).nextParts.get(0); + List caseBodyParts = new ArrayList<>(); + caseBodyParts.add(part.nextParts.get(0)); + GraphTargetItem top = null; + int cnt = 1; + while (part.nextParts.size() > 1 + && part.nextParts.get(1).getHeight() > 1 + && code.get(part.nextParts.get(1).end >= code.size() ? code.size() - 1 : part.nextParts.get(1).end) instanceof ActionIf + && ((top = translatePartGetStack(localData, part.nextParts.get(1), stack, staticOperation)) instanceof StrictEqActionItem)) { + cnt++; + part = part.nextParts.get(1); + pos++; + caseBodyParts.add(part.nextParts.get(0)); + + set = (StrictEqActionItem) top; + caseValuesMap.put(pos, set.rightSide); + } + if (cnt == 1) { + stack.push(set); + } else { + part = part.nextParts.get(1); + + GraphPart defaultPart = part; //21-21 + //caseBodyParts.add(defaultPart); + + List defaultAndLastPart = new ArrayList<>(); + defaultAndLastPart.add(defaultPart); + defaultAndLastPart.add(caseBodyParts.get(caseBodyParts.size() - 1)); + + GraphPart defaultPart2 = getCommonPart(localData, defaultAndLastPart, loops);//34-37 + + List defaultCommands = new ArrayList<>(); + List stopPart2 = new ArrayList<>(stopPart); + stopPart2.add(defaultPart2); + defaultCommands = printGraph(localData, stack, allParts, null, defaultPart, stopPart2, loops, staticOperation, path); + + List loopContinues = new ArrayList<>(); + for (Loop l : loops) { + if (l.loopContinue != null) { + loopContinues.add(l.loopContinue); + } + } + + List breakParts = new ArrayList<>(); + /*for (int g = 0; g < caseBodyParts.size(); g++) { + if (g < caseBodyParts.size() - 1) { + if (caseBodyParts.get(g).leadsTo(code, caseBodyParts.get(g + 1), loops)) { + continue; + } + } + GraphPart nsp = caseBodyParts.get(g).getNextSuperPartPath(loopContinues); + if (nsp != null) { + breakParts.add(nsp); + } + } + Collections.sort(breakParts, new Comparator() { + @Override + public int compare(GraphPart o1, GraphPart o2) { + return o2.path.length() - o1.path.length(); + } + });*/ + + //GraphPart breakPart = breakParts.isEmpty() ? null : breakParts.get(0); + List mcp = new ArrayList<>(); + mcp.addAll(caseBodyParts); + if (defaultPart2 != null) { + mcp.add(defaultPart2); + } + GraphPart breakPart = getMostCommonPart(localData, mcp, loops); + if ((defaultPart2 != breakPart) && (defaultCommands.isEmpty())) { + defaultPart = defaultPart2; + } + + List caseValues = new ArrayList<>(); + for (int i = 0; i < caseBodyParts.size(); i++) { + if (caseValuesMap.containsKey(i)) { + caseValues.add(caseValuesMap.get(i)); + } else { + continue; + } + } + + List> caseCommands = new ArrayList<>(); + GraphPart next = null; + + next = breakPart; + + GraphTargetItem ti = checkLoop(next, stopPart, loops); + currentLoop = new Loop(loops.size(), null, next); + currentLoop.phase = 1; + loops.add(currentLoop); + //switchLoc.getNextPartPath(new ArrayList()); + List valuesMapping = new ArrayList<>(); + List caseBodies = new ArrayList<>(); + for (int i = 0; i < caseValues.size(); i++) { + GraphPart cur = caseBodyParts.get(i); + if (!caseBodies.contains(cur)) { + caseBodies.add(cur); + } + valuesMapping.add(caseBodies.indexOf(cur)); + } + + if (defaultPart == breakPart) { + defaultPart = null; + } + if ((defaultPart != null) && (defaultCommands.isEmpty())) { + List stopPart2x = new ArrayList<>(stopPart); + stopPart2x.add(next); + defaultCommands = printGraph(localData, stack, allParts, null, defaultPart, stopPart2x, loops, staticOperation, path); + } + + if (!defaultCommands.isEmpty()) { + if (defaultCommands.get(defaultCommands.size() - 1) instanceof BreakItem) { + BreakItem bi = (BreakItem) defaultCommands.get(defaultCommands.size() - 1); + if (bi.loopId == currentLoop.id) { + defaultCommands.remove(defaultCommands.size() - 1); + } + } + } + + List ignored = new ArrayList<>(); + for (Loop l : loops) { + ignored.add(l.loopContinue); + } + + for (int i = 0; i < caseBodies.size(); i++) { + List cc = new ArrayList<>(); + GraphPart nextCase = null; + nextCase = next; + if (next != null) { + if (i < caseBodies.size() - 1) { + if (!caseBodies.get(i).leadsTo(localData, this, code, caseBodies.get(i + 1), loops)) { + cc.add(new BreakItem(null, currentLoop.id)); + } else { + nextCase = caseBodies.get(i + 1); + } + } else if (!defaultCommands.isEmpty()) { + if (!caseBodies.get(i).leadsTo(localData, this, code, defaultPart, loops)) { + cc.add(new BreakItem(null, currentLoop.id)); + } else { + nextCase = defaultPart; + } + } + } + List stopPart2x = new ArrayList<>(stopPart); + //stopPart2.add(nextCase); + for (GraphPart b : caseBodies) { + if (b != caseBodies.get(i)) { + stopPart2x.add(b); + } + } + if (defaultPart != null) { + stopPart2x.add(defaultPart); + } + if (breakPart != null) { + stopPart2x.add(breakPart); + } + cc.addAll(0, printGraph(localData, stack, allParts, null, caseBodies.get(i), stopPart2x, loops, staticOperation, path)); + if (cc.size() >= 2) { + if (cc.get(cc.size() - 1) instanceof BreakItem) { + if ((cc.get(cc.size() - 2) instanceof ContinueItem) || (cc.get(cc.size() - 2) instanceof BreakItem)) { + cc.remove(cc.size() - 1); + } + } + } + caseCommands.add(cc); + } + ret = new ArrayList<>(); + ret.addAll(output); + SwitchItem sti = new SwitchItem(null, currentLoop, switchedObject, caseValues, caseCommands, defaultCommands, valuesMapping); + ret.add(sti); + currentLoop.phase = 2; + if (next != null) { + if (ti != null) { + ret.add(ti); + } else { + ret.addAll(printGraph(localData, stack, allParts, null, next, stopPart, loops, staticOperation, path)); + } + } + } + } + return ret; + } + + @Override + protected int checkIp(int ip) { + int oldIp = ip; + //return in for..in + GraphSourceItem action = code.get(ip); + if ((action instanceof ActionPush) && (((ActionPush) action).values.size() == 1) && (((ActionPush) action).values.get(0) instanceof Null)) { + if (ip + 3 < code.size()) { + if ((code.get(ip + 1) instanceof ActionEquals) || (code.get(ip + 1) instanceof ActionEquals2)) { + if (code.get(ip + 2) instanceof ActionNot) { + if (code.get(ip + 3) instanceof ActionIf) { + ActionIf aif = (ActionIf) code.get(ip + 3); + if (code.adr2pos(code.pos2adr(ip + 4) + aif.getJumpOffset()) == ip) { + ip += 4; + } + } + } + } + } + } + if (oldIp != ip) { + return checkIp(ip); + } + return ip; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/ActionListReader.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/ActionListReader.java index 6c2f8852d..ef574d29f 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/ActionListReader.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/ActionListReader.java @@ -1,1011 +1,1011 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.action; - -import com.jpexs.decompiler.flash.DisassemblyListener; -import com.jpexs.decompiler.flash.SWFInputStream; -import com.jpexs.decompiler.flash.action.deobfuscation.ActionDeobfuscator; -import com.jpexs.decompiler.flash.action.deobfuscation.ActionDeobfuscatorSimple; -import com.jpexs.decompiler.flash.action.model.ConstantPool; -import com.jpexs.decompiler.flash.action.model.DirectValueActionItem; -import com.jpexs.decompiler.flash.action.special.ActionDeobfuscateJump; -import com.jpexs.decompiler.flash.action.special.ActionEnd; -import com.jpexs.decompiler.flash.action.special.ActionNop; -import com.jpexs.decompiler.flash.action.special.ActionStore; -import com.jpexs.decompiler.flash.action.swf4.ActionEquals; -import com.jpexs.decompiler.flash.action.swf4.ActionIf; -import com.jpexs.decompiler.flash.action.swf4.ActionJump; -import com.jpexs.decompiler.flash.action.swf4.ActionPush; -import com.jpexs.decompiler.flash.action.swf5.ActionConstantPool; -import com.jpexs.decompiler.flash.action.swf5.ActionDefineFunction; -import com.jpexs.decompiler.flash.action.swf5.ActionEquals2; -import com.jpexs.decompiler.flash.action.swf5.ActionStoreRegister; -import com.jpexs.decompiler.flash.action.swf7.ActionDefineFunction2; -import com.jpexs.decompiler.flash.configuration.Configuration; -import com.jpexs.decompiler.flash.ecma.EcmaScript; -import com.jpexs.decompiler.flash.ecma.Null; -import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; -import com.jpexs.decompiler.flash.helpers.SWFDecompilerPlugin; -import com.jpexs.decompiler.graph.Graph; -import com.jpexs.decompiler.graph.GraphSourceItemContainer; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.NotCompileTimeItem; -import com.jpexs.decompiler.graph.TranslateException; -import com.jpexs.decompiler.graph.TranslateStack; -import com.jpexs.decompiler.graph.model.LocalData; -import com.jpexs.helpers.CancellableWorker; -import com.jpexs.helpers.Helper; -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Queue; -import java.util.Scanner; -import java.util.TreeMap; -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * Class for reading data from SWF file - * - * @author JPEXS - */ -public class ActionListReader { - - private static final Logger logger = Logger.getLogger(ActionListReader.class.getName()); - - /** - * Reads list of actions from the stream. Reading ends with - * ActionEndFlag(=0) or end of the stream. - * - * @param listeners - * @param sis - * @param version - * @param ip - * @param endIp - * @param path - * @return List of actions - * @throws IOException - * @throws java.lang.InterruptedException - * @throws java.util.concurrent.TimeoutException - */ - public static ActionList readActionListTimeout(final List listeners, final SWFInputStream sis, final int version, final int ip, final int endIp, final String path) throws IOException, InterruptedException, TimeoutException { - try { - final int deobfuscationMode = Configuration.autoDeobfuscate.get() ? Configuration.deobfuscationMode.get() : -1; - ActionList actions = CancellableWorker.call(new Callable() { - - @Override - public ActionList call() throws IOException, InterruptedException { - return readActionList(listeners, sis, version, ip, endIp, path, deobfuscationMode); - } - }, Configuration.decompilationTimeoutSingleMethod.get(), TimeUnit.SECONDS); - - return actions; - } catch (ExecutionException ex) { - Throwable cause = ex.getCause(); - if (cause instanceof InterruptedException) { - throw (InterruptedException) cause; - } else if (cause instanceof InterruptedException) { - throw (IOException) cause; - } else { - logger.log(Level.SEVERE, null, ex); - } - } - return new ActionList(); - } - - /** - * Reads list of actions from the stream. Reading ends with - * ActionEndFlag(=0) or end of the stream. - * - * @param listeners - * @param sis - * @param version - * @param ip - * @param endIp - * @param path - * @param deobfuscationMode - * @return List of actions - * @throws IOException - * @throws java.lang.InterruptedException - */ - public static ActionList readActionList(List listeners, SWFInputStream sis, int version, int ip, int endIp, String path, int deobfuscationMode) throws IOException, InterruptedException { - // Map of the actions. Use TreeMap to sort the keys in ascending order - // actionMap and nextOffsets should contain exaclty the same keys - Map actionMap = new TreeMap<>(); - Map nextOffsets = new HashMap<>(); - Action entryAction = readActionListAtPos(listeners, null, - sis, actionMap, nextOffsets, - ip, 0, endIp, path, false, new ArrayList()); - - if (actionMap.isEmpty()) { - return new ActionList(); - } - - List addresses = new ArrayList<>(actionMap.keySet()); - - // add end action - Action lastAction = actionMap.get(addresses.get(addresses.size() - 1)); - long endAddress; - if (!(lastAction instanceof ActionEnd)) { - Action aEnd = new ActionEnd(); - aEnd.setAddress(nextOffsets.get(lastAction.getAddress())); - endAddress = aEnd.getAddress(); - actionMap.put(aEnd.getAddress(), aEnd); - nextOffsets.put(endAddress, endAddress + 1); - } - - ActionList actions = fixActionList(new ActionList(actionMap.values()), nextOffsets, version); - - // jump to the entry action when it is diffrent from the first action in the map - if (entryAction != actions.get(0)) { - ActionJump jump = new ActionDeobfuscateJump(0); - actions.addAction(0, jump); - jump.setJumpOffset((int) (entryAction.getAddress() - jump.getTotalActionLength())); - } - - if (SWFDecompilerPlugin.fireActionListParsed(actions, sis.getSwf())) { - actions = fixActionList(actions, null, version); - } - - if (deobfuscationMode == 0) { - try { - actions = deobfuscateActionList(listeners, actions, version, 0, path); - updateActionLengths(actions, version); - } catch (OutOfMemoryError | StackOverflowError | TranslateException ex) { - // keep orignal (not deobfuscated) actions - logger.log(Level.SEVERE, null, ex); - } - } else if (deobfuscationMode == 1) { - try { - new ActionDeobfuscatorSimple().actionListParsed(actions, sis.getSwf()); - new ActionDeobfuscator().actionListParsed(actions, sis.getSwf()); - } catch (OutOfMemoryError | StackOverflowError | TranslateException ex) { - // keep orignal (not deobfuscated) actions - logger.log(Level.SEVERE, null, ex); - } - } - - return actions; - } - - public static ActionList fixActionList(ActionList actions, Map nextOffsets, int version) { - Map> containerLastActions = new HashMap<>(); - getContainerLastActions(actions, containerLastActions); - - ActionList ret = new ActionList(); - - if (nextOffsets != null) { - int index = 0; - while (index != -1 && index < actions.size()) { - Action action = actions.get(index); - ret.add(action); - index++; - if (index < actions.size()) { - long nextAddress = nextOffsets.get(action.getAddress()); - if (actions.get(index).getAddress() != nextAddress) { - if (!action.isExit() && !(action instanceof ActionJump)) { - ActionJump jump = new ActionDeobfuscateJump(0); - jump.setAddress(action.getAddress()); - int size = jump.getTotalActionLength(); - jump.setJumpOffset((int) (nextAddress - action.getAddress() - size)); - ret.add(jump); - } - } - } - } - } else { - ret.addAll(actions); - } - - // Map for storing the targers of the "jump" actions - // "jump" action can be ActionIf, ActionJump and any ActionStore - Map jumps = new HashMap<>(); - getJumps(ret, jumps); - - updateActionLengths(ret, version); - updateAddresses(ret, 0); - long endAddress = ret.get(ret.size() - 1).getAddress(); - - updateJumps(ret, jumps, containerLastActions, endAddress); - updateActionStores(ret, jumps); - updateContainerSizes(ret, containerLastActions); - - return ret; - } - - public static List getOriginalActions(SWFInputStream sis, int startIp, int endIp) throws IOException, InterruptedException { - // Map of the actions. Use TreeMap to sort the keys in ascending order - Map actionMap = new TreeMap<>(); - Map nextOffsets = new HashMap<>(); - readActionListAtPos(new ArrayList(), null, - sis, actionMap, nextOffsets, - startIp, startIp, endIp + 1, "", false, new ArrayList()); - - return new ArrayList<>(actionMap.values()); - } - - /** - * Reads list of actions from the stream. Reading ends with - * ActionEndFlag(=0) or end of the stream. - * - * @param listeners - * @param actions - * @param version - * @param ip - * @param path - * @return List of actions - * @throws IOException - * @throws java.lang.InterruptedException - */ - private static ActionList deobfuscateActionList(List listeners, ActionList actions, int version, int ip, String path) throws IOException, InterruptedException { - if (actions.isEmpty()) { - return actions; - } - - Action lastAction = actions.get(actions.size() - 1); - int endIp = (int) lastAction.getAddress(); - - List retMap = new ArrayList<>(endIp); - for (int i = 0; i < endIp; i++) { - retMap.add(null); - } - List actionMap = new ArrayList<>(endIp); - for (int i = 0; i <= endIp; i++) { - actionMap.add(null); - } - for (Action a : actions) { - actionMap.set((int) a.getAddress(), a); - } - - int maxRecursionLevel = 0; - for (int i = 0; i < actions.size(); i++) { - Action a = actions.get(i); - if (a instanceof ActionIf || a instanceof GraphSourceItemContainer) { - maxRecursionLevel++; - } - if (a instanceof ActionIf) { - ActionIf aif = (ActionIf) a; - aif.ignoreUsed = false; - aif.jumpUsed = false; - } - } - - deobfustaceActionListAtPosRecursive(listeners, - new ArrayList(), - new HashMap>(), - new ActionLocalData(), - new TranslateStack(), - new ConstantPool(), - actionMap, ip, retMap, ip, endIp, path, - new HashMap(), false, - new HashMap>(), - version, 0, maxRecursionLevel); - - ActionList ret = new ActionList(); - Action last = null; - for (Action a : retMap) { - if (a != last && a != null) { - ret.add(a); - } - last = a; - } - ret.removeNops(); - ActionList reta = new ActionList(); - for (Object o : ret) { - if (o instanceof Action) { - reta.add((Action) o); - } - } - return reta; - } - - private static long getNearAddress(ActionList actions, long address, boolean next) { - int min = 0; - int max = actions.size() - 1; - - while (max >= min) { - int mid = (min + max) / 2; - long midValue = actions.get(mid).getAddress(); - if (midValue == address) { - return address; - } else if (midValue < address) { - min = mid + 1; - } else { - max = mid - 1; - } - } - - return next - ? (min < actions.size() ? actions.get(min).getAddress() : -1) - : (max >= 0 ? actions.get(max).getAddress() : -1); - } - - private static Map actionListToMap(List actions) { - Map map = new HashMap<>(actions.size()); - for (Action a : actions) { - long address = a.getAddress(); - // There are multiple actions in the same address (2nd action is a jump for obfuscated code) - // So this check is required - if (!map.containsKey(address)) { - map.put(a.getAddress(), a); - } - } - return map; - } - - private static void getJumps(List actions, Map jumps) { - Map actionMap = actionListToMap(actions); - for (Action a : actions) { - long target = -1; - if (a instanceof ActionIf) { - ActionIf aIf = (ActionIf) a; - target = aIf.getAddress() + a.getTotalActionLength() + aIf.getJumpOffset(); - } else if (a instanceof ActionJump) { - ActionJump aJump = (ActionJump) a; - target = aJump.getAddress() + a.getTotalActionLength() + aJump.getJumpOffset(); - } else if (a instanceof ActionStore) { - ActionStore aStore = (ActionStore) a; - int storeSize = aStore.getStoreSize(); - // skip storeSize + 1 actions (+1 is the current action) - Action targetAction = a; - for (int i = 0; i <= storeSize; i++) { - long address = targetAction.getAddress() + targetAction.getTotalActionLength(); - targetAction = actionMap.get(address); - if (targetAction == null) { - break; - } - } - jumps.put(a, targetAction); - } - if (target >= 0) { - Action targetAction = actionMap.get(target); - jumps.put(a, targetAction); - } - } - } - - public static List getContainerLastActions(ActionList actions, Action action) { - GraphSourceItemContainer container = (GraphSourceItemContainer) action; - List sizes = container.getContainerSizes(); - long endAddress = action.getAddress() + container.getHeaderSize(); - List lasts = new ArrayList<>(sizes.size()); - for (long size : sizes) { - endAddress += size; - long lastActionAddress = getNearAddress(actions, endAddress - 1, false); - Action lastAction = null; - if (lastActionAddress != -1) { - lastAction = actions.getByAddress(lastActionAddress); - } - lasts.add(lastAction); - } - return lasts; - } - - private static void getContainerLastActions(ActionList actions, Map> lastActions) { - for (Action a : actions) { - if (a instanceof GraphSourceItemContainer) { - lastActions.put(a, getContainerLastActions(actions, a)); - } - } - } - - private static long updateAddresses(List actions, long address) { - for (int i = 0; i < actions.size(); i++) { - Action a = actions.get(i); - a.setAddress(address); - int length = a.getTotalActionLength(); - if ((i != actions.size() - 1) && (a instanceof ActionEnd)) { - // placeholder for jump action - length = new ActionDeobfuscateJump(0).getTotalActionLength(); - } - address += length; - } - return address; - } - - private static void updateActionLengths(List actions, int version) { - for (int i = 0; i < actions.size(); i++) { - actions.get(i).updateLength(version); - } - } - - private static void updateActionStores(List actions, Map jumps) { - Map actionMap = actionListToMap(actions); - for (int i = 0; i < actions.size(); i++) { - Action a = actions.get(i); - if (a instanceof ActionStore) { - ActionStore aStore = (ActionStore) a; - Action nextActionAfterStore = jumps.get(a); - Action a1 = a; - List store = new ArrayList<>(); - while (true) { - long address = a1.getAddress() + a1.getTotalActionLength(); - a1 = actionMap.get(address); - if (a1 == null || a1 == nextActionAfterStore) { - break; - } - store.add(a1); - } - aStore.setStore(store); - } - } - } - - private static void updateContainerSizes(List actions, Map> containerLastActions) { - for (int i = 0; i < actions.size(); i++) { - Action a = actions.get(i); - if (a instanceof GraphSourceItemContainer) { - GraphSourceItemContainer container = (GraphSourceItemContainer) a; - List lastActions = containerLastActions.get(a); - long startAddress = a.getAddress() + container.getHeaderSize(); - for (int j = 0; j < lastActions.size(); j++) { - Action lastAction = lastActions.get(j); - int length = (int) (lastAction.getAddress() + lastAction.getTotalActionLength() - startAddress); - container.setContainerSize(j, length); - startAddress += length; - } - } - } - } - - private static void replaceJumpTargets(Map jumps, Action oldTarget, Action newTarget) { - for (Action a : jumps.keySet()) { - if (jumps.get(a) == oldTarget) { - jumps.put(a, newTarget); - } - } - } - - private static void replaceContainerLastActions(Map> containerLastActions, Action oldTarget, Action newTarget) { - for (Action a : containerLastActions.keySet()) { - List targets = containerLastActions.get(a); - for (int i = 0; i < targets.size(); i++) { - if (targets.get(i) == oldTarget) { - targets.set(i, newTarget); - } - } - } - } - - private static void updateJumps(List actions, Map jumps, Map> containerLastActions, long endAddress) { - if (actions.isEmpty()) { - return; - } - - for (int i = 0; i < actions.size(); i++) { - Action a = actions.get(i); - if ((i != actions.size() - 1) && (a instanceof ActionEnd)) { - ActionJump aJump = new ActionDeobfuscateJump(0); - aJump.setJumpOffset((int) (endAddress - a.getAddress() - aJump.getTotalActionLength())); - aJump.setAddress(a.getAddress()); - replaceJumpTargets(jumps, a, aJump); - replaceContainerLastActions(containerLastActions, a, aJump); - a = aJump; - actions.set(i, a); - } else if (a instanceof ActionIf) { - ActionIf aIf = (ActionIf) a; - Action target = jumps.get(a); - long offset; - if (target != null) { - offset = target.getAddress() - a.getAddress() - a.getTotalActionLength(); - } else { - offset = endAddress - a.getAddress() - a.getTotalActionLength(); - } - aIf.setJumpOffset((int) offset); - } else if (a instanceof ActionJump) { - ActionJump aJump = (ActionJump) a; - Action target = jumps.get(a); - long offset; - if (target != null) { - offset = target.getAddress() - a.getAddress() - a.getTotalActionLength(); - } else { - offset = endAddress - a.getAddress() - a.getTotalActionLength(); - } - aJump.setJumpOffset((int) offset); - } - } - } - - /** - * Removes an action from the action list, and updates all references This - * method will keep the inner actions of the container when you remove the - * container - * - * @param actions - * @param index - * @param version - * @param removeWhenLast - * @return - */ - public static boolean removeAction(ActionList actions, int index, int version, boolean removeWhenLast) { - - if (index < 0 || actions.size() <= index) { - return false; - } - - long startIp = actions.get(0).getAddress(); - Action lastAction = actions.get(actions.size() - 1); - long endAddress = lastAction.getAddress() + lastAction.getTotalActionLength(); - - Map> containerLastActions = new HashMap<>(); - getContainerLastActions(actions, containerLastActions); - - Map jumps = new HashMap<>(); - getJumps(actions, jumps); - - Action prevAction = index > 0 ? actions.get(index - 1) : null; - Action nextAction = index + 1 < actions.size() ? actions.get(index + 1) : null; - Action actionToRemove = actions.get(index); - for (Action a : containerLastActions.keySet()) { - List lastActions = containerLastActions.get(a); - for (int i = 0; i < lastActions.size(); i++) { - if (lastActions.get(i) == actionToRemove) { - if (!removeWhenLast) { - return false; - } - lastActions.set(i, prevAction); - } - } - } - for (Action a : jumps.keySet()) { - Action targetAction = jumps.get(a); - if (targetAction == actionToRemove) { - jumps.put(a, nextAction); - } - } - if (containerLastActions.containsKey(actionToRemove)) { - containerLastActions.remove(actionToRemove); - } - if (jumps.containsKey(actionToRemove)) { - jumps.remove(actionToRemove); - } - - actions.remove(index); - - updateActionLengths(actions, version); - updateAddresses(actions, startIp); - updateJumps(actions, jumps, containerLastActions, endAddress); - updateActionStores(actions, jumps); - updateContainerSizes(actions, containerLastActions); - - return true; - } - - /** - * Adds an action to the action list to the specified location, and updates - * all references - * - * @param actions - * @param index - * @param action - * @param version - * @param addToContainer - * @param replaceJump - * @return - */ - public static boolean addAction(ActionList actions, int index, Action action, - int version, boolean addToContainer, boolean replaceJump) { - - if (index < 0 || actions.size() < index) { - return false; - } - - long startIp = actions.get(0).getAddress(); - Action lastAction = actions.get(actions.size() - 1); - if (!(lastAction instanceof ActionEnd)) { - Action aEnd = new ActionEnd(); - aEnd.setAddress(lastAction.getAddress() + lastAction.getTotalActionLength()); - actions.add(aEnd); - lastAction = aEnd; - } - - long endAddress = lastAction.getAddress(); - - Map> containerLastActions = new HashMap<>(); - getContainerLastActions(actions, containerLastActions); - - Map jumps = new HashMap<>(); - List tempActions = new ArrayList<>(actions); - tempActions.add(action); - getJumps(tempActions, jumps); - - Action prevAction = actions.get(index); - if (addToContainer) { - for (Action a : containerLastActions.keySet()) { - List lastActions = containerLastActions.get(a); - for (int i = 0; i < lastActions.size(); i++) { - if (lastActions.get(i) == prevAction) { - lastActions.set(i, action); - } - } - } - } - - if (replaceJump) { - for (Action a : jumps.keySet()) { - Action targetAction = jumps.get(a); - if (targetAction == prevAction) { - jumps.put(a, action); - } - } - } - - actions.add(index, action); - - updateActionLengths(actions, version); - updateAddresses(actions, startIp); - updateJumps(actions, jumps, containerLastActions, endAddress); - updateActionStores(actions, jumps); - updateContainerSizes(actions, containerLastActions); - - return true; - } - - private static Action readActionListAtPos(List listeners, ConstantPool cpool, - SWFInputStream sis, Map actions, Map nextOffsets, - long ip, long startIp, long endIp, String path, boolean indeterminate, List visitedContainers) throws IOException { - - Action entryAction = null; - - if (visitedContainers.contains(ip)) { - return null; - } - visitedContainers.add(ip); - - Queue jumpQueue = new LinkedList<>(); - jumpQueue.add(ip); - while (!jumpQueue.isEmpty()) { - ip = jumpQueue.remove(); - if (ip < startIp) { - continue; - } - - while (endIp == -1 || endIp > ip) { - sis.seek((int) ip); - - Action a; - if ((a = sis.readAction()) == null) { - break; - } - - int actionLengthWithHeader = a.getTotalActionLength(); - - // unknown action, replace with jump - if (a instanceof ActionNop) { - ActionJump aJump = new ActionDeobfuscateJump(0); - int jumpLength = aJump.getTotalActionLength(); - aJump.setAddress(a.getAddress()); - aJump.setJumpOffset(actionLengthWithHeader - jumpLength); - a = aJump; - actionLengthWithHeader = a.getTotalActionLength(); - } - - if (entryAction == null) { - entryAction = a; - } - - Action existingAction = actions.get(ip); - if (existingAction != null) { - break; - } - - actions.put(ip, a); - nextOffsets.put(ip, ip + actionLengthWithHeader); - - long pos = sis.getPos(); - long length = pos + sis.available(); - for (int i = 0; i < listeners.size(); i++) { - listeners.get(i).progressReading(pos, length); - } - - a.setAddress(ip); - - if (a instanceof ActionPush && cpool != null) { - ((ActionPush) a).constantPool = cpool.constants; - } else if (a instanceof ActionConstantPool) { - cpool = new ConstantPool(((ActionConstantPool) a).constantPool); - } else if (a instanceof ActionIf) { - ActionIf aIf = (ActionIf) a; - long nIp = ip + actionLengthWithHeader + aIf.getJumpOffset(); - if (nIp >= 0) { - jumpQueue.add(nIp); - } - } else if (a instanceof ActionJump) { - ActionJump aJump = (ActionJump) a; - long nIp = ip + actionLengthWithHeader + aJump.getJumpOffset(); - if (nIp >= 0) { - jumpQueue.add(nIp); - } - break; - } else if (a instanceof GraphSourceItemContainer) { - GraphSourceItemContainer cnt = (GraphSourceItemContainer) a; - String cntName = cnt.getName(); - String newPath = path + (cntName == null ? "" : "/" + cntName); - for (long size : cnt.getContainerSizes()) { - if (size != 0) { - long ip2 = ip + actionLengthWithHeader; - long endIp2 = ip + actionLengthWithHeader + size; - readActionListAtPos(listeners, cpool, - sis, actions, nextOffsets, - ip2, startIp, endIp2, newPath, indeterminate, visitedContainers); - actionLengthWithHeader += size; - } - } - } - - ip += actionLengthWithHeader; - - if (a.isExit()) { - break; - } - } - } - return entryAction; - } - - private static void deobfustaceActionListAtPosRecursive(List listeners, List output, HashMap> containers, ActionLocalData localData, TranslateStack stack, ConstantPool cpool, List actions, int ip, List ret, int startIp, int endip, String path, Map visited, boolean indeterminate, Map> decisionStates, int version, int recursionLevel, int maxRecursionLevel) throws IOException, InterruptedException { - boolean debugMode = false; - boolean decideBranch = false; - - if (recursionLevel > maxRecursionLevel + 1) { - throw new TranslateException("deobfustaceActionListAtPosRecursive max recursion level reached."); - } - - Action a; - Scanner sc = null; - loopip: - while (((endip == -1) || (endip > ip)) && (a = actions.get(ip)) != null) { - if (Thread.currentThread().isInterrupted()) { - throw new InterruptedException(); - } - - int actionLen = a.getTotalActionLength(); - if (!visited.containsKey(ip)) { - visited.put(ip, 0); - } - int curVisited = visited.get(ip); - curVisited++; - visited.put(ip, curVisited); - for (int i = 0; i < listeners.size(); i++) { - listeners.get(i).progressDeobfuscating(ip, actions.size()); - } - int info = a.getTotalActionLength(); - - if (a instanceof ActionPush) { - if (cpool != null) { - ((ActionPush) a).constantPool = cpool.constants; - } - } - - if (debugMode) { - String atos = a.getASMSource(new ActionList(), new HashSet(), ScriptExportMode.PCODE); - if (a instanceof GraphSourceItemContainer) { - atos = a.toString(); - } - System.err.println("readActionListAtPos ip: " + (ip - startIp) + " (0x" + Helper.formatAddress(ip - startIp) + ") " + " action(len " + a.actionLength + "): " + atos + (a.isIgnored() ? " (ignored)" : "") + " stack:" + Helper.stackToString(stack, LocalData.create(cpool)) + " " + Helper.byteArrToString(a.getBytes(version))); - System.err.print("variables: "); - for (Map.Entry v : localData.variables.entrySet()) { - System.err.print("'" + v + "' = " + v.getValue().toString(LocalData.create(cpool)) + ", "); - } - System.err.println(); - String add = ""; - if (a instanceof ActionIf) { - add = " change: " + ((ActionIf) a).getJumpOffset(); - } - if (a instanceof ActionJump) { - add = " change: " + ((ActionJump) a).getJumpOffset(); - } - System.err.println(add); - } - - int newip = -1; - - if (a instanceof ActionConstantPool) { - if (cpool == null) { - cpool = new ConstantPool(); - } - cpool.setNew(((ActionConstantPool) a).constantPool); - } - ActionIf aif = null; - boolean goaif = false; - if (!a.isIgnored()) { - String varname = null; - if (a instanceof StoreTypeAction) { - StoreTypeAction sta = (StoreTypeAction) a; - varname = sta.getVariableName(stack, cpool); - } - - try { - if (a instanceof ActionIf) { - aif = (ActionIf) a; - - GraphTargetItem top = stack.pop(); - int nip = ip + actionLen + aif.getJumpOffset(); - - if (decideBranch) { - System.out.print("newip " + nip + ", "); - System.out.print("Action: jump(j),ignore(i),compute(c)?"); - if (sc == null) { - sc = new Scanner(System.in); - } - String next = sc.next(); - switch (next) { - case "j": - newip = nip; - break; - case "i": - break; - case "c": - goaif = true; - break; - } - } else if (top.isCompileTime() && (!top.hasSideEffect())) { - if (debugMode) { - System.err.print("is compiletime -> "); - } - if (EcmaScript.toBoolean(top.getResult())) { - newip = nip; - aif.jumpUsed = true; - if (debugMode) { - System.err.println("jump"); - } - } else { - aif.ignoreUsed = true; - if (debugMode) { - System.err.println("ignore"); - } - } - } else { - if (debugMode) { - System.err.println("goaif"); - } - goaif = true; - } - } else if (a instanceof ActionJump) { - newip = ip + actionLen + ((ActionJump) a).getJumpOffset(); - } else if (!(a instanceof GraphSourceItemContainer)) { - //return in for..in, TODO:Handle this better way - if (((a instanceof ActionEquals) || (a instanceof ActionEquals2)) && (stack.size() == 1) && (stack.peek() instanceof DirectValueActionItem)) { - stack.push(new DirectValueActionItem(null, 0, new Null(), new ArrayList())); - } - if ((a instanceof ActionStoreRegister) && stack.isEmpty()) { - stack.push(new DirectValueActionItem(null, 0, new Null(), new ArrayList())); - } - a.translate(localData, stack, output, Graph.SOP_USE_STATIC/*Graph.SOP_SKIP_STATIC*/, path); - } - } catch (RuntimeException ex) { - logger.log(Level.SEVERE, "Disassembly exception", ex); - break; - } - - HashMap vars = localData.variables; - if (varname != null) { - GraphTargetItem varval = vars.get(varname); - if (varval != null && varval.isCompileTime() && indeterminate) { - vars.put(varname, new NotCompileTimeItem(null, varval)); - } - } - } - for (int i = 0; i < actionLen; i++) { - ret.set(ip + i, a); - } - - if (a instanceof GraphSourceItemContainer) { - GraphSourceItemContainer cnt = (GraphSourceItemContainer) a; - if (a instanceof Action) { - long endAddr = a.getAddress() + cnt.getHeaderSize(); - String cntName = cnt.getName(); - List> output2s = new ArrayList<>(); - for (long size : cnt.getContainerSizes()) { - if (size == 0) { - output2s.add(new ArrayList()); - continue; - } - ActionLocalData localData2; - List output2 = new ArrayList<>(); - if ((cnt instanceof ActionDefineFunction) || (cnt instanceof ActionDefineFunction2)) { - localData2 = new ActionLocalData(); - } else { - localData2 = localData; - } - deobfustaceActionListAtPosRecursive(listeners, output2, containers, localData2, new TranslateStack(), cpool, actions, (int) endAddr, ret, startIp, (int) (endAddr + size), path + (cntName == null ? "" : "/" + cntName), visited, indeterminate, decisionStates, version, recursionLevel + 1, maxRecursionLevel); - output2s.add(output2); - endAddr += size; - } - cnt.translateContainer(output2s, stack, output, localData.regNames, localData.variables, localData.functions); - ip = (int) endAddr; - continue; - } - } - - if (a instanceof ActionEnd) { - break; - } - if (goaif) { - aif.ignoreUsed = true; - aif.jumpUsed = true; - indeterminate = true; - - HashMap vars = localData.variables; - boolean stateChanged = false; - if (decisionStates.containsKey(ip)) { - HashMap oldstate = decisionStates.get(ip); - if (oldstate.size() != vars.size()) { - stateChanged = true; - } else { - for (String k : vars.keySet()) { - if (!oldstate.containsKey(k)) { - stateChanged = true; - break; - } - if (!vars.get(k).isCompileTime() && oldstate.get(k).isCompileTime()) { - stateChanged = true; - break; - } - } - } - } - HashMap curstate = new HashMap<>(); - curstate.putAll(vars); - decisionStates.put(ip, curstate); - - if ((!stateChanged) && curVisited > 1) { - List branches = new ArrayList<>(); - branches.add(ip + actionLen + aif.getJumpOffset()); - branches.add(ip + actionLen); - for (int br : branches) { - int visc = 0; - if (visited.containsKey(br)) { - visc = visited.get(br); - } - if (visc == 0) {//(localData.regNames), - new HashMap<>(localData.variables), new HashMap<>(localData.functions)); - deobfustaceActionListAtPosRecursive(listeners, output, containers, subLocalData, subStack, cpool, actions, ip + actionLen + aif.getJumpOffset(), ret, startIp, endip, path, visited, indeterminate, decisionStates, version, recursionLevel + 1, maxRecursionLevel); - } - - if (newip > -1) { - ip = newip; - } else { - ip += info; - } - - if (a.isExit()) { - break; - } - } - for (DisassemblyListener listener : listeners) { - listener.progressDeobfuscating(ip, actions.size()); - } - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.action; + +import com.jpexs.decompiler.flash.DisassemblyListener; +import com.jpexs.decompiler.flash.SWFInputStream; +import com.jpexs.decompiler.flash.action.deobfuscation.ActionDeobfuscator; +import com.jpexs.decompiler.flash.action.deobfuscation.ActionDeobfuscatorSimple; +import com.jpexs.decompiler.flash.action.model.ConstantPool; +import com.jpexs.decompiler.flash.action.model.DirectValueActionItem; +import com.jpexs.decompiler.flash.action.special.ActionDeobfuscateJump; +import com.jpexs.decompiler.flash.action.special.ActionEnd; +import com.jpexs.decompiler.flash.action.special.ActionNop; +import com.jpexs.decompiler.flash.action.special.ActionStore; +import com.jpexs.decompiler.flash.action.swf4.ActionEquals; +import com.jpexs.decompiler.flash.action.swf4.ActionIf; +import com.jpexs.decompiler.flash.action.swf4.ActionJump; +import com.jpexs.decompiler.flash.action.swf4.ActionPush; +import com.jpexs.decompiler.flash.action.swf5.ActionConstantPool; +import com.jpexs.decompiler.flash.action.swf5.ActionDefineFunction; +import com.jpexs.decompiler.flash.action.swf5.ActionEquals2; +import com.jpexs.decompiler.flash.action.swf5.ActionStoreRegister; +import com.jpexs.decompiler.flash.action.swf7.ActionDefineFunction2; +import com.jpexs.decompiler.flash.configuration.Configuration; +import com.jpexs.decompiler.flash.ecma.EcmaScript; +import com.jpexs.decompiler.flash.ecma.Null; +import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; +import com.jpexs.decompiler.flash.helpers.SWFDecompilerPlugin; +import com.jpexs.decompiler.graph.Graph; +import com.jpexs.decompiler.graph.GraphSourceItemContainer; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.NotCompileTimeItem; +import com.jpexs.decompiler.graph.TranslateException; +import com.jpexs.decompiler.graph.TranslateStack; +import com.jpexs.decompiler.graph.model.LocalData; +import com.jpexs.helpers.CancellableWorker; +import com.jpexs.helpers.Helper; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Queue; +import java.util.Scanner; +import java.util.TreeMap; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Class for reading data from SWF file + * + * @author JPEXS + */ +public class ActionListReader { + + private static final Logger logger = Logger.getLogger(ActionListReader.class.getName()); + + /** + * Reads list of actions from the stream. Reading ends with + * ActionEndFlag(=0) or end of the stream. + * + * @param listeners + * @param sis + * @param version + * @param ip + * @param endIp + * @param path + * @return List of actions + * @throws IOException + * @throws java.lang.InterruptedException + * @throws java.util.concurrent.TimeoutException + */ + public static ActionList readActionListTimeout(final List listeners, final SWFInputStream sis, final int version, final int ip, final int endIp, final String path) throws IOException, InterruptedException, TimeoutException { + try { + final int deobfuscationMode = Configuration.autoDeobfuscate.get() ? Configuration.deobfuscationMode.get() : -1; + ActionList actions = CancellableWorker.call(new Callable() { + + @Override + public ActionList call() throws IOException, InterruptedException { + return readActionList(listeners, sis, version, ip, endIp, path, deobfuscationMode); + } + }, Configuration.decompilationTimeoutSingleMethod.get(), TimeUnit.SECONDS); + + return actions; + } catch (ExecutionException ex) { + Throwable cause = ex.getCause(); + if (cause instanceof InterruptedException) { + throw (InterruptedException) cause; + } else if (cause instanceof InterruptedException) { + throw (IOException) cause; + } else { + logger.log(Level.SEVERE, null, ex); + } + } + return new ActionList(); + } + + /** + * Reads list of actions from the stream. Reading ends with + * ActionEndFlag(=0) or end of the stream. + * + * @param listeners + * @param sis + * @param version + * @param ip + * @param endIp + * @param path + * @param deobfuscationMode + * @return List of actions + * @throws IOException + * @throws java.lang.InterruptedException + */ + public static ActionList readActionList(List listeners, SWFInputStream sis, int version, int ip, int endIp, String path, int deobfuscationMode) throws IOException, InterruptedException { + // Map of the actions. Use TreeMap to sort the keys in ascending order + // actionMap and nextOffsets should contain exaclty the same keys + Map actionMap = new TreeMap<>(); + Map nextOffsets = new HashMap<>(); + Action entryAction = readActionListAtPos(listeners, null, + sis, actionMap, nextOffsets, + ip, 0, endIp, path, false, new ArrayList()); + + if (actionMap.isEmpty()) { + return new ActionList(); + } + + List addresses = new ArrayList<>(actionMap.keySet()); + + // add end action + Action lastAction = actionMap.get(addresses.get(addresses.size() - 1)); + long endAddress; + if (!(lastAction instanceof ActionEnd)) { + Action aEnd = new ActionEnd(); + aEnd.setAddress(nextOffsets.get(lastAction.getAddress())); + endAddress = aEnd.getAddress(); + actionMap.put(aEnd.getAddress(), aEnd); + nextOffsets.put(endAddress, endAddress + 1); + } + + ActionList actions = fixActionList(new ActionList(actionMap.values()), nextOffsets, version); + + // jump to the entry action when it is diffrent from the first action in the map + if (entryAction != actions.get(0)) { + ActionJump jump = new ActionDeobfuscateJump(0); + actions.addAction(0, jump); + jump.setJumpOffset((int) (entryAction.getAddress() - jump.getTotalActionLength())); + } + + if (SWFDecompilerPlugin.fireActionListParsed(actions, sis.getSwf())) { + actions = fixActionList(actions, null, version); + } + + if (deobfuscationMode == 0) { + try { + actions = deobfuscateActionList(listeners, actions, version, 0, path); + updateActionLengths(actions, version); + } catch (OutOfMemoryError | StackOverflowError | TranslateException ex) { + // keep orignal (not deobfuscated) actions + logger.log(Level.SEVERE, null, ex); + } + } else if (deobfuscationMode == 1) { + try { + new ActionDeobfuscatorSimple().actionListParsed(actions, sis.getSwf()); + new ActionDeobfuscator().actionListParsed(actions, sis.getSwf()); + } catch (OutOfMemoryError | StackOverflowError | TranslateException ex) { + // keep orignal (not deobfuscated) actions + logger.log(Level.SEVERE, null, ex); + } + } + + return actions; + } + + public static ActionList fixActionList(ActionList actions, Map nextOffsets, int version) { + Map> containerLastActions = new HashMap<>(); + getContainerLastActions(actions, containerLastActions); + + ActionList ret = new ActionList(); + + if (nextOffsets != null) { + int index = 0; + while (index != -1 && index < actions.size()) { + Action action = actions.get(index); + ret.add(action); + index++; + if (index < actions.size()) { + long nextAddress = nextOffsets.get(action.getAddress()); + if (actions.get(index).getAddress() != nextAddress) { + if (!action.isExit() && !(action instanceof ActionJump)) { + ActionJump jump = new ActionDeobfuscateJump(0); + jump.setAddress(action.getAddress()); + int size = jump.getTotalActionLength(); + jump.setJumpOffset((int) (nextAddress - action.getAddress() - size)); + ret.add(jump); + } + } + } + } + } else { + ret.addAll(actions); + } + + // Map for storing the targers of the "jump" actions + // "jump" action can be ActionIf, ActionJump and any ActionStore + Map jumps = new HashMap<>(); + getJumps(ret, jumps); + + updateActionLengths(ret, version); + updateAddresses(ret, 0); + long endAddress = ret.get(ret.size() - 1).getAddress(); + + updateJumps(ret, jumps, containerLastActions, endAddress); + updateActionStores(ret, jumps); + updateContainerSizes(ret, containerLastActions); + + return ret; + } + + public static List getOriginalActions(SWFInputStream sis, int startIp, int endIp) throws IOException, InterruptedException { + // Map of the actions. Use TreeMap to sort the keys in ascending order + Map actionMap = new TreeMap<>(); + Map nextOffsets = new HashMap<>(); + readActionListAtPos(new ArrayList(), null, + sis, actionMap, nextOffsets, + startIp, startIp, endIp + 1, "", false, new ArrayList()); + + return new ArrayList<>(actionMap.values()); + } + + /** + * Reads list of actions from the stream. Reading ends with + * ActionEndFlag(=0) or end of the stream. + * + * @param listeners + * @param actions + * @param version + * @param ip + * @param path + * @return List of actions + * @throws IOException + * @throws java.lang.InterruptedException + */ + private static ActionList deobfuscateActionList(List listeners, ActionList actions, int version, int ip, String path) throws IOException, InterruptedException { + if (actions.isEmpty()) { + return actions; + } + + Action lastAction = actions.get(actions.size() - 1); + int endIp = (int) lastAction.getAddress(); + + List retMap = new ArrayList<>(endIp); + for (int i = 0; i < endIp; i++) { + retMap.add(null); + } + List actionMap = new ArrayList<>(endIp); + for (int i = 0; i <= endIp; i++) { + actionMap.add(null); + } + for (Action a : actions) { + actionMap.set((int) a.getAddress(), a); + } + + int maxRecursionLevel = 0; + for (int i = 0; i < actions.size(); i++) { + Action a = actions.get(i); + if (a instanceof ActionIf || a instanceof GraphSourceItemContainer) { + maxRecursionLevel++; + } + if (a instanceof ActionIf) { + ActionIf aif = (ActionIf) a; + aif.ignoreUsed = false; + aif.jumpUsed = false; + } + } + + deobfustaceActionListAtPosRecursive(listeners, + new ArrayList(), + new HashMap>(), + new ActionLocalData(), + new TranslateStack(), + new ConstantPool(), + actionMap, ip, retMap, ip, endIp, path, + new HashMap(), false, + new HashMap>(), + version, 0, maxRecursionLevel); + + ActionList ret = new ActionList(); + Action last = null; + for (Action a : retMap) { + if (a != last && a != null) { + ret.add(a); + } + last = a; + } + ret.removeNops(); + ActionList reta = new ActionList(); + for (Object o : ret) { + if (o instanceof Action) { + reta.add((Action) o); + } + } + return reta; + } + + private static long getNearAddress(ActionList actions, long address, boolean next) { + int min = 0; + int max = actions.size() - 1; + + while (max >= min) { + int mid = (min + max) / 2; + long midValue = actions.get(mid).getAddress(); + if (midValue == address) { + return address; + } else if (midValue < address) { + min = mid + 1; + } else { + max = mid - 1; + } + } + + return next + ? (min < actions.size() ? actions.get(min).getAddress() : -1) + : (max >= 0 ? actions.get(max).getAddress() : -1); + } + + private static Map actionListToMap(List actions) { + Map map = new HashMap<>(actions.size()); + for (Action a : actions) { + long address = a.getAddress(); + // There are multiple actions in the same address (2nd action is a jump for obfuscated code) + // So this check is required + if (!map.containsKey(address)) { + map.put(a.getAddress(), a); + } + } + return map; + } + + private static void getJumps(List actions, Map jumps) { + Map actionMap = actionListToMap(actions); + for (Action a : actions) { + long target = -1; + if (a instanceof ActionIf) { + ActionIf aIf = (ActionIf) a; + target = aIf.getAddress() + a.getTotalActionLength() + aIf.getJumpOffset(); + } else if (a instanceof ActionJump) { + ActionJump aJump = (ActionJump) a; + target = aJump.getAddress() + a.getTotalActionLength() + aJump.getJumpOffset(); + } else if (a instanceof ActionStore) { + ActionStore aStore = (ActionStore) a; + int storeSize = aStore.getStoreSize(); + // skip storeSize + 1 actions (+1 is the current action) + Action targetAction = a; + for (int i = 0; i <= storeSize; i++) { + long address = targetAction.getAddress() + targetAction.getTotalActionLength(); + targetAction = actionMap.get(address); + if (targetAction == null) { + break; + } + } + jumps.put(a, targetAction); + } + if (target >= 0) { + Action targetAction = actionMap.get(target); + jumps.put(a, targetAction); + } + } + } + + public static List getContainerLastActions(ActionList actions, Action action) { + GraphSourceItemContainer container = (GraphSourceItemContainer) action; + List sizes = container.getContainerSizes(); + long endAddress = action.getAddress() + container.getHeaderSize(); + List lasts = new ArrayList<>(sizes.size()); + for (long size : sizes) { + endAddress += size; + long lastActionAddress = getNearAddress(actions, endAddress - 1, false); + Action lastAction = null; + if (lastActionAddress != -1) { + lastAction = actions.getByAddress(lastActionAddress); + } + lasts.add(lastAction); + } + return lasts; + } + + private static void getContainerLastActions(ActionList actions, Map> lastActions) { + for (Action a : actions) { + if (a instanceof GraphSourceItemContainer) { + lastActions.put(a, getContainerLastActions(actions, a)); + } + } + } + + private static long updateAddresses(List actions, long address) { + for (int i = 0; i < actions.size(); i++) { + Action a = actions.get(i); + a.setAddress(address); + int length = a.getTotalActionLength(); + if ((i != actions.size() - 1) && (a instanceof ActionEnd)) { + // placeholder for jump action + length = new ActionDeobfuscateJump(0).getTotalActionLength(); + } + address += length; + } + return address; + } + + private static void updateActionLengths(List actions, int version) { + for (int i = 0; i < actions.size(); i++) { + actions.get(i).updateLength(version); + } + } + + private static void updateActionStores(List actions, Map jumps) { + Map actionMap = actionListToMap(actions); + for (int i = 0; i < actions.size(); i++) { + Action a = actions.get(i); + if (a instanceof ActionStore) { + ActionStore aStore = (ActionStore) a; + Action nextActionAfterStore = jumps.get(a); + Action a1 = a; + List store = new ArrayList<>(); + while (true) { + long address = a1.getAddress() + a1.getTotalActionLength(); + a1 = actionMap.get(address); + if (a1 == null || a1 == nextActionAfterStore) { + break; + } + store.add(a1); + } + aStore.setStore(store); + } + } + } + + private static void updateContainerSizes(List actions, Map> containerLastActions) { + for (int i = 0; i < actions.size(); i++) { + Action a = actions.get(i); + if (a instanceof GraphSourceItemContainer) { + GraphSourceItemContainer container = (GraphSourceItemContainer) a; + List lastActions = containerLastActions.get(a); + long startAddress = a.getAddress() + container.getHeaderSize(); + for (int j = 0; j < lastActions.size(); j++) { + Action lastAction = lastActions.get(j); + int length = (int) (lastAction.getAddress() + lastAction.getTotalActionLength() - startAddress); + container.setContainerSize(j, length); + startAddress += length; + } + } + } + } + + private static void replaceJumpTargets(Map jumps, Action oldTarget, Action newTarget) { + for (Action a : jumps.keySet()) { + if (jumps.get(a) == oldTarget) { + jumps.put(a, newTarget); + } + } + } + + private static void replaceContainerLastActions(Map> containerLastActions, Action oldTarget, Action newTarget) { + for (Action a : containerLastActions.keySet()) { + List targets = containerLastActions.get(a); + for (int i = 0; i < targets.size(); i++) { + if (targets.get(i) == oldTarget) { + targets.set(i, newTarget); + } + } + } + } + + private static void updateJumps(List actions, Map jumps, Map> containerLastActions, long endAddress) { + if (actions.isEmpty()) { + return; + } + + for (int i = 0; i < actions.size(); i++) { + Action a = actions.get(i); + if ((i != actions.size() - 1) && (a instanceof ActionEnd)) { + ActionJump aJump = new ActionDeobfuscateJump(0); + aJump.setJumpOffset((int) (endAddress - a.getAddress() - aJump.getTotalActionLength())); + aJump.setAddress(a.getAddress()); + replaceJumpTargets(jumps, a, aJump); + replaceContainerLastActions(containerLastActions, a, aJump); + a = aJump; + actions.set(i, a); + } else if (a instanceof ActionIf) { + ActionIf aIf = (ActionIf) a; + Action target = jumps.get(a); + long offset; + if (target != null) { + offset = target.getAddress() - a.getAddress() - a.getTotalActionLength(); + } else { + offset = endAddress - a.getAddress() - a.getTotalActionLength(); + } + aIf.setJumpOffset((int) offset); + } else if (a instanceof ActionJump) { + ActionJump aJump = (ActionJump) a; + Action target = jumps.get(a); + long offset; + if (target != null) { + offset = target.getAddress() - a.getAddress() - a.getTotalActionLength(); + } else { + offset = endAddress - a.getAddress() - a.getTotalActionLength(); + } + aJump.setJumpOffset((int) offset); + } + } + } + + /** + * Removes an action from the action list, and updates all references This + * method will keep the inner actions of the container when you remove the + * container + * + * @param actions + * @param index + * @param version + * @param removeWhenLast + * @return + */ + public static boolean removeAction(ActionList actions, int index, int version, boolean removeWhenLast) { + + if (index < 0 || actions.size() <= index) { + return false; + } + + long startIp = actions.get(0).getAddress(); + Action lastAction = actions.get(actions.size() - 1); + long endAddress = lastAction.getAddress() + lastAction.getTotalActionLength(); + + Map> containerLastActions = new HashMap<>(); + getContainerLastActions(actions, containerLastActions); + + Map jumps = new HashMap<>(); + getJumps(actions, jumps); + + Action prevAction = index > 0 ? actions.get(index - 1) : null; + Action nextAction = index + 1 < actions.size() ? actions.get(index + 1) : null; + Action actionToRemove = actions.get(index); + for (Action a : containerLastActions.keySet()) { + List lastActions = containerLastActions.get(a); + for (int i = 0; i < lastActions.size(); i++) { + if (lastActions.get(i) == actionToRemove) { + if (!removeWhenLast) { + return false; + } + lastActions.set(i, prevAction); + } + } + } + for (Action a : jumps.keySet()) { + Action targetAction = jumps.get(a); + if (targetAction == actionToRemove) { + jumps.put(a, nextAction); + } + } + if (containerLastActions.containsKey(actionToRemove)) { + containerLastActions.remove(actionToRemove); + } + if (jumps.containsKey(actionToRemove)) { + jumps.remove(actionToRemove); + } + + actions.remove(index); + + updateActionLengths(actions, version); + updateAddresses(actions, startIp); + updateJumps(actions, jumps, containerLastActions, endAddress); + updateActionStores(actions, jumps); + updateContainerSizes(actions, containerLastActions); + + return true; + } + + /** + * Adds an action to the action list to the specified location, and updates + * all references + * + * @param actions + * @param index + * @param action + * @param version + * @param addToContainer + * @param replaceJump + * @return + */ + public static boolean addAction(ActionList actions, int index, Action action, + int version, boolean addToContainer, boolean replaceJump) { + + if (index < 0 || actions.size() < index) { + return false; + } + + long startIp = actions.get(0).getAddress(); + Action lastAction = actions.get(actions.size() - 1); + if (!(lastAction instanceof ActionEnd)) { + Action aEnd = new ActionEnd(); + aEnd.setAddress(lastAction.getAddress() + lastAction.getTotalActionLength()); + actions.add(aEnd); + lastAction = aEnd; + } + + long endAddress = lastAction.getAddress(); + + Map> containerLastActions = new HashMap<>(); + getContainerLastActions(actions, containerLastActions); + + Map jumps = new HashMap<>(); + List tempActions = new ArrayList<>(actions); + tempActions.add(action); + getJumps(tempActions, jumps); + + Action prevAction = actions.get(index); + if (addToContainer) { + for (Action a : containerLastActions.keySet()) { + List lastActions = containerLastActions.get(a); + for (int i = 0; i < lastActions.size(); i++) { + if (lastActions.get(i) == prevAction) { + lastActions.set(i, action); + } + } + } + } + + if (replaceJump) { + for (Action a : jumps.keySet()) { + Action targetAction = jumps.get(a); + if (targetAction == prevAction) { + jumps.put(a, action); + } + } + } + + actions.add(index, action); + + updateActionLengths(actions, version); + updateAddresses(actions, startIp); + updateJumps(actions, jumps, containerLastActions, endAddress); + updateActionStores(actions, jumps); + updateContainerSizes(actions, containerLastActions); + + return true; + } + + private static Action readActionListAtPos(List listeners, ConstantPool cpool, + SWFInputStream sis, Map actions, Map nextOffsets, + long ip, long startIp, long endIp, String path, boolean indeterminate, List visitedContainers) throws IOException { + + Action entryAction = null; + + if (visitedContainers.contains(ip)) { + return null; + } + visitedContainers.add(ip); + + Queue jumpQueue = new LinkedList<>(); + jumpQueue.add(ip); + while (!jumpQueue.isEmpty()) { + ip = jumpQueue.remove(); + if (ip < startIp) { + continue; + } + + while (endIp == -1 || endIp > ip) { + sis.seek((int) ip); + + Action a; + if ((a = sis.readAction()) == null) { + break; + } + + int actionLengthWithHeader = a.getTotalActionLength(); + + // unknown action, replace with jump + if (a instanceof ActionNop) { + ActionJump aJump = new ActionDeobfuscateJump(0); + int jumpLength = aJump.getTotalActionLength(); + aJump.setAddress(a.getAddress()); + aJump.setJumpOffset(actionLengthWithHeader - jumpLength); + a = aJump; + actionLengthWithHeader = a.getTotalActionLength(); + } + + if (entryAction == null) { + entryAction = a; + } + + Action existingAction = actions.get(ip); + if (existingAction != null) { + break; + } + + actions.put(ip, a); + nextOffsets.put(ip, ip + actionLengthWithHeader); + + long pos = sis.getPos(); + long length = pos + sis.available(); + for (int i = 0; i < listeners.size(); i++) { + listeners.get(i).progressReading(pos, length); + } + + a.setAddress(ip); + + if (a instanceof ActionPush && cpool != null) { + ((ActionPush) a).constantPool = cpool.constants; + } else if (a instanceof ActionConstantPool) { + cpool = new ConstantPool(((ActionConstantPool) a).constantPool); + } else if (a instanceof ActionIf) { + ActionIf aIf = (ActionIf) a; + long nIp = ip + actionLengthWithHeader + aIf.getJumpOffset(); + if (nIp >= 0) { + jumpQueue.add(nIp); + } + } else if (a instanceof ActionJump) { + ActionJump aJump = (ActionJump) a; + long nIp = ip + actionLengthWithHeader + aJump.getJumpOffset(); + if (nIp >= 0) { + jumpQueue.add(nIp); + } + break; + } else if (a instanceof GraphSourceItemContainer) { + GraphSourceItemContainer cnt = (GraphSourceItemContainer) a; + String cntName = cnt.getName(); + String newPath = path + (cntName == null ? "" : "/" + cntName); + for (long size : cnt.getContainerSizes()) { + if (size != 0) { + long ip2 = ip + actionLengthWithHeader; + long endIp2 = ip + actionLengthWithHeader + size; + readActionListAtPos(listeners, cpool, + sis, actions, nextOffsets, + ip2, startIp, endIp2, newPath, indeterminate, visitedContainers); + actionLengthWithHeader += size; + } + } + } + + ip += actionLengthWithHeader; + + if (a.isExit()) { + break; + } + } + } + return entryAction; + } + + private static void deobfustaceActionListAtPosRecursive(List listeners, List output, HashMap> containers, ActionLocalData localData, TranslateStack stack, ConstantPool cpool, List actions, int ip, List ret, int startIp, int endip, String path, Map visited, boolean indeterminate, Map> decisionStates, int version, int recursionLevel, int maxRecursionLevel) throws IOException, InterruptedException { + boolean debugMode = false; + boolean decideBranch = false; + + if (recursionLevel > maxRecursionLevel + 1) { + throw new TranslateException("deobfustaceActionListAtPosRecursive max recursion level reached."); + } + + Action a; + Scanner sc = null; + loopip: + while (((endip == -1) || (endip > ip)) && (a = actions.get(ip)) != null) { + if (Thread.currentThread().isInterrupted()) { + throw new InterruptedException(); + } + + int actionLen = a.getTotalActionLength(); + if (!visited.containsKey(ip)) { + visited.put(ip, 0); + } + int curVisited = visited.get(ip); + curVisited++; + visited.put(ip, curVisited); + for (int i = 0; i < listeners.size(); i++) { + listeners.get(i).progressDeobfuscating(ip, actions.size()); + } + int info = a.getTotalActionLength(); + + if (a instanceof ActionPush) { + if (cpool != null) { + ((ActionPush) a).constantPool = cpool.constants; + } + } + + if (debugMode) { + String atos = a.getASMSource(new ActionList(), new HashSet(), ScriptExportMode.PCODE); + if (a instanceof GraphSourceItemContainer) { + atos = a.toString(); + } + System.err.println("readActionListAtPos ip: " + (ip - startIp) + " (0x" + Helper.formatAddress(ip - startIp) + ") " + " action(len " + a.actionLength + "): " + atos + (a.isIgnored() ? " (ignored)" : "") + " stack:" + Helper.stackToString(stack, LocalData.create(cpool)) + " " + Helper.byteArrToString(a.getBytes(version))); + System.err.print("variables: "); + for (Map.Entry v : localData.variables.entrySet()) { + System.err.print("'" + v + "' = " + v.getValue().toString(LocalData.create(cpool)) + ", "); + } + System.err.println(); + String add = ""; + if (a instanceof ActionIf) { + add = " change: " + ((ActionIf) a).getJumpOffset(); + } + if (a instanceof ActionJump) { + add = " change: " + ((ActionJump) a).getJumpOffset(); + } + System.err.println(add); + } + + int newip = -1; + + if (a instanceof ActionConstantPool) { + if (cpool == null) { + cpool = new ConstantPool(); + } + cpool.setNew(((ActionConstantPool) a).constantPool); + } + ActionIf aif = null; + boolean goaif = false; + if (!a.isIgnored()) { + String varname = null; + if (a instanceof StoreTypeAction) { + StoreTypeAction sta = (StoreTypeAction) a; + varname = sta.getVariableName(stack, cpool); + } + + try { + if (a instanceof ActionIf) { + aif = (ActionIf) a; + + GraphTargetItem top = stack.pop(); + int nip = ip + actionLen + aif.getJumpOffset(); + + if (decideBranch) { + System.out.print("newip " + nip + ", "); + System.out.print("Action: jump(j),ignore(i),compute(c)?"); + if (sc == null) { + sc = new Scanner(System.in); + } + String next = sc.next(); + switch (next) { + case "j": + newip = nip; + break; + case "i": + break; + case "c": + goaif = true; + break; + } + } else if (top.isCompileTime() && (!top.hasSideEffect())) { + if (debugMode) { + System.err.print("is compiletime -> "); + } + if (EcmaScript.toBoolean(top.getResult())) { + newip = nip; + aif.jumpUsed = true; + if (debugMode) { + System.err.println("jump"); + } + } else { + aif.ignoreUsed = true; + if (debugMode) { + System.err.println("ignore"); + } + } + } else { + if (debugMode) { + System.err.println("goaif"); + } + goaif = true; + } + } else if (a instanceof ActionJump) { + newip = ip + actionLen + ((ActionJump) a).getJumpOffset(); + } else if (!(a instanceof GraphSourceItemContainer)) { + //return in for..in, TODO:Handle this better way + if (((a instanceof ActionEquals) || (a instanceof ActionEquals2)) && (stack.size() == 1) && (stack.peek() instanceof DirectValueActionItem)) { + stack.push(new DirectValueActionItem(null, 0, new Null(), new ArrayList())); + } + if ((a instanceof ActionStoreRegister) && stack.isEmpty()) { + stack.push(new DirectValueActionItem(null, 0, new Null(), new ArrayList())); + } + a.translate(localData, stack, output, Graph.SOP_USE_STATIC/*Graph.SOP_SKIP_STATIC*/, path); + } + } catch (RuntimeException ex) { + logger.log(Level.SEVERE, "Disassembly exception", ex); + break; + } + + HashMap vars = localData.variables; + if (varname != null) { + GraphTargetItem varval = vars.get(varname); + if (varval != null && varval.isCompileTime() && indeterminate) { + vars.put(varname, new NotCompileTimeItem(null, varval)); + } + } + } + for (int i = 0; i < actionLen; i++) { + ret.set(ip + i, a); + } + + if (a instanceof GraphSourceItemContainer) { + GraphSourceItemContainer cnt = (GraphSourceItemContainer) a; + if (a instanceof Action) { + long endAddr = a.getAddress() + cnt.getHeaderSize(); + String cntName = cnt.getName(); + List> output2s = new ArrayList<>(); + for (long size : cnt.getContainerSizes()) { + if (size == 0) { + output2s.add(new ArrayList()); + continue; + } + ActionLocalData localData2; + List output2 = new ArrayList<>(); + if ((cnt instanceof ActionDefineFunction) || (cnt instanceof ActionDefineFunction2)) { + localData2 = new ActionLocalData(); + } else { + localData2 = localData; + } + deobfustaceActionListAtPosRecursive(listeners, output2, containers, localData2, new TranslateStack(), cpool, actions, (int) endAddr, ret, startIp, (int) (endAddr + size), path + (cntName == null ? "" : "/" + cntName), visited, indeterminate, decisionStates, version, recursionLevel + 1, maxRecursionLevel); + output2s.add(output2); + endAddr += size; + } + cnt.translateContainer(output2s, stack, output, localData.regNames, localData.variables, localData.functions); + ip = (int) endAddr; + continue; + } + } + + if (a instanceof ActionEnd) { + break; + } + if (goaif) { + aif.ignoreUsed = true; + aif.jumpUsed = true; + indeterminate = true; + + HashMap vars = localData.variables; + boolean stateChanged = false; + if (decisionStates.containsKey(ip)) { + HashMap oldstate = decisionStates.get(ip); + if (oldstate.size() != vars.size()) { + stateChanged = true; + } else { + for (String k : vars.keySet()) { + if (!oldstate.containsKey(k)) { + stateChanged = true; + break; + } + if (!vars.get(k).isCompileTime() && oldstate.get(k).isCompileTime()) { + stateChanged = true; + break; + } + } + } + } + HashMap curstate = new HashMap<>(); + curstate.putAll(vars); + decisionStates.put(ip, curstate); + + if ((!stateChanged) && curVisited > 1) { + List branches = new ArrayList<>(); + branches.add(ip + actionLen + aif.getJumpOffset()); + branches.add(ip + actionLen); + for (int br : branches) { + int visc = 0; + if (visited.containsKey(br)) { + visc = visited.get(br); + } + if (visc == 0) {//(localData.regNames), + new HashMap<>(localData.variables), new HashMap<>(localData.functions)); + deobfustaceActionListAtPosRecursive(listeners, output, containers, subLocalData, subStack, cpool, actions, ip + actionLen + aif.getJumpOffset(), ret, startIp, endip, path, visited, indeterminate, decisionStates, version, recursionLevel + 1, maxRecursionLevel); + } + + if (newip > -1) { + ip = newip; + } else { + ip += info; + } + + if (a.isExit()) { + break; + } + } + for (DisassemblyListener listener : listeners) { + listener.progressDeobfuscating(ip, actions.size()); + } + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/FunctionActionItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/FunctionActionItem.java index 10ab11c00..5b4829b53 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/FunctionActionItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/FunctionActionItem.java @@ -1,339 +1,339 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.action.model; - -import com.jpexs.decompiler.flash.IdentifiersDeobfuscation; -import com.jpexs.decompiler.flash.SWF; -import com.jpexs.decompiler.flash.SourceGeneratorLocalData; -import com.jpexs.decompiler.flash.action.Action; -import com.jpexs.decompiler.flash.action.parser.script.ActionSourceGenerator; -import com.jpexs.decompiler.flash.action.parser.script.VariableActionItem; -import com.jpexs.decompiler.flash.action.swf4.ActionPush; -import com.jpexs.decompiler.flash.action.swf4.RegisterNumber; -import com.jpexs.decompiler.flash.action.swf5.ActionDefineFunction; -import com.jpexs.decompiler.flash.action.swf7.ActionDefineFunction2; -import com.jpexs.decompiler.flash.helpers.GraphTextWriter; -import com.jpexs.decompiler.graph.CompilationException; -import com.jpexs.decompiler.graph.Graph; -import com.jpexs.decompiler.graph.GraphSourceItem; -import com.jpexs.decompiler.graph.GraphSourceItemPos; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.SourceGenerator; -import com.jpexs.decompiler.graph.model.LocalData; -import com.jpexs.helpers.Helper; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -public class FunctionActionItem extends ActionItem { - - public List actions; - - public List constants; - - public String functionName; - - public List paramNames; - - public GraphTargetItem calculatedFunctionName; - - private int regStart; - - private List variables; - - public static final int REGISTER_THIS = 1; - - public static final int REGISTER_ARGUMENTS = 2; - - public static final int REGISTER_SUPER = 3; - - public static final int REGISTER_ROOT = 4; - - public static final int REGISTER_PARENT = 5; - - public static final int REGISTER_GLOBAL = 6; - - @Override - public List getAllSubItems() { - List ret = new ArrayList<>(); - ret.addAll(actions); - return ret; - } - - public FunctionActionItem() { - super(null, PRECEDENCE_PRIMARY); - } - - public FunctionActionItem(GraphSourceItem instruction, String functionName, List paramNames, List actions, List constants, int regStart, List variables) { - super(instruction, PRECEDENCE_PRIMARY); - this.actions = actions; - this.constants = constants; - this.functionName = functionName; - this.paramNames = paramNames; - this.regStart = regStart; - this.variables = variables; - } - - @Override - public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException { - writer.append("function"); - if (calculatedFunctionName != null) { - writer.append(" "); - String fname = calculatedFunctionName.toStringNoQuotes(localData); - if (!IdentifiersDeobfuscation.isValidName(false, fname)) { - writer.append(IdentifiersDeobfuscation.makeObfuscatedIdentifier(fname)); - } else { - calculatedFunctionName.appendToNoQuotes(writer, localData); - } - } else if (!functionName.isEmpty()) { - writer.append(" "); - if (!IdentifiersDeobfuscation.isValidName(false, functionName)) { - writer.append(IdentifiersDeobfuscation.makeObfuscatedIdentifier(functionName)); - } else { - writer.append(functionName); - } - } - writer.spaceBeforeCallParenthesies(paramNames.size()); - writer.append("("); - - for (int p = 0; p < paramNames.size(); p++) { - if (p > 0) { - writer.append(", "); - } - String pname = paramNames.get(p); - if (pname == null || pname.isEmpty()) { - pname = new RegisterNumber(regStart + p).translate(); - } - if (!IdentifiersDeobfuscation.isValidName(false, pname)) { - writer.append(IdentifiersDeobfuscation.makeObfuscatedIdentifier(pname)); - } - writer.append(pname); - } - writer.append(")").startBlock(); - - Graph.graphToString(actions, writer, localData); - - return writer.endBlock(); - } - - @Override - public List getNeededSources() { - List ret = super.getNeededSources(); - for (GraphTargetItem ti : actions) { - ret.addAll(ti.getNeededSources()); - } - return ret; - } - - @Override - public boolean needsSemicolon() { - return false; - } - - @Override - public boolean isCompileTime(Set dependencies) { - for (GraphTargetItem a : actions) { - if (dependencies.contains(a)) { - return false; - } - dependencies.add(a); - if (!a.isCompileTime(dependencies)) { - return false; - } - } - return true; - } - - @Override - public Object getResult() { - if (!actions.isEmpty()) { - if (actions.get(actions.size() - 1) instanceof ReturnActionItem) { - ReturnActionItem r = (ReturnActionItem) actions.get(actions.size() - 1); - return r.value.getResult(); - } - } - return 0; - } - - @Override - public boolean needsNewLine() { - return true; - } - - @Override - public List toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException { - - Set usedNames = new HashSet<>(); - for (VariableActionItem v : variables) { - usedNames.add(v.getVariableName()); - } - - List ret = new ArrayList<>(); - ActionSourceGenerator asGenerator = (ActionSourceGenerator) generator; - List paramRegs = new ArrayList<>(); - SourceGeneratorLocalData localDataCopy = Helper.deepCopy(localData); - localDataCopy.inFunction++; - boolean preloadParentFlag = false; - boolean preloadRootFlag = false; - boolean preloadSuperFlag = false; - boolean preloadArgumentsFlag = false; - boolean preloadThisFlag = false; - boolean preloadGlobalFlag = false; - - boolean suppressParentFlag = false; - boolean suppressArgumentsFlag = false; - boolean suppressThisFlag = false; - - boolean needsFun2 = false; - - List registerNames = new ArrayList<>(); - registerNames.add("***** ZERO *****"); - if (usedNames.contains("this")) { - needsFun2 = true; - preloadThisFlag = true; - registerNames.add("this"); - } else { - suppressThisFlag = true; - } - if (usedNames.contains("arguments")) { - preloadArgumentsFlag = true; - needsFun2 = true; - registerNames.add("arguments"); - } else { - suppressArgumentsFlag = true; - } - if (usedNames.contains("super")) { - preloadSuperFlag = true; - needsFun2 = true; - registerNames.add("super"); - } - if (usedNames.contains("_root")) { - preloadRootFlag = true; - needsFun2 = true; - registerNames.add("_root"); - } - if (usedNames.contains("_parent")) { - preloadParentFlag = true; - needsFun2 = true; - registerNames.add("_parent"); - } else { - suppressParentFlag = true; - } - if (usedNames.contains("_global")) { - needsFun2 = true; - preloadGlobalFlag = true; - registerNames.add("_global"); - } - - int preloadedNumber = registerNames.size(); - if (!paramNames.isEmpty()) { - needsFun2 = true; - } - if (localData.inMethod) { - needsFun2 = true; - } - if (localData.inFunction > 1) { - needsFun2 = true; - } - if (needsFun2) { - for (int i = 0; i < paramNames.size(); i++) { - paramRegs.add(registerNames.size()); - registerNames.add(paramNames.get(i)); - } - } - - int regCount = 0; - if (actions != null && !actions.isEmpty()) { - localDataCopy.inFunction++; - - for (VariableActionItem v : variables) { - String varName = v.getVariableName(); - GraphTargetItem stored = v.getStoreValue(); - if (needsFun2) { - if (v.isDefinition() && !registerNames.contains(varName)) { - registerNames.add(varName); - } - } - - if (registerNames.contains(varName)) { - if (stored != null) { - v.setBoxedValue(new StoreRegisterActionItem(null, new RegisterNumber(registerNames.indexOf(varName), varName), stored, false)); - } else { - v.setBoxedValue(new DirectValueActionItem(new RegisterNumber(registerNames.indexOf(varName), varName))); - } - } else { - if (v.isDefinition()) { - v.setBoxedValue(new DefineLocalActionItem(null, ((ActionSourceGenerator) generator).pushConstTargetItem(varName), stored)); - } else { - if (stored != null) { - v.setBoxedValue(new SetVariableActionItem(null, ((ActionSourceGenerator) generator).pushConstTargetItem(varName), stored)); - } else { - v.setBoxedValue(new GetVariableActionItem(null, ((ActionSourceGenerator) generator).pushConstTargetItem(varName))); - } - } - } - - } - for (int i = 1 /* zero is not preloaded*/; i < registerNames.size(); i++) { - localDataCopy.registerVars.put(registerNames.get(i), i); - } - - ret.addAll(asGenerator.toActionList(asGenerator.generate(localDataCopy, actions))); - - regCount = registerNames.size(); - - //some temporary registers can exceed variable+param count - for (GraphSourceItem a : ret) { - if (a instanceof ActionPush) { - ActionPush apu = (ActionPush) a; - for (Object o : apu.values) { - if (o instanceof RegisterNumber) { - RegisterNumber rn = (RegisterNumber) o; - if (rn.number >= regCount) { - regCount++; - } - } - } - } - } - } - int len = Action.actionsToBytes(asGenerator.toActionList(ret), false, SWF.DEFAULT_VERSION).length; - if (!needsFun2 && paramNames.isEmpty()) { - ret.add(0, new ActionDefineFunction(functionName, paramNames, len, SWF.DEFAULT_VERSION)); - } else { - ret.add(0, new ActionDefineFunction2(functionName, - preloadParentFlag, - preloadRootFlag, - suppressParentFlag, - preloadSuperFlag, - suppressArgumentsFlag, - preloadArgumentsFlag, - suppressThisFlag, - preloadThisFlag, - preloadGlobalFlag, - regCount, len, SWF.DEFAULT_VERSION, paramNames, paramRegs)); - } - - return ret; - } - - @Override - public boolean hasReturnValue() { - return false; //function actually returns itself, but here is false for generator to not add Pop - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.action.model; + +import com.jpexs.decompiler.flash.IdentifiersDeobfuscation; +import com.jpexs.decompiler.flash.SWF; +import com.jpexs.decompiler.flash.SourceGeneratorLocalData; +import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.parser.script.ActionSourceGenerator; +import com.jpexs.decompiler.flash.action.parser.script.VariableActionItem; +import com.jpexs.decompiler.flash.action.swf4.ActionPush; +import com.jpexs.decompiler.flash.action.swf4.RegisterNumber; +import com.jpexs.decompiler.flash.action.swf5.ActionDefineFunction; +import com.jpexs.decompiler.flash.action.swf7.ActionDefineFunction2; +import com.jpexs.decompiler.flash.helpers.GraphTextWriter; +import com.jpexs.decompiler.graph.CompilationException; +import com.jpexs.decompiler.graph.Graph; +import com.jpexs.decompiler.graph.GraphSourceItem; +import com.jpexs.decompiler.graph.GraphSourceItemPos; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.SourceGenerator; +import com.jpexs.decompiler.graph.model.LocalData; +import com.jpexs.helpers.Helper; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class FunctionActionItem extends ActionItem { + + public List actions; + + public List constants; + + public String functionName; + + public List paramNames; + + public GraphTargetItem calculatedFunctionName; + + private int regStart; + + private List variables; + + public static final int REGISTER_THIS = 1; + + public static final int REGISTER_ARGUMENTS = 2; + + public static final int REGISTER_SUPER = 3; + + public static final int REGISTER_ROOT = 4; + + public static final int REGISTER_PARENT = 5; + + public static final int REGISTER_GLOBAL = 6; + + @Override + public List getAllSubItems() { + List ret = new ArrayList<>(); + ret.addAll(actions); + return ret; + } + + public FunctionActionItem() { + super(null, PRECEDENCE_PRIMARY); + } + + public FunctionActionItem(GraphSourceItem instruction, String functionName, List paramNames, List actions, List constants, int regStart, List variables) { + super(instruction, PRECEDENCE_PRIMARY); + this.actions = actions; + this.constants = constants; + this.functionName = functionName; + this.paramNames = paramNames; + this.regStart = regStart; + this.variables = variables; + } + + @Override + public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException { + writer.append("function"); + if (calculatedFunctionName != null) { + writer.append(" "); + String fname = calculatedFunctionName.toStringNoQuotes(localData); + if (!IdentifiersDeobfuscation.isValidName(false, fname)) { + writer.append(IdentifiersDeobfuscation.makeObfuscatedIdentifier(fname)); + } else { + calculatedFunctionName.appendToNoQuotes(writer, localData); + } + } else if (!functionName.isEmpty()) { + writer.append(" "); + if (!IdentifiersDeobfuscation.isValidName(false, functionName)) { + writer.append(IdentifiersDeobfuscation.makeObfuscatedIdentifier(functionName)); + } else { + writer.append(functionName); + } + } + writer.spaceBeforeCallParenthesies(paramNames.size()); + writer.append("("); + + for (int p = 0; p < paramNames.size(); p++) { + if (p > 0) { + writer.append(", "); + } + String pname = paramNames.get(p); + if (pname == null || pname.isEmpty()) { + pname = new RegisterNumber(regStart + p).translate(); + } + if (!IdentifiersDeobfuscation.isValidName(false, pname)) { + writer.append(IdentifiersDeobfuscation.makeObfuscatedIdentifier(pname)); + } + writer.append(pname); + } + writer.append(")").startBlock(); + + Graph.graphToString(actions, writer, localData); + + return writer.endBlock(); + } + + @Override + public List getNeededSources() { + List ret = super.getNeededSources(); + for (GraphTargetItem ti : actions) { + ret.addAll(ti.getNeededSources()); + } + return ret; + } + + @Override + public boolean needsSemicolon() { + return false; + } + + @Override + public boolean isCompileTime(Set dependencies) { + for (GraphTargetItem a : actions) { + if (dependencies.contains(a)) { + return false; + } + dependencies.add(a); + if (!a.isCompileTime(dependencies)) { + return false; + } + } + return true; + } + + @Override + public Object getResult() { + if (!actions.isEmpty()) { + if (actions.get(actions.size() - 1) instanceof ReturnActionItem) { + ReturnActionItem r = (ReturnActionItem) actions.get(actions.size() - 1); + return r.value.getResult(); + } + } + return 0; + } + + @Override + public boolean needsNewLine() { + return true; + } + + @Override + public List toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException { + + Set usedNames = new HashSet<>(); + for (VariableActionItem v : variables) { + usedNames.add(v.getVariableName()); + } + + List ret = new ArrayList<>(); + ActionSourceGenerator asGenerator = (ActionSourceGenerator) generator; + List paramRegs = new ArrayList<>(); + SourceGeneratorLocalData localDataCopy = Helper.deepCopy(localData); + localDataCopy.inFunction++; + boolean preloadParentFlag = false; + boolean preloadRootFlag = false; + boolean preloadSuperFlag = false; + boolean preloadArgumentsFlag = false; + boolean preloadThisFlag = false; + boolean preloadGlobalFlag = false; + + boolean suppressParentFlag = false; + boolean suppressArgumentsFlag = false; + boolean suppressThisFlag = false; + + boolean needsFun2 = false; + + List registerNames = new ArrayList<>(); + registerNames.add("***** ZERO *****"); + if (usedNames.contains("this")) { + needsFun2 = true; + preloadThisFlag = true; + registerNames.add("this"); + } else { + suppressThisFlag = true; + } + if (usedNames.contains("arguments")) { + preloadArgumentsFlag = true; + needsFun2 = true; + registerNames.add("arguments"); + } else { + suppressArgumentsFlag = true; + } + if (usedNames.contains("super")) { + preloadSuperFlag = true; + needsFun2 = true; + registerNames.add("super"); + } + if (usedNames.contains("_root")) { + preloadRootFlag = true; + needsFun2 = true; + registerNames.add("_root"); + } + if (usedNames.contains("_parent")) { + preloadParentFlag = true; + needsFun2 = true; + registerNames.add("_parent"); + } else { + suppressParentFlag = true; + } + if (usedNames.contains("_global")) { + needsFun2 = true; + preloadGlobalFlag = true; + registerNames.add("_global"); + } + + int preloadedNumber = registerNames.size(); + if (!paramNames.isEmpty()) { + needsFun2 = true; + } + if (localData.inMethod) { + needsFun2 = true; + } + if (localData.inFunction > 1) { + needsFun2 = true; + } + if (needsFun2) { + for (int i = 0; i < paramNames.size(); i++) { + paramRegs.add(registerNames.size()); + registerNames.add(paramNames.get(i)); + } + } + + int regCount = 0; + if (actions != null && !actions.isEmpty()) { + localDataCopy.inFunction++; + + for (VariableActionItem v : variables) { + String varName = v.getVariableName(); + GraphTargetItem stored = v.getStoreValue(); + if (needsFun2) { + if (v.isDefinition() && !registerNames.contains(varName)) { + registerNames.add(varName); + } + } + + if (registerNames.contains(varName)) { + if (stored != null) { + v.setBoxedValue(new StoreRegisterActionItem(null, new RegisterNumber(registerNames.indexOf(varName), varName), stored, false)); + } else { + v.setBoxedValue(new DirectValueActionItem(new RegisterNumber(registerNames.indexOf(varName), varName))); + } + } else { + if (v.isDefinition()) { + v.setBoxedValue(new DefineLocalActionItem(null, ((ActionSourceGenerator) generator).pushConstTargetItem(varName), stored)); + } else { + if (stored != null) { + v.setBoxedValue(new SetVariableActionItem(null, ((ActionSourceGenerator) generator).pushConstTargetItem(varName), stored)); + } else { + v.setBoxedValue(new GetVariableActionItem(null, ((ActionSourceGenerator) generator).pushConstTargetItem(varName))); + } + } + } + + } + for (int i = 1 /* zero is not preloaded*/; i < registerNames.size(); i++) { + localDataCopy.registerVars.put(registerNames.get(i), i); + } + + ret.addAll(asGenerator.toActionList(asGenerator.generate(localDataCopy, actions))); + + regCount = registerNames.size(); + + //some temporary registers can exceed variable+param count + for (GraphSourceItem a : ret) { + if (a instanceof ActionPush) { + ActionPush apu = (ActionPush) a; + for (Object o : apu.values) { + if (o instanceof RegisterNumber) { + RegisterNumber rn = (RegisterNumber) o; + if (rn.number >= regCount) { + regCount++; + } + } + } + } + } + } + int len = Action.actionsToBytes(asGenerator.toActionList(ret), false, SWF.DEFAULT_VERSION).length; + if (!needsFun2 && paramNames.isEmpty()) { + ret.add(0, new ActionDefineFunction(functionName, paramNames, len, SWF.DEFAULT_VERSION)); + } else { + ret.add(0, new ActionDefineFunction2(functionName, + preloadParentFlag, + preloadRootFlag, + suppressParentFlag, + preloadSuperFlag, + suppressArgumentsFlag, + preloadArgumentsFlag, + suppressThisFlag, + preloadThisFlag, + preloadGlobalFlag, + regCount, len, SWF.DEFAULT_VERSION, paramNames, paramRegs)); + } + + return ret; + } + + @Override + public boolean hasReturnValue() { + return false; //function actually returns itself, but here is false for generator to not add Pop + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/SetMemberActionItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/SetMemberActionItem.java index 653e30b70..29e9bd47d 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/SetMemberActionItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/SetMemberActionItem.java @@ -1,142 +1,142 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.action.model; - -import com.jpexs.decompiler.flash.IdentifiersDeobfuscation; -import com.jpexs.decompiler.flash.SourceGeneratorLocalData; -import com.jpexs.decompiler.flash.action.parser.script.ActionSourceGenerator; -import com.jpexs.decompiler.flash.action.swf4.ActionPush; -import com.jpexs.decompiler.flash.action.swf4.RegisterNumber; -import com.jpexs.decompiler.flash.action.swf5.ActionSetMember; -import com.jpexs.decompiler.flash.action.swf5.ActionStoreRegister; -import com.jpexs.decompiler.flash.helpers.GraphTextWriter; -import com.jpexs.decompiler.graph.CompilationException; -import com.jpexs.decompiler.graph.GraphPart; -import com.jpexs.decompiler.graph.GraphSourceItem; -import com.jpexs.decompiler.graph.GraphSourceItemPos; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.SourceGenerator; -import com.jpexs.decompiler.graph.model.LocalData; -import java.util.ArrayList; -import java.util.List; - -public class SetMemberActionItem extends ActionItem implements SetTypeActionItem { - - public GraphTargetItem object; - - public GraphTargetItem objectName; - - //public GraphTargetItem value; - private int tempRegister = -1; - - @Override - public List getAllSubItems() { - List ret = new ArrayList<>(); - ret.add(object); - ret.add(value); - return ret; - } - - @Override - public GraphPart getFirstPart() { - return value.getFirstPart(); - } - - @Override - public void setValue(GraphTargetItem value) { - this.value = value; - } - - @Override - public int getTempRegister() { - return tempRegister; - } - - @Override - public void setTempRegister(int tempRegister) { - this.tempRegister = tempRegister; - } - - @Override - public GraphTargetItem getValue() { - return value; - } - - public SetMemberActionItem(GraphSourceItem instruction, GraphTargetItem object, GraphTargetItem objectName, GraphTargetItem value) { - super(instruction, PRECEDENCE_ASSIGMENT); - this.object = object; - this.objectName = objectName; - this.value = value; - } - - @Override - public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException { - object.toString(writer, localData); - - if ((!(objectName instanceof DirectValueActionItem)) || (!((DirectValueActionItem) objectName).isString()) || (!IdentifiersDeobfuscation.isValidName(false, ((DirectValueActionItem) objectName).toStringNoQuotes(localData)))) { - writer.append("["); - objectName.toString(writer, localData); - writer.append("]"); - } else { - writer.append("."); - stripQuotes(objectName, localData, writer); - } - writer.append(" = "); - return value.toString(writer, localData); - - } - - @Override - public GraphTargetItem getObject() { - return new GetMemberActionItem(src, object, objectName); - } - - @Override - public List getNeededSources() { - List ret = super.getNeededSources(); - ret.addAll(object.getNeededSources()); - ret.addAll(objectName.getNeededSources()); - ret.addAll(value.getNeededSources()); - return ret; - } - - @Override - public boolean hasSideEffect() { - return true; - } - - @Override - public List toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException { - ActionSourceGenerator asGenerator = (ActionSourceGenerator) generator; - int tmpReg = asGenerator.getTempRegister(localData); - try { - return toSourceMerge(localData, generator, object, objectName, value, new ActionStoreRegister(tmpReg), new ActionSetMember(), new ActionPush(new RegisterNumber(tmpReg))); - } finally { - asGenerator.releaseTempRegister(localData, tmpReg); - } - } - - @Override - public List toSourceIgnoreReturnValue(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException { - return toSourceMerge(localData, generator, object, objectName, value, new ActionSetMember()); - } - - @Override - public boolean hasReturnValue() { - return false; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.action.model; + +import com.jpexs.decompiler.flash.IdentifiersDeobfuscation; +import com.jpexs.decompiler.flash.SourceGeneratorLocalData; +import com.jpexs.decompiler.flash.action.parser.script.ActionSourceGenerator; +import com.jpexs.decompiler.flash.action.swf4.ActionPush; +import com.jpexs.decompiler.flash.action.swf4.RegisterNumber; +import com.jpexs.decompiler.flash.action.swf5.ActionSetMember; +import com.jpexs.decompiler.flash.action.swf5.ActionStoreRegister; +import com.jpexs.decompiler.flash.helpers.GraphTextWriter; +import com.jpexs.decompiler.graph.CompilationException; +import com.jpexs.decompiler.graph.GraphPart; +import com.jpexs.decompiler.graph.GraphSourceItem; +import com.jpexs.decompiler.graph.GraphSourceItemPos; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.SourceGenerator; +import com.jpexs.decompiler.graph.model.LocalData; +import java.util.ArrayList; +import java.util.List; + +public class SetMemberActionItem extends ActionItem implements SetTypeActionItem { + + public GraphTargetItem object; + + public GraphTargetItem objectName; + + //public GraphTargetItem value; + private int tempRegister = -1; + + @Override + public List getAllSubItems() { + List ret = new ArrayList<>(); + ret.add(object); + ret.add(value); + return ret; + } + + @Override + public GraphPart getFirstPart() { + return value.getFirstPart(); + } + + @Override + public void setValue(GraphTargetItem value) { + this.value = value; + } + + @Override + public int getTempRegister() { + return tempRegister; + } + + @Override + public void setTempRegister(int tempRegister) { + this.tempRegister = tempRegister; + } + + @Override + public GraphTargetItem getValue() { + return value; + } + + public SetMemberActionItem(GraphSourceItem instruction, GraphTargetItem object, GraphTargetItem objectName, GraphTargetItem value) { + super(instruction, PRECEDENCE_ASSIGMENT); + this.object = object; + this.objectName = objectName; + this.value = value; + } + + @Override + public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException { + object.toString(writer, localData); + + if ((!(objectName instanceof DirectValueActionItem)) || (!((DirectValueActionItem) objectName).isString()) || (!IdentifiersDeobfuscation.isValidName(false, ((DirectValueActionItem) objectName).toStringNoQuotes(localData)))) { + writer.append("["); + objectName.toString(writer, localData); + writer.append("]"); + } else { + writer.append("."); + stripQuotes(objectName, localData, writer); + } + writer.append(" = "); + return value.toString(writer, localData); + + } + + @Override + public GraphTargetItem getObject() { + return new GetMemberActionItem(src, object, objectName); + } + + @Override + public List getNeededSources() { + List ret = super.getNeededSources(); + ret.addAll(object.getNeededSources()); + ret.addAll(objectName.getNeededSources()); + ret.addAll(value.getNeededSources()); + return ret; + } + + @Override + public boolean hasSideEffect() { + return true; + } + + @Override + public List toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException { + ActionSourceGenerator asGenerator = (ActionSourceGenerator) generator; + int tmpReg = asGenerator.getTempRegister(localData); + try { + return toSourceMerge(localData, generator, object, objectName, value, new ActionStoreRegister(tmpReg), new ActionSetMember(), new ActionPush(new RegisterNumber(tmpReg))); + } finally { + asGenerator.releaseTempRegister(localData, tmpReg); + } + } + + @Override + public List toSourceIgnoreReturnValue(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException { + return toSourceMerge(localData, generator, object, objectName, value, new ActionSetMember()); + } + + @Override + public boolean hasReturnValue() { + return false; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/SetPropertyActionItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/SetPropertyActionItem.java index 320dc546a..5aea831b5 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/SetPropertyActionItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/SetPropertyActionItem.java @@ -1,126 +1,126 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.action.model; - -import com.jpexs.decompiler.flash.SourceGeneratorLocalData; -import com.jpexs.decompiler.flash.action.Action; -import com.jpexs.decompiler.flash.action.parser.script.ActionSourceGenerator; -import com.jpexs.decompiler.flash.action.swf4.ActionPush; -import com.jpexs.decompiler.flash.action.swf4.ActionSetProperty; -import com.jpexs.decompiler.flash.action.swf4.RegisterNumber; -import com.jpexs.decompiler.flash.action.swf5.ActionStoreRegister; -import com.jpexs.decompiler.flash.helpers.GraphTextWriter; -import com.jpexs.decompiler.graph.CompilationException; -import com.jpexs.decompiler.graph.GraphPart; -import com.jpexs.decompiler.graph.GraphSourceItem; -import com.jpexs.decompiler.graph.GraphSourceItemPos; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.SourceGenerator; -import com.jpexs.decompiler.graph.model.LocalData; -import java.util.List; - -public class SetPropertyActionItem extends ActionItem implements SetTypeActionItem { - - public GraphTargetItem target; - - public int propertyIndex; - //public GraphTargetItem value; - - @Override - public GraphPart getFirstPart() { - return value.getFirstPart(); - } - - @Override - public void setValue(GraphTargetItem value) { - this.value = value; - } - - private int tempRegister = -1; - - @Override - public int getTempRegister() { - return tempRegister; - } - - @Override - public void setTempRegister(int tempRegister) { - this.tempRegister = tempRegister; - } - - @Override - public GraphTargetItem getValue() { - return value; - } - - public SetPropertyActionItem(GraphSourceItem instruction, GraphTargetItem target, int propertyIndex, GraphTargetItem value) { - super(instruction, PRECEDENCE_ASSIGMENT); - this.target = target; - this.propertyIndex = propertyIndex; - this.value = value; - } - - @Override - public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException { - if (isEmptyString(target)) { - writer.append(Action.propertyNames[propertyIndex] + " = "); - return value.toString(writer, localData); - } - target.toString(writer, localData); - writer.append("." + Action.propertyNames[propertyIndex] + " = "); - return value.toString(writer, localData); - } - - @Override - public GraphTargetItem getObject() { - return new GetPropertyActionItem(src, target, propertyIndex); - } - - @Override - public List getNeededSources() { - List ret = super.getNeededSources(); - ret.addAll(target.getNeededSources()); - ret.addAll(value.getNeededSources()); - return ret; - } - - @Override - public boolean hasSideEffect() { - return true; - } - - @Override - public List toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException { - ActionSourceGenerator asGenerator = (ActionSourceGenerator) generator; - int tmpReg = asGenerator.getTempRegister(localData); - try { - return toSourceMerge(localData, generator, target, new ActionPush((Long) (long) propertyIndex), value, new ActionStoreRegister(tmpReg), new ActionSetProperty(), new ActionPush(new RegisterNumber(tmpReg))); - } finally { - asGenerator.releaseTempRegister(localData, tmpReg); - } - } - - @Override - public List toSourceIgnoreReturnValue(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException { - return toSourceMerge(localData, generator, target, new ActionPush((Long) (long) propertyIndex), value, new ActionSetProperty()); - } - - @Override - public boolean hasReturnValue() { - return false; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.action.model; + +import com.jpexs.decompiler.flash.SourceGeneratorLocalData; +import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.parser.script.ActionSourceGenerator; +import com.jpexs.decompiler.flash.action.swf4.ActionPush; +import com.jpexs.decompiler.flash.action.swf4.ActionSetProperty; +import com.jpexs.decompiler.flash.action.swf4.RegisterNumber; +import com.jpexs.decompiler.flash.action.swf5.ActionStoreRegister; +import com.jpexs.decompiler.flash.helpers.GraphTextWriter; +import com.jpexs.decompiler.graph.CompilationException; +import com.jpexs.decompiler.graph.GraphPart; +import com.jpexs.decompiler.graph.GraphSourceItem; +import com.jpexs.decompiler.graph.GraphSourceItemPos; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.SourceGenerator; +import com.jpexs.decompiler.graph.model.LocalData; +import java.util.List; + +public class SetPropertyActionItem extends ActionItem implements SetTypeActionItem { + + public GraphTargetItem target; + + public int propertyIndex; + //public GraphTargetItem value; + + @Override + public GraphPart getFirstPart() { + return value.getFirstPart(); + } + + @Override + public void setValue(GraphTargetItem value) { + this.value = value; + } + + private int tempRegister = -1; + + @Override + public int getTempRegister() { + return tempRegister; + } + + @Override + public void setTempRegister(int tempRegister) { + this.tempRegister = tempRegister; + } + + @Override + public GraphTargetItem getValue() { + return value; + } + + public SetPropertyActionItem(GraphSourceItem instruction, GraphTargetItem target, int propertyIndex, GraphTargetItem value) { + super(instruction, PRECEDENCE_ASSIGMENT); + this.target = target; + this.propertyIndex = propertyIndex; + this.value = value; + } + + @Override + public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException { + if (isEmptyString(target)) { + writer.append(Action.propertyNames[propertyIndex] + " = "); + return value.toString(writer, localData); + } + target.toString(writer, localData); + writer.append("." + Action.propertyNames[propertyIndex] + " = "); + return value.toString(writer, localData); + } + + @Override + public GraphTargetItem getObject() { + return new GetPropertyActionItem(src, target, propertyIndex); + } + + @Override + public List getNeededSources() { + List ret = super.getNeededSources(); + ret.addAll(target.getNeededSources()); + ret.addAll(value.getNeededSources()); + return ret; + } + + @Override + public boolean hasSideEffect() { + return true; + } + + @Override + public List toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException { + ActionSourceGenerator asGenerator = (ActionSourceGenerator) generator; + int tmpReg = asGenerator.getTempRegister(localData); + try { + return toSourceMerge(localData, generator, target, new ActionPush((Long) (long) propertyIndex), value, new ActionStoreRegister(tmpReg), new ActionSetProperty(), new ActionPush(new RegisterNumber(tmpReg))); + } finally { + asGenerator.releaseTempRegister(localData, tmpReg); + } + } + + @Override + public List toSourceIgnoreReturnValue(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException { + return toSourceMerge(localData, generator, target, new ActionPush((Long) (long) propertyIndex), value, new ActionSetProperty()); + } + + @Override + public boolean hasReturnValue() { + return false; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/SetVariableActionItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/SetVariableActionItem.java index 2737e1ca8..7913d0582 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/SetVariableActionItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/SetVariableActionItem.java @@ -1,142 +1,142 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.action.model; - -import com.jpexs.decompiler.flash.IdentifiersDeobfuscation; -import com.jpexs.decompiler.flash.SourceGeneratorLocalData; -import com.jpexs.decompiler.flash.action.parser.script.ActionSourceGenerator; -import com.jpexs.decompiler.flash.action.swf4.ActionPush; -import com.jpexs.decompiler.flash.action.swf4.ActionSetVariable; -import com.jpexs.decompiler.flash.action.swf4.RegisterNumber; -import com.jpexs.decompiler.flash.action.swf5.ActionStoreRegister; -import com.jpexs.decompiler.flash.helpers.GraphTextWriter; -import com.jpexs.decompiler.graph.CompilationException; -import com.jpexs.decompiler.graph.GraphPart; -import com.jpexs.decompiler.graph.GraphSourceItem; -import com.jpexs.decompiler.graph.GraphSourceItemPos; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.SourceGenerator; -import com.jpexs.decompiler.graph.model.LocalData; -import java.util.List; -import java.util.Set; - -public class SetVariableActionItem extends ActionItem implements SetTypeActionItem { - - public GraphTargetItem name; - - //public GraphTargetItem value; - private int tempRegister = -1; - - @Override - public GraphPart getFirstPart() { - return value.getFirstPart(); - } - - @Override - public void setValue(GraphTargetItem value) { - this.value = value; - } - - @Override - public int getTempRegister() { - return tempRegister; - } - - @Override - public void setTempRegister(int tempRegister) { - this.tempRegister = tempRegister; - } - - @Override - public GraphTargetItem getValue() { - return value; - } - - public SetVariableActionItem(GraphSourceItem instruction, GraphTargetItem name, GraphTargetItem value) { - super(instruction, PRECEDENCE_ASSIGMENT); - this.name = name; - this.value = value; - } - - @Override - public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException { - if (((name instanceof DirectValueActionItem)) && (((DirectValueActionItem) name).isString()) && (!IdentifiersDeobfuscation.isValidName(false, ((DirectValueActionItem) name).toStringNoQuotes(localData), "this", "super"))) { - writer.append(IdentifiersDeobfuscation.makeObfuscatedIdentifier(((DirectValueActionItem) name).toStringNoQuotes(localData))); - writer.append(" = "); - return value.toString(writer, localData); - } else if ((!(name instanceof DirectValueActionItem)) || (!((DirectValueActionItem) name).isString())) { - writer.append("set"); - writer.spaceBeforeCallParenthesies(2); - writer.append("("); - name.toString(writer, localData); - writer.append(","); - value.toString(writer, localData); - return writer.append(")"); - } - stripQuotes(name, localData, writer); - writer.append(" = "); - return value.toString(writer, localData); - } - - @Override - public GraphTargetItem getObject() { - return new GetVariableActionItem(src, name); - } - - @Override - public List getNeededSources() { - List ret = super.getNeededSources(); - ret.addAll(name.getNeededSources()); - ret.addAll(value.getNeededSources()); - return ret; - } - - @Override - public boolean isCompileTime(Set dependencies) { - if (dependencies.contains(value)) { - return false; - } - dependencies.add(value); - return value.isCompileTime(dependencies); - } - - @Override - public boolean hasSideEffect() { - return true; - } - - @Override - public List toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException { - ActionSourceGenerator asGenerator = (ActionSourceGenerator) generator; - int tmpReg = asGenerator.getTempRegister(localData); - try { - return toSourceMerge(localData, generator, name, value, new ActionStoreRegister(tmpReg), new ActionSetVariable(), new ActionPush(new RegisterNumber(tmpReg))); - } finally { - asGenerator.releaseTempRegister(localData, tmpReg); - } - } - - @Override - public List toSourceIgnoreReturnValue(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException { - return toSourceMerge(localData, generator, name, value, new ActionSetVariable()); - } - - @Override - public boolean hasReturnValue() { - return false; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.action.model; + +import com.jpexs.decompiler.flash.IdentifiersDeobfuscation; +import com.jpexs.decompiler.flash.SourceGeneratorLocalData; +import com.jpexs.decompiler.flash.action.parser.script.ActionSourceGenerator; +import com.jpexs.decompiler.flash.action.swf4.ActionPush; +import com.jpexs.decompiler.flash.action.swf4.ActionSetVariable; +import com.jpexs.decompiler.flash.action.swf4.RegisterNumber; +import com.jpexs.decompiler.flash.action.swf5.ActionStoreRegister; +import com.jpexs.decompiler.flash.helpers.GraphTextWriter; +import com.jpexs.decompiler.graph.CompilationException; +import com.jpexs.decompiler.graph.GraphPart; +import com.jpexs.decompiler.graph.GraphSourceItem; +import com.jpexs.decompiler.graph.GraphSourceItemPos; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.SourceGenerator; +import com.jpexs.decompiler.graph.model.LocalData; +import java.util.List; +import java.util.Set; + +public class SetVariableActionItem extends ActionItem implements SetTypeActionItem { + + public GraphTargetItem name; + + //public GraphTargetItem value; + private int tempRegister = -1; + + @Override + public GraphPart getFirstPart() { + return value.getFirstPart(); + } + + @Override + public void setValue(GraphTargetItem value) { + this.value = value; + } + + @Override + public int getTempRegister() { + return tempRegister; + } + + @Override + public void setTempRegister(int tempRegister) { + this.tempRegister = tempRegister; + } + + @Override + public GraphTargetItem getValue() { + return value; + } + + public SetVariableActionItem(GraphSourceItem instruction, GraphTargetItem name, GraphTargetItem value) { + super(instruction, PRECEDENCE_ASSIGMENT); + this.name = name; + this.value = value; + } + + @Override + public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException { + if (((name instanceof DirectValueActionItem)) && (((DirectValueActionItem) name).isString()) && (!IdentifiersDeobfuscation.isValidName(false, ((DirectValueActionItem) name).toStringNoQuotes(localData), "this", "super"))) { + writer.append(IdentifiersDeobfuscation.makeObfuscatedIdentifier(((DirectValueActionItem) name).toStringNoQuotes(localData))); + writer.append(" = "); + return value.toString(writer, localData); + } else if ((!(name instanceof DirectValueActionItem)) || (!((DirectValueActionItem) name).isString())) { + writer.append("set"); + writer.spaceBeforeCallParenthesies(2); + writer.append("("); + name.toString(writer, localData); + writer.append(","); + value.toString(writer, localData); + return writer.append(")"); + } + stripQuotes(name, localData, writer); + writer.append(" = "); + return value.toString(writer, localData); + } + + @Override + public GraphTargetItem getObject() { + return new GetVariableActionItem(src, name); + } + + @Override + public List getNeededSources() { + List ret = super.getNeededSources(); + ret.addAll(name.getNeededSources()); + ret.addAll(value.getNeededSources()); + return ret; + } + + @Override + public boolean isCompileTime(Set dependencies) { + if (dependencies.contains(value)) { + return false; + } + dependencies.add(value); + return value.isCompileTime(dependencies); + } + + @Override + public boolean hasSideEffect() { + return true; + } + + @Override + public List toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException { + ActionSourceGenerator asGenerator = (ActionSourceGenerator) generator; + int tmpReg = asGenerator.getTempRegister(localData); + try { + return toSourceMerge(localData, generator, name, value, new ActionStoreRegister(tmpReg), new ActionSetVariable(), new ActionPush(new RegisterNumber(tmpReg))); + } finally { + asGenerator.releaseTempRegister(localData, tmpReg); + } + } + + @Override + public List toSourceIgnoreReturnValue(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException { + return toSourceMerge(localData, generator, name, value, new ActionSetVariable()); + } + + @Override + public boolean hasReturnValue() { + return false; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/clauses/ForInActionItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/clauses/ForInActionItem.java index 527acaa5c..8f106f250 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/clauses/ForInActionItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/clauses/ForInActionItem.java @@ -1,162 +1,162 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.action.model.clauses; - -import com.jpexs.decompiler.flash.SWF; -import com.jpexs.decompiler.flash.SourceGeneratorLocalData; -import com.jpexs.decompiler.flash.action.Action; -import com.jpexs.decompiler.flash.action.model.DirectValueActionItem; -import com.jpexs.decompiler.flash.action.parser.script.ActionSourceGenerator; -import com.jpexs.decompiler.flash.action.swf4.ActionIf; -import com.jpexs.decompiler.flash.action.swf4.ActionJump; -import com.jpexs.decompiler.flash.action.swf4.ActionPush; -import com.jpexs.decompiler.flash.action.swf4.RegisterNumber; -import com.jpexs.decompiler.flash.action.swf5.ActionEquals2; -import com.jpexs.decompiler.flash.action.swf5.ActionStoreRegister; -import com.jpexs.decompiler.flash.action.swf6.ActionEnumerate2; -import com.jpexs.decompiler.flash.ecma.Null; -import com.jpexs.decompiler.flash.helpers.GraphTextWriter; -import com.jpexs.decompiler.flash.helpers.LoopWithType; -import com.jpexs.decompiler.flash.helpers.NulWriter; -import com.jpexs.decompiler.graph.Block; -import com.jpexs.decompiler.graph.CompilationException; -import com.jpexs.decompiler.graph.GraphSourceItem; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.Loop; -import com.jpexs.decompiler.graph.SourceGenerator; -import com.jpexs.decompiler.graph.model.ContinueItem; -import com.jpexs.decompiler.graph.model.LocalData; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; - -public class ForInActionItem extends LoopActionItem implements Block { - - public GraphTargetItem variableName; - - public GraphTargetItem enumVariable; - - public List commands; - - private boolean labelUsed; - - @Override - public List> getSubs() { - List> ret = new ArrayList<>(); - if (commands != null) { - ret.add(commands); - } - return ret; - } - - public ForInActionItem(Action instruction, Loop loop, GraphTargetItem variableName, GraphTargetItem enumVariable, List commands) { - super(instruction, loop); - this.variableName = variableName; - this.enumVariable = enumVariable; - this.commands = commands; - } - - @Override - public boolean needsSemicolon() { - return false; - } - - @Override - public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException { - if (writer instanceof NulWriter) { - ((NulWriter) writer).startLoop(loop.id, LoopWithType.LOOP_TYPE_LOOP); - } - if (labelUsed) { - writer.append("loop" + loop.id + ":").newLine(); - } - writer.append("for"); - if (writer.getFormatting().spaceBeforeParenthesesForParentheses) { - writer.append(" "); - } - writer.append("("); - if ((variableName instanceof DirectValueActionItem) && (((DirectValueActionItem) variableName).value instanceof RegisterNumber)) { - writer.append("var "); - } - stripQuotes(variableName, localData, writer); - writer.append(" in "); - enumVariable.toString(writer, localData); - writer.append(")").startBlock(); - for (GraphTargetItem ti : commands) { - ti.toStringSemicoloned(writer, localData).newLine(); - } - writer.endBlock(); - if (writer instanceof NulWriter) { - LoopWithType loopOjb = ((NulWriter) writer).endLoop(loop.id); - labelUsed = loopOjb.used; - } - return writer; - } - - @Override - public List getContinues() { - List ret = new ArrayList<>(); - for (GraphTargetItem ti : commands) { - if (ti instanceof ContinueItem) { - ret.add((ContinueItem) ti); - } - if (ti instanceof Block) { - ret.addAll(((Block) ti).getContinues()); - } - } - return ret; - } - - @Override - public List toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException { - List ret = new ArrayList<>(); - ActionSourceGenerator asGenerator = (ActionSourceGenerator) generator; - HashMap registerVars = asGenerator.getRegisterVars(localData); - ret.addAll(enumVariable.toSource(localData, generator)); - ret.add(new ActionEnumerate2()); - - List loopExpr = new ArrayList<>(); - int exprReg = asGenerator.getTempRegister(localData); - - loopExpr.add(new ActionStoreRegister(exprReg)); - loopExpr.add(new ActionPush(new Null())); - loopExpr.add(new ActionEquals2()); - ActionIf forInEndIf = new ActionIf(0); - loopExpr.add(forInEndIf); - List loopBody = new ArrayList<>(); - loopBody.add(new ActionPush(new RegisterNumber(exprReg))); - loopBody.addAll(asGenerator.toActionList(variableName.toSourceIgnoreReturnValue(localData, generator))); - int oldForIn = asGenerator.getForInLevel(localData); - asGenerator.setForInLevel(localData, oldForIn + 1); - loopBody.addAll(asGenerator.toActionList(asGenerator.generate(localData, commands))); - asGenerator.setForInLevel(localData, oldForIn); - ActionJump forinJmpBack = new ActionJump(0); - loopBody.add(forinJmpBack); - int bodyLen = Action.actionsToBytes(loopBody, false, SWF.DEFAULT_VERSION).length; - int exprLen = Action.actionsToBytes(loopExpr, false, SWF.DEFAULT_VERSION).length; - forinJmpBack.setJumpOffset(-bodyLen - exprLen); - forInEndIf.setJumpOffset(bodyLen); - ret.addAll(loopExpr); - ret.addAll(loopBody); - asGenerator.releaseTempRegister(localData, exprReg); - return ret; - } - - @Override - public boolean hasReturnValue() { - return false; - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.action.model.clauses; + +import com.jpexs.decompiler.flash.SWF; +import com.jpexs.decompiler.flash.SourceGeneratorLocalData; +import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.model.DirectValueActionItem; +import com.jpexs.decompiler.flash.action.parser.script.ActionSourceGenerator; +import com.jpexs.decompiler.flash.action.swf4.ActionIf; +import com.jpexs.decompiler.flash.action.swf4.ActionJump; +import com.jpexs.decompiler.flash.action.swf4.ActionPush; +import com.jpexs.decompiler.flash.action.swf4.RegisterNumber; +import com.jpexs.decompiler.flash.action.swf5.ActionEquals2; +import com.jpexs.decompiler.flash.action.swf5.ActionStoreRegister; +import com.jpexs.decompiler.flash.action.swf6.ActionEnumerate2; +import com.jpexs.decompiler.flash.ecma.Null; +import com.jpexs.decompiler.flash.helpers.GraphTextWriter; +import com.jpexs.decompiler.flash.helpers.LoopWithType; +import com.jpexs.decompiler.flash.helpers.NulWriter; +import com.jpexs.decompiler.graph.Block; +import com.jpexs.decompiler.graph.CompilationException; +import com.jpexs.decompiler.graph.GraphSourceItem; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.Loop; +import com.jpexs.decompiler.graph.SourceGenerator; +import com.jpexs.decompiler.graph.model.ContinueItem; +import com.jpexs.decompiler.graph.model.LocalData; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +public class ForInActionItem extends LoopActionItem implements Block { + + public GraphTargetItem variableName; + + public GraphTargetItem enumVariable; + + public List commands; + + private boolean labelUsed; + + @Override + public List> getSubs() { + List> ret = new ArrayList<>(); + if (commands != null) { + ret.add(commands); + } + return ret; + } + + public ForInActionItem(Action instruction, Loop loop, GraphTargetItem variableName, GraphTargetItem enumVariable, List commands) { + super(instruction, loop); + this.variableName = variableName; + this.enumVariable = enumVariable; + this.commands = commands; + } + + @Override + public boolean needsSemicolon() { + return false; + } + + @Override + public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException { + if (writer instanceof NulWriter) { + ((NulWriter) writer).startLoop(loop.id, LoopWithType.LOOP_TYPE_LOOP); + } + if (labelUsed) { + writer.append("loop" + loop.id + ":").newLine(); + } + writer.append("for"); + if (writer.getFormatting().spaceBeforeParenthesesForParentheses) { + writer.append(" "); + } + writer.append("("); + if ((variableName instanceof DirectValueActionItem) && (((DirectValueActionItem) variableName).value instanceof RegisterNumber)) { + writer.append("var "); + } + stripQuotes(variableName, localData, writer); + writer.append(" in "); + enumVariable.toString(writer, localData); + writer.append(")").startBlock(); + for (GraphTargetItem ti : commands) { + ti.toStringSemicoloned(writer, localData).newLine(); + } + writer.endBlock(); + if (writer instanceof NulWriter) { + LoopWithType loopOjb = ((NulWriter) writer).endLoop(loop.id); + labelUsed = loopOjb.used; + } + return writer; + } + + @Override + public List getContinues() { + List ret = new ArrayList<>(); + for (GraphTargetItem ti : commands) { + if (ti instanceof ContinueItem) { + ret.add((ContinueItem) ti); + } + if (ti instanceof Block) { + ret.addAll(((Block) ti).getContinues()); + } + } + return ret; + } + + @Override + public List toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException { + List ret = new ArrayList<>(); + ActionSourceGenerator asGenerator = (ActionSourceGenerator) generator; + HashMap registerVars = asGenerator.getRegisterVars(localData); + ret.addAll(enumVariable.toSource(localData, generator)); + ret.add(new ActionEnumerate2()); + + List loopExpr = new ArrayList<>(); + int exprReg = asGenerator.getTempRegister(localData); + + loopExpr.add(new ActionStoreRegister(exprReg)); + loopExpr.add(new ActionPush(new Null())); + loopExpr.add(new ActionEquals2()); + ActionIf forInEndIf = new ActionIf(0); + loopExpr.add(forInEndIf); + List loopBody = new ArrayList<>(); + loopBody.add(new ActionPush(new RegisterNumber(exprReg))); + loopBody.addAll(asGenerator.toActionList(variableName.toSourceIgnoreReturnValue(localData, generator))); + int oldForIn = asGenerator.getForInLevel(localData); + asGenerator.setForInLevel(localData, oldForIn + 1); + loopBody.addAll(asGenerator.toActionList(asGenerator.generate(localData, commands))); + asGenerator.setForInLevel(localData, oldForIn); + ActionJump forinJmpBack = new ActionJump(0); + loopBody.add(forinJmpBack); + int bodyLen = Action.actionsToBytes(loopBody, false, SWF.DEFAULT_VERSION).length; + int exprLen = Action.actionsToBytes(loopExpr, false, SWF.DEFAULT_VERSION).length; + forinJmpBack.setJumpOffset(-bodyLen - exprLen); + forInEndIf.setJumpOffset(bodyLen); + ret.addAll(loopExpr); + ret.addAll(loopBody); + asGenerator.releaseTempRegister(localData, exprReg); + return ret; + } + + @Override + public boolean hasReturnValue() { + return false; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/PreDecrementActionItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/PreDecrementActionItem.java index 9997baa0d..a6cae52cc 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/PreDecrementActionItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/PreDecrementActionItem.java @@ -1,104 +1,104 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.action.model.operations; - -import com.jpexs.decompiler.flash.SourceGeneratorLocalData; -import com.jpexs.decompiler.flash.action.model.DirectValueActionItem; -import com.jpexs.decompiler.flash.action.model.GetMemberActionItem; -import com.jpexs.decompiler.flash.action.model.GetPropertyActionItem; -import com.jpexs.decompiler.flash.action.model.GetVariableActionItem; -import com.jpexs.decompiler.flash.action.parser.script.ActionSourceGenerator; -import com.jpexs.decompiler.flash.action.parser.script.VariableActionItem; -import com.jpexs.decompiler.flash.action.swf4.ActionPush; -import com.jpexs.decompiler.flash.action.swf4.ActionSetProperty; -import com.jpexs.decompiler.flash.action.swf4.ActionSetVariable; -import com.jpexs.decompiler.flash.action.swf4.RegisterNumber; -import com.jpexs.decompiler.flash.action.swf5.ActionDecrement; -import com.jpexs.decompiler.flash.action.swf5.ActionSetMember; -import com.jpexs.decompiler.flash.action.swf5.ActionStoreRegister; -import com.jpexs.decompiler.flash.ecma.EcmaScript; -import com.jpexs.decompiler.graph.CompilationException; -import com.jpexs.decompiler.graph.GraphSourceItem; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.SourceGenerator; -import com.jpexs.decompiler.graph.model.UnaryOpItem; -import java.util.ArrayList; -import java.util.List; - -public class PreDecrementActionItem extends UnaryOpItem { - - public PreDecrementActionItem(GraphSourceItem instruction, GraphTargetItem object) { - super(instruction, PRECEDENCE_UNARY, object, "--"); - } - - @Override - public Object getResult() { - return EcmaScript.toNumber(value.getResult()) - 1; - } - - @Override - public List toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException { - ActionSourceGenerator asGenerator = (ActionSourceGenerator) generator; - List ret = new ArrayList<>(); - GraphTargetItem val = value; - if (val instanceof VariableActionItem) { - val = ((VariableActionItem) val).getBoxedValue(); - } - if (val instanceof GetVariableActionItem) { - GetVariableActionItem gv = (GetVariableActionItem) val; - ret.addAll(gv.toSource(localData, generator)); - ret.remove(ret.size() - 1); //ActionGetVariable - ret.addAll(gv.toSource(localData, generator)); - ret.add(new ActionDecrement()); - int tmpReg = asGenerator.getTempRegister(localData); - ret.add(new ActionStoreRegister(tmpReg)); - ret.add(new ActionSetVariable()); - ret.add(new ActionPush(new RegisterNumber(tmpReg))); - asGenerator.releaseTempRegister(localData, tmpReg); - } else if (val instanceof GetMemberActionItem) { - GetMemberActionItem mem = (GetMemberActionItem) val; - ret.addAll(mem.toSource(localData, generator)); - ret.remove(ret.size() - 1); //ActionGetMember - ret.addAll(mem.toSource(localData, generator)); - ret.add(new ActionDecrement()); - int tmpReg = asGenerator.getTempRegister(localData); - ret.add(new ActionStoreRegister(tmpReg)); - ret.add(new ActionSetMember()); - ret.add(new ActionPush(new RegisterNumber(tmpReg))); - asGenerator.releaseTempRegister(localData, tmpReg); - } else if ((val instanceof DirectValueActionItem) && ((DirectValueActionItem) val).value instanceof RegisterNumber) { - RegisterNumber rn = (RegisterNumber) ((DirectValueActionItem) val).value; - ret.add(new ActionPush(new RegisterNumber(rn.number))); - ret.add(new ActionDecrement()); - ret.add(new ActionStoreRegister(rn.number)); - } else if (val instanceof GetPropertyActionItem) { - GetPropertyActionItem gp = (GetPropertyActionItem) val; - ret.addAll(gp.toSource(localData, generator)); // old value - ret.addAll(gp.toSource(localData, generator)); - ret.remove(ret.size() - 1); - ret.addAll(gp.toSource(localData, generator)); - ret.add(new ActionDecrement()); - ret.add(new ActionSetProperty()); - } - return ret; - } - - @Override - public GraphTargetItem returnType() { - return value.returnType(); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.action.model.operations; + +import com.jpexs.decompiler.flash.SourceGeneratorLocalData; +import com.jpexs.decompiler.flash.action.model.DirectValueActionItem; +import com.jpexs.decompiler.flash.action.model.GetMemberActionItem; +import com.jpexs.decompiler.flash.action.model.GetPropertyActionItem; +import com.jpexs.decompiler.flash.action.model.GetVariableActionItem; +import com.jpexs.decompiler.flash.action.parser.script.ActionSourceGenerator; +import com.jpexs.decompiler.flash.action.parser.script.VariableActionItem; +import com.jpexs.decompiler.flash.action.swf4.ActionPush; +import com.jpexs.decompiler.flash.action.swf4.ActionSetProperty; +import com.jpexs.decompiler.flash.action.swf4.ActionSetVariable; +import com.jpexs.decompiler.flash.action.swf4.RegisterNumber; +import com.jpexs.decompiler.flash.action.swf5.ActionDecrement; +import com.jpexs.decompiler.flash.action.swf5.ActionSetMember; +import com.jpexs.decompiler.flash.action.swf5.ActionStoreRegister; +import com.jpexs.decompiler.flash.ecma.EcmaScript; +import com.jpexs.decompiler.graph.CompilationException; +import com.jpexs.decompiler.graph.GraphSourceItem; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.SourceGenerator; +import com.jpexs.decompiler.graph.model.UnaryOpItem; +import java.util.ArrayList; +import java.util.List; + +public class PreDecrementActionItem extends UnaryOpItem { + + public PreDecrementActionItem(GraphSourceItem instruction, GraphTargetItem object) { + super(instruction, PRECEDENCE_UNARY, object, "--"); + } + + @Override + public Object getResult() { + return EcmaScript.toNumber(value.getResult()) - 1; + } + + @Override + public List toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException { + ActionSourceGenerator asGenerator = (ActionSourceGenerator) generator; + List ret = new ArrayList<>(); + GraphTargetItem val = value; + if (val instanceof VariableActionItem) { + val = ((VariableActionItem) val).getBoxedValue(); + } + if (val instanceof GetVariableActionItem) { + GetVariableActionItem gv = (GetVariableActionItem) val; + ret.addAll(gv.toSource(localData, generator)); + ret.remove(ret.size() - 1); //ActionGetVariable + ret.addAll(gv.toSource(localData, generator)); + ret.add(new ActionDecrement()); + int tmpReg = asGenerator.getTempRegister(localData); + ret.add(new ActionStoreRegister(tmpReg)); + ret.add(new ActionSetVariable()); + ret.add(new ActionPush(new RegisterNumber(tmpReg))); + asGenerator.releaseTempRegister(localData, tmpReg); + } else if (val instanceof GetMemberActionItem) { + GetMemberActionItem mem = (GetMemberActionItem) val; + ret.addAll(mem.toSource(localData, generator)); + ret.remove(ret.size() - 1); //ActionGetMember + ret.addAll(mem.toSource(localData, generator)); + ret.add(new ActionDecrement()); + int tmpReg = asGenerator.getTempRegister(localData); + ret.add(new ActionStoreRegister(tmpReg)); + ret.add(new ActionSetMember()); + ret.add(new ActionPush(new RegisterNumber(tmpReg))); + asGenerator.releaseTempRegister(localData, tmpReg); + } else if ((val instanceof DirectValueActionItem) && ((DirectValueActionItem) val).value instanceof RegisterNumber) { + RegisterNumber rn = (RegisterNumber) ((DirectValueActionItem) val).value; + ret.add(new ActionPush(new RegisterNumber(rn.number))); + ret.add(new ActionDecrement()); + ret.add(new ActionStoreRegister(rn.number)); + } else if (val instanceof GetPropertyActionItem) { + GetPropertyActionItem gp = (GetPropertyActionItem) val; + ret.addAll(gp.toSource(localData, generator)); // old value + ret.addAll(gp.toSource(localData, generator)); + ret.remove(ret.size() - 1); + ret.addAll(gp.toSource(localData, generator)); + ret.add(new ActionDecrement()); + ret.add(new ActionSetProperty()); + } + return ret; + } + + @Override + public GraphTargetItem returnType() { + return value.returnType(); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/PreIncrementActionItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/PreIncrementActionItem.java index e43762deb..81d0cbc30 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/PreIncrementActionItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/PreIncrementActionItem.java @@ -1,105 +1,105 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.action.model.operations; - -import com.jpexs.decompiler.flash.SourceGeneratorLocalData; -import com.jpexs.decompiler.flash.action.model.DirectValueActionItem; -import com.jpexs.decompiler.flash.action.model.GetMemberActionItem; -import com.jpexs.decompiler.flash.action.model.GetPropertyActionItem; -import com.jpexs.decompiler.flash.action.model.GetVariableActionItem; -import com.jpexs.decompiler.flash.action.parser.script.ActionSourceGenerator; -import com.jpexs.decompiler.flash.action.parser.script.VariableActionItem; -import com.jpexs.decompiler.flash.action.swf4.ActionPush; -import com.jpexs.decompiler.flash.action.swf4.ActionSetProperty; -import com.jpexs.decompiler.flash.action.swf4.ActionSetVariable; -import com.jpexs.decompiler.flash.action.swf4.RegisterNumber; -import com.jpexs.decompiler.flash.action.swf5.ActionIncrement; -import com.jpexs.decompiler.flash.action.swf5.ActionSetMember; -import com.jpexs.decompiler.flash.action.swf5.ActionStoreRegister; -import com.jpexs.decompiler.flash.ecma.EcmaScript; -import com.jpexs.decompiler.graph.CompilationException; -import com.jpexs.decompiler.graph.GraphSourceItem; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.SourceGenerator; -import com.jpexs.decompiler.graph.model.UnaryOpItem; -import java.util.ArrayList; -import java.util.List; - -public class PreIncrementActionItem extends UnaryOpItem { - - public PreIncrementActionItem(GraphSourceItem instruction, GraphTargetItem object) { - super(instruction, PRECEDENCE_UNARY, object, "++"); - } - - @Override - public Object getResult() { - return EcmaScript.toNumber(value.getResult()) + 1; - } - - @Override - public List toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException { - ActionSourceGenerator asGenerator = (ActionSourceGenerator) generator; - List ret = new ArrayList<>(); - GraphTargetItem val = value; - if (val instanceof VariableActionItem) { - val = ((VariableActionItem) val).getBoxedValue(); - } - if (val instanceof GetVariableActionItem) { - GetVariableActionItem gv = (GetVariableActionItem) val; - ret.addAll(gv.toSource(localData, generator)); - ret.remove(ret.size() - 1); //ActionGetVariable - ret.addAll(gv.toSource(localData, generator)); - ret.add(new ActionIncrement()); - int tmpReg = asGenerator.getTempRegister(localData); - - ret.add(new ActionStoreRegister(tmpReg)); - ret.add(new ActionSetVariable()); - ret.add(new ActionPush(new RegisterNumber(tmpReg))); - asGenerator.releaseTempRegister(localData, tmpReg); - } else if (val instanceof GetMemberActionItem) { - GetMemberActionItem mem = (GetMemberActionItem) val; - ret.addAll(mem.toSource(localData, generator)); - ret.remove(ret.size() - 1); //ActionGetMember - ret.addAll(mem.toSource(localData, generator)); - ret.add(new ActionIncrement()); - int tmpReg = asGenerator.getTempRegister(localData); - ret.add(new ActionStoreRegister(tmpReg)); - ret.add(new ActionSetMember()); - ret.add(new ActionPush(new RegisterNumber(tmpReg))); - asGenerator.releaseTempRegister(localData, tmpReg); - } else if ((val instanceof DirectValueActionItem) && ((DirectValueActionItem) val).value instanceof RegisterNumber) { - RegisterNumber rn = (RegisterNumber) ((DirectValueActionItem) val).value; - ret.add(new ActionPush(new RegisterNumber(rn.number))); - ret.add(new ActionIncrement()); - ret.add(new ActionStoreRegister(rn.number)); - } else if (val instanceof GetPropertyActionItem) { - GetPropertyActionItem gp = (GetPropertyActionItem) val; - ret.addAll(gp.toSource(localData, generator)); // old value - ret.addAll(gp.toSource(localData, generator)); - ret.remove(ret.size() - 1); - ret.addAll(gp.toSource(localData, generator)); - ret.add(new ActionIncrement()); - ret.add(new ActionSetProperty()); - } - return ret; - } - - @Override - public GraphTargetItem returnType() { - return value.returnType(); - } -} +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.action.model.operations; + +import com.jpexs.decompiler.flash.SourceGeneratorLocalData; +import com.jpexs.decompiler.flash.action.model.DirectValueActionItem; +import com.jpexs.decompiler.flash.action.model.GetMemberActionItem; +import com.jpexs.decompiler.flash.action.model.GetPropertyActionItem; +import com.jpexs.decompiler.flash.action.model.GetVariableActionItem; +import com.jpexs.decompiler.flash.action.parser.script.ActionSourceGenerator; +import com.jpexs.decompiler.flash.action.parser.script.VariableActionItem; +import com.jpexs.decompiler.flash.action.swf4.ActionPush; +import com.jpexs.decompiler.flash.action.swf4.ActionSetProperty; +import com.jpexs.decompiler.flash.action.swf4.ActionSetVariable; +import com.jpexs.decompiler.flash.action.swf4.RegisterNumber; +import com.jpexs.decompiler.flash.action.swf5.ActionIncrement; +import com.jpexs.decompiler.flash.action.swf5.ActionSetMember; +import com.jpexs.decompiler.flash.action.swf5.ActionStoreRegister; +import com.jpexs.decompiler.flash.ecma.EcmaScript; +import com.jpexs.decompiler.graph.CompilationException; +import com.jpexs.decompiler.graph.GraphSourceItem; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.SourceGenerator; +import com.jpexs.decompiler.graph.model.UnaryOpItem; +import java.util.ArrayList; +import java.util.List; + +public class PreIncrementActionItem extends UnaryOpItem { + + public PreIncrementActionItem(GraphSourceItem instruction, GraphTargetItem object) { + super(instruction, PRECEDENCE_UNARY, object, "++"); + } + + @Override + public Object getResult() { + return EcmaScript.toNumber(value.getResult()) + 1; + } + + @Override + public List toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException { + ActionSourceGenerator asGenerator = (ActionSourceGenerator) generator; + List ret = new ArrayList<>(); + GraphTargetItem val = value; + if (val instanceof VariableActionItem) { + val = ((VariableActionItem) val).getBoxedValue(); + } + if (val instanceof GetVariableActionItem) { + GetVariableActionItem gv = (GetVariableActionItem) val; + ret.addAll(gv.toSource(localData, generator)); + ret.remove(ret.size() - 1); //ActionGetVariable + ret.addAll(gv.toSource(localData, generator)); + ret.add(new ActionIncrement()); + int tmpReg = asGenerator.getTempRegister(localData); + + ret.add(new ActionStoreRegister(tmpReg)); + ret.add(new ActionSetVariable()); + ret.add(new ActionPush(new RegisterNumber(tmpReg))); + asGenerator.releaseTempRegister(localData, tmpReg); + } else if (val instanceof GetMemberActionItem) { + GetMemberActionItem mem = (GetMemberActionItem) val; + ret.addAll(mem.toSource(localData, generator)); + ret.remove(ret.size() - 1); //ActionGetMember + ret.addAll(mem.toSource(localData, generator)); + ret.add(new ActionIncrement()); + int tmpReg = asGenerator.getTempRegister(localData); + ret.add(new ActionStoreRegister(tmpReg)); + ret.add(new ActionSetMember()); + ret.add(new ActionPush(new RegisterNumber(tmpReg))); + asGenerator.releaseTempRegister(localData, tmpReg); + } else if ((val instanceof DirectValueActionItem) && ((DirectValueActionItem) val).value instanceof RegisterNumber) { + RegisterNumber rn = (RegisterNumber) ((DirectValueActionItem) val).value; + ret.add(new ActionPush(new RegisterNumber(rn.number))); + ret.add(new ActionIncrement()); + ret.add(new ActionStoreRegister(rn.number)); + } else if (val instanceof GetPropertyActionItem) { + GetPropertyActionItem gp = (GetPropertyActionItem) val; + ret.addAll(gp.toSource(localData, generator)); // old value + ret.addAll(gp.toSource(localData, generator)); + ret.remove(ret.size() - 1); + ret.addAll(gp.toSource(localData, generator)); + ret.add(new ActionIncrement()); + ret.add(new ActionSetProperty()); + } + return ret; + } + + @Override + public GraphTargetItem returnType() { + return value.returnType(); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/pcode/ASMParser.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/pcode/ASMParser.java index 2c1485919..c0cd69e43 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/pcode/ASMParser.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/pcode/ASMParser.java @@ -1,553 +1,553 @@ -/* - * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.action.parser.pcode; - -import com.jpexs.decompiler.flash.action.Action; -import com.jpexs.decompiler.flash.action.ActionList; -import com.jpexs.decompiler.flash.action.flashlite.ActionFSCommand2; -import com.jpexs.decompiler.flash.action.flashlite.ActionStrictMode; -import com.jpexs.decompiler.flash.action.parser.ActionParseException; -import com.jpexs.decompiler.flash.action.special.ActionDeobfuscateJump; -import com.jpexs.decompiler.flash.action.special.ActionDeobfuscatePop; -import com.jpexs.decompiler.flash.action.special.ActionEnd; -import com.jpexs.decompiler.flash.action.special.ActionNop; -import com.jpexs.decompiler.flash.action.swf3.ActionGetURL; -import com.jpexs.decompiler.flash.action.swf3.ActionGoToLabel; -import com.jpexs.decompiler.flash.action.swf3.ActionGotoFrame; -import com.jpexs.decompiler.flash.action.swf3.ActionNextFrame; -import com.jpexs.decompiler.flash.action.swf3.ActionPlay; -import com.jpexs.decompiler.flash.action.swf3.ActionPrevFrame; -import com.jpexs.decompiler.flash.action.swf3.ActionSetTarget; -import com.jpexs.decompiler.flash.action.swf3.ActionStop; -import com.jpexs.decompiler.flash.action.swf3.ActionStopSounds; -import com.jpexs.decompiler.flash.action.swf3.ActionToggleQuality; -import com.jpexs.decompiler.flash.action.swf3.ActionWaitForFrame; -import com.jpexs.decompiler.flash.action.swf4.ActionAdd; -import com.jpexs.decompiler.flash.action.swf4.ActionAnd; -import com.jpexs.decompiler.flash.action.swf4.ActionAsciiToChar; -import com.jpexs.decompiler.flash.action.swf4.ActionCall; -import com.jpexs.decompiler.flash.action.swf4.ActionCharToAscii; -import com.jpexs.decompiler.flash.action.swf4.ActionCloneSprite; -import com.jpexs.decompiler.flash.action.swf4.ActionDivide; -import com.jpexs.decompiler.flash.action.swf4.ActionEndDrag; -import com.jpexs.decompiler.flash.action.swf4.ActionEquals; -import com.jpexs.decompiler.flash.action.swf4.ActionGetProperty; -import com.jpexs.decompiler.flash.action.swf4.ActionGetTime; -import com.jpexs.decompiler.flash.action.swf4.ActionGetURL2; -import com.jpexs.decompiler.flash.action.swf4.ActionGetVariable; -import com.jpexs.decompiler.flash.action.swf4.ActionGotoFrame2; -import com.jpexs.decompiler.flash.action.swf4.ActionIf; -import com.jpexs.decompiler.flash.action.swf4.ActionJump; -import com.jpexs.decompiler.flash.action.swf4.ActionLess; -import com.jpexs.decompiler.flash.action.swf4.ActionMBAsciiToChar; -import com.jpexs.decompiler.flash.action.swf4.ActionMBCharToAscii; -import com.jpexs.decompiler.flash.action.swf4.ActionMBStringExtract; -import com.jpexs.decompiler.flash.action.swf4.ActionMBStringLength; -import com.jpexs.decompiler.flash.action.swf4.ActionMultiply; -import com.jpexs.decompiler.flash.action.swf4.ActionNot; -import com.jpexs.decompiler.flash.action.swf4.ActionOr; -import com.jpexs.decompiler.flash.action.swf4.ActionPop; -import com.jpexs.decompiler.flash.action.swf4.ActionPush; -import com.jpexs.decompiler.flash.action.swf4.ActionRandomNumber; -import com.jpexs.decompiler.flash.action.swf4.ActionRemoveSprite; -import com.jpexs.decompiler.flash.action.swf4.ActionSetProperty; -import com.jpexs.decompiler.flash.action.swf4.ActionSetTarget2; -import com.jpexs.decompiler.flash.action.swf4.ActionSetVariable; -import com.jpexs.decompiler.flash.action.swf4.ActionStartDrag; -import com.jpexs.decompiler.flash.action.swf4.ActionStringAdd; -import com.jpexs.decompiler.flash.action.swf4.ActionStringEquals; -import com.jpexs.decompiler.flash.action.swf4.ActionStringExtract; -import com.jpexs.decompiler.flash.action.swf4.ActionStringLength; -import com.jpexs.decompiler.flash.action.swf4.ActionStringLess; -import com.jpexs.decompiler.flash.action.swf4.ActionSubtract; -import com.jpexs.decompiler.flash.action.swf4.ActionToInteger; -import com.jpexs.decompiler.flash.action.swf4.ActionTrace; -import com.jpexs.decompiler.flash.action.swf4.ActionWaitForFrame2; -import com.jpexs.decompiler.flash.action.swf5.ActionAdd2; -import com.jpexs.decompiler.flash.action.swf5.ActionBitAnd; -import com.jpexs.decompiler.flash.action.swf5.ActionBitLShift; -import com.jpexs.decompiler.flash.action.swf5.ActionBitOr; -import com.jpexs.decompiler.flash.action.swf5.ActionBitRShift; -import com.jpexs.decompiler.flash.action.swf5.ActionBitURShift; -import com.jpexs.decompiler.flash.action.swf5.ActionBitXor; -import com.jpexs.decompiler.flash.action.swf5.ActionCallFunction; -import com.jpexs.decompiler.flash.action.swf5.ActionCallMethod; -import com.jpexs.decompiler.flash.action.swf5.ActionConstantPool; -import com.jpexs.decompiler.flash.action.swf5.ActionDecrement; -import com.jpexs.decompiler.flash.action.swf5.ActionDefineFunction; -import com.jpexs.decompiler.flash.action.swf5.ActionDefineLocal; -import com.jpexs.decompiler.flash.action.swf5.ActionDefineLocal2; -import com.jpexs.decompiler.flash.action.swf5.ActionDelete; -import com.jpexs.decompiler.flash.action.swf5.ActionDelete2; -import com.jpexs.decompiler.flash.action.swf5.ActionEnumerate; -import com.jpexs.decompiler.flash.action.swf5.ActionEquals2; -import com.jpexs.decompiler.flash.action.swf5.ActionGetMember; -import com.jpexs.decompiler.flash.action.swf5.ActionIncrement; -import com.jpexs.decompiler.flash.action.swf5.ActionInitArray; -import com.jpexs.decompiler.flash.action.swf5.ActionInitObject; -import com.jpexs.decompiler.flash.action.swf5.ActionLess2; -import com.jpexs.decompiler.flash.action.swf5.ActionModulo; -import com.jpexs.decompiler.flash.action.swf5.ActionNewMethod; -import com.jpexs.decompiler.flash.action.swf5.ActionNewObject; -import com.jpexs.decompiler.flash.action.swf5.ActionPushDuplicate; -import com.jpexs.decompiler.flash.action.swf5.ActionReturn; -import com.jpexs.decompiler.flash.action.swf5.ActionSetMember; -import com.jpexs.decompiler.flash.action.swf5.ActionStackSwap; -import com.jpexs.decompiler.flash.action.swf5.ActionStoreRegister; -import com.jpexs.decompiler.flash.action.swf5.ActionTargetPath; -import com.jpexs.decompiler.flash.action.swf5.ActionToNumber; -import com.jpexs.decompiler.flash.action.swf5.ActionToString; -import com.jpexs.decompiler.flash.action.swf5.ActionTypeOf; -import com.jpexs.decompiler.flash.action.swf5.ActionWith; -import com.jpexs.decompiler.flash.action.swf6.ActionEnumerate2; -import com.jpexs.decompiler.flash.action.swf6.ActionGreater; -import com.jpexs.decompiler.flash.action.swf6.ActionInstanceOf; -import com.jpexs.decompiler.flash.action.swf6.ActionStrictEquals; -import com.jpexs.decompiler.flash.action.swf6.ActionStringGreater; -import com.jpexs.decompiler.flash.action.swf7.ActionCastOp; -import com.jpexs.decompiler.flash.action.swf7.ActionDefineFunction2; -import com.jpexs.decompiler.flash.action.swf7.ActionExtends; -import com.jpexs.decompiler.flash.action.swf7.ActionImplementsOp; -import com.jpexs.decompiler.flash.action.swf7.ActionThrow; -import com.jpexs.decompiler.flash.action.swf7.ActionTry; -import com.jpexs.decompiler.graph.GraphSourceItemContainer; -import com.jpexs.helpers.Helper; -import java.io.IOException; -import java.io.StringReader; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Stack; -import java.util.logging.Level; -import java.util.logging.Logger; - -public class ASMParser { - - public static ActionList parse(boolean ignoreNops, List