Author: ebourg Date: Fri Feb 20 11:11:54 2015 New Revision: 1661091 URL: http://svn.apache.org/r1661091 Log: Reformatted the examples
Modified: commons/proper/bcel/trunk/src/examples/HelloWorldBuilder.java commons/proper/bcel/trunk/src/examples/JasminVisitor.java commons/proper/bcel/trunk/src/examples/Package.java commons/proper/bcel/trunk/src/examples/Peephole.java commons/proper/bcel/trunk/src/examples/ProxyCreator.java commons/proper/bcel/trunk/src/examples/TransitiveHull.java commons/proper/bcel/trunk/src/examples/helloify.java commons/proper/bcel/trunk/src/examples/id.java commons/proper/bcel/trunk/src/examples/listclass.java commons/proper/bcel/trunk/src/examples/maxstack.java commons/proper/bcel/trunk/src/examples/patchclass.java Modified: commons/proper/bcel/trunk/src/examples/HelloWorldBuilder.java URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/examples/HelloWorldBuilder.java?rev=1661091&r1=1661090&r2=1661091&view=diff ============================================================================== --- commons/proper/bcel/trunk/src/examples/HelloWorldBuilder.java (original) +++ commons/proper/bcel/trunk/src/examples/HelloWorldBuilder.java Fri Feb 20 11:11:54 2015 @@ -15,6 +15,9 @@ * limitations under the License. * */ + +import java.io.IOException; + import org.apache.bcel.Constants; import org.apache.bcel.generic.ALOAD; import org.apache.bcel.generic.ASTORE; @@ -38,162 +41,143 @@ import org.apache.bcel.generic.Type; * import java.io.*; * * public class HelloWorld { - * public static void main(String[] argv) { - * BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); - * String name = null; + * public static void main(String[] argv) { + * BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); + * String name = null; * - * try { - * System.out.print("Please enter your name> "); - * name = in.readLine(); - * } catch(IOException e) { - * System.out.println(e); - * return; - * } + * try { + * System.out.print("Please enter your name> "); + * name = in.readLine(); + * } catch(IOException e) { + * System.out.println(e); + * return; + * } * - * System.out.println("Hello, " + name); - * } + * System.out.println("Hello, " + name); + * } * } * </PRE> * - * @version $Id$ * @author <A HREF="mailto:m.d...@gmx.de">M. Dahm</A> + * @version $Id$ */ public class HelloWorldBuilder { - public static void main(String[] argv) { - ClassGen cg = new ClassGen("HelloWorld", "java.lang.Object", - "<generated>", Constants.ACC_PUBLIC | - Constants.ACC_SUPER, - null); - ConstantPoolGen cp = cg.getConstantPool(); // cg creates constant pool - InstructionList il = new InstructionList(); - MethodGen mg = new MethodGen(Constants.ACC_STATIC | - Constants.ACC_PUBLIC,// access flags - Type.VOID, // return type - new Type[] { // argument types - new ArrayType(Type.STRING, 1) - }, - new String[] { "argv" }, // arg names - "main", "HelloWorld", // method, class - il, cp); - InstructionFactory factory = new InstructionFactory(cg); - - ObjectType i_stream = new ObjectType("java.io.InputStream"); - ObjectType p_stream = new ObjectType("java.io.PrintStream"); - - /* Create BufferedReader object and store it in local variable `in'. - */ - il.append(factory.createNew("java.io.BufferedReader")); - il.append(InstructionConstants.DUP); // Use predefined constant, i.e. flyweight - il.append(factory.createNew("java.io.InputStreamReader")); - il.append(InstructionConstants.DUP); - il.append(factory.createFieldAccess("java.lang.System", "in", i_stream, - Constants.GETSTATIC)); - - /* Call constructors, i.e. BufferedReader(InputStreamReader()) - */ - il.append(factory.createInvoke("java.io.InputStreamReader", "<init>", - Type.VOID, new Type[] { i_stream }, - Constants.INVOKESPECIAL)); - il.append(factory.createInvoke("java.io.BufferedReader", "<init>", Type.VOID, - new Type[] { new ObjectType("java.io.Reader") }, - Constants.INVOKESPECIAL)); - - /* Create local variable `in' - */ - LocalVariableGen lg = mg.addLocalVariable("in", - new ObjectType("java.io.BufferedReader"), - null, null); - int in = lg.getIndex(); - lg.setStart(il.append(new ASTORE(in))); // `i' valid from here - - /* Create local variable `name' - */ - lg = mg.addLocalVariable("name", Type.STRING, null, null); - int name = lg.getIndex(); - il.append(InstructionConstants.ACONST_NULL); - lg.setStart(il.append(new ASTORE(name))); // `name' valid from here - - /* try { ... - */ - InstructionHandle try_start = - il.append(factory.createFieldAccess("java.lang.System", "out", p_stream, - Constants.GETSTATIC)); - - il.append(new PUSH(cp, "Please enter your name> ")); - il.append(factory.createInvoke("java.io.PrintStream", "print", Type.VOID, - new Type[] { Type.STRING }, Constants.INVOKEVIRTUAL)); - il.append(new ALOAD(in)); - il.append(factory.createInvoke("java.io.BufferedReader", "readLine", - Type.STRING, Type.NO_ARGS, Constants.INVOKEVIRTUAL)); - il.append(new ASTORE(name)); - - /* Upon normal execution we jump behind exception handler, - * the target address is not known yet. - */ - GOTO g = new GOTO(null); - InstructionHandle try_end = il.append(g); - - /* } catch() { ... } - * Add exception handler: print exception and return from method - */ - InstructionHandle handler = - il.append(factory.createFieldAccess("java.lang.System", "out", p_stream, - Constants.GETSTATIC)); - // Little trick in order not to save exception object temporarily - il.append(InstructionConstants.SWAP); - - il.append(factory.createInvoke("java.io.PrintStream", "println", Type.VOID, - new Type[] { Type.OBJECT }, Constants.INVOKEVIRTUAL)); - il.append(InstructionConstants.RETURN); - mg.addExceptionHandler(try_start, try_end, handler, - new ObjectType("java.io.IOException")); - - /* Normal code continues, now we can set the branch target of the GOTO - * that jumps over the handler code. - */ - InstructionHandle ih = - il.append(factory.createFieldAccess("java.lang.System", "out", p_stream, - Constants.GETSTATIC)); - g.setTarget(ih); - - /* String concatenation compiles to StringBuffer operations. - */ - il.append(factory.createNew(Type.STRINGBUFFER)); - il.append(InstructionConstants.DUP); - il.append(new PUSH(cp, "Hello, ")); - il.append(factory.createInvoke("java.lang.StringBuffer", "<init>", - Type.VOID, new Type[] { Type.STRING }, - Constants.INVOKESPECIAL)); - il.append(new ALOAD(name)); - - /* Concatenate strings using a StringBuffer and print them. - */ - il.append(factory.createInvoke("java.lang.StringBuffer", "append", - Type.STRINGBUFFER, new Type[] { Type.STRING }, - Constants.INVOKEVIRTUAL)); - il.append(factory.createInvoke("java.lang.StringBuffer", "toString", - Type.STRING, Type.NO_ARGS, - Constants.INVOKEVIRTUAL)); + public static void main(String[] argv) { + ClassGen cg = new ClassGen("HelloWorld", "java.lang.Object", + "<generated>", Constants.ACC_PUBLIC | + Constants.ACC_SUPER, + null); + ConstantPoolGen cp = cg.getConstantPool(); // cg creates constant pool + InstructionList il = new InstructionList(); + MethodGen mg = new MethodGen(Constants.ACC_STATIC | + Constants.ACC_PUBLIC,// access flags + Type.VOID, // return type + new Type[]{ // argument types + new ArrayType(Type.STRING, 1) + }, + new String[]{"argv"}, // arg names + "main", "HelloWorld", // method, class + il, cp); + InstructionFactory factory = new InstructionFactory(cg); + + ObjectType i_stream = new ObjectType("java.io.InputStream"); + ObjectType p_stream = new ObjectType("java.io.PrintStream"); + + // Create BufferedReader object and store it in local variable `in'. + il.append(factory.createNew("java.io.BufferedReader")); + il.append(InstructionConstants.DUP); // Use predefined constant, i.e. flyweight + il.append(factory.createNew("java.io.InputStreamReader")); + il.append(InstructionConstants.DUP); + il.append(factory.createFieldAccess("java.lang.System", "in", i_stream, Constants.GETSTATIC)); + + // Call constructors, i.e. BufferedReader(InputStreamReader()) + il.append(factory.createInvoke("java.io.InputStreamReader", "<init>", + Type.VOID, new Type[]{i_stream}, + Constants.INVOKESPECIAL)); + il.append(factory.createInvoke("java.io.BufferedReader", "<init>", Type.VOID, + new Type[]{new ObjectType("java.io.Reader")}, + Constants.INVOKESPECIAL)); + + // Create local variable `in' + LocalVariableGen lg = mg.addLocalVariable("in", new ObjectType("java.io.BufferedReader"), null, null); + int in = lg.getIndex(); + lg.setStart(il.append(new ASTORE(in))); // `i' valid from here + + // Create local variable `name' + lg = mg.addLocalVariable("name", Type.STRING, null, null); + int name = lg.getIndex(); + il.append(InstructionConstants.ACONST_NULL); + lg.setStart(il.append(new ASTORE(name))); // `name' valid from here + + // try { ... + InstructionHandle try_start = + il.append(factory.createFieldAccess("java.lang.System", "out", p_stream, Constants.GETSTATIC)); + + il.append(new PUSH(cp, "Please enter your name> ")); + il.append(factory.createInvoke("java.io.PrintStream", "print", Type.VOID, + new Type[]{Type.STRING}, Constants.INVOKEVIRTUAL)); + il.append(new ALOAD(in)); + il.append(factory.createInvoke("java.io.BufferedReader", "readLine", + Type.STRING, Type.NO_ARGS, Constants.INVOKEVIRTUAL)); + il.append(new ASTORE(name)); + + // Upon normal execution we jump behind exception handler, the target address is not known yet. + GOTO g = new GOTO(null); + InstructionHandle try_end = il.append(g); + + /* } catch() { ... } + * Add exception handler: print exception and return from method + */ + InstructionHandle handler = + il.append(factory.createFieldAccess("java.lang.System", "out", p_stream, Constants.GETSTATIC)); + // Little trick in order not to save exception object temporarily + il.append(InstructionConstants.SWAP); + + il.append(factory.createInvoke("java.io.PrintStream", "println", Type.VOID, new Type[]{Type.OBJECT}, Constants.INVOKEVIRTUAL)); + il.append(InstructionConstants.RETURN); + mg.addExceptionHandler(try_start, try_end, handler, new ObjectType("java.io.IOException")); + + // Normal code continues, now we can set the branch target of the GOTO that jumps over the handler code. + InstructionHandle ih = + il.append(factory.createFieldAccess("java.lang.System", "out", p_stream, Constants.GETSTATIC)); + g.setTarget(ih); + + // String concatenation compiles to StringBuffer operations. + il.append(factory.createNew(Type.STRINGBUFFER)); + il.append(InstructionConstants.DUP); + il.append(new PUSH(cp, "Hello, ")); + il.append(factory.createInvoke("java.lang.StringBuffer", "<init>", + Type.VOID, new Type[]{Type.STRING}, + Constants.INVOKESPECIAL)); + il.append(new ALOAD(name)); - il.append(factory.createInvoke("java.io.PrintStream", "println", - Type.VOID, new Type[] { Type.STRING }, - Constants.INVOKEVIRTUAL)); - - il.append(InstructionConstants.RETURN); - - mg.setMaxStack(5); // Needed stack size - cg.addMethod(mg.getMethod()); - - il.dispose(); // Reuse instruction handles - - /* Add public <init> method, i.e. empty constructor - */ - cg.addEmptyConstructor(Constants.ACC_PUBLIC); - - /* Get JavaClass object and dump it to file. - */ - try { - cg.getJavaClass().dump("HelloWorld.class"); - } catch(java.io.IOException e) { System.err.println(e); } - } + // Concatenate strings using a StringBuffer and print them. + il.append(factory.createInvoke("java.lang.StringBuffer", "append", + Type.STRINGBUFFER, new Type[]{Type.STRING}, + Constants.INVOKEVIRTUAL)); + il.append(factory.createInvoke("java.lang.StringBuffer", "toString", + Type.STRING, Type.NO_ARGS, + Constants.INVOKEVIRTUAL)); + + il.append(factory.createInvoke("java.io.PrintStream", "println", + Type.VOID, new Type[]{Type.STRING}, + Constants.INVOKEVIRTUAL)); + + il.append(InstructionConstants.RETURN); + + mg.setMaxStack(5); // Needed stack size + cg.addMethod(mg.getMethod()); + + il.dispose(); // Reuse instruction handles + + // Add public <init> method, i.e. empty constructor + cg.addEmptyConstructor(Constants.ACC_PUBLIC); + + // Get JavaClass object and dump it to file. + try { + cg.getJavaClass().dump("HelloWorld.class"); + } catch (IOException e) { + System.err.println(e); + } + } } Modified: commons/proper/bcel/trunk/src/examples/JasminVisitor.java URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/examples/JasminVisitor.java?rev=1661091&r1=1661090&r2=1661091&view=diff ============================================================================== --- commons/proper/bcel/trunk/src/examples/JasminVisitor.java (original) +++ commons/proper/bcel/trunk/src/examples/JasminVisitor.java Fri Feb 20 11:11:54 2015 @@ -15,6 +15,7 @@ * limitations under the License. * */ + import java.io.File; import java.io.FileOutputStream; import java.io.OutputStream; @@ -22,6 +23,7 @@ import java.io.PrintWriter; import java.util.Date; import java.util.Hashtable; import java.util.StringTokenizer; + import org.apache.bcel.Constants; import org.apache.bcel.Repository; import org.apache.bcel.classfile.Attribute; @@ -53,294 +55,282 @@ import org.apache.bcel.generic.TABLESWIT * Disassemble Java class object into the <a href="http://jasmin.sourceforge.net"> * Jasmin</a> format. * - * @version $Id$ * @author <A HREF="mailto:m.d...@gmx.de">M. Dahm</A> + * @version $Id$ */ public class JasminVisitor extends org.apache.bcel.classfile.EmptyVisitor { - private JavaClass clazz; - private PrintWriter out; - private String class_name; - private ConstantPoolGen cp; - - public JasminVisitor(JavaClass clazz, OutputStream out) { - this.clazz = clazz; - this.out = new PrintWriter(out); - class_name = clazz.getClassName(); - cp = new ConstantPoolGen(clazz.getConstantPool()); - } - - /** - * Start traversal using DefaultVisitor pattern. - */ - public void disassemble() { - new org.apache.bcel.classfile.DescendingVisitor(clazz, this).visit(); - out.close(); - } - - @Override - public void visitJavaClass(JavaClass clazz) { - out.println(";; Produced by JasminVisitor (BCEL)"); - out.println(";; http://commons.apache.org/bcel/"); - out.println(";; " + new Date() + "\n"); - - out.println(".source " + clazz.getSourceFileName()); - out.println("." + Utility.classOrInterface(clazz.getAccessFlags()) + " " + - Utility.accessToString(clazz.getAccessFlags(), true) + - " " + clazz.getClassName().replace('.', '/')); - out.println(".super " + clazz.getSuperclassName().replace('.', '/')); - - String[] interfaces = clazz.getInterfaceNames(); - - for(int i=0; i < interfaces.length; i++) { - out.println(".implements " + interfaces[i].replace('.', '/')); - } - - out.print("\n"); - } - - @Override - public void visitField(Field field) { - out.print(".field " + Utility.accessToString(field.getAccessFlags()) + - " \"" +field.getName() + "\"" + field.getSignature()); - if(field.getAttributes().length == 0) { + private JavaClass clazz; + private PrintWriter out; + private String class_name; + private ConstantPoolGen cp; + + public JasminVisitor(JavaClass clazz, OutputStream out) { + this.clazz = clazz; + this.out = new PrintWriter(out); + this.class_name = clazz.getClassName(); + this.cp = new ConstantPoolGen(clazz.getConstantPool()); + } + + /** + * Start traversal using DefaultVisitor pattern. + */ + public void disassemble() { + new org.apache.bcel.classfile.DescendingVisitor(clazz, this).visit(); + out.close(); + } + + @Override + public void visitJavaClass(JavaClass clazz) { + out.println(";; Produced by JasminVisitor (BCEL)"); + out.println(";; http://commons.apache.org/bcel/"); + out.println(";; " + new Date() + "\n"); + + out.println(".source " + clazz.getSourceFileName()); + out.println("." + Utility.classOrInterface(clazz.getAccessFlags()) + " " + + Utility.accessToString(clazz.getAccessFlags(), true) + + " " + clazz.getClassName().replace('.', '/')); + out.println(".super " + clazz.getSuperclassName().replace('.', '/')); + + for (String iface : clazz.getInterfaceNames()) { + out.println(".implements " + iface.replace('.', '/')); + } + out.print("\n"); } - } - @Override - public void visitConstantValue(ConstantValue cv) { - out.println(" = " + cv); - } - - private Method _method; - - /** - * Unfortunately Jasmin expects ".end method" after each method. Thus we've to check - * for every of the method's attributes if it's the last one and print ".end method" - * then. - */ - private void printEndMethod(Attribute attr) { - Attribute[] attributes = _method.getAttributes(); - - if(attr == attributes[attributes.length - 1]) { - out.println(".end method"); - } - } - - @Override - public void visitDeprecated(Deprecated attribute) { printEndMethod(attribute); } - - @Override - public void visitSynthetic(Synthetic attribute) { - if(_method != null) { - printEndMethod(attribute); + @Override + public void visitField(Field field) { + out.print(".field " + Utility.accessToString(field.getAccessFlags()) + + " \"" + field.getName() + "\"" + field.getSignature()); + if (field.getAttributes().length == 0) { + out.print("\n"); + } } - } - @Override - public void visitMethod(Method method) { - this._method = method; // Remember for use in subsequent visitXXX calls + @Override + public void visitConstantValue(ConstantValue cv) { + out.println(" = " + cv); + } - out.println("\n.method " + Utility.accessToString(_method.getAccessFlags()) + - " " + _method.getName() + _method.getSignature()); + private Method _method; - Attribute[] attributes = _method.getAttributes(); - if((attributes == null) || (attributes.length == 0)) { - out.println(".end method"); + /** + * Unfortunately Jasmin expects ".end method" after each method. Thus we've to check + * for every of the method's attributes if it's the last one and print ".end method" + * then. + */ + private void printEndMethod(Attribute attr) { + Attribute[] attributes = _method.getAttributes(); + + if (attr == attributes[attributes.length - 1]) { + out.println(".end method"); + } } - } - @Override - public void visitExceptionTable(ExceptionTable e) { - String[] names = e.getExceptionNames(); - for(int i=0; i < names.length; i++) { - out.println(".throws " + names[i].replace('.', '/')); + @Override + public void visitDeprecated(Deprecated attribute) { + printEndMethod(attribute); } - printEndMethod(e); - } + @Override + public void visitSynthetic(Synthetic attribute) { + if (_method != null) { + printEndMethod(attribute); + } + } - private Hashtable<InstructionHandle, String> map; + @Override + public void visitMethod(Method method) { + this._method = method; // Remember for use in subsequent visitXXX calls + + out.println("\n.method " + Utility.accessToString(_method.getAccessFlags()) + + " " + _method.getName() + _method.getSignature()); + + Attribute[] attributes = _method.getAttributes(); + if ((attributes == null) || (attributes.length == 0)) { + out.println(".end method"); + } + } - @Override - public void visitCode(Code code) { - int label_counter = 0; + @Override + public void visitExceptionTable(ExceptionTable e) { + for (String name : e.getExceptionNames()) { + out.println(".throws " + name.replace('.', '/')); + } + + printEndMethod(e); + } - out.println(".limit stack " + code.getMaxStack()); - out.println(".limit locals " + code.getMaxLocals()); + private Hashtable<InstructionHandle, String> map; - MethodGen mg = new MethodGen(_method, class_name, cp); - InstructionList il = mg.getInstructionList(); - InstructionHandle[] ihs = il.getInstructionHandles(); + @Override + public void visitCode(Code code) { + int label_counter = 0; + + out.println(".limit stack " + code.getMaxStack()); + out.println(".limit locals " + code.getMaxLocals()); + + MethodGen mg = new MethodGen(_method, class_name, cp); + InstructionList il = mg.getInstructionList(); + InstructionHandle[] ihs = il.getInstructionHandles(); /* Pass 1: Give all referenced instruction handles a symbolic name, i.e. a * label. */ - map = new Hashtable<InstructionHandle, String>(); + map = new Hashtable<InstructionHandle, String>(); + + for (InstructionHandle ih1 : ihs) { + if (ih1 instanceof BranchHandle) { + BranchInstruction bi = (BranchInstruction) ih1.getInstruction(); + + if (bi instanceof Select) { // Special cases LOOKUPSWITCH and TABLESWITCH + for (InstructionHandle target : ((Select) bi).getTargets()) { + put(target, "Label" + label_counter++ + ":"); + } + } + + InstructionHandle ih = bi.getTarget(); + put(ih, "Label" + label_counter++ + ":"); + } + } + + LocalVariableGen[] lvs = mg.getLocalVariables(); + for (LocalVariableGen lv : lvs) { + InstructionHandle ih = lv.getStart(); + put(ih, "Label" + label_counter++ + ":"); + ih = lv.getEnd(); + put(ih, "Label" + label_counter++ + ":"); + } + + CodeExceptionGen[] ehs = mg.getExceptionHandlers(); + for (CodeExceptionGen c : ehs) { + InstructionHandle ih = c.getStartPC(); + + put(ih, "Label" + label_counter++ + ":"); + ih = c.getEndPC(); + put(ih, "Label" + label_counter++ + ":"); + ih = c.getHandlerPC(); + put(ih, "Label" + label_counter++ + ":"); + } + + LineNumberGen[] lns = mg.getLineNumbers(); + for (LineNumberGen ln : lns) { + InstructionHandle ih = ln.getInstruction(); + put(ih, ".line " + ln.getSourceLine()); + } - for(int i=0; i < ihs.length; i++) { - if(ihs[i] instanceof BranchHandle) { - BranchInstruction bi = (BranchInstruction)ihs[i].getInstruction(); - - if(bi instanceof Select) { // Special cases LOOKUPSWITCH and TABLESWITCH - InstructionHandle[] targets = ((Select)bi).getTargets(); - - for(int j=0; j < targets.length; j++) { - put(targets[j], "Label" + label_counter++ + ":"); + // Pass 2: Output code. + for (LocalVariableGen l : lvs) { + out.println(".var " + l.getIndex() + " is " + l.getName() + " " + + l.getType().getSignature() + + " from " + get(l.getStart()) + + " to " + get(l.getEnd())); + } + + out.print("\n"); + + for (InstructionHandle ih : ihs) { + Instruction inst = ih.getInstruction(); + String str = map.get(ih); + + if (str != null) { + out.println(str); + } + + if (inst instanceof BranchInstruction) { + if (inst instanceof Select) { // Special cases LOOKUPSWITCH and TABLESWITCH + Select s = (Select) inst; + int[] matchs = s.getMatchs(); + InstructionHandle[] targets = s.getTargets(); + + if (s instanceof TABLESWITCH) { + out.println("\ttableswitch " + matchs[0] + " " + matchs[matchs.length - 1]); + + for (InstructionHandle target : targets) { + out.println("\t\t" + get(target)); + } + + } else { // LOOKUPSWITCH + out.println("\tlookupswitch "); + + for (int j = 0; j < targets.length; j++) { + out.println("\t\t" + matchs[j] + " : " + get(targets[j])); + } + } + + out.println("\t\tdefault: " + get(s.getTarget())); // Applies for both + } else { + BranchInstruction bi = (BranchInstruction) inst; + ih = bi.getTarget(); + str = get(ih); + out.println("\t" + Constants.OPCODE_NAMES[bi.getOpcode()] + " " + str); + } + } else { + out.println("\t" + inst.toString(cp.getConstantPool())); + } + } + + out.print("\n"); + + for (CodeExceptionGen c : ehs) { + ObjectType caught = c.getCatchType(); + String class_name = (caught == null) ? // catch any exception, used when compiling finally + "all" : caught.getClassName().replace('.', '/'); + + out.println(".catch " + class_name + " from " + + get(c.getStartPC()) + " to " + get(c.getEndPC()) + + " using " + get(c.getHandlerPC())); + } + + printEndMethod(code); } + + private String get(InstructionHandle ih) { + String str = new StringTokenizer(map.get(ih), "\n").nextToken(); + return str.substring(0, str.length() - 1); } - InstructionHandle ih = bi.getTarget(); - put(ih, "Label" + label_counter++ + ":"); - } - } - - LocalVariableGen[] lvs = mg.getLocalVariables(); - for(int i=0; i < lvs.length; i++) { - InstructionHandle ih = lvs[i].getStart(); - put(ih, "Label" + label_counter++ + ":"); - ih = lvs[i].getEnd(); - put(ih, "Label" + label_counter++ + ":"); - } - - CodeExceptionGen[] ehs = mg.getExceptionHandlers(); - for(int i=0; i < ehs.length; i++) { - CodeExceptionGen c = ehs[i]; - InstructionHandle ih = c.getStartPC(); - - put(ih, "Label" + label_counter++ + ":"); - ih = c.getEndPC(); - put(ih, "Label" + label_counter++ + ":"); - ih = c.getHandlerPC(); - put(ih, "Label" + label_counter++ + ":"); - } - - LineNumberGen[] lns = mg.getLineNumbers(); - for(int i=0; i < lns.length; i++) { - InstructionHandle ih = lns[i].getInstruction(); - put(ih, ".line " + lns[i].getSourceLine()); + private void put(InstructionHandle ih, String line) { + String str = map.get(ih); + + if (str == null) { + map.put(ih, line); + } else { + if (line.startsWith("Label") || str.endsWith(line)) { + return; + } + + map.put(ih, str + "\n" + line); // append + } } - - /* Pass 2: Output code. - */ - for(int i=0; i < lvs.length; i++) { - LocalVariableGen l = lvs[i]; - out.println(".var " + l.getIndex() + " is " + l.getName() + " " + - l.getType().getSignature() + - " from " + get(l.getStart()) + - " to " + get(l.getEnd())); - } - - out.print("\n"); - - for(int i=0; i < ihs.length; i++) { - InstructionHandle ih = ihs[i]; - Instruction inst = ih.getInstruction(); - String str = map.get(ih); - - if(str != null) { - out.println(str); - } - - if(inst instanceof BranchInstruction) { - if(inst instanceof Select) { // Special cases LOOKUPSWITCH and TABLESWITCH - Select s = (Select)inst; - int[] matchs = s.getMatchs(); - InstructionHandle[] targets = s.getTargets(); - - if(s instanceof TABLESWITCH) { - out.println("\ttableswitch " + matchs[0] + " " + - matchs[matchs.length - 1]); - - for(int j=0; j < targets.length; j++) { - out.println("\t\t" + get(targets[j])); - } - - } else { // LOOKUPSWITCH - out.println("\tlookupswitch "); - - for(int j=0; j < targets.length; j++) { - out.println("\t\t" + matchs[j] + " : " + get(targets[j])); - } - } - - out.println("\t\tdefault: " + get(s.getTarget())); // Applies for both - } else { - BranchInstruction bi = (BranchInstruction)inst; - ih = bi.getTarget(); - str = get(ih); - out.println("\t" + Constants.OPCODE_NAMES[bi.getOpcode()] + " " + str); - } - } else { - out.println("\t" + inst.toString(cp.getConstantPool())); - } - } - - out.print("\n"); - - for(int i=0; i < ehs.length; i++) { - CodeExceptionGen c = ehs[i]; - ObjectType caught = c.getCatchType(); - String class_name = (caught == null)? // catch any exception, used when compiling finally - "all" : caught.getClassName().replace('.', '/'); - - out.println(".catch " + class_name + " from " + - get(c.getStartPC()) + " to " + get(c.getEndPC()) + - " using " + get(c.getHandlerPC())); - } - - printEndMethod(code); - } - - private String get(InstructionHandle ih) { - String str = new StringTokenizer(map.get(ih), "\n").nextToken(); - return str.substring(0, str.length() - 1); - } - - private void put(InstructionHandle ih, String line) { - String str = map.get(ih); - - if(str == null) { - map.put(ih, line); - } else { - if(line.startsWith("Label") || str.endsWith(line)) { - return; - } - - map.put(ih, str + "\n" + line); // append - } - } - - public static void main(String[] argv) { - JavaClass java_class; - - try { - if(argv.length == 0) { - System.err.println("disassemble: No input files specified"); - } else { - for(int i=0; i < argv.length; i++) { - if((java_class = Repository.lookupClass(argv[i])) == null) { - java_class = new ClassParser(argv[i]).parse(); - } - - String class_name = java_class.getClassName(); - int index = class_name.lastIndexOf('.'); - String path = class_name.substring(0, index + 1).replace('.', File.separatorChar); - class_name = class_name.substring(index + 1); - - if(!path.equals("")) { - File f = new File(path); - f.mkdirs(); - } - - String name = path + class_name + ".j"; - FileOutputStream out = new FileOutputStream(name); - new JasminVisitor(java_class, out).disassemble(); - System.out.println("File dumped to: " + name); - } - } - } catch(Exception e) { - e.printStackTrace(); + + public static void main(String[] argv) throws Exception { + JavaClass java_class; + + if (argv.length == 0) { + System.err.println("disassemble: No input files specified"); + return; + } + + for (String arg : argv) { + if ((java_class = Repository.lookupClass(arg)) == null) { + java_class = new ClassParser(arg).parse(); + } + + String class_name = java_class.getClassName(); + int index = class_name.lastIndexOf('.'); + String path = class_name.substring(0, index + 1).replace('.', File.separatorChar); + class_name = class_name.substring(index + 1); + + if (!path.equals("")) { + File f = new File(path); + f.mkdirs(); + } + + String name = path + class_name + ".j"; + FileOutputStream out = new FileOutputStream(name); + new JasminVisitor(java_class, out).disassemble(); + System.out.println("File dumped to: " + name); + } } - } } Modified: commons/proper/bcel/trunk/src/examples/Package.java URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/examples/Package.java?rev=1661091&r1=1661090&r2=1661091&view=diff ============================================================================== --- commons/proper/bcel/trunk/src/examples/Package.java (original) +++ commons/proper/bcel/trunk/src/examples/Package.java Fri Feb 20 11:11:54 2015 @@ -15,6 +15,7 @@ * limitations under the License. * */ + import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; @@ -36,235 +37,247 @@ import org.apache.bcel.classfile.JavaCla import org.apache.bcel.util.ClassPath; /** - * Package the client. Creates a jar file in the current directory + * Package the client. Creates a jar file in the current directory * that contains a minimal set of classes needed to run the client. * * Use BCEL to extract class names and read/write classes + * * @author First Hop Ltd / Torsten Rueger */ public class Package { - - /** - * The name of the resulting jar is Client.jar - */ - static String defaultJar = "Client.jar"; - - /* - * See usage() for arguments. Create an instance and run that - *(just so not all members have to be static) - */ - static void main(String args[]) { - Package instance = new Package(); - try{ - instance.go(args); - }catch(Exception e){ - e.printStackTrace(); - instance.usage(); - } - } - - /** - * We use a "default ClassPath object which uses the environments - * CLASSPATH - */ - ClassPath classPath = ClassPath.SYSTEM_CLASS_PATH; - - /** - * A map for all Classes, the ones we're going to package. - * Store class name against the JavaClass. From the JavaClass - * we get the bytes to create the jar. - */ - Map<String, JavaClass> allClasses = new TreeMap<String, JavaClass>(); - /** - * We start at the root classes, put them in here, then go through - * this list, putting dependent classes in here and from there - * into allClasses. Store class names against class names of their dependents - */ - TreeMap<String, String> dependents = new TreeMap<String, String>(); - /** - * Collect all classes that could not be found in the classpath. - * Store class names against class names of their dependents - */ - TreeMap<String, String> notFound = new TreeMap<String, String>(); - /** - * See wheather we print the classes that were not found (default = false) - */ - boolean showNotFound = false ; - /** - * Remember wheather to print allClasses at the end (default = false) - */ - boolean printClasses = false ; - /** - * Wheather we log classes during processing (default = false) - */ - boolean log = false ; - - public void usage(){ - System.out.println(" This program packages classes and all their dependents"); - System.out.println(" into one jar. Give all starting classes (your main)"); - System.out.println(" on the command line. Use / as separator, the .class is"); - System.out.println(" optional. We use the environments CLASSPATH to resolve"); - System.out.println(" classes. Anything but java.* packages are packaged."); - System.out.println(" If you use Class.forName (or similar), be sure to"); - System.out.println(" include the classes that you load dynamically on the"); - System.out.println(" command line.\n"); - System.out.println(" These options are recognized:"); - System.out.println(" -e -error Show errors, meaning classes that could not "); - System.out.println(" resolved + the classes that referenced them."); - System.out.println(" -l -log Show classes as they are processed. This will"); - System.out.println(" include doubles, java classes and is difficult to"); - System.out.println(" read. I use it as a sort of progress monitor"); - System.out.println(" -s -show Prints all the classes that were packaged"); - System.out.println(" in alphabetical order, which is ordered by package"); - System.out.println(" for the most part."); - } - /** - * the main of this class - */ - void go(String[] args) throws IOException { - JavaClass clazz ; - // sort the options - for(int i = 0 ; i < args.length ; i++ ){ - if( args[i].startsWith("-e") ) { - showNotFound = true; - continue; - } - if( args[i].startsWith("-s") ) { - printClasses = true ; - continue; - } - if( args[i].startsWith("-l") ) { - log = true ; - continue; - } - String clName = args[i]; - if(clName.endsWith(".class")) { - clName = clName.substring(0,clName.length()-6); - } - clName = clName.replace('.','/'); - clazz = new ClassParser(classPath.getInputStream(clName),clName).parse(); - // here we create the root set of classes to process - addDependents(clazz); - System.out.println("Packaging for class: " + clName ); - } - if( dependents.isEmpty() ){ - usage(); - return ; - } - System.out.println("Creating jar file: " + defaultJar ); - // starting processing: Grab from the dependents list an add back to it - // and the allClasses list. see addDependents - while(!dependents.isEmpty() ){ - String name = dependents.firstKey(); - String from = dependents.remove(name); - if(allClasses.get(name) == null){ - try{ - InputStream is = classPath.getInputStream(name); - clazz = new ClassParser(is, name).parse(); - addDependents(clazz); - }catch( IOException e){ - //System.err.println("Error, class not found " + name ); - notFound.put(name,from); - } - } - } - if(printClasses) { // if wanted show all classes - printAllClasses(); - } - // create the jar - JarOutputStream jarFile = new JarOutputStream(new FileOutputStream(defaultJar)); - jarFile.setLevel(5); // use compression - int written = 0; - for (String name : allClasses.keySet()) { // add entries for every class - JavaClass claz = allClasses.get(name); - ZipEntry zipEntry = new ZipEntry(name+".class"); - byte[] bytes = claz.getBytes() ; - int length = bytes.length ; - jarFile.putNextEntry(zipEntry); - jarFile.write( bytes , 0 , length ); - written += length; // for logging - } - jarFile.close(); - System.err.println("The jar file contains " + allClasses.size() - +" classes and contains " +written+ " bytes"); - if( !notFound.isEmpty() ){ - System.err.println( notFound.size() +" classes could not be found"); - if(showNotFound){ // if wanted show the actual classes that we not found - while(!notFound.isEmpty()){ - String name = notFound.firstKey(); - System.err.println( name+ " (" + notFound.remove(name)+")"); - } - }else{ - System.err.println("Use '-e' option to view classes that were not found"); - } + + /** + * The name of the resulting jar is Client.jar + */ + static String defaultJar = "Client.jar"; + + /* + * See usage() for arguments. Create an instance and run that + *(just so not all members have to be static) + */ + static void main(String args[]) { + Package instance = new Package(); + try { + instance.go(args); + } catch (Exception e) { + e.printStackTrace(); + instance.usage(); + } } - } - /** - * Print all classes that were packaged. Sort alphabetically for better - * overview. Enabled by -s option - */ - void printAllClasses(){ - List<String> names = new ArrayList<String>(allClasses.keySet()); - Collections.sort(names); - for( int i = 0 ; i < names.size() ; i ++ ){ - String cl = names.get(i); - System.err.println(cl); + /** + * We use a "default ClassPath object which uses the environments + * CLASSPATH + */ + ClassPath classPath = ClassPath.SYSTEM_CLASS_PATH; + + /** + * A map for all Classes, the ones we're going to package. + * Store class name against the JavaClass. From the JavaClass + * we get the bytes to create the jar. + */ + Map<String, JavaClass> allClasses = new TreeMap<String, JavaClass>(); + + /** + * We start at the root classes, put them in here, then go through + * this list, putting dependent classes in here and from there + * into allClasses. Store class names against class names of their dependents + */ + TreeMap<String, String> dependents = new TreeMap<String, String>(); + + /** + * Collect all classes that could not be found in the classpath. + * Store class names against class names of their dependents + */ + TreeMap<String, String> notFound = new TreeMap<String, String>(); + + /** + * See wheather we print the classes that were not found (default = false) + */ + boolean showNotFound = false; + /** + * Remember wheather to print allClasses at the end (default = false) + */ + boolean printClasses = false; + /** + * Wheather we log classes during processing (default = false) + */ + boolean log = false; + + public void usage() { + System.out.println(" This program packages classes and all their dependents"); + System.out.println(" into one jar. Give all starting classes (your main)"); + System.out.println(" on the command line. Use / as separator, the .class is"); + System.out.println(" optional. We use the environments CLASSPATH to resolve"); + System.out.println(" classes. Anything but java.* packages are packaged."); + System.out.println(" If you use Class.forName (or similar), be sure to"); + System.out.println(" include the classes that you load dynamically on the"); + System.out.println(" command line.\n"); + System.out.println(" These options are recognized:"); + System.out.println(" -e -error Show errors, meaning classes that could not "); + System.out.println(" resolved + the classes that referenced them."); + System.out.println(" -l -log Show classes as they are processed. This will"); + System.out.println(" include doubles, java classes and is difficult to"); + System.out.println(" read. I use it as a sort of progress monitor"); + System.out.println(" -s -show Prints all the classes that were packaged"); + System.out.println(" in alphabetical order, which is ordered by package"); + System.out.println(" for the most part."); } - } - - /** - *Add this class to allClasses. Then go through all its dependents - * and add them to the dependents list if they are not in allClasses - */ - void addDependents( JavaClass clazz ) throws IOException { - String name = clazz.getClassName().replace('.', '/'); - allClasses.put( name , clazz ); - ConstantPool pool = clazz.getConstantPool(); - for( int i = 1 ; i < pool.getLength() ; i++){ - Constant cons = pool.getConstant(i); - //System.out.println("("+i+") " + cons ); - if( cons!=null && cons.getTag() == Constants.CONSTANT_Class ){ - int idx = ((ConstantClass)pool.getConstant(i)).getNameIndex(); - String clas = ((ConstantUtf8)pool.getConstant(idx)).getBytes(); - addClassString(clas,name); - } + + /** + * the main of this class + */ + void go(String[] args) throws IOException { + JavaClass clazz; + // sort the options + for (String arg : args) { + if (arg.startsWith("-e")) { + showNotFound = true; + continue; + } + if (arg.startsWith("-s")) { + printClasses = true; + continue; + } + if (arg.startsWith("-l")) { + log = true; + continue; + } + String clName = arg; + if (clName.endsWith(".class")) { + clName = clName.substring(0, clName.length() - 6); + } + clName = clName.replace('.', '/'); + clazz = new ClassParser(classPath.getInputStream(clName), clName).parse(); + // here we create the root set of classes to process + addDependents(clazz); + System.out.println("Packaging for class: " + clName); + } + + if (dependents.isEmpty()) { + usage(); + return; + } + + System.out.println("Creating jar file: " + defaultJar); + + // starting processing: Grab from the dependents list an add back to it + // and the allClasses list. see addDependents + while (!dependents.isEmpty()) { + String name = dependents.firstKey(); + String from = dependents.remove(name); + if (allClasses.get(name) == null) { + try { + InputStream is = classPath.getInputStream(name); + clazz = new ClassParser(is, name).parse(); + addDependents(clazz); + } catch (IOException e) { + //System.err.println("Error, class not found " + name ); + notFound.put(name, from); + } + } + } + + if (printClasses) { // if wanted show all classes + printAllClasses(); + } + + // create the jar + JarOutputStream jarFile = new JarOutputStream(new FileOutputStream(defaultJar)); + jarFile.setLevel(5); // use compression + int written = 0; + for (String name : allClasses.keySet()) { // add entries for every class + JavaClass claz = allClasses.get(name); + ZipEntry zipEntry = new ZipEntry(name + ".class"); + byte[] bytes = claz.getBytes(); + int length = bytes.length; + jarFile.putNextEntry(zipEntry); + jarFile.write(bytes, 0, length); + written += length; // for logging + } + jarFile.close(); + System.err.println("The jar file contains " + allClasses.size() + + " classes and contains " + written + " bytes"); + + if (!notFound.isEmpty()) { + System.err.println(notFound.size() + " classes could not be found"); + if (showNotFound) { // if wanted show the actual classes that we not found + while (!notFound.isEmpty()) { + String name = notFound.firstKey(); + System.err.println(name + " (" + notFound.remove(name) + ")"); + } + } else { + System.err.println("Use '-e' option to view classes that were not found"); + } + } } - } - /** - * add given class to dependents (from is where its dependent from) - * some fiddeling to be done because of array class notation - */ - void addClassString(String clas,String from) throws IOException{ - if(log){ - System.out.println("processing: " + clas +" referenced by " + from); + /** + * Print all classes that were packaged. Sort alphabetically for better + * overview. Enabled by -s option + */ + void printAllClasses() { + List<String> names = new ArrayList<String>(allClasses.keySet()); + Collections.sort(names); + for (int i = 0; i < names.size(); i++) { + String cl = names.get(i); + System.err.println(cl); + } } - // must check if it's an arrary (start with "[") - if(clas.startsWith("[")) { - if(clas.length() == 2 ) { - // it's an array of built in type, ignore - return; - } - if( 'L' == clas.charAt(1) ){ - // it's an array of objects, the class name is between [L and ; - // like [Ljava/lang/Object; - addClassString(clas.substring(2,clas.length()-1),from); - return; - } - if( '[' == clas.charAt(1) ){ - // it's an array of arrays, call recursive - addClassString(clas.substring(1),from); - return ; - } - throw new IOException("Can't recognize class name =" + clas); + + /** + * Add this class to allClasses. Then go through all its dependents + * and add them to the dependents list if they are not in allClasses + */ + void addDependents(JavaClass clazz) throws IOException { + String name = clazz.getClassName().replace('.', '/'); + allClasses.put(name, clazz); + ConstantPool pool = clazz.getConstantPool(); + for (int i = 1; i < pool.getLength(); i++) { + Constant cons = pool.getConstant(i); + //System.out.println("("+i+") " + cons ); + if (cons != null && cons.getTag() == Constants.CONSTANT_Class) { + int idx = ((ConstantClass) pool.getConstant(i)).getNameIndex(); + String clas = ((ConstantUtf8) pool.getConstant(idx)).getBytes(); + addClassString(clas, name); + } + } } - if( !clas.startsWith("java/") && allClasses.get(clas) == null) { - dependents.put(clas,from); - // System.out.println(" yes" ); - } else { - // System.out.println(" no" ); + /** + * add given class to dependents (from is where its dependent from) + * some fiddeling to be done because of array class notation + */ + void addClassString(String clas, String from) throws IOException { + if (log) { + System.out.println("processing: " + clas + " referenced by " + from); + } + + // must check if it's an arrary (start with "[") + if (clas.startsWith("[")) { + if (clas.length() == 2) { + // it's an array of built in type, ignore + return; + } + if ('L' == clas.charAt(1)) { + // it's an array of objects, the class name is between [L and ; + // like [Ljava/lang/Object; + addClassString(clas.substring(2, clas.length() - 1), from); + return; + } + if ('[' == clas.charAt(1)) { + // it's an array of arrays, call recursive + addClassString(clas.substring(1), from); + return; + } + throw new IOException("Can't recognize class name =" + clas); + } + + if (!clas.startsWith("java/") && allClasses.get(clas) == null) { + dependents.put(clas, from); + // System.out.println(" yes" ); + } else { + // System.out.println(" no" ); + } } - } } Modified: commons/proper/bcel/trunk/src/examples/Peephole.java URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/examples/Peephole.java?rev=1661091&r1=1661090&r2=1661091&view=diff ============================================================================== --- commons/proper/bcel/trunk/src/examples/Peephole.java (original) +++ commons/proper/bcel/trunk/src/examples/Peephole.java Fri Feb 20 11:11:54 2015 @@ -15,7 +15,9 @@ * limitations under the License. * */ + import java.util.Iterator; + import org.apache.bcel.Repository; import org.apache.bcel.classfile.JavaClass; import org.apache.bcel.classfile.Method; @@ -30,83 +32,76 @@ import org.apache.bcel.util.InstructionF /** * Remove NOPs from given class * - * @version $Id$ * @author <A HREF="mailto:m.d...@gmx.de">M. Dahm</A> + * @version $Id$ */ public class Peephole { - public static void main(String[] argv) { - try { - /* Load the class from CLASSPATH. - */ - JavaClass clazz = Repository.lookupClass(argv[0]); - Method[] methods = clazz.getMethods(); - ConstantPoolGen cp = new ConstantPoolGen(clazz.getConstantPool()); - - for(int i=0; i < methods.length; i++) { - if(!(methods[i].isAbstract() || methods[i].isNative())) { - MethodGen mg = new MethodGen(methods[i], - clazz.getClassName(), cp); - Method stripped = removeNOPs(mg); - - if(stripped != null) { - methods[i] = stripped; // Overwrite with stripped method - } - } - } - /* Dump the class to <class name>_.class - */ - clazz.setConstantPool(cp.getFinalConstantPool()); - clazz.dump(clazz.getClassName() + "_.class"); - } catch(Exception e) { e.printStackTrace(); } - } - - private static Method removeNOPs(MethodGen mg) { - InstructionList il = mg.getInstructionList(); - InstructionFinder f = new InstructionFinder(il); - String pat = "NOP+"; // Find at least one NOP - InstructionHandle next = null; - int count = 0; - - for(Iterator<InstructionHandle[]> e = f.search(pat); e.hasNext(); ) { - InstructionHandle[] match = e.next(); - InstructionHandle first = match[0]; - InstructionHandle last = match[match.length - 1]; - - /* Some nasty Java compilers may add NOP at end of method. - */ - if((next = last.getNext()) == null) { - break; - } + public static void main(String[] argv) { + try { + // Load the class from CLASSPATH. + JavaClass clazz = Repository.lookupClass(argv[0]); + Method[] methods = clazz.getMethods(); + ConstantPoolGen cp = new ConstantPoolGen(clazz.getConstantPool()); + + for (int i = 0; i < methods.length; i++) { + if (!(methods[i].isAbstract() || methods[i].isNative())) { + MethodGen mg = new MethodGen(methods[i], clazz.getClassName(), cp); + Method stripped = removeNOPs(mg); + + if (stripped != null) { + methods[i] = stripped; // Overwrite with stripped method + } + } + } + + // Dump the class to <class name>_.class + clazz.setConstantPool(cp.getFinalConstantPool()); + clazz.dump(clazz.getClassName() + "_.class"); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private static Method removeNOPs(MethodGen mg) { + InstructionList il = mg.getInstructionList(); + InstructionFinder f = new InstructionFinder(il); + String pat = "NOP+"; // Find at least one NOP + InstructionHandle next = null; + int count = 0; + + for (Iterator<InstructionHandle[]> e = f.search(pat); e.hasNext(); ) { + InstructionHandle[] match = e.next(); + InstructionHandle first = match[0]; + InstructionHandle last = match[match.length - 1]; + + // Some nasty Java compilers may add NOP at end of method. + if ((next = last.getNext()) == null) { + break; + } + + count += match.length; + + // Delete NOPs and redirect any references to them to the following (non-nop) instruction. + try { + il.delete(first, last); + } catch (TargetLostException e2) { + for (InstructionHandle target : e2.getTargets()) { + for (InstructionTargeter targeter : target.getTargeters()) { + targeter.updateTarget(target, next); + } + } + } + } + + Method m = null; + + if (count > 0) { + System.out.println("Removed " + count + " NOP instructions from method " + mg.getName()); + m = mg.getMethod(); + } - count += match.length; - - /* Delete NOPs and redirect any references to them to the following - * (non-nop) instruction. - */ - try { - il.delete(first, last); - } catch(TargetLostException e2) { - InstructionHandle[] targets = e2.getTargets(); - for(int i=0; i < targets.length; i++) { - InstructionTargeter[] targeters = targets[i].getTargeters(); - - for(int j=0; j < targeters.length; j++) { - targeters[j].updateTarget(targets[i], next); - } - } - } + il.dispose(); // Reuse instruction handles + return m; } - - Method m = null; - - if(count > 0) { - System.out.println("Removed " + count + " NOP instructions from method " + - mg.getName()); - m = mg.getMethod(); - } - - il.dispose(); // Reuse instruction handles - return m; - } } Modified: commons/proper/bcel/trunk/src/examples/ProxyCreator.java URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/examples/ProxyCreator.java?rev=1661091&r1=1661090&r2=1661091&view=diff ============================================================================== --- commons/proper/bcel/trunk/src/examples/ProxyCreator.java (original) +++ commons/proper/bcel/trunk/src/examples/ProxyCreator.java Fri Feb 20 11:11:54 2015 @@ -15,8 +15,10 @@ * limitations under the License. * */ + import java.awt.event.ActionEvent; import java.awt.event.ActionListener; + import org.apache.bcel.Constants; import org.apache.bcel.classfile.Utility; import org.apache.bcel.generic.ALOAD; @@ -44,88 +46,91 @@ import org.apache.bcel.generic.Type; * comparable to the mechanism provided via * {@code java.lang.reflect.Proxy}, but much more flexible. * - * @version $Id$ * @author <A HREF="mailto:m.d...@gmx.de">M. Dahm</A> + * @version $Id$ * @see org.apache.bcel.util.JavaWrapper * @see org.apache.bcel.util.ClassLoader * @see Utility */ public class ProxyCreator { - /** Load class and create instance - */ - public static Object createProxy(String pack, String class_name) { - try { - Class<?> cl = Class.forName(pack + "$$BCEL$$" + class_name); - return cl.newInstance(); - } catch(Exception e) { - e.printStackTrace(); - } - return null; - } + /** + * Load class and create instance + */ + public static Object createProxy(String pack, String class_name) { + try { + Class<?> cl = Class.forName(pack + "$$BCEL$$" + class_name); + return cl.newInstance(); + } catch (Exception e) { + e.printStackTrace(); + } + + return null; + } - /** Create JavaClass object for a simple proxy for an java.awt.event.ActionListener - * that just prints the passed arguments, load and use it via the class loader - * mechanism. - */ - public static void main(String[] argv) throws Exception { - ClassLoader loader = ProxyCreator.class.getClassLoader(); - - // instanceof won't work here ... - if(loader.getClass().toString().equals("class org.apache.bcel.util.ClassLoader")) { - // Real class name will be set by the class loader - ClassGen cg = new ClassGen("foo", "java.lang.Object", "", Constants.ACC_PUBLIC, - new String[] {"java.awt.event.ActionListener"}); - - // That's important, otherwise newInstance() won't work - cg.addEmptyConstructor(Constants.ACC_PUBLIC); - - InstructionList il = new InstructionList(); - ConstantPoolGen cp = cg.getConstantPool(); - InstructionFactory factory = new InstructionFactory(cg); - - int out = cp.addFieldref("java.lang.System", "out", - "Ljava/io/PrintStream;"); - int println = cp.addMethodref("java.io.PrintStream", "println", - "(Ljava/lang/Object;)V"); - MethodGen mg = new MethodGen(Constants.ACC_PUBLIC, Type.VOID, - new Type[] { - new ObjectType("java.awt.event.ActionEvent") - }, null, "actionPerformed", "foo", il, cp); - - // System.out.println("actionPerformed:" + event); - il.append(new GETSTATIC(out)); - il.append(factory.createNew("java.lang.StringBuffer")); - il.append(InstructionConstants.DUP); - il.append(new PUSH(cp, "actionPerformed:")); - il.append(factory.createInvoke("java.lang.StringBuffer", "<init>", Type.VOID, - new Type[] {Type.STRING}, Constants.INVOKESPECIAL)); - - il.append(new ALOAD(1)); - il.append(factory.createAppend(Type.OBJECT)); - il.append(new INVOKEVIRTUAL(println)); - il.append(InstructionConstants.RETURN); - - mg.stripAttributes(true); - mg.setMaxStack(); - mg.setMaxLocals(); - cg.addMethod(mg.getMethod()); - - byte[] bytes = cg.getJavaClass().getBytes(); - - System.out.println("Uncompressed class: " + bytes.length); - - String s = Utility.encode(bytes, true); - System.out.println("Encoded class: " + s.length()); - - System.out.print("Creating proxy ... "); - ActionListener a = (ActionListener)createProxy("foo.bar.", s); - System.out.println("Done. Now calling actionPerformed()"); - - a.actionPerformed(new ActionEvent(a, ActionEvent.ACTION_PERFORMED, "hello")); - } else { - System.err.println("Call me with java org.apache.bcel.util.JavaWrapper ProxyCreator"); + /** + * Create JavaClass object for a simple proxy for an java.awt.event.ActionListener + * that just prints the passed arguments, load and use it via the class loader + * mechanism. + */ + public static void main(String[] argv) throws Exception { + ClassLoader loader = ProxyCreator.class.getClassLoader(); + + // instanceof won't work here ... + if (loader.getClass().toString().equals("class org.apache.bcel.util.ClassLoader")) { + // Real class name will be set by the class loader + ClassGen cg = new ClassGen("foo", "java.lang.Object", "", Constants.ACC_PUBLIC, + new String[]{"java.awt.event.ActionListener"}); + + // That's important, otherwise newInstance() won't work + cg.addEmptyConstructor(Constants.ACC_PUBLIC); + + InstructionList il = new InstructionList(); + ConstantPoolGen cp = cg.getConstantPool(); + InstructionFactory factory = new InstructionFactory(cg); + + int out = cp.addFieldref("java.lang.System", "out", + "Ljava/io/PrintStream;"); + int println = cp.addMethodref("java.io.PrintStream", "println", + "(Ljava/lang/Object;)V"); + MethodGen mg = new MethodGen(Constants.ACC_PUBLIC, Type.VOID, + new Type[]{ + new ObjectType("java.awt.event.ActionEvent") + }, null, "actionPerformed", "foo", il, cp); + + // System.out.println("actionPerformed:" + event); + il.append(new GETSTATIC(out)); + il.append(factory.createNew("java.lang.StringBuffer")); + il.append(InstructionConstants.DUP); + il.append(new PUSH(cp, "actionPerformed:")); + il.append(factory.createInvoke("java.lang.StringBuffer", "<init>", Type.VOID, + new Type[]{Type.STRING}, Constants.INVOKESPECIAL)); + + il.append(new ALOAD(1)); + il.append(factory.createAppend(Type.OBJECT)); + il.append(new INVOKEVIRTUAL(println)); + il.append(InstructionConstants.RETURN); + + mg.stripAttributes(true); + mg.setMaxStack(); + mg.setMaxLocals(); + cg.addMethod(mg.getMethod()); + + byte[] bytes = cg.getJavaClass().getBytes(); + + System.out.println("Uncompressed class: " + bytes.length); + + String s = Utility.encode(bytes, true); + System.out.println("Encoded class: " + s.length()); + + System.out.print("Creating proxy ... "); + ActionListener a = (ActionListener) createProxy("foo.bar.", s); + System.out.println("Done. Now calling actionPerformed()"); + + a.actionPerformed(new ActionEvent(a, ActionEvent.ACTION_PERFORMED, "hello")); + } else { + System.err.println("Call me with java org.apache.bcel.util.JavaWrapper ProxyCreator"); + } } - } } Modified: commons/proper/bcel/trunk/src/examples/TransitiveHull.java URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/examples/TransitiveHull.java?rev=1661091&r1=1661090&r2=1661091&view=diff ============================================================================== --- commons/proper/bcel/trunk/src/examples/TransitiveHull.java (original) +++ commons/proper/bcel/trunk/src/examples/TransitiveHull.java Fri Feb 20 11:11:54 2015 @@ -15,8 +15,10 @@ * limitations under the License. * */ + import java.util.Arrays; import java.util.regex.Pattern; + import org.apache.bcel.Constants; import org.apache.bcel.Repository; import org.apache.bcel.classfile.ClassParser; @@ -46,41 +48,42 @@ import org.apache.bcel.util.ClassSet; * <p> * You'll need Apache's regular expression library supplied together with BCEL * to use this class. - * - * @version $Id$ + * * @author <A HREF="mailto:m.d...@gmx.de">M. Dahm</A> + * @version $Id$ */ public class TransitiveHull extends org.apache.bcel.classfile.EmptyVisitor { - private ClassQueue _queue; - private ClassSet _set; - private ConstantPool _cp; - private String[] _ignored = IGNORED; - public static final String[] IGNORED = { "java[.].*", "javax[.].*", "sun[.].*", "sunw[.].*", - "com[.]sun[.].*", "org[.]omg[.].*", "org[.]w3c[.].*", "org[.]xml[.].*", "net[.]jini[.].*" }; + private ClassQueue queue; + private ClassSet set; + private ConstantPool cp; + private String[] ignored = IGNORED; + + public static final String[] IGNORED = {"java[.].*", "javax[.].*", "sun[.].*", "sunw[.].*", + "com[.]sun[.].*", "org[.]omg[.].*", "org[.]w3c[.].*", "org[.]xml[.].*", "net[.]jini[.].*"}; public TransitiveHull(JavaClass clazz) { - _queue = new ClassQueue(); - _queue.enqueue(clazz); - _set = new ClassSet(); - _set.add(clazz); + queue = new ClassQueue(); + queue.enqueue(clazz); + set = new ClassSet(); + set.add(clazz); } public JavaClass[] getClasses() { - return _set.toArray(); + return set.toArray(); } public String[] getClassNames() { - return _set.getClassNames(); + return set.getClassNames(); } /** * Start traversal using DescendingVisitor pattern. */ public void start() { - while (!_queue.empty()) { - JavaClass clazz = _queue.dequeue(); - _cp = clazz.getConstantPool(); + while (!queue.empty()) { + JavaClass clazz = queue.dequeue(); + cp = clazz.getConstantPool(); new org.apache.bcel.classfile.DescendingVisitor(clazz, this).visit(); } @@ -89,8 +92,8 @@ public class TransitiveHull extends org. private void add(String class_name) { class_name = class_name.replace('/', '.'); - for (int i = 0; i < _ignored.length; i++) { - if (Pattern.matches(_ignored[i], class_name)) { + for (String anIgnored : ignored) { + if (Pattern.matches(anIgnored, class_name)) { return; } } @@ -98,8 +101,8 @@ public class TransitiveHull extends org. try { JavaClass clazz = Repository.lookupClass(class_name); - if (_set.add(clazz)) { - _queue.enqueue(clazz); + if (set.add(clazz)) { + queue.enqueue(clazz); } } catch (ClassNotFoundException e) { throw new IllegalStateException("Missing class: " + e.toString()); @@ -108,7 +111,7 @@ public class TransitiveHull extends org. @Override public void visitConstantClass(ConstantClass cc) { - String class_name = (String) cc.getConstantValue(_cp); + String class_name = (String) cc.getConstantValue(cp); add(class_name); } @@ -123,23 +126,21 @@ public class TransitiveHull extends org. } private void visitRef(ConstantCP ccp, boolean method) { - String class_name = ccp.getClass(_cp); + String class_name = ccp.getClass(cp); add(class_name); - ConstantNameAndType cnat = (ConstantNameAndType) _cp.getConstant(ccp.getNameAndTypeIndex(), + ConstantNameAndType cnat = (ConstantNameAndType) cp.getConstant(ccp.getNameAndTypeIndex(), Constants.CONSTANT_NameAndType); - String signature = cnat.getSignature(_cp); + String signature = cnat.getSignature(cp); if (method) { Type type = Type.getReturnType(signature); checkType(type); - Type[] types = Type.getArgumentTypes(signature); - - for (int i = 0; i < types.length; i++) { - checkType(types[i]); + for (Type type1 : Type.getArgumentTypes(signature)) { + checkType(type1); } } else { checkType(Type.getType(signature)); @@ -162,17 +163,16 @@ public class TransitiveHull extends org. } public String[] getIgnored() { - return _ignored; + return ignored; } /** - * Set the value of _ignored. - * - * @param v - * Value to assign to _ignored. + * Set the value of ignored. + * + * @param v Value to assign to ignored. */ public void setIgnored(String[] v) { - _ignored = v; + ignored = v; } public static void main(String[] argv) { Modified: commons/proper/bcel/trunk/src/examples/helloify.java URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/examples/helloify.java?rev=1661091&r1=1661090&r2=1661091&view=diff ============================================================================== --- commons/proper/bcel/trunk/src/examples/helloify.java (original) +++ commons/proper/bcel/trunk/src/examples/helloify.java Fri Feb 20 11:11:54 2015 @@ -15,6 +15,7 @@ * limitations under the License. * */ + import org.apache.bcel.Constants; import org.apache.bcel.classfile.ClassParser; import org.apache.bcel.classfile.Code; @@ -37,108 +38,99 @@ import org.apache.bcel.generic.PUSH; * Read class file(s) and patch all of its methods, so that they print * "hello" and their name and signature before doing anything else. * - * @version $Id$ * @author <A HREF="mailto:m.d...@gmx.de">M. Dahm</A> + * @version $Id$ */ public final class helloify implements Constants { - private static String class_name; - private static ConstantPoolGen cp; - private static int out; // reference to System.out - private static int println; // reference to PrintStream.println - - public static void main(String[] argv) { - try { - for(int i=0; i < argv.length; i++) { - if(argv[i].endsWith(".class")) { - JavaClass java_class = new ClassParser(argv[i]).parse(); - ConstantPool constants = java_class.getConstantPool(); - String file_name = argv[i].substring(0, argv[i].length() - 6) + - "_hello.class"; - cp = new ConstantPoolGen(constants); - - helloifyClassName(java_class); - - out = cp.addFieldref("java.lang.System", "out", - "Ljava/io/PrintStream;"); - println = cp.addMethodref("java.io.PrintStream", "println", - "(Ljava/lang/String;)V"); - /* Patch all methods. - */ - Method[] methods = java_class.getMethods(); - for(int j=0; j < methods.length; j++) { - methods[j] = helloifyMethod(methods[j]); + private static String class_name; + private static ConstantPoolGen cp; + private static int out; // reference to System.out + private static int println; // reference to PrintStream.println + + public static void main(String[] argv) throws Exception { + for (String arg : argv) { + if (arg.endsWith(".class")) { + JavaClass java_class = new ClassParser(arg).parse(); + ConstantPool constants = java_class.getConstantPool(); + String file_name = arg.substring(0, arg.length() - 6) + "_hello.class"; + cp = new ConstantPoolGen(constants); + + helloifyClassName(java_class); + + out = cp.addFieldref("java.lang.System", "out", "Ljava/io/PrintStream;"); + println = cp.addMethodref("java.io.PrintStream", "println", "(Ljava/lang/String;)V"); + // Patch all methods. + Method[] methods = java_class.getMethods(); + + for (int j = 0; j < methods.length; j++) { + methods[j] = helloifyMethod(methods[j]); + } + + // Finally dump it back to a file. + java_class.setConstantPool(cp.getFinalConstantPool()); + java_class.dump(file_name); + } + } } - /* Finally dump it back to a file. - */ - java_class.setConstantPool(cp.getFinalConstantPool()); - java_class.dump(file_name); - } - } - } catch(Exception e) { - e.printStackTrace(); - } - } - - /** Change class name to <old_name>_hello - */ - private static void helloifyClassName(JavaClass java_class ) { - class_name = java_class.getClassName() + "_hello"; - int index = java_class.getClassNameIndex(); - - index = ((ConstantClass)cp.getConstant(index)).getNameIndex(); - cp.setConstant(index, new ConstantUtf8(class_name.replace('.', '/'))); - } - - /** - * Patch a method. - */ - private static Method helloifyMethod(Method m) { - Code code = m.getCode(); - int flags = m.getAccessFlags(); - String name = m.getName(); - - // Sanity check - if(m.isNative() || m.isAbstract() || (code == null)) { - return m; - } - - /* Create instruction list to be inserted at method start. + /** + * Change class name to <old_name>_hello */ - String mesg = "Hello from " + Utility.methodSignatureToString(m.getSignature(), - name, - Utility.accessToString(flags)); - InstructionList patch = new InstructionList(); - patch.append(new GETSTATIC(out)); - patch.append(new PUSH(cp, mesg)); - patch.append(new INVOKEVIRTUAL(println)); - - MethodGen mg = new MethodGen(m, class_name, cp); - InstructionList il = mg.getInstructionList(); - InstructionHandle[] ihs = il.getInstructionHandles(); - - if(name.equals("<init>")) { // First let the super or other constructor be called - for(int j=1; j < ihs.length; j++) { - if(ihs[j].getInstruction() instanceof INVOKESPECIAL) { - il.append(ihs[j], patch); // Should check: method name == "<init>" - break; - } - } - } else { - il.insert(ihs[0], patch); + private static void helloifyClassName(JavaClass java_class) { + class_name = java_class.getClassName() + "_hello"; + int index = java_class.getClassNameIndex(); + + index = ((ConstantClass) cp.getConstant(index)).getNameIndex(); + cp.setConstant(index, new ConstantUtf8(class_name.replace('.', '/'))); } - /* Stack size must be at least 2, since the println method takes 2 argument. + /** + * Patch a method. */ - if(code.getMaxStack() < 2) { - mg.setMaxStack(2); - } + private static Method helloifyMethod(Method m) { + Code code = m.getCode(); + int flags = m.getAccessFlags(); + String name = m.getName(); + + // Sanity check + if (m.isNative() || m.isAbstract() || (code == null)) { + return m; + } + + // Create instruction list to be inserted at method start. + String mesg = "Hello from " + Utility.methodSignatureToString(m.getSignature(), + name, + Utility.accessToString(flags)); + InstructionList patch = new InstructionList(); + patch.append(new GETSTATIC(out)); + patch.append(new PUSH(cp, mesg)); + patch.append(new INVOKEVIRTUAL(println)); + + MethodGen mg = new MethodGen(m, class_name, cp); + InstructionList il = mg.getInstructionList(); + InstructionHandle[] ihs = il.getInstructionHandles(); + + if (name.equals("<init>")) { // First let the super or other constructor be called + for (int j = 1; j < ihs.length; j++) { + if (ihs[j].getInstruction() instanceof INVOKESPECIAL) { + il.append(ihs[j], patch); // Should check: method name == "<init>" + break; + } + } + } else { + il.insert(ihs[0], patch); + } + + // Stack size must be at least 2, since the println method takes 2 argument. + if (code.getMaxStack() < 2) { + mg.setMaxStack(2); + } - m = mg.getMethod(); + m = mg.getMethod(); - il.dispose(); // Reuse instruction handles - - return m; - } + il.dispose(); // Reuse instruction handles + + return m; + } } Modified: commons/proper/bcel/trunk/src/examples/id.java URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/examples/id.java?rev=1661091&r1=1661090&r2=1661091&view=diff ============================================================================== --- commons/proper/bcel/trunk/src/examples/id.java (original) +++ commons/proper/bcel/trunk/src/examples/id.java Fri Feb 20 11:11:54 2015 @@ -15,6 +15,7 @@ * limitations under the License. * */ + import org.apache.bcel.Repository; import org.apache.bcel.classfile.ClassParser; import org.apache.bcel.classfile.Field; @@ -31,39 +32,36 @@ import org.apache.bcel.generic.MethodGen * * Try to: * <pre> -% java id <someclass> -% java listclass -code <someclass> > foo -% java listclass -code <someclass>.clazz > bar -% diff foo bar | more + * % java id <someclass> + * % java listclass -code <someclass> > foo + * % java listclass -code <someclass>.clazz > bar + * % diff foo bar | more * <pre> * - * @version $Id$ * @author <A HREF="mailto:m.d...@gmx.de">M. Dahm</A> + * @version $Id$ */ public class id { - public static void main(String[] argv) throws Exception { - JavaClass clazz = null; - - if((clazz = Repository.lookupClass(argv[0])) == null) { - clazz = new ClassParser(argv[0]).parse(); // May throw IOException - } - ClassGen cg = new ClassGen(clazz); + public static void main(String[] argv) throws Exception { + JavaClass clazz; - Method[] methods = clazz.getMethods(); + if ((clazz = Repository.lookupClass(argv[0])) == null) { + clazz = new ClassParser(argv[0]).parse(); // May throw IOException + } + + ClassGen cg = new ClassGen(clazz); + + for (Method method : clazz.getMethods()) { + MethodGen mg = new MethodGen(method, cg.getClassName(), cg.getConstantPool()); + cg.replaceMethod(method, mg.getMethod()); + } + + for (Field field : clazz.getFields()) { + FieldGen fg = new FieldGen(field, cg.getConstantPool()); + cg.replaceField(field, fg.getField()); + } - for(int i=0; i < methods.length; i++) { - MethodGen mg = new MethodGen(methods[i], cg.getClassName(), cg.getConstantPool()); - cg.replaceMethod(methods[i], mg.getMethod()); + cg.getJavaClass().dump(clazz.getClassName() + ".clazz"); } - - Field[] fields = clazz.getFields(); - - for(int i=0; i < fields.length; i++) { - FieldGen fg = new FieldGen(fields[i], cg.getConstantPool()); - cg.replaceField(fields[i], fg.getField()); - } - - cg.getJavaClass().dump(clazz.getClassName() + ".clazz"); - } }