📄 manual.txt
字号:
[CCZ97] Suzanne Collin, Dominique Colnet, and Olivier Zendra. Type Inference for Late Binding. The SmallEiffel Compiler. In Proceedings JMLC'97, 1997.[Cos98] Pascal Costanza. The ClassFilters package. Universit"at Bonn, http://www.cs. uni-bonn.de/~costanza/ClassFilters/, 1998. 22[FM98] C. Fischer and D. Meemken. JaWa: Java with Assertions. In Clemens Cap, editor, Proceedings JIT'98. Springer, 1998.[GHJV95] E. Gamma, R. Helm, R. Johnson, and J. Vlissides. Design Patterns: Elements of Reusable Object-Oriented Software. Addison-Wesley, 1995.[GJS96] J. Gosling, B. Joy, and G. Steele. The Java Language Specification. Addison-Wesley, 1996.[Jav98] JavaSoft. Reflection API. http://java.sun.com/products/jdk/1.1/docs/ guide/reflection/, 1998.[KH98] Ralph Keller and Urs Ho"lzle. Binary Component Adaptation. In Eric Jul, editor, Proceedings ECOOP'98. Springer, 1998.[KLM+ 97] Gregor Kiczales, John Lamping, Anurag Mendhekar, Chris Maeda, Cristina Lopes, Jean-Marc Loingtier, and John Irwin. Aspect-Oriented Programming. Technical re- port, Xerox Palo Alto Research Center, 1997.[LB98] Sheng Lian and Gilad Bracha. Dynamic Class Loading in the Java Virtual Machine. In Proceedings OOPSLA'98, 1998.[LY97] Tim Lindholm and Frank Yellin. The Java Virtual Machine Specification. Addison- Wesley, 1997.[LZ98] Han Bok Lee and Benjamin G. Zorn. BIT: A Tool for Instrumenting Java Bytecodes. In Proceedings USENIX Symposium on Internet Technologies and Systems, 1998.[MBL97] A.C. Myers, J. A. Bank, and B. Liskov. Parameterized Types for Java. In Proceedings POPL'97, Paris, France, 1997.[MD97] J. Meyer and T. Downing. Java Virtual Machine. O'Reilly, 1997.[Sil98] Shawn Silverman. The classfile API. University of Manitoba, http://Meurrens. ML.org/ip-Links/java/codeEngineering/viewers.html, 1998.[Taf96] Tucker Taft. Programming the Internet in Ada95. In Proceedings Ada-Europe Interna- tional Conference on Reliable Software Technologies, 1996.[TK98] M. Thies and U. Kastens. Statische Analyse von Bibliotheken als Grundlage dy- namischer Optimierung. In Clemens Cap, editor, Proceedings JIT'98. Springer, 1998.[You98] Matt T. Yourst. Inside Java Class Files. Laserstars Technologies, http://www. laserstars.com/articles/ddj/insidejcf/, 1998. 23A Code examples for the BCEL APIA.1 HelloWorldBuilder.javaThe following Java program reads a name from the standard input and prints a friendly "Hello".Since the readLine() method may throw an IOException it is enclosed by a try-catchblock.import java.io.*;public class HelloWorld - 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) - return; " System.out.println("Hello, " + name); ""A.2 HelloWorldBuilder.javaWe will sketch here how the above Java class can be created from the scratch using the BCELAPI. For ease of reading we will use textual signatures and not create them dynamically. Forexample, the signature "(Ljava/lang/String;)Ljava/lang/StringBuffer;" would actually be created with Type.getMethodSignature(Type.STRINGBUFFER, new Type[] - Type.STRING ");A.2.1 Initialization:First we create an empty class and an instruction list: ClassGen cg = new ClassGen("HelloWorld", "java.lang.Object", "<generated>", ACC`PUBLIC -- ACC`SUPER, null); ConstantPoolGen cp = cg.getConstantPool(); // cg creates constant pool InstructionList il = new InstructionList(); We then create the main method, supplying the method's name and the symbolic type sig-nature encoded with Type objects. MethodGen mg = new MethodGen(ACC`STATIC -- 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); We define some often use types: ObjectType i`stream = new ObjectType("java.io.InputStream"); ObjectType p`stream = new ObjectType("java.io.PrintStream");A.2.2 Create variables in and name:We call the constructors, i.e. execute BufferedReader(InputStreamReader(System.in)).The reference to the BufferedReader object stays on top of the stack and is stored in the newlyallocated in variable. il.append(factory.createNew("java.io.BufferedReader")); il.append(InstructionConstants.DUP); // Use predefined constant il.append(factory.createNew("java.io.InputStreamReader")); il.append(InstructionConstants.DUP); il.append(factory.createFieldAccess("java.lang.System", "in", i`stream, Constants.GETSTATIC)); 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)); 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 and initialize it to null. 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 hereA.2.3 Create try-catch blockWe remember the start of the block, read a line from the standard input and store it into thevariable name. 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 knownyet. GOTO g = new GOTO(null); InstructionHandle try`end = il.append(g); We add the exception handler which simply returns from the method. InstructionHandle handler = il.append(InstructionConstants.RETURN); mg.addExceptionHandler(try`start, try`end, handler, "java.io.IOException"); "Normal" code continues, now we can set the branch target of the GOTO. InstructionHandle ih = il.append(factory.createFieldAccess("java.lang.System", "out", p`stream, Constants.GETSTATIC)); g.setTarget(ih);A.2.4 Printing "Hello"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.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);A.2.5 FinalizationFinally, we have to set the stack size, which normally would be computed on the fly and add adefault constructor method to the class, which is empty in this case. mg.setMaxStack(5); cg.addMethod(mg.getMethod()); il.dispose(); // Allow instruction handles to be reused cg.addEmptyConstructor(ACC`PUBLIC); Last but not least we dump the JavaClass object to a file. try - cg.getJavaClass().dump("HelloWorld.class"); " catch(java.io.IOException e) - System.err.println(e); "A.3 Peephole.javaThis class implements a simple peephole optimizer that removes any NOP instructions from thegiven class.import java.io.*;import java.util.Iterator;import org.apache.bcel.classfile.*;import org.apache.bcel.generic.*;import org.apache.bcel.Repository;import org.apache.bcel.util.InstructionFinder;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) // Any NOPs stripped? 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 final 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 i = f.search(pat); i.hasNext(); ) - InstructionHandle[] match = (InstructionHandle[])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 e) - InstructionHandle[] targets = e.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); " " " 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; ""Figure 8: UML diagram for the ConstantPool APIFigure 9: UML diagram for the Instruction API
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -