Initial commit
This commit is contained in:
commit
61202b8db3
|
@ -0,0 +1,2 @@
|
|||
# Project exclude paths
|
||||
/out/
|
|
@ -0,0 +1,2 @@
|
|||
# Default ignored files
|
||||
/workspace.xml
|
|
@ -0,0 +1,5 @@
|
|||
<component name="ProjectCodeStyleConfiguration">
|
||||
<state>
|
||||
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
|
||||
</state>
|
||||
</component>
|
|
@ -0,0 +1,19 @@
|
|||
<component name="libraryTable">
|
||||
<library name="asm-6.2.1">
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/lib/asm-6.2.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/asm-tree-6.2.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/asm-util-6.2.1.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC>
|
||||
<root url="jar://$PROJECT_DIR$/lib/asm-util-6.2.1-javadoc.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/asm-tree-6.2.1-javadoc.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/asm-6.2.1-javadoc.jar!/" />
|
||||
</JAVADOC>
|
||||
<SOURCES>
|
||||
<root url="jar://$PROJECT_DIR$/lib/asm-util-6.2.1-sources.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/asm-tree-6.2.1-sources.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/asm-6.2.1-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
|
@ -0,0 +1,19 @@
|
|||
<component name="libraryTable">
|
||||
<library name="asm-7.1">
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/lib/asm-7.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/asm-tree-7.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/asm-util-7.1.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC>
|
||||
<root url="jar://$PROJECT_DIR$/lib/asm-7.1-javadoc.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/asm-tree-7.1-javadoc.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/asm-util-7.1-javadoc.jar!/" />
|
||||
</JAVADOC>
|
||||
<SOURCES>
|
||||
<root url="jar://$PROJECT_DIR$/lib/asm-7.1-sources.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/asm-tree-7.1-sources.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/asm-util-7.1-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ASMPluginConfiguration">
|
||||
<asm skipDebug="false" skipFrames="false" skipCode="false" expandFrames="false" />
|
||||
<groovy codeStyle="LEGACY" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="10" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/starter-lab-03-control-flow-graph.iml" filepath="$PROJECT_DIR$/starter-lab-03-control-flow-graph.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
|
@ -0,0 +1,16 @@
|
|||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="App" type="Application" factoryName="Application" nameIsGenerated="true">
|
||||
<option name="MAIN_CLASS_NAME" value="ch.usi.inf.sp.cfg.App" />
|
||||
<module name="starter-lab-03-control-flow-graph" />
|
||||
<option name="PROGRAM_PARAMETERS" value="test-input/java10/ExampleClass.class test-output" />
|
||||
<extension name="coverage">
|
||||
<pattern>
|
||||
<option name="PATTERN" value="ch.usi.inf.sp.cfg.*" />
|
||||
<option name="ENABLED" value="true" />
|
||||
</pattern>
|
||||
</extension>
|
||||
<method v="2">
|
||||
<option name="Make" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
|
@ -0,0 +1,16 @@
|
|||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Disassembler" type="Application" factoryName="Application" nameIsGenerated="true">
|
||||
<option name="MAIN_CLASS_NAME" value="ch.usi.inf.sp.bytecode.Disassembler" />
|
||||
<module name="starter-lab-03-control-flow-graph" />
|
||||
<option name="PROGRAM_PARAMETERS" value="test-input/java10/ExampleClass.class" />
|
||||
<extension name="coverage">
|
||||
<pattern>
|
||||
<option name="PATTERN" value="ch.usi.inf.sp.bytecode.*" />
|
||||
<option name="ENABLED" value="true" />
|
||||
</pattern>
|
||||
</extension>
|
||||
<method v="2">
|
||||
<option name="Make" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
|
@ -0,0 +1,33 @@
|
|||
|
||||
Z
|
||||
*src/ch/usi/inf/sp/cfg/ControlFlowEdge.java,e/2/e247c98c4559c2496de82f3e8f48496d2bcdddf8
|
||||
U
|
||||
%src/ch/usi/inf/sp/cfg/BasicBlock.java,a/e/aec2e516e41cb21c9a4ade8ba65df93a4d9fab34
|
||||
R
|
||||
"src/ch/usi/inf/sp/cfg/DiGraph.java,f/c/fc8a9475de791989c6b6f67b2633ef05316bc452
|
||||
O
|
||||
src/ch/usi/inf/sp/cfg/Node.java,8/2/82486daf1ead06938ed753f9c0b9a037e820dea6
|
||||
O
|
||||
src/ch/usi/inf/sp/cfg/Edge.java,f/2/f2cb273ead76d5551936493264dcd26c5e017524
|
||||
b
|
||||
2src/ch/usi/inf/sp/cfg/ControlFlowGraphBuilder.java,2/a/2a5d56a977b03b073089a819a9ea6194fc1afd0a
|
||||
g
|
||||
7test/ch/usi/inf/sp/cfg/ControlFlowGraphBuilderTest.java,0/9/097045e1e02092132bbc47711f6f4819d63ae00c
|
||||
`
|
||||
0test/ch/usi/inf/sp/cfg/ControlFlowGraphTest.java,7/d/7de9ba135972e3a5bb4c4be3f09617c7b4308b2a
|
||||
Z
|
||||
*test/ch/usi/inf/sp/cfg/BasicBlockTest.java,6/0/608b59d29ada3bdf791d1e893cca82439461779b
|
||||
c
|
||||
3src/ch/usi/inf/sp/cfg/ControlFlowGraphRenderer.java,f/3/f3b5286492d8303e6f1bc94ef61c96398d676415
|
||||
N
|
||||
src/ch/usi/inf/sp/cfg/App.java,3/1/315516d2cd295643960002e984aed7e635fef323
|
||||
J
|
||||
test-output/<init>.asm.txt,8/7/8725d0be13ceef5da1489242474461bbb2d9776a
|
||||
F
|
||||
test-output/<init>.dot,3/0/3064536d3d56d61bacd44c824877cd8dc595b027
|
||||
[
|
||||
+src/ch/usi/inf/sp/cfg/ControlFlowGraph.java,5/8/58e91939af92da74db3736e65036de3095a35b4b
|
||||
\
|
||||
,src/ch/usi/inf/sp/bytecode/Disassembler.java,b/f/bf6e198d42d74354a5c5895e3ca0d4dc6b806e6c
|
||||
9
|
||||
README.md,8/e/8ec9a00bfd09b3190ac6b22251dbb1aa95a0579d
|
|
@ -0,0 +1,124 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Palette2">
|
||||
<group name="Swing">
|
||||
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
|
||||
</item>
|
||||
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
|
||||
</item>
|
||||
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
|
||||
</item>
|
||||
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
|
||||
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
|
||||
</item>
|
||||
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
|
||||
<initial-values>
|
||||
<property name="text" value="Button" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
|
||||
<initial-values>
|
||||
<property name="text" value="RadioButton" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
|
||||
<initial-values>
|
||||
<property name="text" value="CheckBox" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
|
||||
<initial-values>
|
||||
<property name="text" value="Label" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||
<preferred-size width="150" height="-1" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||
<preferred-size width="150" height="-1" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||
<preferred-size width="150" height="-1" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
|
||||
<preferred-size width="200" height="200" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
|
||||
<preferred-size width="200" height="200" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
|
||||
</item>
|
||||
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
|
||||
<preferred-size width="-1" height="20" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
|
||||
</item>
|
||||
</group>
|
||||
</component>
|
||||
</project>
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
|
@ -0,0 +1,31 @@
|
|||
# Lab 3 - Software Peformance 2023
|
||||
|
||||
This is Lab 3 of the **Software Performance** course at USI.
|
||||
|
||||
Go to [this Lab on iCorsi](https://www.icorsi.ch/course/view.php?id=16963).
|
||||
|
||||
## Submission Info
|
||||
|
||||
Property | Value
|
||||
------------ | -------------
|
||||
First Name | ...
|
||||
Last Name | ...
|
||||
|
||||
## Submission Checklist
|
||||
|
||||
Please complete this checklist (turn [ ] into [X]) before you submit:
|
||||
|
||||
- [ ] I completed the above Submission Info
|
||||
- [ ] I built the project in IntelliJ (Build > Build Project)
|
||||
- [ ] I implemented the ControlFlowGraphBuilder
|
||||
- [ ] I implemented the ControlFlowGraphRenderer
|
||||
- [ ] I wrote the source code myself and did not look at the source code of my class mates
|
||||
- [ ] I ran all the JUnit tests and verified that they all pass
|
||||
- [ ] I manually checked that my implementation is correct by doing this:
|
||||
- [ ] I studied the test-input/ExampleClass.java source code
|
||||
- [ ] I ran App to produce the dot files (in test-output/)
|
||||
- [ ] I ran dot to turn the dot files in test-output into a PDF
|
||||
- [ ] I manually verified that the PDF contains one page per method of ExampleClass
|
||||
- [ ] I manually verified that those CFGs correspond to the methods' source code
|
||||
- [ ] I committed my changes (at least one commit, but possibly many)
|
||||
- [ ] I pushed my commits to GitHub
|
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,265 @@
|
|||
package ch.usi.inf.sp.bytecode;
|
||||
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.util.List;
|
||||
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.tree.*;
|
||||
import org.objectweb.asm.util.Printer;
|
||||
|
||||
|
||||
/**
|
||||
* A Disassembler can disassemble Java class files.
|
||||
* It presents an output similar to javap -c.
|
||||
* Given the name of the class file as a command line argument,
|
||||
* it prints the name of the class, a list of all methods,
|
||||
* and for each method, the list of all Java bytecode instructions.
|
||||
* <p>
|
||||
* The format of the disassembled bytecode includes the opcodes
|
||||
* (in the form of mnemonics such as "ILOAD") and all the operands.
|
||||
* Some operands can be printed as simple integers, while others have to be printed in a more understandable form
|
||||
* (e.g. method or field names and descriptors).
|
||||
* Operands of branch instructions are shown as an "id" of the targeted instruction.
|
||||
* For this, all instructions of a method, including ASM's pseudo-instructions (LABEL, LINE, FRAME),
|
||||
* are numbered, starting at 0.
|
||||
* The instruction id allows you to look up the corresponding instruction object in the instruction list:
|
||||
* AbstractInsnNode target = instructionList.get(targetId);
|
||||
* <p>
|
||||
* An example output:
|
||||
*
|
||||
* <pre>
|
||||
* Class: ExampleClass
|
||||
* ...
|
||||
* Method: switchMethod2(I)I
|
||||
* 0: // label
|
||||
* 1: // line number information
|
||||
* 2: ICONST_0
|
||||
* 3: ISTORE 2
|
||||
* 4: // label
|
||||
* 5: // line number information
|
||||
* 6: ILOAD 1
|
||||
* 7: LOOKUPSWITCH 0: 8, 1000: 13, 2000: 18, default: 23
|
||||
* 8: // label
|
||||
* 9: // line number information
|
||||
* 10: ICONST_0
|
||||
* 11: ISTORE 2
|
||||
* 12: GOTO 27
|
||||
* 13: // label
|
||||
* 14: // line number information
|
||||
* 15: ICONST_1
|
||||
* 16: ISTORE 2
|
||||
* 17: GOTO 27
|
||||
* 18: // label
|
||||
* 19: // line number information
|
||||
* 20: ICONST_2
|
||||
* 21: ISTORE 2
|
||||
* 22: GOTO 27
|
||||
* 23: // label
|
||||
* 24: // line number information
|
||||
* 25: ICONST_M1
|
||||
* 26: ISTORE 2
|
||||
* 27: // label
|
||||
* 28: // line number information
|
||||
* 29: ILOAD 2
|
||||
* 30: IRETURN
|
||||
* 31: // label
|
||||
* </pre>
|
||||
*
|
||||
* @author Matthias.Hauswirth@usi.ch
|
||||
*/
|
||||
public class Disassembler {
|
||||
|
||||
public static void main(final String[] args) throws Exception {
|
||||
// create a ClassReader that loads the Java .class file specified as the command line argument
|
||||
final String classFileName = args[0];
|
||||
final ClassReader cr = new ClassReader(new FileInputStream(classFileName));
|
||||
// create an empty ClassNode (in-memory representation of a class)
|
||||
final ClassNode clazz = new ClassNode();
|
||||
// have the ClassReader read the class file and populate the ClassNode with the corresponding information
|
||||
cr.accept(clazz, 0);
|
||||
// create a dumper and have it dump the given ClassNode
|
||||
System.out.println(disassembleClass(clazz));
|
||||
}
|
||||
|
||||
public static String disassembleClass(final ClassNode clazz) {
|
||||
final StringBuffer sb = new StringBuffer("Class: ");
|
||||
sb.append(clazz.name);
|
||||
sb.append('\n');
|
||||
// get the list of all methods in that class
|
||||
final List<MethodNode> methods = clazz.methods;
|
||||
for (int m = 0; m < methods.size(); m++) {
|
||||
final MethodNode method = methods.get(m);
|
||||
sb.append(disassembleMethod(method));
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static String disassembleMethod(final MethodNode method) {
|
||||
final StringBuffer sb = new StringBuffer(" Method: ");
|
||||
sb.append(method.name);
|
||||
sb.append(method.desc);
|
||||
sb.append('\n');
|
||||
// get the list of all instructions in that method
|
||||
final InsnList instructions = method.instructions;
|
||||
for (int i = 0; i < instructions.size(); i++) {
|
||||
final AbstractInsnNode instruction = instructions.get(i);
|
||||
sb.append(" ");
|
||||
sb.append(Disassembler.disassembleInstruction(instruction, i, instructions));
|
||||
sb.append('\n');
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Hint: Check out org.objectweb.asm.MethodVisitor to determine which instructions (opcodes)
|
||||
* have which instruction types (subclasses of AbstractInsnNode).
|
||||
*
|
||||
* @see org.objectweb.asm.MethodVisitor
|
||||
* <p>
|
||||
* E.g. the comment in org.objectweb.asm.MethodVisitor.visitIntInsn(int opcode, int operand)
|
||||
* shows the list of all opcodes that are represented as instructions of type IntInsnNode.
|
||||
* That list e.g. includes the BIPUSH opcode.
|
||||
*/
|
||||
public static String disassembleInstruction(final AbstractInsnNode instruction, final int i, final InsnList instructions) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
final int opcode = instruction.getOpcode();
|
||||
final String mnemonic = opcode == -1 ? "" : Printer.OPCODES[instruction.getOpcode()];
|
||||
sb.append(i + ":\t" + mnemonic + " ");
|
||||
// There are different subclasses of AbstractInsnNode.
|
||||
// AbstractInsnNode.getType() represents the subclass as an int.
|
||||
// Note:
|
||||
// to check the subclass of an instruction node, we can either use:
|
||||
// if (instruction.getType()==AbstractInsnNode.LABEL)
|
||||
// or we can use:
|
||||
// if (instruction instanceof LabelNode)
|
||||
// They give the same result, but the first one can be used in a switch statement.
|
||||
switch (instruction.getType()) {
|
||||
case AbstractInsnNode.LABEL:
|
||||
// pseudo-instruction (branch or exception target)
|
||||
sb.append("// label");
|
||||
break;
|
||||
case AbstractInsnNode.FRAME:
|
||||
// pseudo-instruction (stack frame map)
|
||||
sb.append("// stack frame map");
|
||||
break;
|
||||
case AbstractInsnNode.LINE:
|
||||
// pseudo-instruction (line number information)
|
||||
sb.append("// line number information");
|
||||
case AbstractInsnNode.INSN:
|
||||
// Opcodes: NOP, ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1, ICONST_2,
|
||||
// ICONST_3, ICONST_4, ICONST_5, LCONST_0, LCONST_1, FCONST_0,
|
||||
// FCONST_1, FCONST_2, DCONST_0, DCONST_1, IALOAD, LALOAD, FALOAD,
|
||||
// DALOAD, AALOAD, BALOAD, CALOAD, SALOAD, IASTORE, LASTORE, FASTORE,
|
||||
// DASTORE, AASTORE, BASTORE, CASTORE, SASTORE, POP, POP2, DUP,
|
||||
// DUP_X1, DUP_X2, DUP2, DUP2_X1, DUP2_X2, SWAP, IADD, LADD, FADD,
|
||||
// DADD, ISUB, LSUB, FSUB, DSUB, IMUL, LMUL, FMUL, DMUL, IDIV, LDIV,
|
||||
// FDIV, DDIV, IREM, LREM, FREM, DREM, INEG, LNEG, FNEG, DNEG, ISHL,
|
||||
// LSHL, ISHR, LSHR, IUSHR, LUSHR, IAND, LAND, IOR, LOR, IXOR, LXOR,
|
||||
// I2L, I2F, I2D, L2I, L2F, L2D, F2I, F2L, F2D, D2I, D2L, D2F, I2B,
|
||||
// I2C, I2S, LCMP, FCMPL, FCMPG, DCMPL, DCMPG, IRETURN, LRETURN,
|
||||
// FRETURN, DRETURN, ARETURN, RETURN, ARRAYLENGTH, ATHROW,
|
||||
// MONITORENTER, or MONITOREXIT.
|
||||
// zero operands, nothing to print
|
||||
break;
|
||||
case AbstractInsnNode.INT_INSN:
|
||||
// Opcodes: NEWARRAY, BIPUSH, SIPUSH.
|
||||
if (instruction.getOpcode() == Opcodes.NEWARRAY) {
|
||||
// NEWARRAY
|
||||
sb.append(Printer.TYPES[((IntInsnNode) instruction).operand]);
|
||||
} else {
|
||||
// BIPUSH or SIPUSH
|
||||
sb.append(((IntInsnNode) instruction).operand);
|
||||
}
|
||||
break;
|
||||
case AbstractInsnNode.JUMP_INSN:
|
||||
// Opcodes: IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ,
|
||||
// IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ACMPEQ,
|
||||
// IF_ACMPNE, GOTO, JSR, IFNULL or IFNONNULL.
|
||||
{
|
||||
final LabelNode targetInstruction = ((JumpInsnNode) instruction).label;
|
||||
final int targetId = instructions.indexOf(targetInstruction);
|
||||
sb.append(targetId);
|
||||
break;
|
||||
}
|
||||
case AbstractInsnNode.LDC_INSN:
|
||||
// Opcodes: LDC.
|
||||
sb.append(((LdcInsnNode) instruction).cst);
|
||||
break;
|
||||
case AbstractInsnNode.IINC_INSN:
|
||||
// Opcodes: IINC.
|
||||
sb.append(((IincInsnNode) instruction).var);
|
||||
sb.append(" ");
|
||||
sb.append(((IincInsnNode) instruction).incr);
|
||||
break;
|
||||
case AbstractInsnNode.TYPE_INSN:
|
||||
// Opcodes: NEW, ANEWARRAY, CHECKCAST or INSTANCEOF.
|
||||
sb.append(((TypeInsnNode) instruction).desc);
|
||||
break;
|
||||
case AbstractInsnNode.VAR_INSN:
|
||||
// Opcodes: ILOAD, LLOAD, FLOAD, DLOAD, ALOAD, ISTORE,
|
||||
// LSTORE, FSTORE, DSTORE, ASTORE or RET.
|
||||
sb.append(((VarInsnNode) instruction).var);
|
||||
break;
|
||||
case AbstractInsnNode.FIELD_INSN:
|
||||
// Opcodes: GETSTATIC, PUTSTATIC, GETFIELD or PUTFIELD.
|
||||
sb.append(((FieldInsnNode) instruction).owner);
|
||||
sb.append(".");
|
||||
sb.append(((FieldInsnNode) instruction).name);
|
||||
sb.append(" ");
|
||||
sb.append(((FieldInsnNode) instruction).desc);
|
||||
break;
|
||||
case AbstractInsnNode.METHOD_INSN:
|
||||
// Opcodes: INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC,
|
||||
// INVOKEINTERFACE or INVOKEDYNAMIC.
|
||||
sb.append(((MethodInsnNode) instruction).owner);
|
||||
sb.append(".");
|
||||
sb.append(((MethodInsnNode) instruction).name);
|
||||
sb.append(" ");
|
||||
sb.append(((MethodInsnNode) instruction).desc);
|
||||
break;
|
||||
case AbstractInsnNode.MULTIANEWARRAY_INSN:
|
||||
// Opcodes: MULTIANEWARRAY.
|
||||
sb.append(((MultiANewArrayInsnNode) instruction).desc);
|
||||
sb.append(" ");
|
||||
sb.append(((MultiANewArrayInsnNode) instruction).dims);
|
||||
break;
|
||||
case AbstractInsnNode.LOOKUPSWITCH_INSN:
|
||||
// Opcodes: LOOKUPSWITCH.
|
||||
{
|
||||
final List keys = ((LookupSwitchInsnNode) instruction).keys;
|
||||
final List labels = ((LookupSwitchInsnNode) instruction).labels;
|
||||
for (int t = 0; t < keys.size(); t++) {
|
||||
final int key = (Integer) keys.get(t);
|
||||
final LabelNode targetInstruction = (LabelNode) labels.get(t);
|
||||
final int targetId = instructions.indexOf(targetInstruction);
|
||||
sb.append(key + ": " + targetId + ", ");
|
||||
}
|
||||
final LabelNode defaultTargetInstruction = ((LookupSwitchInsnNode) instruction).dflt;
|
||||
final int defaultTargetId = instructions.indexOf(defaultTargetInstruction);
|
||||
sb.append("default: " + defaultTargetId);
|
||||
break;
|
||||
}
|
||||
case AbstractInsnNode.TABLESWITCH_INSN:
|
||||
// Opcodes: TABLESWITCH.
|
||||
{
|
||||
final int minKey = ((TableSwitchInsnNode) instruction).min;
|
||||
final List labels = ((TableSwitchInsnNode) instruction).labels;
|
||||
for (int t = 0; t < labels.size(); t++) {
|
||||
final int key = minKey + t;
|
||||
final LabelNode targetInstruction = (LabelNode) labels.get(t);
|
||||
final int targetId = instructions.indexOf(targetInstruction);
|
||||
sb.append(key + ": " + targetId + ", ");
|
||||
}
|
||||
final LabelNode defaultTargetInstruction = ((TableSwitchInsnNode) instruction).dflt;
|
||||
final int defaultTargetId = instructions.indexOf(defaultTargetInstruction);
|
||||
sb.append("default: " + defaultTargetId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
package ch.usi.inf.sp.cfg;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import ch.usi.inf.sp.bytecode.Disassembler;
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import org.objectweb.asm.tree.MethodNode;
|
||||
|
||||
|
||||
public final class App {
|
||||
|
||||
/**
|
||||
* Invoke like this...
|
||||
* <p>
|
||||
* java App test-input/java10/ExampleClass.class test-output
|
||||
* <p>
|
||||
* to produce one disassembly and one CFG for each method in ExampleClass.
|
||||
* Afterwards, go to the test-output folder, and call...
|
||||
* <p>
|
||||
* dot -Tpdf -oall.pdf *.dot
|
||||
* <p>
|
||||
* ...to produce a file all.pdf containing one page for each CFG.
|
||||
*/
|
||||
public static void main(final String[] args) throws IOException {
|
||||
final File classFile = new File(args[0]);
|
||||
final File outputDirectory = new File(args[1]);
|
||||
final App app = new App(classFile, outputDirectory);
|
||||
app.execute();
|
||||
}
|
||||
|
||||
private final File classFile;
|
||||
private final File outputDirectory;
|
||||
|
||||
|
||||
public App(final File classFile, final File outputDirectory) {
|
||||
this.classFile = classFile;
|
||||
this.outputDirectory = outputDirectory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the given contents into a file with the given fileName in the outputDirectory.
|
||||
*/
|
||||
private void save(final String fileName, final String contents) throws IOException {
|
||||
if (!outputDirectory.exists()) {
|
||||
outputDirectory.mkdirs();
|
||||
}
|
||||
final File file = new File(outputDirectory, fileName);
|
||||
final FileWriter writer = new FileWriter(file);
|
||||
writer.write(contents);
|
||||
writer.close();
|
||||
}
|
||||
|
||||
public void execute() throws IOException {
|
||||
final ClassReader cr = new ClassReader(new FileInputStream(classFile));
|
||||
// create an empty ClassNode (in-memory representation of a class)
|
||||
final ClassNode cn = new ClassNode();
|
||||
// have the ClassReader read the class file and populate the ClassNode with the corresponding information
|
||||
cr.accept(cn, 0);
|
||||
// disassemble and perform control-flow analysis
|
||||
processClass(cn);
|
||||
}
|
||||
|
||||
private void processClass(final ClassNode cn) throws IOException {
|
||||
System.out.println("Class: " + cn.name);
|
||||
// get the list of all methods in that class
|
||||
final List<MethodNode> methods = cn.methods;
|
||||
for (int m = 0; m < methods.size(); m++) {
|
||||
final MethodNode method = methods.get(m);
|
||||
processMethod(method);
|
||||
}
|
||||
}
|
||||
|
||||
private void processMethod(final MethodNode method) throws IOException {
|
||||
System.out.println(" Method: " + method.name + method.desc);
|
||||
save(method.name + ".asm.txt", Disassembler.disassembleMethod(method));
|
||||
final ControlFlowGraph cfg = ControlFlowGraphBuilder.createControlFlowGraph(method);
|
||||
save(method.name + ".dot", ControlFlowGraphRenderer.renderControlFlowGraph(method.name, cfg));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package ch.usi.inf.sp.cfg;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
|
||||
public final class BasicBlock extends Node {
|
||||
|
||||
private final int id;
|
||||
private final ArrayList<String> instructions;
|
||||
|
||||
|
||||
public BasicBlock(final int id) {
|
||||
this.id = id;
|
||||
instructions = new ArrayList<String>();
|
||||
}
|
||||
|
||||
public void appendInstruction(final String s) {
|
||||
instructions.add(s);
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public int getInstructionCount() {
|
||||
return instructions.size();
|
||||
}
|
||||
|
||||
public String getInstruction(int i) {
|
||||
return instructions.get(i);
|
||||
}
|
||||
|
||||
public Iterable<String> getInstructions() {
|
||||
return instructions;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package ch.usi.inf.sp.cfg;
|
||||
|
||||
|
||||
public final class ControlFlowEdge extends Edge<BasicBlock> {
|
||||
|
||||
private final String label;
|
||||
|
||||
|
||||
public ControlFlowEdge(final String label) {
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
public String getLabel() {
|
||||
return label;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
package ch.usi.inf.sp.cfg;
|
||||
|
||||
|
||||
public final class ControlFlowGraph extends DiGraph<BasicBlock, ControlFlowEdge> {
|
||||
|
||||
private BasicBlock entry;
|
||||
private BasicBlock exit;
|
||||
|
||||
|
||||
public ControlFlowGraph() {
|
||||
entry = new BasicBlock(-1);
|
||||
addNode(entry);
|
||||
exit = new BasicBlock(-2);
|
||||
addNode(exit);
|
||||
}
|
||||
|
||||
private final void checkContains(BasicBlock block, String name) {
|
||||
if (!getNodes().contains(block)) {
|
||||
throw new IllegalStateException("Control flow graph does not contain the given " + name + " block.");
|
||||
}
|
||||
}
|
||||
|
||||
public ControlFlowEdge addEntryEdge(BasicBlock firstBlock) {
|
||||
if (entry.getOutEdges().size() > 0) {
|
||||
throw new IllegalStateException("Control flow graph already has an entry edge. It can only have one.");
|
||||
}
|
||||
checkContains(firstBlock, "firstBlock");
|
||||
ControlFlowEdge edge = new ControlFlowEdge("");
|
||||
addEdge(edge);
|
||||
connect(entry, edge, firstBlock);
|
||||
return edge;
|
||||
}
|
||||
|
||||
public ControlFlowEdge addExitEdge(BasicBlock returnBlock) {
|
||||
checkContains(returnBlock, "returnBlock");
|
||||
ControlFlowEdge edge = new ControlFlowEdge("");
|
||||
addEdge(edge);
|
||||
connect(returnBlock, edge, exit);
|
||||
return edge;
|
||||
}
|
||||
|
||||
public ControlFlowEdge addFallthroughEdge(BasicBlock fromBlock, BasicBlock toBlock) {
|
||||
checkContains(fromBlock, "fromBlock");
|
||||
checkContains(toBlock, "toBlock");
|
||||
ControlFlowEdge edge = new ControlFlowEdge("");
|
||||
addEdge(edge);
|
||||
connect(fromBlock, edge, toBlock);
|
||||
return edge;
|
||||
}
|
||||
|
||||
public ControlFlowEdge addBranchTakenEdge(BasicBlock fromBlock, BasicBlock toBlock) {
|
||||
checkContains(fromBlock, "fromBlock");
|
||||
checkContains(toBlock, "toBlock");
|
||||
ControlFlowEdge edge = new ControlFlowEdge("T");
|
||||
addEdge(edge);
|
||||
connect(fromBlock, edge, toBlock);
|
||||
return edge;
|
||||
}
|
||||
|
||||
public ControlFlowEdge addCaseEdge(BasicBlock fromBlock, BasicBlock toBlock, int key) {
|
||||
checkContains(fromBlock, "fromBlock");
|
||||
checkContains(toBlock, "toBlock");
|
||||
ControlFlowEdge edge = new ControlFlowEdge("" + key);
|
||||
addEdge(edge);
|
||||
connect(fromBlock, edge, toBlock);
|
||||
return edge;
|
||||
}
|
||||
|
||||
public ControlFlowEdge addDefaultEdge(BasicBlock fromBlock, BasicBlock toBlock) {
|
||||
checkContains(fromBlock, "fromBlock");
|
||||
checkContains(toBlock, "toBlock");
|
||||
ControlFlowEdge edge = new ControlFlowEdge("default");
|
||||
addEdge(edge);
|
||||
connect(fromBlock, edge, toBlock);
|
||||
return edge;
|
||||
}
|
||||
|
||||
public BasicBlock getEntry() {
|
||||
return entry;
|
||||
}
|
||||
|
||||
public BasicBlock getExit() {
|
||||
return exit;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package ch.usi.inf.sp.cfg;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import ch.usi.inf.sp.bytecode.Disassembler;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.tree.AbstractInsnNode;
|
||||
import org.objectweb.asm.tree.InsnList;
|
||||
import org.objectweb.asm.tree.JumpInsnNode;
|
||||
import org.objectweb.asm.tree.LabelNode;
|
||||
import org.objectweb.asm.tree.LookupSwitchInsnNode;
|
||||
import org.objectweb.asm.tree.MethodNode;
|
||||
import org.objectweb.asm.tree.TableSwitchInsnNode;
|
||||
|
||||
|
||||
public class ControlFlowGraphBuilder {
|
||||
|
||||
public static ControlFlowGraph createControlFlowGraph(final MethodNode method) {
|
||||
//TODO
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package ch.usi.inf.sp.cfg;
|
||||
|
||||
|
||||
public class ControlFlowGraphRenderer {
|
||||
|
||||
public static String renderControlFlowGraph(final String label, final ControlFlowGraph cfg) {
|
||||
//TODO
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
package ch.usi.inf.sp.cfg;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class DiGraph<N extends Node, E extends Edge<N>> {
|
||||
|
||||
private final ArrayList<N> nodes;
|
||||
private final ArrayList<E> edges;
|
||||
|
||||
|
||||
public DiGraph() {
|
||||
nodes = new ArrayList<N>();
|
||||
edges = new ArrayList<E>();
|
||||
}
|
||||
|
||||
public void addNode(N node) {
|
||||
nodes.add(node);
|
||||
}
|
||||
|
||||
public void addEdge(E edge) {
|
||||
edges.add(edge);
|
||||
}
|
||||
|
||||
public void connect(N from, E edge, N to) {
|
||||
if (!nodes.contains(from)) {
|
||||
throw new IllegalStateException("Graph does not contain from node.");
|
||||
}
|
||||
if (!nodes.contains(to)) {
|
||||
throw new IllegalStateException("Graph does not contain to node.");
|
||||
}
|
||||
if (!edges.contains(edge)) {
|
||||
throw new IllegalStateException("Graph does not contain edge.");
|
||||
}
|
||||
if (from.getOutEdges().contains(edge)) {
|
||||
throw new IllegalStateException("From node already has this edge as out edge");
|
||||
}
|
||||
if (to.getInEdges().contains(edge)) {
|
||||
throw new IllegalStateException("To node already has this edge as in edge");
|
||||
}
|
||||
edge.setFrom(from);
|
||||
edge.setTo(to);
|
||||
from.addOutEdge(edge);
|
||||
to.addInEdge(edge);
|
||||
}
|
||||
|
||||
public List<E> getEdges() {
|
||||
return Collections.unmodifiableList(edges);
|
||||
}
|
||||
|
||||
public List<N> getNodes() {
|
||||
return Collections.unmodifiableList(nodes);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package ch.usi.inf.sp.cfg;
|
||||
|
||||
|
||||
public class Edge<N extends Node> {
|
||||
|
||||
private N from;
|
||||
private N to;
|
||||
|
||||
public Edge() {
|
||||
}
|
||||
|
||||
public void setFrom(N node) {
|
||||
from = node;
|
||||
}
|
||||
|
||||
public N getFrom() {
|
||||
return from;
|
||||
}
|
||||
|
||||
public void setTo(N node) {
|
||||
to = node;
|
||||
}
|
||||
|
||||
public N getTo() {
|
||||
return to;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package ch.usi.inf.sp.cfg;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class Node {
|
||||
|
||||
private final ArrayList<Edge> inEdges;
|
||||
private final ArrayList<Edge> outEdges;
|
||||
|
||||
public Node() {
|
||||
inEdges = new ArrayList<Edge>();
|
||||
outEdges = new ArrayList<Edge>();
|
||||
}
|
||||
|
||||
public void addInEdge(Edge edge) {
|
||||
inEdges.add(edge);
|
||||
}
|
||||
|
||||
public void addOutEdge(Edge edge) {
|
||||
outEdges.add(edge);
|
||||
}
|
||||
|
||||
public List<Edge> getInEdges() {
|
||||
return Collections.unmodifiableList(inEdges);
|
||||
}
|
||||
|
||||
public List<Edge> getOutEdges() {
|
||||
return Collections.unmodifiableList(outEdges);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="module-library" scope="TEST">
|
||||
<library name="JUnit5.2">
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/junit/jupiter/junit-jupiter-api/5.3.1/junit-jupiter-api-5.3.1.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/apiguardian/apiguardian-api/1.0.0/apiguardian-api-1.0.0.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/opentest4j/opentest4j/1.1.1/opentest4j-1.1.1.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/junit/platform/junit-platform-commons/1.3.1/junit-platform-commons-1.3.1.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</orderEntry>
|
||||
<orderEntry type="library" exported="" name="asm-7.1" level="project" />
|
||||
</component>
|
||||
</module>
|
|
@ -0,0 +1,288 @@
|
|||
import java.util.Set;
|
||||
|
||||
|
||||
/**
|
||||
* This class contains a set of methods that are useful for testing
|
||||
* Java disassemblers and control-flow graph generators.
|
||||
*
|
||||
* @author Matthias.Hauswirth@usi.ch
|
||||
*/
|
||||
public class ExampleClass {
|
||||
|
||||
public void emptyMethod() {
|
||||
return;
|
||||
}
|
||||
|
||||
//--- conditionals
|
||||
public int ifMethod(int i) {
|
||||
int j = 0;
|
||||
if (i<0) {
|
||||
j = 1;
|
||||
}
|
||||
return j;
|
||||
}
|
||||
|
||||
public int ifElseMethod(int i) {
|
||||
int j = 0;
|
||||
if (i>0) {
|
||||
j = 0;
|
||||
} else {
|
||||
j = i;
|
||||
}
|
||||
return j;
|
||||
}
|
||||
|
||||
public int switchMethod(int i) {
|
||||
int j = 0;
|
||||
switch (i) {
|
||||
case 0: j = 0; break;
|
||||
case 1: j = 1; break;
|
||||
case 2: j = 2; break;
|
||||
default: j = -1;
|
||||
}
|
||||
return j;
|
||||
}
|
||||
|
||||
public int switchMethod2(int i) {
|
||||
int j = 0;
|
||||
switch (i) {
|
||||
case 0: j = 0; break;
|
||||
case 1000: j = 1; break;
|
||||
case 2000: j = 2; break;
|
||||
default: j = -1;
|
||||
}
|
||||
return j;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//--- loops
|
||||
public int forMethod(int i) {
|
||||
int sum = 0;
|
||||
for (int j=0; j<i; i++) {
|
||||
sum += j;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
public int whileMethod(int i) {
|
||||
int sum = 0;
|
||||
while (i>0) {
|
||||
sum +=i;
|
||||
i--;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
public int doWhileMethod(int i) {
|
||||
int sum = 0;
|
||||
do {
|
||||
sum += i;
|
||||
i--;
|
||||
} while (i>0);
|
||||
return sum;
|
||||
}
|
||||
|
||||
public int forEachArrayMethod(String[] a) {
|
||||
int sum = 0;
|
||||
for (String s : a) {
|
||||
sum++;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
public int forEachCollectionMethod(Set<String> a) {
|
||||
int sum = 0;
|
||||
for (String s : a) {
|
||||
sum++;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
public int forWithBreakMethod(int n) {
|
||||
int sum = 0;
|
||||
for (int i=0; i<n; i++) {
|
||||
if (i==10) {
|
||||
break;
|
||||
}
|
||||
sum += i;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
public int forWithContinueMethod(int n) {
|
||||
int sum = 0;
|
||||
for (int i=0; i<n; i++) {
|
||||
if (i==10) {
|
||||
continue;
|
||||
}
|
||||
sum += i;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
public int whileTrueMethod(int n) {
|
||||
while (true) {
|
||||
n++;
|
||||
}
|
||||
}
|
||||
|
||||
public int doWhileTrue(int n) {
|
||||
do {
|
||||
n++;
|
||||
} while (true);
|
||||
}
|
||||
|
||||
public int forEver(int n) {
|
||||
for (int i=0; true; i++) {
|
||||
}
|
||||
}
|
||||
|
||||
public int nestedFor(int n) {
|
||||
int sum = 0;
|
||||
for (int i=0; i<n; i++) {
|
||||
for (int j=0; j<i; j++) {
|
||||
sum += j;
|
||||
}
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//--- calls
|
||||
public int staticCallMethod(int i) {
|
||||
staticCallTarget();
|
||||
return 2;
|
||||
}
|
||||
|
||||
public int instanceCallMethod(ExampleClass i) {
|
||||
i.instanceCallTarget();
|
||||
return 2;
|
||||
}
|
||||
|
||||
public int privateInstanceCallMethod(ExampleClass i) {
|
||||
i.privateInstanceCallTarget();
|
||||
return 2;
|
||||
}
|
||||
|
||||
public int interfaceCallMethod(Interface i) {
|
||||
i.interfaceCallTarget();
|
||||
return 2;
|
||||
}
|
||||
|
||||
static interface Interface {
|
||||
public void interfaceCallTarget();
|
||||
}
|
||||
|
||||
static class Implementation implements Interface {
|
||||
public void interfaceCallTarget() {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public static void staticCallTarget() {
|
||||
}
|
||||
|
||||
public void instanceCallTarget() {
|
||||
}
|
||||
|
||||
private void privateInstanceCallTarget() {
|
||||
}
|
||||
|
||||
|
||||
|
||||
//--- field and array accesses
|
||||
private String field;
|
||||
|
||||
public String fieldReadMethod() {
|
||||
return field;
|
||||
}
|
||||
|
||||
public void fieldWriteMethod(String s) {
|
||||
field = s;
|
||||
}
|
||||
|
||||
private static String staticField;
|
||||
|
||||
public String staticFieldReadMethod() {
|
||||
return staticField;
|
||||
}
|
||||
|
||||
public void staticFieldWriteMethod(String s) {
|
||||
staticField = s;
|
||||
}
|
||||
|
||||
public int arrayLengthMethod(String[] a) {
|
||||
return a.length;
|
||||
}
|
||||
|
||||
public String arrayReadMethod(String[] a) {
|
||||
return a[0];
|
||||
}
|
||||
|
||||
public void arrayWriteMethod(String[] a, String s) {
|
||||
a[0] = s;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//--- allocation
|
||||
public Object allocObjectMethod() {
|
||||
return new Object();
|
||||
}
|
||||
|
||||
public int[] allocIntArrayMethod() {
|
||||
return new int[3];
|
||||
}
|
||||
|
||||
public Object[] allocObjectArrayMethod() {
|
||||
return new Object[3];
|
||||
}
|
||||
|
||||
public int[][] alloc2dArrayMethod() {
|
||||
return new int[2][3];
|
||||
}
|
||||
|
||||
public int[][] allocIncomplete2dArrayMethod() {
|
||||
return new int[2][];
|
||||
}
|
||||
|
||||
public int[][][] alloc2Of3dArrayMethod() {
|
||||
return new int[2][3][];
|
||||
}
|
||||
|
||||
public int[] allocAndInitIntArrayMethod() {
|
||||
return new int[] {1, 2};
|
||||
}
|
||||
|
||||
public Object[] allocAndInitObjectArrayMethod() {
|
||||
return new Object[] {"1", "2"};
|
||||
}
|
||||
|
||||
public int[][] allocAndInit2dArrayMethod() {
|
||||
return new int[][] {{1}};
|
||||
}
|
||||
|
||||
|
||||
|
||||
//--- more conditionals
|
||||
public int condMethod(int a, int b) {
|
||||
return a>b?a:b;
|
||||
}
|
||||
|
||||
public int shortCircuitMethod(int i, int j, int k) {
|
||||
if (i>j && i<k) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int nonShortCircuitMethod(int i, int j, int k) {
|
||||
if (i>j & i<k) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
// A minimal class, with one "method" (the constructor)
|
||||
public class Mini {
|
||||
|
||||
public Mini() {
|
||||
super();
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# Compile the given Java file for the different versions of Java
|
||||
# E.g., if you use the ASM Viewer plugin for IntelliJ IDEA,
|
||||
# that plugin can't deal with Java 10.
|
||||
# It can read Java class files for older versions of Java, though.
|
||||
# So, here we compile it for all versions of Java supported by the Java 10 javac compiler.
|
||||
CLASS=$1
|
||||
|
||||
VERSIONS=( 6 7 8 9 10 )
|
||||
for VERSION in "${VERSIONS[@]}"
|
||||
do
|
||||
echo Version $VERSION
|
||||
mkdir -p java$VERSION
|
||||
javac -d java$VERSION --release $VERSION $CLASS
|
||||
done
|
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.
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.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,6 @@
|
|||
Method: <init>()V
|
||||
0: // label
|
||||
1: // line number information
|
||||
2: ALOAD 0
|
||||
3: INVOKESPECIAL java/lang/Object.<init> ()V
|
||||
4: RETURN
|
|
@ -0,0 +1,7 @@
|
|||
Method: alloc2Of3dArrayMethod()[[[I
|
||||
0: // label
|
||||
1: // line number information
|
||||
2: ICONST_2
|
||||
3: ICONST_3
|
||||
4: MULTIANEWARRAY [[[I 2
|
||||
5: ARETURN
|
|
@ -0,0 +1,7 @@
|
|||
Method: alloc2dArrayMethod()[[I
|
||||
0: // label
|
||||
1: // line number information
|
||||
2: ICONST_2
|
||||
3: ICONST_3
|
||||
4: MULTIANEWARRAY [[I 2
|
||||
5: ARETURN
|
|
@ -0,0 +1,15 @@
|
|||
Method: allocAndInit2dArrayMethod()[[I
|
||||
0: // label
|
||||
1: // line number information
|
||||
2: ICONST_1
|
||||
3: ANEWARRAY [I
|
||||
4: DUP
|
||||
5: ICONST_0
|
||||
6: ICONST_1
|
||||
7: NEWARRAY T_INT
|
||||
8: DUP
|
||||
9: ICONST_0
|
||||
10: ICONST_1
|
||||
11: IASTORE
|
||||
12: AASTORE
|
||||
13: ARETURN
|
|
@ -0,0 +1,14 @@
|
|||
Method: allocAndInitIntArrayMethod()[I
|
||||
0: // label
|
||||
1: // line number information
|
||||
2: ICONST_2
|
||||
3: NEWARRAY T_INT
|
||||
4: DUP
|
||||
5: ICONST_0
|
||||
6: ICONST_1
|
||||
7: IASTORE
|
||||
8: DUP
|
||||
9: ICONST_1
|
||||
10: ICONST_2
|
||||
11: IASTORE
|
||||
12: ARETURN
|
|
@ -0,0 +1,14 @@
|
|||
Method: allocAndInitObjectArrayMethod()[Ljava/lang/Object;
|
||||
0: // label
|
||||
1: // line number information
|
||||
2: ICONST_2
|
||||
3: ANEWARRAY java/lang/Object
|
||||
4: DUP
|
||||
5: ICONST_0
|
||||
6: LDC 1
|
||||
7: AASTORE
|
||||
8: DUP
|
||||
9: ICONST_1
|
||||
10: LDC 2
|
||||
11: AASTORE
|
||||
12: ARETURN
|
|
@ -0,0 +1,6 @@
|
|||
Method: allocIncomplete2dArrayMethod()[[I
|
||||
0: // label
|
||||
1: // line number information
|
||||
2: ICONST_2
|
||||
3: ANEWARRAY [I
|
||||
4: ARETURN
|
|
@ -0,0 +1,6 @@
|
|||
Method: allocIntArrayMethod()[I
|
||||
0: // label
|
||||
1: // line number information
|
||||
2: ICONST_3
|
||||
3: NEWARRAY T_INT
|
||||
4: ARETURN
|
|
@ -0,0 +1,6 @@
|
|||
Method: allocObjectArrayMethod()[Ljava/lang/Object;
|
||||
0: // label
|
||||
1: // line number information
|
||||
2: ICONST_3
|
||||
3: ANEWARRAY java/lang/Object
|
||||
4: ARETURN
|
|
@ -0,0 +1,7 @@
|
|||
Method: allocObjectMethod()Ljava/lang/Object;
|
||||
0: // label
|
||||
1: // line number information
|
||||
2: NEW java/lang/Object
|
||||
3: DUP
|
||||
4: INVOKESPECIAL java/lang/Object.<init> ()V
|
||||
5: ARETURN
|
|
@ -0,0 +1,6 @@
|
|||
Method: arrayLengthMethod([Ljava/lang/String;)I
|
||||
0: // label
|
||||
1: // line number information
|
||||
2: ALOAD 1
|
||||
3: ARRAYLENGTH
|
||||
4: IRETURN
|
|
@ -0,0 +1,7 @@
|
|||
Method: arrayReadMethod([Ljava/lang/String;)Ljava/lang/String;
|
||||
0: // label
|
||||
1: // line number information
|
||||
2: ALOAD 1
|
||||
3: ICONST_0
|
||||
4: AALOAD
|
||||
5: ARETURN
|
|
@ -0,0 +1,10 @@
|
|||
Method: arrayWriteMethod([Ljava/lang/String;Ljava/lang/String;)V
|
||||
0: // label
|
||||
1: // line number information
|
||||
2: ALOAD 1
|
||||
3: ICONST_0
|
||||
4: ALOAD 2
|
||||
5: AASTORE
|
||||
6: // label
|
||||
7: // line number information
|
||||
8: RETURN
|
|
@ -0,0 +1,14 @@
|
|||
Method: condMethod(II)I
|
||||
0: // label
|
||||
1: // line number information
|
||||
2: ILOAD 1
|
||||
3: ILOAD 2
|
||||
4: IF_ICMPLE 7
|
||||
5: ILOAD 1
|
||||
6: GOTO 10
|
||||
7: // label
|
||||
8: // stack frame map
|
||||
9: ILOAD 2
|
||||
10: // label
|
||||
11: // stack frame map
|
||||
12: IRETURN
|
|
@ -0,0 +1,23 @@
|
|||
Method: doWhileMethod(I)I
|
||||
0: // label
|
||||
1: // line number information
|
||||
2: ICONST_0
|
||||
3: ISTORE 2
|
||||
4: // label
|
||||
5: // line number information
|
||||
6: // stack frame map
|
||||
7: ILOAD 2
|
||||
8: ILOAD 1
|
||||
9: IADD
|
||||
10: ISTORE 2
|
||||
11: // label
|
||||
12: // line number information
|
||||
13: IINC 1 -1
|
||||
14: // label
|
||||
15: // line number information
|
||||
16: ILOAD 1
|
||||
17: IFGT 4
|
||||
18: // label
|
||||
19: // line number information
|
||||
20: ILOAD 2
|
||||
21: IRETURN
|
|
@ -0,0 +1,8 @@
|
|||
Method: doWhileTrue(I)I
|
||||
0: // label
|
||||
1: // line number information
|
||||
2: // stack frame map
|
||||
3: IINC 1 1
|
||||
4: // label
|
||||
5: // line number information
|
||||
6: GOTO 0
|
|
@ -0,0 +1,4 @@
|
|||
Method: emptyMethod()V
|
||||
0: // label
|
||||
1: // line number information
|
||||
2: RETURN
|
|
@ -0,0 +1,6 @@
|
|||
Method: fieldReadMethod()Ljava/lang/String;
|
||||
0: // label
|
||||
1: // line number information
|
||||
2: ALOAD 0
|
||||
3: GETFIELD ExampleClass.field Ljava/lang/String;
|
||||
4: ARETURN
|
|
@ -0,0 +1,9 @@
|
|||
Method: fieldWriteMethod(Ljava/lang/String;)V
|
||||
0: // label
|
||||
1: // line number information
|
||||
2: ALOAD 0
|
||||
3: ALOAD 1
|
||||
4: PUTFIELD ExampleClass.field Ljava/lang/String;
|
||||
5: // label
|
||||
6: // line number information
|
||||
7: RETURN
|
|
@ -0,0 +1,35 @@
|
|||
Method: forEachArrayMethod([Ljava/lang/String;)I
|
||||
0: // label
|
||||
1: // line number information
|
||||
2: ICONST_0
|
||||
3: ISTORE 2
|
||||
4: // label
|
||||
5: // line number information
|
||||
6: ALOAD 1
|
||||
7: ASTORE 3
|
||||
8: ALOAD 3
|
||||
9: ARRAYLENGTH
|
||||
10: ISTORE 4
|
||||
11: ICONST_0
|
||||
12: ISTORE 5
|
||||
13: // label
|
||||
14: // stack frame map
|
||||
15: ILOAD 5
|
||||
16: ILOAD 4
|
||||
17: IF_ICMPGE 29
|
||||
18: ALOAD 3
|
||||
19: ILOAD 5
|
||||
20: AALOAD
|
||||
21: ASTORE 6
|
||||
22: // label
|
||||
23: // line number information
|
||||
24: IINC 2 1
|
||||
25: // label
|
||||
26: // line number information
|
||||
27: IINC 5 1
|
||||
28: GOTO 13
|
||||
29: // label
|
||||
30: // line number information
|
||||
31: // stack frame map
|
||||
32: ILOAD 2
|
||||
33: IRETURN
|
|
@ -0,0 +1,30 @@
|
|||
Method: forEachCollectionMethod(Ljava/util/Set;)I
|
||||
0: // label
|
||||
1: // line number information
|
||||
2: ICONST_0
|
||||
3: ISTORE 2
|
||||
4: // label
|
||||
5: // line number information
|
||||
6: ALOAD 1
|
||||
7: INVOKEINTERFACE java/util/Set.iterator ()Ljava/util/Iterator;
|
||||
8: ASTORE 3
|
||||
9: // label
|
||||
10: // stack frame map
|
||||
11: ALOAD 3
|
||||
12: INVOKEINTERFACE java/util/Iterator.hasNext ()Z
|
||||
13: IFEQ 24
|
||||
14: ALOAD 3
|
||||
15: INVOKEINTERFACE java/util/Iterator.next ()Ljava/lang/Object;
|
||||
16: CHECKCAST java/lang/String
|
||||
17: ASTORE 4
|
||||
18: // label
|
||||
19: // line number information
|
||||
20: IINC 2 1
|
||||
21: // label
|
||||
22: // line number information
|
||||
23: GOTO 9
|
||||
24: // label
|
||||
25: // line number information
|
||||
26: // stack frame map
|
||||
27: ILOAD 2
|
||||
28: IRETURN
|
|
@ -0,0 +1,9 @@
|
|||
Method: forEver(I)I
|
||||
0: // label
|
||||
1: // line number information
|
||||
2: ICONST_0
|
||||
3: ISTORE 2
|
||||
4: // label
|
||||
5: // stack frame map
|
||||
6: IINC 2 1
|
||||
7: GOTO 4
|
|
@ -0,0 +1,29 @@
|
|||
Method: forMethod(I)I
|
||||
0: // label
|
||||
1: // line number information
|
||||
2: ICONST_0
|
||||
3: ISTORE 2
|
||||
4: // label
|
||||
5: // line number information
|
||||
6: ICONST_0
|
||||
7: ISTORE 3
|
||||
8: // label
|
||||
9: // stack frame map
|
||||
10: ILOAD 3
|
||||
11: ILOAD 1
|
||||
12: IF_ICMPGE 23
|
||||
13: // label
|
||||
14: // line number information
|
||||
15: ILOAD 2
|
||||
16: ILOAD 3
|
||||
17: IADD
|
||||
18: ISTORE 2
|
||||
19: // label
|
||||
20: // line number information
|
||||
21: IINC 1 1
|
||||
22: GOTO 8
|
||||
23: // label
|
||||
24: // line number information
|
||||
25: // stack frame map
|
||||
26: ILOAD 2
|
||||
27: IRETURN
|
|
@ -0,0 +1,38 @@
|
|||
Method: forWithBreakMethod(I)I
|
||||
0: // label
|
||||
1: // line number information
|
||||
2: ICONST_0
|
||||
3: ISTORE 2
|
||||
4: // label
|
||||
5: // line number information
|
||||
6: ICONST_0
|
||||
7: ISTORE 3
|
||||
8: // label
|
||||
9: // stack frame map
|
||||
10: ILOAD 3
|
||||
11: ILOAD 1
|
||||
12: IF_ICMPGE 32
|
||||
13: // label
|
||||
14: // line number information
|
||||
15: ILOAD 3
|
||||
16: BIPUSH 10
|
||||
17: IF_ICMPNE 21
|
||||
18: // label
|
||||
19: // line number information
|
||||
20: GOTO 32
|
||||
21: // label
|
||||
22: // line number information
|
||||
23: // stack frame map
|
||||
24: ILOAD 2
|
||||
25: ILOAD 3
|
||||
26: IADD
|
||||
27: ISTORE 2
|
||||
28: // label
|
||||
29: // line number information
|
||||
30: IINC 3 1
|
||||
31: GOTO 8
|
||||
32: // label
|
||||
33: // line number information
|
||||
34: // stack frame map
|
||||
35: ILOAD 2
|
||||
36: IRETURN
|
|
@ -0,0 +1,39 @@
|
|||
Method: forWithContinueMethod(I)I
|
||||
0: // label
|
||||
1: // line number information
|
||||
2: ICONST_0
|
||||
3: ISTORE 2
|
||||
4: // label
|
||||
5: // line number information
|
||||
6: ICONST_0
|
||||
7: ISTORE 3
|
||||
8: // label
|
||||
9: // stack frame map
|
||||
10: ILOAD 3
|
||||
11: ILOAD 1
|
||||
12: IF_ICMPGE 33
|
||||
13: // label
|
||||
14: // line number information
|
||||
15: ILOAD 3
|
||||
16: BIPUSH 10
|
||||
17: IF_ICMPNE 21
|
||||
18: // label
|
||||
19: // line number information
|
||||
20: GOTO 28
|
||||
21: // label
|
||||
22: // line number information
|
||||
23: // stack frame map
|
||||
24: ILOAD 2
|
||||
25: ILOAD 3
|
||||
26: IADD
|
||||
27: ISTORE 2
|
||||
28: // label
|
||||
29: // line number information
|
||||
30: // stack frame map
|
||||
31: IINC 3 1
|
||||
32: GOTO 8
|
||||
33: // label
|
||||
34: // line number information
|
||||
35: // stack frame map
|
||||
36: ILOAD 2
|
||||
37: IRETURN
|
|
@ -0,0 +1,24 @@
|
|||
Method: ifElseMethod(I)I
|
||||
0: // label
|
||||
1: // line number information
|
||||
2: ICONST_0
|
||||
3: ISTORE 2
|
||||
4: // label
|
||||
5: // line number information
|
||||
6: ILOAD 1
|
||||
7: IFLE 13
|
||||
8: // label
|
||||
9: // line number information
|
||||
10: ICONST_0
|
||||
11: ISTORE 2
|
||||
12: GOTO 18
|
||||
13: // label
|
||||
14: // line number information
|
||||
15: // stack frame map
|
||||
16: ILOAD 1
|
||||
17: ISTORE 2
|
||||
18: // label
|
||||
19: // line number information
|
||||
20: // stack frame map
|
||||
21: ILOAD 2
|
||||
22: IRETURN
|
|
@ -0,0 +1,18 @@
|
|||
Method: ifMethod(I)I
|
||||
0: // label
|
||||
1: // line number information
|
||||
2: ICONST_0
|
||||
3: ISTORE 2
|
||||
4: // label
|
||||
5: // line number information
|
||||
6: ILOAD 1
|
||||
7: IFGE 12
|
||||
8: // label
|
||||
9: // line number information
|
||||
10: ICONST_1
|
||||
11: ISTORE 2
|
||||
12: // label
|
||||
13: // line number information
|
||||
14: // stack frame map
|
||||
15: ILOAD 2
|
||||
16: IRETURN
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue