1 26 27 package net.sourceforge.groboutils.codecoverage.v2.compiler; 28 29 import java.util.ArrayList ; 30 import java.util.Iterator ; 31 import java.util.List ; 32 33 import org.apache.bcel.generic.InstructionHandle; 34 import org.apache.bcel.generic.InstructionList; 35 36 49 public class ModifiedInstructionList 50 { 51 private static final org.apache.log4j.Logger LOG = 52 org.apache.log4j.Logger.getLogger( ModifiedInstructionList.class ); 53 private boolean closed = false; 54 private InstructionList modList; private List marked; 56 57 60 private int classSigPoolIndex; 61 62 65 private int staticMethodPoolIndex; 66 67 70 private short methodIndex; 71 72 76 private ModifiedTargeters targeters; 77 78 82 ModifiedInstructionList( short methodIndex, int classSigPoolIndex, 83 int staticMethodPoolIndex, InstructionList list, 84 ModifiedTargeters mt ) 85 { 86 if (list == null || mt == null) 87 { 88 throw new IllegalArgumentException ("no null args"); 89 } 90 this.methodIndex = methodIndex; 91 this.classSigPoolIndex = classSigPoolIndex; 92 this.staticMethodPoolIndex = staticMethodPoolIndex; 93 94 if (!isValidInstructionList( list )) 95 { 96 throw new IllegalArgumentException ( "Instruction list contains "+ 97 "unsupported instruction setup." ); 98 } 99 this.modList = list; 100 this.targeters = mt; 101 102 setupMarkList(); 105 } 106 107 108 110 111 public static boolean isValidInstructionList( InstructionList list ) 112 { 113 try 114 { 115 list.getByteCode(); 116 } 117 catch (Exception ex) 118 { 119 return false; 120 } 121 return true; 122 } 123 124 125 126 133 void updateInstructionList() 134 { 135 checkClose(); 136 137 LOG.debug( "********************************" ); 138 Iterator iter = this.marked.iterator(); 139 while (iter.hasNext()) 140 { 141 MarkedInstruction mi = (MarkedInstruction)iter.next(); 142 143 InstructionList list = mi.getMarkedList(); 144 if (list != null && list.getLength() > 0) 145 { 146 InstructionHandle instr = mi.getHandle(); 147 LOG.debug( "Adding list (length = "+list.getLength()+ 148 ", value='"+list+"') before handle '"+instr+"'." ); 149 InstructionHandle probe; 150 if (mi.getInstruction() instanceof NullInstruction) 151 { 152 159 LOG.warn( 160 "Appending probes to end of instructions is no longer allowed" ); 161 } 162 else 163 { 164 LOG.debug( "Inserting probe before ["+instr+"]" ); 167 probe = this.modList.insert( instr, list ); 168 this.targeters.insertProbe( instr, probe ); 169 } 170 } 171 } 172 this.targeters.update(); 173 LOG.debug( "Final modified list = '"+this.modList+"'" ); 174 } 175 176 177 public int getInstructionCount() 178 { 179 checkClose(); 180 181 return this.marked.size() - 1; 183 } 184 185 186 public MarkedInstruction getInstructionAt( int index ) 187 { 188 checkClose(); 189 190 return (MarkedInstruction)this.marked.get( index ); 191 } 192 193 194 void close() 195 { 196 checkClose(); 197 198 this.closed = true; 199 this.modList.dispose(); 200 this.marked = null; 201 this.modList = null; 202 } 203 204 205 207 208 private void setupMarkList() 209 { 210 this.marked = new ArrayList (); 211 Iterator iter = this.modList.iterator(); 213 while (iter.hasNext()) 214 { 215 InstructionHandle ih = (InstructionHandle)iter.next(); 216 this.marked.add( new MarkedInstruction( this.methodIndex, 217 this.classSigPoolIndex, this.staticMethodPoolIndex, ih ) ); 218 } 219 220 InstructionList il = new InstructionList(); 223 InstructionHandle ih = il.append( new NullInstruction() ); 224 this.marked.add( new MarkedInstruction( this.methodIndex, 225 this.classSigPoolIndex, this.staticMethodPoolIndex, ih ) ); 226 } 227 228 229 private void checkClose() 230 { 231 if (this.closed) 232 { 233 throw new IllegalStateException ("Method has been closed."); 234 } 235 } 236 } 237 238 | Popular Tags |