initial commit
This commit is contained in:
commit
e2d0f5d9c3
8
.classpath
Normal file
8
.classpath
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="src" path="timer"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry kind="lib" path="lib/timer/timer.jar"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
17
.project
Normal file
17
.project
Normal file
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>Fernflower</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
3
.settings/org.eclipse.core.resources.prefs
Normal file
3
.settings/org.eclipse.core.resources.prefs
Normal file
@ -0,0 +1,3 @@
|
||||
#Mon Oct 11 16:34:37 CEST 2010
|
||||
eclipse.preferences.version=1
|
||||
encoding//src/test/misc/en/InnerTest.java=UTF-8
|
11
.settings/org.eclipse.jdt.core.prefs
Normal file
11
.settings/org.eclipse.jdt.core.prefs
Normal file
@ -0,0 +1,11 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
|
||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||
org.eclipse.jdt.core.compiler.compliance=1.7
|
||||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.source=1.7
|
6
bin/.gitignore
vendored
Normal file
6
bin/.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
/HRTimerResolution.class
|
||||
/SystemTimerResolution.class
|
||||
/com
|
||||
/de
|
||||
/native
|
||||
/test
|
131
build.xml
Normal file
131
build.xml
Normal file
@ -0,0 +1,131 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<project name="Fernflower" default="buildAll" basedir=".">
|
||||
|
||||
<taskdef resource="proguard/ant/task.properties"
|
||||
classpath="${basedir}/lib/proguard_4_11.jar" />
|
||||
|
||||
<taskdef name="javancss"
|
||||
classname="javancss.JavancssAntTask">
|
||||
<classpath>
|
||||
<pathelement path="${classpath}"/>
|
||||
<pathelement location="${basedir}/lib/ncss/javancss.jar"/>
|
||||
<pathelement location="${basedir}/lib/ncss/javacc.jar"/>
|
||||
<pathelement location="${basedir}/lib/ncss/ccl.jar"/>
|
||||
</classpath>
|
||||
</taskdef>
|
||||
|
||||
<target name="init" description="initialization">
|
||||
<property name="jar.file" value="fernflower.jar" />
|
||||
<property name="timer.jar.file" value="timer.jar" />
|
||||
<property name="bin" value="${basedir}/bin" />
|
||||
<property name="lib" value="${basedir}/lib" />
|
||||
<property name="fulldist" value="${basedir}/dist/full" />
|
||||
<property name="obfuscateddist" value="${basedir}/dist/obfuscated" />
|
||||
|
||||
<property name="tomcat" value="C:/revjava/apache-tomcat-5.5.27/shared/lib/" />
|
||||
<property name="webwrapper" value="D:/Nonbku/workspace/webwrapper/lib/" />
|
||||
</target>
|
||||
|
||||
<target name="buildAll" depends="init, jar, obfuscate" description="build full distribution paket"/>
|
||||
|
||||
<target name="timer" depends="init" description="generate timer jar file">
|
||||
<jar jarfile="${lib}/timer/${timer.jar.file}" compress="true" basedir="${bin}" includes="com/**/*.class,*.class"/>
|
||||
</target>
|
||||
|
||||
<target name="jar" depends="init" description="generate jar file">
|
||||
<jar jarfile="${fulldist}/${jar.file}" compress="true" basedir="${bin}" includes="**/*.class" excludes="test/**/*.*,com/**/*.*,*.class">
|
||||
<manifest>
|
||||
<attribute name="Main-Class" value="de.fernflower.main.decompiler.ConsoleDecompiler"/>
|
||||
</manifest>
|
||||
</jar>
|
||||
</target>
|
||||
|
||||
<target name="deploy" depends="jar" description="deploy generated jar file to Tomcat">
|
||||
<copy todir="${webwrapper}" file="${fulldist}/${jar.file}" overwrite="true"/>
|
||||
<copy todir="${tomcat}" file="${fulldist}/${jar.file}" overwrite="true"/>
|
||||
</target>
|
||||
|
||||
<target name="loc" description="count lines of code">
|
||||
<javancss srcdir="${basedir}/src"
|
||||
generateReport="true"
|
||||
functionMetrics="false"
|
||||
classMetrics="false"
|
||||
includes="**/*.java"
|
||||
excludes="**/test/**,**/de/fernflower/code/instructions/**,**/timer/**"
|
||||
/>
|
||||
</target>
|
||||
|
||||
|
||||
<target name="obfuscate" description="Call Proguard on Fernflower">
|
||||
<!-- 4.0.1 -->
|
||||
<proguard>
|
||||
|
||||
-injars "${fulldist}/${jar.file}"
|
||||
-outjars "${obfuscateddist}/${jar.file}"
|
||||
-libraryjars "${java.home}/lib/rt.jar"
|
||||
|
||||
-forceprocessing
|
||||
-repackageclasses
|
||||
<!-- -allowaccessmodification -->
|
||||
|
||||
-optimizationpasses 5
|
||||
|
||||
-keep public class de.fernflower.main.decompiler.ConsoleDecompiler {
|
||||
public protected *;
|
||||
}
|
||||
|
||||
-keep public class de.fernflower.main.decompiler.EclipseDecompiler {
|
||||
public protected *;
|
||||
}
|
||||
|
||||
-keep public class de.fernflower.main.extern.* {
|
||||
public protected *;
|
||||
}
|
||||
|
||||
<!--
|
||||
-keep public class de.fernflower.code.instructions.* {
|
||||
public protected *;
|
||||
}
|
||||
-->
|
||||
|
||||
</proguard>
|
||||
</target>
|
||||
|
||||
<target name="printunused" depends="init" description="Print unused code">
|
||||
<proguard>
|
||||
|
||||
-injars ${fulldist}/${jar.file}
|
||||
-libraryjars ${java.home}/lib/rt.jar
|
||||
|
||||
-dontoptimize
|
||||
-dontobfuscate
|
||||
-dontpreverify
|
||||
-printusage
|
||||
|
||||
<!--
|
||||
-whyareyoukeeping public class de.fernflower.code.instructions.ALOAD {
|
||||
public *;
|
||||
}
|
||||
-->
|
||||
|
||||
-keep public class de.fernflower.main.decompiler.ConsoleDecompiler {
|
||||
public protected *;
|
||||
}
|
||||
|
||||
-keep public class de.fernflower.main.decompiler.EclipseDecompiler {
|
||||
public protected *;
|
||||
}
|
||||
|
||||
-keep public class de.fernflower.main.extern.* {
|
||||
public protected *;
|
||||
}
|
||||
|
||||
<!--
|
||||
-keep public class de.fernflower.code.instructions.*
|
||||
-->
|
||||
|
||||
</proguard>
|
||||
</target>
|
||||
|
||||
</project>
|
51
dist/docs/license_en.txt
vendored
Normal file
51
dist/docs/license_en.txt
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
Fernflower Freeware License 1.0
|
||||
|
||||
This license applies to the Fernflower decompiler (hereafter “Software")
|
||||
including any associated files, information and examples.
|
||||
|
||||
You are hereby granted a non-exclusive and non-transferable license to
|
||||
use and distribute the Software in binary form according to the following
|
||||
terms and conditions.
|
||||
|
||||
|
||||
1) Copies and Redistribution
|
||||
|
||||
You may copy and distribute unmodified binary copies of the Software
|
||||
provided that you keep this license intact. You must NOT charge money
|
||||
or fees for the Software except to cover the absolutely necessary
|
||||
distribution costs.
|
||||
|
||||
Any other form of redistribution is prohibited. Especially you are not
|
||||
allowed to redistribute the Software as part of any other software
|
||||
collection or other product.
|
||||
|
||||
|
||||
2) Use
|
||||
|
||||
You may use the Software "as is" in any commercial or non-commercial environment
|
||||
for any purpose.
|
||||
|
||||
|
||||
3) Contact Information
|
||||
|
||||
The sole author and owner of Fernflower is Stiver. Address all correspondence regarding
|
||||
this license to:
|
||||
|
||||
fernflower.decompiler@gmail.com
|
||||
|
||||
http://www.reversed-java.com
|
||||
|
||||
|
||||
4) Disclaimer of Warranty
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
62
dist/docs/lizenz_de.txt
vendored
Normal file
62
dist/docs/lizenz_de.txt
vendored
Normal file
@ -0,0 +1,62 @@
|
||||
Fernflower Freeware Lizenz 1.0
|
||||
|
||||
Gegenstand der vorliegenden Lizenz ist der Fernflower Decompiler (im Folgenden "Software" genannt)
|
||||
einschließlich aller dazu gehörenden Dateien, Informationen und Beispiele.
|
||||
|
||||
Hiermit erhalten Sie eine nicht-ausschließliche und nicht-übertragbare Lizenz
|
||||
für die Nutzung und Weitergabe der Software gemäß den nachfolgenden
|
||||
Bedingungen.
|
||||
|
||||
|
||||
1) Kopieren und Weitergeben
|
||||
|
||||
Sie dürfen die Software kopieren und exakte Binärkopien unverändert
|
||||
weitergeben, vorausgesetzt, diese Lizenz bleibt in der ursprünglichen Form
|
||||
erhalten. Sie dürfen KEINE wie auch immer geartete Bezahlung oder Gebühren
|
||||
für die Software verlangen, außer um die absolut unvermeidbaren Selbstkosten
|
||||
der Weitergabe zu decken.
|
||||
|
||||
Jede andere Form der Weitergabe ist untersagt. Insbesondere ist es nicht gestattet,
|
||||
die Software als Teil einer anderen Softwaresammlung oder eines anderen Produktes
|
||||
weiterzugeben.
|
||||
|
||||
|
||||
2) Nutzung
|
||||
|
||||
Sie können die Software beliebig in jeder kommerziellen oder nicht-kommerziellen Umgebung
|
||||
zu jedem Zweck einsetzen.
|
||||
|
||||
|
||||
3) Kontaktinformation
|
||||
|
||||
Der einzige Autor und Eigentümer von Fernflower ist Stiver. Alle Rückfragen bezüglich dieser Lizenz
|
||||
sind an
|
||||
|
||||
fernflower.decompiler@gmail.com
|
||||
|
||||
http://www.reversed-java.com
|
||||
|
||||
zu richten.
|
||||
|
||||
|
||||
4) GARANTIE- UND HAFTUNGSBESCHRÄNKUNGEN
|
||||
|
||||
DIESE SOFTWARE WIRD IHNEN AUF DER GRUNDLAGE DES GEGENWÄRTIGEN ZUSTANDS ZUR
|
||||
VERFÜGUNG GESTELLT. ES GIBT KEINE GARANTIE, WEDER AUSDRÜCKLICH NOCH IMPLIZIT.
|
||||
DIES SCHLIEßT AUCH GARANTIEANSPRÜCHE BEZÜGLICH DER VERKAUFSQUALITÄT,
|
||||
VERKÄUFLICHKEIT ODER EIGNUNG FÜR EINEN BESTIMMTEN ZWECk AUS, ODER SOLCHE, DIE
|
||||
DURCH GELTENDES RECHT, GESETZLICHE VORSCHRIFTEN, GESCHÄFTSGEBRAUCH ODER
|
||||
HANDELSVERKEHR VERURSACHT WERDEN. DAS GESAMTE RISIKO IN BEZUG AUF DIE ERGEBNISSE
|
||||
UND DIE LEISTUNG DES PROGRAMMS LIEGT BEI IHNEN. WEDER DER AUTOR NOCH IRGENDEIN
|
||||
AN DEM PROJEKT BETEILIGTER HAT IRGENDEINE HAFTUNGSVERPFLICHTUNG IHNEN ODER
|
||||
IRGENDEINER ANDEREN PERSON ODER INSTITUTION GEGENÜBER FÜR JEDWEDE INDIREKTE,
|
||||
ZUFÄLLIGE, BESONDERE SCHÄDEN ODER IRGENDWELCHE FOLGESCHÄDEN. DIES GILT AUCH FÜR
|
||||
SCHÄDEN AUS ENTGANGENEM GEWINN, VERLORENEN ODER BESCHÄDIGTEN DATEN ODER FÜR
|
||||
ANDERE KOMMERZIELLE ODER WIRTSCHAFTLICHE VERLUSTE, SELBST DANN, WENN DER AUTOR
|
||||
ODER IRGENDEIN AN DEM PROJEKT BETEILIGTER AUF DIE MÖGLICHKEIT DERARTIGER SCHÄDEN
|
||||
HINGEWIESEN WURDE ODER DIESE VORHERSEHBAR WAREN, ODER FÜR ANSPRÜCHE DRITTER. DIE
|
||||
HIER FESTGELEGTEN HAFTUNGSBESCHRÄNKUNGEN GELTEN UNABHÄNGUG DAVON, OB DER VERMEINTLICHE
|
||||
ODER TATSÄCHLICHE VERTRAGSBRUCH EINE GRUNDSÄTZLICHE BEDINGUNG ODER
|
||||
VERTRAGSVEREINBARUNG BERÜHRT, ODER EIN GRUNDSÄTZLICHER VERTRAGSBRUCH IST. DIESER
|
||||
ABSATZ IST EIN ESSENZIELLER TEIL DIESER LIZENZ. ES IST VERBOTEN DAS PROGRAMM ZU
|
||||
BENUTZEN OHNE DASS DIESEM ABSATZ ZUGESTIMMT WIRD.
|
86
dist/docs/readme.txt
vendored
Normal file
86
dist/docs/readme.txt
vendored
Normal file
@ -0,0 +1,86 @@
|
||||
1. About the decompiler
|
||||
|
||||
Fernflower is the first actually working analytical decompiler for Java and
|
||||
probably for a high-level programming language in general. Naturally it is still
|
||||
under development, please send your bug reports and improvement suggestions at
|
||||
fernflower.decompiler@gmail.com
|
||||
|
||||
|
||||
2. License
|
||||
|
||||
See license_en.txt
|
||||
|
||||
|
||||
3. Running from the command line
|
||||
|
||||
java -jar fernflower.jar [-<option>=<value>]* [<source>]+ <destination>
|
||||
|
||||
* means 0 or more times
|
||||
+ means 1 or more times
|
||||
|
||||
<source>: file or directory with files to be decompiled. Directories are recursively scanned. Allowed file extensions are class, zip and jar.
|
||||
Sources prefixed with -e= mean "library" files that won't be decompiled, but taken into account when analysing relationships between
|
||||
classes or methods. Especially renaming of identifiers (s. option 'ren') can benefit from information about external classes.
|
||||
<destination>: destination directory
|
||||
<option>,<value>: command line option with the corresponding value, see 4.
|
||||
|
||||
Examples:
|
||||
|
||||
java -jar fernflower.jar -hes=0 -hdc=0 c:\Temp\binary\ -e=c:\Java\rt.jar c:\Temp\source\
|
||||
|
||||
java -jar fernflower.jar -dgs=1 c:\Temp\binary\library.jar c:\Temp\binary\Boot.class c:\Temp\source\
|
||||
|
||||
|
||||
4. Command line options
|
||||
|
||||
With the exception of mpm and urc the value of 1 means the option is activated, 0 - deactivated. Default
|
||||
value, if any, is given between parentheses.
|
||||
|
||||
Typically, the following options will be changed by user, if any: hes, hdc, dgs, mpm, ren, urc
|
||||
The rest of options can be left as they are: they are aimed at professional reverse engineers.
|
||||
|
||||
rbr (1): hide bridge methods
|
||||
rsy (0): hide synthetic class members
|
||||
din (1): decompile inner classes
|
||||
dc4 (1): collapse 1.4 class references
|
||||
das (1): decompile assertions
|
||||
hes (1): hide empty super invocation
|
||||
hdc (1): hide empty default constructor
|
||||
dgs (0): decompile generic signatures
|
||||
occ (0): ouput copyright comment
|
||||
ner (1): assume return not throwing exceptions
|
||||
den (1): decompile enumerations
|
||||
rgn (1): remove getClass() invocation, when it is part of a qualified new statement
|
||||
bto (1): interpret int 1 as boolean true (workaround to a compiler bug)
|
||||
nns (1): allow for not set synthetic attribute (workaround to a compiler bug)
|
||||
uto (1): consider nameless types as java.lang.Object (workaround to a compiler architecture flaw)
|
||||
udv (1): reconstruct variable names from debug information, if present
|
||||
rer (1): remove empty exception ranges
|
||||
fdi (1): deinline finally structures
|
||||
asc (0): allow only ASCII characters in string literals. All other characters will be encoded using Unicode escapes (JLS 3.3). Default encoding is UTF8.
|
||||
mpm (0): maximum allowed processing time per decompiled method, in seconds. 0 means no upper limit.
|
||||
ren (0): rename ambiguous (resp. obfuscated) classes and class elements
|
||||
urc : full name of user-supplied class implementing IIdentifierRenamer. It is used to determine which
|
||||
class identifiers should be renamed and provides new identifier names. For more information
|
||||
s. section 5
|
||||
|
||||
The default logging level is INFO. This value can be overwritten by setting the option 'log' as follows:
|
||||
|
||||
log (INFO): possible values TRACE, INFO, WARN, ERROR
|
||||
|
||||
|
||||
5. Renaming identifiers
|
||||
|
||||
Some obfuscators give classes and their member elements short, meaningless and above all ambiguous names. Recompiling of such
|
||||
code leads to a great number of conflicts. Therefore it is advisable to let the decompiler rename elements in its turn,
|
||||
ensuring uniqueness of each identifier.
|
||||
|
||||
Option 'ren' (i.e. -ren=1) activates renaming functionality. Default renaming strategy goes as follows:
|
||||
- rename an element if its name is a reserved word or is shorter than 3 characters
|
||||
- new names are built according to a simple pattern: (class|method|field)_<consecutive unique number>
|
||||
You can overwrite this rules by providing your own implementation of the 4 key methods invoked by the decompiler while renaming. Simply
|
||||
pass a class that implements de.fernflower.main.extern.IIdentifierRenamer in the option 'urc' (e.g. -urc=com.mypackage.MyRenamer) to
|
||||
Fernflower. The class must be available on the application classpath.
|
||||
|
||||
The meaning of each method should be clear from naming: toBeRenamed determine whether the element will be renamed, while the other three
|
||||
provide new names for classes, methods and fields respectively.
|
BIN
dist/full/fernflower.jar
vendored
Normal file
BIN
dist/full/fernflower.jar
vendored
Normal file
Binary file not shown.
BIN
dist/obfuscated/fernflower.jar
vendored
Normal file
BIN
dist/obfuscated/fernflower.jar
vendored
Normal file
Binary file not shown.
BIN
lib/ncss/ccl.jar
Normal file
BIN
lib/ncss/ccl.jar
Normal file
Binary file not shown.
BIN
lib/ncss/javacc.jar
Normal file
BIN
lib/ncss/javacc.jar
Normal file
Binary file not shown.
BIN
lib/ncss/javancss.jar
Normal file
BIN
lib/ncss/javancss.jar
Normal file
Binary file not shown.
BIN
lib/proguard.jar
Normal file
BIN
lib/proguard.jar
Normal file
Binary file not shown.
BIN
lib/proguard_4_11.jar
Normal file
BIN
lib/proguard_4_11.jar
Normal file
Binary file not shown.
BIN
lib/timer/hrtlib.dll
Normal file
BIN
lib/timer/hrtlib.dll
Normal file
Binary file not shown.
BIN
lib/timer/timer.jar
Normal file
BIN
lib/timer/timer.jar
Normal file
Binary file not shown.
347
src/de/fernflower/code/CodeConstants.java
Normal file
347
src/de/fernflower/code/CodeConstants.java
Normal file
@ -0,0 +1,347 @@
|
||||
/*
|
||||
* Fernflower - The Analytical Java Decompiler
|
||||
* http://www.reversed-java.com
|
||||
*
|
||||
* (C) 2008 - 2010, Stiver
|
||||
*
|
||||
* This software is NEITHER public domain NOR free software
|
||||
* as per GNU License. See license.txt for more details.
|
||||
*
|
||||
* This software is distributed WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
package de.fernflower.code;
|
||||
|
||||
public interface CodeConstants {
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// VARIABLE TYPES
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
public final static int TYPE_BYTE = 0;
|
||||
public final static int TYPE_CHAR = 1;
|
||||
public final static int TYPE_DOUBLE = 2;
|
||||
public final static int TYPE_FLOAT = 3;
|
||||
public final static int TYPE_INT = 4;
|
||||
public final static int TYPE_LONG = 5;
|
||||
public final static int TYPE_SHORT = 6;
|
||||
public final static int TYPE_BOOLEAN = 7;
|
||||
public final static int TYPE_OBJECT = 8;
|
||||
public final static int TYPE_ADDRESS = 9;
|
||||
public final static int TYPE_VOID = 10;
|
||||
public final static int TYPE_ANY = 11;
|
||||
public final static int TYPE_GROUP2EMPTY = 12;
|
||||
public final static int TYPE_NULL = 13;
|
||||
public final static int TYPE_NOTINITIALIZED = 14;
|
||||
public final static int TYPE_BYTECHAR = 15;
|
||||
public final static int TYPE_SHORTCHAR = 16;
|
||||
public final static int TYPE_UNKNOWN = 17;
|
||||
public final static int TYPE_GENVAR = 18;
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// VARIABLE TYPE FAMILIES
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
public final static int TYPE_FAMILY_UNKNOWN = 0;
|
||||
public final static int TYPE_FAMILY_BOOLEAN = 1;
|
||||
public final static int TYPE_FAMILY_INTEGER = 2;
|
||||
public final static int TYPE_FAMILY_FLOAT = 3;
|
||||
public final static int TYPE_FAMILY_LONG = 4;
|
||||
public final static int TYPE_FAMILY_DOUBLE = 5;
|
||||
public final static int TYPE_FAMILY_OBJECT = 6;
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// MODULE CONSTANTS
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
public final static int STACKSIZE_SIMPLE = 1;
|
||||
public final static int STACKSIZE_DOUBLE = 2;
|
||||
|
||||
public final static int VAR_LOCAL = 0;
|
||||
public final static int VAR_STACK = 1;
|
||||
|
||||
public final static int VAR_WRITE = 0;
|
||||
public final static int VAR_READ = 1;
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// ACCESS FLAGS
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
public final static int ACC_PUBLIC = 0x0001;
|
||||
public final static int ACC_PRIVATE = 0x0002;
|
||||
public final static int ACC_PROTECTED = 0x0004;
|
||||
public final static int ACC_STATIC = 0x0008;
|
||||
public final static int ACC_FINAL = 0x0010;
|
||||
public final static int ACC_SYNCHRONIZED = 0x0020;
|
||||
public final static int ACC_NATIVE = 0x0100;
|
||||
public final static int ACC_ABSTRACT = 0x0400;
|
||||
public final static int ACC_STRICT = 0x0800;
|
||||
public final static int ACC_VOLATILE = 0x0040;
|
||||
public final static int ACC_BRIDGE = 0x0040;
|
||||
public final static int ACC_TRANSIENT = 0x0080;
|
||||
public final static int ACC_VARARGS = 0x0080;
|
||||
public final static int ACC_SYNTHETIC = 0x1000;
|
||||
public final static int ACC_ANNOTATION = 0x2000;
|
||||
public final static int ACC_ENUM = 0x4000;
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// CLASS FLAGS
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
public final static int ACC_SUPER = 0x0020;
|
||||
public final static int ACC_INTERFACE = 0x0200;
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// DEPENDENCY CONSTANTS
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
public final static int DEP_CONSTANT = 0;
|
||||
public final static int DEP_UNKNOWN = 1;
|
||||
public final static int DEP_GENERAL = 2;
|
||||
public final static int DEP_PARAMS = 4;
|
||||
public final static int DEP_STATIC = 8;
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// INSTRUCTION GROUPS
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
public final static int GROUP_GENERAL = 1;
|
||||
public final static int GROUP_JUMP = 2;
|
||||
public final static int GROUP_SWITCH = 3;
|
||||
public final static int GROUP_INVOCATION = 4;
|
||||
public final static int GROUP_FIELDACCESS = 5;
|
||||
public final static int GROUP_RETURN = 6;
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// POOL CONSTANTS
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
public final static int CONSTANT_Utf8 = 1;
|
||||
public final static int CONSTANT_Integer = 3;
|
||||
public final static int CONSTANT_Float = 4;
|
||||
public final static int CONSTANT_Long = 5;
|
||||
public final static int CONSTANT_Double = 6;
|
||||
public final static int CONSTANT_Class = 7;
|
||||
public final static int CONSTANT_String = 8;
|
||||
public final static int CONSTANT_Fieldref = 9;
|
||||
public final static int CONSTANT_Methodref = 10;
|
||||
public final static int CONSTANT_InterfaceMethodref = 11;
|
||||
public final static int CONSTANT_NameAndType = 12;
|
||||
public final static int CONSTANT_MethodHandle = 15;
|
||||
public final static int CONSTANT_MethodType = 16;
|
||||
public final static int CONSTANT_InvokeDynamic = 18;
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// VM OPCODES
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
public final static int opc_nop = 0;
|
||||
public final static int opc_aconst_null = 1;
|
||||
public final static int opc_iconst_m1 = 2;
|
||||
public final static int opc_iconst_0 = 3;
|
||||
public final static int opc_iconst_1 = 4;
|
||||
public final static int opc_iconst_2 = 5;
|
||||
public final static int opc_iconst_3 = 6;
|
||||
public final static int opc_iconst_4 = 7;
|
||||
public final static int opc_iconst_5 = 8;
|
||||
public final static int opc_lconst_0 = 9;
|
||||
public final static int opc_lconst_1 = 10;
|
||||
public final static int opc_fconst_0 = 11;
|
||||
public final static int opc_fconst_1 = 12;
|
||||
public final static int opc_fconst_2 = 13;
|
||||
public final static int opc_dconst_0 = 14;
|
||||
public final static int opc_dconst_1 = 15;
|
||||
public final static int opc_bipush = 16;
|
||||
public final static int opc_sipush = 17;
|
||||
public final static int opc_ldc = 18;
|
||||
public final static int opc_ldc_w = 19;
|
||||
public final static int opc_ldc2_w = 20;
|
||||
public final static int opc_iload = 21;
|
||||
public final static int opc_lload = 22;
|
||||
public final static int opc_fload = 23;
|
||||
public final static int opc_dload = 24;
|
||||
public final static int opc_aload = 25;
|
||||
public final static int opc_iload_0 = 26;
|
||||
public final static int opc_iload_1 = 27;
|
||||
public final static int opc_iload_2 = 28;
|
||||
public final static int opc_iload_3 = 29;
|
||||
public final static int opc_lload_0 = 30;
|
||||
public final static int opc_lload_1 = 31;
|
||||
public final static int opc_lload_2 = 32;
|
||||
public final static int opc_lload_3 = 33;
|
||||
public final static int opc_fload_0 = 34;
|
||||
public final static int opc_fload_1 = 35;
|
||||
public final static int opc_fload_2 = 36;
|
||||
public final static int opc_fload_3 = 37;
|
||||
public final static int opc_dload_0 = 38;
|
||||
public final static int opc_dload_1 = 39;
|
||||
public final static int opc_dload_2 = 40;
|
||||
public final static int opc_dload_3 = 41;
|
||||
public final static int opc_aload_0 = 42;
|
||||
public final static int opc_aload_1 = 43;
|
||||
public final static int opc_aload_2 = 44;
|
||||
public final static int opc_aload_3 = 45;
|
||||
public final static int opc_iaload = 46;
|
||||
public final static int opc_laload = 47;
|
||||
public final static int opc_faload = 48;
|
||||
public final static int opc_daload = 49;
|
||||
public final static int opc_aaload = 50;
|
||||
public final static int opc_baload = 51;
|
||||
public final static int opc_caload = 52;
|
||||
public final static int opc_saload = 53;
|
||||
public final static int opc_istore = 54;
|
||||
public final static int opc_lstore = 55;
|
||||
public final static int opc_fstore = 56;
|
||||
public final static int opc_dstore = 57;
|
||||
public final static int opc_astore = 58;
|
||||
public final static int opc_istore_0 = 59;
|
||||
public final static int opc_istore_1 = 60;
|
||||
public final static int opc_istore_2 = 61;
|
||||
public final static int opc_istore_3 = 62;
|
||||
public final static int opc_lstore_0 = 63;
|
||||
public final static int opc_lstore_1 = 64;
|
||||
public final static int opc_lstore_2 = 65;
|
||||
public final static int opc_lstore_3 = 66;
|
||||
public final static int opc_fstore_0 = 67;
|
||||
public final static int opc_fstore_1 = 68;
|
||||
public final static int opc_fstore_2 = 69;
|
||||
public final static int opc_fstore_3 = 70;
|
||||
public final static int opc_dstore_0 = 71;
|
||||
public final static int opc_dstore_1 = 72;
|
||||
public final static int opc_dstore_2 = 73;
|
||||
public final static int opc_dstore_3 = 74;
|
||||
public final static int opc_astore_0 = 75;
|
||||
public final static int opc_astore_1 = 76;
|
||||
public final static int opc_astore_2 = 77;
|
||||
public final static int opc_astore_3 = 78;
|
||||
public final static int opc_iastore = 79;
|
||||
public final static int opc_lastore = 80;
|
||||
public final static int opc_fastore = 81;
|
||||
public final static int opc_dastore = 82;
|
||||
public final static int opc_aastore = 83;
|
||||
public final static int opc_bastore = 84;
|
||||
public final static int opc_castore = 85;
|
||||
public final static int opc_sastore = 86;
|
||||
public final static int opc_pop = 87;
|
||||
public final static int opc_pop2 = 88;
|
||||
public final static int opc_dup = 89;
|
||||
public final static int opc_dup_x1 = 90;
|
||||
public final static int opc_dup_x2 = 91;
|
||||
public final static int opc_dup2 = 92;
|
||||
public final static int opc_dup2_x1 = 93;
|
||||
public final static int opc_dup2_x2 = 94;
|
||||
public final static int opc_swap = 95;
|
||||
public final static int opc_iadd = 96;
|
||||
public final static int opc_ladd = 97;
|
||||
public final static int opc_fadd = 98;
|
||||
public final static int opc_dadd = 99;
|
||||
public final static int opc_isub = 100;
|
||||
public final static int opc_lsub = 101;
|
||||
public final static int opc_fsub = 102;
|
||||
public final static int opc_dsub = 103;
|
||||
public final static int opc_imul = 104;
|
||||
public final static int opc_lmul = 105;
|
||||
public final static int opc_fmul = 106;
|
||||
public final static int opc_dmul = 107;
|
||||
public final static int opc_idiv = 108;
|
||||
public final static int opc_ldiv = 109;
|
||||
public final static int opc_fdiv = 110;
|
||||
public final static int opc_ddiv = 111;
|
||||
public final static int opc_irem = 112;
|
||||
public final static int opc_lrem = 113;
|
||||
public final static int opc_frem = 114;
|
||||
public final static int opc_drem = 115;
|
||||
public final static int opc_ineg = 116;
|
||||
public final static int opc_lneg = 117;
|
||||
public final static int opc_fneg = 118;
|
||||
public final static int opc_dneg = 119;
|
||||
public final static int opc_ishl = 120;
|
||||
public final static int opc_lshl = 121;
|
||||
public final static int opc_ishr = 122;
|
||||
public final static int opc_lshr = 123;
|
||||
public final static int opc_iushr = 124;
|
||||
public final static int opc_lushr = 125;
|
||||
public final static int opc_iand = 126;
|
||||
public final static int opc_land = 127;
|
||||
public final static int opc_ior = 128;
|
||||
public final static int opc_lor = 129;
|
||||
public final static int opc_ixor = 130;
|
||||
public final static int opc_lxor = 131;
|
||||
public final static int opc_iinc = 132;
|
||||
public final static int opc_i2l = 133;
|
||||
public final static int opc_i2f = 134;
|
||||
public final static int opc_i2d = 135;
|
||||
public final static int opc_l2i = 136;
|
||||
public final static int opc_l2f = 137;
|
||||
public final static int opc_l2d = 138;
|
||||
public final static int opc_f2i = 139;
|
||||
public final static int opc_f2l = 140;
|
||||
public final static int opc_f2d = 141;
|
||||
public final static int opc_d2i = 142;
|
||||
public final static int opc_d2l = 143;
|
||||
public final static int opc_d2f = 144;
|
||||
public final static int opc_i2b = 145;
|
||||
public final static int opc_i2c = 146;
|
||||
public final static int opc_i2s = 147;
|
||||
public final static int opc_lcmp = 148;
|
||||
public final static int opc_fcmpl = 149;
|
||||
public final static int opc_fcmpg = 150;
|
||||
public final static int opc_dcmpl = 151;
|
||||
public final static int opc_dcmpg = 152;
|
||||
public final static int opc_ifeq = 153;
|
||||
public final static int opc_ifne = 154;
|
||||
public final static int opc_iflt = 155;
|
||||
public final static int opc_ifge = 156;
|
||||
public final static int opc_ifgt = 157;
|
||||
public final static int opc_ifle = 158;
|
||||
public final static int opc_if_icmpeq = 159;
|
||||
public final static int opc_if_icmpne = 160;
|
||||
public final static int opc_if_icmplt = 161;
|
||||
public final static int opc_if_icmpge = 162;
|
||||
public final static int opc_if_icmpgt = 163;
|
||||
public final static int opc_if_icmple = 164;
|
||||
public final static int opc_if_acmpeq = 165;
|
||||
public final static int opc_if_acmpne = 166;
|
||||
public final static int opc_goto = 167;
|
||||
public final static int opc_jsr = 168;
|
||||
public final static int opc_ret = 169;
|
||||
public final static int opc_tableswitch = 170;
|
||||
public final static int opc_lookupswitch = 171;
|
||||
public final static int opc_ireturn = 172;
|
||||
public final static int opc_lreturn = 173;
|
||||
public final static int opc_freturn = 174;
|
||||
public final static int opc_dreturn = 175;
|
||||
public final static int opc_areturn = 176;
|
||||
public final static int opc_return = 177;
|
||||
public final static int opc_getstatic = 178;
|
||||
public final static int opc_putstatic = 179;
|
||||
public final static int opc_getfield = 180;
|
||||
public final static int opc_putfield = 181;
|
||||
public final static int opc_invokevirtual = 182;
|
||||
public final static int opc_invokespecial = 183;
|
||||
public final static int opc_invokestatic = 184;
|
||||
public final static int opc_invokeinterface = 185;
|
||||
public final static int opc_xxxunusedxxx = 186;
|
||||
public final static int opc_new = 187;
|
||||
public final static int opc_newarray = 188;
|
||||
public final static int opc_anewarray = 189;
|
||||
public final static int opc_arraylength = 190;
|
||||
public final static int opc_athrow = 191;
|
||||
public final static int opc_checkcast = 192;
|
||||
public final static int opc_instanceof = 193;
|
||||
public final static int opc_monitorenter = 194;
|
||||
public final static int opc_monitorexit = 195;
|
||||
public final static int opc_wide = 196;
|
||||
public final static int opc_multianewarray = 197;
|
||||
public final static int opc_ifnull = 198;
|
||||
public final static int opc_ifnonnull = 199;
|
||||
public final static int opc_goto_w = 200;
|
||||
public final static int opc_jsr_w = 201;
|
||||
|
||||
|
||||
}
|
510
src/de/fernflower/code/ConstantsUtil.java
Normal file
510
src/de/fernflower/code/ConstantsUtil.java
Normal file
@ -0,0 +1,510 @@
|
||||
/*
|
||||
* Fernflower - The Analytical Java Decompiler
|
||||
* http://www.reversed-java.com
|
||||
*
|
||||
* (C) 2008 - 2010, Stiver
|
||||
*
|
||||
* This software is NEITHER public domain NOR free software
|
||||
* as per GNU License. See license.txt for more details.
|
||||
*
|
||||
* This software is distributed WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
package de.fernflower.code;
|
||||
|
||||
import de.fernflower.code.optinstructions.ALOAD;
|
||||
import de.fernflower.code.optinstructions.ANEWARRAY;
|
||||
import de.fernflower.code.optinstructions.ASTORE;
|
||||
import de.fernflower.code.optinstructions.BIPUSH;
|
||||
import de.fernflower.code.optinstructions.CHECKCAST;
|
||||
import de.fernflower.code.optinstructions.DLOAD;
|
||||
import de.fernflower.code.optinstructions.DSTORE;
|
||||
import de.fernflower.code.optinstructions.FLOAD;
|
||||
import de.fernflower.code.optinstructions.FSTORE;
|
||||
import de.fernflower.code.optinstructions.GETFIELD;
|
||||
import de.fernflower.code.optinstructions.GETSTATIC;
|
||||
import de.fernflower.code.optinstructions.GOTO;
|
||||
import de.fernflower.code.optinstructions.GOTO_W;
|
||||
import de.fernflower.code.optinstructions.IINC;
|
||||
import de.fernflower.code.optinstructions.ILOAD;
|
||||
import de.fernflower.code.optinstructions.INSTANCEOF;
|
||||
import de.fernflower.code.optinstructions.INVOKEINTERFACE;
|
||||
import de.fernflower.code.optinstructions.INVOKESPECIAL;
|
||||
import de.fernflower.code.optinstructions.INVOKESTATIC;
|
||||
import de.fernflower.code.optinstructions.INVOKEVIRTUAL;
|
||||
import de.fernflower.code.optinstructions.ISTORE;
|
||||
import de.fernflower.code.optinstructions.JSR;
|
||||
import de.fernflower.code.optinstructions.JSR_W;
|
||||
import de.fernflower.code.optinstructions.LDC;
|
||||
import de.fernflower.code.optinstructions.LDC2_W;
|
||||
import de.fernflower.code.optinstructions.LDC_W;
|
||||
import de.fernflower.code.optinstructions.LLOAD;
|
||||
import de.fernflower.code.optinstructions.LOOKUPSWITCH;
|
||||
import de.fernflower.code.optinstructions.LSTORE;
|
||||
import de.fernflower.code.optinstructions.MULTIANEWARRAY;
|
||||
import de.fernflower.code.optinstructions.NEW;
|
||||
import de.fernflower.code.optinstructions.NEWARRAY;
|
||||
import de.fernflower.code.optinstructions.PUTFIELD;
|
||||
import de.fernflower.code.optinstructions.PUTSTATIC;
|
||||
import de.fernflower.code.optinstructions.RET;
|
||||
import de.fernflower.code.optinstructions.SIPUSH;
|
||||
import de.fernflower.code.optinstructions.TABLESWITCH;
|
||||
|
||||
public class ConstantsUtil {
|
||||
|
||||
public static String getName(int opcode) {
|
||||
return opcodeNames[opcode];
|
||||
}
|
||||
|
||||
public static Instruction getInstructionInstance(int opcode, boolean wide, int group, int[] operands) {
|
||||
|
||||
Instruction instr = getInstructionInstance(opcode);
|
||||
instr.wide = wide;
|
||||
instr.group = group;
|
||||
instr.setOperands(operands);
|
||||
|
||||
return instr;
|
||||
}
|
||||
|
||||
public static Instruction getInstructionInstance(int opcode) {
|
||||
try {
|
||||
Instruction instr;
|
||||
|
||||
if((opcode >= CodeConstants.opc_ifeq &&
|
||||
opcode <= CodeConstants.opc_if_acmpne) ||
|
||||
opcode == CodeConstants.opc_ifnull ||
|
||||
opcode == CodeConstants.opc_ifnonnull) {
|
||||
instr = new IfInstruction();
|
||||
} else {
|
||||
Class cl = opcodeClasses[opcode];
|
||||
if(cl == null) {
|
||||
instr = new Instruction();
|
||||
} else {
|
||||
instr = (Instruction)cl.newInstance();
|
||||
}
|
||||
}
|
||||
|
||||
instr.opcode = opcode;
|
||||
return instr;
|
||||
} catch (Exception ex) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private static String[] opcodeNames = {
|
||||
"nop", // "nop",
|
||||
"aconst_null", // "aconst_null",
|
||||
"iconst_m1", // "iconst_m1",
|
||||
"iconst_0", // "iconst_0",
|
||||
"iconst_1", // "iconst_1",
|
||||
"iconst_2", // "iconst_2",
|
||||
"iconst_3", // "iconst_3",
|
||||
"iconst_4", // "iconst_4",
|
||||
"iconst_5", // "iconst_5",
|
||||
"lconst_0", // "lconst_0",
|
||||
"lconst_1", // "lconst_1",
|
||||
"fconst_0", // "fconst_0",
|
||||
"fconst_1", // "fconst_1",
|
||||
"fconst_2", // "fconst_2",
|
||||
"dconst_0", // "dconst_0",
|
||||
"dconst_1", // "dconst_1",
|
||||
"bipush", // "bipush",
|
||||
"sipush", // "sipush",
|
||||
"ldc", // "ldc",
|
||||
"ldc_w", // "ldc_w",
|
||||
"ldc2_w", // "ldc2_w",
|
||||
"iload", // "iload",
|
||||
"lload", // "lload",
|
||||
"fload", // "fload",
|
||||
"dload", // "dload",
|
||||
"aload", // "aload",
|
||||
"iload_0", // "iload_0",
|
||||
"iload_1", // "iload_1",
|
||||
"iload_2", // "iload_2",
|
||||
"iload_3", // "iload_3",
|
||||
"lload_0", // "lload_0",
|
||||
"lload_1", // "lload_1",
|
||||
"lload_2", // "lload_2",
|
||||
"lload_3", // "lload_3",
|
||||
"fload_0", // "fload_0",
|
||||
"fload_1", // "fload_1",
|
||||
"fload_2", // "fload_2",
|
||||
"fload_3", // "fload_3",
|
||||
"dload_0", // "dload_0",
|
||||
"dload_1", // "dload_1",
|
||||
"dload_2", // "dload_2",
|
||||
"dload_3", // "dload_3",
|
||||
"aload_0", // "aload_0",
|
||||
"aload_1", // "aload_1",
|
||||
"aload_2", // "aload_2",
|
||||
"aload_3", // "aload_3",
|
||||
"iaload", // "iaload",
|
||||
"laload", // "laload",
|
||||
"faload", // "faload",
|
||||
"daload", // "daload",
|
||||
"aaload", // "aaload",
|
||||
"baload", // "baload",
|
||||
"caload", // "caload",
|
||||
"saload", // "saload",
|
||||
"istore", // "istore",
|
||||
"lstore", // "lstore",
|
||||
"fstore", // "fstore",
|
||||
"dstore", // "dstore",
|
||||
"astore", // "astore",
|
||||
"istore_0", // "istore_0",
|
||||
"istore_1", // "istore_1",
|
||||
"istore_2", // "istore_2",
|
||||
"istore_3", // "istore_3",
|
||||
"lstore_0", // "lstore_0",
|
||||
"lstore_1", // "lstore_1",
|
||||
"lstore_2", // "lstore_2",
|
||||
"lstore_3", // "lstore_3",
|
||||
"fstore_0", // "fstore_0",
|
||||
"fstore_1", // "fstore_1",
|
||||
"fstore_2", // "fstore_2",
|
||||
"fstore_3", // "fstore_3",
|
||||
"dstore_0", // "dstore_0",
|
||||
"dstore_1", // "dstore_1",
|
||||
"dstore_2", // "dstore_2",
|
||||
"dstore_3", // "dstore_3",
|
||||
"astore_0", // "astore_0",
|
||||
"astore_1", // "astore_1",
|
||||
"astore_2", // "astore_2",
|
||||
"astore_3", // "astore_3",
|
||||
"iastore", // "iastore",
|
||||
"lastore", // "lastore",
|
||||
"fastore", // "fastore",
|
||||
"dastore", // "dastore",
|
||||
"aastore", // "aastore",
|
||||
"bastore", // "bastore",
|
||||
"castore", // "castore",
|
||||
"sastore", // "sastore",
|
||||
"pop", // "pop",
|
||||
"pop2", // "pop2",
|
||||
"dup", // "dup",
|
||||
"dup_x1", // "dup_x1",
|
||||
"dup_x2", // "dup_x2",
|
||||
"dup2", // "dup2",
|
||||
"dup2_x1", // "dup2_x1",
|
||||
"dup2_x2", // "dup2_x2",
|
||||
"swap", // "swap",
|
||||
"iadd", // "iadd",
|
||||
"ladd", // "ladd",
|
||||
"fadd", // "fadd",
|
||||
"dadd", // "dadd",
|
||||
"isub", // "isub",
|
||||
"lsub", // "lsub",
|
||||
"fsub", // "fsub",
|
||||
"dsub", // "dsub",
|
||||
"imul", // "imul",
|
||||
"lmul", // "lmul",
|
||||
"fmul", // "fmul",
|
||||
"dmul", // "dmul",
|
||||
"idiv", // "idiv",
|
||||
"ldiv", // "ldiv",
|
||||
"fdiv", // "fdiv",
|
||||
"ddiv", // "ddiv",
|
||||
"irem", // "irem",
|
||||
"lrem", // "lrem",
|
||||
"frem", // "frem",
|
||||
"drem", // "drem",
|
||||
"ineg", // "ineg",
|
||||
"lneg", // "lneg",
|
||||
"fneg", // "fneg",
|
||||
"dneg", // "dneg",
|
||||
"ishl", // "ishl",
|
||||
"lshl", // "lshl",
|
||||
"ishr", // "ishr",
|
||||
"lshr", // "lshr",
|
||||
"iushr", // "iushr",
|
||||
"lushr", // "lushr",
|
||||
"iand", // "iand",
|
||||
"land", // "land",
|
||||
"ior", // "ior",
|
||||
"lor", // "lor",
|
||||
"ixor", // "ixor",
|
||||
"lxor", // "lxor",
|
||||
"iinc", // "iinc",
|
||||
"i2l", // "i2l",
|
||||
"i2f", // "i2f",
|
||||
"i2d", // "i2d",
|
||||
"l2i", // "l2i",
|
||||
"l2f", // "l2f",
|
||||
"l2d", // "l2d",
|
||||
"f2i", // "f2i",
|
||||
"f2l", // "f2l",
|
||||
"f2d", // "f2d",
|
||||
"d2i", // "d2i",
|
||||
"d2l", // "d2l",
|
||||
"d2f", // "d2f",
|
||||
"i2b", // "i2b",
|
||||
"i2c", // "i2c",
|
||||
"i2s", // "i2s",
|
||||
"lcmp", // "lcmp",
|
||||
"fcmpl", // "fcmpl",
|
||||
"fcmpg", // "fcmpg",
|
||||
"dcmpl", // "dcmpl",
|
||||
"dcmpg", // "dcmpg",
|
||||
"ifeq", // "ifeq",
|
||||
"ifne", // "ifne",
|
||||
"iflt", // "iflt",
|
||||
"ifge", // "ifge",
|
||||
"ifgt", // "ifgt",
|
||||
"ifle", // "ifle",
|
||||
"if_icmpeq", // "if_icmpeq",
|
||||
"if_icmpne", // "if_icmpne",
|
||||
"if_icmplt", // "if_icmplt",
|
||||
"if_icmpge", // "if_icmpge",
|
||||
"if_icmpgt", // "if_icmpgt",
|
||||
"if_icmple", // "if_icmple",
|
||||
"if_acmpeq", // "if_acmpeq",
|
||||
"if_acmpne", // "if_acmpne",
|
||||
"goto", // "goto",
|
||||
"jsr", // "jsr",
|
||||
"ret", // "ret",
|
||||
"tableswitch", // "tableswitch",
|
||||
"lookupswitch", // "lookupswitch",
|
||||
"ireturn", // "ireturn",
|
||||
"lreturn", // "lreturn",
|
||||
"freturn", // "freturn",
|
||||
"dreturn", // "dreturn",
|
||||
"areturn", // "areturn",
|
||||
"return", // "return",
|
||||
"getstatic", // "getstatic",
|
||||
"putstatic", // "putstatic",
|
||||
"getfield", // "getfield",
|
||||
"putfield", // "putfield",
|
||||
"invokevirtual", // "invokevirtual",
|
||||
"invokespecial", // "invokespecial",
|
||||
"invokestatic", // "invokestatic",
|
||||
"invokeinterface", // "invokeinterface",
|
||||
"xxxunusedxxx", // "xxxunusedxxx",
|
||||
"new", // "new",
|
||||
"newarray", // "newarray",
|
||||
"anewarray", // "anewarray",
|
||||
"arraylength", // "arraylength",
|
||||
"athrow", // "athrow",
|
||||
"checkcast", // "checkcast",
|
||||
"instanceof", // "instanceof",
|
||||
"monitorenter", // "monitorenter",
|
||||
"monitorexit", // "monitorexit",
|
||||
"wide", // "wide",
|
||||
"multianewarray", // "multianewarray",
|
||||
"ifnull", // "ifnull",
|
||||
"ifnonnull", // "ifnonnull",
|
||||
"goto_w", // "goto_w",
|
||||
"jsr_w" // "jsr_w"
|
||||
};
|
||||
|
||||
private static Class[] opcodeClasses = {
|
||||
null, // "nop",
|
||||
null, // "aconst_null",
|
||||
null, // "iconst_m1",
|
||||
null, // "iconst_0",
|
||||
null, // "iconst_1",
|
||||
null, // "iconst_2",
|
||||
null, // "iconst_3",
|
||||
null, // "iconst_4",
|
||||
null, // "iconst_5",
|
||||
null, // "lconst_0",
|
||||
null, // "lconst_1",
|
||||
null, // "fconst_0",
|
||||
null, // "fconst_1",
|
||||
null, // "fconst_2",
|
||||
null, // "dconst_0",
|
||||
null, // "dconst_1",
|
||||
BIPUSH.class, // "bipush",
|
||||
SIPUSH.class, // "sipush",
|
||||
LDC.class, // "ldc",
|
||||
LDC_W.class, // "ldc_w",
|
||||
LDC2_W.class, // "ldc2_w",
|
||||
ILOAD.class, // "iload",
|
||||
LLOAD.class, // "lload",
|
||||
FLOAD.class, // "fload",
|
||||
DLOAD.class, // "dload",
|
||||
ALOAD.class, // "aload",
|
||||
null, // "iload_0",
|
||||
null, // "iload_1",
|
||||
null, // "iload_2",
|
||||
null, // "iload_3",
|
||||
null, // "lload_0",
|
||||
null, // "lload_1",
|
||||
null, // "lload_2",
|
||||
null, // "lload_3",
|
||||
null, // "fload_0",
|
||||
null, // "fload_1",
|
||||
null, // "fload_2",
|
||||
null, // "fload_3",
|
||||
null, // "dload_0",
|
||||
null, // "dload_1",
|
||||
null, // "dload_2",
|
||||
null, // "dload_3",
|
||||
null, // "aload_0",
|
||||
null, // "aload_1",
|
||||
null, // "aload_2",
|
||||
null, // "aload_3",
|
||||
null, // "iaload",
|
||||
null, // "laload",
|
||||
null, // "faload",
|
||||
null, // "daload",
|
||||
null, // "aaload",
|
||||
null, // "baload",
|
||||
null, // "caload",
|
||||
null, // "saload",
|
||||
ISTORE.class, // "istore",
|
||||
LSTORE.class, // "lstore",
|
||||
FSTORE.class, // "fstore",
|
||||
DSTORE.class, // "dstore",
|
||||
ASTORE.class, // "astore",
|
||||
null, // "istore_0",
|
||||
null, // "istore_1",
|
||||
null, // "istore_2",
|
||||
null, // "istore_3",
|
||||
null, // "lstore_0",
|
||||
null, // "lstore_1",
|
||||
null, // "lstore_2",
|
||||
null, // "lstore_3",
|
||||
null, // "fstore_0",
|
||||
null, // "fstore_1",
|
||||
null, // "fstore_2",
|
||||
null, // "fstore_3",
|
||||
null, // "dstore_0",
|
||||
null, // "dstore_1",
|
||||
null, // "dstore_2",
|
||||
null, // "dstore_3",
|
||||
null, // "astore_0",
|
||||
null, // "astore_1",
|
||||
null, // "astore_2",
|
||||
null, // "astore_3",
|
||||
null, // "iastore",
|
||||
null, // "lastore",
|
||||
null, // "fastore",
|
||||
null, // "dastore",
|
||||
null, // "aastore",
|
||||
null, // "bastore",
|
||||
null, // "castore",
|
||||
null, // "sastore",
|
||||
null, // "pop",
|
||||
null, // "pop2",
|
||||
null, // "dup",
|
||||
null, // "dup_x1",
|
||||
null, // "dup_x2",
|
||||
null, // "dup2",
|
||||
null, // "dup2_x1",
|
||||
null, // "dup2_x2",
|
||||
null, // "swap",
|
||||
null, // "iadd",
|
||||
null, // "ladd",
|
||||
null, // "fadd",
|
||||
null, // "dadd",
|
||||
null, // "isub",
|
||||
null, // "lsub",
|
||||
null, // "fsub",
|
||||
null, // "dsub",
|
||||
null, // "imul",
|
||||
null, // "lmul",
|
||||
null, // "fmul",
|
||||
null, // "dmul",
|
||||
null, // "idiv",
|
||||
null, // "ldiv",
|
||||
null, // "fdiv",
|
||||
null, // "ddiv",
|
||||
null, // "irem",
|
||||
null, // "lrem",
|
||||
null, // "frem",
|
||||
null, // "drem",
|
||||
null, // "ineg",
|
||||
null, // "lneg",
|
||||
null, // "fneg",
|
||||
null, // "dneg",
|
||||
null, // "ishl",
|
||||
null, // "lshl",
|
||||
null, // "ishr",
|
||||
null, // "lshr",
|
||||
null, // "iushr",
|
||||
null, // "lushr",
|
||||
null, // "iand",
|
||||
null, // "land",
|
||||
null, // "ior",
|
||||
null, // "lor",
|
||||
null, // "ixor",
|
||||
null, // "lxor",
|
||||
IINC.class, // "iinc",
|
||||
null, // "i2l",
|
||||
null, // "i2f",
|
||||
null, // "i2d",
|
||||
null, // "l2i",
|
||||
null, // "l2f",
|
||||
null, // "l2d",
|
||||
null, // "f2i",
|
||||
null, // "f2l",
|
||||
null, // "f2d",
|
||||
null, // "d2i",
|
||||
null, // "d2l",
|
||||
null, // "d2f",
|
||||
null, // "i2b",
|
||||
null, // "i2c",
|
||||
null, // "i2s",
|
||||
null, // "lcmp",
|
||||
null, // "fcmpl",
|
||||
null, // "fcmpg",
|
||||
null, // "dcmpl",
|
||||
null, // "dcmpg",
|
||||
null, // "ifeq",
|
||||
null, // "ifne",
|
||||
null, // "iflt",
|
||||
null, // "ifge",
|
||||
null, // "ifgt",
|
||||
null, // "ifle",
|
||||
null, // "if_icmpeq",
|
||||
null, // "if_icmpne",
|
||||
null, // "if_icmplt",
|
||||
null, // "if_icmpge",
|
||||
null, // "if_icmpgt",
|
||||
null, // "if_icmple",
|
||||
null, // "if_acmpeq",
|
||||
null, // "if_acmpne",
|
||||
GOTO.class, // "goto",
|
||||
JSR.class, // "jsr",
|
||||
RET.class, // "ret",
|
||||
TABLESWITCH.class, // "tableswitch",
|
||||
LOOKUPSWITCH.class, // "lookupswitch",
|
||||
null, // "ireturn",
|
||||
null, // "lreturn",
|
||||
null, // "freturn",
|
||||
null, // "dreturn",
|
||||
null, // "areturn",
|
||||
null, // "return",
|
||||
GETSTATIC.class, // "getstatic",
|
||||
PUTSTATIC.class, // "putstatic",
|
||||
GETFIELD.class, // "getfield",
|
||||
PUTFIELD.class, // "putfield",
|
||||
INVOKEVIRTUAL.class, // "invokevirtual",
|
||||
INVOKESPECIAL.class, // "invokespecial",
|
||||
INVOKESTATIC.class, // "invokestatic",
|
||||
INVOKEINTERFACE.class, // "invokeinterface",
|
||||
null , // "xxxunusedxxx",
|
||||
NEW.class, // "new",
|
||||
NEWARRAY.class, // "newarray",
|
||||
ANEWARRAY.class, // "anewarray",
|
||||
null, // "arraylength",
|
||||
null, // "athrow",
|
||||
CHECKCAST.class, // "checkcast",
|
||||
INSTANCEOF.class, // "instanceof",
|
||||
null, // "monitorenter",
|
||||
null, // "monitorexit",
|
||||
null, // "wide",
|
||||
MULTIANEWARRAY.class, // "multianewarray",
|
||||
null, // "ifnull",
|
||||
null, // "ifnonnull",
|
||||
GOTO_W.class, // "goto_w",
|
||||
JSR_W.class // "jsr_w"
|
||||
};
|
||||
|
||||
|
||||
|
||||
}
|
442
src/de/fernflower/code/ConstantsUtilOld.java
Normal file
442
src/de/fernflower/code/ConstantsUtilOld.java
Normal file
@ -0,0 +1,442 @@
|
||||
package de.fernflower.code;
|
||||
|
||||
public class ConstantsUtilOld {
|
||||
public static String getName(int opcode) {
|
||||
return opcodeNames[opcode];
|
||||
}
|
||||
|
||||
public static Instruction getInstructionInstance(int opcode, boolean wide, int group, int[] operands) {
|
||||
|
||||
Instruction instr = getInstructionInstance(opcode);
|
||||
instr.wide = wide;
|
||||
instr.group = group;
|
||||
instr.setOperands(operands);
|
||||
|
||||
return instr;
|
||||
}
|
||||
|
||||
public static Instruction getInstructionInstance(int opcode) {
|
||||
try {
|
||||
Instruction instr = (Instruction)Class.forName("de.fernflower.code.instructions."+opcodeClasses[opcode]).newInstance();
|
||||
instr.opcode = opcode;
|
||||
return instr;
|
||||
} catch (Exception ex) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private static String[] opcodeNames = {
|
||||
"nop", // "nop",
|
||||
"aconst_null", // "aconst_null",
|
||||
"iconst_m1", // "iconst_m1",
|
||||
"iconst_0", // "iconst_0",
|
||||
"iconst_1", // "iconst_1",
|
||||
"iconst_2", // "iconst_2",
|
||||
"iconst_3", // "iconst_3",
|
||||
"iconst_4", // "iconst_4",
|
||||
"iconst_5", // "iconst_5",
|
||||
"lconst_0", // "lconst_0",
|
||||
"lconst_1", // "lconst_1",
|
||||
"fconst_0", // "fconst_0",
|
||||
"fconst_1", // "fconst_1",
|
||||
"fconst_2", // "fconst_2",
|
||||
"dconst_0", // "dconst_0",
|
||||
"dconst_1", // "dconst_1",
|
||||
"bipush", // "bipush",
|
||||
"sipush", // "sipush",
|
||||
"ldc", // "ldc",
|
||||
"ldc_w", // "ldc_w",
|
||||
"ldc2_w", // "ldc2_w",
|
||||
"iload", // "iload",
|
||||
"lload", // "lload",
|
||||
"fload", // "fload",
|
||||
"dload", // "dload",
|
||||
"aload", // "aload",
|
||||
"iload_0", // "iload_0",
|
||||
"iload_1", // "iload_1",
|
||||
"iload_2", // "iload_2",
|
||||
"iload_3", // "iload_3",
|
||||
"lload_0", // "lload_0",
|
||||
"lload_1", // "lload_1",
|
||||
"lload_2", // "lload_2",
|
||||
"lload_3", // "lload_3",
|
||||
"fload_0", // "fload_0",
|
||||
"fload_1", // "fload_1",
|
||||
"fload_2", // "fload_2",
|
||||
"fload_3", // "fload_3",
|
||||
"dload_0", // "dload_0",
|
||||
"dload_1", // "dload_1",
|
||||
"dload_2", // "dload_2",
|
||||
"dload_3", // "dload_3",
|
||||
"aload_0", // "aload_0",
|
||||
"aload_1", // "aload_1",
|
||||
"aload_2", // "aload_2",
|
||||
"aload_3", // "aload_3",
|
||||
"iaload", // "iaload",
|
||||
"laload", // "laload",
|
||||
"faload", // "faload",
|
||||
"daload", // "daload",
|
||||
"aaload", // "aaload",
|
||||
"baload", // "baload",
|
||||
"caload", // "caload",
|
||||
"saload", // "saload",
|
||||
"istore", // "istore",
|
||||
"lstore", // "lstore",
|
||||
"fstore", // "fstore",
|
||||
"dstore", // "dstore",
|
||||
"astore", // "astore",
|
||||
"istore_0", // "istore_0",
|
||||
"istore_1", // "istore_1",
|
||||
"istore_2", // "istore_2",
|
||||
"istore_3", // "istore_3",
|
||||
"lstore_0", // "lstore_0",
|
||||
"lstore_1", // "lstore_1",
|
||||
"lstore_2", // "lstore_2",
|
||||
"lstore_3", // "lstore_3",
|
||||
"fstore_0", // "fstore_0",
|
||||
"fstore_1", // "fstore_1",
|
||||
"fstore_2", // "fstore_2",
|
||||
"fstore_3", // "fstore_3",
|
||||
"dstore_0", // "dstore_0",
|
||||
"dstore_1", // "dstore_1",
|
||||
"dstore_2", // "dstore_2",
|
||||
"dstore_3", // "dstore_3",
|
||||
"astore_0", // "astore_0",
|
||||
"astore_1", // "astore_1",
|
||||
"astore_2", // "astore_2",
|
||||
"astore_3", // "astore_3",
|
||||
"iastore", // "iastore",
|
||||
"lastore", // "lastore",
|
||||
"fastore", // "fastore",
|
||||
"dastore", // "dastore",
|
||||
"aastore", // "aastore",
|
||||
"bastore", // "bastore",
|
||||
"castore", // "castore",
|
||||
"sastore", // "sastore",
|
||||
"pop", // "pop",
|
||||
"pop2", // "pop2",
|
||||
"dup", // "dup",
|
||||
"dup_x1", // "dup_x1",
|
||||
"dup_x2", // "dup_x2",
|
||||
"dup2", // "dup2",
|
||||
"dup2_x1", // "dup2_x1",
|
||||
"dup2_x2", // "dup2_x2",
|
||||
"swap", // "swap",
|
||||
"iadd", // "iadd",
|
||||
"ladd", // "ladd",
|
||||
"fadd", // "fadd",
|
||||
"dadd", // "dadd",
|
||||
"isub", // "isub",
|
||||
"lsub", // "lsub",
|
||||
"fsub", // "fsub",
|
||||
"dsub", // "dsub",
|
||||
"imul", // "imul",
|
||||
"lmul", // "lmul",
|
||||
"fmul", // "fmul",
|
||||
"dmul", // "dmul",
|
||||
"idiv", // "idiv",
|
||||
"ldiv", // "ldiv",
|
||||
"fdiv", // "fdiv",
|
||||
"ddiv", // "ddiv",
|
||||
"irem", // "irem",
|
||||
"lrem", // "lrem",
|
||||
"frem", // "frem",
|
||||
"drem", // "drem",
|
||||
"ineg", // "ineg",
|
||||
"lneg", // "lneg",
|
||||
"fneg", // "fneg",
|
||||
"dneg", // "dneg",
|
||||
"ishl", // "ishl",
|
||||
"lshl", // "lshl",
|
||||
"ishr", // "ishr",
|
||||
"lshr", // "lshr",
|
||||
"iushr", // "iushr",
|
||||
"lushr", // "lushr",
|
||||
"iand", // "iand",
|
||||
"land", // "land",
|
||||
"ior", // "ior",
|
||||
"lor", // "lor",
|
||||
"ixor", // "ixor",
|
||||
"lxor", // "lxor",
|
||||
"iinc", // "iinc",
|
||||
"i2l", // "i2l",
|
||||
"i2f", // "i2f",
|
||||
"i2d", // "i2d",
|
||||
"l2i", // "l2i",
|
||||
"l2f", // "l2f",
|
||||
"l2d", // "l2d",
|
||||
"f2i", // "f2i",
|
||||
"f2l", // "f2l",
|
||||
"f2d", // "f2d",
|
||||
"d2i", // "d2i",
|
||||
"d2l", // "d2l",
|
||||
"d2f", // "d2f",
|
||||
"i2b", // "i2b",
|
||||
"i2c", // "i2c",
|
||||
"i2s", // "i2s",
|
||||
"lcmp", // "lcmp",
|
||||
"fcmpl", // "fcmpl",
|
||||
"fcmpg", // "fcmpg",
|
||||
"dcmpl", // "dcmpl",
|
||||
"dcmpg", // "dcmpg",
|
||||
"ifeq", // "ifeq",
|
||||
"ifne", // "ifne",
|
||||
"iflt", // "iflt",
|
||||
"ifge", // "ifge",
|
||||
"ifgt", // "ifgt",
|
||||
"ifle", // "ifle",
|
||||
"if_icmpeq", // "if_icmpeq",
|
||||
"if_icmpne", // "if_icmpne",
|
||||
"if_icmplt", // "if_icmplt",
|
||||
"if_icmpge", // "if_icmpge",
|
||||
"if_icmpgt", // "if_icmpgt",
|
||||
"if_icmple", // "if_icmple",
|
||||
"if_acmpeq", // "if_acmpeq",
|
||||
"if_acmpne", // "if_acmpne",
|
||||
"goto", // "goto",
|
||||
"jsr", // "jsr",
|
||||
"ret", // "ret",
|
||||
"tableswitch", // "tableswitch",
|
||||
"lookupswitch", // "lookupswitch",
|
||||
"ireturn", // "ireturn",
|
||||
"lreturn", // "lreturn",
|
||||
"freturn", // "freturn",
|
||||
"dreturn", // "dreturn",
|
||||
"areturn", // "areturn",
|
||||
"return", // "return",
|
||||
"getstatic", // "getstatic",
|
||||
"putstatic", // "putstatic",
|
||||
"getfield", // "getfield",
|
||||
"putfield", // "putfield",
|
||||
"invokevirtual", // "invokevirtual",
|
||||
"invokespecial", // "invokespecial",
|
||||
"invokestatic", // "invokestatic",
|
||||
"invokeinterface", // "invokeinterface",
|
||||
"xxxunusedxxx", // "xxxunusedxxx",
|
||||
"new", // "new",
|
||||
"newarray", // "newarray",
|
||||
"anewarray", // "anewarray",
|
||||
"arraylength", // "arraylength",
|
||||
"athrow", // "athrow",
|
||||
"checkcast", // "checkcast",
|
||||
"instanceof", // "instanceof",
|
||||
"monitorenter", // "monitorenter",
|
||||
"monitorexit", // "monitorexit",
|
||||
"wide", // "wide",
|
||||
"multianewarray", // "multianewarray",
|
||||
"ifnull", // "ifnull",
|
||||
"ifnonnull", // "ifnonnull",
|
||||
"goto_w", // "goto_w",
|
||||
"jsr_w" // "jsr_w"
|
||||
};
|
||||
|
||||
private static String[] opcodeClasses = {
|
||||
"NOP", // "nop",
|
||||
"ACONST_NULL", // "aconst_null",
|
||||
null, // "iconst_m1",
|
||||
null, // "iconst_0",
|
||||
null, // "iconst_1",
|
||||
null, // "iconst_2",
|
||||
null, // "iconst_3",
|
||||
null, // "iconst_4",
|
||||
null, // "iconst_5",
|
||||
"LCONST_0", // "lconst_0",
|
||||
"LCONST_1", // "lconst_1",
|
||||
"FCONST_0", // "fconst_0",
|
||||
"FCONST_1", // "fconst_1",
|
||||
"FCONST_2", // "fconst_2",
|
||||
"DCONST_0", // "dconst_0",
|
||||
"DCONST_1", // "dconst_1",
|
||||
"BIPUSH", // "bipush",
|
||||
"SIPUSH", // "sipush",
|
||||
"LDC", // "ldc",
|
||||
"LDC_W", // "ldc_w",
|
||||
"LDC2_W", // "ldc2_w",
|
||||
"ILOAD", // "iload",
|
||||
"LLOAD", // "lload",
|
||||
"FLOAD", // "fload",
|
||||
"DLOAD", // "dload",
|
||||
"ALOAD", // "aload",
|
||||
null, // "iload_0",
|
||||
null, // "iload_1",
|
||||
null, // "iload_2",
|
||||
null, // "iload_3",
|
||||
null, // "lload_0",
|
||||
null, // "lload_1",
|
||||
null, // "lload_2",
|
||||
null, // "lload_3",
|
||||
null, // "fload_0",
|
||||
null, // "fload_1",
|
||||
null, // "fload_2",
|
||||
null, // "fload_3",
|
||||
null, // "dload_0",
|
||||
null, // "dload_1",
|
||||
null, // "dload_2",
|
||||
null, // "dload_3",
|
||||
null, // "aload_0",
|
||||
null, // "aload_1",
|
||||
null, // "aload_2",
|
||||
null, // "aload_3",
|
||||
"IALOAD", // "iaload",
|
||||
"LALOAD", // "laload",
|
||||
"FALOAD", // "faload",
|
||||
"DALOAD", // "daload",
|
||||
"AALOAD", // "aaload",
|
||||
"BALOAD", // "baload",
|
||||
"CALOAD", // "caload",
|
||||
"SALOAD", // "saload",
|
||||
"ISTORE", // "istore",
|
||||
"LSTORE", // "lstore",
|
||||
"FSTORE", // "fstore",
|
||||
"DSTORE", // "dstore",
|
||||
"ASTORE", // "astore",
|
||||
null, // "istore_0",
|
||||
null, // "istore_1",
|
||||
null, // "istore_2",
|
||||
null, // "istore_3",
|
||||
null, // "lstore_0",
|
||||
null, // "lstore_1",
|
||||
null, // "lstore_2",
|
||||
null, // "lstore_3",
|
||||
null, // "fstore_0",
|
||||
null, // "fstore_1",
|
||||
null, // "fstore_2",
|
||||
null, // "fstore_3",
|
||||
null, // "dstore_0",
|
||||
null, // "dstore_1",
|
||||
null, // "dstore_2",
|
||||
null, // "dstore_3",
|
||||
null, // "astore_0",
|
||||
null, // "astore_1",
|
||||
null, // "astore_2",
|
||||
null, // "astore_3",
|
||||
"IASTORE", // "iastore",
|
||||
"LASTORE", // "lastore",
|
||||
"FASTORE", // "fastore",
|
||||
"DASTORE", // "dastore",
|
||||
"AASTORE", // "aastore",
|
||||
"BASTORE", // "bastore",
|
||||
"CASTORE", // "castore",
|
||||
"SASTORE", // "sastore",
|
||||
"POP", // "pop",
|
||||
"POP2", // "pop2",
|
||||
"DUP", // "dup",
|
||||
"DUP_X1", // "dup_x1",
|
||||
"DUP_X2", // "dup_x2",
|
||||
"DUP2", // "dup2",
|
||||
"DUP2_X1", // "dup2_x1",
|
||||
"DUP2_X2", // "dup2_x2",
|
||||
"SWAP", // "swap",
|
||||
"IADD", // "iadd",
|
||||
"LADD", // "ladd",
|
||||
"FADD", // "fadd",
|
||||
"DADD", // "dadd",
|
||||
"ISUB", // "isub",
|
||||
"LSUB", // "lsub",
|
||||
"FSUB", // "fsub",
|
||||
"DSUB", // "dsub",
|
||||
"IMUL", // "imul",
|
||||
"LMUL", // "lmul",
|
||||
"FMUL", // "fmul",
|
||||
"DMUL", // "dmul",
|
||||
"IDIV", // "idiv",
|
||||
"LDIV", // "ldiv",
|
||||
"FDIV", // "fdiv",
|
||||
"DDIV", // "ddiv",
|
||||
"IREM", // "irem",
|
||||
"LREM", // "lrem",
|
||||
"FREM", // "frem",
|
||||
"DREM", // "drem",
|
||||
"INEG", // "ineg",
|
||||
"LNEG", // "lneg",
|
||||
"FNEG", // "fneg",
|
||||
"DNEG", // "dneg",
|
||||
"ISHL", // "ishl",
|
||||
"LSHL", // "lshl",
|
||||
"ISHR", // "ishr",
|
||||
"LSHR", // "lshr",
|
||||
"IUSHR", // "iushr",
|
||||
"LUSHR", // "lushr",
|
||||
"IAND", // "iand",
|
||||
"LAND", // "land",
|
||||
"IOR", // "ior",
|
||||
"LOR", // "lor",
|
||||
"IXOR", // "ixor",
|
||||
"LXOR", // "lxor",
|
||||
"IINC", // "iinc",
|
||||
"I2L", // "i2l",
|
||||
"I2F", // "i2f",
|
||||
"I2D", // "i2d",
|
||||
"L2I", // "l2i",
|
||||
"L2F", // "l2f",
|
||||
"L2D", // "l2d",
|
||||
"F2I", // "f2i",
|
||||
"F2L", // "f2l",
|
||||
"F2D", // "f2d",
|
||||
"D2I", // "d2i",
|
||||
"D2L", // "d2l",
|
||||
"D2F", // "d2f",
|
||||
"I2B", // "i2b",
|
||||
"I2C", // "i2c",
|
||||
"I2S", // "i2s",
|
||||
"LCMP", // "lcmp",
|
||||
"FCMPL", // "fcmpl",
|
||||
"FCMPG", // "fcmpg",
|
||||
"DCMPL", // "dcmpl",
|
||||
"DCMPG", // "dcmpg",
|
||||
"IFEQ", // "ifeq",
|
||||
"IFNE", // "ifne",
|
||||
"IFLT", // "iflt",
|
||||
"IFGE", // "ifge",
|
||||
"IFGT", // "ifgt",
|
||||
"IFLE", // "ifle",
|
||||
"IF_ICMPEQ", // "if_icmpeq",
|
||||
"IF_ICMPNE", // "if_icmpne",
|
||||
"IF_ICMPLT", // "if_icmplt",
|
||||
"IF_ICMPGE", // "if_icmpge",
|
||||
"IF_ICMPGT", // "if_icmpgt",
|
||||
"IF_ICMPLE", // "if_icmple",
|
||||
"IF_ACMPEQ", // "if_acmpeq",
|
||||
"IF_ACMPNE", // "if_acmpne",
|
||||
"GOTO", // "goto",
|
||||
"JSR", // "jsr",
|
||||
"RET", // "ret",
|
||||
"TABLESWITCH", // "tableswitch",
|
||||
"LOOKUPSWITCH", // "lookupswitch",
|
||||
"IRETURN", // "ireturn",
|
||||
"LRETURN", // "lreturn",
|
||||
"FRETURN", // "freturn",
|
||||
"DRETURN", // "dreturn",
|
||||
"ARETURN", // "areturn",
|
||||
"RETURN", // "return",
|
||||
"GETSTATIC", // "getstatic",
|
||||
"PUTSTATIC", // "putstatic",
|
||||
"GETFIELD", // "getfield",
|
||||
"PUTFIELD", // "putfield",
|
||||
"INVOKEVIRTUAL", // "invokevirtual",
|
||||
"INVOKESPECIAL", // "invokespecial",
|
||||
"INVOKESTATIC", // "invokestatic",
|
||||
"INVOKEINTERFACE", // "invokeinterface",
|
||||
null , // "xxxunusedxxx",
|
||||
"NEW", // "new",
|
||||
"NEWARRAY", // "newarray",
|
||||
"ANEWARRAY", // "anewarray",
|
||||
"ARRAYLENGTH", // "arraylength",
|
||||
"ATHROW", // "athrow",
|
||||
"CHECKCAST", // "checkcast",
|
||||
"INSTANCEOF", // "instanceof",
|
||||
"MONITORENTER", // "monitorenter",
|
||||
"MONITOREXIT", // "monitorexit",
|
||||
null, // "wide",
|
||||
"MULTIANEWARRAY", // "multianewarray",
|
||||
"IFNULL", // "ifnull",
|
||||
"IFNONNULL", // "ifnonnull",
|
||||
"GOTO_W", // "goto_w",
|
||||
"JSR_W" // "jsr_w"
|
||||
};
|
||||
|
||||
|
||||
|
||||
}
|
62
src/de/fernflower/code/ExceptionHandler.java
Normal file
62
src/de/fernflower/code/ExceptionHandler.java
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Fernflower - The Analytical Java Decompiler
|
||||
* http://www.reversed-java.com
|
||||
*
|
||||
* (C) 2008 - 2010, Stiver
|
||||
*
|
||||
* This software is NEITHER public domain NOR free software
|
||||
* as per GNU License. See license.txt for more details.
|
||||
*
|
||||
* This software is distributed WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
package de.fernflower.code;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import de.fernflower.main.DecompilerContext;
|
||||
|
||||
public class ExceptionHandler {
|
||||
|
||||
public int from = 0;
|
||||
public int to = 0;
|
||||
public int handler = 0;
|
||||
|
||||
public int from_instr = 0;
|
||||
public int to_instr = 0;
|
||||
public int handler_instr = 0;
|
||||
|
||||
public int class_index = 0;
|
||||
public String exceptionClass = null;
|
||||
|
||||
public ExceptionHandler(){}
|
||||
|
||||
public ExceptionHandler(int from_raw, int to_raw, int handler_raw, String exceptionClass) {
|
||||
this.from = from_raw;
|
||||
this.to = to_raw;
|
||||
this.handler = handler_raw;
|
||||
this.exceptionClass = exceptionClass;
|
||||
}
|
||||
|
||||
public void writeToStream(DataOutputStream out) throws IOException {
|
||||
out.writeShort(from);
|
||||
out.writeShort(to);
|
||||
out.writeShort(handler);
|
||||
out.writeShort(class_index);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
|
||||
String new_line_separator = DecompilerContext.getNewLineSeparator();
|
||||
|
||||
StringBuffer buf = new StringBuffer();
|
||||
buf.append("from: "+from+" to: "+to+" handler: "+handler+new_line_separator);
|
||||
buf.append("from_instr: "+from_instr+" to_instr: "+to_instr+" handler_instr: "+handler_instr+new_line_separator);
|
||||
buf.append("exceptionClass: "+exceptionClass+new_line_separator);
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
}
|
57
src/de/fernflower/code/ExceptionTable.java
Normal file
57
src/de/fernflower/code/ExceptionTable.java
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Fernflower - The Analytical Java Decompiler
|
||||
* http://www.reversed-java.com
|
||||
*
|
||||
* (C) 2008 - 2010, Stiver
|
||||
*
|
||||
* This software is NEITHER public domain NOR free software
|
||||
* as per GNU License. See license.txt for more details.
|
||||
*
|
||||
* This software is distributed WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
package de.fernflower.code;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import de.fernflower.code.interpreter.Util;
|
||||
import de.fernflower.struct.StructContext;
|
||||
|
||||
public class ExceptionTable {
|
||||
|
||||
private List<ExceptionHandler> handlers = new ArrayList<ExceptionHandler>();
|
||||
|
||||
public ExceptionTable() {}
|
||||
|
||||
public ExceptionTable(List<ExceptionHandler> handlers) {
|
||||
this.handlers = handlers;
|
||||
}
|
||||
|
||||
|
||||
public ExceptionHandler getHandlerByClass(StructContext context, int line, String valclass, boolean withany) {
|
||||
|
||||
ExceptionHandler res = null; // no handler found
|
||||
|
||||
for(ExceptionHandler handler : handlers) {
|
||||
if(handler.from<=line && handler.to>line) {
|
||||
String name = handler.exceptionClass;
|
||||
|
||||
if((withany && name==null) || // any -> finally or synchronized handler
|
||||
(name!=null && Util.instanceOf(context, valclass, name))) {
|
||||
res = handler;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
public List<ExceptionHandler> getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
}
|
38
src/de/fernflower/code/FullInstructionSequence.java
Normal file
38
src/de/fernflower/code/FullInstructionSequence.java
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Fernflower - The Analytical Java Decompiler
|
||||
* http://www.reversed-java.com
|
||||
*
|
||||
* (C) 2008 - 2010, Stiver
|
||||
*
|
||||
* This software is NEITHER public domain NOR free software
|
||||
* as per GNU License. See license.txt for more details.
|
||||
*
|
||||
* This software is distributed WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
package de.fernflower.code;
|
||||
|
||||
import de.fernflower.util.VBStyleCollection;
|
||||
|
||||
|
||||
public class FullInstructionSequence extends InstructionSequence {
|
||||
|
||||
// *****************************************************************************
|
||||
// constructors
|
||||
// *****************************************************************************
|
||||
|
||||
public FullInstructionSequence(VBStyleCollection<Instruction, Integer> collinstr, ExceptionTable extable) {
|
||||
this.collinstr = collinstr;
|
||||
this.exceptionTable = extable;
|
||||
|
||||
// translate raw exception handlers to instr
|
||||
for(ExceptionHandler handler : extable.getHandlers()) {
|
||||
handler.from_instr = this.getPointerByAbsOffset(handler.from);
|
||||
handler.to_instr = this.getPointerByAbsOffset(handler.to);
|
||||
handler.handler_instr = this.getPointerByAbsOffset(handler.handler);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
36
src/de/fernflower/code/IfInstruction.java
Normal file
36
src/de/fernflower/code/IfInstruction.java
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Fernflower - The Analytical Java Decompiler
|
||||
* http://www.reversed-java.com
|
||||
*
|
||||
* (C) 2008 - 2010, Stiver
|
||||
*
|
||||
* This software is NEITHER public domain NOR free software
|
||||
* as per GNU License. See license.txt for more details.
|
||||
*
|
||||
* This software is distributed WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
package de.fernflower.code;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
/*
|
||||
* opc_ifeq, opc_ifne, opc_iflt, opc_ifge, opc_ifgt, opc_ifle, opc_if_icmpeq, opc_if_icmpne, opc_if_icmplt,
|
||||
* opc_if_icmpge, opc_if_icmpgt, opc_if_icmple, opc_if_acmpeq, opc_if_acmpne, opc_ifnull, opc_ifnonnull
|
||||
*/
|
||||
|
||||
public class IfInstruction extends JumpInstruction {
|
||||
|
||||
public void writeToStream(DataOutputStream out, int offset) throws IOException {
|
||||
out.writeByte(opcode);
|
||||
out.writeShort(getOperand(0));
|
||||
}
|
||||
|
||||
public int length() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
}
|
123
src/de/fernflower/code/Instruction.java
Normal file
123
src/de/fernflower/code/Instruction.java
Normal file
@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Fernflower - The Analytical Java Decompiler
|
||||
* http://www.reversed-java.com
|
||||
*
|
||||
* (C) 2008 - 2010, Stiver
|
||||
*
|
||||
* This software is NEITHER public domain NOR free software
|
||||
* as per GNU License. See license.txt for more details.
|
||||
*
|
||||
* This software is distributed WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
package de.fernflower.code;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public class Instruction implements CodeConstants {
|
||||
|
||||
// *****************************************************************************
|
||||
// public fields
|
||||
// *****************************************************************************
|
||||
|
||||
public int opcode;
|
||||
|
||||
public int group = CodeConstants.GROUP_GENERAL;
|
||||
|
||||
public boolean wide = false;
|
||||
|
||||
|
||||
// *****************************************************************************
|
||||
// private fields
|
||||
// *****************************************************************************
|
||||
|
||||
private int[] operands = null;
|
||||
|
||||
// *****************************************************************************
|
||||
// public methods
|
||||
// *****************************************************************************
|
||||
|
||||
public Instruction() {}
|
||||
|
||||
public int length() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
public int operandsCount() {
|
||||
return (operands==null)?0:operands.length;
|
||||
}
|
||||
|
||||
public int getOperand(int index) {
|
||||
return operands[index];
|
||||
}
|
||||
|
||||
public Instruction clone() {
|
||||
return ConstantsUtil.getInstructionInstance(opcode, wide, group, operands==null?null:(int[])operands.clone());
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
|
||||
String res = wide?"@wide ":"";
|
||||
res+="@"+ConstantsUtil.getName(opcode);
|
||||
|
||||
int len = operandsCount();
|
||||
for(int i=0;i<len;i++) {
|
||||
int op = operands[i];
|
||||
if(op<0) {
|
||||
res+=" -"+Integer.toHexString(-op);
|
||||
} else {
|
||||
res+=" "+Integer.toHexString(op);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
|
||||
}
|
||||
|
||||
public boolean canFallthrough() {
|
||||
return opcode!=opc_goto && opcode!=opc_goto_w && opcode!=opc_ret &&
|
||||
!(opcode>=opc_ireturn && opcode<=opc_return) && opcode!=opc_athrow
|
||||
&& opcode!=opc_jsr && opcode!=opc_tableswitch && opcode!=opc_lookupswitch;
|
||||
}
|
||||
|
||||
public boolean equalsInstruction(Instruction instr) {
|
||||
if(opcode != instr.opcode || wide != instr.wide
|
||||
|| operandsCount() != instr.operandsCount()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(operands != null) {
|
||||
for(int i=0;i<operands.length;i++) {
|
||||
if(operands[i] != instr.getOperand(i)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// should be overwritten by subclasses
|
||||
public void initInstruction(InstructionSequence seq) {}
|
||||
|
||||
// should be overwritten by subclasses
|
||||
public void writeToStream(DataOutputStream out, int offset) throws IOException {
|
||||
out.writeByte(opcode);
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// getter and setter methods
|
||||
// *****************************************************************************
|
||||
|
||||
public int[] getOperands() {
|
||||
return operands;
|
||||
}
|
||||
|
||||
public void setOperands(int[] operands) {
|
||||
this.operands = operands;
|
||||
}
|
||||
|
||||
}
|
219
src/de/fernflower/code/InstructionSequence.java
Normal file
219
src/de/fernflower/code/InstructionSequence.java
Normal file
@ -0,0 +1,219 @@
|
||||
/*
|
||||
* Fernflower - The Analytical Java Decompiler
|
||||
* http://www.reversed-java.com
|
||||
*
|
||||
* (C) 2008 - 2010, Stiver
|
||||
*
|
||||
* This software is NEITHER public domain NOR free software
|
||||
* as per GNU License. See license.txt for more details.
|
||||
*
|
||||
* This software is distributed WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
package de.fernflower.code;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import de.fernflower.code.interpreter.Util;
|
||||
import de.fernflower.main.DecompilerContext;
|
||||
import de.fernflower.struct.StructContext;
|
||||
import de.fernflower.util.InterpreterUtil;
|
||||
import de.fernflower.util.VBStyleCollection;
|
||||
|
||||
|
||||
public abstract class InstructionSequence {
|
||||
|
||||
// *****************************************************************************
|
||||
// private fields
|
||||
// *****************************************************************************
|
||||
|
||||
protected VBStyleCollection<Instruction, Integer> collinstr = new VBStyleCollection<Instruction, Integer>();
|
||||
|
||||
protected int pointer = 0;
|
||||
|
||||
protected ExceptionTable exceptionTable = new ExceptionTable();
|
||||
|
||||
// *****************************************************************************
|
||||
// public methods
|
||||
// *****************************************************************************
|
||||
|
||||
// to nbe overwritten
|
||||
public InstructionSequence clone() {return null;}
|
||||
|
||||
public void clear() {
|
||||
collinstr.clear();
|
||||
pointer = 0;
|
||||
exceptionTable = new ExceptionTable();
|
||||
}
|
||||
|
||||
public void addInstruction(Instruction inst, int offset){
|
||||
collinstr.addWithKey(inst, offset);
|
||||
}
|
||||
|
||||
public void addInstruction(int index, Instruction inst, int offset){
|
||||
collinstr.addWithKeyAndIndex(index, inst, offset);
|
||||
}
|
||||
|
||||
public void addSequence(InstructionSequence seq){
|
||||
for(int i=0;i<seq.length();i++) {
|
||||
addInstruction(seq.getInstr(i), -1); // TODO: any sensible value possible?
|
||||
}
|
||||
}
|
||||
|
||||
public void removeInstruction(int index) {
|
||||
collinstr.remove(index);
|
||||
}
|
||||
|
||||
public Instruction getCurrentInstr() {
|
||||
return (Instruction)collinstr.get(pointer);
|
||||
}
|
||||
|
||||
public Instruction getInstr(int index) {
|
||||
return (Instruction)collinstr.get(index);
|
||||
}
|
||||
|
||||
public Instruction getLastInstr() {
|
||||
return (Instruction)collinstr.getLast();
|
||||
}
|
||||
|
||||
public int getCurrentOffset() {
|
||||
return ((Integer)collinstr.getKey(pointer)).intValue();
|
||||
}
|
||||
|
||||
public int getOffset(int index) {
|
||||
return ((Integer)collinstr.getKey(index)).intValue();
|
||||
}
|
||||
|
||||
public int getPointerByAbsOffset(int offset) {
|
||||
Integer absoffset = new Integer(offset);
|
||||
if(collinstr.containsKey(absoffset)) {
|
||||
return collinstr.getIndexByKey(absoffset);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public int getPointerByRelOffset(int offset) {
|
||||
Integer absoffset = new Integer(((Integer)collinstr.getKey(pointer)).intValue()+offset);
|
||||
if(collinstr.containsKey(absoffset)) {
|
||||
return collinstr.getIndexByKey(absoffset);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public void setPointerByAbsOffset(int offset) {
|
||||
Integer absoffset = new Integer(((Integer)collinstr.getKey(pointer)).intValue()+offset);
|
||||
if(collinstr.containsKey(absoffset)) {
|
||||
pointer = collinstr.getIndexByKey(absoffset);
|
||||
}
|
||||
}
|
||||
|
||||
public int length() {
|
||||
return collinstr.size();
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return collinstr.isEmpty();
|
||||
}
|
||||
|
||||
public void addToPointer(int diff) {
|
||||
this.pointer += diff;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return toString(0);
|
||||
}
|
||||
|
||||
public String toString(int indent) {
|
||||
|
||||
String new_line_separator = DecompilerContext.getNewLineSeparator();
|
||||
|
||||
StringBuffer buf = new StringBuffer();
|
||||
|
||||
for(int i=0;i<collinstr.size();i++) {
|
||||
buf.append(InterpreterUtil.getIndentString(indent));
|
||||
buf.append(((Integer)collinstr.getKey(i)).intValue());
|
||||
buf.append(": ");
|
||||
buf.append(((Instruction)collinstr.get(i)).toString());
|
||||
buf.append(new_line_separator);
|
||||
}
|
||||
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
public void writeCodeToStream(DataOutputStream out) throws IOException {
|
||||
|
||||
for(int i=0;i<collinstr.size();i++) {
|
||||
((Instruction)collinstr.get(i)).writeToStream(out, ((Integer)collinstr.getKey(i)).intValue());
|
||||
}
|
||||
}
|
||||
|
||||
public void writeExceptionsToStream(DataOutputStream out) throws IOException {
|
||||
|
||||
List<ExceptionHandler> handlers = exceptionTable.getHandlers();
|
||||
|
||||
out.writeShort(handlers.size());
|
||||
for(int i=0;i<handlers.size();i++) {
|
||||
((ExceptionHandler)handlers.get(i)).writeToStream(out);
|
||||
}
|
||||
}
|
||||
|
||||
public void sortHandlers(final StructContext context) {
|
||||
|
||||
Collections.sort(exceptionTable.getHandlers(), new Comparator<ExceptionHandler>() {
|
||||
|
||||
public int compare(ExceptionHandler handler0, ExceptionHandler handler1) {
|
||||
|
||||
if(handler0.to == handler1.to) {
|
||||
if(handler0.exceptionClass == null) {
|
||||
return 1;
|
||||
} else {
|
||||
if(handler1.exceptionClass == null) {
|
||||
return -1;
|
||||
} else if(handler0.exceptionClass.equals(handler1.exceptionClass)){
|
||||
return (handler0.from > handler1.from)?-1:1; // invalid code
|
||||
} else {
|
||||
if(Util.instanceOf(context, handler0.exceptionClass, handler1.exceptionClass)) {
|
||||
return -1;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return (handler0.to > handler1.to)?1:-1;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
// *****************************************************************************
|
||||
// getter and setter methods
|
||||
// *****************************************************************************
|
||||
|
||||
public int getPointer() {
|
||||
return pointer;
|
||||
}
|
||||
|
||||
public void setPointer(int pointer) {
|
||||
this.pointer = pointer;
|
||||
}
|
||||
|
||||
public ExceptionTable getExceptionTable() {
|
||||
return exceptionTable;
|
||||
}
|
||||
|
||||
public void setExceptionTable(ExceptionTable exceptionTable) {
|
||||
this.exceptionTable = exceptionTable;
|
||||
}
|
||||
|
||||
}
|
41
src/de/fernflower/code/JumpInstruction.java
Normal file
41
src/de/fernflower/code/JumpInstruction.java
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Fernflower - The Analytical Java Decompiler
|
||||
* http://www.reversed-java.com
|
||||
*
|
||||
* (C) 2008 - 2010, Stiver
|
||||
*
|
||||
* This software is NEITHER public domain NOR free software
|
||||
* as per GNU License. See license.txt for more details.
|
||||
*
|
||||
* This software is distributed WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
package de.fernflower.code;
|
||||
|
||||
/*
|
||||
* opc_ifeq, opc_ifne, opc_iflt, opc_ifge, opc_ifgt, opc_ifle, opc_if_icmpeq, opc_if_icmpne, opc_if_icmplt,
|
||||
* opc_if_icmpge, opc_if_icmpgt, opc_if_icmple, opc_if_acmpeq, opc_if_acmpne, opc_ifnull, opc_ifnonnull
|
||||
* opc_goto, opc_jsr, opc_goto_w, opc_jsr_w
|
||||
*/
|
||||
|
||||
|
||||
public class JumpInstruction extends Instruction {
|
||||
|
||||
public int destination;
|
||||
|
||||
public JumpInstruction() {}
|
||||
|
||||
public void initInstruction(InstructionSequence seq) {
|
||||
destination = seq.getPointerByRelOffset(this.getOperand(0));
|
||||
}
|
||||
|
||||
public JumpInstruction clone() {
|
||||
JumpInstruction newinstr = (JumpInstruction)super.clone();
|
||||
|
||||
newinstr.destination = destination;
|
||||
return newinstr;
|
||||
}
|
||||
|
||||
}
|
39
src/de/fernflower/code/SimpleInstructionSequence.java
Normal file
39
src/de/fernflower/code/SimpleInstructionSequence.java
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Fernflower - The Analytical Java Decompiler
|
||||
* http://www.reversed-java.com
|
||||
*
|
||||
* (C) 2008 - 2010, Stiver
|
||||
*
|
||||
* This software is NEITHER public domain NOR free software
|
||||
* as per GNU License. See license.txt for more details.
|
||||
*
|
||||
* This software is distributed WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
package de.fernflower.code;
|
||||
|
||||
import de.fernflower.util.VBStyleCollection;
|
||||
|
||||
public class SimpleInstructionSequence extends InstructionSequence {
|
||||
|
||||
public SimpleInstructionSequence() {}
|
||||
|
||||
public SimpleInstructionSequence(VBStyleCollection<Instruction, Integer> collinstr) {
|
||||
this.collinstr = collinstr;
|
||||
}
|
||||
|
||||
public SimpleInstructionSequence clone() {
|
||||
SimpleInstructionSequence newseq = new SimpleInstructionSequence(collinstr.clone());
|
||||
newseq.setPointer(this.getPointer());
|
||||
|
||||
return newseq;
|
||||
}
|
||||
|
||||
public void removeInstruction(int index) {
|
||||
collinstr.remove(index);
|
||||
}
|
||||
|
||||
|
||||
}
|
93
src/de/fernflower/code/SwitchInstruction.java
Normal file
93
src/de/fernflower/code/SwitchInstruction.java
Normal file
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Fernflower - The Analytical Java Decompiler
|
||||
* http://www.reversed-java.com
|
||||
*
|
||||
* (C) 2008 - 2010, Stiver
|
||||
*
|
||||
* This software is NEITHER public domain NOR free software
|
||||
* as per GNU License. See license.txt for more details.
|
||||
*
|
||||
* This software is distributed WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
package de.fernflower.code;
|
||||
|
||||
/*
|
||||
* opc_tableswitch, lookupswitch
|
||||
*/
|
||||
|
||||
public class SwitchInstruction extends Instruction {
|
||||
|
||||
private int[] destinations;
|
||||
|
||||
private int[] values;
|
||||
|
||||
private int defaultdest;
|
||||
|
||||
public SwitchInstruction() {}
|
||||
|
||||
|
||||
public void initInstruction(InstructionSequence seq) {
|
||||
|
||||
int pref = (opcode==CodeConstants.opc_tableswitch?3:2);
|
||||
int len = this.getOperands().length - pref;
|
||||
defaultdest = seq.getPointerByRelOffset(this.getOperand(0));
|
||||
|
||||
int low = 0;
|
||||
|
||||
if(opcode==CodeConstants.opc_lookupswitch) {
|
||||
len/=2;
|
||||
} else {
|
||||
low = this.getOperand(1);
|
||||
}
|
||||
|
||||
destinations = new int[len];
|
||||
values = new int[len];
|
||||
|
||||
for(int i=0,k=0;i<len;i++,k++) {
|
||||
if(opcode==CodeConstants.opc_lookupswitch){
|
||||
values[i] = this.getOperand(pref+k);
|
||||
k++;
|
||||
} else {
|
||||
values[i] = low+k;
|
||||
}
|
||||
destinations[i] = seq.getPointerByRelOffset(this.getOperand(pref+k));
|
||||
}
|
||||
}
|
||||
|
||||
public SwitchInstruction clone() {
|
||||
SwitchInstruction newinstr = (SwitchInstruction)super.clone();
|
||||
|
||||
newinstr.defaultdest = defaultdest;
|
||||
newinstr.destinations = destinations.clone();
|
||||
newinstr.values = values.clone();
|
||||
|
||||
return newinstr;
|
||||
}
|
||||
|
||||
public int[] getDestinations() {
|
||||
return destinations;
|
||||
}
|
||||
|
||||
public void setDestinations(int[] destinations) {
|
||||
this.destinations = destinations;
|
||||
}
|
||||
|
||||
public int getDefaultdest() {
|
||||
return defaultdest;
|
||||
}
|
||||
|
||||
public void setDefaultdest(int defaultdest) {
|
||||
this.defaultdest = defaultdest;
|
||||
}
|
||||
|
||||
public int[] getValues() {
|
||||
return values;
|
||||
}
|
||||
|
||||
public void setValues(int[] values) {
|
||||
this.values = values;
|
||||
}
|
||||
}
|
265
src/de/fernflower/code/cfg/BasicBlock.java
Normal file
265
src/de/fernflower/code/cfg/BasicBlock.java
Normal file
@ -0,0 +1,265 @@
|
||||
/*
|
||||
* Fernflower - The Analytical Java Decompiler
|
||||
* http://www.reversed-java.com
|
||||
*
|
||||
* (C) 2008 - 2010, Stiver
|
||||
*
|
||||
* This software is NEITHER public domain NOR free software
|
||||
* as per GNU License. See license.txt for more details.
|
||||
*
|
||||
* This software is distributed WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
package de.fernflower.code.cfg;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
import de.fernflower.code.InstructionSequence;
|
||||
import de.fernflower.code.SimpleInstructionSequence;
|
||||
import de.fernflower.main.DecompilerContext;
|
||||
import de.fernflower.modules.decompiler.decompose.IGraphNode;
|
||||
|
||||
public class BasicBlock implements IGraphNode {
|
||||
|
||||
// *****************************************************************************
|
||||
// public fields
|
||||
// *****************************************************************************
|
||||
|
||||
public int id = 0;
|
||||
|
||||
public int mark = 0;
|
||||
|
||||
// *****************************************************************************
|
||||
// private fields
|
||||
// *****************************************************************************
|
||||
|
||||
private InstructionSequence seq = new SimpleInstructionSequence();
|
||||
|
||||
private List<BasicBlock> preds = new ArrayList<BasicBlock>();
|
||||
|
||||
private List<BasicBlock> succs = new ArrayList<BasicBlock>();
|
||||
|
||||
private List<Integer> instrOldOffsets = new ArrayList<Integer>();
|
||||
|
||||
private List<BasicBlock> predExceptions = new ArrayList<BasicBlock>();
|
||||
|
||||
private List<BasicBlock> succExceptions = new ArrayList<BasicBlock>();
|
||||
|
||||
|
||||
|
||||
public BasicBlock() {}
|
||||
|
||||
public BasicBlock(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// public methods
|
||||
// *****************************************************************************
|
||||
|
||||
public Object clone() {
|
||||
|
||||
BasicBlock block = new BasicBlock();
|
||||
block.id = id;
|
||||
block.setSeq(seq.clone());
|
||||
block.setInstrOldOffsets(new ArrayList<Integer>(instrOldOffsets));
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
public void free() {
|
||||
preds.clear();
|
||||
succs.clear();
|
||||
instrOldOffsets.clear();
|
||||
succExceptions.clear();
|
||||
seq = new SimpleInstructionSequence();
|
||||
}
|
||||
|
||||
public Instruction getInstruction(int index) {
|
||||
return seq.getInstr(index);
|
||||
}
|
||||
|
||||
public Instruction getLastInstruction() {
|
||||
if(seq.isEmpty()) {
|
||||
return null;
|
||||
} else {
|
||||
return seq.getLastInstr();
|
||||
}
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return seq.length();
|
||||
}
|
||||
|
||||
public void addPredecessor(BasicBlock block) {
|
||||
preds.add(block);
|
||||
}
|
||||
|
||||
public void removePredecessor(BasicBlock block) {
|
||||
while(preds.remove(block));
|
||||
}
|
||||
|
||||
public void addSuccessor(BasicBlock block) {
|
||||
succs.add(block);
|
||||
block.addPredecessor(this);
|
||||
}
|
||||
|
||||
public void removeSuccessor(BasicBlock block) {
|
||||
while(succs.remove(block));
|
||||
block.removePredecessor(this);
|
||||
}
|
||||
|
||||
// FIXME: unify block comparisons: id or direkt equality
|
||||
public void replaceSuccessor(BasicBlock oldBlock, BasicBlock newBlock) {
|
||||
for(int i=0;i<succs.size();i++) {
|
||||
if(succs.get(i).id == oldBlock.id) {
|
||||
succs.set(i, newBlock);
|
||||
oldBlock.removePredecessor(this);
|
||||
newBlock.addPredecessor(this);
|
||||
}
|
||||
}
|
||||
|
||||
for(int i=0;i<succExceptions.size();i++) {
|
||||
if(succExceptions.get(i).id == oldBlock.id) {
|
||||
succExceptions.set(i, newBlock);
|
||||
oldBlock.removePredecessorException(this);
|
||||
newBlock.addPredecessorException(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void addPredecessorException(BasicBlock block) {
|
||||
predExceptions.add(block);
|
||||
}
|
||||
|
||||
public void removePredecessorException(BasicBlock block) {
|
||||
while(predExceptions.remove(block));
|
||||
}
|
||||
|
||||
public void addSuccessorException(BasicBlock block) {
|
||||
if(!succExceptions.contains(block)) {
|
||||
succExceptions.add(block);
|
||||
block.addPredecessorException(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeSuccessorException(BasicBlock block) {
|
||||
while(succExceptions.remove(block));
|
||||
block.removePredecessorException(this);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return toString(0);
|
||||
}
|
||||
|
||||
public String toString(int indent) {
|
||||
|
||||
String new_line_separator = DecompilerContext.getNewLineSeparator();
|
||||
|
||||
return id+":" + new_line_separator +seq.toString(indent);
|
||||
}
|
||||
|
||||
public String toStringOldIndices() {
|
||||
|
||||
String new_line_separator = DecompilerContext.getNewLineSeparator();
|
||||
|
||||
StringBuffer buf = new StringBuffer();
|
||||
|
||||
for(int i=0;i<seq.length();i++) {
|
||||
if(i<instrOldOffsets.size()) {
|
||||
buf.append(instrOldOffsets.get(i));
|
||||
} else {
|
||||
buf.append("-1");
|
||||
}
|
||||
buf.append(": ");
|
||||
buf.append(seq.getInstr(i).toString());
|
||||
buf.append(new_line_separator);
|
||||
}
|
||||
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
public boolean isSuccessor(BasicBlock block) {
|
||||
for(BasicBlock succ : succs) {
|
||||
if(succ.id == block.id) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isPredecessor(BasicBlock block) {
|
||||
for(int i=0;i<preds.size();i++) {
|
||||
if(preds.get(i).id == block.id) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// getter and setter methods
|
||||
// *****************************************************************************
|
||||
|
||||
public List<Integer> getInstrOldOffsets() {
|
||||
return instrOldOffsets;
|
||||
}
|
||||
|
||||
public void setInstrOldOffsets(List<Integer> instrInds) {
|
||||
this.instrOldOffsets = instrInds;
|
||||
}
|
||||
|
||||
public List<? extends IGraphNode> getPredecessors() {
|
||||
List<BasicBlock> lst = new ArrayList<BasicBlock>(preds);
|
||||
lst.addAll(predExceptions);
|
||||
return lst;
|
||||
}
|
||||
|
||||
public List<BasicBlock> getPreds() {
|
||||
return preds;
|
||||
}
|
||||
|
||||
public void setPreds(List<BasicBlock> preds) {
|
||||
this.preds = preds;
|
||||
}
|
||||
|
||||
public InstructionSequence getSeq() {
|
||||
return seq;
|
||||
}
|
||||
|
||||
public void setSeq(InstructionSequence seq) {
|
||||
this.seq = seq;
|
||||
}
|
||||
|
||||
public List<BasicBlock> getSuccs() {
|
||||
return succs;
|
||||
}
|
||||
|
||||
public void setSuccs(List<BasicBlock> succs) {
|
||||
this.succs = succs;
|
||||
}
|
||||
|
||||
|
||||
public List<BasicBlock> getSuccExceptions() {
|
||||
return succExceptions;
|
||||
}
|
||||
|
||||
|
||||
public void setSuccExceptions(List<BasicBlock> succExceptions) {
|
||||
this.succExceptions = succExceptions;
|
||||
}
|
||||
|
||||
public List<BasicBlock> getPredExceptions() {
|
||||
return predExceptions;
|
||||
}
|
||||
|
||||
public void setPredExceptions(List<BasicBlock> predExceptions) {
|
||||
this.predExceptions = predExceptions;
|
||||
}
|
||||
|
||||
|
||||
}
|
887
src/de/fernflower/code/cfg/ControlFlowGraph.java
Normal file
887
src/de/fernflower/code/cfg/ControlFlowGraph.java
Normal file
@ -0,0 +1,887 @@
|
||||
/*
|
||||
* Fernflower - The Analytical Java Decompiler
|
||||
* http://www.reversed-java.com
|
||||
*
|
||||
* (C) 2008 - 2010, Stiver
|
||||
*
|
||||
* This software is NEITHER public domain NOR free software
|
||||
* as per GNU License. See license.txt for more details.
|
||||
*
|
||||
* This software is distributed WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
package de.fernflower.code.cfg;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import de.fernflower.code.CodeConstants;
|
||||
import de.fernflower.code.ExceptionHandler;
|
||||
import de.fernflower.code.Instruction;
|
||||
import de.fernflower.code.InstructionSequence;
|
||||
import de.fernflower.code.JumpInstruction;
|
||||
import de.fernflower.code.SimpleInstructionSequence;
|
||||
import de.fernflower.code.SwitchInstruction;
|
||||
import de.fernflower.code.interpreter.InstructionImpact;
|
||||
import de.fernflower.main.DecompilerContext;
|
||||
import de.fernflower.modules.code.DeadCodeHelper;
|
||||
import de.fernflower.struct.StructMethod;
|
||||
import de.fernflower.struct.consts.ConstantPool;
|
||||
import de.fernflower.struct.gen.DataPoint;
|
||||
import de.fernflower.struct.gen.VarType;
|
||||
import de.fernflower.util.ListStack;
|
||||
import de.fernflower.util.VBStyleCollection;
|
||||
|
||||
public class ControlFlowGraph implements CodeConstants {
|
||||
|
||||
public int last_id = 0;
|
||||
|
||||
// *****************************************************************************
|
||||
// private fields
|
||||
// *****************************************************************************
|
||||
|
||||
private VBStyleCollection<BasicBlock, Integer> blocks;
|
||||
|
||||
private BasicBlock first;
|
||||
|
||||
private BasicBlock last;
|
||||
|
||||
private List<ExceptionRangeCFG> exceptions;
|
||||
|
||||
private HashMap<BasicBlock, BasicBlock> subroutines;
|
||||
|
||||
private HashSet<BasicBlock> finallyExits = new HashSet<BasicBlock>();
|
||||
|
||||
// *****************************************************************************
|
||||
// constructors
|
||||
// *****************************************************************************
|
||||
|
||||
public ControlFlowGraph(InstructionSequence seq) {
|
||||
buildBlocks(seq);
|
||||
}
|
||||
|
||||
|
||||
// *****************************************************************************
|
||||
// public methods
|
||||
// *****************************************************************************
|
||||
|
||||
public void free() {
|
||||
|
||||
for(BasicBlock block: blocks) {
|
||||
block.free();
|
||||
}
|
||||
|
||||
blocks.clear();
|
||||
first = null;
|
||||
last = null;
|
||||
exceptions.clear();
|
||||
finallyExits.clear();
|
||||
}
|
||||
|
||||
public void removeMarkers() {
|
||||
for(BasicBlock block: blocks) {
|
||||
block.mark = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
|
||||
String new_line_separator = DecompilerContext.getNewLineSeparator();
|
||||
|
||||
StringBuffer buf = new StringBuffer();
|
||||
|
||||
for(BasicBlock block: blocks) {
|
||||
buf.append("----- Block "+block.id+" -----" + new_line_separator);
|
||||
buf.append(block.toString());
|
||||
buf.append("----- Edges -----" + new_line_separator);
|
||||
|
||||
List<BasicBlock> suc = block.getSuccs();
|
||||
for(int j=0;j<suc.size();j++) {
|
||||
buf.append(">>>>>>>>(regular) Block "+((BasicBlock)suc.get(j)).id+new_line_separator);
|
||||
}
|
||||
suc = block.getSuccExceptions();
|
||||
for(int j=0;j<suc.size();j++) {
|
||||
BasicBlock handler = (BasicBlock)suc.get(j);
|
||||
ExceptionRangeCFG range = getExceptionRange(handler, block);
|
||||
|
||||
if(range == null) {
|
||||
buf.append(">>>>>>>>(exception) Block "+handler.id+"\t"+"ERROR: range not found!"+new_line_separator);
|
||||
} else {
|
||||
List<String> exceptionTypes = range.getExceptionTypes();
|
||||
if(exceptionTypes == null) {
|
||||
buf.append(">>>>>>>>(exception) Block "+handler.id+"\t"+"NULL"+new_line_separator);
|
||||
} else {
|
||||
for(String exceptionType : exceptionTypes) {
|
||||
buf.append(">>>>>>>>(exception) Block "+handler.id+"\t"+exceptionType+new_line_separator);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
buf.append("----- ----- -----" + new_line_separator);
|
||||
|
||||
}
|
||||
|
||||
return buf.toString();
|
||||
|
||||
}
|
||||
|
||||
public void inlineJsr(StructMethod mt) {
|
||||
processJsr();
|
||||
removeJsr(mt);
|
||||
|
||||
removeMarkers();
|
||||
|
||||
DeadCodeHelper.removeEmptyBlocks(this);
|
||||
}
|
||||
|
||||
public void removeBlock(BasicBlock block) {
|
||||
|
||||
while(block.getSuccs().size()>0) {
|
||||
block.removeSuccessor((BasicBlock)block.getSuccs().get(0));
|
||||
}
|
||||
|
||||
while(block.getSuccExceptions().size()>0) {
|
||||
block.removeSuccessorException((BasicBlock)block.getSuccExceptions().get(0));
|
||||
}
|
||||
|
||||
while(block.getPreds().size()>0) {
|
||||
((BasicBlock)block.getPreds().get(0)).removeSuccessor(block);
|
||||
}
|
||||
|
||||
while(block.getPredExceptions().size()>0) {
|
||||
((BasicBlock)block.getPredExceptions().get(0)).removeSuccessorException(block);
|
||||
}
|
||||
|
||||
last.removePredecessor(block);
|
||||
|
||||
blocks.removeWithKey(block.id);
|
||||
|
||||
for(int i=exceptions.size()-1;i>=0;i--) {
|
||||
ExceptionRangeCFG range = (ExceptionRangeCFG)exceptions.get(i);
|
||||
if(range.getHandler() == block) {
|
||||
exceptions.remove(i);
|
||||
} else {
|
||||
List<BasicBlock> lstRange = range.getProtectedRange();
|
||||
lstRange.remove(block);
|
||||
|
||||
if(lstRange.isEmpty()) {
|
||||
exceptions.remove(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Iterator<Entry<BasicBlock, BasicBlock>> it = subroutines.entrySet().iterator();
|
||||
while(it.hasNext()) {
|
||||
Entry<BasicBlock, BasicBlock> ent = it.next();
|
||||
if(ent.getKey() == block || ent.getValue() == block) {
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public ExceptionRangeCFG getExceptionRange(BasicBlock handler, BasicBlock block) {
|
||||
|
||||
//List<ExceptionRangeCFG> ranges = new ArrayList<ExceptionRangeCFG>();
|
||||
|
||||
for(int i=exceptions.size()-1;i>=0;i--) {
|
||||
ExceptionRangeCFG range = exceptions.get(i);
|
||||
if(range.getHandler() == handler && range.getProtectedRange().contains(block)) {
|
||||
return range;
|
||||
//ranges.add(range);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
//return ranges.isEmpty() ? null : ranges;
|
||||
}
|
||||
|
||||
// public String getExceptionsUniqueString(BasicBlock handler, BasicBlock block) {
|
||||
//
|
||||
// List<ExceptionRangeCFG> ranges = getExceptionRange(handler, block);
|
||||
//
|
||||
// if(ranges == null) {
|
||||
// return null;
|
||||
// } else {
|
||||
// Set<String> setExceptionStrings = new HashSet<String>();
|
||||
// for(ExceptionRangeCFG range : ranges) {
|
||||
// setExceptionStrings.add(range.getExceptionType());
|
||||
// }
|
||||
//
|
||||
// String ret = "";
|
||||
// for(String exception : setExceptionStrings) {
|
||||
// ret += exception;
|
||||
// }
|
||||
//
|
||||
// return ret;
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
// *****************************************************************************
|
||||
// private methods
|
||||
// *****************************************************************************
|
||||
|
||||
private void buildBlocks(InstructionSequence instrseq) {
|
||||
|
||||
short[] states = findStartInstructions(instrseq);
|
||||
|
||||
HashMap<Integer, BasicBlock> mapInstrBlocks = new HashMap<Integer, BasicBlock>();
|
||||
VBStyleCollection<BasicBlock, Integer> colBlocks = createBasicBlocks(states, instrseq, mapInstrBlocks);
|
||||
|
||||
blocks = colBlocks;
|
||||
|
||||
connectBlocks(colBlocks, mapInstrBlocks);
|
||||
|
||||
setExceptionEdges(instrseq, mapInstrBlocks);
|
||||
|
||||
setSubroutineEdges();
|
||||
|
||||
setFirstAndLastBlocks();
|
||||
}
|
||||
|
||||
private short[] findStartInstructions(InstructionSequence seq) {
|
||||
|
||||
int len = seq.length();
|
||||
short[] inststates = new short[len];
|
||||
|
||||
HashSet<Integer> excSet = new HashSet<Integer>();
|
||||
|
||||
for(ExceptionHandler handler : seq.getExceptionTable().getHandlers()) {
|
||||
excSet.add(handler.from_instr);
|
||||
excSet.add(handler.to_instr);
|
||||
excSet.add(handler.handler_instr);
|
||||
}
|
||||
|
||||
|
||||
for(int i=0;i<len;i++) {
|
||||
|
||||
// exception blocks
|
||||
if(excSet.contains(new Integer(i))) {
|
||||
inststates[i] = 1;
|
||||
}
|
||||
|
||||
Instruction instr = seq.getInstr(i);
|
||||
switch(instr.group){
|
||||
case GROUP_JUMP:
|
||||
inststates[((JumpInstruction)instr).destination] = 1;
|
||||
case GROUP_RETURN:
|
||||
if(i+1 < len) {
|
||||
inststates[i+1] = 1;
|
||||
}
|
||||
break;
|
||||
case GROUP_SWITCH:
|
||||
SwitchInstruction swinstr = (SwitchInstruction)instr;
|
||||
int[] dests = swinstr.getDestinations();
|
||||
for(int j=dests.length-1;j>=0;j--) {
|
||||
inststates[dests[j]] = 1;
|
||||
}
|
||||
inststates[swinstr.getDefaultdest()] = 1;
|
||||
if(i+1 < len) {
|
||||
inststates[i+1] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// first instruction
|
||||
inststates[0] = 1;
|
||||
|
||||
return inststates;
|
||||
}
|
||||
|
||||
|
||||
private VBStyleCollection<BasicBlock, Integer> createBasicBlocks(short[] startblock, InstructionSequence instrseq,
|
||||
HashMap<Integer, BasicBlock> mapInstrBlocks) {
|
||||
|
||||
VBStyleCollection<BasicBlock, Integer> col = new VBStyleCollection<BasicBlock, Integer>();
|
||||
|
||||
InstructionSequence currseq = null;
|
||||
ArrayList<Integer> lstOffs = null;
|
||||
|
||||
int len = startblock.length;
|
||||
short counter = 0;
|
||||
int blockoffset = 0;
|
||||
|
||||
BasicBlock currentBlock = null;
|
||||
for(int i=0;i<len;i++) {
|
||||
|
||||
if (startblock[i] == 1) {
|
||||
currentBlock = new BasicBlock();
|
||||
currentBlock.id = ++counter;
|
||||
|
||||
currseq = new SimpleInstructionSequence();
|
||||
lstOffs = new ArrayList<Integer>();
|
||||
|
||||
currentBlock.setSeq(currseq);
|
||||
currentBlock.setInstrOldOffsets(lstOffs);
|
||||
col.addWithKey(currentBlock, currentBlock.id);
|
||||
|
||||
blockoffset = instrseq.getOffset(i);
|
||||
}
|
||||
|
||||
startblock[i] = counter;
|
||||
mapInstrBlocks.put(i, currentBlock);
|
||||
|
||||
currseq.addInstruction(instrseq.getInstr(i), instrseq.getOffset(i)-blockoffset);
|
||||
lstOffs.add(instrseq.getOffset(i));
|
||||
}
|
||||
|
||||
last_id = counter;
|
||||
|
||||
return col;
|
||||
}
|
||||
|
||||
|
||||
private void connectBlocks(List<BasicBlock> lstbb, HashMap<Integer, BasicBlock> mapInstrBlocks) {
|
||||
|
||||
for(int i=0;i<lstbb.size();i++) {
|
||||
|
||||
BasicBlock block = lstbb.get(i);
|
||||
Instruction instr = block.getLastInstruction();
|
||||
|
||||
boolean fallthrough = instr.canFallthrough();
|
||||
BasicBlock bTemp;
|
||||
|
||||
switch(instr.group) {
|
||||
case GROUP_JUMP:
|
||||
int dest = ((JumpInstruction)instr).destination;
|
||||
bTemp = mapInstrBlocks.get(dest);
|
||||
block.addSuccessor(bTemp);
|
||||
|
||||
break;
|
||||
case GROUP_SWITCH:
|
||||
SwitchInstruction sinstr = (SwitchInstruction)instr;
|
||||
int[] dests = sinstr.getDestinations();
|
||||
|
||||
bTemp = mapInstrBlocks.get(((SwitchInstruction)instr).getDefaultdest());
|
||||
block.addSuccessor(bTemp);
|
||||
for(int j=0;j<dests.length;j++) {
|
||||
bTemp = mapInstrBlocks.get(dests[j]);
|
||||
block.addSuccessor(bTemp);
|
||||
}
|
||||
}
|
||||
|
||||
if(fallthrough && i<lstbb.size()-1) {
|
||||
BasicBlock defaultBlock = lstbb.get(i+1);
|
||||
block.addSuccessor(defaultBlock);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void setExceptionEdges(InstructionSequence instrseq, HashMap<Integer, BasicBlock> instrBlocks) {
|
||||
|
||||
exceptions = new ArrayList<ExceptionRangeCFG>();
|
||||
|
||||
Map<String, ExceptionRangeCFG> mapRanges = new HashMap<String, ExceptionRangeCFG>();
|
||||
|
||||
for(ExceptionHandler handler : instrseq.getExceptionTable().getHandlers()) {
|
||||
|
||||
BasicBlock from = instrBlocks.get(handler.from_instr);
|
||||
BasicBlock to = instrBlocks.get(handler.to_instr);
|
||||
BasicBlock handle = instrBlocks.get(handler.handler_instr);
|
||||
|
||||
String key = from.id + ":" + to.id + ":" + handle.id;
|
||||
|
||||
if(mapRanges.containsKey(key)) {
|
||||
ExceptionRangeCFG range = mapRanges.get(key);
|
||||
range.addExceptionType(handler.exceptionClass);
|
||||
} else {
|
||||
|
||||
List<BasicBlock> protectedRange = new ArrayList<BasicBlock>();
|
||||
for(int j=from.id;j<to.id;j++) {
|
||||
BasicBlock block = blocks.getWithKey(j);
|
||||
protectedRange.add(block);
|
||||
block.addSuccessorException(handle);
|
||||
}
|
||||
|
||||
ExceptionRangeCFG range = new ExceptionRangeCFG(protectedRange, handle, handler.exceptionClass == null ? null : Arrays.asList(new String[]{handler.exceptionClass}));
|
||||
mapRanges.put(key, range);
|
||||
|
||||
exceptions.add(range);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setSubroutineEdges() {
|
||||
|
||||
final HashMap<BasicBlock, BasicBlock> subroutines = new HashMap<BasicBlock, BasicBlock>();
|
||||
|
||||
for(BasicBlock block : blocks) {
|
||||
|
||||
if(block.getSeq().getLastInstr().opcode == CodeConstants.opc_jsr) {
|
||||
|
||||
LinkedList<BasicBlock> stack = new LinkedList<BasicBlock>();
|
||||
LinkedList<LinkedList<BasicBlock>> stackJsrStacks = new LinkedList<LinkedList<BasicBlock>>();
|
||||
|
||||
HashSet<BasicBlock> setVisited = new HashSet<BasicBlock>();
|
||||
|
||||
stack.add(block);
|
||||
stackJsrStacks.add(new LinkedList<BasicBlock>());
|
||||
|
||||
while(!stack.isEmpty()) {
|
||||
|
||||
BasicBlock node = stack.removeFirst();
|
||||
LinkedList<BasicBlock> jsrstack = stackJsrStacks.removeFirst();
|
||||
|
||||
setVisited.add(node);
|
||||
|
||||
switch(node.getSeq().getLastInstr().opcode) {
|
||||
case CodeConstants.opc_jsr:
|
||||
jsrstack.add(node);
|
||||
break;
|
||||
case CodeConstants.opc_ret:
|
||||
BasicBlock enter = jsrstack.getLast();
|
||||
BasicBlock exit = blocks.getWithKey(enter.id + 1); // FIXME: find successor in a better way
|
||||
|
||||
if(exit!=null) {
|
||||
if(!node.isSuccessor(exit)) {
|
||||
node.addSuccessor(exit);
|
||||
}
|
||||
jsrstack.removeLast();
|
||||
subroutines.put(enter, exit);
|
||||
} else {
|
||||
throw new RuntimeException("ERROR: last instruction jsr");
|
||||
}
|
||||
}
|
||||
|
||||
if(!jsrstack.isEmpty()) {
|
||||
for(BasicBlock succ : node.getSuccs()) {
|
||||
if(!setVisited.contains(succ)) {
|
||||
stack.add(succ);
|
||||
stackJsrStacks.add(new LinkedList<BasicBlock>(jsrstack));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.subroutines = subroutines;
|
||||
}
|
||||
|
||||
private void processJsr() {
|
||||
|
||||
while(processJsrRanges()!=0);
|
||||
}
|
||||
|
||||
private int processJsrRanges() {
|
||||
|
||||
List<Object[]> lstJsrAll = new ArrayList<Object[]>();
|
||||
|
||||
// get all jsr ranges
|
||||
for(Entry<BasicBlock, BasicBlock> ent : subroutines.entrySet()){
|
||||
BasicBlock jsr = ent.getKey();
|
||||
BasicBlock ret = ent.getValue();
|
||||
|
||||
lstJsrAll.add(new Object[]{jsr, getJsrRange(jsr, ret), ret});
|
||||
}
|
||||
|
||||
// sort ranges
|
||||
// FIXME: better sort order
|
||||
List<Object[]> lstJsr = new ArrayList<Object[]>();
|
||||
for(Object[] arr : lstJsrAll) {
|
||||
int i=0;
|
||||
for(;i<lstJsr.size();i++) {
|
||||
Object[] arrJsr = lstJsr.get(i);
|
||||
|
||||
if(((HashSet<BasicBlock>)arrJsr[1]).contains(arr[0])) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
lstJsr.add(i, arr);
|
||||
}
|
||||
|
||||
// find the first intersection
|
||||
for(int i=0;i<lstJsr.size();i++) {
|
||||
Object[] arr = (Object[])lstJsr.get(i);
|
||||
HashSet<BasicBlock> set = (HashSet<BasicBlock>)arr[1];
|
||||
|
||||
for(int j=i+1;j<lstJsr.size();j++) {
|
||||
Object[] arr1 = (Object[])lstJsr.get(j);
|
||||
HashSet<BasicBlock> set1 = (HashSet<BasicBlock>)arr1[1];
|
||||
|
||||
if(!set.contains(arr1[0]) && !set1.contains(arr[0])) { // rang 0 doesn't contain entry 1 and vice versa
|
||||
HashSet<BasicBlock> setc = new HashSet<BasicBlock>(set);
|
||||
setc.retainAll(set1);
|
||||
|
||||
if(!setc.isEmpty()) {
|
||||
splitJsrRange((BasicBlock)arr[0], (BasicBlock)arr[2], setc);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private HashSet<BasicBlock> getJsrRange(BasicBlock jsr, BasicBlock ret) {
|
||||
|
||||
HashSet<BasicBlock> blocks = new HashSet<BasicBlock>();
|
||||
|
||||
LinkedList<BasicBlock> lstNodes = new LinkedList<BasicBlock>();
|
||||
lstNodes.add(jsr);
|
||||
|
||||
BasicBlock dom = jsr.getSuccs().get(0);
|
||||
|
||||
while(!lstNodes.isEmpty()) {
|
||||
|
||||
BasicBlock node = lstNodes.remove(0);
|
||||
|
||||
for(int j=0;j<2;j++) {
|
||||
List<BasicBlock> lst;
|
||||
if(j==0) {
|
||||
if(node.getLastInstruction().opcode == CodeConstants.opc_ret) {
|
||||
if(node.getSuccs().contains(ret)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
lst = node.getSuccs();
|
||||
} else {
|
||||
if(node == jsr) {
|
||||
continue;
|
||||
}
|
||||
lst = node.getSuccExceptions();
|
||||
}
|
||||
|
||||
CHILD:
|
||||
for(int i=lst.size()-1;i>=0;i--) {
|
||||
|
||||
BasicBlock child = lst.get(i);
|
||||
if(!blocks.contains(child)) {
|
||||
|
||||
if(node != jsr) {
|
||||
for(int k=0;k<child.getPreds().size();k++) {
|
||||
if(!DeadCodeHelper.isDominator(this, child.getPreds().get(k), dom)) {
|
||||
continue CHILD;
|
||||
}
|
||||
}
|
||||
|
||||
for(int k=0;k<child.getPredExceptions().size();k++) {
|
||||
if(!DeadCodeHelper.isDominator(this, child.getPredExceptions().get(k), dom)) {
|
||||
continue CHILD;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// last block is a dummy one
|
||||
if(child!=last) {
|
||||
blocks.add(child);
|
||||
}
|
||||
|
||||
lstNodes.add(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return blocks;
|
||||
}
|
||||
|
||||
private void splitJsrRange(BasicBlock jsr, BasicBlock ret, HashSet<BasicBlock> common_blocks) {
|
||||
|
||||
LinkedList<BasicBlock> lstNodes = new LinkedList<BasicBlock>();
|
||||
HashMap<Integer, BasicBlock> mapNewNodes = new HashMap<Integer, BasicBlock>();
|
||||
|
||||
lstNodes.add(jsr);
|
||||
mapNewNodes.put(jsr.id, jsr);
|
||||
|
||||
while(!lstNodes.isEmpty()) {
|
||||
|
||||
BasicBlock node = lstNodes.remove(0);
|
||||
|
||||
for(int j=0;j<2;j++) {
|
||||
List<BasicBlock> lst;
|
||||
if(j==0) {
|
||||
if(node.getLastInstruction().opcode == CodeConstants.opc_ret) {
|
||||
if(node.getSuccs().contains(ret)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
lst = node.getSuccs();
|
||||
} else {
|
||||
if(node == jsr) {
|
||||
continue;
|
||||
}
|
||||
lst = node.getSuccExceptions();
|
||||
}
|
||||
|
||||
|
||||
for(int i=lst.size()-1;i>=0;i--) {
|
||||
|
||||
BasicBlock child = (BasicBlock)lst.get(i);
|
||||
Integer childid = child.id;
|
||||
|
||||
if(mapNewNodes.containsKey(childid)) {
|
||||
node.replaceSuccessor(child, (BasicBlock)mapNewNodes.get(childid));
|
||||
} else if(common_blocks.contains(child)) {
|
||||
|
||||
// make a copy of the current block
|
||||
BasicBlock copy = (BasicBlock)child.clone();
|
||||
copy.id = ++last_id;
|
||||
// copy all successors
|
||||
if(copy.getLastInstruction().opcode == CodeConstants.opc_ret &&
|
||||
child.getSuccs().contains(ret)) {
|
||||
copy.addSuccessor(ret);
|
||||
child.removeSuccessor(ret);
|
||||
} else {
|
||||
for(int k=0;k<child.getSuccs().size();k++) {
|
||||
copy.addSuccessor((BasicBlock)child.getSuccs().get(k));
|
||||
}
|
||||
}
|
||||
for(int k=0;k<child.getSuccExceptions().size();k++) {
|
||||
copy.addSuccessorException((BasicBlock)child.getSuccExceptions().get(k));
|
||||
}
|
||||
|
||||
lstNodes.add(copy);
|
||||
mapNewNodes.put(childid, copy);
|
||||
|
||||
if(last.getPreds().contains(child)) {
|
||||
last.addPredecessor(copy);
|
||||
}
|
||||
|
||||
node.replaceSuccessor(child, copy);
|
||||
blocks.addWithKey(copy, copy.id);
|
||||
} else {
|
||||
// stop at the first fixed node
|
||||
//lstNodes.add(child);
|
||||
mapNewNodes.put(childid, child);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// note: subroutines won't be copied!
|
||||
splitJsrExceptionRanges(common_blocks, mapNewNodes);
|
||||
}
|
||||
|
||||
private void splitJsrExceptionRanges(HashSet<BasicBlock> common_blocks, HashMap<Integer, BasicBlock> mapNewNodes) {
|
||||
|
||||
for(int i=exceptions.size()-1;i>=0;i--) {
|
||||
|
||||
ExceptionRangeCFG range = (ExceptionRangeCFG)exceptions.get(i);
|
||||
List<BasicBlock> lstRange = range.getProtectedRange();
|
||||
|
||||
HashSet<BasicBlock> setBoth = new HashSet<BasicBlock>(common_blocks);
|
||||
setBoth.retainAll(lstRange);
|
||||
|
||||
if(setBoth.size()>0) {
|
||||
List<BasicBlock> lstNewRange;
|
||||
|
||||
if(setBoth.size()==lstRange.size()) {
|
||||
lstNewRange = new ArrayList<BasicBlock>();
|
||||
ExceptionRangeCFG newRange = new ExceptionRangeCFG(lstNewRange,
|
||||
(BasicBlock)mapNewNodes.get(range.getHandler().id),range.getExceptionTypes());
|
||||
exceptions.add(newRange);
|
||||
} else {
|
||||
lstNewRange = lstRange;
|
||||
}
|
||||
|
||||
for(BasicBlock block : setBoth) {
|
||||
lstNewRange.add(mapNewNodes.get(block.id));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void removeJsr(StructMethod mt) {
|
||||
removeJsrInstructions(mt.getClassStruct().getPool(), first, DataPoint.getInitialDataPoint(mt));
|
||||
}
|
||||
|
||||
private void removeJsrInstructions(ConstantPool pool, BasicBlock block, DataPoint data) {
|
||||
|
||||
ListStack<VarType> stack = data.getStack();
|
||||
|
||||
InstructionSequence seq = block.getSeq();
|
||||
for(int i=0;i<seq.length();i++) {
|
||||
Instruction instr = seq.getInstr(i);
|
||||
|
||||
VarType var = null;
|
||||
if(instr.opcode == CodeConstants.opc_astore || instr.opcode == CodeConstants.opc_pop) {
|
||||
var = stack.getByOffset(-1);
|
||||
}
|
||||
|
||||
InstructionImpact.stepTypes(data, instr, pool);
|
||||
|
||||
switch(instr.opcode) {
|
||||
case CodeConstants.opc_jsr:
|
||||
case CodeConstants.opc_ret:
|
||||
seq.removeInstruction(i);
|
||||
i--;
|
||||
break;
|
||||
case CodeConstants.opc_astore:
|
||||
case CodeConstants.opc_pop:
|
||||
if(var.type == CodeConstants.TYPE_ADDRESS) {
|
||||
seq.removeInstruction(i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
block.mark = 1;
|
||||
|
||||
for(int i=0;i<block.getSuccs().size();i++) {
|
||||
BasicBlock suc = (BasicBlock)block.getSuccs().get(i);
|
||||
if(suc.mark != 1) {
|
||||
removeJsrInstructions(pool, suc, data.copy());
|
||||
}
|
||||
}
|
||||
|
||||
for(int i=0;i<block.getSuccExceptions().size();i++) {
|
||||
BasicBlock suc = (BasicBlock)block.getSuccExceptions().get(i);
|
||||
if(suc.mark != 1) {
|
||||
|
||||
DataPoint point = new DataPoint();
|
||||
point.setLocalVariables(new ArrayList<VarType>(data.getLocalVariables()));
|
||||
point.getStack().push(new VarType(CodeConstants.TYPE_OBJECT, 0, null));
|
||||
|
||||
removeJsrInstructions(pool, suc, point);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void setFirstAndLastBlocks() {
|
||||
|
||||
first = blocks.get(0);
|
||||
|
||||
last = new BasicBlock();
|
||||
last.id = ++last_id;
|
||||
last.setSeq(new SimpleInstructionSequence());
|
||||
|
||||
for(BasicBlock block: blocks) {
|
||||
if(block.getSuccs().isEmpty()) {
|
||||
last.addPredecessor(block);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<BasicBlock> getReversePostOrder() {
|
||||
|
||||
LinkedList<BasicBlock> res = new LinkedList<BasicBlock>();
|
||||
addToReversePostOrderListIterative(first, res);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
private void addToReversePostOrderListIterative(BasicBlock root, List<BasicBlock> lst) {
|
||||
|
||||
LinkedList<BasicBlock> stackNode = new LinkedList<BasicBlock>();
|
||||
LinkedList<Integer> stackIndex = new LinkedList<Integer>();
|
||||
|
||||
HashSet<BasicBlock> setVisited = new HashSet<BasicBlock>();
|
||||
|
||||
stackNode.add(root);
|
||||
stackIndex.add(0);
|
||||
|
||||
while(!stackNode.isEmpty()) {
|
||||
|
||||
BasicBlock node = stackNode.getLast();
|
||||
int index = stackIndex.removeLast();
|
||||
|
||||
setVisited.add(node);
|
||||
|
||||
List<BasicBlock> lstSuccs = new ArrayList<BasicBlock>(node.getSuccs());
|
||||
lstSuccs.addAll(node.getSuccExceptions());
|
||||
|
||||
for(;index<lstSuccs.size();index++) {
|
||||
BasicBlock succ = lstSuccs.get(index);
|
||||
|
||||
if(!setVisited.contains(succ)) {
|
||||
stackIndex.add(index+1);
|
||||
|
||||
stackNode.add(succ);
|
||||
stackIndex.add(0);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(index == lstSuccs.size()) {
|
||||
lst.add(0, node);
|
||||
|
||||
stackNode.removeLast();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// *****************************************************************************
|
||||
// getter and setter methods
|
||||
// *****************************************************************************
|
||||
|
||||
public VBStyleCollection<BasicBlock, Integer> getBlocks() {
|
||||
return blocks;
|
||||
}
|
||||
|
||||
public void setBlocks(VBStyleCollection<BasicBlock, Integer> blocks) {
|
||||
this.blocks = blocks;
|
||||
}
|
||||
|
||||
public BasicBlock getFirst() {
|
||||
return first;
|
||||
}
|
||||
|
||||
public void setFirst(BasicBlock first) {
|
||||
this.first = first;
|
||||
}
|
||||
|
||||
public List<BasicBlock> getEndBlocks() {
|
||||
return last.getPreds();
|
||||
}
|
||||
|
||||
public List<ExceptionRangeCFG> getExceptions() {
|
||||
return exceptions;
|
||||
}
|
||||
|
||||
public void setExceptions(List<ExceptionRangeCFG> exceptions) {
|
||||
this.exceptions = exceptions;
|
||||
}
|
||||
|
||||
|
||||
public BasicBlock getLast() {
|
||||
return last;
|
||||
}
|
||||
|
||||
|
||||
public void setLast(BasicBlock last) {
|
||||
this.last = last;
|
||||
}
|
||||
|
||||
|
||||
public HashMap<BasicBlock, BasicBlock> getSubroutines() {
|
||||
return subroutines;
|
||||
}
|
||||
|
||||
|
||||
public void setSubroutines(HashMap<BasicBlock, BasicBlock> subroutines) {
|
||||
this.subroutines = subroutines;
|
||||
}
|
||||
|
||||
|
||||
public HashSet<BasicBlock> getFinallyExits() {
|
||||
return finallyExits;
|
||||
}
|
||||
|
||||
|
||||
public void setFinallyExits(HashSet<BasicBlock> finallyExits) {
|
||||
this.finallyExits = finallyExits;
|
||||
}
|
||||
|
||||
}
|
128
src/de/fernflower/code/cfg/ExceptionRangeCFG.java
Normal file
128
src/de/fernflower/code/cfg/ExceptionRangeCFG.java
Normal file
@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Fernflower - The Analytical Java Decompiler
|
||||
* http://www.reversed-java.com
|
||||
*
|
||||
* (C) 2008 - 2010, Stiver
|
||||
*
|
||||
* This software is NEITHER public domain NOR free software
|
||||
* as per GNU License. See license.txt for more details.
|
||||
*
|
||||
* This software is distributed WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
package de.fernflower.code.cfg;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import de.fernflower.main.DecompilerContext;
|
||||
|
||||
public class ExceptionRangeCFG {
|
||||
|
||||
private List<BasicBlock> protectedRange = new ArrayList<BasicBlock>(); // FIXME: replace with set
|
||||
|
||||
private BasicBlock handler;
|
||||
|
||||
private List<String> exceptionTypes;
|
||||
|
||||
public ExceptionRangeCFG(List<BasicBlock> protectedRange, BasicBlock handler, List<String> exceptionType) {
|
||||
this.protectedRange = protectedRange;
|
||||
this.handler = handler;
|
||||
|
||||
if(exceptionType != null) {
|
||||
this.exceptionTypes = new ArrayList<String>(exceptionType);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isCircular() {
|
||||
return protectedRange.contains(handler);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
|
||||
String new_line_separator = DecompilerContext.getNewLineSeparator();
|
||||
|
||||
StringBuffer buf = new StringBuffer();
|
||||
|
||||
buf.append("exceptionType:");
|
||||
for(String exception_type : exceptionTypes) {
|
||||
buf.append(" "+exception_type);
|
||||
}
|
||||
buf.append(new_line_separator);
|
||||
|
||||
buf.append("handler: "+handler.id+new_line_separator);
|
||||
buf.append("range: ");
|
||||
for(int i=0;i<protectedRange.size();i++) {
|
||||
buf.append(protectedRange.get(i).id+" ");
|
||||
}
|
||||
buf.append(new_line_separator);
|
||||
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
public BasicBlock getHandler() {
|
||||
return handler;
|
||||
}
|
||||
|
||||
public void setHandler(BasicBlock handler) {
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
public List<BasicBlock> getProtectedRange() {
|
||||
return protectedRange;
|
||||
}
|
||||
|
||||
public void setProtectedRange(List<BasicBlock> protectedRange) {
|
||||
this.protectedRange = protectedRange;
|
||||
}
|
||||
|
||||
public List<String> getExceptionTypes() {
|
||||
return this.exceptionTypes;
|
||||
}
|
||||
|
||||
public void addExceptionType(String exceptionType) {
|
||||
|
||||
if(this.exceptionTypes == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(exceptionType == null) {
|
||||
this.exceptionTypes = null;
|
||||
} else {
|
||||
this.exceptionTypes.add(exceptionType);
|
||||
}
|
||||
}
|
||||
|
||||
public String getUniqueExceptionsString() {
|
||||
|
||||
if(exceptionTypes == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Set<String> setExceptionStrings = new HashSet<String>();
|
||||
|
||||
for(String exceptionType : exceptionTypes) { // normalize order
|
||||
setExceptionStrings.add(exceptionType);
|
||||
}
|
||||
|
||||
String ret = "";
|
||||
for(String exception : setExceptionStrings) {
|
||||
if(!ret.isEmpty()) {
|
||||
ret += ":";
|
||||
}
|
||||
ret += exception;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
// public void setExceptionType(String exceptionType) {
|
||||
// this.exceptionType = exceptionType;
|
||||
// }
|
||||
|
||||
}
|
7
src/de/fernflower/code/instructions/AALOAD.java
Normal file
7
src/de/fernflower/code/instructions/AALOAD.java
Normal file
@ -0,0 +1,7 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class AALOAD extends Instruction {
|
||||
|
||||
}
|
7
src/de/fernflower/code/instructions/AASTORE.java
Normal file
7
src/de/fernflower/code/instructions/AASTORE.java
Normal file
@ -0,0 +1,7 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class AASTORE extends Instruction {
|
||||
|
||||
}
|
7
src/de/fernflower/code/instructions/ACONST_NULL.java
Normal file
7
src/de/fernflower/code/instructions/ACONST_NULL.java
Normal file
@ -0,0 +1,7 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class ACONST_NULL extends Instruction {
|
||||
|
||||
}
|
43
src/de/fernflower/code/instructions/ALOAD.java
Normal file
43
src/de/fernflower/code/instructions/ALOAD.java
Normal file
@ -0,0 +1,43 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class ALOAD extends Instruction {
|
||||
|
||||
private static int[] opcodes = new int[] {opc_aload_0,opc_aload_1,opc_aload_2,opc_aload_3};
|
||||
|
||||
public void writeToStream(DataOutputStream out, int offset) throws IOException {
|
||||
int index = getOperand(0);
|
||||
if(index>3) {
|
||||
if(wide) {
|
||||
out.writeByte(opc_wide);
|
||||
}
|
||||
out.writeByte(opc_aload);
|
||||
if(wide) {
|
||||
out.writeShort(index);
|
||||
} else {
|
||||
out.writeByte(index);
|
||||
}
|
||||
} else {
|
||||
out.writeByte(opcodes[index]);
|
||||
}
|
||||
}
|
||||
|
||||
public int length() {
|
||||
int index = getOperand(0);
|
||||
if(index>3) {
|
||||
if(wide) {
|
||||
return 4;
|
||||
} else {
|
||||
return 2;
|
||||
}
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
19
src/de/fernflower/code/instructions/ANEWARRAY.java
Normal file
19
src/de/fernflower/code/instructions/ANEWARRAY.java
Normal file
@ -0,0 +1,19 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class ANEWARRAY extends Instruction {
|
||||
|
||||
public void writeToStream(DataOutputStream out, int offset) throws IOException {
|
||||
out.writeByte(opc_anewarray);
|
||||
out.writeShort(getOperand(0));
|
||||
}
|
||||
|
||||
public int length() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
}
|
7
src/de/fernflower/code/instructions/ARETURN.java
Normal file
7
src/de/fernflower/code/instructions/ARETURN.java
Normal file
@ -0,0 +1,7 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class ARETURN extends Instruction {
|
||||
|
||||
}
|
7
src/de/fernflower/code/instructions/ARRAYLENGTH.java
Normal file
7
src/de/fernflower/code/instructions/ARRAYLENGTH.java
Normal file
@ -0,0 +1,7 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class ARRAYLENGTH extends Instruction {
|
||||
|
||||
}
|
42
src/de/fernflower/code/instructions/ASTORE.java
Normal file
42
src/de/fernflower/code/instructions/ASTORE.java
Normal file
@ -0,0 +1,42 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class ASTORE extends Instruction {
|
||||
|
||||
private static int[] opcodes = new int[] {opc_astore_0,opc_astore_1,opc_astore_2,opc_astore_3};
|
||||
|
||||
public void writeToStream(DataOutputStream out, int offset) throws IOException {
|
||||
int index = getOperand(0);
|
||||
if(index>3) {
|
||||
if(wide) {
|
||||
out.writeByte(opc_wide);
|
||||
}
|
||||
out.writeByte(opc_astore);
|
||||
if(wide) {
|
||||
out.writeShort(index);
|
||||
} else {
|
||||
out.writeByte(index);
|
||||
}
|
||||
} else {
|
||||
out.writeByte(opcodes[index]);
|
||||
}
|
||||
}
|
||||
|
||||
public int length() {
|
||||
int index = getOperand(0);
|
||||
if(index>3) {
|
||||
if(wide) {
|
||||
return 4;
|
||||
} else {
|
||||
return 2;
|
||||
}
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
7
src/de/fernflower/code/instructions/ATHROW.java
Normal file
7
src/de/fernflower/code/instructions/ATHROW.java
Normal file
@ -0,0 +1,7 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class ATHROW extends Instruction {
|
||||
|
||||
}
|
7
src/de/fernflower/code/instructions/BALOAD.java
Normal file
7
src/de/fernflower/code/instructions/BALOAD.java
Normal file
@ -0,0 +1,7 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class BALOAD extends Instruction {
|
||||
|
||||
}
|
7
src/de/fernflower/code/instructions/BASTORE.java
Normal file
7
src/de/fernflower/code/instructions/BASTORE.java
Normal file
@ -0,0 +1,7 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class BASTORE extends Instruction {
|
||||
|
||||
}
|
30
src/de/fernflower/code/instructions/BIPUSH.java
Normal file
30
src/de/fernflower/code/instructions/BIPUSH.java
Normal file
@ -0,0 +1,30 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class BIPUSH extends Instruction {
|
||||
|
||||
private static int[] opcodes = new int[] {opc_iconst_m1,opc_iconst_0,opc_iconst_1,opc_iconst_2,opc_iconst_3,opc_iconst_4,opc_iconst_5};
|
||||
|
||||
public void writeToStream(DataOutputStream out, int offset) throws IOException {
|
||||
int value = getOperand(0);
|
||||
if(value<-1 || value > 5) {
|
||||
out.writeByte(opc_bipush);
|
||||
out.writeByte(value);
|
||||
} else {
|
||||
out.writeByte(opcodes[value+1]);
|
||||
}
|
||||
}
|
||||
|
||||
public int length() {
|
||||
int value = getOperand(0);
|
||||
if(value<-1 || value > 5) {
|
||||
return 2;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
7
src/de/fernflower/code/instructions/CALOAD.java
Normal file
7
src/de/fernflower/code/instructions/CALOAD.java
Normal file
@ -0,0 +1,7 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class CALOAD extends Instruction {
|
||||
|
||||
}
|
7
src/de/fernflower/code/instructions/CASTORE.java
Normal file
7
src/de/fernflower/code/instructions/CASTORE.java
Normal file
@ -0,0 +1,7 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class CASTORE extends Instruction {
|
||||
|
||||
}
|
20
src/de/fernflower/code/instructions/CHECKCAST.java
Normal file
20
src/de/fernflower/code/instructions/CHECKCAST.java
Normal file
@ -0,0 +1,20 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class CHECKCAST extends Instruction {
|
||||
|
||||
public void writeToStream(DataOutputStream out, int offset) throws IOException {
|
||||
out.writeByte(opc_checkcast);
|
||||
out.writeShort(getOperand(0));
|
||||
}
|
||||
|
||||
public int length() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
}
|
||||
|
7
src/de/fernflower/code/instructions/D2F.java
Normal file
7
src/de/fernflower/code/instructions/D2F.java
Normal file
@ -0,0 +1,7 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class D2F extends Instruction {
|
||||
|
||||
}
|
7
src/de/fernflower/code/instructions/D2I.java
Normal file
7
src/de/fernflower/code/instructions/D2I.java
Normal file
@ -0,0 +1,7 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class D2I extends Instruction {
|
||||
|
||||
}
|
7
src/de/fernflower/code/instructions/D2L.java
Normal file
7
src/de/fernflower/code/instructions/D2L.java
Normal file
@ -0,0 +1,7 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class D2L extends Instruction {
|
||||
|
||||
}
|
7
src/de/fernflower/code/instructions/DADD.java
Normal file
7
src/de/fernflower/code/instructions/DADD.java
Normal file
@ -0,0 +1,7 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class DADD extends Instruction {
|
||||
|
||||
}
|
7
src/de/fernflower/code/instructions/DALOAD.java
Normal file
7
src/de/fernflower/code/instructions/DALOAD.java
Normal file
@ -0,0 +1,7 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class DALOAD extends Instruction {
|
||||
|
||||
}
|
7
src/de/fernflower/code/instructions/DASTORE.java
Normal file
7
src/de/fernflower/code/instructions/DASTORE.java
Normal file
@ -0,0 +1,7 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class DASTORE extends Instruction {
|
||||
|
||||
}
|
7
src/de/fernflower/code/instructions/DCMPG.java
Normal file
7
src/de/fernflower/code/instructions/DCMPG.java
Normal file
@ -0,0 +1,7 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class DCMPG extends Instruction {
|
||||
|
||||
}
|
7
src/de/fernflower/code/instructions/DCMPL.java
Normal file
7
src/de/fernflower/code/instructions/DCMPL.java
Normal file
@ -0,0 +1,7 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class DCMPL extends Instruction {
|
||||
|
||||
}
|
7
src/de/fernflower/code/instructions/DCONST_0.java
Normal file
7
src/de/fernflower/code/instructions/DCONST_0.java
Normal file
@ -0,0 +1,7 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class DCONST_0 extends Instruction {
|
||||
|
||||
}
|
7
src/de/fernflower/code/instructions/DCONST_1.java
Normal file
7
src/de/fernflower/code/instructions/DCONST_1.java
Normal file
@ -0,0 +1,7 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class DCONST_1 extends Instruction {
|
||||
|
||||
}
|
7
src/de/fernflower/code/instructions/DDIV.java
Normal file
7
src/de/fernflower/code/instructions/DDIV.java
Normal file
@ -0,0 +1,7 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class DDIV extends Instruction {
|
||||
|
||||
}
|
42
src/de/fernflower/code/instructions/DLOAD.java
Normal file
42
src/de/fernflower/code/instructions/DLOAD.java
Normal file
@ -0,0 +1,42 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class DLOAD extends Instruction {
|
||||
|
||||
private static int[] opcodes = new int[] {opc_dload_0,opc_dload_1,opc_dload_2,opc_dload_3};
|
||||
|
||||
public void writeToStream(DataOutputStream out, int offset) throws IOException {
|
||||
int index = getOperand(0);
|
||||
if(index>3) {
|
||||
if(wide) {
|
||||
out.writeByte(opc_wide);
|
||||
}
|
||||
out.writeByte(opc_dload);
|
||||
if(wide) {
|
||||
out.writeShort(index);
|
||||
} else {
|
||||
out.writeByte(index);
|
||||
}
|
||||
} else {
|
||||
out.writeByte(opcodes[index]);
|
||||
}
|
||||
}
|
||||
|
||||
public int length() {
|
||||
int index = getOperand(0);
|
||||
if(index>3) {
|
||||
if(wide) {
|
||||
return 4;
|
||||
} else {
|
||||
return 2;
|
||||
}
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
7
src/de/fernflower/code/instructions/DMUL.java
Normal file
7
src/de/fernflower/code/instructions/DMUL.java
Normal file
@ -0,0 +1,7 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class DMUL extends Instruction {
|
||||
|
||||
}
|
7
src/de/fernflower/code/instructions/DNEG.java
Normal file
7
src/de/fernflower/code/instructions/DNEG.java
Normal file
@ -0,0 +1,7 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class DNEG extends Instruction {
|
||||
|
||||
}
|
7
src/de/fernflower/code/instructions/DREM.java
Normal file
7
src/de/fernflower/code/instructions/DREM.java
Normal file
@ -0,0 +1,7 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class DREM extends Instruction {
|
||||
|
||||
}
|
7
src/de/fernflower/code/instructions/DRETURN.java
Normal file
7
src/de/fernflower/code/instructions/DRETURN.java
Normal file
@ -0,0 +1,7 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class DRETURN extends Instruction {
|
||||
|
||||
}
|
41
src/de/fernflower/code/instructions/DSTORE.java
Normal file
41
src/de/fernflower/code/instructions/DSTORE.java
Normal file
@ -0,0 +1,41 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class DSTORE extends Instruction {
|
||||
|
||||
private static int[] opcodes = new int[] {opc_dstore_0,opc_dstore_1,opc_dstore_2,opc_dstore_3};
|
||||
|
||||
public void writeToStream(DataOutputStream out, int offset) throws IOException {
|
||||
int index = getOperand(0);
|
||||
if(index>3) {
|
||||
if(wide) {
|
||||
out.writeByte(opc_wide);
|
||||
}
|
||||
out.writeByte(opc_dstore);
|
||||
if(wide) {
|
||||
out.writeShort(index);
|
||||
} else {
|
||||
out.writeByte(index);
|
||||
}
|
||||
} else {
|
||||
out.writeByte(opcodes[index]);
|
||||
}
|
||||
}
|
||||
|
||||
public int length() {
|
||||
int index = getOperand(0);
|
||||
if(index>3) {
|
||||
if(wide) {
|
||||
return 4;
|
||||
} else {
|
||||
return 2;
|
||||
}
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
7
src/de/fernflower/code/instructions/DSUB.java
Normal file
7
src/de/fernflower/code/instructions/DSUB.java
Normal file
@ -0,0 +1,7 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class DSUB extends Instruction {
|
||||
|
||||
}
|
7
src/de/fernflower/code/instructions/DUP.java
Normal file
7
src/de/fernflower/code/instructions/DUP.java
Normal file
@ -0,0 +1,7 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class DUP extends Instruction {
|
||||
|
||||
}
|
7
src/de/fernflower/code/instructions/DUP2.java
Normal file
7
src/de/fernflower/code/instructions/DUP2.java
Normal file
@ -0,0 +1,7 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class DUP2 extends Instruction {
|
||||
|
||||
}
|
7
src/de/fernflower/code/instructions/DUP2_X1.java
Normal file
7
src/de/fernflower/code/instructions/DUP2_X1.java
Normal file
@ -0,0 +1,7 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class DUP2_X1 extends Instruction {
|
||||
|
||||
}
|
7
src/de/fernflower/code/instructions/DUP2_X2.java
Normal file
7
src/de/fernflower/code/instructions/DUP2_X2.java
Normal file
@ -0,0 +1,7 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class DUP2_X2 extends Instruction {
|
||||
|
||||
}
|
7
src/de/fernflower/code/instructions/DUP_X1.java
Normal file
7
src/de/fernflower/code/instructions/DUP_X1.java
Normal file
@ -0,0 +1,7 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class DUP_X1 extends Instruction {
|
||||
|
||||
}
|
7
src/de/fernflower/code/instructions/DUP_X2.java
Normal file
7
src/de/fernflower/code/instructions/DUP_X2.java
Normal file
@ -0,0 +1,7 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class DUP_X2 extends Instruction {
|
||||
|
||||
}
|
7
src/de/fernflower/code/instructions/F2D.java
Normal file
7
src/de/fernflower/code/instructions/F2D.java
Normal file
@ -0,0 +1,7 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class F2D extends Instruction {
|
||||
|
||||
}
|
7
src/de/fernflower/code/instructions/F2I.java
Normal file
7
src/de/fernflower/code/instructions/F2I.java
Normal file
@ -0,0 +1,7 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class F2I extends Instruction {
|
||||
|
||||
}
|
7
src/de/fernflower/code/instructions/F2L.java
Normal file
7
src/de/fernflower/code/instructions/F2L.java
Normal file
@ -0,0 +1,7 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class F2L extends Instruction {
|
||||
|
||||
}
|
7
src/de/fernflower/code/instructions/FADD.java
Normal file
7
src/de/fernflower/code/instructions/FADD.java
Normal file
@ -0,0 +1,7 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class FADD extends Instruction {
|
||||
|
||||
}
|
7
src/de/fernflower/code/instructions/FALOAD.java
Normal file
7
src/de/fernflower/code/instructions/FALOAD.java
Normal file
@ -0,0 +1,7 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class FALOAD extends Instruction {
|
||||
|
||||
}
|
7
src/de/fernflower/code/instructions/FASTORE.java
Normal file
7
src/de/fernflower/code/instructions/FASTORE.java
Normal file
@ -0,0 +1,7 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class FASTORE extends Instruction {
|
||||
|
||||
}
|
7
src/de/fernflower/code/instructions/FCMPG.java
Normal file
7
src/de/fernflower/code/instructions/FCMPG.java
Normal file
@ -0,0 +1,7 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class FCMPG extends Instruction {
|
||||
|
||||
}
|
7
src/de/fernflower/code/instructions/FCMPL.java
Normal file
7
src/de/fernflower/code/instructions/FCMPL.java
Normal file
@ -0,0 +1,7 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class FCMPL extends Instruction {
|
||||
|
||||
}
|
7
src/de/fernflower/code/instructions/FCONST_0.java
Normal file
7
src/de/fernflower/code/instructions/FCONST_0.java
Normal file
@ -0,0 +1,7 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class FCONST_0 extends Instruction {
|
||||
|
||||
}
|
7
src/de/fernflower/code/instructions/FCONST_1.java
Normal file
7
src/de/fernflower/code/instructions/FCONST_1.java
Normal file
@ -0,0 +1,7 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class FCONST_1 extends Instruction {
|
||||
|
||||
}
|
7
src/de/fernflower/code/instructions/FCONST_2.java
Normal file
7
src/de/fernflower/code/instructions/FCONST_2.java
Normal file
@ -0,0 +1,7 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class FCONST_2 extends Instruction {
|
||||
|
||||
}
|
7
src/de/fernflower/code/instructions/FDIV.java
Normal file
7
src/de/fernflower/code/instructions/FDIV.java
Normal file
@ -0,0 +1,7 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class FDIV extends Instruction {
|
||||
|
||||
}
|
42
src/de/fernflower/code/instructions/FLOAD.java
Normal file
42
src/de/fernflower/code/instructions/FLOAD.java
Normal file
@ -0,0 +1,42 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class FLOAD extends Instruction {
|
||||
|
||||
private static int[] opcodes = new int[] {opc_fload_0,opc_fload_1,opc_fload_2,opc_fload_3};
|
||||
|
||||
public void writeToStream(DataOutputStream out, int offset) throws IOException {
|
||||
int index = getOperand(0);
|
||||
if(index>3) {
|
||||
if(wide) {
|
||||
out.writeByte(opc_wide);
|
||||
}
|
||||
out.writeByte(opc_fload);
|
||||
if(wide) {
|
||||
out.writeShort(index);
|
||||
} else {
|
||||
out.writeByte(index);
|
||||
}
|
||||
} else {
|
||||
out.writeByte(opcodes[index]);
|
||||
}
|
||||
}
|
||||
|
||||
public int length() {
|
||||
int index = getOperand(0);
|
||||
if(index>3) {
|
||||
if(wide) {
|
||||
return 4;
|
||||
} else {
|
||||
return 2;
|
||||
}
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
7
src/de/fernflower/code/instructions/FMUL.java
Normal file
7
src/de/fernflower/code/instructions/FMUL.java
Normal file
@ -0,0 +1,7 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class FMUL extends Instruction {
|
||||
|
||||
}
|
7
src/de/fernflower/code/instructions/FNEG.java
Normal file
7
src/de/fernflower/code/instructions/FNEG.java
Normal file
@ -0,0 +1,7 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class FNEG extends Instruction {
|
||||
|
||||
}
|
7
src/de/fernflower/code/instructions/FREM.java
Normal file
7
src/de/fernflower/code/instructions/FREM.java
Normal file
@ -0,0 +1,7 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class FREM extends Instruction {
|
||||
|
||||
}
|
7
src/de/fernflower/code/instructions/FRETURN.java
Normal file
7
src/de/fernflower/code/instructions/FRETURN.java
Normal file
@ -0,0 +1,7 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class FRETURN extends Instruction {
|
||||
|
||||
}
|
41
src/de/fernflower/code/instructions/FSTORE.java
Normal file
41
src/de/fernflower/code/instructions/FSTORE.java
Normal file
@ -0,0 +1,41 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class FSTORE extends Instruction {
|
||||
|
||||
private static int[] opcodes = new int[] {opc_fstore_0,opc_fstore_1,opc_fstore_2,opc_fstore_3};
|
||||
|
||||
public void writeToStream(DataOutputStream out, int offset) throws IOException {
|
||||
int index = getOperand(0);
|
||||
if(index>3) {
|
||||
if(wide) {
|
||||
out.writeByte(opc_wide);
|
||||
}
|
||||
out.writeByte(opc_fstore);
|
||||
if(wide) {
|
||||
out.writeShort(index);
|
||||
} else {
|
||||
out.writeByte(index);
|
||||
}
|
||||
} else {
|
||||
out.writeByte(opcodes[index]);
|
||||
}
|
||||
}
|
||||
|
||||
public int length() {
|
||||
int index = getOperand(0);
|
||||
if(index>3) {
|
||||
if(wide) {
|
||||
return 4;
|
||||
} else {
|
||||
return 2;
|
||||
}
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
7
src/de/fernflower/code/instructions/FSUB.java
Normal file
7
src/de/fernflower/code/instructions/FSUB.java
Normal file
@ -0,0 +1,7 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class FSUB extends Instruction {
|
||||
|
||||
}
|
18
src/de/fernflower/code/instructions/GETFIELD.java
Normal file
18
src/de/fernflower/code/instructions/GETFIELD.java
Normal file
@ -0,0 +1,18 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class GETFIELD extends Instruction {
|
||||
|
||||
public void writeToStream(DataOutputStream out, int offset) throws IOException {
|
||||
out.writeByte(opc_getfield);
|
||||
out.writeShort(getOperand(0));
|
||||
}
|
||||
|
||||
public int length() {
|
||||
return 3;
|
||||
}
|
||||
}
|
19
src/de/fernflower/code/instructions/GETSTATIC.java
Normal file
19
src/de/fernflower/code/instructions/GETSTATIC.java
Normal file
@ -0,0 +1,19 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class GETSTATIC extends Instruction {
|
||||
|
||||
public void writeToStream(DataOutputStream out, int offset) throws IOException {
|
||||
out.writeByte(opc_getstatic);
|
||||
out.writeShort(getOperand(0));
|
||||
}
|
||||
|
||||
public int length() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
}
|
30
src/de/fernflower/code/instructions/GOTO.java
Normal file
30
src/de/fernflower/code/instructions/GOTO.java
Normal file
@ -0,0 +1,30 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import de.fernflower.code.JumpInstruction;
|
||||
|
||||
public class GOTO extends JumpInstruction {
|
||||
|
||||
public void writeToStream(DataOutputStream out, int offset) throws IOException {
|
||||
int operand = getOperand(0);
|
||||
if(operand < -32768 || operand > 32767) {
|
||||
out.writeByte(opc_goto_w);
|
||||
out.writeInt(operand);
|
||||
} else {
|
||||
out.writeByte(opc_goto);
|
||||
out.writeShort(operand);
|
||||
}
|
||||
}
|
||||
|
||||
public int length() {
|
||||
int operand = getOperand(0);
|
||||
if(operand < -32768 || operand > 32767) {
|
||||
return 5;
|
||||
} else {
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
19
src/de/fernflower/code/instructions/GOTO_W.java
Normal file
19
src/de/fernflower/code/instructions/GOTO_W.java
Normal file
@ -0,0 +1,19 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import de.fernflower.code.JumpInstruction;
|
||||
|
||||
public class GOTO_W extends JumpInstruction {
|
||||
|
||||
public void writeToStream(DataOutputStream out, int offset) throws IOException {
|
||||
out.writeByte(opc_goto_w);
|
||||
out.writeInt(getOperand(0));
|
||||
}
|
||||
|
||||
public int length() {
|
||||
return 5;
|
||||
}
|
||||
|
||||
}
|
7
src/de/fernflower/code/instructions/I2B.java
Normal file
7
src/de/fernflower/code/instructions/I2B.java
Normal file
@ -0,0 +1,7 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class I2B extends Instruction {
|
||||
|
||||
}
|
7
src/de/fernflower/code/instructions/I2C.java
Normal file
7
src/de/fernflower/code/instructions/I2C.java
Normal file
@ -0,0 +1,7 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class I2C extends Instruction {
|
||||
|
||||
}
|
7
src/de/fernflower/code/instructions/I2D.java
Normal file
7
src/de/fernflower/code/instructions/I2D.java
Normal file
@ -0,0 +1,7 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class I2D extends Instruction {
|
||||
|
||||
}
|
7
src/de/fernflower/code/instructions/I2F.java
Normal file
7
src/de/fernflower/code/instructions/I2F.java
Normal file
@ -0,0 +1,7 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class I2F extends Instruction {
|
||||
|
||||
}
|
7
src/de/fernflower/code/instructions/I2L.java
Normal file
7
src/de/fernflower/code/instructions/I2L.java
Normal file
@ -0,0 +1,7 @@
|
||||
package de.fernflower.code.instructions;
|
||||
|
||||
import de.fernflower.code.Instruction;
|
||||
|
||||
public class I2L extends Instruction {
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user