View Javadoc
1 /*** 2 * SMClassLoader - 3 * 4 * This class extends the ClassLoader provided 5 * by the BCEL project. 6 * 7 * It instruments the code loaded with the implementation 8 * of the StateMachine provided here. 9 */ 10 11 package junit.quilt.cover.state; 12 13 import java.io.*; 14 15 import java.net.URL; 16 17 import java.util.Set; 18 import java.util.List; 19 import java.util.ArrayList; 20 import java.util.Map; 21 import java.util.HashMap; 22 import java.util.Iterator; 23 import java.util.Collection; 24 25 // import java.lang.reflect.Constructor; 26 27 import junit.quilt.cover.generic.*; 28 29 import org.apache.bcel.generic.*; 30 import org.apache.bcel.classfile.*; 31 import org.apache.bcel.Constants; 32 33 import org.apache.commons.graph.*; 34 35 public class SMClassLoader 36 extends MethInstClassLoader 37 { 38 private StateMachineRegistry registry = null; 39 40 protectedSMClassLoader( String packages[],/index.html"> SMClassLoader( String packages[], 41 URL path[], 42 ClassLoader parent, 43 StateMachineRegistry registry ) { 44 super( packages, path, parent ); 45 this.registry = registry; 46 } 47 48 public void instrumentPool(InstContext context) 49 { 50 ConstantPoolGen pool = context.getConstantPoolGen(); 51 52 int visitRef 53 = pool.addMethodref( 54 "junit/quilt/cover/state/SimpleStateMachine", 55 "visit", 56 "(I)V"); 57 58 int startRef 59 = pool.addMethodref( 60 "junit/quilt/cover/state/SimpleStateMachine", 61 "start", 62 "()V" ); 63 64 context.put( "visitRef", new Integer( visitRef )); 65 context.put( "startRef", new Integer( startRef )); 66 } 67 68 public void instrumentMethod( InstContext context, 69 ControlFlowGraph cfg ) { 70 ClassGen clazz = context.getClassGen(); 71 72 // Initialize some variables. . . 73 int startRef = ((Integer) context.get("startRef")).intValue(); 74 int visitRef = ((Integer) context.get("visitRef")).intValue(); 75 int fieldVar = cfg.makeNewLocal("MSM", 76 new ObjectType("junit.quilt.cover.state.SimpleStateMachine")); 77 78 int numVertices = cfg.getVertices().size() + 4; 79 SimpleStateMachine ssm = new SimpleStateMachine( clazz.getFileName(), 80 numVertices); 81 int fieldRef = addStaticField( context, 82 new ObjectType("junit.quilt.cover.state.SimpleStateMachine"), 83 ssm); 84 85 // Add Initialization Code 86 junit.quilt.cover.state.InitVertex init = 87 new junit.quilt.cover.state.InitVertex(fieldVar, 88 fieldRef, 89 startRef); 90 91 BlockVertex start = cfg.getStartVertex(); 92 cfg.setStartVertex( init ); 93 94 FlowControlEdge initEdge = 95 getEdgeFactory().makeNormalEdge( init, start ); 96 cfg.addEdge( initEdge ); 97 98 // Add the Visit code 99 Set blockSet = cfg.getVertices(); 100 Vertex blocks[] = (Vertex []) blockSet.toArray( new Vertex[ blockSet.size() ]); 101 102 Map labels = new HashMap(); // BLOCK X INDEX 103 for (short i = 0; i < blocks.length; i++) { 104 BlockVertex bv = (BlockVertex) blocks[i]; 105 if ((bv != cfg.getStartVertex()) && 106 (bv != cfg.getEndVertex())) { 107 labels.put( bv, new Integer( i )); 108 ssm.addState( i, bv ); 109 110 CallVisitVertex cvv = 111 new CallVisitVertex( fieldVar, visitRef, i ); 112 bv.prefixInstructionList( cvv.copyInstructionList() ); 113 114 115 Iterator edges = cfg.getEdges().iterator(); 116 while (edges.hasNext()) { 117 Edge cEdge = (Edge) edges.next(); 118 if (cfg.getSource( cEdge ) == bv) { 119 // Edge leads away. . . 120 Vertex target = cfg.getTarget(cEdge); 121 if (labels.containsKey( target )) { 122 int iTarget = 123 ((Integer) labels.get(target)).intValue(); 124 ssm.addTransition( i, iTarget ); 125 } 126 } else { 127 // Edge leads in . . . 128 Vertex source = cfg.getSource(cEdge); 129 if (labels.containsKey( source )) { 130 int iSource = 131 ((Integer) labels.get(source)).intValue(); 132 ssm.addTransition( iSource, i ); 133 } 134 } 135 } 136 } 137 } 138 139 // Write the StateMachine to the StateMachineRegistry 140 registry.bind( clazz.getClassName(), 141 cfg.getMethodName(), 142 ssm ); 143 } 144 145 }

This page was automatically generated by Maven