1 5 package de.uka.ipd.coverage.utils; 6 7 8 import java.io.*; 9 import java.util.*; 10 11 import org.apache.bcel.classfile.*; 12 import org.apache.bcel.generic.*; 13 14 20 public class ByteCodePrinter { 21 22 private static SafeStringArray sourcecode = new SafeStringArray(); 23 private JavaClass jclass; 24 25 public ByteCodePrinter(JavaClass jclass) { 26 this.jclass = jclass; 27 sourcecode.setStringArray(openSource(jclass)); 28 } 29 30 37 public void printBytecode() { 38 printBytecode(System.out); 39 } 40 41 public void printBytecode(PrintStream out, boolean indicateBranches) { 42 Method[] methods = jclass.getMethods(); 43 for (int i = 0; i < methods.length; i++) { 44 printBytecode(out, methods[i], indicateBranches); 45 } 46 } 47 48 public void printBytecode(PrintStream out) { 49 printBytecode(out, true); 50 } 51 52 public void printBytecode(PrintStream out, Method method, boolean indicateBranches) { 53 StringBuffer sb = new StringBuffer (); 54 sb.append("\n\nKlasse: " + jclass.getClassName() + " Source: " + jclass.getSourceFileName()); sb.append("\nMethode: " + method.getName() + ":"); Code code = method.getCode(); 57 printByteCode(out, sb.toString(), code, indicateBranches, true); 58 } 59 60 69 private static String createOutputLine(boolean indicateBranches, 70 boolean showPositions, 71 SafeStringArray sourcecode, Code code, int lastsourceline, 72 InstructionHandle element, int pos, int sourceLine) { 73 List outputParams = createOutputParams(sourcecode, 74 code, 75 lastsourceline, 76 element, 77 pos, 78 sourceLine); 79 String outputString = null; 80 if (indicateBranches) { 81 String branchIndicator = getBranchIndicatorString(element); 82 outputParams.add(branchIndicator); 83 assert outputParams.size() == 5; outputString = "[{0}(PC):{1}(Source)]\t| {2:45}| {4:9}| {3}"; } else if (showPositions) { 86 assert outputParams.size() == 4; outputString = "[{0}(PC):{1}(Source)]\t| {2:35}| {3}"; } else { 89 outputString = "{0}: {2}"; } 92 String output = StringFormatter.format( 93 outputString, 94 outputParams.toArray(new String [outputParams.size()]) 95 ); 96 return output; 97 } 98 99 102 private static String getBranchIndicatorString(InstructionHandle element) { 103 String branchIndicator = ""; if (element.getInstruction() instanceof BranchInstruction) { 105 branchIndicator = "branch"; } else if (element.getInstruction() instanceof ReturnInstruction) { 107 branchIndicator = "return"; } 109 return branchIndicator; 110 } 111 112 120 private static List createOutputParams(SafeStringArray sourcecode, 121 Code code, int lastsourceline, InstructionHandle element, 122 int pos, int sourceLine) { 123 List outputParams = new ArrayList(); 124 outputParams.add("" + pos); outputParams.add("" + sourceLine); outputParams.add(element.getInstruction().toString( 127 code.getConstantPool())); 128 if (sourceLine == lastsourceline) { 129 outputParams.add(""); } else { 131 outputParams.add(sourcecode.getString(sourceLine - 1).trim()); 132 } 133 return outputParams; 134 } 135 136 143 public static int getCorrespondingSourceLine(LineNumber[] lineNumbers, int pos) { 144 if (lineNumbers != null && lineNumbers.length > 0) { 145 int i = 0; 146 LineNumber largestSmallerNumber = null; 147 while (i < lineNumbers.length && lineNumbers[i].getStartPC() <= pos) { 148 largestSmallerNumber = lineNumbers[i]; 149 i++; 150 } 151 if (largestSmallerNumber != null) { 152 return largestSmallerNumber.getLineNumber(); 153 } 154 } 155 return Integer.MIN_VALUE; 156 } 157 158 166 public static String [] openSource(JavaClass javaClass) { 167 String javaPath = javaClass.getPackageName().replaceAll("\\.", File.separator); 169 String javaSource = "src" + File.separator+ javaPath + File.separator + javaClass.getSourceFileName(); 171 172 File file = new File(javaSource); 173 List lineList = new LinkedList(); 174 LineNumberReader reader = null; 175 try { 176 reader = new LineNumberReader(new FileReader(file)); 177 } catch (FileNotFoundException e) { 178 Logger.getInstance().info("File " + javaSource + " could not be found"); return generateErrorResult(javaClass); 180 } 181 String line = null; 182 try { 183 while ((line = reader.readLine()) != null) { 184 lineList.add(line); 185 } 186 } catch (IOException e1) { 187 e1.printStackTrace(); 188 } 189 return (String []) lineList.toArray(new String [lineList.size()]); 190 } 191 192 196 private static String [] generateErrorResult(JavaClass javaClass) { 197 Method[] methods = javaClass.getMethods(); 198 int maxLineNumber = 0; 199 for (int i = 0; i < methods.length; i++) { 200 LineNumberTable table = methods[i].getLineNumberTable(); 201 if (table != null) { 202 LineNumber[] linenumbers = table.getLineNumberTable(); 203 for (int j = 0; j < linenumbers.length; j++) { 204 if (linenumbers[j] != null && 205 linenumbers[j].getLineNumber() > maxLineNumber) { 206 maxLineNumber = linenumbers[j].getLineNumber(); 207 } 208 } 209 } 210 } 211 String [] result = new String [maxLineNumber * 2]; 212 for (int i = 0; i < result.length; i++) { 213 result[i] = "Source for " + javaClass.getClassName() + " could not be found"; } 215 return result; 216 } 217 218 public static void printByteCode(PrintStream out, String id, Code code, boolean indicateBranches, boolean showPositions) { 219 if (id != null) { 220 out.println(id); 221 } 222 if (code == null || code.getLineNumberTable() == null) { 223 return; 224 } 225 LineNumber[] lineNumbers = code.getLineNumberTable().getLineNumberTable(); 226 InstructionList bytecode = new InstructionList(code.getCode()); 227 bytecode.setPositions(); 228 int lastsourceline = Integer.MIN_VALUE; 229 230 for (Iterator iter = bytecode.iterator(); iter.hasNext();) { 231 InstructionHandle element = (InstructionHandle) iter.next(); 232 int pos = element.getPosition(); 233 int sourceLine = getCorrespondingSourceLine(lineNumbers, pos); 234 if (lastsourceline != sourceLine && showPositions) { 235 out.println("-------------------------------------------------------------------------------------------------"); } 237 String output = createOutputLine(indicateBranches, 238 showPositions, 239 sourcecode, 240 code, 241 lastsourceline, 242 element, 243 pos, 244 sourceLine); 245 lastsourceline = sourceLine; 246 out.println(output); 247 } 248 } 249 250 public static String [] printToStringArray(Code code) { 251 ByteCodePrinterThread t = new ByteCodePrinterThread(code); 252 BufferedReader reader = t.getReader(); 253 t.start(); 254 String line; 255 List lines = new ArrayList(); 256 try { 257 while ((line = reader.readLine()) != null) { 258 lines.add(line); 259 } 260 } catch (IOException e) { 261 e.printStackTrace(); 262 } 263 return (String []) lines.toArray(new String [lines.size()]); 264 } 265 } | Popular Tags |