1 package alt.jiapi.tool; 2 3 import java.io.*; 4 import java.lang.reflect.Modifier ; 5 6 import alt.jiapi.reflect.*; 7 import alt.jiapi.reflect.instruction.*; 8 import alt.jiapi.file.*; 9 10 23 public class Javap { 24 private JiapiClass jc; 25 26 public static void main(String [] args) throws Exception { 27 if (args.length == 0) { 28 help(); 29 return; 30 } 31 32 Javap javap = null; 33 try { 34 javap = new Javap(args[0]); 35 } 36 catch(ParseException pe) { 37 if (pe.getConstantPool() != null) { 38 System.out.println("\n" + pe.getConstantPool()); 39 } 40 41 throw pe; 42 } 43 44 if (System.getProperty("verify") != null) { 45 javap.verify(); 46 } 47 48 if (System.getProperty("constantpool") != null) { 49 javap.printConstantPool(); 50 } 51 52 String mName = System.getProperty("method"); 53 if (mName != null) { 54 System.setProperty("instructions", ""); 55 } 56 57 58 javap.printClassInfo(); 59 javap.printFields(); 60 javap.printMethods(); 61 } 62 63 64 public Javap(String classOrFileName) throws Exception { 65 Loader l = new Loader(); 66 File f = new File(classOrFileName); 67 InputStream is = null; 68 69 if (f.exists()) { 70 this.jc = l.loadClass(new FileInputStream(f)); } 72 else { 73 this.jc = l.loadClass(classOrFileName); } 75 } 76 77 78 79 private static void help() { 80 System.out.println("Usage: "); 81 System.out.println(" java [-Dconstantpool] [-Dinstructions] [-Dmethod=<name>] [-Dverify] [-Dverbose] alt.jiapi.tool.Javap <path_to_class | className>"); 82 } 83 84 private void printFields() { 85 JiapiField[] fields = jc.getDeclaredFields(); 86 87 System.out.println("Fields:"); 88 for (int i = 0; i < fields.length; i++) { 89 printField(fields[i]); 90 } 91 } 92 93 private void printMethods() { 94 String mName = System.getProperty("method"); 95 JiapiMethod[] methods = jc.getDeclaredMethods(); 96 97 System.out.println("Methods:"); 98 for (int i = 0; i < methods.length; i++) { 99 if (mName == null) { 100 printMethod(methods[i]); 101 } 102 else if (mName.equals(methods[i].getName())) { 103 printMethod(methods[i]); 104 } 105 else { 106 continue; 107 } 108 109 if(System.getProperty("instructions") != null) { 110 printInstructions(methods[i].getInstructionList()); 111 } 112 } 113 } 114 115 116 protected void printClassInfo() { 117 System.out.println(Modifier.toString(jc.getModifiers() & 0xffdf) + 118 " JiapiClass " + jc.getName()); 119 } 120 121 122 protected void verify() { 123 } 124 125 126 protected void printConstantPool() { 127 System.out.println(jc.getConstantPool()); 128 } 129 130 protected void printField(JiapiField jf) { 131 System.out.println(jf); 132 } 133 134 protected void printMethod(JiapiMethod jm) { 135 System.out.println(jm); 136 try { 137 if (! (Modifier.isAbstract(jm.getModifiers()) || 138 Modifier.isNative(jm.getModifiers())) ) { 139 System.out.println("Max-stack: " + jm.getMaxStack() + ", " + 140 "Max-locals: " + jm.getMaxLocals()); 141 } 142 } 143 catch(Exception e) { 144 System.out.println("Failed to print max-stack and max-locals. There is something wrong with this class"); 145 } 146 } 147 148 protected void printInstructions(InstructionList il) { 149 int offset = 0; 150 int stackUsage = 0; 151 StringBuffer sb = new StringBuffer ("index offset mnemonic operands stack-usage (consumes)\n"); 152 ConstantPool cp = jc.getConstantPool(); 153 154 Instruction ins = null; 155 for (int i = 0; i < il.size(); i++) { 156 try { 157 ins = il.get(i); 158 159 stackUsage += ins.stackUsage(); 160 161 sb.append(" #"); 162 sb.append(i); 163 if (i < 10) { 164 sb.append(' '); 165 } 166 if (i < 100) { 167 if (il.size() >= 100) { 168 sb.append(' '); 169 } 170 } 171 172 sb.append(" ("); 173 sb.append(offset); 174 sb.append(")"); 175 176 if (offset < 10) { 177 sb.append(" "); 178 } 179 else if (offset < 100) { 180 sb.append(" "); 181 } 182 else { 183 sb.append(" "); 184 } 185 186 sb.append(toString(cp, ins, il)); 188 if (i < il.size() - 1) { 189 sb.append('\n'); 190 } 191 192 offset += ins.length(); 193 194 } 195 catch(Exception e) { 196 e.printStackTrace(); 197 sb.append("ERROR: Failed to handle instruction " + 198 Opcodes.opcodeStrings[ins.getOpcode() & 0xff]); 199 if (ins instanceof CPInstruction) { 200 sb.append(", cp-idx: " + ((CPInstruction)ins).getIndex()); 201 } 202 203 sb.append('\n'); 204 } 205 } 206 207 System.out.println(sb); 208 209 } 211 212 213 private String toString(ConstantPool cp, Instruction ins, InstructionList il) { 214 int opCode = ins.getOpcode() & 0xff; 215 StringBuffer sb = new StringBuffer (); 216 sb.append(Opcodes.opcodeStrings[opCode]); 217 218 boolean verbose = true; 220 if (ins instanceof CPInstruction) { 221 CPInstruction cpIns = (CPInstruction)ins; 222 int idx = cpIns.getEntry().getEntryIndex(); 223 sb.append(' '); 224 225 if (verbose) { 226 ConstantPool.Entry ce = cp.get(idx); 227 toTabPosition(15, sb); 228 if (ce instanceof ConstantPool.ClassInfo) { 229 sb.append(((ConstantPool.ClassInfo)ce).getName().replace('/','.')); 230 } 231 else if (ce instanceof ConstantPool.FieldRefInfo) { 232 ConstantPool.FieldRefInfo fri = 233 (ConstantPool.FieldRefInfo)ce; 234 if (!il.getDeclaringMethod().getDeclaringClass().getName().equals(fri.getClassInfo().getName().replace('/', '.'))) { 235 sb.append(fri.getClassInfo().getName()); 236 sb.append('.'); 237 } 238 sb.append(fri.getFieldName()); 239 } 240 else if (ce instanceof ConstantPool.MethodRefInfo) { 241 sb.append(((ConstantPool.MethodRefInfo)ce).getMethodName()); 242 sb.append(((ConstantPool.MethodRefInfo)ce).getDescriptor()); 243 } 244 else if (ce instanceof ConstantPool.InterfaceMethodRefInfo) { 245 sb.append(((ConstantPool.InterfaceMethodRefInfo)ce).getMethodName()); 246 sb.append(((ConstantPool.InterfaceMethodRefInfo)ce).getDescriptor()); 247 } 248 else if (ce instanceof ConstantPool.StringInfo) { 249 sb.append('\"'); 250 sb.append(((ConstantPool.StringInfo)ce).stringValue()); 251 sb.append('\"'); 252 } 253 else { 254 sb.append(ce.toString()); 255 } 256 257 sb.append(" (" + cpIns.getIndex() + ")"); 258 } 259 else { 260 sb.append(idx); 261 } 262 } 263 else if (ins instanceof BranchInstruction) { 264 BranchInstruction bi = (BranchInstruction)ins; 265 toTabPosition(15, sb); 266 Instruction target = bi.getTarget(); 267 sb.append('#'); 268 sb.append(il.indexOf(target)); 269 270 sb.append(", offset "); 271 sb.append(bi.getTargetOffset()); 272 } 273 else { 274 toTabPosition(15, sb); 275 byte[] bytes = ins.getBytes(); 276 for (int i = 1; i < bytes.length; i++) { 277 sb.append(bytes[i]); 278 sb.append(' '); 279 } 280 } 281 282 if (verbose) { 283 toTabPosition(50, sb); 284 sb.append(' '); 285 if (ins.stackUsage() > 0){ 286 sb.append('+'); 287 } 288 else if (ins.stackUsage() == 0){ 289 sb.append(' '); 290 } 291 292 sb.append(ins.stackUsage()); 293 294 sb.append(" ("); 295 sb.append(ins.stackConsumption()); 296 sb.append(")"); 297 } 298 299 return sb.toString(); 300 } 301 302 303 private void toTabPosition(int pos, StringBuffer sb) { 304 int count = pos - sb.length(); 305 306 for (int i = 0; i < count; i++) { 307 sb.append(' '); 308 } 309 } 310 } 311 | Popular Tags |