done part of graph building code
This commit is contained in:
parent
61202b8db3
commit
e64edeecbe
6 changed files with 157 additions and 15 deletions
6
.idea/jpa-buddy.xml
Normal file
6
.idea/jpa-buddy.xml
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="JpaBuddyIdeaProjectConfig">
|
||||
<option name="renamerInitialized" value="true" />
|
||||
</component>
|
||||
</project>
|
|
@ -4,7 +4,10 @@
|
|||
<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">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="17" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
<component name="ProjectType">
|
||||
<option name="id" value="jpab" />
|
||||
</component>
|
||||
</project>
|
22
README.md
22
README.md
|
@ -6,26 +6,26 @@ Go to [this Lab on iCorsi](https://www.icorsi.ch/course/view.php?id=16963).
|
|||
|
||||
## Submission Info
|
||||
|
||||
Property | Value
|
||||
------------ | -------------
|
||||
First Name | ...
|
||||
Last Name | ...
|
||||
| Property | Value |
|
||||
|------------|----------|
|
||||
| First Name | Claudio |
|
||||
| Last Name | Maggioni |
|
||||
|
||||
## 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)
|
||||
- [x] I completed the above Submission Info
|
||||
- [x] 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 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
|
||||
|
|
16
lab-3-maggicl.iml
Normal file
16
lab-3-maggicl.iml
Normal file
|
@ -0,0 +1,16 @@
|
|||
<?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" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/test-input" isTestSource="false" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="lib" level="project" />
|
||||
<orderEntry type="library" name="lib1" level="project" />
|
||||
<orderEntry type="library" name="asm-6.2.1" level="project" />
|
||||
</component>
|
||||
</module>
|
|
@ -1,6 +1,6 @@
|
|||
package ch.usi.inf.sp.cfg;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
import ch.usi.inf.sp.bytecode.Disassembler;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
@ -16,8 +16,99 @@ import org.objectweb.asm.tree.TableSwitchInsnNode;
|
|||
public class ControlFlowGraphBuilder {
|
||||
|
||||
public static ControlFlowGraph createControlFlowGraph(final MethodNode method) {
|
||||
//TODO
|
||||
return null;
|
||||
final Map<LabelNode, Edge> labelToSource = new HashMap<>();
|
||||
|
||||
// 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);
|
||||
|
||||
switch (instruction.getType()) {
|
||||
case AbstractInsnNode.JUMP_INSN:
|
||||
final JumpInsnNode jumpInsn = (JumpInsnNode) instruction;
|
||||
labelToSource.put(jumpInsn.label, new Edge(instruction, "T"));
|
||||
|
||||
case AbstractInsnNode.LOOKUPSWITCH_INSN:
|
||||
final LookupSwitchInsnNode lookupSwitchInsnNode = (LookupSwitchInsnNode) instruction;
|
||||
for (int j = 0; j < lookupSwitchInsnNode.labels.size(); j++) {
|
||||
final LabelNode label = lookupSwitchInsnNode.labels.get(i);
|
||||
final String value = lookupSwitchInsnNode.keys.get(i).toString();
|
||||
labelToSource.put(label, new Edge(instruction, value));
|
||||
}
|
||||
if (lookupSwitchInsnNode.dflt != null)
|
||||
labelToSource.put(lookupSwitchInsnNode.dflt, new Edge(instruction, "default"));
|
||||
|
||||
case AbstractInsnNode.TABLESWITCH_INSN:
|
||||
final TableSwitchInsnNode tableSwitchInsnNode = (TableSwitchInsnNode) instruction;
|
||||
for (int k = 0; k < tableSwitchInsnNode.labels.size(); k++) {
|
||||
final LabelNode label = tableSwitchInsnNode.labels.get(i);
|
||||
final String value = Integer.toString(tableSwitchInsnNode.min + k);
|
||||
labelToSource.put(label, new Edge(instruction, value));
|
||||
}
|
||||
if (tableSwitchInsnNode.dflt != null)
|
||||
labelToSource.put(tableSwitchInsnNode.dflt, new Edge(instruction, "default"));
|
||||
}
|
||||
}
|
||||
|
||||
final ControlFlowGraph graph = new ControlFlowGraph();
|
||||
final Map<Integer, BasicBlock> blocksById = new HashMap<>();
|
||||
|
||||
BasicBlock currentBasicBlock = new BasicBlock(0);
|
||||
graph.addNode(currentBasicBlock);
|
||||
blocksById.put(0, currentBasicBlock);
|
||||
|
||||
graph.addEntryEdge(currentBasicBlock);
|
||||
|
||||
for (int i = 0; i < instructions.size(); i++) {
|
||||
final AbstractInsnNode instruction = instructions.get(i);
|
||||
final int opcode = instruction.getOpcode();
|
||||
final int type = instruction.getType();
|
||||
|
||||
currentBasicBlock.appendInstruction(Disassembler.disassembleInstruction(instruction, i, instructions));
|
||||
|
||||
if (opcode == Opcodes.RETURN
|
||||
|| opcode == Opcodes.ARETURN
|
||||
|| opcode == Opcodes.LRETURN
|
||||
|| opcode == Opcodes.IRETURN
|
||||
|| opcode == Opcodes.FRETURN) {
|
||||
graph.addExitEdge(currentBasicBlock);
|
||||
}
|
||||
|
||||
if (type == AbstractInsnNode.JUMP_INSN
|
||||
|| type == AbstractInsnNode.LOOKUPSWITCH_INSN
|
||||
|| type == AbstractInsnNode.TABLESWITCH_INSN
|
||||
|| labelToSource.containsKey(instruction)) {
|
||||
final int nextI = i + 1;
|
||||
|
||||
// if we're not at the end
|
||||
if (nextI < instructions.size()) {
|
||||
final BasicBlock previousBasicBlock = currentBasicBlock;
|
||||
|
||||
currentBasicBlock = new BasicBlock(nextI);
|
||||
graph.addNode(currentBasicBlock);
|
||||
blocksById.put(nextI, currentBasicBlock);
|
||||
|
||||
// Handle "implicit" edges from this basic block to the next one, or the exit node
|
||||
if (instructions.get(nextI).getOpcode() != Opcodes.GOTO) {
|
||||
graph.addFallthroughEdge(previousBasicBlock, currentBasicBlock);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: add remaining branching edges and refactor code
|
||||
|
||||
return graph;
|
||||
}
|
||||
|
||||
private static class Edge {
|
||||
final AbstractInsnNode instruction;
|
||||
final String condition;
|
||||
|
||||
Edge(AbstractInsnNode instruction, String condition) {
|
||||
this.instruction = instruction;
|
||||
this.condition = condition;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -21,5 +21,31 @@
|
|||
</library>
|
||||
</orderEntry>
|
||||
<orderEntry type="library" exported="" name="asm-7.1" level="project" />
|
||||
<orderEntry type="module-library" scope="TEST">
|
||||
<library name="JUnit4">
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/junit/junit/4.13.1/junit-4.13.1.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</orderEntry>
|
||||
<orderEntry type="module-library" exported="" scope="TEST">
|
||||
<library name="JUnit5.8.1">
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/junit/jupiter/junit-jupiter/5.8.1/junit-jupiter-5.8.1.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/junit/jupiter/junit-jupiter-api/5.8.1/junit-jupiter-api-5.8.1.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/opentest4j/opentest4j/1.2.0/opentest4j-1.2.0.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/junit/platform/junit-platform-commons/1.8.1/junit-platform-commons-1.8.1.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/apiguardian/apiguardian-api/1.1.2/apiguardian-api-1.1.2.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/junit/jupiter/junit-jupiter-params/5.8.1/junit-jupiter-params-5.8.1.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/junit/jupiter/junit-jupiter-engine/5.8.1/junit-jupiter-engine-5.8.1.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/junit/platform/junit-platform-engine/1.8.1/junit-platform-engine-1.8.1.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</orderEntry>
|
||||
</component>
|
||||
</module>
|
Reference in a new issue