Author: kohsuke
Date: Wed Dec 28 11:54:05 2005
New Revision: 359611

URL: http://svn.apache.org/viewcvs?rev=359611&view=rev
Log:
simplified the traversal code.

still trying to fix the JSR/RET issue, but I think I'm getting to the core.

Modified:
    
jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/analyser/Subroutines.java

Modified: 
jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/analyser/Subroutines.java
URL: 
http://svn.apache.org/viewcvs/jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/analyser/Subroutines.java?rev=359611&r1=359610&r2=359611&view=diff
==============================================================================
--- 
jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/analyser/Subroutines.java
 (original)
+++ 
jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/analyser/Subroutines.java
 Wed Dec 28 11:54:05 2005
@@ -15,12 +15,6 @@
  */
 package org.apache.commons.javaflow.bytecode.transformation.bcel.analyser;
 
-import java.awt.Color;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.Hashtable;
-import java.util.Iterator;
-
 import org.apache.bcel.generic.ASTORE;
 import org.apache.bcel.generic.ATHROW;
 import org.apache.bcel.generic.BranchInstruction;
@@ -38,6 +32,12 @@
 import org.apache.bcel.verifier.exc.AssertionViolatedException;
 import org.apache.bcel.verifier.exc.StructuralCodeConstraintException;
 
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Set;
+
 /**
  * Instances of this class contain information about the subroutines
  * found in a code array of a method.
@@ -85,7 +85,7 @@
                private int localVariable = UNSET;
 
                /** The instructions that belong to this subroutine. */
-               private HashSet instructions = new HashSet(); // Elements: 
InstructionHandle
+               private Set instructions;
                
                /*
                 * Refer to the Subroutine interface for documentation.
@@ -212,18 +212,6 @@
                        return (InstructionHandle[]) instructions.toArray(ret);
                }
                
-               /*
-                * Adds an instruction to this subroutine.
-                * All instructions must have been added before invoking 
setLeavingRET().
-                * @see #setLeavingRET
-                */
-               void addInstruction(InstructionHandle ih){
-                       if (theRET != null){
-                               throw new AssertionViolatedException("All 
instructions must have been added before invoking setLeavingRET().");
-                       }
-                       instructions.add(ih);
-               }
-
                /* Satisfies Subroutine.getRecursivelyAccessedLocalsIndices(). 
*/
                public int[] getRecursivelyAccessedLocalsIndices(){
                        HashSet s = new HashSet();
@@ -338,7 +326,10 @@
                public SubroutineImpl(){
                }
 
-       }// end Inner Class SubrouteImpl
+        void setInstructions(Set _instructions) {
+            this.instructions = _instructions;
+        }
+    }// end Inner Class SubrouteImpl
 
        /**
         * The Hashtable containing the subroutines found.
@@ -406,56 +397,46 @@
                // Now do a BFS from every subroutine leader to find all the
                // instructions that belong to a subroutine.
                HashSet instructions_assigned = new HashSet(); // we don't want 
to assign an instruction to two or more Subroutine objects.
-               
-               Hashtable colors = new Hashtable(); //Graph colouring. Key: 
InstructionHandle, Value: java.awt.Color .
-               
-               iter = sub_leaders.iterator();
+
+        iter = sub_leaders.iterator();
                while (iter.hasNext()){
-                       // Do some BFS with "actual" as the root of the graph.
-                       InstructionHandle actual = (InstructionHandle) 
(iter.next());
-                       // Init colors
-                       for (int i=0; i<all.length; i++){
-                               colors.put(all[i], Color.white);
-                       }
-                       colors.put(actual, Color.gray);
+            // set of InstructionHandles reachable from the top
+            Set closure = new HashSet();
+
+                       // Do a BFS with "actual" as the root of the graph.
+            InstructionHandle actual = (InstructionHandle) (iter.next());
                        // Init Queue
                        ArrayList Q = new ArrayList();
                        Q.add(actual); // add(Obj) adds to the end, remove(0) 
removes from the start.
-                       
-                       /* BFS ALGORITHM MODIFICATION: Start out with multiple 
"root" nodes, as exception handlers are starting points of top-level code, too. 
[why top-level? TODO: Refer to the special JustIce notion of subroutines.]*/
+
+            /* BFS ALGORITHM MODIFICATION: Start out with multiple "root" 
nodes, as exception handlers are starting points of top-level code, too. [why 
top-level? TODO: Refer to the special JustIce notion of subroutines.]*/
                        if (actual == all[0]){
                                for (int j=0; j<handlers.length; j++){
-                                       colors.put(handlers[j].getHandlerPC(), 
Color.gray);
                                        Q.add(handlers[j].getHandlerPC());
                                }
                        }
                        /* CONTINUE NORMAL BFS ALGORITHM */
                        
-                       // Loop until Queue is empty
-                       while (Q.size() != 0){
+                       while (!Q.isEmpty()){
                                InstructionHandle u = (InstructionHandle) 
Q.remove(0);
-                               InstructionHandle[] successors = 
getSuccessors(u);
-                               for (int i=0; i<successors.length; i++){
-                                       if (((Color) colors.get(successors[i])) 
== Color.white){
-                                               colors.put(successors[i], 
Color.gray);
-                                               Q.add(successors[i]);
-                                       }
-                               }
-                               colors.put(u, Color.black);
-                       }
+                if(closure.add(u)) {
+                    InstructionHandle[] successors = getSuccessors(u);
+                    for (int i=0; i<successors.length; i++){
+                        Q.add(successors[i]);
+                    }
+                }
+            }
                        // BFS ended above.
-                       for (int i=0; i<all.length; i++){
-                               if (colors.get(all[i]) == Color.black){
-                                       ((SubroutineImpl) 
(actual==all[0]?getTopLevel():getSubroutine(actual))).addInstruction(all[i]);
-                                       if 
(instructions_assigned.contains(all[i])){
-                                               //throw new 
StructuralCodeConstraintException("Instruction '"+all[i]+"' is part of more 
than one subroutine (or of the top level and a subroutine).");
-                                       }
-                                       else{
-                                               
instructions_assigned.add(all[i]);
-                                       }
-                               }
-                       }
-                       if (actual != all[0]){// If we don't deal with the 
top-level 'subroutine'
+            ((SubroutineImpl) 
(actual==all[0]?getTopLevel():getSubroutine(actual))).setInstructions(closure);
+
+            for (Iterator itr = closure.iterator(); itr.hasNext();) {
+                InstructionHandle h = (InstructionHandle) itr.next();
+                if(!instructions_assigned.add(h)) {
+                    throw new StructuralCodeConstraintException("Instruction 
'"+h+"' is part of more than one subroutine (or of the top level and a 
subroutine).");
+                }
+            }
+            
+            if (actual != all[0]){// If we don't deal with the top-level 
'subroutine'
                                ((SubroutineImpl) 
getSubroutine(actual)).setLeavingRET();
                        }
                }



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to