From 75af837a166d5413f341178e6c32c04aae63761d Mon Sep 17 00:00:00 2001
From: Vincent Rasquier <vrasquier@keley-live.com>
Date: Fri, 15 Dec 2017 11:51:20 +0100
Subject: [PATCH] Progress on edge and label + README

---
 README.md    |  5 +++--
 asm/edge.go  |  4 ++++
 asm/label.go | 38 +++++++++++++++++++++++++++++---------
 3 files changed, 36 insertions(+), 11 deletions(-)

diff --git a/README.md b/README.md
index c8b7241..944e004 100644
--- a/README.md
+++ b/README.md
@@ -13,7 +13,7 @@ Second reason could be to provide different tools for JVM manipulation through G
 
 | CLASS | PROGRESS % |
 | ----- | ---------- |
-| ClassReader | 60% |
+| ClassReader | 70% |
 | ClassVisitor | 100% |
 | MethodVisitor | 100% |
 | FieldVisitor | 100% |
@@ -22,8 +22,9 @@ Second reason could be to provide different tools for JVM manipulation through G
 | Handle | 100% |
 | Attribute | ? |
 | Context | ? |
-| Label | 80% |
+| Label | 90% |
 | TypeReference | ? |
 | Opcodes | ? |
 | Symbol | ? |
 | TypePath | 0% |
+| EDGE | 80% |
diff --git a/asm/edge.go b/asm/edge.go
index 3414e20..1547ef4 100644
--- a/asm/edge.go
+++ b/asm/edge.go
@@ -15,3 +15,7 @@ type Edge struct {
 	successor *Label
 	nextEdge  *Edge
 }
+
+func NewEdge(info int, successor *Label, nextEdge *Edge) *Edge {
+	return &Edge{info, successor, nextEdge}
+}
diff --git a/asm/label.go b/asm/label.go
index 6b78e90..af4ebad 100644
--- a/asm/label.go
+++ b/asm/label.go
@@ -137,22 +137,42 @@ func (l *Label) resolve(code []byte, bytecodeOffset int) bool {
 	return hasAsmInstructions
 }
 
-func (l *Label) markSubroutine(subroutineId int, numSubroutine int) {
+func (l *Label) markSubroutine(subroutineID int, numSubroutine int) {
 	listOfBlocksToProcess := l
 	listOfBlocksToProcess.nextListElement = EMPTY_LIST
 	for listOfBlocksToProcess != EMPTY_LIST {
 		basicBlock := listOfBlocksToProcess
 		listOfBlocksToProcess = listOfBlocksToProcess.nextListElement
 		basicBlock.nextListElement = nil
-		if !basicBlock.isInSubroutine(subroutineId) {
-			basicBlock.addToSubroutine(subroutineId, numSubroutine)
+		if !basicBlock.isInSubroutine(subroutineID) {
+			basicBlock.addToSubroutine(subroutineID, numSubroutine)
 			listOfBlocksToProcess = basicBlock.pushSuccessors(listOfBlocksToProcess)
 		}
 	}
 }
 
-func (l Label) addSubroutineRetSuccessors(subroutineCaller *Label, numSubroutine int) {
-	//TODO
+func (l *Label) addSubroutineRetSuccessors(subroutineCaller *Label, numSubroutine int) {
+	listOfProcessedBlocks := EMPTY_LIST
+	listOfBlocksToProcess := l
+	listOfBlocksToProcess.nextListElement = EMPTY_LIST
+	for listOfBlocksToProcess != EMPTY_LIST {
+		basicBlock := listOfBlocksToProcess
+		listOfBlocksToProcess = basicBlock.nextListElement
+		basicBlock.nextListElement = listOfProcessedBlocks
+		listOfProcessedBlocks = basicBlock
+
+		if (basicBlock.flags&FLAG_SUBROUTINE_END) != 0 && !basicBlock.isInSameSubroutine(subroutineCaller) {
+			basicBlock.outgoingEdges = NewEdge(int(basicBlock.outputStackSize), subroutineCaller.outgoingEdges.successor, basicBlock.outgoingEdges)
+		}
+
+		listOfBlocksToProcess = basicBlock.pushSuccessors(listOfBlocksToProcess)
+	}
+
+	for listOfProcessedBlocks != EMPTY_LIST {
+		nextListElement := listOfProcessedBlocks.nextListElement
+		listOfProcessedBlocks.nextListElement = nil
+		listOfProcessedBlocks = nextListElement
+	}
 }
 
 func (l *Label) pushSuccessors(listOfLabelsToProcess *Label) *Label {
@@ -170,9 +190,9 @@ func (l *Label) pushSuccessors(listOfLabelsToProcess *Label) *Label {
 	return listOfLabelsToProcess
 }
 
-func (l Label) isInSubroutine(subroutineId int) bool {
+func (l Label) isInSubroutine(subroutineID int) bool {
 	if (l.flags & FLAG_SUBROUTINE_BODY) != 0 {
-		return (l.values[subroutineId/32] & (1 << (uint(subroutineId) % 32))) != 0
+		return (l.values[subroutineID/32] & (1 << (uint(subroutineID) % 32))) != 0
 	}
 	return false
 }
@@ -189,10 +209,10 @@ func (l Label) isInSameSubroutine(basicBlock *Label) bool {
 	return false
 }
 
-func (l *Label) addToSubroutine(subroutineId int, numSubroutine int) {
+func (l *Label) addToSubroutine(subroutineID int, numSubroutine int) {
 	if (l.flags & FLAG_SUBROUTINE_BODY) == 0 {
 		l.flags |= FLAG_SUBROUTINE_BODY
 		l.values = make([]int, numSubroutine/32+1)
 	}
-	l.values[subroutineId/32] |= (1 << (uint(subroutineId) % 32))
+	l.values[subroutineID/32] |= (1 << (uint(subroutineID) % 32))
 }