done part of graph building code

This commit is contained in:
Claudio Maggioni 2023-10-09 17:30:03 +02:00
parent 61202b8db3
commit e64edeecbe
6 changed files with 157 additions and 15 deletions

6
.idea/jpa-buddy.xml Normal file
View 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>

View file

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

View file

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

View file

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

View file

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