mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-09-25 14:10:46 +00:00
Project renamed to Free Flash Decompiler.
Code moved to new dir. Version changed to 1.3
This commit is contained in:
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash;
|
||||
|
||||
import com.jpexs.proxy.Replacement;
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
import javax.swing.JOptionPane;
|
||||
|
||||
public class Configuration {
|
||||
|
||||
private static final String CONFIG_NAME = "asdec.cfg";
|
||||
private static final String REPLACEMENTS_NAME = "replacements.ini";
|
||||
private static HashMap<String, Object> config = new HashMap<String, Object>();
|
||||
|
||||
public static String getASDecHome() {
|
||||
String dir = ".";//System.getProperty("user.home");
|
||||
if (!dir.endsWith(File.separator)) {
|
||||
dir += File.separator;
|
||||
}
|
||||
dir += "config" + File.separator;
|
||||
return dir;
|
||||
}
|
||||
|
||||
private static String getReplacementsFile() {
|
||||
return getASDecHome() + REPLACEMENTS_NAME;
|
||||
}
|
||||
|
||||
private static String getConfigFile() {
|
||||
return getASDecHome() + CONFIG_NAME;
|
||||
}
|
||||
/**
|
||||
* List of replacements
|
||||
*/
|
||||
public static java.util.List<Replacement> replacements = new ArrayList<Replacement>();
|
||||
|
||||
/**
|
||||
* Saves replacements to file for future use
|
||||
*/
|
||||
private static void saveReplacements() {
|
||||
try {
|
||||
if (replacements.isEmpty()) {
|
||||
File rf = new File(getReplacementsFile());
|
||||
if (rf.exists()) {
|
||||
rf.delete();
|
||||
}
|
||||
} else {
|
||||
File f = new File(getASDecHome());
|
||||
if (!f.exists()) {
|
||||
f.mkdir();
|
||||
}
|
||||
PrintWriter pw = new PrintWriter(new FileWriter(getReplacementsFile()));
|
||||
for (Replacement r : replacements) {
|
||||
pw.println(r.urlPattern);
|
||||
pw.println(r.targetFile);
|
||||
}
|
||||
pw.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load replacements from file
|
||||
*/
|
||||
private static void loadReplacements() {
|
||||
replacements = new ArrayList<Replacement>();
|
||||
try {
|
||||
BufferedReader br = new BufferedReader(new FileReader(getReplacementsFile()));
|
||||
String s;
|
||||
while ((s = br.readLine()) != null) {
|
||||
Replacement r = new Replacement(s, br.readLine());
|
||||
replacements.add(r);
|
||||
}
|
||||
br.close();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
|
||||
public static Object getConfig(String cfg) {
|
||||
return getConfig(cfg, null);
|
||||
}
|
||||
|
||||
public static Object getConfig(String cfg, Object defaultValue) {
|
||||
if (!config.containsKey(cfg)) {
|
||||
return defaultValue;
|
||||
}
|
||||
return config.get(cfg);
|
||||
}
|
||||
|
||||
public static Object setConfig(String cfg, Object value) {
|
||||
return config.put(cfg, value);
|
||||
}
|
||||
|
||||
public static void load() {
|
||||
ObjectInputStream ois = null;
|
||||
try {
|
||||
ois = new ObjectInputStream(new FileInputStream(getConfigFile()));
|
||||
config = (HashMap<String, Object>) ois.readObject();
|
||||
} catch (FileNotFoundException ex) {
|
||||
} catch (ClassNotFoundException cnf) {
|
||||
} catch (IOException ex) {
|
||||
} finally {
|
||||
if (ois != null) {
|
||||
try {
|
||||
ois.close();
|
||||
} catch (IOException ex1) {
|
||||
//ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
loadReplacements();
|
||||
}
|
||||
|
||||
public static void save() {
|
||||
File f = new File(getASDecHome());
|
||||
if (!f.exists()) {
|
||||
f.mkdir();
|
||||
}
|
||||
ObjectOutputStream oos = null;
|
||||
try {
|
||||
oos = new ObjectOutputStream(new FileOutputStream(getConfigFile()));
|
||||
oos.writeObject(config);
|
||||
} catch (IOException ex) {
|
||||
JOptionPane.showMessageDialog(null, "Cannot save configuration.\nPlease make application directory writable.", "Error", JOptionPane.ERROR_MESSAGE);
|
||||
Logger.getLogger(SWFInputStream.class.getName()).severe("Configuration directory is read only.");
|
||||
} finally {
|
||||
if (oos != null) {
|
||||
try {
|
||||
oos.close();
|
||||
} catch (IOException ex1) {
|
||||
//ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
saveReplacements();
|
||||
}
|
||||
|
||||
public static List<Replacement> getReplacements() {
|
||||
return replacements;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public interface EventListener {
|
||||
|
||||
public void handleEvent(String event, Object data);
|
||||
}
|
||||
@@ -0,0 +1,830 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodBody;
|
||||
import com.jpexs.decompiler.flash.gui.AboutDialog;
|
||||
import com.jpexs.decompiler.flash.gui.LoadingDialog;
|
||||
import com.jpexs.decompiler.flash.gui.MainFrame;
|
||||
import com.jpexs.decompiler.flash.gui.ModeFrame;
|
||||
import com.jpexs.decompiler.flash.gui.View;
|
||||
import com.jpexs.decompiler.flash.gui.proxy.ProxyFrame;
|
||||
import com.jpexs.decompiler.flash.helpers.Highlighting;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.io.*;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.net.Socket;
|
||||
import java.util.Calendar;
|
||||
import java.util.logging.ConsoleHandler;
|
||||
import java.util.logging.FileHandler;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.logging.SimpleFormatter;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.SwingWorker;
|
||||
import javax.swing.filechooser.FileFilter;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
/**
|
||||
* Main executable class
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class Main {
|
||||
|
||||
public static ProxyFrame proxyFrame;
|
||||
public static String file;
|
||||
public static String maskURL;
|
||||
public static SWF swf;
|
||||
public static final String version = "1.3";
|
||||
public static final String applicationName = "JPEXS Free Flash Decompiler v." + version;
|
||||
public static final String shortApplicationName = "FFDec";
|
||||
public static final String shortApplicationVerName = shortApplicationName + " v." + version;
|
||||
public static final String projectPage = "http://www.free-decompiler.com/flash";
|
||||
public static LoadingDialog loadingDialog;
|
||||
public static ModeFrame modeFrame;
|
||||
private static boolean working = false;
|
||||
private static TrayIcon trayIcon;
|
||||
private static MenuItem stopMenuItem;
|
||||
private static boolean commandLineMode = false;
|
||||
public static MainFrame mainFrame;
|
||||
|
||||
public static boolean isCommandLineMode() {
|
||||
return commandLineMode;
|
||||
}
|
||||
public static boolean DEBUG_COPY = false;
|
||||
/**
|
||||
* Debug mode = throwing an error when comparing original file and recompiled
|
||||
*/
|
||||
public static boolean debugMode = false;
|
||||
/**
|
||||
* Turn off reading unsafe tags (tags which can cause problems with
|
||||
* recompiling)
|
||||
*/
|
||||
public static boolean DISABLE_DANGEROUS = false;
|
||||
/**
|
||||
* Turn off resolving constants in ActionScript 2
|
||||
*/
|
||||
public static final boolean RESOLVE_CONSTANTS = true;
|
||||
/**
|
||||
* Turn off decompiling if needed
|
||||
*/
|
||||
public static final boolean DO_DECOMPILE = true;
|
||||
/**
|
||||
* Find latest constant pool in the code
|
||||
*/
|
||||
public static final boolean LATEST_CONSTANTPOOL_HACK = false;
|
||||
/**
|
||||
* Dump tags to stdout
|
||||
*/
|
||||
public static boolean dump_tags = false;
|
||||
/**
|
||||
* Limit of code subs (for obfuscated code)
|
||||
*/
|
||||
public static final int SUBLIMITER = 500;
|
||||
//using parameter names in decompiling may cause problems because oficial programs like Flash CS 5.5 inserts wrong parameter names indices
|
||||
public static final boolean PARAM_NAMES_ENABLE = false;
|
||||
|
||||
public static String getFileTitle() {
|
||||
if (maskURL != null) {
|
||||
return maskURL;
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
public static void setSubLimiter(boolean value) {
|
||||
if (value) {
|
||||
AVM2Code.toSourceLimit = Main.SUBLIMITER;
|
||||
} else {
|
||||
AVM2Code.toSourceLimit = -1;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isWorking() {
|
||||
return working;
|
||||
}
|
||||
|
||||
public static void showProxy() {
|
||||
if (proxyFrame == null) {
|
||||
proxyFrame = new ProxyFrame();
|
||||
}
|
||||
proxyFrame.setVisible(true);
|
||||
proxyFrame.setState(Frame.NORMAL);
|
||||
}
|
||||
|
||||
public static void startWork(String name) {
|
||||
startWork(name, -1);
|
||||
}
|
||||
|
||||
public static void startWork(String name, int percent) {
|
||||
working = true;
|
||||
if (mainFrame != null) {
|
||||
mainFrame.setWorkStatus(name);
|
||||
if (percent == -1) {
|
||||
mainFrame.hidePercent();
|
||||
} else {
|
||||
mainFrame.setPercent(percent);
|
||||
}
|
||||
}
|
||||
if (loadingDialog != null) {
|
||||
loadingDialog.setDetail(name);
|
||||
if (percent == -1) {
|
||||
loadingDialog.hidePercent();
|
||||
} else {
|
||||
loadingDialog.setPercent(percent);
|
||||
}
|
||||
}
|
||||
if (Main.isCommandLineMode()) {
|
||||
System.out.println(name);
|
||||
}
|
||||
}
|
||||
|
||||
public static void stopWork() {
|
||||
working = false;
|
||||
if (mainFrame != null) {
|
||||
mainFrame.setWorkStatus("");
|
||||
}
|
||||
if (loadingDialog != null) {
|
||||
loadingDialog.setDetail("");
|
||||
}
|
||||
}
|
||||
|
||||
public static SWF parseSWF(String file) throws Exception {
|
||||
FileInputStream fis = new FileInputStream(file);
|
||||
InputStream bis = new BufferedInputStream(fis);
|
||||
SWF locswf = new SWF(bis, new PercentListener() {
|
||||
@Override
|
||||
public void percent(int p) {
|
||||
startWork("Reading SWF", p);
|
||||
}
|
||||
});
|
||||
locswf.addEventListener(new EventListener() {
|
||||
public void handleEvent(String event, Object data) {
|
||||
if (event.equals("export")) {
|
||||
startWork((String) data);
|
||||
}
|
||||
}
|
||||
});
|
||||
return locswf;
|
||||
}
|
||||
|
||||
public static void saveFile(String outfile) throws IOException {
|
||||
file = outfile;
|
||||
swf.saveTo(new FileOutputStream(outfile));
|
||||
}
|
||||
|
||||
private static class OpenFileWorker extends SwingWorker {
|
||||
|
||||
@Override
|
||||
protected Object doInBackground() throws Exception {
|
||||
try {
|
||||
Main.startWork("Reading SWF...");
|
||||
swf = parseSWF(Main.file);
|
||||
FileInputStream fis = new FileInputStream(file);
|
||||
DEBUG_COPY = true;
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
/*try {
|
||||
swf.saveTo(baos);
|
||||
} catch (NotSameException nse) {
|
||||
Logger.getLogger(Main.class.getName()).log(Level.FINE, null, nse);
|
||||
JOptionPane.showMessageDialog(null, "WARNING: The SWF decompiler may have problems saving this file. Recommended usage is READ ONLY.");
|
||||
}*/
|
||||
DEBUG_COPY = false;
|
||||
//DEBUG_COPY=true;
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
|
||||
JOptionPane.showMessageDialog(null, "Cannot load SWF file.");
|
||||
loadingDialog.setVisible(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
mainFrame = new MainFrame(swf);
|
||||
loadingDialog.setVisible(false);
|
||||
mainFrame.setVisible(true);
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean openFile(String swfFile) {
|
||||
if (mainFrame != null) {
|
||||
mainFrame.setVisible(false);
|
||||
}
|
||||
Main.file = swfFile;
|
||||
if (Main.loadingDialog == null) {
|
||||
Main.loadingDialog = new LoadingDialog();
|
||||
}
|
||||
Main.loadingDialog.setVisible(true);
|
||||
(new OpenFileWorker()).execute();
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean saveFileDialog() {
|
||||
JFileChooser fc = new JFileChooser();
|
||||
fc.setCurrentDirectory(new File((String) Configuration.getConfig("lastSaveDir", ".")));
|
||||
JFrame f = new JFrame();
|
||||
View.setWindowIcon(f);
|
||||
int returnVal = fc.showSaveDialog(f);
|
||||
if (returnVal == JFileChooser.APPROVE_OPTION) {
|
||||
File file = fc.getSelectedFile();
|
||||
try {
|
||||
Main.saveFile(file.getAbsolutePath());
|
||||
Configuration.setConfig("lastSaveDir", file.getParentFile().getAbsolutePath());
|
||||
maskURL = null;
|
||||
return true;
|
||||
} catch (IOException ex) {
|
||||
JOptionPane.showMessageDialog(null, "Cannot write to the file");
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean openFileDialog() {
|
||||
maskURL = null;
|
||||
JFileChooser fc = new JFileChooser();
|
||||
fc.setCurrentDirectory(new File((String) Configuration.getConfig("lastOpenDir", ".")));
|
||||
fc.setFileFilter(new FileFilter() {
|
||||
@Override
|
||||
public boolean accept(File f) {
|
||||
return (f.getName().endsWith(".swf")) || (f.isDirectory());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "SWF files (*.swf)";
|
||||
}
|
||||
});
|
||||
JFrame f = new JFrame();
|
||||
View.setWindowIcon(f);
|
||||
int returnVal = fc.showOpenDialog(f);
|
||||
if (returnVal == JFileChooser.APPROVE_OPTION) {
|
||||
Configuration.setConfig("lastOpenDir", fc.getSelectedFile().getParentFile().getAbsolutePath());
|
||||
File selfile = fc.getSelectedFile();
|
||||
Main.openFile(selfile.getAbsolutePath());
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static void showModeFrame() {
|
||||
if (modeFrame == null) {
|
||||
modeFrame = new ModeFrame();
|
||||
}
|
||||
modeFrame.setVisible(true);
|
||||
}
|
||||
|
||||
public static void updateLicense() {
|
||||
updateLicenseInDir(new File(".\\src\\"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Script for updating license header in java files :-)
|
||||
*
|
||||
* @param dir Star directory (e.g. "src/")
|
||||
*/
|
||||
public static void updateLicenseInDir(File dir) {
|
||||
int defaultStartYear = 2010;
|
||||
int defaultFinalYear = 2013;
|
||||
String defaultAuthor = "JPEXS";
|
||||
String defaultYearStr = "" + defaultStartYear;
|
||||
if (defaultFinalYear != defaultStartYear) {
|
||||
defaultYearStr += "-" + defaultFinalYear;
|
||||
}
|
||||
String license = "/*\r\n * Copyright (C) {year} {author}\r\n * \r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU General Public License as published by\r\n * the Free Software Foundation, either version 3 of the License, or\r\n * (at your option) any later version.\r\n * \r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU General Public License for more details.\r\n * \r\n * You should have received a copy of the GNU General Public License\r\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\r\n */";
|
||||
|
||||
File files[] = dir.listFiles();
|
||||
for (File f : files) {
|
||||
if (f.isDirectory()) {
|
||||
updateLicenseInDir(f);
|
||||
} else {
|
||||
if (f.getName().endsWith(".java")) {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
PrintWriter pw = null;
|
||||
try {
|
||||
pw = new PrintWriter(new OutputStreamWriter(baos, "utf8"));
|
||||
} catch (UnsupportedEncodingException ex) {
|
||||
}
|
||||
try {
|
||||
BufferedReader br = new BufferedReader(new FileReader(f));
|
||||
String s;
|
||||
boolean packageFound = false;
|
||||
String author = defaultAuthor;
|
||||
String yearStr = defaultYearStr;
|
||||
while ((s = br.readLine()) != null) {
|
||||
if (!packageFound) {
|
||||
if (s.trim().startsWith("package")) {
|
||||
packageFound = true;
|
||||
pw.println(license.replace("{year}", yearStr).replace("{author}", author));
|
||||
} else {
|
||||
Matcher mAuthor = Pattern.compile("^.*Copyright \\(C\\) ([0-9]+)(-[0-9]+)? (.*)$").matcher(s);
|
||||
if (mAuthor.matches()) {
|
||||
author = mAuthor.group(3).trim();
|
||||
int startYear = Integer.parseInt(mAuthor.group(1).trim());
|
||||
if (startYear == defaultFinalYear) {
|
||||
yearStr = "" + startYear;
|
||||
} else {
|
||||
yearStr = "" + startYear + "-" + defaultFinalYear;
|
||||
}
|
||||
if (!author.equals(defaultAuthor)) {
|
||||
System.out.println("Detected nodefault author:" + author + " in " + f.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (packageFound) {
|
||||
pw.println(s);
|
||||
}
|
||||
}
|
||||
br.close();
|
||||
pw.close();
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
|
||||
FileOutputStream fos;
|
||||
try {
|
||||
fos = new FileOutputStream(f);
|
||||
fos.write(baos.toByteArray());
|
||||
fos.close();
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void badArguments() {
|
||||
System.err.println("Error: Bad Commandline Arguments!");
|
||||
printCmdLineUsage();
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
public static void printHeader() {
|
||||
System.out.println(applicationName);
|
||||
for (int i = 0; i < applicationName.length(); i++) {
|
||||
System.out.print("-");
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
public static void printCmdLineUsage() {
|
||||
System.out.println("Commandline arguments:");
|
||||
System.out.println(" 1) -help | --help | /?");
|
||||
System.out.println(" ...shows commandline arguments (this help)");
|
||||
System.out.println(" 2) infile");
|
||||
System.out.println(" ...opens SWF file with the decompiler GUI");
|
||||
System.out.println(" 3) -proxy (-PXXX)");
|
||||
System.out.println(" ...auto start proxy in the tray. Optional parameter -P specifies port for proxy. Defaults to 55555. ");
|
||||
System.out.println(" 4) -export (as|pcode|image) outdirectory infile");
|
||||
System.out.println(" ...export infile sources to outdirectory as AsctionScript code (\"as\" argument) or as PCode (\"pcode\" argument) or images");
|
||||
System.out.println(" 5) -dumpSWF infile");
|
||||
System.out.println(" ...dumps list of SWF tags to console");
|
||||
System.out.println(" 6) -compress infile outfile");
|
||||
System.out.println(" ...Compress SWF infile and save it to outfile");
|
||||
System.out.println(" 7) -decompress infile outfile");
|
||||
System.out.println(" ...Decompress infile and save it to outfile");
|
||||
System.out.println();
|
||||
System.out.println("Examples:");
|
||||
System.out.println("java -jar FFDec.jar myfile.swf");
|
||||
System.out.println("java -jar FFDec.jar -proxy");
|
||||
System.out.println("java -jar FFDec.jar -proxy -P1234");
|
||||
System.out.println("java -jar FFDec.jar -export as \"C:\\decompiled\\\" myfile.swf");
|
||||
System.out.println("java -jar FFDec.jar -export pcode \"C:\\decompiled\\\" myfile.swf");
|
||||
System.out.println("java -jar FFDec.jar -dumpSWF myfile.swf");
|
||||
System.out.println("java -jar FFDec.jar -compress myfile.swf myfiledec.swf");
|
||||
System.out.println("java -jar FFDec.jar -decompress myfiledec.swf myfile.swf");
|
||||
}
|
||||
|
||||
private static void copyFile(String from, String to) throws IOException {
|
||||
FileInputStream fis = new FileInputStream(from);
|
||||
FileOutputStream fos = new FileOutputStream(to);
|
||||
byte buf[] = new byte[4096];
|
||||
int cnt = 0;
|
||||
while ((cnt = fis.read(buf)) > 0) {
|
||||
fos.write(buf, 0, cnt);
|
||||
}
|
||||
fis.close();
|
||||
fos.close();
|
||||
}
|
||||
|
||||
public static void restartApplication(String[] args) {
|
||||
StringBuilder cmd = new StringBuilder();
|
||||
cmd.append(System.getProperty("java.home") + File.separator + "bin" + File.separator + "java ");
|
||||
for (String jvmArg : ManagementFactory.getRuntimeMXBean().getInputArguments()) {
|
||||
cmd.append(jvmArg + " ");
|
||||
}
|
||||
cmd.append("-cp ").append(ManagementFactory.getRuntimeMXBean().getClassPath()).append(" ");
|
||||
cmd.append(Main.class.getName()).append(" ");
|
||||
for (String arg : args) {
|
||||
cmd.append(arg).append(" ");
|
||||
}
|
||||
|
||||
try {
|
||||
Runtime.getRuntime().exec(cmd.toString());
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
public static void checkSWT(String[] args) {
|
||||
if (System.getProperty("os.name").toLowerCase().indexOf("win") == -1) {
|
||||
return;
|
||||
}
|
||||
String lastBits = (String) Configuration.getConfig("bits", "-");
|
||||
if ((!System.getProperty("sun.arch.data.model").equals(lastBits)) || (!(new File("lib/swt.jar")).exists())) {
|
||||
try {
|
||||
if (System.getProperty("sun.arch.data.model").equals("32")) {
|
||||
copyFile("lib/swt32.jar", "lib/swt.jar");
|
||||
} else if (System.getProperty("sun.arch.data.model").equals("64")) {
|
||||
copyFile("lib/swt64.jar", "lib/swt.jar");
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
JOptionPane.showMessageDialog(null, "Cannot copy SWT library.\nPlease make application directory writeable.\n(Placing outside of Program files may help)", "Error", JOptionPane.ERROR_MESSAGE);
|
||||
Logger.getLogger(SWFInputStream.class.getName()).severe("Cannot copy SWT library");
|
||||
System.exit(1);
|
||||
}
|
||||
Configuration.setConfig("bits", System.getProperty("sun.arch.data.model"));
|
||||
Configuration.save();
|
||||
restartApplication(args);
|
||||
}
|
||||
}
|
||||
|
||||
public static final void printASM(AVM2Code code) {
|
||||
String s = Highlighting.stripHilights(code.toASMSource(null, new MethodBody()));
|
||||
String ss[] = s.split("\n");
|
||||
for (int i = 0; i < ss.length; i++) {
|
||||
System.out.println("" + i + ":" + ss[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param args the command line arguments
|
||||
*/
|
||||
public static void main(String[] args) throws IOException {
|
||||
View.setLookAndFeel();
|
||||
Configuration.load();
|
||||
checkSWT(args);
|
||||
|
||||
int pos = 0;
|
||||
if (args.length > 0) {
|
||||
if (args[0].equals("-debug")) {
|
||||
debugMode = true;
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
initLogging(debugMode);
|
||||
if (args.length < pos + 1) {
|
||||
autoCheckForUpdates();
|
||||
showModeFrame();
|
||||
} else {
|
||||
if (args[pos].equals("-proxy")) {
|
||||
int port = 55555;
|
||||
for (int i = pos; i < args.length; i++) {
|
||||
if (args[i].startsWith("-P")) {
|
||||
try {
|
||||
port = Integer.parseInt(args[pos].substring(2));
|
||||
} catch (NumberFormatException nex) {
|
||||
System.err.println("Bad port number");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (proxyFrame == null) {
|
||||
proxyFrame = new ProxyFrame();
|
||||
}
|
||||
proxyFrame.setPort(port);
|
||||
addTrayIcon();
|
||||
switchProxy();
|
||||
} else if (args[pos].equals("-export")) {
|
||||
if (args.length < pos + 4) {
|
||||
badArguments();
|
||||
}
|
||||
String exportFormat = args[pos + 1];
|
||||
if (!exportFormat.toLowerCase().equals("as")) {
|
||||
if (!exportFormat.toLowerCase().equals("pcode")) {
|
||||
if (!exportFormat.toLowerCase().equals("image")) {
|
||||
System.err.println("Invalid export format:" + exportFormat);
|
||||
badArguments();
|
||||
}
|
||||
}
|
||||
}
|
||||
File outDir = new File(args[pos + 2]);
|
||||
File inFile = new File(args[pos + 3]);
|
||||
if (!inFile.exists()) {
|
||||
System.err.println("Input SWF file does not exist!");
|
||||
badArguments();
|
||||
}
|
||||
commandLineMode = true;
|
||||
boolean exportOK;
|
||||
try {
|
||||
printHeader();
|
||||
dump_tags = true;
|
||||
SWF exfile = new SWF(new FileInputStream(inFile));
|
||||
exfile.addEventListener(new EventListener() {
|
||||
public void handleEvent(String event, Object data) {
|
||||
if (event.equals("export")) {
|
||||
System.out.println((String) data);
|
||||
}
|
||||
}
|
||||
});
|
||||
if (exportFormat.equals("image")) {
|
||||
exfile.exportImages(outDir.getAbsolutePath());
|
||||
exportOK = true;
|
||||
} else if (exportFormat.equals("as") || exportFormat.equals("pcode")) {
|
||||
exportOK = exfile.exportActionScript(outDir.getAbsolutePath(), exportFormat.equals("pcode"));
|
||||
} else {
|
||||
exportOK = false;
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
exportOK = false;
|
||||
System.err.print("FAIL: Exporting Failed on Exception - ");
|
||||
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
|
||||
System.exit(1);
|
||||
}
|
||||
if (exportOK) {
|
||||
System.out.println("OK");
|
||||
System.exit(0);
|
||||
} else {
|
||||
System.err.println("FAIL");
|
||||
System.exit(1);
|
||||
}
|
||||
} else if (args[pos].equals("-compress")) {
|
||||
if (args.length < pos + 3) {
|
||||
badArguments();
|
||||
}
|
||||
|
||||
if (SWF.fws2cws(new FileInputStream(args[pos + 1]), new FileOutputStream(args[pos + 2]))) {
|
||||
System.out.println("OK");
|
||||
} else {
|
||||
System.err.println("FAIL");
|
||||
}
|
||||
} else if (args[pos].equals("-decompress")) {
|
||||
if (args.length < pos + 3) {
|
||||
badArguments();
|
||||
}
|
||||
|
||||
if (SWF.cws2fws(new FileInputStream(args[pos + 1]), new FileOutputStream(args[pos + 2]))) {
|
||||
System.out.println("OK");
|
||||
System.exit(0);
|
||||
} else {
|
||||
System.err.println("FAIL");
|
||||
System.exit(1);
|
||||
}
|
||||
} else if (args[pos].equals("-dumpSWF")) {
|
||||
if (args.length < pos + 2) {
|
||||
badArguments();
|
||||
}
|
||||
try {
|
||||
dump_tags = true;
|
||||
SWF swf = parseSWF(args[pos + 1]);
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
|
||||
System.exit(1);
|
||||
}
|
||||
System.exit(0);
|
||||
} else if (args[pos].equals("-help") || args[pos].equals("--help") || args[pos].equals("/?")) {
|
||||
printHeader();
|
||||
printCmdLineUsage();
|
||||
System.exit(0);
|
||||
} else if (args.length == pos + 1) {
|
||||
autoCheckForUpdates();
|
||||
openFile(args[pos]);
|
||||
} else {
|
||||
badArguments();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static String tempFile(String url) {
|
||||
File f = new File(Configuration.getASDecHome() + "saved" + File.separator);
|
||||
if (!f.exists()) {
|
||||
f.mkdirs();
|
||||
}
|
||||
return Configuration.getASDecHome() + "saved" + File.separator + "asdec_" + Integer.toHexString(url.hashCode()) + ".tmp";
|
||||
|
||||
}
|
||||
|
||||
public static void removeTrayIcon() {
|
||||
if (SystemTray.isSupported()) {
|
||||
SystemTray tray = SystemTray.getSystemTray();
|
||||
if (trayIcon != null) {
|
||||
tray.remove(trayIcon);
|
||||
trayIcon = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void switchProxy() {
|
||||
proxyFrame.switchState();
|
||||
if (stopMenuItem != null) {
|
||||
if (proxyFrame.isRunning()) {
|
||||
stopMenuItem.setLabel("Stop proxy");
|
||||
} else {
|
||||
stopMenuItem.setLabel("Start proxy");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void addTrayIcon() {
|
||||
if (trayIcon != null) {
|
||||
return;
|
||||
}
|
||||
if (SystemTray.isSupported()) {
|
||||
SystemTray tray = SystemTray.getSystemTray();
|
||||
trayIcon = new TrayIcon(View.loadImage("com/jpexs/decompiler/flash/gui/graphics/proxy16.png"), "JP ASDec Proxy");
|
||||
trayIcon.setImageAutoSize(true);
|
||||
PopupMenu trayPopup = new PopupMenu();
|
||||
|
||||
|
||||
ActionListener trayListener = new ActionListener() {
|
||||
/**
|
||||
* Invoked when an action occurs.
|
||||
*/
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (e.getActionCommand().equals("EXIT")) {
|
||||
Main.exit();
|
||||
}
|
||||
if (e.getActionCommand().equals("SHOW")) {
|
||||
Main.showProxy();
|
||||
}
|
||||
if (e.getActionCommand().equals("SWITCH")) {
|
||||
Main.switchProxy();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
MenuItem showMenuItem = new MenuItem("Show proxy");
|
||||
showMenuItem.setActionCommand("SHOW");
|
||||
showMenuItem.addActionListener(trayListener);
|
||||
trayPopup.add(showMenuItem);
|
||||
stopMenuItem = new MenuItem("Start proxy");
|
||||
stopMenuItem.setActionCommand("SWITCH");
|
||||
stopMenuItem.addActionListener(trayListener);
|
||||
trayPopup.add(stopMenuItem);
|
||||
trayPopup.addSeparator();
|
||||
MenuItem exitMenuItem = new MenuItem("Exit");
|
||||
exitMenuItem.setActionCommand("EXIT");
|
||||
exitMenuItem.addActionListener(trayListener);
|
||||
trayPopup.add(exitMenuItem);
|
||||
|
||||
trayIcon.setPopupMenu(trayPopup);
|
||||
trayIcon.addMouseListener(new MouseAdapter() {
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
if (e.getButton() == MouseEvent.BUTTON1) {
|
||||
Main.showProxy();
|
||||
}
|
||||
}
|
||||
});
|
||||
try {
|
||||
tray.add(trayIcon);
|
||||
} catch (AWTException ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void exit() {
|
||||
Configuration.save();
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
public static void about() {
|
||||
(new AboutDialog()).setVisible(true);
|
||||
}
|
||||
|
||||
public static void autoCheckForUpdates() {
|
||||
Calendar lastUpdatesCheckDate = (Calendar) Configuration.getConfig("lastUpdatesCheckDate", null);
|
||||
if ((lastUpdatesCheckDate == null) || (lastUpdatesCheckDate.getTime().getTime() < Calendar.getInstance().getTime().getTime() - 1000 * 60 * 60 * 24)) {
|
||||
checkForUpdates();
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean checkForUpdates() {
|
||||
try {
|
||||
Socket sock = new Socket("code.google.com", 80);
|
||||
OutputStream os = sock.getOutputStream();
|
||||
os.write("GET /feeds/p/asdec/downloads/basic HTTP/1.1\r\nHost: code.google.com\r\nConnection: close\r\n\r\n".getBytes());
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(sock.getInputStream()));
|
||||
String s;
|
||||
String response = "";
|
||||
boolean start = false;
|
||||
while ((s = br.readLine()) != null) {
|
||||
if (start) {
|
||||
response += s + "\r\n";
|
||||
}
|
||||
if (s.equals("")) {
|
||||
start = true;
|
||||
}
|
||||
}
|
||||
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
|
||||
Document doc = builder.parse(new ByteArrayInputStream(response.getBytes()));
|
||||
NodeList contents = doc.getElementsByTagName("content");
|
||||
for (int i = 0; i < contents.getLength(); i++) {
|
||||
Node nod = contents.item(i);
|
||||
String cont = nod.getTextContent().trim();
|
||||
String parts[] = cont.split("\n");
|
||||
boolean isUpdate = false;
|
||||
for (String part : parts) {
|
||||
if (part.trim().equals("Update")) {
|
||||
isUpdate = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((parts.length > 4) && (isUpdate)) {
|
||||
String downloadName = parts[1];
|
||||
String link = parts[parts.length - 2];
|
||||
if (isUpdate) {
|
||||
String downVersion = "NEW";
|
||||
if (downloadName.startsWith(shortApplicationName + " version ")) {
|
||||
downVersion = downloadName.substring((shortApplicationName + " version ").length());
|
||||
}
|
||||
if (link.startsWith("<a href=\"")) {
|
||||
link = link.substring(link.indexOf("\"") + 1);
|
||||
link = link.substring(0, link.indexOf("\""));
|
||||
if (!downVersion.equals(version)) {
|
||||
java.awt.Desktop desktop = null;
|
||||
if (java.awt.Desktop.isDesktopSupported()) {
|
||||
desktop = java.awt.Desktop.getDesktop();
|
||||
if (desktop.isSupported(java.awt.Desktop.Action.BROWSE)) {
|
||||
if (JOptionPane.showConfirmDialog(null, "New version of " + shortApplicationName + " is available: " + downloadName + ".\r\nDo you want to go to project web page to download it?", "New version", JOptionPane.YES_NO_OPTION, JOptionPane.INFORMATION_MESSAGE) == JOptionPane.YES_OPTION) {
|
||||
java.net.URI uri = new java.net.URI(projectPage);
|
||||
desktop.browse(uri);
|
||||
}
|
||||
} else {
|
||||
desktop = null;
|
||||
}
|
||||
}
|
||||
if (desktop == null) {
|
||||
JOptionPane.showMessageDialog(null, "New version of " + shortApplicationName + " is available: " + downloadName + ".\r\nPlease go to " + projectPage + " to download it.", "New version", JOptionPane.INFORMATION_MESSAGE);
|
||||
}
|
||||
|
||||
Configuration.setConfig("lastUpdatesCheckDate", Calendar.getInstance());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception ex) {
|
||||
return false;
|
||||
}
|
||||
Configuration.setConfig("lastUpdatesCheckDate", Calendar.getInstance());
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void initLogging(boolean debug) {
|
||||
try {
|
||||
Logger logger = Logger.getLogger("");
|
||||
logger.setLevel(debug ? Level.CONFIG : Level.WARNING);
|
||||
FileHandler fileTxt = new FileHandler("log.txt");
|
||||
|
||||
SimpleFormatter formatterTxt = new SimpleFormatter();
|
||||
fileTxt.setFormatter(formatterTxt);
|
||||
logger.addHandler(fileTxt);
|
||||
|
||||
if (debug) {
|
||||
ConsoleHandler conHan = new ConsoleHandler();
|
||||
conHan.setFormatter(formatterTxt);
|
||||
logger.addHandler(conHan);
|
||||
}
|
||||
|
||||
} catch (Exception ex) {
|
||||
throw new RuntimeException("Problems with creating the log files");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public interface PercentListener {
|
||||
|
||||
public void percent(int p);
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class ReReadableInputStream extends InputStream {
|
||||
|
||||
InputStream is;
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
byte[] converted;
|
||||
int pos = 0;
|
||||
int count = 0;
|
||||
|
||||
public byte[] getAllRead() {
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
public int getPos() {
|
||||
return pos;
|
||||
}
|
||||
|
||||
public ReReadableInputStream(InputStream is) {
|
||||
this.is = is;
|
||||
}
|
||||
|
||||
public void setPos(int pos) throws IOException {
|
||||
if (pos > count) {
|
||||
skip(pos - count);
|
||||
}
|
||||
this.pos = pos;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
if (pos < count) {
|
||||
if (converted == null) {
|
||||
converted = baos.toByteArray();
|
||||
}
|
||||
int ret = converted[pos] & 0xff;
|
||||
pos++;
|
||||
return ret;
|
||||
}
|
||||
int i = is.read();
|
||||
baos.write(i);
|
||||
count++;
|
||||
pos++;
|
||||
converted = null;
|
||||
return i;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int available() throws IOException {
|
||||
return (pos < count ? count - pos : 0) + is.available();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,509 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash;
|
||||
|
||||
import SevenZip.Compression.LZMA.Encoder;
|
||||
import com.jpexs.decompiler.flash.action.TagNode;
|
||||
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.DoABCTag;
|
||||
import com.jpexs.decompiler.flash.tags.JPEGTablesTag;
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.decompiler.flash.types.RECT;
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.zip.DeflaterOutputStream;
|
||||
import java.util.zip.InflaterInputStream;
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
/**
|
||||
* Class representing SWF file
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class SWF {
|
||||
|
||||
/**
|
||||
* Default version of SWF file format
|
||||
*/
|
||||
public static final int DEFAULT_VERSION = 10;
|
||||
/**
|
||||
* Tags inside of file
|
||||
*/
|
||||
public List<Tag> tags = new ArrayList<Tag>();
|
||||
/**
|
||||
* Rectangle 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;
|
||||
/**
|
||||
* Size of the file
|
||||
*/
|
||||
public long fileSize;
|
||||
/**
|
||||
* Use compression
|
||||
*/
|
||||
public boolean compressed = false;
|
||||
/**
|
||||
* Use LZMA compression
|
||||
*/
|
||||
public boolean lzma = false;
|
||||
/**
|
||||
* Compressed size of the file (LZMA)
|
||||
*/
|
||||
public long compressedSize;
|
||||
/**
|
||||
* LZMA Properties
|
||||
*/
|
||||
public byte lzmaProperties[];
|
||||
|
||||
/**
|
||||
* Gets all tags with specified id
|
||||
*
|
||||
* @param tagId Identificator of tag type
|
||||
* @return List of tags
|
||||
*/
|
||||
public List<Tag> getTagData(int tagId) {
|
||||
List<Tag> ret = new ArrayList<Tag>();
|
||||
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 {
|
||||
try {
|
||||
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);
|
||||
sos.writeUI16(0);
|
||||
sos.close();
|
||||
if (compressed && lzma) {
|
||||
os.write('Z');
|
||||
} else if (compressed) {
|
||||
os.write('C');
|
||||
} else {
|
||||
os.write('F');
|
||||
}
|
||||
os.write('W');
|
||||
os.write('S');
|
||||
os.write(version);
|
||||
byte data[] = baos.toByteArray();
|
||||
sos = new SWFOutputStream(os, version);
|
||||
sos.writeUI32(data.length + 8);
|
||||
|
||||
if (compressed) {
|
||||
if (lzma) {
|
||||
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);
|
||||
}
|
||||
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();
|
||||
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);
|
||||
os.write(lzmaProperties);
|
||||
} else {
|
||||
os = new DeflaterOutputStream(os);
|
||||
}
|
||||
}
|
||||
os.write(data);
|
||||
} finally {
|
||||
if (os != null) {
|
||||
os.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public SWF(InputStream is) throws IOException {
|
||||
this(is, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct SWF from stream
|
||||
*
|
||||
* @param is Stream to read SWF from
|
||||
* @throws IOException
|
||||
*/
|
||||
public SWF(InputStream is, PercentListener listener) throws IOException {
|
||||
byte hdr[] = new byte[3];
|
||||
is.read(hdr);
|
||||
String shdr = new String(hdr);
|
||||
if ((!shdr.equals("FWS")) && (!shdr.equals("CWS")) && (!shdr.equals("ZWS"))) {
|
||||
throw new IOException("Invalid SWF file");
|
||||
}
|
||||
version = is.read();
|
||||
SWFInputStream sis = new SWFInputStream(is, version, 4);
|
||||
fileSize = sis.readUI32();
|
||||
|
||||
if (hdr[0] == 'C') {
|
||||
sis = new SWFInputStream(new InflaterInputStream(is), version, 8);
|
||||
compressed = true;
|
||||
}
|
||||
|
||||
if (hdr[0] == 'Z') {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
long outSize = sis.readUI32();
|
||||
int propertiesSize = 5;
|
||||
lzmaProperties = new byte[propertiesSize];
|
||||
if (sis.read(lzmaProperties, 0, propertiesSize) != propertiesSize) {
|
||||
throw new IOException("LZMA:input .lzma file is too short");
|
||||
}
|
||||
SevenZip.Compression.LZMA.Decoder decoder = new SevenZip.Compression.LZMA.Decoder();
|
||||
if (!decoder.SetDecoderProperties(lzmaProperties)) {
|
||||
throw new IOException("LZMA:Incorrect stream properties");
|
||||
}
|
||||
|
||||
if (!decoder.Code(sis, baos, fileSize - 8)) {
|
||||
throw new IOException("LZMA:Error in data stream");
|
||||
}
|
||||
sis = new SWFInputStream(new ByteArrayInputStream(baos.toByteArray()), version, 8);
|
||||
compressed = true;
|
||||
lzma = true;
|
||||
}
|
||||
|
||||
|
||||
if (listener != null) {
|
||||
sis.addPercentListener(listener);
|
||||
}
|
||||
sis.setPercentMax(fileSize);
|
||||
displayRect = sis.readRECT();
|
||||
// FIXED8 (16 bit fixed point) frameRate
|
||||
int tmpFirstByetOfFrameRate = sis.readUI8();
|
||||
frameRate = sis.readUI8();
|
||||
frameCount = sis.readUI16();
|
||||
tags = sis.readTagList(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compress SWF file
|
||||
*
|
||||
* @param fis Input stream
|
||||
* @param fos Output stream
|
||||
*/
|
||||
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 (FileNotFoundException ex) {
|
||||
return false;
|
||||
} catch (IOException ex) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decompress SWF file
|
||||
*
|
||||
* @param fis Input stream
|
||||
* @param fos Output stream
|
||||
*/
|
||||
public static boolean cws2fws(InputStream fis, OutputStream fos) {
|
||||
try {
|
||||
byte swfHead[] = new byte[8];
|
||||
fis.read(swfHead);
|
||||
InflaterInputStream iis = new InflaterInputStream(fis);
|
||||
if (swfHead[0] != 'C') {
|
||||
fis.close();
|
||||
return false;
|
||||
}
|
||||
swfHead[0] = 'F';
|
||||
fos.write(swfHead);
|
||||
int i;
|
||||
while ((i = iis.read()) != -1) {
|
||||
fos.write(i);
|
||||
}
|
||||
|
||||
fis.close();
|
||||
fos.close();
|
||||
} catch (FileNotFoundException ex) {
|
||||
return false;
|
||||
} catch (IOException ex) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decompress LZMA compressed SWF file
|
||||
*
|
||||
* @param fis Input stream
|
||||
* @param fos Output stream
|
||||
*/
|
||||
public static boolean zws2fws(InputStream fis, OutputStream fos) {
|
||||
try {
|
||||
byte hdr[] = new byte[3];
|
||||
fis.read(hdr);
|
||||
String shdr = new String(hdr);
|
||||
if (!shdr.equals("ZWS")) {
|
||||
return false;
|
||||
}
|
||||
int version = fis.read();
|
||||
SWFInputStream sis = new SWFInputStream(fis, version, 4);
|
||||
long fileSize = sis.readUI32();
|
||||
|
||||
if (hdr[0] == 'Z') {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
long outSize = sis.readUI32();
|
||||
int propertiesSize = 5;
|
||||
byte lzmaProperties[] = new byte[propertiesSize];
|
||||
if (sis.read(lzmaProperties, 0, propertiesSize) != propertiesSize) {
|
||||
throw new IOException("LZMA:input .lzma file is too short");
|
||||
}
|
||||
SevenZip.Compression.LZMA.Decoder decoder = new SevenZip.Compression.LZMA.Decoder();
|
||||
if (!decoder.SetDecoderProperties(lzmaProperties)) {
|
||||
throw new IOException("LZMA:Incorrect stream properties");
|
||||
}
|
||||
|
||||
if (!decoder.Code(sis, baos, fileSize - 8)) {
|
||||
throw new IOException("LZMA:Error in data stream");
|
||||
}
|
||||
SWFOutputStream sos = new SWFOutputStream(fos, version);
|
||||
sos.write("FWS".getBytes());
|
||||
sos.write(version);
|
||||
sos.writeUI32(fileSize);
|
||||
sos.write(baos.toByteArray());
|
||||
sos.close();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} catch (FileNotFoundException ex) {
|
||||
return false;
|
||||
} catch (IOException ex) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean exportActionScript(String outdir, boolean isPcode) throws Exception {
|
||||
boolean asV3Found = false;
|
||||
final EventListener evl = new EventListener() {
|
||||
public void handleEvent(String event, Object data) {
|
||||
if (event.equals("export")) {
|
||||
informListeners(event, data);
|
||||
}
|
||||
}
|
||||
};
|
||||
List<DoABCTag> abcTags = new ArrayList<DoABCTag>();
|
||||
for (Tag t : tags) {
|
||||
if (t instanceof DoABCTag) {
|
||||
abcTags.add((DoABCTag) t);
|
||||
asV3Found = true;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < abcTags.size(); i++) {
|
||||
DoABCTag t = abcTags.get(i);
|
||||
t.abc.addEventListener(evl);
|
||||
t.abc.export(outdir, isPcode, abcTags, "tag " + (i + 1) + "/" + abcTags.size() + " ");
|
||||
}
|
||||
for (DoABCTag t : abcTags) {
|
||||
}
|
||||
|
||||
if (!asV3Found) {
|
||||
List<Object> list2 = new ArrayList<Object>();
|
||||
list2.addAll(tags);
|
||||
List<TagNode> list = TagNode.createTagList(list2);
|
||||
TagNode.setExport(list, true);
|
||||
return TagNode.exportNode(list, outdir, isPcode);
|
||||
}
|
||||
return asV3Found;
|
||||
}
|
||||
protected HashSet<EventListener> listeners = new HashSet<EventListener>();
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
private static String getImageFormat(byte data[]) {
|
||||
if (hasErrorHeader(data)) {
|
||||
return "jpg";
|
||||
}
|
||||
if (data.length > 2 && ((data[0] & 0xff) == 0xff) && ((data[1] & 0xff) == 0xd8)) {
|
||||
return "jpg";
|
||||
}
|
||||
if (data.length > 6 && ((data[0] & 0xff) == 0x47) && ((data[1] & 0xff) == 0x49) && ((data[2] & 0xff) == 0x46) && ((data[3] & 0xff) == 0x38) && ((data[4] & 0xff) == 0x39) && ((data[5] & 0xff) == 0x61)) {
|
||||
return "gif";
|
||||
}
|
||||
|
||||
if (data.length > 8 && ((data[0] & 0xff) == 0x89) && ((data[1] & 0xff) == 0x50) && ((data[2] & 0xff) == 0x4e) && ((data[3] & 0xff) == 0x47) && ((data[4] & 0xff) == 0x0d) && ((data[5] & 0xff) == 0x0a) && ((data[6] & 0xff) == 0x1a) && ((data[7] & 0xff) == 0x0a)) {
|
||||
return "png";
|
||||
}
|
||||
|
||||
return "unk";
|
||||
}
|
||||
|
||||
public static boolean hasErrorHeader(byte data[]) {
|
||||
if (data.length > 4) {
|
||||
if ((data[0] & 0xff) == 0xff) {
|
||||
if ((data[1] & 0xff) == 0xd9) {
|
||||
if ((data[2] & 0xff) == 0xff) {
|
||||
if ((data[3] & 0xff) == 0xd8) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void exportImages(String outdir, List<Tag> tags, JPEGTablesTag jtt) throws IOException {
|
||||
for (Tag t : tags) {
|
||||
if ((t instanceof DefineBitsJPEG2Tag) || (t instanceof DefineBitsJPEG3Tag) || (t instanceof DefineBitsJPEG4Tag)) {
|
||||
byte imageData[] = null;
|
||||
int characterID = 0;
|
||||
if (t instanceof DefineBitsJPEG2Tag) {
|
||||
imageData = ((DefineBitsJPEG2Tag) t).imageData;
|
||||
characterID = ((DefineBitsJPEG2Tag) t).characterID;
|
||||
}
|
||||
if (t instanceof DefineBitsJPEG3Tag) {
|
||||
imageData = ((DefineBitsJPEG3Tag) t).imageData;
|
||||
characterID = ((DefineBitsJPEG3Tag) t).characterID;
|
||||
}
|
||||
if (t instanceof DefineBitsJPEG4Tag) {
|
||||
imageData = ((DefineBitsJPEG4Tag) t).imageData;
|
||||
characterID = ((DefineBitsJPEG4Tag) t).characterID;
|
||||
}
|
||||
|
||||
FileOutputStream fos = null;
|
||||
try {
|
||||
fos = new FileOutputStream(outdir + File.separator + characterID + "." + getImageFormat(imageData));
|
||||
if (hasErrorHeader(imageData)) {
|
||||
fos.write(imageData, 4, imageData.length - 4);
|
||||
} else {
|
||||
fos.write(imageData);
|
||||
}
|
||||
} finally {
|
||||
if (fos != null) {
|
||||
try {
|
||||
fos.close();
|
||||
} catch (Exception ex) {
|
||||
//ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (t instanceof DefineBitsLosslessTag) {
|
||||
DefineBitsLosslessTag dbl = (DefineBitsLosslessTag) t;
|
||||
ImageIO.write(dbl.getImage(), "PNG", new File(outdir + File.separator + dbl.characterID + ".png"));
|
||||
}
|
||||
if (t instanceof DefineBitsLossless2Tag) {
|
||||
DefineBitsLossless2Tag dbl = (DefineBitsLossless2Tag) t;
|
||||
|
||||
ImageIO.write(dbl.getImage(), "PNG", new File(outdir + File.separator + dbl.characterID + ".png"));
|
||||
}
|
||||
if ((jtt != null) && (t instanceof DefineBitsTag)) {
|
||||
DefineBitsTag dbt = (DefineBitsTag) t;
|
||||
FileOutputStream fos = null;
|
||||
try {
|
||||
fos = new FileOutputStream(outdir + File.separator + dbt.characterID + ".jpg");
|
||||
fos.write(dbt.getFullImageData(jtt));
|
||||
} finally {
|
||||
if (fos != null) {
|
||||
try {
|
||||
fos.close();
|
||||
} catch (Exception ex) {
|
||||
//ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void exportImages(String outdir) throws IOException {
|
||||
JPEGTablesTag jtt = null;
|
||||
for (Tag t : tags) {
|
||||
if (t instanceof JPEGTablesTag) {
|
||||
jtt = (JPEGTablesTag) t;
|
||||
}
|
||||
}
|
||||
exportImages(outdir, tags, jtt);
|
||||
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,865 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc;
|
||||
|
||||
import com.jpexs.decompiler.flash.EventListener;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.UnknownInstructionCode;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
|
||||
import com.jpexs.decompiler.flash.abc.types.*;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.Trait;
|
||||
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.*;
|
||||
import com.jpexs.decompiler.flash.tags.DoABCTag;
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class ABC {
|
||||
|
||||
public int major_version = 0;
|
||||
public int minor_version = 0;
|
||||
public ConstantPool constants;
|
||||
public MethodInfo method_info[];
|
||||
public MetadataInfo metadata_info[];
|
||||
public InstanceInfo instance_info[];
|
||||
public ClassInfo class_info[];
|
||||
public ScriptInfo script_info[];
|
||||
public MethodBody bodies[];
|
||||
private int bodyIdxFromMethodIdx[];
|
||||
public long stringOffsets[];
|
||||
public static String IDENT_STRING = " ";
|
||||
public static final int MINORwithDECIMAL = 17;
|
||||
protected HashSet<EventListener> listeners = new HashSet<EventListener>();
|
||||
private static Logger logger = Logger.getLogger(ABC.class.getName());
|
||||
|
||||
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() {
|
||||
int rem = 0;
|
||||
for (MethodBody body : bodies) {
|
||||
rem += body.removeTraps(constants);
|
||||
}
|
||||
return rem;
|
||||
}
|
||||
|
||||
public int removeDeadCode() {
|
||||
int rem = 0;
|
||||
for (MethodBody body : bodies) {
|
||||
rem += body.removeDeadCode(constants);
|
||||
}
|
||||
return rem;
|
||||
}
|
||||
|
||||
public void restoreControlFlow() {
|
||||
for (MethodBody body : bodies) {
|
||||
body.restoreControlFlow(constants);
|
||||
}
|
||||
}
|
||||
|
||||
public int deobfuscateIdentifiers(HashMap<String, String> namesMap) {
|
||||
int ret = 0;
|
||||
for (int i = 1; i < instance_info.length; i++) {
|
||||
if (instance_info[i].name_index != 0) {
|
||||
if (deobfuscateName(namesMap, constants.constant_multiname[instance_info[i].name_index].name_index, true)) {
|
||||
ret++;
|
||||
}
|
||||
}
|
||||
if (instance_info[i].super_index != 0) {
|
||||
if (deobfuscateName(namesMap, constants.constant_multiname[instance_info[i].super_index].name_index, true)) {
|
||||
ret++;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 1; i < constants.constant_multiname.length; i++) {
|
||||
if (deobfuscateName(namesMap, constants.constant_multiname[i].name_index, false)) {
|
||||
ret++;
|
||||
}
|
||||
}
|
||||
for (int i = 1; i < constants.constant_namespace.length; i++) {
|
||||
if (deobfuscateNameSpace(namesMap, constants.constant_namespace[i].name_index)) {
|
||||
ret++;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public ABC(InputStream is) throws IOException {
|
||||
ABCInputStream ais = new ABCInputStream(is);
|
||||
minor_version = ais.readU16();
|
||||
major_version = ais.readU16();
|
||||
logger.log(Level.FINE, "ABC minor_version: {0}, major_version: {1}", new Object[]{minor_version, major_version});
|
||||
constants = new ConstantPool();
|
||||
//constant integers
|
||||
int constant_int_pool_count = ais.readU30();
|
||||
constants.constant_int = new long[constant_int_pool_count];
|
||||
for (int i = 1; i < constant_int_pool_count; i++) { //index 0 not used. Values 1..n-1
|
||||
constants.constant_int[i] = ais.readS32();
|
||||
}
|
||||
|
||||
//constant unsigned integers
|
||||
int constant_uint_pool_count = ais.readU30();
|
||||
constants.constant_uint = new long[constant_uint_pool_count];
|
||||
for (int i = 1; i < constant_uint_pool_count; i++) { //index 0 not used. Values 1..n-1
|
||||
constants.constant_uint[i] = ais.readU32();
|
||||
}
|
||||
|
||||
//constant double
|
||||
int constant_double_pool_count = ais.readU30();
|
||||
constants.constant_double = new double[constant_double_pool_count];
|
||||
for (int i = 1; i < constant_double_pool_count; i++) { //index 0 not used. Values 1..n-1
|
||||
constants.constant_double[i] = ais.readDouble();
|
||||
}
|
||||
|
||||
|
||||
//constant decimal
|
||||
if (minor_version >= MINORwithDECIMAL) {
|
||||
int constant_decimal_pool_count = ais.readU30();
|
||||
constants.constant_decimal = new Decimal[constant_decimal_pool_count];
|
||||
for (int i = 1; i < constant_decimal_pool_count; i++) { //index 0 not used. Values 1..n-1
|
||||
constants.constant_decimal[i] = ais.readDecimal();
|
||||
}
|
||||
} else {
|
||||
constants.constant_decimal = new Decimal[0];
|
||||
}
|
||||
|
||||
//constant string
|
||||
int constant_string_pool_count = ais.readU30();
|
||||
constants.constant_string = new String[constant_string_pool_count];
|
||||
stringOffsets = new long[constant_string_pool_count];
|
||||
constants.constant_string[0] = "";
|
||||
for (int i = 1; i < constant_string_pool_count; i++) { //index 0 not used. Values 1..n-1
|
||||
long pos = ais.getPosition();
|
||||
constants.constant_string[i] = ais.readString();
|
||||
stringOffsets[i] = pos;
|
||||
}
|
||||
|
||||
//constant namespace
|
||||
int constant_namespace_pool_count = ais.readU30();
|
||||
constants.constant_namespace = new Namespace[constant_namespace_pool_count];
|
||||
for (int i = 1; i < constant_namespace_pool_count; i++) { //index 0 not used. Values 1..n-1
|
||||
constants.constant_namespace[i] = ais.readNamespace();
|
||||
}
|
||||
|
||||
//constant namespace set
|
||||
int constant_namespace_set_pool_count = ais.readU30();
|
||||
constants.constant_namespace_set = new NamespaceSet[constant_namespace_set_pool_count];
|
||||
for (int i = 1; i < constant_namespace_set_pool_count; i++) { //index 0 not used. Values 1..n-1
|
||||
constants.constant_namespace_set[i] = new NamespaceSet();
|
||||
int namespace_count = ais.readU30();
|
||||
constants.constant_namespace_set[i].namespaces = new int[namespace_count];
|
||||
for (int j = 0; j < namespace_count; j++) {
|
||||
constants.constant_namespace_set[i].namespaces[j] = ais.readU30();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//constant multiname
|
||||
int constant_multiname_pool_count = ais.readU30();
|
||||
constants.constant_multiname = new Multiname[constant_multiname_pool_count];
|
||||
for (int i = 1; i < constant_multiname_pool_count; i++) { //index 0 not used. Values 1..n-1
|
||||
constants.constant_multiname[i] = ais.readMultiname();
|
||||
}
|
||||
|
||||
|
||||
//method info
|
||||
int methods_count = ais.readU30();
|
||||
method_info = new MethodInfo[methods_count];
|
||||
bodyIdxFromMethodIdx = new int[methods_count];
|
||||
for (int i = 0; i < methods_count; i++) {
|
||||
method_info[i] = ais.readMethodInfo();
|
||||
bodyIdxFromMethodIdx[i] = -1;
|
||||
}
|
||||
|
||||
//metadata info
|
||||
int metadata_count = ais.readU30();
|
||||
metadata_info = new MetadataInfo[metadata_count];
|
||||
for (int i = 0; i < metadata_count; i++) {
|
||||
int name_index = ais.readU30();
|
||||
int values_count = ais.readU30();
|
||||
int keys[] = new int[values_count];
|
||||
for (int v = 0; v < values_count; v++) {
|
||||
keys[v] = ais.readU30();
|
||||
}
|
||||
int values[] = new int[values_count];
|
||||
for (int v = 0; v < values_count; v++) {
|
||||
values[v] = ais.readU30();
|
||||
}
|
||||
metadata_info[i] = new MetadataInfo(name_index, keys, values);
|
||||
}
|
||||
|
||||
int class_count = ais.readU30();
|
||||
instance_info = new InstanceInfo[class_count];
|
||||
for (int i = 0; i < class_count; i++) {
|
||||
instance_info[i] = ais.readInstanceInfo();
|
||||
}
|
||||
class_info = new ClassInfo[class_count];
|
||||
for (int i = 0; i < class_count; i++) {
|
||||
ClassInfo ci = new ClassInfo();
|
||||
ci.cinit_index = ais.readU30();
|
||||
ci.static_traits = ais.readTraits();
|
||||
class_info[i] = ci;
|
||||
}
|
||||
int script_count = ais.readU30();
|
||||
script_info = new ScriptInfo[script_count];
|
||||
for (int i = 0; i < script_count; i++) {
|
||||
ScriptInfo si = new ScriptInfo();
|
||||
si.init_index = ais.readU30();
|
||||
si.traits = ais.readTraits();
|
||||
script_info[i] = si;
|
||||
}
|
||||
|
||||
int bodies_count = ais.readU30();
|
||||
bodies = new MethodBody[bodies_count];
|
||||
for (int i = 0; i < bodies_count; i++) {
|
||||
MethodBody mb = new MethodBody();
|
||||
mb.method_info = ais.readU30();
|
||||
mb.max_stack = ais.readU30();
|
||||
mb.max_regs = ais.readU30();
|
||||
mb.init_scope_depth = ais.readU30();
|
||||
mb.max_scope_depth = ais.readU30();
|
||||
int code_length = ais.readU30();
|
||||
mb.codeBytes = new byte[code_length];
|
||||
ais.read(mb.codeBytes);
|
||||
try {
|
||||
mb.code = new AVM2Code(new ByteArrayInputStream(mb.codeBytes));
|
||||
} catch (UnknownInstructionCode re) {
|
||||
mb.code = new AVM2Code();
|
||||
Logger.getLogger(ABC.class.getName()).log(Level.SEVERE, null, re);
|
||||
}
|
||||
mb.code.compact();
|
||||
int ex_count = ais.readU30();
|
||||
mb.exceptions = new ABCException[ex_count];
|
||||
for (int j = 0; j < ex_count; j++) {
|
||||
ABCException abce = new ABCException();
|
||||
abce.start = ais.readU30();
|
||||
abce.end = ais.readU30();
|
||||
abce.target = ais.readU30();
|
||||
abce.type_index = ais.readU30();
|
||||
abce.name_index = ais.readU30();
|
||||
mb.exceptions[j] = abce;
|
||||
}
|
||||
mb.traits = ais.readTraits();
|
||||
bodies[i] = mb;
|
||||
method_info[mb.method_info].setBody(mb);
|
||||
bodyIdxFromMethodIdx[mb.method_info] = i;
|
||||
}
|
||||
loadNamespaceMap();
|
||||
/* for(ScriptInfo si:script_info){
|
||||
System.out.println("--------------------------------------------");
|
||||
System.out.println(findBody(si.init_index).toString(true, false, -1, this, constants, method_info,new Stack<TreeItem>(),false,false));
|
||||
System.out.println("sitrait:"+si.traits.toString(this));
|
||||
}*/
|
||||
/*try {
|
||||
MethodBody body=new MethodBody();
|
||||
AVM2Code code=ASM3Parser.parse(new FileInputStream("D:\\tst2.txt"), constants, body);
|
||||
//code.removeTraps(constants, body);
|
||||
code.restoreControlFlow(constants, body);
|
||||
FileOutputStream fos=new FileOutputStream("D:\\tst3.txt");
|
||||
fos.write(Highlighting.stripHilights(code.toASMSource(constants, body)).getBytes());
|
||||
fos.close();
|
||||
System.out.println(code.toSource(false, 0, this, constants, method_info, body, new HashMap<Integer,String>(), new Stack<TreeItem>(), false, null, null));
|
||||
System.exit(0);
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(ABC.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}*/
|
||||
}
|
||||
|
||||
public void saveToStream(OutputStream os) throws IOException {
|
||||
ABCOutputStream aos = new ABCOutputStream(os);
|
||||
aos.writeU16(minor_version);
|
||||
aos.writeU16(major_version);
|
||||
|
||||
aos.writeU30(constants.constant_int.length);
|
||||
for (int i = 1; i < constants.constant_int.length; i++) {
|
||||
aos.writeS32(constants.constant_int[i]);
|
||||
}
|
||||
aos.writeU30(constants.constant_uint.length);
|
||||
for (int i = 1; i < constants.constant_uint.length; i++) {
|
||||
aos.writeU32(constants.constant_uint[i]);
|
||||
}
|
||||
|
||||
aos.writeU30(constants.constant_double.length);
|
||||
for (int i = 1; i < constants.constant_double.length; i++) {
|
||||
aos.writeDouble(constants.constant_double[i]);
|
||||
}
|
||||
|
||||
if (minor_version >= MINORwithDECIMAL) {
|
||||
aos.writeU30(constants.constant_decimal.length);
|
||||
for (int i = 1; i < constants.constant_decimal.length; i++) {
|
||||
aos.writeDecimal(constants.constant_decimal[i]);
|
||||
}
|
||||
}
|
||||
|
||||
aos.writeU30(constants.constant_string.length);
|
||||
for (int i = 1; i < constants.constant_string.length; i++) {
|
||||
aos.writeString(constants.constant_string[i]);
|
||||
}
|
||||
|
||||
aos.writeU30(constants.constant_namespace.length);
|
||||
for (int i = 1; i < constants.constant_namespace.length; i++) {
|
||||
aos.writeNamespace(constants.constant_namespace[i]);
|
||||
}
|
||||
|
||||
aos.writeU30(constants.constant_namespace_set.length);
|
||||
for (int i = 1; i < constants.constant_namespace_set.length; i++) {
|
||||
aos.writeU30(constants.constant_namespace_set[i].namespaces.length);
|
||||
for (int j = 0; j < constants.constant_namespace_set[i].namespaces.length; j++) {
|
||||
aos.writeU30(constants.constant_namespace_set[i].namespaces[j]);
|
||||
}
|
||||
}
|
||||
|
||||
aos.writeU30(constants.constant_multiname.length);
|
||||
for (int i = 1; i < constants.constant_multiname.length; i++) {
|
||||
aos.writeMultiname(constants.constant_multiname[i]);
|
||||
}
|
||||
|
||||
aos.writeU30(method_info.length);
|
||||
for (int i = 0; i < method_info.length; i++) {
|
||||
aos.writeMethodInfo(method_info[i]);
|
||||
}
|
||||
|
||||
aos.writeU30(metadata_info.length);
|
||||
for (int i = 0; i < metadata_info.length; i++) {
|
||||
aos.writeU30(metadata_info[i].name_index);
|
||||
aos.writeU30(metadata_info[i].values.length);
|
||||
for (int j = 0; j < metadata_info[i].values.length; j++) {
|
||||
aos.writeU30(metadata_info[i].keys[j]);
|
||||
}
|
||||
for (int j = 0; j < metadata_info[i].values.length; j++) {
|
||||
aos.writeU30(metadata_info[i].values[j]);
|
||||
}
|
||||
}
|
||||
|
||||
aos.writeU30(class_info.length);
|
||||
for (int i = 0; i < instance_info.length; i++) {
|
||||
aos.writeInstanceInfo(instance_info[i]);
|
||||
}
|
||||
for (int i = 0; i < class_info.length; i++) {
|
||||
aos.writeU30(class_info[i].cinit_index);
|
||||
aos.writeTraits(class_info[i].static_traits);
|
||||
}
|
||||
aos.writeU30(script_info.length);
|
||||
for (int i = 0; i < script_info.length; i++) {
|
||||
aos.writeU30(script_info[i].init_index);
|
||||
aos.writeTraits(script_info[i].traits);
|
||||
}
|
||||
|
||||
aos.writeU30(bodies.length);
|
||||
for (int i = 0; i < bodies.length; i++) {
|
||||
aos.writeU30(bodies[i].method_info);
|
||||
aos.writeU30(bodies[i].max_stack);
|
||||
aos.writeU30(bodies[i].max_regs);
|
||||
aos.writeU30(bodies[i].init_scope_depth);
|
||||
aos.writeU30(bodies[i].max_scope_depth);
|
||||
byte codeBytes[] = bodies[i].code.getBytes();
|
||||
aos.writeU30(codeBytes.length);
|
||||
try {
|
||||
aos.write(codeBytes);
|
||||
} catch (NotSameException ex) {
|
||||
System.out.println(bodies[i].code.toString(constants));
|
||||
System.exit(0);
|
||||
return;
|
||||
}
|
||||
aos.writeU30(bodies[i].exceptions.length);
|
||||
for (int j = 0; j < bodies[i].exceptions.length; j++) {
|
||||
aos.writeU30(bodies[i].exceptions[j].start);
|
||||
aos.writeU30(bodies[i].exceptions[j].end);
|
||||
aos.writeU30(bodies[i].exceptions[j].target);
|
||||
aos.writeU30(bodies[i].exceptions[j].type_index);
|
||||
aos.writeU30(bodies[i].exceptions[j].name_index);
|
||||
}
|
||||
aos.writeTraits(bodies[i].traits);
|
||||
}
|
||||
}
|
||||
|
||||
public MethodBody findBody(int methodInfo) {
|
||||
if (methodInfo < 0) {
|
||||
return null;
|
||||
}
|
||||
return method_info[methodInfo].getBody();
|
||||
}
|
||||
|
||||
public int findBodyIndex(int methodInfo) {
|
||||
if (methodInfo == -1) {
|
||||
return -1;
|
||||
}
|
||||
return bodyIdxFromMethodIdx[methodInfo];
|
||||
}
|
||||
|
||||
public MethodBody findBodyByClassAndName(String className, String methodName) {
|
||||
for (int i = 0; i < instance_info.length; i++) {
|
||||
if (className.equals(constants.constant_multiname[instance_info[i].name_index].getName(constants, new ArrayList<String>()))) {
|
||||
for (Trait t : instance_info[i].instance_traits.traits) {
|
||||
if (t instanceof TraitMethodGetterSetter) {
|
||||
TraitMethodGetterSetter t2 = (TraitMethodGetterSetter) t;
|
||||
if (methodName.equals(t2.getName(this).getName(constants, new ArrayList<String>()))) {
|
||||
for (MethodBody body : bodies) {
|
||||
if (body.method_info == t2.method_info) {
|
||||
return body;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//break;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < class_info.length; i++) {
|
||||
if (className.equals(constants.constant_multiname[instance_info[i].name_index].getName(constants, new ArrayList<String>()))) {
|
||||
for (Trait t : class_info[i].static_traits.traits) {
|
||||
if (t instanceof TraitMethodGetterSetter) {
|
||||
TraitMethodGetterSetter t2 = (TraitMethodGetterSetter) t;
|
||||
if (methodName.equals(t2.getName(this).getName(constants, new ArrayList<String>()))) {
|
||||
for (MethodBody body : bodies) {
|
||||
if (body.method_info == t2.method_info) {
|
||||
return body;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String addTabs(String s, int tabs) {
|
||||
String parts[] = s.split("\r\n");
|
||||
if (!s.contains("\r\n")) {
|
||||
parts = s.split("\n");
|
||||
}
|
||||
StringBuilder ret = new StringBuilder();
|
||||
for (int i = 0; i < parts.length; i++) {
|
||||
for (int t = 0; t < tabs; t++) {
|
||||
ret.append(IDENT_STRING);
|
||||
}
|
||||
ret.append(parts[i]);
|
||||
if (i < parts.length - 1) {
|
||||
ret.append("\r\n");
|
||||
}
|
||||
}
|
||||
return ret.toString();
|
||||
}
|
||||
|
||||
public Trait findTraitByTraitId(int classIndex, int traitId) {
|
||||
if (traitId < class_info[classIndex].static_traits.traits.length) {
|
||||
return class_info[classIndex].static_traits.traits[traitId];
|
||||
} else if (traitId < class_info[classIndex].static_traits.traits.length + instance_info[classIndex].instance_traits.traits.length) {
|
||||
traitId -= class_info[classIndex].static_traits.traits.length;
|
||||
return instance_info[classIndex].instance_traits.traits[traitId];
|
||||
} else {
|
||||
return null; //Can be class or instance initializer
|
||||
}
|
||||
}
|
||||
|
||||
public int findMethodIdByTraitId(int classIndex, int traitId) {
|
||||
if (traitId < class_info[classIndex].static_traits.traits.length) {
|
||||
if (class_info[classIndex].static_traits.traits[traitId] instanceof TraitMethodGetterSetter) {
|
||||
return ((TraitMethodGetterSetter) class_info[classIndex].static_traits.traits[traitId]).method_info;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
} else if (traitId < class_info[classIndex].static_traits.traits.length + instance_info[classIndex].instance_traits.traits.length) {
|
||||
traitId -= class_info[classIndex].static_traits.traits.length;
|
||||
if (instance_info[classIndex].instance_traits.traits[traitId] instanceof TraitMethodGetterSetter) {
|
||||
return ((TraitMethodGetterSetter) instance_info[classIndex].instance_traits.traits[traitId]).method_info;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
traitId -= class_info[classIndex].static_traits.traits.length + instance_info[classIndex].instance_traits.traits.length;
|
||||
if (traitId == 0) {
|
||||
return instance_info[classIndex].iinit_index;
|
||||
} else if (traitId == 1) {
|
||||
return class_info[classIndex].cinit_index;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Map from multiname index of namespace value to namespace name**/
|
||||
private HashMap<String, String> namespaceMap;
|
||||
|
||||
private void loadNamespaceMap() {
|
||||
namespaceMap = new HashMap<String, String>();
|
||||
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.constant_namespace[s.value_index].getName(constants);
|
||||
String val = constants.constant_multiname[s.name_index].getNameWithNamespace(constants);
|
||||
namespaceMap.put(key, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String builtInNs(String ns) {
|
||||
if (ns.equals("http://www.adobe.com/2006/actionscript/flash/proxy")) {
|
||||
return "flash.utils.flash_proxy";
|
||||
}
|
||||
if (ns.equals("http://adobe.com/AS3/2006/builtin")) {
|
||||
return "-";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String nsValueToName(String value) {
|
||||
if (namespaceMap.containsKey(value)) {
|
||||
return namespaceMap.get(value);
|
||||
} else {
|
||||
String ns = builtInNs(value);
|
||||
if (ns == null) {
|
||||
return "";
|
||||
} else {
|
||||
return ns;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void export(String directory, boolean pcode, List<DoABCTag> abcList) throws IOException {
|
||||
export(directory, pcode, abcList, "");
|
||||
}
|
||||
|
||||
public void export(String directory, boolean pcode, List<DoABCTag> abcList, String abcStr) throws IOException {
|
||||
for (int i = 0; i < script_info.length; i++) {
|
||||
String path = script_info[i].getPath(this);
|
||||
String packageName = path.substring(0, path.lastIndexOf("."));
|
||||
if (packageName.equals("")) {
|
||||
path = path.substring(1);
|
||||
}
|
||||
String cnt = "";
|
||||
if (script_info.length > 1) {
|
||||
cnt = "script " + (i + 1) + "/" + script_info.length + " ";
|
||||
}
|
||||
String exStr = "Exporting " + abcStr + cnt + path + " ...";
|
||||
informListeners("export", exStr);
|
||||
script_info[i].export(this, abcList, directory, pcode);
|
||||
}
|
||||
}
|
||||
|
||||
public void dump(OutputStream os) {
|
||||
PrintStream output = new PrintStream(os);
|
||||
constants.dump(output);
|
||||
for (int i = 0; i < method_info.length; i++) {
|
||||
output.println("MethodInfo[" + i + "]:" + method_info[i].toString(constants, new ArrayList<String>()));
|
||||
}
|
||||
for (int i = 0; i < metadata_info.length; i++) {
|
||||
output.println("MetadataInfo[" + i + "]:" + metadata_info[i].toString(constants));
|
||||
}
|
||||
for (int i = 0; i < instance_info.length; i++) {
|
||||
output.println("InstanceInfo[" + i + "]:" + instance_info[i].toString(this, new ArrayList<String>()));
|
||||
}
|
||||
for (int i = 0; i < class_info.length; i++) {
|
||||
output.println("ClassInfo[" + i + "]:" + class_info[i].toString(this, new ArrayList<String>()));
|
||||
}
|
||||
for (int i = 0; i < script_info.length; i++) {
|
||||
output.println("ScriptInfo[" + i + "]:" + script_info[i].toString(this, new ArrayList<String>()));
|
||||
}
|
||||
for (int i = 0; i < bodies.length; i++) {
|
||||
output.println("MethodBody[" + i + "]:"); //+ bodies[i].toString(this, constants, method_info));
|
||||
}
|
||||
}
|
||||
public static final String[] reservedWords = {
|
||||
"as", "break", "case", "catch", "class", "const", "continue", "default", "delete", "do", "each", "else",
|
||||
"extends", "false", "finally", "for", "function", "get", "if", "implements", "import", "in", "instanceof",
|
||||
"interface", "internal", "is", "native", "new", "null", "override", "package", "private", "protected", "public",
|
||||
"return", "set", "super", "switch", "this", "throw", "true", "try", "typeof", "use", "var", /*"void",*/ "while",
|
||||
"with", "dynamic", "default", "final", "in"};
|
||||
public static final String validFirstCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_";
|
||||
public static final String validNextCharacters = validFirstCharacters + "0123456789";
|
||||
public static final String validNsCharacters = ".:$";
|
||||
public static final String fooCharacters = "bcdfghjklmnpqrstvwz";
|
||||
public static final String fooJoinCharacters = "aeiouy";
|
||||
private HashMap<String, String> deobfuscated = new HashMap<String, String>();
|
||||
private Random rnd = new Random();
|
||||
private final int DEFAULT_FOO_SIZE = 10;
|
||||
|
||||
private String fooString(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 = "" + fooCharacters.charAt(rnd.nextInt(fooCharacters.length()));
|
||||
} else {
|
||||
c = "" + fooJoinCharacters.charAt(rnd.nextInt(fooJoinCharacters.length()));
|
||||
}
|
||||
if (i == 0 && firstUppercase) {
|
||||
c = c.toUpperCase();
|
||||
}
|
||||
ret += c;
|
||||
}
|
||||
for (int i = 1; i < constants.constant_string.length; i++) {
|
||||
if (constants.constant_string[i].equals(ret)) {
|
||||
exists = true;
|
||||
rndSize = rndSize + 1;
|
||||
continue loopfoo;
|
||||
}
|
||||
}
|
||||
if (isReserved(ret)) {
|
||||
exists = true;
|
||||
rndSize = rndSize + 1;
|
||||
continue;
|
||||
}
|
||||
if (deobfuscated.containsValue(ret)) {
|
||||
exists = true;
|
||||
rndSize = rndSize + 1;
|
||||
continue;
|
||||
}
|
||||
} while (exists);
|
||||
deobfuscated.put(orig, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
private boolean isReserved(String s) {
|
||||
for (String rw : reservedWords) {
|
||||
if (rw.equals(s.trim())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isValidNSPart(String s) {
|
||||
boolean isValid = true;
|
||||
if (isReserved(s)) {
|
||||
isValid = false;
|
||||
}
|
||||
|
||||
if (isValid) {
|
||||
for (int i = 0; i < s.length(); i++) {
|
||||
if (s.charAt(i) > 127) {
|
||||
isValid = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isValid) {
|
||||
Pattern pat = Pattern.compile("^([" + Pattern.quote(validFirstCharacters) + "]" + "[" + Pattern.quote(validFirstCharacters + validNextCharacters + validNsCharacters) + "]*)*$");
|
||||
if (!pat.matcher(s).matches()) {
|
||||
isValid = false;
|
||||
}
|
||||
}
|
||||
return isValid;
|
||||
}
|
||||
|
||||
public boolean deobfuscateNameSpace(HashMap<String, String> namesMap, int strIndex) {
|
||||
if (strIndex <= 0) {
|
||||
return false;
|
||||
}
|
||||
String s = constants.constant_string[strIndex];
|
||||
boolean isValid = isValidNSPart(s);
|
||||
if (!isValid) {
|
||||
if (namesMap.containsKey(s)) {
|
||||
constants.constant_string[strIndex] = namesMap.get(s);
|
||||
} else {
|
||||
String parts[] = null;
|
||||
if (s.contains(".")) {
|
||||
parts = s.split("\\.");
|
||||
} else {
|
||||
parts = new String[]{s};
|
||||
}
|
||||
String ret = "";
|
||||
for (int p = 0; p < parts.length; p++) {
|
||||
if (p > 0) {
|
||||
ret += ".";
|
||||
}
|
||||
if (!isValidNSPart(parts[p])) {
|
||||
ret += fooString(constants.constant_string[strIndex], false, DEFAULT_FOO_SIZE);
|
||||
} else {
|
||||
ret += parts[p];
|
||||
}
|
||||
}
|
||||
constants.constant_string[strIndex] = ret;
|
||||
namesMap.put(s, constants.constant_string[strIndex]);
|
||||
}
|
||||
}
|
||||
return !isValid;
|
||||
}
|
||||
|
||||
public boolean deobfuscateName(HashMap<String, String> namesMap, int strIndex, boolean firstUppercase) {
|
||||
if (strIndex <= 0) {
|
||||
return false;
|
||||
}
|
||||
String s = constants.constant_string[strIndex];
|
||||
boolean isValid = true;
|
||||
if (isReserved(s)) {
|
||||
isValid = false;
|
||||
}
|
||||
|
||||
if (isValid) {
|
||||
for (int i = 0; i < s.length(); i++) {
|
||||
if (s.charAt(i) > 127) {
|
||||
isValid = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isValid) {
|
||||
Pattern pat = Pattern.compile("^[" + Pattern.quote(validFirstCharacters) + "]" + "[" + Pattern.quote(validFirstCharacters + validNextCharacters) + "]*$");
|
||||
if (!pat.matcher(s).matches()) {
|
||||
isValid = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isValid) {
|
||||
if (namesMap.containsKey(s)) {
|
||||
constants.constant_string[strIndex] = namesMap.get(s);
|
||||
} else {
|
||||
constants.constant_string[strIndex] = fooString(constants.constant_string[strIndex], firstUppercase, DEFAULT_FOO_SIZE);
|
||||
namesMap.put(s, constants.constant_string[strIndex]);
|
||||
}
|
||||
}
|
||||
return !isValid;
|
||||
}
|
||||
|
||||
private void checkMultinameUsedInMethod(int multinameIndex, int methodInfo, List<MultinameUsage> ret, int classIndex, int traitIndex, boolean isStatic, boolean isInitializer, Traits traits, int parentTraitIndex) {
|
||||
for (int p = 0; p < method_info[methodInfo].param_types.length; p++) {
|
||||
if (method_info[methodInfo].param_types[p] == multinameIndex) {
|
||||
ret.add(new MethodParamsMultinameUsage(multinameIndex, classIndex, traitIndex, isStatic, isInitializer, traits, parentTraitIndex));
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (method_info[methodInfo].ret_type == multinameIndex) {
|
||||
ret.add(new MethodReturnTypeMultinameUsage(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(multinameIndex, classIndex, traitIndex, isStatic, isInitializer, traits, parentTraitIndex));
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (AVM2Instruction ins : body.code.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(multinameIndex, classIndex, traitIndex, isStatic, isInitializer, traits, parentTraitIndex));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void findMultinameUsageInTraits(Traits traits, int multinameIndex, boolean isStatic, int classIndex, List<MultinameUsage> ret, int parentTraitIndex) {
|
||||
for (int t = 0; t < traits.traits.length; t++) {
|
||||
if (traits.traits[t] instanceof TraitSlotConst) {
|
||||
TraitSlotConst tsc = (TraitSlotConst) traits.traits[t];
|
||||
if (tsc.name_index == multinameIndex) {
|
||||
ret.add(new ConstVarNameMultinameUsage(multinameIndex, classIndex, t, isStatic, traits, parentTraitIndex));
|
||||
}
|
||||
if (tsc.type_index == multinameIndex) {
|
||||
ret.add(new ConstVarTypeMultinameUsage(multinameIndex, classIndex, t, isStatic, traits, parentTraitIndex));
|
||||
}
|
||||
}
|
||||
if (traits.traits[t] instanceof TraitMethodGetterSetter) {
|
||||
TraitMethodGetterSetter tmgs = (TraitMethodGetterSetter) traits.traits[t];
|
||||
if (tmgs.name_index == multinameIndex) {
|
||||
ret.add(new MethodNameMultinameUsage(multinameIndex, classIndex, t, isStatic, false, traits, parentTraitIndex));
|
||||
}
|
||||
checkMultinameUsedInMethod(multinameIndex, tmgs.method_info, ret, classIndex, t, isStatic, false, traits, parentTraitIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<MultinameUsage> findMultinameUsage(int multinameIndex) {
|
||||
List<MultinameUsage> ret = new ArrayList<MultinameUsage>();
|
||||
if (multinameIndex == 0) {
|
||||
return ret;
|
||||
}
|
||||
for (int c = 0; c < instance_info.length; c++) {
|
||||
if (instance_info[c].name_index == multinameIndex) {
|
||||
ret.add(new ClassNameMultinameUsage(multinameIndex, c));
|
||||
}
|
||||
if (instance_info[c].super_index == multinameIndex) {
|
||||
ret.add(new ExtendsMultinameUsage(multinameIndex, c));
|
||||
}
|
||||
for (int i = 0; i < instance_info[c].interfaces.length; i++) {
|
||||
if (instance_info[c].interfaces[i] == multinameIndex) {
|
||||
ret.add(new ImplementsMultinameUsage(multinameIndex, c));
|
||||
}
|
||||
}
|
||||
checkMultinameUsedInMethod(multinameIndex, instance_info[c].iinit_index, ret, c, 0, false, true, null, -1);
|
||||
checkMultinameUsedInMethod(multinameIndex, class_info[c].cinit_index, ret, c, 0, true, true, null, -1);
|
||||
findMultinameUsageInTraits(instance_info[c].instance_traits, multinameIndex, false, c, ret, -1);
|
||||
findMultinameUsageInTraits(class_info[c].static_traits, multinameIndex, true, c, ret, -1);
|
||||
}
|
||||
loopm:
|
||||
for (int m = 1; m < constants.constant_multiname.length; m++) {
|
||||
if (constants.constant_multiname[m].kind == Multiname.TYPENAME) {
|
||||
if (constants.constant_multiname[m].qname_index == multinameIndex) {
|
||||
ret.add(new TypeNameMultinameUsage(m));
|
||||
continue;
|
||||
}
|
||||
for (int mp : constants.constant_multiname[m].params) {
|
||||
if (mp == multinameIndex) {
|
||||
ret.add(new TypeNameMultinameUsage(m));
|
||||
continue loopm;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void autoFillAllBodyParams() {
|
||||
for (int i = 0; i < bodies.length; i++) {
|
||||
bodies[i].autoFillStats(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,377 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.types.*;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.*;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ABCInputStream extends InputStream {
|
||||
|
||||
private static final int CLASS_PROTECTED_NS = 8;
|
||||
private static final int ATTR_METADATA = 4;
|
||||
private InputStream is;
|
||||
private long bytesRead = 0;
|
||||
private ByteArrayOutputStream bufferOs = null;
|
||||
public static boolean DEBUG_READ = false;
|
||||
|
||||
public void startBuffer() {
|
||||
bufferOs = new ByteArrayOutputStream();
|
||||
}
|
||||
|
||||
public byte[] stopBuffer() {
|
||||
if (bufferOs == null) {
|
||||
return new byte[0];
|
||||
}
|
||||
byte ret[] = bufferOs.toByteArray();
|
||||
bufferOs = null;
|
||||
return ret;
|
||||
}
|
||||
|
||||
public ABCInputStream(InputStream is) {
|
||||
this.is = is;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
bytesRead++;
|
||||
int i = is.read();
|
||||
if (DEBUG_READ) {
|
||||
System.out.println("Read:0x" + Integer.toHexString(i));
|
||||
}
|
||||
if (bufferOs != null) {
|
||||
if (i != -1) {
|
||||
bufferOs.write(i);
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(byte[] b) throws IOException {
|
||||
int currBytesRead = is.read(b);
|
||||
bytesRead += currBytesRead;
|
||||
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() throws IOException {
|
||||
return read();
|
||||
}
|
||||
|
||||
public int readU32() throws IOException {
|
||||
int i;
|
||||
int ret = 0;
|
||||
int bytePos = 0;
|
||||
int byteCount = 0;
|
||||
boolean nextByte;
|
||||
do {
|
||||
i = read();
|
||||
nextByte = (i >> 7) == 1;
|
||||
i = i & 0x7f;
|
||||
ret = ret + (i << bytePos);
|
||||
byteCount++;
|
||||
bytePos += 7;
|
||||
} while (nextByte);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public int readU30() throws IOException {
|
||||
return readU32();
|
||||
}
|
||||
|
||||
public int readS24() throws IOException {
|
||||
int ret = (read()) + (read() << 8) + (read() << 16);
|
||||
|
||||
if ((ret >> 23) == 1) {
|
||||
ret = ret | 0xff000000;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public int readU16() throws IOException {
|
||||
return (read()) + (read() << 8);
|
||||
}
|
||||
|
||||
public long readS32() throws IOException {
|
||||
int i;
|
||||
long ret = 0;
|
||||
int bytePos = 0;
|
||||
int byteCount = 0;
|
||||
boolean nextByte;
|
||||
do {
|
||||
i = read();
|
||||
nextByte = (i >> 7) == 1;
|
||||
i = i & 0x7f;
|
||||
ret = ret + (i << bytePos);
|
||||
byteCount++;
|
||||
bytePos += 7;
|
||||
if (bytePos == 35) {
|
||||
if ((ret >> 31) == 1) {
|
||||
ret = -(ret & 0x7fffffff);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} while (nextByte);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int available() throws IOException {
|
||||
return is.available();
|
||||
}
|
||||
|
||||
public final long readLong() throws IOException {
|
||||
byte readBuffer[] = safeRead(8);
|
||||
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() throws IOException {
|
||||
long el = readLong();
|
||||
double ret = Double.longBitsToDouble(el);
|
||||
return ret;
|
||||
}
|
||||
|
||||
private byte[] safeRead(int count) throws IOException {
|
||||
byte ret[] = new byte[count];
|
||||
for (int i = 0; i < count; i++) {
|
||||
ret[i] = (byte) read();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public Namespace readNamespace() throws IOException {
|
||||
int kind = read();
|
||||
int name_index = 0;
|
||||
for (int k = 0; k < Namespace.nameSpaceKinds.length; k++) {
|
||||
if (Namespace.nameSpaceKinds[k] == kind) {
|
||||
name_index = readU30();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return new Namespace(kind, name_index);
|
||||
}
|
||||
|
||||
public Multiname readMultiname() throws IOException {
|
||||
int kind = readU8();
|
||||
int namespace_index = -1;
|
||||
int name_index = -1;
|
||||
int namespace_set_index = -1;
|
||||
int qname_index = -1;
|
||||
List<Integer> params = new ArrayList<Integer>();
|
||||
|
||||
if ((kind == 7) || (kind == 0xd)) { // CONSTANT_QName and CONSTANT_QNameA.
|
||||
namespace_index = readU30();
|
||||
name_index = readU30();
|
||||
} else if ((kind == 0xf) || (kind == 0x10)) { //CONSTANT_RTQName and CONSTANT_RTQNameA
|
||||
name_index = readU30();
|
||||
} else if ((kind == 0x11) || (kind == 0x12))//kind==0x11,0x12 nothing CONSTANT_RTQNameL and CONSTANT_RTQNameLA.
|
||||
{
|
||||
} else if ((kind == 9) || (kind == 0xe)) { // CONSTANT_Multiname and CONSTANT_MultinameA.
|
||||
name_index = readU30();
|
||||
namespace_set_index = readU30();
|
||||
} else if ((kind == 0x1B) || (kind == 0x1C)) { //CONSTANT_MultinameL and CONSTANT_MultinameLA
|
||||
namespace_set_index = readU30();
|
||||
} else if (kind == 0x1D) {
|
||||
//Constant_TypeName
|
||||
qname_index = readU30(); //Multiname index!!!
|
||||
int paramsLength = readU30();
|
||||
for (int i = 0; i < paramsLength; i++) {
|
||||
params.add(readU30()); //multiname indices!
|
||||
}
|
||||
} else {
|
||||
System.err.println("Unknown kind of Multiname:0x" + Integer.toHexString(kind));
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
return new Multiname(kind, name_index, namespace_index, namespace_set_index, qname_index, params);
|
||||
}
|
||||
|
||||
public MethodInfo readMethodInfo() throws IOException {
|
||||
int param_count = readU30();
|
||||
int ret_type = readU30();
|
||||
int param_types[] = new int[param_count];
|
||||
for (int i = 0; i < param_count; i++) {
|
||||
param_types[i] = readU30();
|
||||
}
|
||||
int name_index = readU30();
|
||||
int flags = read();
|
||||
|
||||
//// 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 = new ValueKind[optional_count];
|
||||
for (int i = 0; i < optional_count; i++) {
|
||||
optional[i] = new ValueKind(readU30(), read());
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
return new MethodInfo(param_types, ret_type, name_index, flags, optional, param_names);
|
||||
}
|
||||
|
||||
public Trait readTrait() throws IOException {
|
||||
long pos = getPosition();
|
||||
startBuffer();
|
||||
int name_index = readU30();
|
||||
int kind = read();
|
||||
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();
|
||||
t1.type_index = readU30();
|
||||
t1.value_index = readU30();
|
||||
if (t1.value_index != 0) {
|
||||
t1.value_kind = read();
|
||||
}
|
||||
trait = t1;
|
||||
break;
|
||||
case 1: //method
|
||||
case 2: //getter
|
||||
case 3: //setter
|
||||
TraitMethodGetterSetter t2 = new TraitMethodGetterSetter();
|
||||
t2.disp_id = readU30();
|
||||
t2.method_info = readU30();
|
||||
trait = t2;
|
||||
break;
|
||||
case 4: //class
|
||||
TraitClass t3 = new TraitClass();
|
||||
t3.slot_id = readU30();
|
||||
t3.class_info = readU30();
|
||||
trait = t3;
|
||||
break;
|
||||
case 5: //function
|
||||
TraitFunction t4 = new TraitFunction();
|
||||
t4.slot_index = readU30();
|
||||
t4.method_info = readU30();
|
||||
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();
|
||||
trait.metadata = new int[metadata_count];
|
||||
for (int i = 0; i < metadata_count; i++) {
|
||||
trait.metadata[i] = readU30();
|
||||
}
|
||||
}
|
||||
trait.bytes = stopBuffer();
|
||||
return trait;
|
||||
}
|
||||
|
||||
public Traits readTraits() throws IOException {
|
||||
int count = readU30();
|
||||
Traits traits = new Traits();
|
||||
traits.traits = new Trait[count];
|
||||
for (int i = 0; i < count; i++) {
|
||||
traits.traits[i] = readTrait();
|
||||
}
|
||||
return traits;
|
||||
}
|
||||
|
||||
public byte[] readBytes(int count) throws IOException {
|
||||
byte ret[] = new byte[count];
|
||||
for (int i = 0; i < count; i++) {
|
||||
ret[i] = (byte) read();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public Decimal readDecimal() throws IOException {
|
||||
byte data[] = readBytes(16);
|
||||
return new Decimal(data);
|
||||
}
|
||||
|
||||
public InstanceInfo readInstanceInfo() throws IOException {
|
||||
InstanceInfo ret = new InstanceInfo();
|
||||
ret.name_index = readU30();
|
||||
ret.super_index = readU30();
|
||||
ret.flags = read();
|
||||
if ((ret.flags & CLASS_PROTECTED_NS) != 0) {
|
||||
ret.protectedNS = readU30();
|
||||
}
|
||||
int interfaces_count = readU30();
|
||||
ret.interfaces = new int[interfaces_count];
|
||||
for (int i = 0; i < interfaces_count; i++) {
|
||||
ret.interfaces[i] = readU30();
|
||||
}
|
||||
ret.iinit_index = readU30();
|
||||
ret.instance_traits = readTraits();
|
||||
return ret;
|
||||
}
|
||||
|
||||
public String readString() throws IOException {
|
||||
int length = readU30();
|
||||
return new String(safeRead(length), "utf8");
|
||||
}
|
||||
|
||||
|
||||
/*public void markStart(){
|
||||
bytesRead=0;
|
||||
}*/
|
||||
public long getPosition() {
|
||||
return bytesRead;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,271 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.types.*;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.*;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public class ABCOutputStream extends OutputStream {
|
||||
|
||||
private OutputStream os;
|
||||
|
||||
public ABCOutputStream(OutputStream os) {
|
||||
this.os = os;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(int b) throws IOException {
|
||||
os.write(b);
|
||||
}
|
||||
|
||||
public void writeU30(long value) throws IOException {
|
||||
writeS32(value);
|
||||
/*boolean loop = true;
|
||||
boolean underZero=value<0;
|
||||
|
||||
if(underZero){
|
||||
value = value & 0xFFFFFFFF;
|
||||
}else{
|
||||
value = value & 0x7FFFFFFF;
|
||||
}
|
||||
do {
|
||||
int ret = (int) (value & 0x7F);
|
||||
if (value < 0x80) {
|
||||
loop = false;
|
||||
}
|
||||
if (value > 0x7F) {
|
||||
ret += 0x80;
|
||||
}
|
||||
write(ret);
|
||||
value = value >> 7;
|
||||
} while (loop);
|
||||
*/
|
||||
}
|
||||
|
||||
public void writeU32(long value) throws IOException {
|
||||
boolean loop = true;
|
||||
value = value & 0xFFFFFFFF;
|
||||
do {
|
||||
int ret = (int) (value & 0x7F);
|
||||
if (value < 0x80) {
|
||||
loop = false;
|
||||
}
|
||||
if (value > 0x7F) {
|
||||
ret += 0x80;
|
||||
}
|
||||
write(ret);
|
||||
value = value >> 7;
|
||||
} while (loop);
|
||||
}
|
||||
|
||||
public void writeS24(long value) throws IOException {
|
||||
int ret = (int) (value & 0xff);
|
||||
write(ret);
|
||||
value = value >> 8;
|
||||
ret = (int) (value & 0xff);
|
||||
write(ret);
|
||||
value = value >> 8;
|
||||
ret = (int) (value & 0xff);
|
||||
write(ret);
|
||||
}
|
||||
|
||||
public void writeS32(long value) throws IOException {
|
||||
boolean belowZero = value < 0;
|
||||
/*if (belowZero) {
|
||||
value = -value;
|
||||
}*/
|
||||
int bitcount = 0;
|
||||
boolean loop = true;
|
||||
//value = value & 0xFFFFFFFF;
|
||||
do {
|
||||
bitcount += 7;
|
||||
int ret = (int) (value & 0x7F);
|
||||
if (value < 0x80) {
|
||||
if (belowZero) { //&& bitcount < 35
|
||||
ret += 0x80;
|
||||
} else {
|
||||
loop = false;
|
||||
}
|
||||
} else {
|
||||
ret += 0x80;
|
||||
}
|
||||
|
||||
if (bitcount == 35) {
|
||||
ret = ret & 0xf;
|
||||
}
|
||||
write(ret);
|
||||
if (bitcount == 35) {
|
||||
break;
|
||||
}
|
||||
value = value >> 7;
|
||||
} while (loop);
|
||||
}
|
||||
|
||||
public void writeLong(long value) throws IOException {
|
||||
byte writeBuffer[] = new byte[8];
|
||||
writeBuffer[7] = (byte) (value >>> 56);
|
||||
writeBuffer[6] = (byte) (value >>> 48);
|
||||
writeBuffer[5] = (byte) (value >>> 40);
|
||||
writeBuffer[4] = (byte) (value >>> 32);
|
||||
writeBuffer[3] = (byte) (value >>> 24);
|
||||
writeBuffer[2] = (byte) (value >>> 16);
|
||||
writeBuffer[1] = (byte) (value >>> 8);
|
||||
writeBuffer[0] = (byte) (value);
|
||||
write(writeBuffer);
|
||||
}
|
||||
|
||||
public void writeDouble(double value) throws IOException {
|
||||
writeLong(Double.doubleToLongBits(value));
|
||||
}
|
||||
|
||||
public void writeU8(int value) throws IOException {
|
||||
write(value);
|
||||
}
|
||||
|
||||
public void writeU16(int value) throws IOException {
|
||||
write(value & 0xff);
|
||||
write((value >> 8) & 0xff);
|
||||
}
|
||||
|
||||
public void writeString(String s) throws IOException {
|
||||
byte sbytes[] = s.getBytes("utf8");
|
||||
writeU30(sbytes.length);
|
||||
write(sbytes);
|
||||
}
|
||||
|
||||
public void writeNamespace(Namespace ns) throws IOException {
|
||||
write(ns.kind);
|
||||
for (int k = 0; k < Namespace.nameSpaceKinds.length; k++) {
|
||||
if (Namespace.nameSpaceKinds[k] == ns.kind) {
|
||||
writeU30(ns.name_index);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void writeMultiname(Multiname m) throws IOException {
|
||||
writeU8(m.kind);
|
||||
if ((m.kind == 7) || (m.kind == 0xd)) { // CONSTANT_QName and CONSTANT_QNameA.
|
||||
writeU30(m.namespace_index);
|
||||
writeU30(m.name_index);
|
||||
}
|
||||
if ((m.kind == 9) || (m.kind == 0xe)) { // CONSTANT_Multiname and CONSTANT_MultinameA.
|
||||
writeU30(m.name_index);
|
||||
writeU30(m.namespace_set_index);
|
||||
}
|
||||
if ((m.kind == 0xf) || (m.kind == 0x10)) { //CONSTANT_RTQName and CONSTANT_RTQNameA
|
||||
writeU30(m.name_index);
|
||||
}
|
||||
if ((m.kind == 0x1B) || (m.kind == 0x1C)) { //CONSTANT_MultinameL and CONSTANT_MultinameLA
|
||||
writeU30(m.namespace_set_index);
|
||||
}
|
||||
if (m.kind == 0x1D) {
|
||||
writeU30(m.qname_index);
|
||||
writeU30(m.params.size());
|
||||
for (int i = 0; i < m.params.size(); i++) {
|
||||
writeU30(m.params.get(i));
|
||||
}
|
||||
}
|
||||
//kind==0x11,0x12 nothing CONSTANT_RTQNameL and CONSTANT_RTQNameLA.
|
||||
}
|
||||
|
||||
public void writeMethodInfo(MethodInfo mi) throws IOException {
|
||||
writeU30(mi.param_types.length);
|
||||
writeU30(mi.ret_type);
|
||||
for (int i = 0; i < mi.param_types.length; i++) {
|
||||
writeU30(mi.param_types[i]);
|
||||
}
|
||||
writeU30(mi.name_index);
|
||||
write(mi.flags);
|
||||
if ((mi.flags & 8) == 8) {
|
||||
writeU30(mi.optional.length);
|
||||
for (int i = 0; i < mi.optional.length; i++) {
|
||||
writeU30(mi.optional[i].value_index);
|
||||
write(mi.optional[i].value_kind);
|
||||
}
|
||||
}
|
||||
|
||||
if ((mi.flags & 128) == 128) { //if has_paramnames
|
||||
for (int i = 0; i < mi.paramNames.length; i++) {
|
||||
writeU30(mi.paramNames[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void writeTrait(Trait t) throws IOException {
|
||||
writeU30(t.name_index);
|
||||
write((t.kindFlags << 4) + t.kindType);
|
||||
if (t instanceof TraitSlotConst) {
|
||||
TraitSlotConst t1 = (TraitSlotConst) t;
|
||||
writeU30(t1.slot_id);
|
||||
writeU30(t1.type_index);
|
||||
writeU30(t1.value_index);
|
||||
if (t1.value_index != 0) {
|
||||
write(t1.value_kind);
|
||||
}
|
||||
}
|
||||
if (t instanceof TraitMethodGetterSetter) {
|
||||
TraitMethodGetterSetter t2 = (TraitMethodGetterSetter) t;
|
||||
writeU30(t2.disp_id);
|
||||
writeU30(t2.method_info);
|
||||
}
|
||||
if (t instanceof TraitClass) {
|
||||
TraitClass t3 = (TraitClass) t;
|
||||
writeU30(t3.slot_id);
|
||||
writeU30(t3.class_info);
|
||||
}
|
||||
if (t instanceof TraitFunction) {
|
||||
TraitFunction t4 = (TraitFunction) t;
|
||||
writeU30(t4.slot_index);
|
||||
writeU30(t4.method_info);
|
||||
}
|
||||
if ((t.kindFlags & 4) == 4) {
|
||||
writeU30(t.metadata.length);
|
||||
for (int i = 0; i < t.metadata.length; i++) {
|
||||
writeU30(t.metadata[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void writeTraits(Traits t) throws IOException {
|
||||
writeU30(t.traits.length);
|
||||
for (int i = 0; i < t.traits.length; i++) {
|
||||
writeTrait(t.traits[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public void writeInstanceInfo(InstanceInfo ii) throws IOException {
|
||||
writeU30(ii.name_index);
|
||||
writeU30(ii.super_index);
|
||||
write(ii.flags);
|
||||
if ((ii.flags & 8) == 8) {
|
||||
writeU30(ii.protectedNS);
|
||||
}
|
||||
writeU30(ii.interfaces.length);
|
||||
for (int i = 0; i < ii.interfaces.length; i++) {
|
||||
writeU30(ii.interfaces[i]);
|
||||
}
|
||||
writeU30(ii.iinit_index);
|
||||
writeTraits(ii.instance_traits);
|
||||
}
|
||||
|
||||
public void writeDecimal(Decimal value) throws IOException {
|
||||
write(value.data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public class CopyOutputStream extends OutputStream {
|
||||
|
||||
private OutputStream os;
|
||||
private InputStream is;
|
||||
private long pos = 0;
|
||||
private int TEMPSIZE = 5;
|
||||
private int temp[] = new int[TEMPSIZE];
|
||||
private int tempPos = 0;
|
||||
public int ignoreFirst = 0;
|
||||
|
||||
public CopyOutputStream(OutputStream os, InputStream is) {
|
||||
this.os = os;
|
||||
this.is = is;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(int b) throws IOException {
|
||||
temp[tempPos] = b;
|
||||
tempPos = (tempPos + 1) % TEMPSIZE;
|
||||
|
||||
pos++;
|
||||
int r = is.read();
|
||||
if ((b & 0xff) != r) {
|
||||
if (ignoreFirst <= 0) {
|
||||
os.flush();
|
||||
|
||||
boolean output = true;
|
||||
|
||||
if (output) {
|
||||
System.out.print("Last written:");
|
||||
for (int i = 0; i < TEMPSIZE; i++) {
|
||||
System.out.print("" + Integer.toHexString(temp[(tempPos + i) % TEMPSIZE]) + " ");
|
||||
}
|
||||
System.out.println("");
|
||||
System.out.println("More expected:");
|
||||
for (int i = 0; i < TEMPSIZE; i++) {
|
||||
System.out.println("" + Integer.toHexString(is.read()));
|
||||
}
|
||||
|
||||
System.out.println("");
|
||||
System.out.println(Integer.toHexString(r) + " expected but " + Integer.toHexString(b) + " found");
|
||||
}
|
||||
throw new NotSameException(pos);
|
||||
} else {
|
||||
ignoreFirst--;
|
||||
}
|
||||
}
|
||||
os.write(b);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc;
|
||||
|
||||
import com.jpexs.decompiler.flash.helpers.Helper;
|
||||
|
||||
public class NotSameException extends RuntimeException {
|
||||
|
||||
public NotSameException(long pos) {
|
||||
super("Streams are not the same at pos " + Helper.formatHex((int) pos, 8));
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 2011-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class CodeStats {
|
||||
|
||||
public int maxstack = 0;
|
||||
public int maxscope = 0;
|
||||
public int maxlocal = 0;
|
||||
public boolean has_set_dxns = false;
|
||||
public boolean has_activation = false;
|
||||
public InstructionStats instructionStats[];
|
||||
|
||||
public String toString(ABC abc, List<String> fullyQualifiedNames) {
|
||||
String ret = "Stats: maxstack=" + maxstack + ", maxscope=" + maxscope + ", maxlocal=" + maxlocal + "\r\n";
|
||||
int i = 0;
|
||||
int ms = 0;
|
||||
for (InstructionStats stats : instructionStats) {
|
||||
int deltastack = stats.ins.definition.getStackDelta(stats.ins, abc);
|
||||
if (stats.stackpos > ms) {
|
||||
ms = stats.stackpos;
|
||||
}
|
||||
ret += "" + i + ":" + stats.stackpos + (deltastack >= 0 ? "+" + deltastack : deltastack) + "," + stats.scopepos + " " + stats.ins.toString(abc.constants, fullyQualifiedNames) + "\r\n";
|
||||
i++;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public CodeStats(AVM2Code code) {
|
||||
instructionStats = new InstructionStats[code.code.size()];
|
||||
for (int i = 0; i < code.code.size(); i++) {
|
||||
instructionStats[i] = new InstructionStats(code.code.get(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.types.Decimal;
|
||||
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 java.io.OutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class ConstantPool {
|
||||
|
||||
public long constant_int[];
|
||||
public long constant_uint[];
|
||||
public double constant_double[];
|
||||
/* Only for some minor versions */
|
||||
public Decimal constant_decimal[];
|
||||
public String constant_string[];
|
||||
public Namespace constant_namespace[];
|
||||
public NamespaceSet constant_namespace_set[];
|
||||
public Multiname constant_multiname[];
|
||||
|
||||
public int addInt(long value) {
|
||||
constant_int = Arrays.copyOf(constant_int, constant_int.length + 1);
|
||||
constant_int[constant_int.length - 1] = value;
|
||||
return constant_int.length - 1;
|
||||
}
|
||||
|
||||
public int addUInt(long value) {
|
||||
constant_uint = Arrays.copyOf(constant_uint, constant_uint.length + 1);
|
||||
constant_uint[constant_uint.length - 1] = value;
|
||||
return constant_uint.length - 1;
|
||||
}
|
||||
|
||||
public int addDouble(double value) {
|
||||
constant_double = Arrays.copyOf(constant_double, constant_double.length + 1);
|
||||
constant_double[constant_double.length - 1] = value;
|
||||
return constant_double.length - 1;
|
||||
}
|
||||
|
||||
public int addString(String value) {
|
||||
constant_string = Arrays.copyOf(constant_string, constant_string.length + 1);
|
||||
constant_string[constant_string.length - 1] = value;
|
||||
return constant_string.length - 1;
|
||||
}
|
||||
|
||||
public int getIntId(long value) {
|
||||
for (int i = 1; i < constant_int.length; i++) {
|
||||
if (constant_int[i] == value) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getUIntId(long value) {
|
||||
for (int i = 1; i < constant_uint.length; i++) {
|
||||
if (constant_uint[i] == value) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getDoubleId(double value) {
|
||||
for (int i = 1; i < constant_double.length; i++) {
|
||||
if (constant_double[i] == value) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getStringId(String s) {
|
||||
for (int i = 1; i < constant_string.length; i++) {
|
||||
if (constant_string[i].equals(s)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int forceGetStringId(String val) {
|
||||
int id = getStringId(val);
|
||||
if (id == 0) {
|
||||
id = addString(val);
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
public int forceGetIntId(long val) {
|
||||
int id = getIntId(val);
|
||||
if (id == 0) {
|
||||
id = addInt(val);
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
public int forceGetUIntId(long val) {
|
||||
int id = getUIntId(val);
|
||||
if (id == 0) {
|
||||
id = addUInt(val);
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
public int forceGetDoubleId(double val) {
|
||||
int id = getDoubleId(val);
|
||||
if (id == 0) {
|
||||
id = addDouble(val);
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
public void dump(OutputStream os) {
|
||||
PrintStream output = new PrintStream(os);
|
||||
String s = "";
|
||||
for (int i = 1; i < constant_int.length; i++) {
|
||||
output.println("INT[" + i + "]=" + constant_int[i]);
|
||||
}
|
||||
for (int i = 1; i < constant_uint.length; i++) {
|
||||
output.println("UINT[" + i + "]=" + constant_uint[i]);
|
||||
}
|
||||
for (int i = 1; i < constant_double.length; i++) {
|
||||
output.println("Double[" + i + "]=" + constant_double[i]);
|
||||
}
|
||||
for (int i = 1; i < constant_string.length; i++) {
|
||||
output.println("String[" + i + "]=" + constant_string[i]);
|
||||
}
|
||||
for (int i = 1; i < constant_namespace.length; i++) {
|
||||
output.println("Namespace[" + i + "]=" + constant_namespace[i].toString(this));
|
||||
}
|
||||
for (int i = 1; i < constant_namespace_set.length; i++) {
|
||||
output.println("NamespaceSet[" + i + "]=" + constant_namespace_set[i].toString(this));
|
||||
}
|
||||
|
||||
for (int i = 1; i < constant_multiname.length; i++) {
|
||||
output.println("Multiname[" + i + "]=" + constant_multiname[i].toString(this, new ArrayList<String>()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2;
|
||||
|
||||
public class ConvertException extends RuntimeException {
|
||||
|
||||
public int line;
|
||||
|
||||
public ConvertException(String s, int line) {
|
||||
super(s + " on line " + line);
|
||||
this.line = line;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.TreeItem;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class ConvertOutput {
|
||||
|
||||
public Stack<TreeItem> stack;
|
||||
public List<TreeItem> output;
|
||||
|
||||
public ConvertOutput(Stack<TreeItem> stack, List<TreeItem> output) {
|
||||
this.stack = stack;
|
||||
this.output = output;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (C) 2011-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class InstructionStats {
|
||||
|
||||
public boolean seen = false;
|
||||
public int stackpos = 0;
|
||||
public int scopepos = 0;
|
||||
public AVM2Instruction ins;
|
||||
|
||||
public InstructionStats(AVM2Instruction ins) {
|
||||
this.ins = ins;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2;
|
||||
|
||||
public class InvalidInstructionArguments extends RuntimeException {
|
||||
|
||||
public InvalidInstructionArguments() {
|
||||
super("Invalid method arguments");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Stack;
|
||||
|
||||
public class LocalDataArea {
|
||||
|
||||
public Stack operandStack = new Stack();
|
||||
public Stack scopeStack = new Stack();
|
||||
public HashMap localRegisters = new HashMap<Integer, Object>();
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2;
|
||||
|
||||
public class UnknownInstructionCode extends RuntimeException {
|
||||
|
||||
public int code;
|
||||
|
||||
public UnknownInstructionCode(int code) {
|
||||
super("Unknown instruction code: 0x" + Integer.toHexString(code));
|
||||
this.code = code;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.TreeItem;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class UnknownJumpException extends RuntimeException {
|
||||
|
||||
public Stack stack;
|
||||
public int ip;
|
||||
public List<TreeItem> output;
|
||||
|
||||
public UnknownJumpException(Stack stack, int ip, List<TreeItem> output) {
|
||||
this.stack = stack;
|
||||
this.ip = ip;
|
||||
this.output = output;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Unknown jump to " + ip;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,996 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.graph;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConvertException;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConvertOutput;
|
||||
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.jumps.IfFalseIns;
|
||||
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.GetLocalTypeIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.KillIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.LabelIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.ReturnValueIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.ReturnVoidIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.ThrowIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.*;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.BooleanTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.BreakTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.CommentTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.ContinueTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.FilteredCheckTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.HasNextTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.InTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.IntegerValueTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.LocalRegTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.NextNameTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.NextValueTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.NullTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.ReturnValueTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.ReturnVoidTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.SetLocalTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.SetPropertyTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.SetTypeTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.WithTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.clauses.DoWhileTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.clauses.ExceptionTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.clauses.FilterTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.clauses.ForEachInTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.clauses.ForInTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.clauses.ForTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.clauses.IfTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.clauses.SwitchTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.clauses.TernarOpTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.clauses.TryTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.clauses.WhileTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.operations.AndTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.operations.LogicalOp;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.operations.OrTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.ABCException;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodBody;
|
||||
import com.jpexs.decompiler.flash.graph.Graph;
|
||||
import com.jpexs.decompiler.flash.graph.GraphPart;
|
||||
import com.jpexs.decompiler.flash.graph.GraphPartMulti;
|
||||
import com.jpexs.decompiler.flash.graph.Loop;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class AVM2Graph extends Graph {
|
||||
|
||||
private AVM2Code code;
|
||||
private ABC abc;
|
||||
private MethodBody body;
|
||||
|
||||
public AVM2Graph(AVM2Code code, ABC abc, MethodBody body) {
|
||||
heads = makeGraph(code, new ArrayList<GraphPart>(), body);
|
||||
this.code = code;
|
||||
this.abc = abc;
|
||||
this.body = body;
|
||||
for (GraphPart head : heads) {
|
||||
fixGraph(head);
|
||||
makeMulti(head, new ArrayList<GraphPart>());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public GraphPart getNextNoJump(GraphPart part) {
|
||||
while (code.code.get(part.start).definition instanceof JumpIns) {
|
||||
part = part.getSubParts().get(0).nextParts.get(0);
|
||||
}
|
||||
return part;
|
||||
}
|
||||
|
||||
public static List<TreeItem> translateViaGraph(String path, AVM2Code code, ABC abc, MethodBody body) {
|
||||
AVM2Graph g = new AVM2Graph(code, abc, body);
|
||||
List<GraphPart> allParts = new ArrayList<GraphPart>();
|
||||
for (GraphPart head : g.heads) {
|
||||
populateParts(head, allParts);
|
||||
}
|
||||
return g.printGraph(path, new Stack<TreeItem>(), new Stack<TreeItem>(), allParts, new ArrayList<ABCException>(), new ArrayList<Integer>(), 0, null, g.heads.get(0), null, new ArrayList<Loop>(), new HashMap<Integer, TreeItem>(), body, new ArrayList<Integer>());
|
||||
}
|
||||
|
||||
private List<GraphPart> getLoopsContinues(List<Loop> loops) {
|
||||
List<GraphPart> ret = new ArrayList<GraphPart>();
|
||||
for (Loop l : loops) {
|
||||
if (l.loopContinue != null) {
|
||||
ret.add(l.loopContinue);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private TreeItem checkLoop(GraphPart part, GraphPart stopPart, List<Loop> loops) {
|
||||
if (part == stopPart) {
|
||||
return null;
|
||||
}
|
||||
for (Loop l : loops) {
|
||||
if (l.loopContinue == part) {
|
||||
return (new ContinueTreeItem(null, l.loopBreak == null ? -1 : l.loopBreak.start));
|
||||
}
|
||||
if (l.loopBreak == part) {
|
||||
return (new BreakTreeItem(null, part.start));
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
private boolean doDecompile = true;
|
||||
|
||||
private List<TreeItem> printGraph(String methodPath, Stack<TreeItem> stack, Stack<TreeItem> scopeStack, List<GraphPart> allParts, List<ABCException> parsedExceptions, List<Integer> finallyJumps, int level, GraphPart parent, GraphPart part, GraphPart stopPart, List<Loop> loops, HashMap<Integer, TreeItem> localRegs, MethodBody body, List<Integer> ignoredSwitches) {
|
||||
List<TreeItem> ret = new ArrayList<TreeItem>();
|
||||
if (level > 50) {
|
||||
//System.err.println(methodPath+": Level>50 :"+part);
|
||||
//new Exception().printStackTrace();
|
||||
//return ret;
|
||||
}
|
||||
boolean debugMode = false;
|
||||
|
||||
try {
|
||||
if (!doDecompile) {
|
||||
ret.add(new CommentTreeItem(null, "not decompiled"));
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (debugMode) {
|
||||
System.err.println("PART " + part);
|
||||
}
|
||||
|
||||
if (part == stopPart) {
|
||||
return ret;
|
||||
}
|
||||
if (part.ignored) {
|
||||
return ret;
|
||||
}
|
||||
List<String> fqn = new ArrayList<String>();
|
||||
HashMap<Integer, String> lrn = new HashMap<Integer, String>();
|
||||
List<TreeItem> output = new ArrayList<TreeItem>();
|
||||
boolean isSwitch = false;
|
||||
try {
|
||||
code.initToSource();
|
||||
List<GraphPart> parts = new ArrayList<GraphPart>();
|
||||
if (part instanceof GraphPartMulti) {
|
||||
parts = ((GraphPartMulti) part).parts;
|
||||
} else {
|
||||
parts.add(part);
|
||||
}
|
||||
boolean isIf = false;
|
||||
int end = part.end;
|
||||
for (GraphPart p : parts) {
|
||||
end = p.end;
|
||||
int start = p.start;
|
||||
isIf = false;
|
||||
if (code.code.get(end).definition instanceof JumpIns) {
|
||||
end--;
|
||||
} else if (code.code.get(end).definition instanceof IfTypeIns) {
|
||||
end--;
|
||||
isIf = true;
|
||||
} else if (code.code.get(end).definition instanceof LookupSwitchIns) {
|
||||
isSwitch = true;
|
||||
end--;
|
||||
}
|
||||
ConvertOutput co = code.toSourceOutput(false, false, 0, localRegs, stack, scopeStack, abc, abc.constants, abc.method_info, body, start, end, lrn, fqn, new boolean[code.code.size()]);
|
||||
output.addAll(co.output);
|
||||
|
||||
}
|
||||
if (isIf) {
|
||||
AVM2Instruction ins = code.code.get(end + 1);
|
||||
if ((stack.size() >= 2) && (ins.definition instanceof IfFalseIns) && (stack.get(stack.size() - 1) == stack.get(stack.size() - 2))) {
|
||||
ret.addAll(output);
|
||||
|
||||
GraphPart sp0 = getNextNoJump(part.nextParts.get(0));
|
||||
GraphPart sp1 = getNextNoJump(part.nextParts.get(1));
|
||||
boolean reversed = false;
|
||||
List<GraphPart> loopContinues = getLoopsContinues(loops);
|
||||
loopContinues.add(part);
|
||||
if (sp1.leadsTo(sp0, loopContinues)) {
|
||||
} else if (sp0.leadsTo(sp1, loopContinues)) {
|
||||
reversed = true;
|
||||
}
|
||||
|
||||
printGraph(methodPath, stack, scopeStack, allParts, parsedExceptions, finallyJumps, level + 1, parent, reversed ? sp0 : sp1, reversed ? sp1 : sp0, loops, localRegs, body, ignoredSwitches);
|
||||
TreeItem second = stack.pop();
|
||||
TreeItem first = stack.pop();
|
||||
if (reversed) {
|
||||
stack.push(new OrTreeItem(ins, first, second));
|
||||
} else {
|
||||
stack.push(new AndTreeItem(ins, first, second));
|
||||
}
|
||||
|
||||
ret.addAll(printGraph(methodPath, stack, scopeStack, allParts, parsedExceptions, finallyJumps, level + 1, parent, reversed ? sp1 : sp0, stopPart, loops, localRegs, body, ignoredSwitches));
|
||||
return ret;
|
||||
} else if ((stack.size() >= 2) && (ins.definition instanceof IfTrueIns) && (stack.get(stack.size() - 1) == stack.get(stack.size() - 2))) {
|
||||
ret.addAll(output);
|
||||
GraphPart sp0 = getNextNoJump(part.nextParts.get(0));
|
||||
GraphPart sp1 = getNextNoJump(part.nextParts.get(1));
|
||||
boolean reversed = false;
|
||||
List<GraphPart> loopContinues = getLoopsContinues(loops);
|
||||
loopContinues.add(part);
|
||||
if (sp1.leadsTo(sp0, loopContinues)) {
|
||||
} else if (sp0.leadsTo(sp1, loopContinues)) {
|
||||
reversed = true;
|
||||
}
|
||||
|
||||
printGraph(methodPath, stack, scopeStack, allParts, parsedExceptions, finallyJumps, level + 1, parent, reversed ? sp0 : sp1, reversed ? sp1 : sp0, loops, localRegs, body, ignoredSwitches);
|
||||
TreeItem second = stack.pop();
|
||||
TreeItem first = stack.pop();
|
||||
if (reversed) {
|
||||
stack.push(new AndTreeItem(ins, first, second));
|
||||
} else {
|
||||
stack.push(new OrTreeItem(ins, first, second));
|
||||
}
|
||||
ret.addAll(printGraph(methodPath, stack, scopeStack, allParts, parsedExceptions, finallyJumps, level + 1, parent, reversed ? sp1 : sp0, stopPart, loops, localRegs, body, ignoredSwitches));
|
||||
return ret;
|
||||
} else if ((((ins.definition instanceof IfStrictNeIns)) && ((part.nextParts.get(1).getHeight() == 2) && (code.code.get(part.nextParts.get(1).start).definition instanceof PushByteIns) && (code.code.get(part.nextParts.get(1).nextParts.get(0).end).definition instanceof LookupSwitchIns)))
|
||||
|| (((ins.definition instanceof IfStrictEqIns)) && ((part.nextParts.get(0).getHeight() == 2) && (code.code.get(part.nextParts.get(0).start).definition instanceof PushByteIns) && (code.code.get(part.nextParts.get(0).nextParts.get(0).end).definition instanceof LookupSwitchIns)))) {
|
||||
ret.addAll(output);
|
||||
boolean reversed = false;
|
||||
if (ins.definition instanceof IfStrictEqIns) {
|
||||
reversed = true;
|
||||
}
|
||||
TreeItem switchedObject = null;
|
||||
if (!output.isEmpty()) {
|
||||
if (output.get(output.size() - 1) instanceof SetLocalTreeItem) {
|
||||
switchedObject = ((SetLocalTreeItem) output.get(output.size() - 1)).value;
|
||||
}
|
||||
}
|
||||
if (switchedObject == null) {
|
||||
switchedObject = new NullTreeItem(null);
|
||||
}
|
||||
HashMap<Integer, TreeItem> caseValuesMap = new HashMap<Integer, TreeItem>();
|
||||
|
||||
stack.pop();
|
||||
caseValuesMap.put(code.code.get(part.nextParts.get(reversed ? 0 : 1).start).operands[0], stack.pop());
|
||||
|
||||
GraphPart switchLoc = part.nextParts.get(reversed ? 0 : 1).nextParts.get(0);
|
||||
|
||||
|
||||
while ((code.code.get(part.nextParts.get(reversed ? 1 : 0).end).definition instanceof IfStrictNeIns)
|
||||
|| (code.code.get(part.nextParts.get(reversed ? 1 : 0).end).definition instanceof IfStrictEqIns)) {
|
||||
part = part.nextParts.get(reversed ? 1 : 0);
|
||||
List<GraphPart> ps = part.getSubParts();
|
||||
for (GraphPart p : ps) {
|
||||
code.toSourceOutput(false, false, 0, localRegs, stack, scopeStack, abc, abc.constants, abc.method_info, body, p.start, p.end - 1, lrn, fqn, new boolean[code.code.size()]);
|
||||
}
|
||||
stack.pop();
|
||||
if (code.code.get(part.end).definition instanceof IfStrictNeIns) {
|
||||
reversed = false;
|
||||
} else {
|
||||
reversed = true;
|
||||
}
|
||||
caseValuesMap.put(code.code.get(part.nextParts.get(reversed ? 0 : 1).start).operands[0], stack.pop());
|
||||
|
||||
}
|
||||
boolean hasDefault = false;
|
||||
GraphPart dp = part.nextParts.get(reversed ? 1 : 0);
|
||||
while (code.code.get(dp.start).definition instanceof JumpIns) {
|
||||
if (dp instanceof GraphPartMulti) {
|
||||
dp = ((GraphPartMulti) dp).parts.get(0);
|
||||
}
|
||||
dp = dp.nextParts.get(0);
|
||||
}
|
||||
if (code.code.get(dp.start).definition instanceof PushByteIns) {
|
||||
hasDefault = true;
|
||||
}
|
||||
List<TreeItem> caseValues = new ArrayList<TreeItem>();
|
||||
for (int i = 0; i < switchLoc.nextParts.size() - 1; i++) {
|
||||
if (caseValuesMap.containsKey(i)) {
|
||||
caseValues.add(caseValuesMap.get(i));
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
List<List<TreeItem>> caseCommands = new ArrayList<List<TreeItem>>();
|
||||
GraphPart next = null;
|
||||
|
||||
List<GraphPart> loopContinues = getLoopsContinues(loops);
|
||||
|
||||
next = switchLoc.getNextPartPath(loopContinues);
|
||||
if (next == null) {
|
||||
next = switchLoc.getNextSuperPartPath(loopContinues);
|
||||
}
|
||||
/*for (GraphPart p : allParts) {
|
||||
if (p.start == switchLoc.end + 1) {
|
||||
next = p;
|
||||
break;
|
||||
}
|
||||
}*/
|
||||
|
||||
TreeItem ti = checkLoop(next, stopPart, loops);
|
||||
Loop currentLoop = new Loop(null, next);
|
||||
loops.add(currentLoop);
|
||||
//switchLoc.getNextPartPath(new ArrayList<GraphPart>());
|
||||
List<Integer> valuesMapping = new ArrayList<Integer>();
|
||||
List<GraphPart> caseBodies = new ArrayList<GraphPart>();
|
||||
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<TreeItem> defaultCommands = new ArrayList<TreeItem>();
|
||||
GraphPart defaultPart = null;
|
||||
if (hasDefault) {
|
||||
defaultPart = switchLoc.nextParts.get(switchLoc.nextParts.size() - 1);
|
||||
defaultCommands = printGraph(methodPath, stack, scopeStack, allParts, parsedExceptions, finallyJumps, level + 1, switchLoc, defaultPart, next, loops, localRegs, body, ignoredSwitches);
|
||||
}
|
||||
|
||||
List<GraphPart> ignored = new ArrayList<GraphPart>();
|
||||
for (Loop l : loops) {
|
||||
ignored.add(l.loopContinue);
|
||||
}
|
||||
|
||||
for (int i = 0; i < caseBodies.size(); i++) {
|
||||
List<TreeItem> cc = new ArrayList<TreeItem>();
|
||||
GraphPart nextCase = null;
|
||||
nextCase = next;
|
||||
if (next != null) {
|
||||
if (i < caseBodies.size() - 1) {
|
||||
if (!caseBodies.get(i).leadsTo(caseBodies.get(i + 1), ignored)) {
|
||||
cc.add(new BreakTreeItem(null, next.start));
|
||||
} else {
|
||||
nextCase = caseBodies.get(i + 1);
|
||||
}
|
||||
} else if (hasDefault) {
|
||||
if (!caseBodies.get(i).leadsTo(defaultPart, ignored)) {
|
||||
cc.add(new BreakTreeItem(null, next.start));
|
||||
} else {
|
||||
nextCase = defaultPart;
|
||||
}
|
||||
}
|
||||
}
|
||||
cc.addAll(0, printGraph(methodPath, stack, scopeStack, allParts, parsedExceptions, finallyJumps, level + 1, switchLoc, caseBodies.get(i), nextCase, loops, localRegs, body, ignoredSwitches));
|
||||
caseCommands.add(cc);
|
||||
}
|
||||
|
||||
SwitchTreeItem sti = new SwitchTreeItem(null, next == null ? -1 : next.start, switchedObject, caseValues, caseCommands, defaultCommands, valuesMapping);
|
||||
ret.add(sti);
|
||||
loops.remove(currentLoop);
|
||||
if (next != null) {
|
||||
if (ti != null) {
|
||||
ret.add(ti);
|
||||
} else {
|
||||
ret.addAll(printGraph(methodPath, stack, scopeStack, allParts, parsedExceptions, finallyJumps, level + 1, null, next, stopPart, loops, localRegs, body, ignoredSwitches));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
} else {
|
||||
try {
|
||||
ins.definition.translate(false, 0, new HashMap<Integer, TreeItem>(), stack, new Stack<TreeItem>(), abc.constants, ins, abc.method_info, output, body, abc, lrn, fqn);
|
||||
} catch (Exception ex) {
|
||||
System.err.println("ip:" + (end + 1));
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
//((IfTypeIns)ins.definition).translateInverted(new HashMap<Integer,TreeItem>(), co.stack, ins);
|
||||
}
|
||||
} catch (ConvertException ex) {
|
||||
Logger.getLogger(AVM2Graph.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
|
||||
int ip = part.start;
|
||||
int addr = code.fixAddrAfterDebugLine(code.pos2adr(part.start));
|
||||
int maxend = -1;
|
||||
List<ABCException> catchedExceptions = new ArrayList<ABCException>();
|
||||
for (int e = 0; e < body.exceptions.length; e++) {
|
||||
if (addr == code.fixAddrAfterDebugLine(body.exceptions[e].start)) {
|
||||
if (!body.exceptions[e].isFinally()) {
|
||||
if (((body.exceptions[e].end) > maxend) && (!parsedExceptions.contains(body.exceptions[e]))) {
|
||||
catchedExceptions.clear();
|
||||
maxend = code.fixAddrAfterDebugLine(body.exceptions[e].end);
|
||||
catchedExceptions.add(body.exceptions[e]);
|
||||
} else if (code.fixAddrAfterDebugLine(body.exceptions[e].end) == maxend) {
|
||||
catchedExceptions.add(body.exceptions[e]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (catchedExceptions.size() > 0) {
|
||||
parsedExceptions.addAll(catchedExceptions);
|
||||
int endpos = code.adr2pos(code.fixAddrAfterDebugLine(catchedExceptions.get(0).end));
|
||||
int endposStartBlock = code.adr2pos(catchedExceptions.get(0).end);
|
||||
|
||||
|
||||
List<List<TreeItem>> catchedCommands = new ArrayList<List<TreeItem>>();
|
||||
if (code.code.get(endpos).definition instanceof JumpIns) {
|
||||
int afterCatchAddr = code.pos2adr(endpos + 1) + code.code.get(endpos).operands[0];
|
||||
int afterCatchPos = code.adr2pos(afterCatchAddr);
|
||||
Collections.sort(catchedExceptions, new Comparator<ABCException>() {
|
||||
public int compare(ABCException o1, ABCException o2) {
|
||||
try {
|
||||
return code.fixAddrAfterDebugLine(o1.target) - code.fixAddrAfterDebugLine(o2.target);
|
||||
} catch (ConvertException ex) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
List<TreeItem> finallyCommands = new ArrayList<TreeItem>();
|
||||
int returnPos = afterCatchPos;
|
||||
for (int e = 0; e < body.exceptions.length; e++) {
|
||||
if (body.exceptions[e].isFinally()) {
|
||||
if (addr == code.fixAddrAfterDebugLine(body.exceptions[e].start)) {
|
||||
if (afterCatchPos + 1 == code.adr2pos(code.fixAddrAfterDebugLine(body.exceptions[e].end))) {
|
||||
AVM2Instruction jmpIns = code.code.get(code.adr2pos(code.fixAddrAfterDebugLine(body.exceptions[e].end)));
|
||||
if (jmpIns.definition instanceof JumpIns) {
|
||||
int finStart = code.adr2pos(code.fixAddrAfterDebugLine(body.exceptions[e].end) + jmpIns.getBytes().length + jmpIns.operands[0]);
|
||||
finallyJumps.add(finStart);
|
||||
/*if (unknownJumps.contains(finStart)) {
|
||||
unknownJumps.remove((Integer) finStart);
|
||||
}*/
|
||||
for (int f = finStart; f < code.code.size(); f++) {
|
||||
if (code.code.get(f).definition instanceof LookupSwitchIns) {
|
||||
AVM2Instruction swins = code.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) {
|
||||
GraphPart fpart = null;
|
||||
for (GraphPart p : allParts) {
|
||||
if (p.start == finStart) {
|
||||
fpart = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
stack.push(new ExceptionTreeItem(body.exceptions[e]));
|
||||
GraphPart fepart = null;
|
||||
for (GraphPart p : allParts) {
|
||||
if (p.start == f + 1) {
|
||||
fepart = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
//code.code.get(f).ignored = true;
|
||||
ignoredSwitches.add(f);
|
||||
finallyCommands = printGraph(methodPath, stack, scopeStack, allParts, parsedExceptions, finallyJumps, level + 1, parent, fpart, fepart, loops, localRegs, body, ignoredSwitches);
|
||||
returnPos = f + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int e = 0; e < catchedExceptions.size(); e++) {
|
||||
int eendpos;
|
||||
if (e < catchedExceptions.size() - 1) {
|
||||
eendpos = code.adr2pos(code.fixAddrAfterDebugLine(catchedExceptions.get(e + 1).target)) - 2;
|
||||
} else {
|
||||
eendpos = afterCatchPos - 1;
|
||||
}
|
||||
Stack<TreeItem> substack = new Stack<TreeItem>();
|
||||
substack.add(new ExceptionTreeItem(catchedExceptions.get(e)));
|
||||
|
||||
GraphPart npart = null;
|
||||
int findpos = code.adr2pos(code.fixAddrAfterDebugLine(catchedExceptions.get(e).target));
|
||||
for (GraphPart p : allParts) {
|
||||
if (p.start == findpos) {
|
||||
npart = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
GraphPart nepart = null;
|
||||
for (GraphPart p : allParts) {
|
||||
if (p.start == eendpos + 1) {
|
||||
nepart = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
stack.add(new ExceptionTreeItem(catchedExceptions.get(e)));
|
||||
catchedCommands.add(printGraph(methodPath, stack, scopeStack, allParts, parsedExceptions, finallyJumps, level + 1, parent, npart, nepart, loops, localRegs, body, ignoredSwitches));
|
||||
}
|
||||
|
||||
GraphPart nepart = null;
|
||||
|
||||
for (GraphPart p : allParts) {
|
||||
if (p.start == endposStartBlock) {
|
||||
nepart = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
List<TreeItem> tryCommands = printGraph(methodPath, stack, scopeStack, allParts, parsedExceptions, finallyJumps, level + 1, parent, part, nepart, loops, localRegs, body, ignoredSwitches);
|
||||
|
||||
output.clear();
|
||||
output.add(new TryTreeItem(tryCommands, catchedExceptions, catchedCommands, finallyCommands));
|
||||
ip = returnPos;
|
||||
addr = code.pos2adr(ip);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (ip != part.start) {
|
||||
part = null;
|
||||
for (GraphPart p : allParts) {
|
||||
List<GraphPart> ps = p.getSubParts();
|
||||
for (GraphPart p2 : ps) {
|
||||
if (p2.start == ip) {
|
||||
part = p2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
ret.addAll(output);
|
||||
TreeItem lop = checkLoop(part, stopPart, loops);
|
||||
if (lop == null) {
|
||||
ret.addAll(printGraph(methodPath, stack, scopeStack, allParts, parsedExceptions, finallyJumps, level + 1, null, part, stopPart, loops, localRegs, body, ignoredSwitches));
|
||||
} else {
|
||||
ret.add(lop);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
List<GraphPart> loopContinues = new ArrayList<GraphPart>();
|
||||
for (Loop l : loops) {
|
||||
if (l.loopContinue != null) {
|
||||
loopContinues.add(l.loopContinue);
|
||||
}
|
||||
}
|
||||
boolean loop = false;
|
||||
boolean reversed = false;
|
||||
if ((!part.nextParts.isEmpty()) && part.nextParts.get(0).leadsTo(part, loopContinues)) {
|
||||
loop = true;
|
||||
} else if ((part.nextParts.size() > 1) && part.nextParts.get(1).leadsTo(part, loopContinues)) {
|
||||
loop = true;
|
||||
reversed = true;
|
||||
}
|
||||
if (((part.nextParts.size() == 2) || ((part.nextParts.size() == 1) && loop)) && (!isSwitch)) {
|
||||
|
||||
boolean doWhile = loop;
|
||||
if (loop && output.isEmpty()) {
|
||||
doWhile = false;
|
||||
}
|
||||
Loop currentLoop = new Loop(part, null);
|
||||
if (loop) {
|
||||
loops.add(currentLoop);
|
||||
}
|
||||
|
||||
loopContinues = new ArrayList<GraphPart>();
|
||||
for (Loop l : loops) {
|
||||
if (l.loopContinue != null) {
|
||||
loopContinues.add(l.loopContinue);
|
||||
}
|
||||
}
|
||||
|
||||
if (part.nextParts.size() > 1) {
|
||||
currentLoop.loopBreak = part.nextParts.get(reversed ? 0 : 1);
|
||||
}
|
||||
|
||||
int breakIp = -1;
|
||||
if (currentLoop.loopBreak != null) {
|
||||
breakIp = currentLoop.loopBreak.start;
|
||||
}
|
||||
TreeItem expr = null;
|
||||
if ((code.code.get(part.end).definition instanceof JumpIns) || (!(code.code.get(part.end).definition instanceof IfTypeIns))) {
|
||||
expr = new BooleanTreeItem(null, true);
|
||||
} else {
|
||||
if (stack.isEmpty()) {
|
||||
}
|
||||
expr = stack.pop();
|
||||
}
|
||||
if (doWhile) {
|
||||
ret.add(new DoWhileTreeItem(null, breakIp, part.start, output, expr));
|
||||
} else {
|
||||
ret.addAll(output);
|
||||
}
|
||||
|
||||
GraphPart next = part.getNextPartPath(loopContinues);
|
||||
if (expr instanceof LogicalOp) {
|
||||
expr = ((LogicalOp) expr).invert();
|
||||
}
|
||||
if (loop && (!doWhile)) {
|
||||
List<TreeItem> loopBody = null;
|
||||
List<TreeItem> finalCommands = null;
|
||||
GraphPart finalPart = null;
|
||||
boolean isFor = false;
|
||||
try {
|
||||
loopBody = printGraph(methodPath, stack, scopeStack, allParts, parsedExceptions, finallyJumps, level + 1, part, part.nextParts.get(reversed ? 1 : 0), stopPart, loops, localRegs, body, ignoredSwitches);
|
||||
} catch (ForException fex) {
|
||||
loopBody = fex.output;
|
||||
finalCommands = fex.finalOutput;
|
||||
if (!finalCommands.isEmpty()) {
|
||||
finalCommands.remove(finalCommands.size() - 1); //remove continue
|
||||
}
|
||||
finalPart = fex.continuePart;
|
||||
isFor = true;
|
||||
for (Object o : finalPart.forContinues) {
|
||||
if (o instanceof ContinueTreeItem) {
|
||||
((ContinueTreeItem) o).loopPos = breakIp;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isFor) {
|
||||
ret.add(new ForTreeItem(null, breakIp, finalPart.start, new ArrayList<TreeItem>(), expr, finalCommands, loopBody));
|
||||
} else if ((expr instanceof HasNextTreeItem) && ((HasNextTreeItem) expr).collection.getNotCoerced().getThroughRegister() instanceof FilteredCheckTreeItem) {
|
||||
TreeItem gti = ((HasNextTreeItem) expr).collection.getNotCoerced().getThroughRegister();
|
||||
boolean found = false;
|
||||
if ((loopBody.size() == 3) || (loopBody.size() == 4)) {
|
||||
TreeItem ft = loopBody.get(0);
|
||||
if (ft instanceof WithTreeItem) {
|
||||
ft = loopBody.get(1);
|
||||
if (ft instanceof IfTreeItem) {
|
||||
IfTreeItem ift = (IfTreeItem) ft;
|
||||
if (ift.onTrue.size() > 0) {
|
||||
ft = ift.onTrue.get(0);
|
||||
if (ft instanceof SetPropertyTreeItem) {
|
||||
SetPropertyTreeItem spt = (SetPropertyTreeItem) ft;
|
||||
if (spt.object instanceof LocalRegTreeItem) {
|
||||
int regIndex = ((LocalRegTreeItem) spt.object).regIndex;
|
||||
HasNextTreeItem iti = (HasNextTreeItem) expr;
|
||||
localRegs.put(regIndex, new FilterTreeItem(null, iti.collection.getThroughRegister(), ift.expression));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if ((expr instanceof HasNextTreeItem) && (!loopBody.isEmpty()) && (loopBody.get(0) instanceof SetTypeTreeItem) && (((SetTypeTreeItem) loopBody.get(0)).getValue().getNotCoerced() instanceof NextValueTreeItem)) {
|
||||
TreeItem obj = ((SetTypeTreeItem) loopBody.get(0)).getObject();
|
||||
loopBody.remove(0);
|
||||
ret.add(new ForEachInTreeItem(null, breakIp, part.start, new InTreeItem(expr.instruction, obj, ((HasNextTreeItem) expr).collection), loopBody));
|
||||
} else if ((expr instanceof HasNextTreeItem) && (!loopBody.isEmpty()) && (loopBody.get(0) instanceof SetTypeTreeItem) && (((SetTypeTreeItem) loopBody.get(0)).getValue().getNotCoerced() instanceof NextNameTreeItem)) {
|
||||
TreeItem obj = ((SetTypeTreeItem) loopBody.get(0)).getObject();
|
||||
loopBody.remove(0);
|
||||
ret.add(new ForInTreeItem(null, breakIp, part.start, new InTreeItem(expr.instruction, obj, ((HasNextTreeItem) expr).collection), loopBody));
|
||||
} else {
|
||||
ret.add(new WhileTreeItem(null, breakIp, part.start, expr, loopBody));
|
||||
}
|
||||
} else if (!loop) {
|
||||
int stackSizeBefore = stack.size();
|
||||
Stack<TreeItem> trueStack = (Stack<TreeItem>) stack.clone();
|
||||
Stack<TreeItem> falseStack = (Stack<TreeItem>) stack.clone();
|
||||
TreeItem lopTrue = checkLoop(part.nextParts.get(1), stopPart, loops);
|
||||
TreeItem lopFalse = null;
|
||||
if (next != part.nextParts.get(0)) {
|
||||
lopFalse = checkLoop(part.nextParts.get(0), stopPart, loops);
|
||||
}
|
||||
List<TreeItem> onTrue = new ArrayList<TreeItem>();
|
||||
if (lopTrue != null) {
|
||||
onTrue.add(lopTrue);
|
||||
} else {
|
||||
if (debugMode) {
|
||||
System.err.println("ONTRUE: (inside " + part + ")");
|
||||
}
|
||||
onTrue = printGraph(methodPath, trueStack, scopeStack, allParts, parsedExceptions, finallyJumps, level + 1, part, part.nextParts.get(1), next == null ? stopPart : next, loops, localRegs, body, ignoredSwitches);
|
||||
if (debugMode) {
|
||||
System.err.println("/ONTRUE (inside " + part + ")");
|
||||
}
|
||||
}
|
||||
List<TreeItem> onFalse = new ArrayList<TreeItem>();
|
||||
if (lopFalse != null) {
|
||||
onFalse.add(lopFalse);
|
||||
} else {
|
||||
if (debugMode) {
|
||||
System.err.println("ONFALSE: (inside " + part + ")");
|
||||
}
|
||||
onFalse = (((next == part.nextParts.get(0)) || (part.nextParts.get(0).path.equals(part.path) || part.nextParts.get(0).path.length() < part.path.length())) ? new ArrayList<TreeItem>() : printGraph(methodPath, falseStack, scopeStack, allParts, parsedExceptions, finallyJumps, level + 1, part, part.nextParts.get(0), next == null ? stopPart : next, loops, localRegs, body, ignoredSwitches));
|
||||
if (debugMode) {
|
||||
System.err.println("/ONFALSE (inside " + part + ")");
|
||||
}
|
||||
}
|
||||
|
||||
if (onTrue.isEmpty() && onFalse.isEmpty() && (trueStack.size() > stackSizeBefore) && (falseStack.size() > stackSizeBefore)) {
|
||||
stack.push(new TernarOpTreeItem(null, expr, trueStack.pop(), falseStack.pop()));
|
||||
} else {
|
||||
ret.add(new IfTreeItem(null, expr, onTrue, onFalse));
|
||||
|
||||
//Same continues in onTrue and onFalse gets continue on parent level
|
||||
if ((!onTrue.isEmpty()) && (!onFalse.isEmpty())) {
|
||||
if (onTrue.get(onTrue.size() - 1) instanceof ContinueTreeItem) {
|
||||
if (onFalse.get(onFalse.size() - 1) instanceof ContinueTreeItem) {
|
||||
if (((ContinueTreeItem) onTrue.get(onTrue.size() - 1)).loopPos == ((ContinueTreeItem) onFalse.get(onFalse.size() - 1)).loopPos) {
|
||||
onTrue.remove(onTrue.size() - 1);
|
||||
ret.add(onFalse.remove(onFalse.size() - 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (loop && (part.nextParts.size() > 1)) {
|
||||
loops.remove(currentLoop); //remove loop so no break shows up
|
||||
//ret.addAll(printGraph(methodPath, stack, scopeStack, allParts, parsedExceptions, finallyJumps, level, part, part.nextParts.get(reversed ? 0 : 1), stopPart, loops, localRegs, body, ignoredSwitches));
|
||||
next = part.nextParts.get(reversed ? 0 : 1);
|
||||
}
|
||||
|
||||
if (next != null) {
|
||||
boolean finallyJump = false;
|
||||
for (int f : finallyJumps) {
|
||||
if (next.start == f) {
|
||||
finallyJump = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!finallyJump) {
|
||||
TreeItem ti = checkLoop(next, stopPart, loops);
|
||||
if (ti != null) {
|
||||
ret.add(ti);
|
||||
} else {
|
||||
if (debugMode) {
|
||||
System.err.println("NEXT: (inside " + part + ")");
|
||||
}
|
||||
ret.addAll(printGraph(methodPath, stack, scopeStack, allParts, parsedExceptions, finallyJumps, level, part, next, stopPart, loops, localRegs, body, ignoredSwitches));
|
||||
if (debugMode) {
|
||||
System.err.println("/NEXT: (inside " + part + ")");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ret.addAll(output);
|
||||
}
|
||||
onepart:
|
||||
if (part.nextParts.size() == 1 && (!loop)) {
|
||||
if (part.end - part.start > 4) {
|
||||
if (code.code.get(part.end).definition instanceof PopIns) {
|
||||
if (code.code.get(part.end - 1).definition instanceof LabelIns) {
|
||||
if (code.code.get(part.end - 2).definition instanceof PushByteIns) {
|
||||
|
||||
//if (code.code.get(part.end - 3).definition instanceof SetLocalTypeIns) {
|
||||
if (part.nextParts.size() == 1) {
|
||||
GraphPart sec = part.nextParts.get(0);
|
||||
|
||||
if (code.code.get(sec.end).definition instanceof ReturnValueIns) {
|
||||
if (sec.end - sec.start >= 3) {
|
||||
if (code.code.get(sec.end - 1).definition instanceof KillIns) {
|
||||
if (code.code.get(sec.end - 2).definition instanceof GetLocalTypeIns) {
|
||||
if (!output.isEmpty()) {
|
||||
if (output.get(output.size() - 1) instanceof SetLocalTreeItem) {
|
||||
sec.ignored = true;
|
||||
ret.add(new ReturnValueTreeItem(code.code.get(sec.end), ((SetLocalTreeItem) output.get(output.size() - 1)).value));
|
||||
break onepart;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else if (code.code.get(sec.end).definition instanceof ReturnVoidIns) {
|
||||
ret.add(new ReturnVoidTreeItem(code.code.get(sec.end)));
|
||||
break onepart;
|
||||
}
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int f : finallyJumps) {
|
||||
if (part.nextParts.get(0).start == f) {
|
||||
if ((!output.isEmpty()) && (output.get(output.size() - 1) instanceof SetLocalTreeItem)) {
|
||||
ret.add(new ReturnValueTreeItem(null, ((SetLocalTreeItem) output.get(output.size() - 1)).value));
|
||||
} else {
|
||||
ret.add(new ReturnVoidTreeItem(null));
|
||||
}
|
||||
|
||||
break onepart;
|
||||
}
|
||||
}
|
||||
|
||||
GraphPart p = part.nextParts.get(0);
|
||||
TreeItem lop = checkLoop(p, stopPart, loops);
|
||||
if (lop == null) {
|
||||
if (p.path.length() == part.path.length()) {
|
||||
ret.addAll(printGraph(methodPath, stack, scopeStack, allParts, parsedExceptions, finallyJumps, level + 1, part, p, stopPart, loops, localRegs, body, ignoredSwitches));
|
||||
} else {
|
||||
if ((p != stopPart) && (p.refs.size() > 1)) {
|
||||
ContinueTreeItem cti = new ContinueTreeItem(null, -1);
|
||||
//p.forContinues.add(cti);
|
||||
ret.add(new CommentTreeItem(null, "Unknown jump"));
|
||||
ret.add(cti);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ret.add(lop);
|
||||
}
|
||||
//}
|
||||
//ret += (strOfChars(level, TAB) + "continue;\r\n");
|
||||
//}
|
||||
}
|
||||
if (isSwitch && (!ignoredSwitches.contains(part.end))) {
|
||||
//ret.add(new CommentTreeItem(code.code.get(part.end), "Switch not supported"));
|
||||
TreeItem switchedObject = stack.pop();
|
||||
List<TreeItem> caseValues = new ArrayList<TreeItem>();
|
||||
List<Integer> valueMappings = new ArrayList<Integer>();
|
||||
List<List<TreeItem>> caseCommands = new ArrayList<List<TreeItem>>();
|
||||
|
||||
GraphPart next = part.getNextPartPath(loopContinues);
|
||||
int breakPos = -1;
|
||||
if (next != null) {
|
||||
breakPos = next.start;
|
||||
}
|
||||
List<TreeItem> defaultCommands = printGraph(methodPath, stack, scopeStack, allParts, parsedExceptions, finallyJumps, level + 1, part, part.nextParts.get(0), stopPart, loops, localRegs, body, ignoredSwitches);
|
||||
|
||||
for (int i = 0; i < part.nextParts.size() - 1; i++) {
|
||||
caseValues.add(new IntegerValueTreeItem(null, (Long) (long) i));
|
||||
valueMappings.add(i);
|
||||
GraphPart nextCase = next;
|
||||
List<TreeItem> caseBody = new ArrayList<TreeItem>();
|
||||
if (i < part.nextParts.size() - 1 - 1) {
|
||||
if (!part.nextParts.get(1 + i).leadsTo(part.nextParts.get(1 + i + 1), new ArrayList<GraphPart>())) {
|
||||
caseBody.add(new BreakTreeItem(null, breakPos));
|
||||
} else {
|
||||
nextCase = part.nextParts.get(1 + i + 1);
|
||||
}
|
||||
} else if (!part.nextParts.get(1 + i).leadsTo(part.nextParts.get(0), new ArrayList<GraphPart>())) {
|
||||
caseBody.add(new BreakTreeItem(null, breakPos));
|
||||
} else {
|
||||
nextCase = part.nextParts.get(0);
|
||||
}
|
||||
caseBody.addAll(0, printGraph(methodPath, stack, scopeStack, allParts, parsedExceptions, finallyJumps, level + 1, part, part.nextParts.get(1 + i), nextCase, loops, localRegs, body, ignoredSwitches));
|
||||
caseCommands.add(caseBody);
|
||||
}
|
||||
|
||||
SwitchTreeItem swt = new SwitchTreeItem(null, breakPos, switchedObject, caseValues, caseCommands, defaultCommands, valueMappings);
|
||||
ret.add(swt);
|
||||
|
||||
TreeItem lopNext = checkLoop(next, stopPart, loops);
|
||||
if (lopNext != null) {
|
||||
ret.add(lopNext);
|
||||
} else {
|
||||
ret.addAll(printGraph(methodPath, stack, scopeStack, allParts, parsedExceptions, finallyJumps, level + 1, part, next, stopPart, loops, localRegs, body, ignoredSwitches));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} catch (ForException fex) {
|
||||
ret.addAll(fex.output);
|
||||
fex.output = ret;
|
||||
throw fex;
|
||||
}
|
||||
code.clearTemporaryRegisters(ret);
|
||||
if (!part.forContinues.isEmpty()) {
|
||||
throw new ForException(new ArrayList<TreeItem>(), ret, part);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private List<GraphPart> makeGraph(AVM2Code code, List<GraphPart> allBlocks, MethodBody body) {
|
||||
HashMap<Integer, List<Integer>> refs = code.visitCode(body);
|
||||
List<GraphPart> ret = new ArrayList<GraphPart>();
|
||||
boolean visited[] = new boolean[code.code.size()];
|
||||
ret.add(makeGraph(null, "0", code, 0, 0, allBlocks, refs, visited));
|
||||
for (ABCException ex : body.exceptions) {
|
||||
GraphPart e1 = new GraphPart(-1, -1);
|
||||
e1.path = "e";
|
||||
GraphPart e2 = new GraphPart(-1, -1);
|
||||
e2.path = "e";
|
||||
GraphPart e3 = new GraphPart(-1, -1);
|
||||
e3.path = "e";
|
||||
makeGraph(e1, "e", code, code.adr2pos(ex.start), code.adr2pos(ex.start), allBlocks, refs, visited);
|
||||
makeGraph(e2, "e", code, code.adr2pos(ex.end), code.adr2pos(ex.end), allBlocks, refs, visited);
|
||||
ret.add(makeGraph(e3, "e", code, code.adr2pos(ex.target), code.adr2pos(ex.target), allBlocks, refs, visited));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private GraphPart makeGraph(GraphPart parent, String path, AVM2Code code, int startip, int lastIp, List<GraphPart> allBlocks, HashMap<Integer, List<Integer>> refs, boolean visited2[]) {
|
||||
|
||||
int ip = startip;
|
||||
for (GraphPart p : allBlocks) {
|
||||
if (p.start == ip) {
|
||||
p.refs.add(parent);
|
||||
return p;
|
||||
}
|
||||
}
|
||||
GraphPart g;
|
||||
GraphPart ret = new GraphPart(ip, -1);
|
||||
ret.path = path;
|
||||
GraphPart part = ret;
|
||||
while (ip < code.code.size()) {
|
||||
if (visited2[ip] || ((ip != startip) && (refs.get(ip).size() > 1))) {
|
||||
part.end = lastIp;
|
||||
GraphPart found = null;
|
||||
for (GraphPart p : allBlocks) {
|
||||
if (p.start == ip) {
|
||||
found = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
allBlocks.add(part);
|
||||
|
||||
if (found != null) {
|
||||
part.nextParts.add(found);
|
||||
found.refs.add(part);
|
||||
break;
|
||||
} else {
|
||||
GraphPart gp = new GraphPart(ip, -1);
|
||||
gp.path = path;
|
||||
part.nextParts.add(gp);
|
||||
gp.refs.add(part);
|
||||
part = gp;
|
||||
}
|
||||
}
|
||||
lastIp = ip;
|
||||
AVM2Instruction ins = code.code.get(ip);
|
||||
if ((ins.definition instanceof ThrowIns) || (ins.definition instanceof ReturnValueIns) || (ins.definition instanceof ReturnVoidIns)) {
|
||||
part.end = ip;
|
||||
allBlocks.add(part);
|
||||
break;
|
||||
}
|
||||
if (ins.definition instanceof LookupSwitchIns) {
|
||||
part.end = ip;
|
||||
allBlocks.add(part);
|
||||
try {
|
||||
part.nextParts.add(g = makeGraph(part, path + "0", code, code.adr2pos(code.pos2adr(ip) + ins.operands[0]), ip, allBlocks, refs, visited2));
|
||||
g.refs.add(part);
|
||||
for (int i = 2; i < ins.operands.length; i++) {
|
||||
part.nextParts.add(g = makeGraph(part, path + (i - 1), code, code.adr2pos(code.pos2adr(ip) + ins.operands[i]), ip, allBlocks, refs, visited2));
|
||||
g.refs.add(part);
|
||||
}
|
||||
break;
|
||||
} catch (ConvertException ex) {
|
||||
}
|
||||
}
|
||||
if (ins.definition instanceof JumpIns) {
|
||||
try {
|
||||
part.end = ip;
|
||||
allBlocks.add(part);
|
||||
ip = code.adr2pos(code.pos2adr(ip) + ins.getBytes().length + ins.operands[0]);
|
||||
part.nextParts.add(g = makeGraph(part, path, code, ip, lastIp, allBlocks, refs, visited2));
|
||||
g.refs.add(part);
|
||||
break;
|
||||
} catch (ConvertException ex) {
|
||||
Logger.getLogger(AVM2Code.class.getName()).log(Level.FINE, null, ex);
|
||||
}
|
||||
} else if (ins.definition instanceof IfTypeIns) {
|
||||
part.end = ip;
|
||||
allBlocks.add(part);
|
||||
try {
|
||||
part.nextParts.add(g = makeGraph(part, path + "0", code, code.adr2pos(code.pos2adr(ip) + ins.getBytes().length + ins.operands[0]), ip, allBlocks, refs, visited2));
|
||||
g.refs.add(part);
|
||||
part.nextParts.add(g = makeGraph(part, path + "1", code, ip + 1, ip, allBlocks, refs, visited2));
|
||||
g.refs.add(part);
|
||||
|
||||
} catch (ConvertException ex) {
|
||||
Logger.getLogger(AVM2Code.class.getName()).log(Level.FINE, null, ex);
|
||||
}
|
||||
break;
|
||||
}
|
||||
ip++;
|
||||
};
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.graph;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.graph.GraphPart;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class ForException extends RuntimeException {
|
||||
|
||||
public List<TreeItem> output;
|
||||
public List<TreeItem> finalOutput;
|
||||
public GraphPart continuePart;
|
||||
|
||||
public ForException(List<TreeItem> output, List<TreeItem> finalOutput, GraphPart continuePart) {
|
||||
this.output = output;
|
||||
this.finalOutput = finalOutput;
|
||||
this.continuePart = continuePart;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,230 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABCOutputStream;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
import com.jpexs.decompiler.flash.helpers.Helper;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class AVM2Instruction implements Serializable {
|
||||
|
||||
public InstructionDefinition definition;
|
||||
public int operands[];
|
||||
public long offset;
|
||||
public byte bytes[];
|
||||
public String comment;
|
||||
public boolean ignored = false;
|
||||
public String labelname;
|
||||
public long mappedOffset = -1;
|
||||
public int changeJumpTo = -1;
|
||||
|
||||
public AVM2Instruction(long offset, InstructionDefinition definition, int[] operands, byte bytes[]) {
|
||||
this.definition = definition;
|
||||
this.operands = operands;
|
||||
this.offset = offset;
|
||||
this.bytes = bytes;
|
||||
}
|
||||
|
||||
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() {
|
||||
String s = definition.instructionName;
|
||||
for (int i = 0; i < operands.length; i++) {
|
||||
s += " " + operands[i];
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
public List<Long> getOffsets() {
|
||||
List<Long> ret = new ArrayList<Long>();
|
||||
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(ConstantPool 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.constant_multiname[operands[i]]);
|
||||
break;
|
||||
case AVM2Code.DAT_STRING_INDEX:
|
||||
s.add(constants.constant_string[operands[i]]);
|
||||
break;
|
||||
case AVM2Code.DAT_INT_INDEX:
|
||||
s.add(new Long(constants.constant_int[operands[i]]));
|
||||
break;
|
||||
case AVM2Code.DAT_UINT_INDEX:
|
||||
s.add(new Long(constants.constant_uint[operands[i]]));
|
||||
break;
|
||||
case AVM2Code.DAT_DOUBLE_INDEX:
|
||||
s.add(new Double(constants.constant_double[operands[i]]));
|
||||
break;
|
||||
case AVM2Code.DAT_OFFSET:
|
||||
s.add(new Long(offset + operands[i] + getBytes().length));
|
||||
break;
|
||||
case AVM2Code.DAT_CASE_BASEOFFSET:
|
||||
s.add(new Long(offset + operands[i]));
|
||||
break;
|
||||
case AVM2Code.OPT_CASE_OFFSETS:
|
||||
s.add(new Long(operands[i]));
|
||||
for (int j = i + 1; j < operands.length; j++) {
|
||||
s.add(new Long(offset + operands[j]));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
s.add(new Long(operands[i]));
|
||||
}
|
||||
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
public String getParams(ConstantPool constants, List<String> fullyQualifiedNames) {
|
||||
String s = "";
|
||||
for (int i = 0; i < definition.operands.length; i++) {
|
||||
switch (definition.operands[i]) {
|
||||
case AVM2Code.DAT_MULTINAME_INDEX:
|
||||
s += " m[" + operands[i] + "]\"" + Helper.escapeString(constants.constant_multiname[operands[i]].toString(constants, fullyQualifiedNames)) + "\"";
|
||||
break;
|
||||
case AVM2Code.DAT_STRING_INDEX:
|
||||
s += " \"" + Helper.escapeString(constants.constant_string[operands[i]]) + "\"";
|
||||
break;
|
||||
case AVM2Code.DAT_INT_INDEX:
|
||||
s += " " + constants.constant_int[operands[i]] + "";
|
||||
break;
|
||||
case AVM2Code.DAT_UINT_INDEX:
|
||||
s += " " + constants.constant_uint[operands[i]] + "";
|
||||
break;
|
||||
case AVM2Code.DAT_DOUBLE_INDEX:
|
||||
s += " " + constants.constant_double[operands[i]] + "";
|
||||
break;
|
||||
case AVM2Code.DAT_OFFSET:
|
||||
s += " ";
|
||||
if (operands[i] > 0) {
|
||||
//s += "+";
|
||||
}//operands[i]
|
||||
s += "ofs" + Helper.formatAddress(offset + operands[i] + getBytes().length) + "";
|
||||
break;
|
||||
case AVM2Code.DAT_CASE_BASEOFFSET:
|
||||
s += " ";
|
||||
if (operands[i] > 0) {
|
||||
//s += "+";
|
||||
}//operands[i]
|
||||
s += "ofs" + Helper.formatAddress(offset + operands[i]) + "";
|
||||
break;
|
||||
case AVM2Code.OPT_CASE_OFFSETS:
|
||||
s += " " + operands[i];
|
||||
for (int j = i + 1; j < operands.length; j++) {
|
||||
s += " ";
|
||||
if (operands[j] > 0) {
|
||||
//s += "+";
|
||||
}//operands[j]
|
||||
s += "ofs" + Helper.formatAddress(offset + operands[j]) + "";
|
||||
}
|
||||
break;
|
||||
default:
|
||||
s += " " + operands[i];
|
||||
}
|
||||
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
public String getComment() {
|
||||
if (ignored) {
|
||||
return " ;ignored";
|
||||
}
|
||||
if ((comment == null) || comment.equals("")) {
|
||||
return "";
|
||||
}
|
||||
return " ;" + comment;
|
||||
}
|
||||
|
||||
public boolean isIgnored() {
|
||||
return ignored;
|
||||
}
|
||||
|
||||
public String toString(ConstantPool constants, List<String> fullyQualifiedNames) {
|
||||
String s = Helper.formatAddress(offset) + " " + Helper.padSpaceRight(Helper.byteArrToString(getBytes()), 30) + definition.instructionName;
|
||||
s += getParams(constants, fullyQualifiedNames) + getComment();
|
||||
return s;
|
||||
}
|
||||
|
||||
public String toStringNoAddress(ConstantPool constants, List<String> fullyQualifiedNames) {
|
||||
String s = definition.instructionName;
|
||||
s += getParams(constants, fullyQualifiedNames) + getComment();
|
||||
return s;
|
||||
}
|
||||
public List replaceWith;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.TreeItem;
|
||||
import java.util.Stack;
|
||||
|
||||
public interface IfTypeIns {
|
||||
|
||||
public abstract void translateInverted(java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, AVM2Instruction ins);
|
||||
}
|
||||
+123
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.FullMultinameTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import com.jpexs.decompiler.flash.helpers.Highlighting;
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class InstructionDefinition implements Serializable {
|
||||
|
||||
protected String hilighOffset(String text, long offset) {
|
||||
return Highlighting.hilighOffset(text, offset);
|
||||
}
|
||||
public int operands[];
|
||||
public String instructionName = "";
|
||||
public int instructionCode = 0;
|
||||
|
||||
public InstructionDefinition(int instructionCode, String instructionName, int operands[]) {
|
||||
this.instructionCode = instructionCode;
|
||||
this.instructionName = instructionName;
|
||||
this.operands = operands;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String s = instructionName;
|
||||
for (int i = 0; i < operands.length; i++) {
|
||||
if ((operands[i] & 0xff00) == AVM2Code.OPT_U30) {
|
||||
s += " U30";
|
||||
}
|
||||
if ((operands[i] & 0xff00) == AVM2Code.OPT_U8) {
|
||||
s += " U8";
|
||||
}
|
||||
if ((operands[i] & 0xff00) == AVM2Code.OPT_BYTE) {
|
||||
s += " BYTE";
|
||||
}
|
||||
if ((operands[i] & 0xff00) == AVM2Code.OPT_S24) {
|
||||
s += " S24";
|
||||
}
|
||||
if ((operands[i] & 0xff00) == AVM2Code.OPT_CASE_OFFSETS) {
|
||||
s += " U30 S24,[S24]...";
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
public void execute(LocalDataArea lda, ConstantPool constants, List arguments) {
|
||||
throw new UnsupportedOperationException("Instruction " + instructionName + " not implemented");
|
||||
}
|
||||
|
||||
public void translate(boolean isStatic, int classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
}
|
||||
|
||||
protected FullMultinameTreeItem resolveMultiname(Stack<TreeItem> stack, ConstantPool constants, int multinameIndex, AVM2Instruction ins) {
|
||||
TreeItem ns = null;
|
||||
TreeItem name = null;
|
||||
if (constants.constant_multiname[multinameIndex].needsName()) {
|
||||
name = (TreeItem) stack.pop();
|
||||
}
|
||||
if (constants.constant_multiname[multinameIndex].needsNs()) {
|
||||
ns = (TreeItem) stack.pop();
|
||||
}
|
||||
return new FullMultinameTreeItem(ins, multinameIndex, name, ns);
|
||||
}
|
||||
|
||||
protected int resolvedCount(ConstantPool constants, int multinameIndex) {
|
||||
int pos = 0;
|
||||
if (constants.constant_multiname[multinameIndex].needsNs()) {
|
||||
pos++;
|
||||
}
|
||||
if (constants.constant_multiname[multinameIndex].needsName()) {
|
||||
pos++;
|
||||
}
|
||||
return pos;
|
||||
|
||||
}
|
||||
|
||||
protected String resolveMultinameNoPop(int pos, Stack<TreeItem> stack, ConstantPool constants, int multinameIndex, AVM2Instruction ins, List<String> fullyQualifiedNames) {
|
||||
String ns = "";
|
||||
String name;
|
||||
if (constants.constant_multiname[multinameIndex].needsNs()) {
|
||||
ns = "[" + stack.get(pos) + "]";
|
||||
pos++;
|
||||
}
|
||||
if (constants.constant_multiname[multinameIndex].needsName()) {
|
||||
name = stack.get(pos).toString();
|
||||
} else {
|
||||
name = hilighOffset(constants.constant_multiname[multinameIndex].getName(constants, fullyQualifiedNames), ins.offset);
|
||||
}
|
||||
return name + ns;
|
||||
}
|
||||
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getScopeStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.TreeItem;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public interface SetTypeIns {
|
||||
|
||||
public abstract String getObject(Stack<TreeItem> stack, ABC abc, AVM2Instruction ins, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class TagInstruction extends InstructionDefinition {
|
||||
|
||||
public TagInstruction(String tagName) {
|
||||
super(-1, tagName, new int[0]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.operations.AddTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class AddIIns extends AddIns {
|
||||
|
||||
public AddIIns() {
|
||||
instructionName = "add_i";
|
||||
instructionCode = 0xc5;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
TreeItem v2 = (TreeItem) stack.pop();
|
||||
TreeItem v1 = (TreeItem) stack.pop();
|
||||
stack.push(new AddTreeItem(ins, v1, v2));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return -2 + 1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
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.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.operations.AddTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class AddIns extends InstructionDefinition {
|
||||
|
||||
public AddIns() {
|
||||
super(0xa0, "add", new int[]{});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(LocalDataArea lda, ConstantPool constants, List arguments) {
|
||||
Object o1 = lda.operandStack.pop();
|
||||
Object o2 = lda.operandStack.pop();
|
||||
if ((o1 instanceof Long) && ((o2 instanceof Long))) {
|
||||
Long ret = new Long(((Long) o1).longValue() + ((Long) o2).longValue());
|
||||
lda.operandStack.push(ret);
|
||||
} else if ((o1 instanceof Double) && ((o2 instanceof Double))) {
|
||||
Double ret = new Double(((Double) o1).doubleValue() + ((Double) o2).doubleValue());
|
||||
lda.operandStack.push(ret);
|
||||
} else if ((o1 instanceof Long) && ((o2 instanceof Double))) {
|
||||
Double ret = new Double(((Long) o1).longValue() + ((Double) o2).doubleValue());
|
||||
lda.operandStack.push(ret);
|
||||
} else if ((o1 instanceof Double) && ((o2 instanceof Long))) {
|
||||
Double ret = new Double(((Double) o1).doubleValue() + ((Long) o2).longValue());
|
||||
lda.operandStack.push(ret);
|
||||
} else {
|
||||
String s = o1.toString() + o2.toString();
|
||||
lda.operandStack.push(s);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
TreeItem v2 = (TreeItem) stack.pop();
|
||||
TreeItem v1 = (TreeItem) stack.pop();
|
||||
stack.push(new AddTreeItem(ins, v1, v2));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return -2 + 1;
|
||||
}
|
||||
}
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
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.treemodel.DecrementTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class DecrementIIns extends InstructionDefinition {
|
||||
|
||||
public DecrementIIns() {
|
||||
super(0xc1, "decrement_i", new int[]{});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(LocalDataArea lda, ConstantPool constants, List arguments) {
|
||||
Object obj = lda.operandStack.pop();
|
||||
if (obj instanceof Long) {
|
||||
Long obj2 = ((Long) obj).longValue() - 1;
|
||||
lda.operandStack.push(obj2);
|
||||
} else if (obj instanceof Double) {
|
||||
Double obj2 = ((Double) obj).doubleValue() - 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 classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
stack.push(new DecrementTreeItem(ins, (TreeItem) stack.pop()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return -1 + 1;
|
||||
}
|
||||
}
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
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.treemodel.DecrementTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class DecrementIns extends InstructionDefinition {
|
||||
|
||||
public DecrementIns() {
|
||||
super(0x93, "decrement", new int[]{});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(LocalDataArea lda, ConstantPool constants, List arguments) {
|
||||
Object obj = lda.operandStack.pop();
|
||||
if (obj instanceof Long) {
|
||||
Long obj2 = ((Long) obj).longValue() - 1;
|
||||
lda.operandStack.push(obj2);
|
||||
} else if (obj instanceof Double) {
|
||||
Double obj2 = ((Double) obj).doubleValue() - 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 classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
stack.push(new DecrementTreeItem(ins, (TreeItem) stack.pop()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return -1 + 1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
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.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.operations.DivideTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class DivideIns extends InstructionDefinition {
|
||||
|
||||
public DivideIns() {
|
||||
super(0xa3, "divide", new int[]{});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(LocalDataArea lda, ConstantPool constants, List arguments) {
|
||||
Object o2 = lda.operandStack.pop();
|
||||
Object o1 = lda.operandStack.pop();
|
||||
if ((o1 instanceof Long) && ((o2 instanceof Long))) {
|
||||
Long ret = new Long(((Long) o1).longValue() / ((Long) o2).longValue());
|
||||
lda.operandStack.push(ret);
|
||||
} else if ((o1 instanceof Double) && ((o2 instanceof Double))) {
|
||||
Double ret = new Double(((Double) o1).doubleValue() / ((Double) o2).doubleValue());
|
||||
lda.operandStack.push(ret);
|
||||
} else if ((o1 instanceof Long) && ((o2 instanceof Double))) {
|
||||
Double ret = new Double(((Long) o1).longValue() / ((Double) o2).doubleValue());
|
||||
lda.operandStack.push(ret);
|
||||
} else if ((o1 instanceof Double) && ((o2 instanceof Long))) {
|
||||
Double ret = new Double(((Double) o1).doubleValue() / ((Long) o2).longValue());
|
||||
lda.operandStack.push(ret);
|
||||
} else {
|
||||
throw new RuntimeException("Cannot divide");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
TreeItem v2 = (TreeItem) stack.pop();
|
||||
TreeItem v1 = (TreeItem) stack.pop();
|
||||
stack.push(new DivideTreeItem(ins, v1, v2));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return -2 + 1;
|
||||
}
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.IncrementTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class IncrementIIns extends InstructionDefinition {
|
||||
|
||||
public IncrementIIns() {
|
||||
super(0xc0, "increment_i", new int[]{});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
stack.push(new IncrementTreeItem(ins, (TreeItem) stack.pop()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return -1 + 1;
|
||||
}
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.IncrementTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class IncrementIns extends InstructionDefinition {
|
||||
|
||||
public IncrementIns() {
|
||||
super(0x91, "increment", new int[]{});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
stack.push(new IncrementTreeItem(ins, (TreeItem) stack.pop()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return -1 + 1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
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.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.operations.ModuloTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class ModuloIns extends InstructionDefinition {
|
||||
|
||||
public ModuloIns() {
|
||||
super(0xa4, "modulo", new int[]{});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(LocalDataArea lda, ConstantPool constants, List arguments) {
|
||||
Object o1 = lda.operandStack.pop();
|
||||
Object o2 = lda.operandStack.pop();
|
||||
|
||||
if ((o1 instanceof Long) && ((o2 instanceof Long))) {
|
||||
Long ret = new Long(((Long) o2).longValue() % ((Long) o1).longValue());
|
||||
lda.operandStack.push(ret);
|
||||
} else {
|
||||
throw new RuntimeException("Cannot modulo");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
TreeItem v2 = (TreeItem) stack.pop();
|
||||
TreeItem v1 = (TreeItem) stack.pop();
|
||||
stack.push(new ModuloTreeItem(ins, v1, v2));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return -2 + 1;
|
||||
}
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.operations.MultiplyTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class MultiplyIIns extends InstructionDefinition {
|
||||
|
||||
public MultiplyIIns() {
|
||||
super(0xc7, "multiply_i", new int[]{});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
TreeItem v2 = (TreeItem) stack.pop();
|
||||
TreeItem v1 = (TreeItem) stack.pop();
|
||||
stack.push(new MultiplyTreeItem(ins, v1, v2));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return -2 + 1;
|
||||
}
|
||||
}
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
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.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.operations.MultiplyTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class MultiplyIns extends InstructionDefinition {
|
||||
|
||||
public MultiplyIns() {
|
||||
super(0xa2, "multiply", new int[]{});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(LocalDataArea lda, ConstantPool constants, List arguments) {
|
||||
Object o1 = lda.operandStack.pop();
|
||||
Object o2 = lda.operandStack.pop();
|
||||
if ((o1 instanceof Long) && ((o2 instanceof Long))) {
|
||||
Long ret = new Long(((Long) o1).longValue() * ((Long) o2).longValue());
|
||||
lda.operandStack.push(ret);
|
||||
} else if ((o1 instanceof Double) && ((o2 instanceof Double))) {
|
||||
Double ret = new Double(((Double) o1).doubleValue() * ((Double) o2).doubleValue());
|
||||
lda.operandStack.push(ret);
|
||||
} else if ((o1 instanceof Long) && ((o2 instanceof Double))) {
|
||||
Double ret = new Double(((Long) o1).longValue() * ((Double) o2).doubleValue());
|
||||
lda.operandStack.push(ret);
|
||||
} else if ((o1 instanceof Double) && ((o2 instanceof Long))) {
|
||||
Double ret = new Double(((Double) o1).doubleValue() * ((Long) o2).longValue());
|
||||
lda.operandStack.push(ret);
|
||||
} else {
|
||||
throw new RuntimeException("Cannot multiply");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
TreeItem v2 = (TreeItem) stack.pop();
|
||||
TreeItem v1 = (TreeItem) stack.pop();
|
||||
stack.push(new MultiplyTreeItem(ins, v1, v2));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return -2 + 1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.operations.NegTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class NegateIIns extends InstructionDefinition {
|
||||
|
||||
public NegateIIns() {
|
||||
super(0xc4, "negate_i", new int[]{});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
TreeItem v = (TreeItem) stack.pop();
|
||||
stack.push(new NegTreeItem(ins, v));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return -1 + 1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.operations.NegTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class NegateIns extends InstructionDefinition {
|
||||
|
||||
public NegateIns() {
|
||||
super(0x90, "negate", new int[]{});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
TreeItem v = (TreeItem) stack.pop();
|
||||
stack.push(new NegTreeItem(ins, v));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return -1 + 1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.operations.NotTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class NotIns extends InstructionDefinition {
|
||||
|
||||
public NotIns() {
|
||||
super(0x96, "not", new int[]{});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
TreeItem v = (TreeItem) stack.pop();
|
||||
stack.push(new NotTreeItem(ins, v));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return -1 + 1;
|
||||
}
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.operations.SubtractTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class SubtractIIns extends InstructionDefinition {
|
||||
|
||||
public SubtractIIns() {
|
||||
super(0xc6, "subtract_i", new int[]{});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
TreeItem v2 = (TreeItem) stack.pop();
|
||||
TreeItem v1 = (TreeItem) stack.pop();
|
||||
stack.push(new SubtractTreeItem(ins, v1, v2));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return -2 + 1;
|
||||
}
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.operations.SubtractTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class SubtractIns extends InstructionDefinition {
|
||||
|
||||
public SubtractIns() {
|
||||
super(0xa1, "subtract", new int[]{});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
TreeItem v2 = (TreeItem) stack.pop();
|
||||
TreeItem v1 = (TreeItem) stack.pop();
|
||||
stack.push(new SubtractTreeItem(ins, v1, v2));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return -2 + 1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.bitwise;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
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.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.operations.BitAndTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class BitAndIns extends InstructionDefinition {
|
||||
|
||||
public BitAndIns() {
|
||||
super(0xa8, "bitand", new int[]{});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(LocalDataArea lda, ConstantPool 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 classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
TreeItem v2 = (TreeItem) stack.pop();
|
||||
TreeItem v1 = (TreeItem) stack.pop();
|
||||
stack.push(new BitAndTreeItem(ins, v1, v2));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return -2 + 1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.bitwise;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
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.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.operations.BitNotTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class BitNotIns extends InstructionDefinition {
|
||||
|
||||
public BitNotIns() {
|
||||
super(0x97, "bitnot", new int[]{});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(LocalDataArea lda, ConstantPool constants, List arguments) {
|
||||
Long value = (Long) lda.operandStack.pop();
|
||||
Long ret = new Long(-value.longValue());
|
||||
lda.operandStack.push(ret);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
TreeItem v = (TreeItem) stack.pop();
|
||||
stack.push(new BitNotTreeItem(ins, v));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return -1 + 1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.bitwise;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
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.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.operations.BitOrTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class BitOrIns extends InstructionDefinition {
|
||||
|
||||
public BitOrIns() {
|
||||
super(0xa9, "bitor", new int[]{});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(LocalDataArea lda, ConstantPool 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 classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
TreeItem v2 = (TreeItem) stack.pop();
|
||||
TreeItem v1 = (TreeItem) stack.pop();
|
||||
stack.push(new BitOrTreeItem(ins, v1, v2));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return -2 + 1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.bitwise;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
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.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.operations.BitXorTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class BitXorIns extends InstructionDefinition {
|
||||
|
||||
public BitXorIns() {
|
||||
super(0xaa, "bitxor", new int[]{});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(LocalDataArea lda, ConstantPool 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 classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
TreeItem v2 = (TreeItem) stack.pop();
|
||||
TreeItem v1 = (TreeItem) stack.pop();
|
||||
stack.push(new BitXorTreeItem(ins, v1, v2));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return -2 + 1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.bitwise;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.operations.LShiftTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class LShiftIns extends InstructionDefinition {
|
||||
|
||||
public LShiftIns() {
|
||||
super(0xa5, "lshift", new int[]{});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
TreeItem v2 = (TreeItem) stack.pop();
|
||||
TreeItem v1 = (TreeItem) stack.pop();
|
||||
stack.push(new LShiftTreeItem(ins, v1, v2));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return -2 + 1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.bitwise;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.operations.RShiftTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class RShiftIns extends InstructionDefinition {
|
||||
|
||||
public RShiftIns() {
|
||||
super(0xa6, "rshift", new int[]{});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
TreeItem v2 = (TreeItem) stack.pop();
|
||||
TreeItem v1 = (TreeItem) stack.pop();
|
||||
stack.push(new RShiftTreeItem(ins, v1, v2));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return -2 + 1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.bitwise;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.operations.URShiftTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class URShiftIns extends InstructionDefinition {
|
||||
|
||||
public URShiftIns() {
|
||||
super(0xa7, "urshift", new int[]{});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
TreeItem v2 = (TreeItem) stack.pop();
|
||||
TreeItem v1 = (TreeItem) stack.pop();
|
||||
stack.push(new URShiftTreeItem(ins, v1, v2));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return -2 + 1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.comparsion;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
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.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.operations.EqTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class EqualsIns extends InstructionDefinition {
|
||||
|
||||
public EqualsIns() {
|
||||
super(0xab, "equals", new int[]{});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(LocalDataArea lda, ConstantPool 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 classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
TreeItem v2 = (TreeItem) stack.pop();
|
||||
TreeItem v1 = (TreeItem) stack.pop();
|
||||
stack.push(new EqTreeItem(ins, v1, v2));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return -2 + 1;
|
||||
}
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.comparsion;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.operations.GeTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class GreaterEqualsIns extends InstructionDefinition {
|
||||
|
||||
public GreaterEqualsIns() {
|
||||
super(0xb0, "greaterequals", new int[]{});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
TreeItem v2 = (TreeItem) stack.pop();
|
||||
TreeItem v1 = (TreeItem) stack.pop();
|
||||
stack.push(new GeTreeItem(ins, v1, v2));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return -2 + 1;
|
||||
}
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.comparsion;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.operations.LtTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class GreaterThanIns extends InstructionDefinition {
|
||||
|
||||
public GreaterThanIns() {
|
||||
super(0xaf, "greaterthan", new int[]{});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
TreeItem v2 = (TreeItem) stack.pop();
|
||||
TreeItem v1 = (TreeItem) stack.pop();
|
||||
stack.push(new LtTreeItem(ins, v1, v2));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return -2 + 1;
|
||||
}
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.comparsion;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.operations.LeTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class LessEqualsIns extends InstructionDefinition {
|
||||
|
||||
public LessEqualsIns() {
|
||||
super(0xae, "lessequals", new int[]{});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
TreeItem v2 = (TreeItem) stack.pop();
|
||||
TreeItem v1 = (TreeItem) stack.pop();
|
||||
stack.push(new LeTreeItem(ins, v1, v2));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return -2 + 1;
|
||||
}
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.comparsion;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.operations.GtTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class LessThanIns extends InstructionDefinition {
|
||||
|
||||
public LessThanIns() {
|
||||
super(0xad, "lessthan", new int[]{});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
TreeItem v2 = (TreeItem) stack.pop();
|
||||
TreeItem v1 = (TreeItem) stack.pop();
|
||||
stack.push(new GtTreeItem(ins, v1, v2));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return -2 + 1;
|
||||
}
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.comparsion;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.operations.StrictEqTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class StrictEqualsIns extends InstructionDefinition {
|
||||
|
||||
public StrictEqualsIns() {
|
||||
super(0xac, "strictequals", new int[]{});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
TreeItem v2 = (TreeItem) stack.pop();
|
||||
TreeItem v1 = (TreeItem) stack.pop();
|
||||
stack.push(new StrictEqTreeItem(ins, v1, v2));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return -2 + 1;
|
||||
}
|
||||
}
|
||||
+118
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.construction;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
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.treemodel.ConstructTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.EscapeXAttrTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.EscapeXElemTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.FindPropertyTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.FullMultinameTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.GetLexTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.GetPropertyTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.StringTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.XMLTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.operations.AddTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class ConstructIns extends InstructionDefinition {
|
||||
|
||||
public ConstructIns() {
|
||||
super(0x42, "construct", new int[]{AVM2Code.DAT_ARG_COUNT});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(LocalDataArea lda, ConstantPool 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(TreeItem item, List<TreeItem> list) {
|
||||
boolean ret = true;
|
||||
if (item instanceof StringTreeItem) {
|
||||
list.add(item);
|
||||
} else if (item instanceof AddTreeItem) {
|
||||
ret = ret && walkXML(((AddTreeItem) item).leftSide, list);
|
||||
ret = ret && walkXML(((AddTreeItem) item).rightSide, list);
|
||||
} else if ((item instanceof EscapeXElemTreeItem) || (item instanceof EscapeXAttrTreeItem)) {
|
||||
list.add(item);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
int argCount = ins.operands[0];
|
||||
List<TreeItem> args = new ArrayList<TreeItem>();
|
||||
for (int a = 0; a < argCount; a++) {
|
||||
args.add(0, (TreeItem) stack.pop());
|
||||
}
|
||||
TreeItem obj = (TreeItem) stack.pop();
|
||||
|
||||
FullMultinameTreeItem xmlMult = null;
|
||||
boolean isXML = false;
|
||||
if (obj instanceof GetPropertyTreeItem) {
|
||||
GetPropertyTreeItem gpt = (GetPropertyTreeItem) obj;
|
||||
if (gpt.object instanceof FindPropertyTreeItem) {
|
||||
FindPropertyTreeItem fpt = (FindPropertyTreeItem) gpt.object;
|
||||
xmlMult = fpt.propertyName;
|
||||
isXML = xmlMult.isXML(constants, localRegNames, fullyQualifiedNames) && xmlMult.isXML(constants, localRegNames, fullyQualifiedNames);
|
||||
}
|
||||
}
|
||||
if (obj instanceof GetLexTreeItem) {
|
||||
GetLexTreeItem glt = (GetLexTreeItem) obj;
|
||||
isXML = glt.propertyName.getName(constants, fullyQualifiedNames).equals("XML");
|
||||
}
|
||||
|
||||
if (isXML) {
|
||||
if (args.size() == 1) {
|
||||
TreeItem arg = args.get(0);
|
||||
List<TreeItem> xmlLines = new ArrayList<TreeItem>();
|
||||
if (walkXML(arg, xmlLines)) {
|
||||
stack.push(new XMLTreeItem(ins, xmlLines));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stack.push(new ConstructTreeItem(ins, obj, args));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return -ins.operands[0] - 1 + 1;
|
||||
}
|
||||
}
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.construction;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
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.treemodel.ConstructPropTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.FullMultinameTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.XMLTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class ConstructPropIns extends InstructionDefinition {
|
||||
|
||||
public ConstructPropIns() {
|
||||
super(0x4a, "constructprop", new int[]{AVM2Code.DAT_MULTINAME_INDEX, AVM2Code.DAT_ARG_COUNT});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(LocalDataArea lda, ConstantPool 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 classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
int multinameIndex = ins.operands[0];
|
||||
int argCount = ins.operands[1];
|
||||
List<TreeItem> args = new ArrayList<TreeItem>();
|
||||
for (int a = 0; a < argCount; a++) {
|
||||
args.add(0, (TreeItem) stack.pop());
|
||||
}
|
||||
FullMultinameTreeItem multiname = resolveMultiname(stack, constants, multinameIndex, ins);
|
||||
TreeItem obj = (TreeItem) stack.pop();
|
||||
|
||||
if (multiname.isXML(constants, localRegNames, fullyQualifiedNames)) {
|
||||
if (args.size() == 1) {
|
||||
TreeItem arg = args.get(0);
|
||||
List<TreeItem> xmlLines = new ArrayList<TreeItem>();
|
||||
if (ConstructIns.walkXML(arg, xmlLines)) {
|
||||
stack.push(new XMLTreeItem(ins, xmlLines));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stack.push(new ConstructPropTreeItem(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.constant_multiname[multinameIndex].needsName()) {
|
||||
ret--;
|
||||
}
|
||||
if (abc.constants.constant_multiname[multinameIndex].needsNs()) {
|
||||
ret--;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.construction;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
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.treemodel.ConstructSuperTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class ConstructSuperIns extends InstructionDefinition {
|
||||
|
||||
public ConstructSuperIns() {
|
||||
super(0x49, "constructsuper", new int[]{AVM2Code.DAT_ARG_COUNT});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(LocalDataArea lda, ConstantPool 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 classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
int argCount = ins.operands[0];
|
||||
List<TreeItem> args = new ArrayList<TreeItem>();
|
||||
for (int a = 0; a < argCount; a++) {
|
||||
args.add(0, (TreeItem) stack.pop());
|
||||
}
|
||||
TreeItem obj = (TreeItem) stack.pop();
|
||||
output.add(new ConstructSuperTreeItem(ins, obj, args));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return -ins.operands[0] - 1;
|
||||
}
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.construction;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.NewActivationTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class NewActivationIns extends InstructionDefinition {
|
||||
|
||||
public NewActivationIns() {
|
||||
super(0x57, "newactivation", new int[]{});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
stack.push(new NewActivationTreeItem(ins));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.construction;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.NewArrayTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class NewArrayIns extends InstructionDefinition {
|
||||
|
||||
public NewArrayIns() {
|
||||
super(0x56, "newarray", new int[]{AVM2Code.DAT_ARG_COUNT});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
int argCount = ins.operands[0];
|
||||
List<TreeItem> args = new ArrayList<TreeItem>();
|
||||
for (int a = 0; a < argCount; a++) {
|
||||
args.add(0, (TreeItem) stack.pop());
|
||||
}
|
||||
stack.push(new NewArrayTreeItem(ins, args));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return -ins.operands[0] + 1;
|
||||
}
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.construction;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.clauses.ExceptionTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class NewCatchIns extends InstructionDefinition {
|
||||
|
||||
public NewCatchIns() {
|
||||
super(0x5a, "newcatch", new int[]{AVM2Code.DAT_EXCEPTION_INDEX});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
int exInfo = ins.operands[0];
|
||||
stack.push(new ExceptionTreeItem(body.exceptions[exInfo]));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.construction;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.UnparsedTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class NewClassIns extends InstructionDefinition {
|
||||
|
||||
public NewClassIns() {
|
||||
super(0x58, "newclass", new int[]{AVM2Code.DAT_CLASS_INDEX});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
int clsIndex = ins.operands[0];
|
||||
String baseType = stack.pop().toString(constants, localRegNames, fullyQualifiedNames);
|
||||
stack.push(new UnparsedTreeItem(ins, "new " + abc.constants.constant_multiname[abc.instance_info[clsIndex].name_index].getName(constants, fullyQualifiedNames) + ".class extends " + baseType));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return -1 + 1;
|
||||
}
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.construction;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.NewFunctionTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodBody;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import com.jpexs.decompiler.flash.helpers.Highlighting;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class NewFunctionIns extends InstructionDefinition {
|
||||
|
||||
public NewFunctionIns() {
|
||||
super(0x40, "newfunction", new int[]{AVM2Code.DAT_METHOD_INDEX});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
int methodIndex = ins.operands[0];
|
||||
MethodBody mybody = abc.findBody(methodIndex);
|
||||
String bodyStr = "";
|
||||
String paramStr = "";
|
||||
if (mybody != null) {
|
||||
bodyStr = Highlighting.hilighMethodEnd() + mybody.toString("", false, isStatic, classIndex, abc, constants, method_info, new Stack<TreeItem>()/*scopeStack*/, false, true, fullyQualifiedNames, null) + Highlighting.hilighMethodBegin(body.method_info);
|
||||
paramStr = method_info[methodIndex].getParamStr(constants, mybody, abc, fullyQualifiedNames);
|
||||
}
|
||||
|
||||
stack.push(new NewFunctionTreeItem(ins, "", paramStr, method_info[methodIndex].getReturnTypeStr(constants, fullyQualifiedNames), bodyStr));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.construction;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.NameValuePair;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.NewObjectTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class NewObjectIns extends InstructionDefinition {
|
||||
|
||||
public NewObjectIns() {
|
||||
super(0x55, "newobject", new int[]{AVM2Code.DAT_ARG_COUNT});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
int argCount = ins.operands[0];
|
||||
List<NameValuePair> args = new ArrayList<NameValuePair>();
|
||||
for (int a = 0; a < argCount; a++) {
|
||||
TreeItem value = (TreeItem) stack.pop();
|
||||
TreeItem name = (TreeItem) stack.pop();
|
||||
args.add(0, new NameValuePair(name, value));
|
||||
}
|
||||
stack.push(new NewObjectTreeItem(ins, args));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return -ins.operands[0] * 2 + 1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.debug;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
|
||||
public class DebugFileIns extends InstructionDefinition {
|
||||
|
||||
public DebugFileIns() {
|
||||
super(0xf1, "debugfile", new int[]{AVM2Code.DAT_STRING_INDEX});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.debug;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
|
||||
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});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.debug;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
|
||||
public class DebugLineIns extends InstructionDefinition {
|
||||
|
||||
public DebugLineIns() {
|
||||
super(0xf0, "debugline", new int[]{AVM2Code.DAT_LINENUM});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.executing;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
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.treemodel.CallTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class CallIns extends InstructionDefinition {
|
||||
|
||||
public CallIns() {
|
||||
super(0x41, "call", new int[]{AVM2Code.DAT_ARG_COUNT});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(LocalDataArea lda, ConstantPool 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 classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
int argCount = ins.operands[0];
|
||||
List<TreeItem> args = new ArrayList<TreeItem>();
|
||||
for (int a = 0; a < argCount; a++) {
|
||||
args.add(0, (TreeItem) stack.pop());
|
||||
}
|
||||
TreeItem receiver = (TreeItem) stack.pop();
|
||||
TreeItem function = (TreeItem) stack.pop();
|
||||
stack.push(new CallTreeItem(ins, receiver, function, args));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return -2 + 1 - ins.operands[0];
|
||||
}
|
||||
}
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.executing;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
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.treemodel.CallMethodTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class CallMethodIns extends InstructionDefinition {
|
||||
|
||||
public CallMethodIns() {
|
||||
super(0x43, "callmethod", new int[]{AVM2Code.DAT_METHOD_INDEX, AVM2Code.DAT_ARG_COUNT});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(LocalDataArea lda, ConstantPool 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 classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
int methodIndex = ins.operands[0];
|
||||
int argCount = ins.operands[1];
|
||||
List<TreeItem> args = new ArrayList<TreeItem>();
|
||||
for (int a = 0; a < argCount; a++) {
|
||||
args.add(0, (TreeItem) stack.pop());
|
||||
}
|
||||
TreeItem receiver = (TreeItem) stack.pop();
|
||||
String methodName = method_info[methodIndex].getName(constants);
|
||||
stack.push(new CallMethodTreeItem(ins, receiver, methodName, args));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return -1 + 1 - ins.operands[1];
|
||||
}
|
||||
}
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.executing;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.CallPropertyTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.FullMultinameTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class CallPropLexIns extends CallPropertyIns {
|
||||
|
||||
public CallPropLexIns() {
|
||||
instructionName = "callproplex";
|
||||
instructionCode = 0x4c;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
int multinameIndex = ins.operands[0];
|
||||
int argCount = ins.operands[1];
|
||||
List<TreeItem> args = new ArrayList<TreeItem>();
|
||||
for (int a = 0; a < argCount; a++) {
|
||||
args.add(0, (TreeItem) stack.pop());
|
||||
}
|
||||
FullMultinameTreeItem multiname = resolveMultiname(stack, constants, multinameIndex, ins);
|
||||
TreeItem receiver = (TreeItem) stack.pop();
|
||||
|
||||
stack.push(new CallPropertyTreeItem(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.constant_multiname[multinameIndex].needsName()) {
|
||||
ret--;
|
||||
}
|
||||
if (abc.constants.constant_multiname[multinameIndex].needsNs()) {
|
||||
ret--;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.executing;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
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.treemodel.CallPropertyTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.FullMultinameTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class CallPropVoidIns extends InstructionDefinition {
|
||||
|
||||
public CallPropVoidIns() {
|
||||
super(0x4f, "callpropvoid", new int[]{AVM2Code.DAT_MULTINAME_INDEX, AVM2Code.DAT_ARG_COUNT});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(LocalDataArea lda, ConstantPool 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 classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
int multinameIndex = ins.operands[0];
|
||||
int argCount = ins.operands[1];
|
||||
List<TreeItem> args = new ArrayList<TreeItem>();
|
||||
for (int a = 0; a < argCount; a++) {
|
||||
args.add(0, (TreeItem) stack.pop());
|
||||
}
|
||||
FullMultinameTreeItem multiname = resolveMultiname(stack, constants, multinameIndex, ins);
|
||||
|
||||
TreeItem receiver = (TreeItem) stack.pop();
|
||||
|
||||
output.add(new CallPropertyTreeItem(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.constant_multiname[multinameIndex].needsName()) {
|
||||
ret--;
|
||||
}
|
||||
if (abc.constants.constant_multiname[multinameIndex].needsNs()) {
|
||||
ret--;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.executing;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
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.treemodel.CallPropertyTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.FullMultinameTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class CallPropertyIns extends InstructionDefinition {
|
||||
|
||||
public CallPropertyIns() {
|
||||
super(0x46, "callproperty", new int[]{AVM2Code.DAT_MULTINAME_INDEX, AVM2Code.DAT_ARG_COUNT});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(LocalDataArea lda, ConstantPool 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 classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
int multinameIndex = ins.operands[0];
|
||||
int argCount = ins.operands[1];
|
||||
List<TreeItem> args = new ArrayList<TreeItem>();
|
||||
for (int a = 0; a < argCount; a++) {
|
||||
args.add(0, (TreeItem) stack.pop());
|
||||
}
|
||||
FullMultinameTreeItem multiname = resolveMultiname(stack, constants, multinameIndex, ins);
|
||||
|
||||
TreeItem receiver = (TreeItem) stack.pop();
|
||||
|
||||
stack.push(new CallPropertyTreeItem(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.constant_multiname[multinameIndex].needsName()) {
|
||||
ret--;
|
||||
}
|
||||
if (abc.constants.constant_multiname[multinameIndex].needsNs()) {
|
||||
ret--;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.executing;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
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.treemodel.CallStaticTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class CallStaticIns extends InstructionDefinition {
|
||||
|
||||
public CallStaticIns() {
|
||||
super(0x44, "callstatic", new int[]{AVM2Code.DAT_METHOD_INDEX, AVM2Code.DAT_ARG_COUNT});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(LocalDataArea lda, ConstantPool 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 classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
int methodIndex = ins.operands[0];
|
||||
int argCount = ins.operands[1];
|
||||
List<TreeItem> args = new ArrayList<TreeItem>();
|
||||
for (int a = 0; a < argCount; a++) {
|
||||
args.add(0, (TreeItem) stack.pop());
|
||||
}
|
||||
TreeItem receiver = (TreeItem) stack.pop();
|
||||
String methodName = method_info[methodIndex].getName(constants);
|
||||
stack.push(new CallStaticTreeItem(ins, receiver, methodName, args));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return -1 + 1 - ins.operands[1];
|
||||
}
|
||||
}
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.executing;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
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.treemodel.CallSuperTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.FullMultinameTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class CallSuperIns extends InstructionDefinition {
|
||||
|
||||
public CallSuperIns() {
|
||||
super(0x45, "callsuper", new int[]{AVM2Code.DAT_MULTINAME_INDEX, AVM2Code.DAT_ARG_COUNT});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(LocalDataArea lda, ConstantPool 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 classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
int multinameIndex = ins.operands[0];
|
||||
int argCount = ins.operands[1];
|
||||
List<TreeItem> args = new ArrayList<TreeItem>();
|
||||
for (int a = 0; a < argCount; a++) {
|
||||
args.add(0, (TreeItem) stack.pop());
|
||||
}
|
||||
FullMultinameTreeItem multiname = resolveMultiname(stack, constants, multinameIndex, ins);
|
||||
TreeItem receiver = (TreeItem) stack.pop();
|
||||
|
||||
stack.push(new CallSuperTreeItem(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.constant_multiname[multinameIndex].needsName()) {
|
||||
ret--;
|
||||
}
|
||||
if (abc.constants.constant_multiname[multinameIndex].needsNs()) {
|
||||
ret--;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.executing;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
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.treemodel.CallSuperTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.FullMultinameTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class CallSuperVoidIns extends InstructionDefinition {
|
||||
|
||||
public CallSuperVoidIns() {
|
||||
super(0x4e, "callsupervoid", new int[]{AVM2Code.DAT_MULTINAME_INDEX, AVM2Code.DAT_ARG_COUNT});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(LocalDataArea lda, ConstantPool 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 classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
int multinameIndex = ins.operands[0];
|
||||
int argCount = ins.operands[1];
|
||||
List<TreeItem> args = new ArrayList<TreeItem>();
|
||||
for (int a = 0; a < argCount; a++) {
|
||||
args.add(0, (TreeItem) stack.pop());
|
||||
}
|
||||
FullMultinameTreeItem multiname = resolveMultiname(stack, constants, multinameIndex, ins);
|
||||
TreeItem receiver = (TreeItem) stack.pop();
|
||||
|
||||
output.add(new CallSuperTreeItem(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.constant_multiname[multinameIndex].needsName()) {
|
||||
ret--;
|
||||
}
|
||||
if (abc.constants.constant_multiname[multinameIndex].needsNs()) {
|
||||
ret--;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.jumps;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
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.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.operations.EqTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.operations.NeqTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class IfEqIns extends InstructionDefinition implements IfTypeIns {
|
||||
|
||||
public IfEqIns() {
|
||||
super(0x13, "ifeq", new int[]{AVM2Code.DAT_OFFSET});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
TreeItem v2 = (TreeItem) stack.pop();
|
||||
TreeItem v1 = (TreeItem) stack.pop();
|
||||
stack.push(new EqTreeItem(ins, v1, v2));
|
||||
}
|
||||
|
||||
public void translateInverted(java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, AVM2Instruction ins) {
|
||||
TreeItem v2 = (TreeItem) stack.pop();
|
||||
TreeItem v1 = (TreeItem) stack.pop();
|
||||
stack.push(new NeqTreeItem(ins, v1, v2));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.jumps;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
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.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.operations.NotTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class IfFalseIns extends InstructionDefinition implements IfTypeIns {
|
||||
|
||||
public IfFalseIns() {
|
||||
super(0x12, "iffalse", new int[]{AVM2Code.DAT_OFFSET});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
TreeItem v1 = (TreeItem) stack.pop();
|
||||
stack.push(new NotTreeItem(ins, v1));
|
||||
}
|
||||
|
||||
public void translateInverted(java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, AVM2Instruction ins) {
|
||||
//String v1 = stack.pop().toString();
|
||||
//stack.push("(" + v1 + ")");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.jumps;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
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.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.operations.GeTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.operations.LtTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class IfGeIns extends InstructionDefinition implements IfTypeIns {
|
||||
|
||||
public IfGeIns() {
|
||||
super(0x18, "ifge", new int[]{AVM2Code.DAT_OFFSET});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
TreeItem v2 = (TreeItem) stack.pop();
|
||||
TreeItem v1 = (TreeItem) stack.pop();
|
||||
stack.push(new GeTreeItem(ins, v1, v2));
|
||||
}
|
||||
|
||||
public void translateInverted(java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, AVM2Instruction ins) {
|
||||
TreeItem v2 = (TreeItem) stack.pop();
|
||||
TreeItem v1 = (TreeItem) stack.pop();
|
||||
stack.push(new LtTreeItem(ins, v1, v2));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.jumps;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
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.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.operations.GtTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.operations.LeTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class IfGtIns extends InstructionDefinition implements IfTypeIns {
|
||||
|
||||
public IfGtIns() {
|
||||
super(0x17, "ifgt", new int[]{AVM2Code.DAT_OFFSET});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
TreeItem v2 = (TreeItem) stack.pop();
|
||||
TreeItem v1 = (TreeItem) stack.pop();
|
||||
stack.push(new GtTreeItem(ins, v1, v2));
|
||||
}
|
||||
|
||||
public void translateInverted(java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, AVM2Instruction ins) {
|
||||
TreeItem v2 = (TreeItem) stack.pop();
|
||||
TreeItem v1 = (TreeItem) stack.pop();
|
||||
stack.push(new LeTreeItem(ins, v1, v2));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.jumps;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
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.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.operations.GtTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.operations.LeTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class IfLeIns extends InstructionDefinition implements IfTypeIns {
|
||||
|
||||
public IfLeIns() {
|
||||
super(0x16, "ifle", new int[]{AVM2Code.DAT_OFFSET});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
TreeItem v2 = (TreeItem) stack.pop();
|
||||
TreeItem v1 = (TreeItem) stack.pop();
|
||||
stack.push(new LeTreeItem(ins, v1, v2));
|
||||
}
|
||||
|
||||
public void translateInverted(java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, AVM2Instruction ins) {
|
||||
TreeItem v2 = (TreeItem) stack.pop();
|
||||
TreeItem v1 = (TreeItem) stack.pop();
|
||||
stack.push(new GtTreeItem(ins, v1, v2));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.jumps;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
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.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.operations.GeTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.operations.LtTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class IfLtIns extends InstructionDefinition implements IfTypeIns {
|
||||
|
||||
public IfLtIns() {
|
||||
super(0x15, "iflt", new int[]{AVM2Code.DAT_OFFSET});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
TreeItem v2 = (TreeItem) stack.pop();
|
||||
TreeItem v1 = (TreeItem) stack.pop();
|
||||
stack.push(new LtTreeItem(ins, v1, v2));
|
||||
}
|
||||
|
||||
public void translateInverted(java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, AVM2Instruction ins) {
|
||||
TreeItem v2 = (TreeItem) stack.pop();
|
||||
TreeItem v1 = (TreeItem) stack.pop();
|
||||
stack.push(new GeTreeItem(ins, v1, v2));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.jumps;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
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.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.operations.GeTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.operations.LtTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class IfNGeIns extends InstructionDefinition implements IfTypeIns {
|
||||
|
||||
public IfNGeIns() {
|
||||
super(0x0f, "ifnge", new int[]{AVM2Code.DAT_OFFSET});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
TreeItem v2 = (TreeItem) stack.pop();
|
||||
TreeItem v1 = (TreeItem) stack.pop();
|
||||
stack.push(new LtTreeItem(ins, v1, v2));
|
||||
}
|
||||
|
||||
public void translateInverted(java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, AVM2Instruction ins) {
|
||||
TreeItem v2 = (TreeItem) stack.pop();
|
||||
TreeItem v1 = (TreeItem) stack.pop();
|
||||
stack.push(new GeTreeItem(ins, v1, v2));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.jumps;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
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.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.operations.GtTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.operations.LeTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class IfNGtIns extends InstructionDefinition implements IfTypeIns {
|
||||
|
||||
public IfNGtIns() {
|
||||
super(0x0e, "ifngt", new int[]{AVM2Code.DAT_OFFSET});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
TreeItem v2 = (TreeItem) stack.pop();
|
||||
TreeItem v1 = (TreeItem) stack.pop();
|
||||
stack.push(new LeTreeItem(ins, v1, v2));
|
||||
}
|
||||
|
||||
public void translateInverted(java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, AVM2Instruction ins) {
|
||||
TreeItem v2 = (TreeItem) stack.pop();
|
||||
TreeItem v1 = (TreeItem) stack.pop();
|
||||
stack.push(new GtTreeItem(ins, v1, v2));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.jumps;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
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.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.operations.GtTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.operations.LeTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class IfNLeIns extends InstructionDefinition implements IfTypeIns {
|
||||
|
||||
public IfNLeIns() {
|
||||
super(0x0d, "ifnle", new int[]{AVM2Code.DAT_OFFSET});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
TreeItem v2 = (TreeItem) stack.pop();
|
||||
TreeItem v1 = (TreeItem) stack.pop();
|
||||
stack.push(new GtTreeItem(ins, v1, v2));
|
||||
}
|
||||
|
||||
public void translateInverted(java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, AVM2Instruction ins) {
|
||||
TreeItem v2 = (TreeItem) stack.pop();
|
||||
TreeItem v1 = (TreeItem) stack.pop();
|
||||
stack.push(new LeTreeItem(ins, v1, v2));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.jumps;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
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.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.operations.GeTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.operations.LtTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class IfNLtIns extends InstructionDefinition implements IfTypeIns {
|
||||
|
||||
public IfNLtIns() {
|
||||
super(0x0c, "ifnlt", new int[]{AVM2Code.DAT_OFFSET});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
TreeItem v2 = (TreeItem) stack.pop();
|
||||
TreeItem v1 = (TreeItem) stack.pop();
|
||||
stack.push(new GeTreeItem(ins, v1, v2));
|
||||
}
|
||||
|
||||
public void translateInverted(java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, AVM2Instruction ins) {
|
||||
TreeItem v2 = (TreeItem) stack.pop();
|
||||
TreeItem v1 = (TreeItem) stack.pop();
|
||||
stack.push(new LtTreeItem(ins, v1, v2));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.jumps;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
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.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.operations.EqTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.operations.NeqTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class IfNeIns extends InstructionDefinition implements IfTypeIns {
|
||||
|
||||
public IfNeIns() {
|
||||
super(0x14, "ifne", new int[]{AVM2Code.DAT_OFFSET});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
TreeItem v2 = (TreeItem) stack.pop();
|
||||
TreeItem v1 = (TreeItem) stack.pop();
|
||||
stack.push(new NeqTreeItem(ins, v1, v2));
|
||||
}
|
||||
|
||||
public void translateInverted(java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, AVM2Instruction ins) {
|
||||
TreeItem v2 = (TreeItem) stack.pop();
|
||||
TreeItem v1 = (TreeItem) stack.pop();
|
||||
stack.push(new EqTreeItem(ins, v1, v2));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.jumps;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
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.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.operations.StrictEqTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.operations.StrictNeqTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class IfStrictEqIns extends InstructionDefinition implements IfTypeIns {
|
||||
|
||||
public IfStrictEqIns() {
|
||||
super(0x19, "ifstricteq", new int[]{AVM2Code.DAT_OFFSET});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
TreeItem v2 = (TreeItem) stack.pop();
|
||||
TreeItem v1 = (TreeItem) stack.pop();
|
||||
stack.push(new StrictEqTreeItem(ins, v1, v2));
|
||||
}
|
||||
|
||||
public void translateInverted(java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, AVM2Instruction ins) {
|
||||
TreeItem v2 = (TreeItem) stack.pop();
|
||||
TreeItem v1 = (TreeItem) stack.pop();
|
||||
stack.push(new StrictNeqTreeItem(ins, v1, v2));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.jumps;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
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.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.operations.StrictEqTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.operations.StrictNeqTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class IfStrictNeIns extends InstructionDefinition implements IfTypeIns {
|
||||
|
||||
public IfStrictNeIns() {
|
||||
super(0x1A, "ifstrictne", new int[]{AVM2Code.DAT_OFFSET});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
TreeItem v2 = (TreeItem) stack.pop();
|
||||
TreeItem v1 = (TreeItem) stack.pop();
|
||||
stack.push(new StrictNeqTreeItem(ins, v1, v2));
|
||||
}
|
||||
|
||||
public void translateInverted(java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, AVM2Instruction ins) {
|
||||
TreeItem v2 = (TreeItem) stack.pop();
|
||||
TreeItem v1 = (TreeItem) stack.pop();
|
||||
stack.push(new StrictEqTreeItem(ins, v1, v2));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.jumps;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
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.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.operations.NotTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class IfTrueIns extends InstructionDefinition implements IfTypeIns {
|
||||
|
||||
public IfTrueIns() {
|
||||
super(0x11, "iftrue", new int[]{AVM2Code.DAT_OFFSET});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
//String v1 = stack.pop().toString();
|
||||
//stack.push("(" + v1 + ")");
|
||||
}
|
||||
|
||||
public void translateInverted(java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, AVM2Instruction ins) {
|
||||
TreeItem v1 = (TreeItem) stack.pop();
|
||||
stack.push(new NotTreeItem(ins, v1));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.jumps;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
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.treemodel.BooleanTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class JumpIns extends InstructionDefinition implements IfTypeIns {
|
||||
|
||||
public JumpIns() {
|
||||
super(0x10, "jump", new int[]{AVM2Code.DAT_OFFSET});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
stack.push(new BooleanTreeItem(ins, Boolean.TRUE));// + ins.operands[0]);
|
||||
}
|
||||
|
||||
public void translateInverted(java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, AVM2Instruction ins) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.jumps;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class LookupSwitchIns extends InstructionDefinition {
|
||||
|
||||
public LookupSwitchIns() {
|
||||
super(0x1b, "lookupswitch", new int[]{AVM2Code.DAT_CASE_BASEOFFSET, AVM2Code.OPT_CASE_OFFSETS});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
int defaultOffset = ins.operands[0];
|
||||
int caseCount = ins.operands[1];
|
||||
//stack.push("switch(...)");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.localregs;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
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.treemodel.DecLocalTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class DecLocalIIns extends InstructionDefinition {
|
||||
|
||||
public DecLocalIIns() {
|
||||
super(0xc3, "declocal_i", new int[]{AVM2Code.DAT_LOCAL_REG_INDEX});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(LocalDataArea lda, ConstantPool 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).longValue() - 1;
|
||||
lda.localRegisters.put(locRegIndex, obj2);
|
||||
} else if (obj instanceof Double) {
|
||||
Double obj2 = ((Double) obj).doubleValue() - 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 classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
int regIndex = ins.operands[0];
|
||||
output.add(new DecLocalTreeItem(ins, regIndex));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.localregs;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
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.treemodel.DecLocalTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class DecLocalIns extends InstructionDefinition {
|
||||
|
||||
public DecLocalIns() {
|
||||
super(0x94, "declocal", new int[]{AVM2Code.DAT_LOCAL_REG_INDEX});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(LocalDataArea lda, ConstantPool 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).longValue() - 1;
|
||||
lda.localRegisters.put(locRegIndex, obj2);
|
||||
} else if (obj instanceof Double) {
|
||||
Double obj2 = ((Double) obj).doubleValue() - 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 classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
int regIndex = ins.operands[0];
|
||||
output.add(new DecLocalTreeItem(ins, regIndex));
|
||||
}
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.localregs;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
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.treemodel.ClassTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.ThisTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class GetLocal0Ins extends InstructionDefinition implements GetLocalTypeIns {
|
||||
|
||||
public GetLocal0Ins() {
|
||||
super(0xd0, "getlocal_0", new int[]{});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(LocalDataArea lda, ConstantPool constants, List arguments) {
|
||||
lda.operandStack.push(lda.localRegisters.get(0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
if (isStatic) {
|
||||
stack.push(new ClassTreeItem(abc.instance_info[classIndex].getName(constants)));
|
||||
} else {
|
||||
stack.push(new ThisTreeItem(abc.instance_info[classIndex].getName(constants)));
|
||||
}
|
||||
}
|
||||
|
||||
public int getRegisterId(AVM2Instruction par0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.localregs;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
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.treemodel.LocalRegTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class GetLocal1Ins extends InstructionDefinition implements GetLocalTypeIns {
|
||||
|
||||
public GetLocal1Ins() {
|
||||
super(0xd1, "getlocal_1", new int[]{});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(LocalDataArea lda, ConstantPool constants, List arguments) {
|
||||
lda.operandStack.push(lda.localRegisters.get(1));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
stack.push(new LocalRegTreeItem(ins, 1, localRegs.get(1)));
|
||||
}
|
||||
|
||||
public int getRegisterId(AVM2Instruction par0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.localregs;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
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.treemodel.LocalRegTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class GetLocal2Ins extends InstructionDefinition implements GetLocalTypeIns {
|
||||
|
||||
public GetLocal2Ins() {
|
||||
super(0xd2, "getlocal_2", new int[]{});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(LocalDataArea lda, ConstantPool constants, List arguments) {
|
||||
lda.operandStack.push(lda.localRegisters.get(2));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
stack.push(new LocalRegTreeItem(ins, 2, localRegs.get(2)));
|
||||
}
|
||||
|
||||
public int getRegisterId(AVM2Instruction par0) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.localregs;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
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.treemodel.LocalRegTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.TreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class GetLocal3Ins extends InstructionDefinition implements GetLocalTypeIns {
|
||||
|
||||
public GetLocal3Ins() {
|
||||
super(0xd3, "getlocal_3", new int[]{});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(LocalDataArea lda, ConstantPool constants, List arguments) {
|
||||
lda.operandStack.push(lda.localRegisters.get(3));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, java.util.Stack<TreeItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<TreeItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
stack.push(new LocalRegTreeItem(ins, 3, localRegs.get(3)));
|
||||
}
|
||||
|
||||
public int getRegisterId(AVM2Instruction par0) {
|
||||
return 3;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackDelta(AVM2Instruction ins, ABC abc) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user