initial commit

master
Stiver 11 years ago
commit e2d0f5d9c3
  1. 8
      .classpath
  2. 17
      .project
  3. 3
      .settings/org.eclipse.core.resources.prefs
  4. 11
      .settings/org.eclipse.jdt.core.prefs
  5. 6
      bin/.gitignore
  6. 131
      build.xml
  7. 51
      dist/docs/license_en.txt
  8. 62
      dist/docs/lizenz_de.txt
  9. 86
      dist/docs/readme.txt
  10. BIN
      dist/full/fernflower.jar
  11. BIN
      dist/obfuscated/fernflower.jar
  12. BIN
      lib/ncss/ccl.jar
  13. BIN
      lib/ncss/javacc.jar
  14. BIN
      lib/ncss/javancss.jar
  15. BIN
      lib/proguard.jar
  16. BIN
      lib/proguard_4_11.jar
  17. BIN
      lib/timer/hrtlib.dll
  18. BIN
      lib/timer/timer.jar
  19. 347
      src/de/fernflower/code/CodeConstants.java
  20. 510
      src/de/fernflower/code/ConstantsUtil.java
  21. 442
      src/de/fernflower/code/ConstantsUtilOld.java
  22. 62
      src/de/fernflower/code/ExceptionHandler.java
  23. 57
      src/de/fernflower/code/ExceptionTable.java
  24. 38
      src/de/fernflower/code/FullInstructionSequence.java
  25. 36
      src/de/fernflower/code/IfInstruction.java
  26. 123
      src/de/fernflower/code/Instruction.java
  27. 219
      src/de/fernflower/code/InstructionSequence.java
  28. 41
      src/de/fernflower/code/JumpInstruction.java
  29. 39
      src/de/fernflower/code/SimpleInstructionSequence.java
  30. 93
      src/de/fernflower/code/SwitchInstruction.java
  31. 265
      src/de/fernflower/code/cfg/BasicBlock.java
  32. 887
      src/de/fernflower/code/cfg/ControlFlowGraph.java
  33. 128
      src/de/fernflower/code/cfg/ExceptionRangeCFG.java
  34. 7
      src/de/fernflower/code/instructions/AALOAD.java
  35. 7
      src/de/fernflower/code/instructions/AASTORE.java
  36. 7
      src/de/fernflower/code/instructions/ACONST_NULL.java
  37. 43
      src/de/fernflower/code/instructions/ALOAD.java
  38. 19
      src/de/fernflower/code/instructions/ANEWARRAY.java
  39. 7
      src/de/fernflower/code/instructions/ARETURN.java
  40. 7
      src/de/fernflower/code/instructions/ARRAYLENGTH.java
  41. 42
      src/de/fernflower/code/instructions/ASTORE.java
  42. 7
      src/de/fernflower/code/instructions/ATHROW.java
  43. 7
      src/de/fernflower/code/instructions/BALOAD.java
  44. 7
      src/de/fernflower/code/instructions/BASTORE.java
  45. 30
      src/de/fernflower/code/instructions/BIPUSH.java
  46. 7
      src/de/fernflower/code/instructions/CALOAD.java
  47. 7
      src/de/fernflower/code/instructions/CASTORE.java
  48. 20
      src/de/fernflower/code/instructions/CHECKCAST.java
  49. 7
      src/de/fernflower/code/instructions/D2F.java
  50. 7
      src/de/fernflower/code/instructions/D2I.java
  51. 7
      src/de/fernflower/code/instructions/D2L.java
  52. 7
      src/de/fernflower/code/instructions/DADD.java
  53. 7
      src/de/fernflower/code/instructions/DALOAD.java
  54. 7
      src/de/fernflower/code/instructions/DASTORE.java
  55. 7
      src/de/fernflower/code/instructions/DCMPG.java
  56. 7
      src/de/fernflower/code/instructions/DCMPL.java
  57. 7
      src/de/fernflower/code/instructions/DCONST_0.java
  58. 7
      src/de/fernflower/code/instructions/DCONST_1.java
  59. 7
      src/de/fernflower/code/instructions/DDIV.java
  60. 42
      src/de/fernflower/code/instructions/DLOAD.java
  61. 7
      src/de/fernflower/code/instructions/DMUL.java
  62. 7
      src/de/fernflower/code/instructions/DNEG.java
  63. 7
      src/de/fernflower/code/instructions/DREM.java
  64. 7
      src/de/fernflower/code/instructions/DRETURN.java
  65. 41
      src/de/fernflower/code/instructions/DSTORE.java
  66. 7
      src/de/fernflower/code/instructions/DSUB.java
  67. 7
      src/de/fernflower/code/instructions/DUP.java
  68. 7
      src/de/fernflower/code/instructions/DUP2.java
  69. 7
      src/de/fernflower/code/instructions/DUP2_X1.java
  70. 7
      src/de/fernflower/code/instructions/DUP2_X2.java
  71. 7
      src/de/fernflower/code/instructions/DUP_X1.java
  72. 7
      src/de/fernflower/code/instructions/DUP_X2.java
  73. 7
      src/de/fernflower/code/instructions/F2D.java
  74. 7
      src/de/fernflower/code/instructions/F2I.java
  75. 7
      src/de/fernflower/code/instructions/F2L.java
  76. 7
      src/de/fernflower/code/instructions/FADD.java
  77. 7
      src/de/fernflower/code/instructions/FALOAD.java
  78. 7
      src/de/fernflower/code/instructions/FASTORE.java
  79. 7
      src/de/fernflower/code/instructions/FCMPG.java
  80. 7
      src/de/fernflower/code/instructions/FCMPL.java
  81. 7
      src/de/fernflower/code/instructions/FCONST_0.java
  82. 7
      src/de/fernflower/code/instructions/FCONST_1.java
  83. 7
      src/de/fernflower/code/instructions/FCONST_2.java
  84. 7
      src/de/fernflower/code/instructions/FDIV.java
  85. 42
      src/de/fernflower/code/instructions/FLOAD.java
  86. 7
      src/de/fernflower/code/instructions/FMUL.java
  87. 7
      src/de/fernflower/code/instructions/FNEG.java
  88. 7
      src/de/fernflower/code/instructions/FREM.java
  89. 7
      src/de/fernflower/code/instructions/FRETURN.java
  90. 41
      src/de/fernflower/code/instructions/FSTORE.java
  91. 7
      src/de/fernflower/code/instructions/FSUB.java
  92. 18
      src/de/fernflower/code/instructions/GETFIELD.java
  93. 19
      src/de/fernflower/code/instructions/GETSTATIC.java
  94. 30
      src/de/fernflower/code/instructions/GOTO.java
  95. 19
      src/de/fernflower/code/instructions/GOTO_W.java
  96. 7
      src/de/fernflower/code/instructions/I2B.java
  97. 7
      src/de/fernflower/code/instructions/I2C.java
  98. 7
      src/de/fernflower/code/instructions/I2D.java
  99. 7
      src/de/fernflower/code/instructions/I2F.java
  100. 7
      src/de/fernflower/code/instructions/I2L.java
  101. Some files were not shown because too many files have changed in this diff Show More

@ -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>

@ -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>

@ -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

@ -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

@ -0,0 +1,6 @@
/HRTimerResolution.class
/SystemTimerResolution.class
/com
/de
/native
/test

@ -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>

@ -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.

@ -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.

@ -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.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -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;
}

@ -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"
};
}

@ -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"
};
}

@ -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();
}
}

@ -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;
}
}

@ -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);
}
}
}

@ -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;
}
}

@ -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;
}
}

@ -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;
}
}

@ -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;
}
}

@ -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);
}
}

@ -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;
}
}

@ -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;
}
}

@ -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;
}
}

@ -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;
// }
}

@ -0,0 +1,7 @@
package de.fernflower.code.instructions;
import de.fernflower.code.Instruction;
public class AALOAD extends Instruction {
}

@ -0,0 +1,7 @@
package de.fernflower.code.instructions;
import de.fernflower.code.Instruction;
public class AASTORE extends Instruction {
}

@ -0,0 +1,7 @@
package de.fernflower.code.instructions;
import de.fernflower.code.Instruction;
public class ACONST_NULL extends Instruction {
}

@ -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;
}
}
}

@ -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;
}
}

@ -0,0 +1,7 @@
package de.fernflower.code.instructions;
import de.fernflower.code.Instruction;
public class ARETURN extends Instruction {
}

@ -0,0 +1,7 @@
package de.fernflower.code.instructions;
import de.fernflower.code.Instruction;
public class ARRAYLENGTH extends Instruction {
}

@ -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;
}
}
}

@ -0,0 +1,7 @@
package de.fernflower.code.instructions;
import de.fernflower.code.Instruction;
public class ATHROW extends Instruction {
}

@ -0,0 +1,7 @@
package de.fernflower.code.instructions;
import de.fernflower.code.Instruction;
public class BALOAD extends Instruction {
}

@ -0,0 +1,7 @@
package de.fernflower.code.instructions;
import de.fernflower.code.Instruction;
public class BASTORE extends Instruction {
}

@ -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;
}
}
}

@ -0,0 +1,7 @@
package de.fernflower.code.instructions;
import de.fernflower.code.Instruction;
public class CALOAD extends Instruction {
}

@ -0,0 +1,7 @@
package de.fernflower.code.instructions;
import de.fernflower.code.Instruction;
public class CASTORE extends Instruction {
}

@ -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;
}
}

@ -0,0 +1,7 @@
package de.fernflower.code.instructions;
import de.fernflower.code.Instruction;
public class D2F extends Instruction {
}

@ -0,0 +1,7 @@
package de.fernflower.code.instructions;
import de.fernflower.code.Instruction;
public class D2I extends Instruction {
}

@ -0,0 +1,7 @@
package de.fernflower.code.instructions;
import de.fernflower.code.Instruction;
public class D2L extends Instruction {
}

@ -0,0 +1,7 @@
package de.fernflower.code.instructions;
import de.fernflower.code.Instruction;
public class DADD extends Instruction {
}

@ -0,0 +1,7 @@
package de.fernflower.code.instructions;
import de.fernflower.code.Instruction;
public class DALOAD extends Instruction {
}

@ -0,0 +1,7 @@
package de.fernflower.code.instructions;
import de.fernflower.code.Instruction;
public class DASTORE extends Instruction {
}

@ -0,0 +1,7 @@
package de.fernflower.code.instructions;
import de.fernflower.code.Instruction;
public class DCMPG extends Instruction {
}

@ -0,0 +1,7 @@
package de.fernflower.code.instructions;
import de.fernflower.code.Instruction;
public class DCMPL extends Instruction {
}

@ -0,0 +1,7 @@
package de.fernflower.code.instructions;
import de.fernflower.code.Instruction;
public class DCONST_0 extends Instruction {
}

@ -0,0 +1,7 @@
package de.fernflower.code.instructions;
import de.fernflower.code.Instruction;
public class DCONST_1 extends Instruction {
}

@ -0,0 +1,7 @@
package de.fernflower.code.instructions;
import de.fernflower.code.Instruction;
public class DDIV extends Instruction {
}

@ -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;
}
}
}

@ -0,0 +1,7 @@
package de.fernflower.code.instructions;
import de.fernflower.code.Instruction;
public class DMUL extends Instruction {
}

@ -0,0 +1,7 @@
package de.fernflower.code.instructions;
import de.fernflower.code.Instruction;
public class DNEG extends Instruction {
}

@ -0,0 +1,7 @@
package de.fernflower.code.instructions;
import de.fernflower.code.Instruction;
public class DREM extends Instruction {
}

@ -0,0 +1,7 @@
package de.fernflower.code.instructions;
import de.fernflower.code.Instruction;
public class DRETURN extends Instruction {
}

@ -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;
}
}
}

@ -0,0 +1,7 @@
package de.fernflower.code.instructions;
import de.fernflower.code.Instruction;
public class DSUB extends Instruction {
}

@ -0,0 +1,7 @@
package de.fernflower.code.instructions;
import de.fernflower.code.Instruction;
public class DUP extends Instruction {
}

@ -0,0 +1,7 @@
package de.fernflower.code.instructions;
import de.fernflower.code.Instruction;
public class DUP2 extends Instruction {
}

@ -0,0 +1,7 @@
package de.fernflower.code.instructions;
import de.fernflower.code.Instruction;
public class DUP2_X1 extends Instruction {
}

@ -0,0 +1,7 @@
package de.fernflower.code.instructions;
import de.fernflower.code.Instruction;
public class DUP2_X2 extends Instruction {
}

@ -0,0 +1,7 @@
package de.fernflower.code.instructions;
import de.fernflower.code.Instruction;
public class DUP_X1 extends Instruction {
}

@ -0,0 +1,7 @@
package de.fernflower.code.instructions;
import de.fernflower.code.Instruction;
public class DUP_X2 extends Instruction {
}

@ -0,0 +1,7 @@
package de.fernflower.code.instructions;
import de.fernflower.code.Instruction;
public class F2D extends Instruction {
}

@ -0,0 +1,7 @@
package de.fernflower.code.instructions;
import de.fernflower.code.Instruction;
public class F2I extends Instruction {
}

@ -0,0 +1,7 @@
package de.fernflower.code.instructions;
import de.fernflower.code.Instruction;
public class F2L extends Instruction {
}

@ -0,0 +1,7 @@
package de.fernflower.code.instructions;
import de.fernflower.code.Instruction;
public class FADD extends Instruction {
}

@ -0,0 +1,7 @@
package de.fernflower.code.instructions;
import de.fernflower.code.Instruction;
public class FALOAD extends Instruction {
}

@ -0,0 +1,7 @@
package de.fernflower.code.instructions;
import de.fernflower.code.Instruction;
public class FASTORE extends Instruction {
}

@ -0,0 +1,7 @@
package de.fernflower.code.instructions;
import de.fernflower.code.Instruction;
public class FCMPG extends Instruction {
}

@ -0,0 +1,7 @@
package de.fernflower.code.instructions;
import de.fernflower.code.Instruction;
public class FCMPL extends Instruction {
}

@ -0,0 +1,7 @@
package de.fernflower.code.instructions;
import de.fernflower.code.Instruction;
public class FCONST_0 extends Instruction {
}

@ -0,0 +1,7 @@
package de.fernflower.code.instructions;
import de.fernflower.code.Instruction;
public class FCONST_1 extends Instruction {
}

@ -0,0 +1,7 @@
package de.fernflower.code.instructions;
import de.fernflower.code.Instruction;
public class FCONST_2 extends Instruction {
}

@ -0,0 +1,7 @@
package de.fernflower.code.instructions;
import de.fernflower.code.Instruction;
public class FDIV extends Instruction {
}

@ -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;
}
}
}

@ -0,0 +1,7 @@
package de.fernflower.code.instructions;
import de.fernflower.code.Instruction;
public class FMUL extends Instruction {
}

@ -0,0 +1,7 @@
package de.fernflower.code.instructions;
import de.fernflower.code.Instruction;
public class FNEG extends Instruction {
}

@ -0,0 +1,7 @@
package de.fernflower.code.instructions;
import de.fernflower.code.Instruction;
public class FREM extends Instruction {
}

@ -0,0 +1,7 @@
package de.fernflower.code.instructions;
import de.fernflower.code.Instruction;
public class FRETURN extends Instruction {
}

@ -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;
}
}
}

@ -0,0 +1,7 @@
package de.fernflower.code.instructions;
import de.fernflower.code.Instruction;
public class FSUB extends Instruction {
}

@ -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;
}
}

@ -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;
}
}

@ -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;
}
}
}

@ -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;
}
}

@ -0,0 +1,7 @@
package de.fernflower.code.instructions;
import de.fernflower.code.Instruction;
public class I2B extends Instruction {
}

@ -0,0 +1,7 @@
package de.fernflower.code.instructions;
import de.fernflower.code.Instruction;
public class I2C extends Instruction {
}

@ -0,0 +1,7 @@
package de.fernflower.code.instructions;
import de.fernflower.code.Instruction;
public class I2D extends Instruction {
}

@ -0,0 +1,7 @@
package de.fernflower.code.instructions;
import de.fernflower.code.Instruction;
public class I2F extends Instruction {
}

@ -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…
Cancel
Save