commit
e2d0f5d9c3
@ -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 |
@ -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…
Reference in new issue