Initial commit

This commit is contained in:
github-classroom[bot] 2023-10-09 07:08:58 +00:00 committed by GitHub
commit 61202b8db3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
124 changed files with 2517 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
# Project exclude paths
/out/

2
.idea/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
# Default ignored files
/workspace.xml

View File

@ -0,0 +1,5 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
</state>
</component>

View File

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

View File

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

10
.idea/misc.xml Normal file
View File

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

8
.idea/modules.xml Normal file
View File

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

View File

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

View File

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

View File

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

124
.idea/uiDesigner.xml Normal file
View File

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

6
.idea/vcs.xml Normal file
View File

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

31
README.md Normal file
View File

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

BIN
lib/asm-7.1-javadoc.jar Normal file

Binary file not shown.

BIN
lib/asm-7.1-sources.jar Normal file

Binary file not shown.

BIN
lib/asm-7.1.jar Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
lib/asm-tree-7.1.jar Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
lib/asm-util-7.1.jar Normal file

Binary file not shown.

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

9
test-input/Mini.java Normal file
View File

@ -0,0 +1,9 @@
// A minimal class, with one "method" (the constructor)
public class Mini {
public Mini() {
super();
return;
}
}

16
test-input/compile-example.sh Executable file
View File

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

BIN
test-input/java6/Mini.class Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
test-input/java7/Mini.class Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
test-input/java8/Mini.class Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
test-input/java9/Mini.class Normal file

Binary file not shown.

View File

@ -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
test-output/<init>.dot Normal file
View File

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,6 @@
Method: allocIncomplete2dArrayMethod()[[I
0: // label
1: // line number information
2: ICONST_2
3: ANEWARRAY [I
4: ARETURN

View File

@ -0,0 +1,6 @@
Method: allocIntArrayMethod()[I
0: // label
1: // line number information
2: ICONST_3
3: NEWARRAY T_INT
4: ARETURN

View File

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

View File

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

View File

@ -0,0 +1,6 @@
Method: arrayLengthMethod([Ljava/lang/String;)I
0: // label
1: // line number information
2: ALOAD 1
3: ARRAYLENGTH
4: IRETURN

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,4 @@
Method: emptyMethod()V
0: // label
1: // line number information
2: RETURN

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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