diff --git a/.idea/jpa-buddy.xml b/.idea/jpa-buddy.xml
new file mode 100644
index 0000000..966d5f5
--- /dev/null
+++ b/.idea/jpa-buddy.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 49a9bf2..ad4a026 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -4,7 +4,10 @@
-
+
+
+
+
\ No newline at end of file
diff --git a/README.md b/README.md
index fe7621a..35a6e6d 100644
--- a/README.md
+++ b/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
diff --git a/lab-3-maggicl.iml b/lab-3-maggicl.iml
new file mode 100644
index 0000000..2663f31
--- /dev/null
+++ b/lab-3-maggicl.iml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/ch/usi/inf/sp/cfg/ControlFlowGraphBuilder.java b/src/ch/usi/inf/sp/cfg/ControlFlowGraphBuilder.java
index 9579528..4806b89 100644
--- a/src/ch/usi/inf/sp/cfg/ControlFlowGraphBuilder.java
+++ b/src/ch/usi/inf/sp/cfg/ControlFlowGraphBuilder.java
@@ -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 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 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;
+ }
}
}
diff --git a/starter-lab-03-control-flow-graph.iml b/starter-lab-03-control-flow-graph.iml
index 4f0d2e5..f4c6023 100644
--- a/starter-lab-03-control-flow-graph.iml
+++ b/starter-lab-03-control-flow-graph.iml
@@ -21,5 +21,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file