Added: tapestry/tapestry5/trunk/plastic/src/external/java/org/objectweb/asm/commons/AnalyzerAdapter.java URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/plastic/src/external/java/org/objectweb/asm/commons/AnalyzerAdapter.java?rev=1089584&view=auto ============================================================================== --- tapestry/tapestry5/trunk/plastic/src/external/java/org/objectweb/asm/commons/AnalyzerAdapter.java (added) +++ tapestry/tapestry5/trunk/plastic/src/external/java/org/objectweb/asm/commons/AnalyzerAdapter.java Wed Apr 6 19:11:34 2011 @@ -0,0 +1,877 @@ +/*** + * ASM: a very small and fast Java bytecode manipulation framework + * Copyright (c) 2000-2007 INRIA, France Telecom + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.objectweb.asm.commons; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.objectweb.asm.Label; +import org.objectweb.asm.MethodAdapter; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.Type; + +/** + * A {@link MethodAdapter} that keeps track of stack map frame changes between + * {@link #visitFrame(int, int, Object[], int, Object[]) visitFrame} calls. This + * adapter must be used with the + * {@link org.objectweb.asm.ClassReader#EXPAND_FRAMES} option. Each visit<i>X</i> + * instruction delegates to the next visitor in the chain, if any, and then + * simulates the effect of this instruction on the stack map frame, represented + * by {@link #locals} and {@link #stack}. The next visitor in the chain can get + * the state of the stack map frame <i>before</i> each instruction by reading + * the value of these fields in its visit<i>X</i> methods (this requires a + * reference to the AnalyzerAdapter that is before it in the chain). + * If this adapter is used with a class that does not contain stack map table + * attributes (i.e., pre Java 6 classes) then this adapter may not be able to + * compute the stack map frame for each instruction. In this case no exception + * is thrown but the {@link #locals} and {@link #stack} fields will be null for + * these instructions. + * + * @author Eric Bruneton + */ +public class AnalyzerAdapter extends MethodAdapter { + + /** + * <code>List</code> of the local variable slots for current execution + * frame. Primitive types are represented by {@link Opcodes#TOP}, + * {@link Opcodes#INTEGER}, {@link Opcodes#FLOAT}, {@link Opcodes#LONG}, + * {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or + * {@link Opcodes#UNINITIALIZED_THIS} (long and double are represented by a + * two elements, the second one being TOP). Reference types are represented + * by String objects (representing internal names), and uninitialized types + * by Label objects (this label designates the NEW instruction that created + * this uninitialized value). This field is <tt>null</tt> for unreacheable + * instructions. + */ + public List locals; + + /** + * <code>List</code> of the operand stack slots for current execution + * frame. Primitive types are represented by {@link Opcodes#TOP}, + * {@link Opcodes#INTEGER}, {@link Opcodes#FLOAT}, {@link Opcodes#LONG}, + * {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or + * {@link Opcodes#UNINITIALIZED_THIS} (long and double are represented by a + * two elements, the second one being TOP). Reference types are represented + * by String objects (representing internal names), and uninitialized types + * by Label objects (this label designates the NEW instruction that created + * this uninitialized value). This field is <tt>null</tt> for unreacheable + * instructions. + */ + public List stack; + + /** + * The labels that designate the next instruction to be visited. May be + * <tt>null</tt>. + */ + private List labels; + + /** + * Information about uninitialized types in the current execution frame. + * This map associates internal names to Label objects. Each label + * designates a NEW instruction that created the currently uninitialized + * types, and the associated internal name represents the NEW operand, i.e. + * the final, initialized type value. + */ + public Map uninitializedTypes; + + /** + * The maximum stack size of this method. + */ + private int maxStack; + + /** + * The maximum number of local variables of this method. + */ + private int maxLocals; + + /** + * The owner's class name. + */ + private String owner; + + /** + * Creates a new {@link AnalyzerAdapter}. + * + * @param owner the owner's class name. + * @param access the method's access flags (see {@link Opcodes}). + * @param name the method's name. + * @param desc the method's descriptor (see {@link Type Type}). + * @param mv the method visitor to which this adapter delegates calls. May + * be <tt>null</tt>. + */ + public AnalyzerAdapter( + final String owner, + final int access, + final String name, + final String desc, + final MethodVisitor mv) + { + super(mv); + this.owner = owner; + locals = new ArrayList(); + stack = new ArrayList(); + uninitializedTypes = new HashMap(); + + if ((access & Opcodes.ACC_STATIC) == 0) { + if ("<init>".equals(name)) { + locals.add(Opcodes.UNINITIALIZED_THIS); + } else { + locals.add(owner); + } + } + Type[] types = Type.getArgumentTypes(desc); + for (int i = 0; i < types.length; ++i) { + Type type = types[i]; + switch (type.getSort()) { + case Type.BOOLEAN: + case Type.CHAR: + case Type.BYTE: + case Type.SHORT: + case Type.INT: + locals.add(Opcodes.INTEGER); + break; + case Type.FLOAT: + locals.add(Opcodes.FLOAT); + break; + case Type.LONG: + locals.add(Opcodes.LONG); + locals.add(Opcodes.TOP); + break; + case Type.DOUBLE: + locals.add(Opcodes.DOUBLE); + locals.add(Opcodes.TOP); + break; + case Type.ARRAY: + locals.add(types[i].getDescriptor()); + break; + // case Type.OBJECT: + default: + locals.add(types[i].getInternalName()); + } + } + } + + public void visitFrame( + final int type, + final int nLocal, + final Object[] local, + final int nStack, + final Object[] stack) + { + if (type != Opcodes.F_NEW) { // uncompressed frame + throw new IllegalStateException("ClassReader.accept() should be called with EXPAND_FRAMES flag"); + } + + if (mv != null) { + mv.visitFrame(type, nLocal, local, nStack, stack); + } + + if (this.locals != null) { + this.locals.clear(); + this.stack.clear(); + } else { + this.locals = new ArrayList(); + this.stack = new ArrayList(); + } + visitFrameTypes(nLocal, local, this.locals); + visitFrameTypes(nStack, stack, this.stack); + maxStack = Math.max(maxStack, this.stack.size()); + } + + private static void visitFrameTypes( + final int n, + final Object[] types, + final List result) + { + for (int i = 0; i < n; ++i) { + Object type = types[i]; + result.add(type); + if (type == Opcodes.LONG || type == Opcodes.DOUBLE) { + result.add(Opcodes.TOP); + } + } + } + + public void visitInsn(final int opcode) { + if (mv != null) { + mv.visitInsn(opcode); + } + execute(opcode, 0, null); + if ((opcode >= Opcodes.IRETURN && opcode <= Opcodes.RETURN) + || opcode == Opcodes.ATHROW) + { + this.locals = null; + this.stack = null; + } + } + + public void visitIntInsn(final int opcode, final int operand) { + if (mv != null) { + mv.visitIntInsn(opcode, operand); + } + execute(opcode, operand, null); + } + + public void visitVarInsn(final int opcode, final int var) { + if (mv != null) { + mv.visitVarInsn(opcode, var); + } + execute(opcode, var, null); + } + + public void visitTypeInsn(final int opcode, final String type) { + if (opcode == Opcodes.NEW) { + if (labels == null) { + Label l = new Label(); + labels = new ArrayList(3); + labels.add(l); + if (mv != null) { + mv.visitLabel(l); + } + } + for (int i = 0; i < labels.size(); ++i) { + uninitializedTypes.put(labels.get(i), type); + } + } + if (mv != null) { + mv.visitTypeInsn(opcode, type); + } + execute(opcode, 0, type); + } + + public void visitFieldInsn( + final int opcode, + final String owner, + final String name, + final String desc) + { + if (mv != null) { + mv.visitFieldInsn(opcode, owner, name, desc); + } + execute(opcode, 0, desc); + } + + public void visitMethodInsn( + final int opcode, + final String owner, + final String name, + final String desc) + { + if (mv != null) { + mv.visitMethodInsn(opcode, owner, name, desc); + } + if (this.locals == null) { + labels = null; + return; + } + pop(desc); + if (opcode != Opcodes.INVOKESTATIC && opcode != Opcodes.INVOKEDYNAMIC) { + Object t = pop(); + if (opcode == Opcodes.INVOKESPECIAL && name.charAt(0) == '<') { + Object u; + if (t == Opcodes.UNINITIALIZED_THIS) { + u = this.owner; + } else { + u = uninitializedTypes.get(t); + } + for (int i = 0; i < locals.size(); ++i) { + if (locals.get(i) == t) { + locals.set(i, u); + } + } + for (int i = 0; i < stack.size(); ++i) { + if (stack.get(i) == t) { + stack.set(i, u); + } + } + } + } + pushDesc(desc); + labels = null; + } + + public void visitJumpInsn(final int opcode, final Label label) { + if (mv != null) { + mv.visitJumpInsn(opcode, label); + } + execute(opcode, 0, null); + if (opcode == Opcodes.GOTO) { + this.locals = null; + this.stack = null; + } + } + + public void visitLabel(final Label label) { + if (mv != null) { + mv.visitLabel(label); + } + if (labels == null) { + labels = new ArrayList(3); + } + labels.add(label); + } + + public void visitLdcInsn(final Object cst) { + if (mv != null) { + mv.visitLdcInsn(cst); + } + if (this.locals == null) { + labels = null; + return; + } + if (cst instanceof Integer) { + push(Opcodes.INTEGER); + } else if (cst instanceof Long) { + push(Opcodes.LONG); + push(Opcodes.TOP); + } else if (cst instanceof Float) { + push(Opcodes.FLOAT); + } else if (cst instanceof Double) { + push(Opcodes.DOUBLE); + push(Opcodes.TOP); + } else if (cst instanceof String) { + push("java/lang/String"); + } else if (cst instanceof Type) { + push("java/lang/Class"); + } else { + throw new IllegalArgumentException(); + } + labels = null; + } + + public void visitIincInsn(final int var, final int increment) { + if (mv != null) { + mv.visitIincInsn(var, increment); + } + execute(Opcodes.IINC, var, null); + } + + public void visitTableSwitchInsn( + final int min, + final int max, + final Label dflt, + final Label[] labels) + { + if (mv != null) { + mv.visitTableSwitchInsn(min, max, dflt, labels); + } + execute(Opcodes.TABLESWITCH, 0, null); + this.locals = null; + this.stack = null; + } + + public void visitLookupSwitchInsn( + final Label dflt, + final int[] keys, + final Label[] labels) + { + if (mv != null) { + mv.visitLookupSwitchInsn(dflt, keys, labels); + } + execute(Opcodes.LOOKUPSWITCH, 0, null); + this.locals = null; + this.stack = null; + } + + public void visitMultiANewArrayInsn(final String desc, final int dims) { + if (mv != null) { + mv.visitMultiANewArrayInsn(desc, dims); + } + execute(Opcodes.MULTIANEWARRAY, dims, desc); + } + + public void visitMaxs(final int maxStack, final int maxLocals) { + if (mv != null) { + this.maxStack = Math.max(this.maxStack, maxStack); + this.maxLocals = Math.max(this.maxLocals, maxLocals); + mv.visitMaxs(this.maxStack, this.maxLocals); + } + } + + // ------------------------------------------------------------------------ + + private Object get(final int local) { + maxLocals = Math.max(maxLocals, local); + return local < locals.size() ? locals.get(local) : Opcodes.TOP; + } + + private void set(final int local, final Object type) { + maxLocals = Math.max(maxLocals, local); + while (local >= locals.size()) { + locals.add(Opcodes.TOP); + } + locals.set(local, type); + } + + private void push(final Object type) { + stack.add(type); + maxStack = Math.max(maxStack, stack.size()); + } + + private void pushDesc(final String desc) { + int index = desc.charAt(0) == '(' ? desc.indexOf(')') + 1 : 0; + switch (desc.charAt(index)) { + case 'V': + return; + case 'Z': + case 'C': + case 'B': + case 'S': + case 'I': + push(Opcodes.INTEGER); + return; + case 'F': + push(Opcodes.FLOAT); + return; + case 'J': + push(Opcodes.LONG); + push(Opcodes.TOP); + return; + case 'D': + push(Opcodes.DOUBLE); + push(Opcodes.TOP); + return; + case '[': + if (index == 0) { + push(desc); + } else { + push(desc.substring(index, desc.length())); + } + break; + // case 'L': + default: + if (index == 0) { + push(desc.substring(1, desc.length() - 1)); + } else { + push(desc.substring(index + 1, desc.length() - 1)); + } + } + } + + private Object pop() { + return stack.remove(stack.size() - 1); + } + + private void pop(final int n) { + int size = stack.size(); + int end = size - n; + for (int i = size - 1; i >= end; --i) { + stack.remove(i); + } + } + + private void pop(final String desc) { + char c = desc.charAt(0); + if (c == '(') { + int n = 0; + Type[] types = Type.getArgumentTypes(desc); + for (int i = 0; i < types.length; ++i) { + n += types[i].getSize(); + } + pop(n); + } else if (c == 'J' || c == 'D') { + pop(2); + } else { + pop(1); + } + } + + private void execute(final int opcode, final int iarg, final String sarg) { + if (this.locals == null) { + labels = null; + return; + } + Object t1, t2, t3, t4; + switch (opcode) { + case Opcodes.NOP: + case Opcodes.INEG: + case Opcodes.LNEG: + case Opcodes.FNEG: + case Opcodes.DNEG: + case Opcodes.I2B: + case Opcodes.I2C: + case Opcodes.I2S: + case Opcodes.GOTO: + case Opcodes.RETURN: + break; + case Opcodes.ACONST_NULL: + push(Opcodes.NULL); + break; + case Opcodes.ICONST_M1: + case Opcodes.ICONST_0: + case Opcodes.ICONST_1: + case Opcodes.ICONST_2: + case Opcodes.ICONST_3: + case Opcodes.ICONST_4: + case Opcodes.ICONST_5: + case Opcodes.BIPUSH: + case Opcodes.SIPUSH: + push(Opcodes.INTEGER); + break; + case Opcodes.LCONST_0: + case Opcodes.LCONST_1: + push(Opcodes.LONG); + push(Opcodes.TOP); + break; + case Opcodes.FCONST_0: + case Opcodes.FCONST_1: + case Opcodes.FCONST_2: + push(Opcodes.FLOAT); + break; + case Opcodes.DCONST_0: + case Opcodes.DCONST_1: + push(Opcodes.DOUBLE); + push(Opcodes.TOP); + break; + case Opcodes.ILOAD: + case Opcodes.FLOAD: + case Opcodes.ALOAD: + push(get(iarg)); + break; + case Opcodes.LLOAD: + case Opcodes.DLOAD: + push(get(iarg)); + push(Opcodes.TOP); + break; + case Opcodes.IALOAD: + case Opcodes.BALOAD: + case Opcodes.CALOAD: + case Opcodes.SALOAD: + pop(2); + push(Opcodes.INTEGER); + break; + case Opcodes.LALOAD: + case Opcodes.D2L: + pop(2); + push(Opcodes.LONG); + push(Opcodes.TOP); + break; + case Opcodes.FALOAD: + pop(2); + push(Opcodes.FLOAT); + break; + case Opcodes.DALOAD: + case Opcodes.L2D: + pop(2); + push(Opcodes.DOUBLE); + push(Opcodes.TOP); + break; + case Opcodes.AALOAD: + pop(1); + t1 = pop(); + if (t1 instanceof String) { + pushDesc(((String) t1).substring(1)); + } else { + push("java/lang/Object"); + } + break; + case Opcodes.ISTORE: + case Opcodes.FSTORE: + case Opcodes.ASTORE: + t1 = pop(); + set(iarg, t1); + if (iarg > 0) { + t2 = get(iarg - 1); + if (t2 == Opcodes.LONG || t2 == Opcodes.DOUBLE) { + set(iarg - 1, Opcodes.TOP); + } + } + break; + case Opcodes.LSTORE: + case Opcodes.DSTORE: + pop(1); + t1 = pop(); + set(iarg, t1); + set(iarg + 1, Opcodes.TOP); + if (iarg > 0) { + t2 = get(iarg - 1); + if (t2 == Opcodes.LONG || t2 == Opcodes.DOUBLE) { + set(iarg - 1, Opcodes.TOP); + } + } + break; + case Opcodes.IASTORE: + case Opcodes.BASTORE: + case Opcodes.CASTORE: + case Opcodes.SASTORE: + case Opcodes.FASTORE: + case Opcodes.AASTORE: + pop(3); + break; + case Opcodes.LASTORE: + case Opcodes.DASTORE: + pop(4); + break; + case Opcodes.POP: + case Opcodes.IFEQ: + case Opcodes.IFNE: + case Opcodes.IFLT: + case Opcodes.IFGE: + case Opcodes.IFGT: + case Opcodes.IFLE: + case Opcodes.IRETURN: + case Opcodes.FRETURN: + case Opcodes.ARETURN: + case Opcodes.TABLESWITCH: + case Opcodes.LOOKUPSWITCH: + case Opcodes.ATHROW: + case Opcodes.MONITORENTER: + case Opcodes.MONITOREXIT: + case Opcodes.IFNULL: + case Opcodes.IFNONNULL: + pop(1); + break; + case Opcodes.POP2: + case Opcodes.IF_ICMPEQ: + case Opcodes.IF_ICMPNE: + case Opcodes.IF_ICMPLT: + case Opcodes.IF_ICMPGE: + case Opcodes.IF_ICMPGT: + case Opcodes.IF_ICMPLE: + case Opcodes.IF_ACMPEQ: + case Opcodes.IF_ACMPNE: + case Opcodes.LRETURN: + case Opcodes.DRETURN: + pop(2); + break; + case Opcodes.DUP: + t1 = pop(); + push(t1); + push(t1); + break; + case Opcodes.DUP_X1: + t1 = pop(); + t2 = pop(); + push(t1); + push(t2); + push(t1); + break; + case Opcodes.DUP_X2: + t1 = pop(); + t2 = pop(); + t3 = pop(); + push(t1); + push(t3); + push(t2); + push(t1); + break; + case Opcodes.DUP2: + t1 = pop(); + t2 = pop(); + push(t2); + push(t1); + push(t2); + push(t1); + break; + case Opcodes.DUP2_X1: + t1 = pop(); + t2 = pop(); + t3 = pop(); + push(t2); + push(t1); + push(t3); + push(t2); + push(t1); + break; + case Opcodes.DUP2_X2: + t1 = pop(); + t2 = pop(); + t3 = pop(); + t4 = pop(); + push(t2); + push(t1); + push(t4); + push(t3); + push(t2); + push(t1); + break; + case Opcodes.SWAP: + t1 = pop(); + t2 = pop(); + push(t1); + push(t2); + break; + case Opcodes.IADD: + case Opcodes.ISUB: + case Opcodes.IMUL: + case Opcodes.IDIV: + case Opcodes.IREM: + case Opcodes.IAND: + case Opcodes.IOR: + case Opcodes.IXOR: + case Opcodes.ISHL: + case Opcodes.ISHR: + case Opcodes.IUSHR: + case Opcodes.L2I: + case Opcodes.D2I: + case Opcodes.FCMPL: + case Opcodes.FCMPG: + pop(2); + push(Opcodes.INTEGER); + break; + case Opcodes.LADD: + case Opcodes.LSUB: + case Opcodes.LMUL: + case Opcodes.LDIV: + case Opcodes.LREM: + case Opcodes.LAND: + case Opcodes.LOR: + case Opcodes.LXOR: + pop(4); + push(Opcodes.LONG); + push(Opcodes.TOP); + break; + case Opcodes.FADD: + case Opcodes.FSUB: + case Opcodes.FMUL: + case Opcodes.FDIV: + case Opcodes.FREM: + case Opcodes.L2F: + case Opcodes.D2F: + pop(2); + push(Opcodes.FLOAT); + break; + case Opcodes.DADD: + case Opcodes.DSUB: + case Opcodes.DMUL: + case Opcodes.DDIV: + case Opcodes.DREM: + pop(4); + push(Opcodes.DOUBLE); + push(Opcodes.TOP); + break; + case Opcodes.LSHL: + case Opcodes.LSHR: + case Opcodes.LUSHR: + pop(3); + push(Opcodes.LONG); + push(Opcodes.TOP); + break; + case Opcodes.IINC: + set(iarg, Opcodes.INTEGER); + break; + case Opcodes.I2L: + case Opcodes.F2L: + pop(1); + push(Opcodes.LONG); + push(Opcodes.TOP); + break; + case Opcodes.I2F: + pop(1); + push(Opcodes.FLOAT); + break; + case Opcodes.I2D: + case Opcodes.F2D: + pop(1); + push(Opcodes.DOUBLE); + push(Opcodes.TOP); + break; + case Opcodes.F2I: + case Opcodes.ARRAYLENGTH: + case Opcodes.INSTANCEOF: + pop(1); + push(Opcodes.INTEGER); + break; + case Opcodes.LCMP: + case Opcodes.DCMPL: + case Opcodes.DCMPG: + pop(4); + push(Opcodes.INTEGER); + break; + case Opcodes.JSR: + case Opcodes.RET: + throw new RuntimeException("JSR/RET are not supported"); + case Opcodes.GETSTATIC: + pushDesc(sarg); + break; + case Opcodes.PUTSTATIC: + pop(sarg); + break; + case Opcodes.GETFIELD: + pop(1); + pushDesc(sarg); + break; + case Opcodes.PUTFIELD: + pop(sarg); + pop(); + break; + case Opcodes.NEW: + push(labels.get(0)); + break; + case Opcodes.NEWARRAY: + pop(); + switch (iarg) { + case Opcodes.T_BOOLEAN: + pushDesc("[Z"); + break; + case Opcodes.T_CHAR: + pushDesc("[C"); + break; + case Opcodes.T_BYTE: + pushDesc("[B"); + break; + case Opcodes.T_SHORT: + pushDesc("[S"); + break; + case Opcodes.T_INT: + pushDesc("[I"); + break; + case Opcodes.T_FLOAT: + pushDesc("[F"); + break; + case Opcodes.T_DOUBLE: + pushDesc("[D"); + break; + // case Opcodes.T_LONG: + default: + pushDesc("[J"); + break; + } + break; + case Opcodes.ANEWARRAY: + pop(); + pushDesc("[" + Type.getObjectType(sarg)); + break; + case Opcodes.CHECKCAST: + pop(); + pushDesc(Type.getObjectType(sarg).getDescriptor()); + break; + // case Opcodes.MULTIANEWARRAY: + default: + pop(iarg); + pushDesc(sarg); + break; + } + labels = null; + } +}
Added: tapestry/tapestry5/trunk/plastic/src/external/java/org/objectweb/asm/commons/CodeSizeEvaluator.java URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/plastic/src/external/java/org/objectweb/asm/commons/CodeSizeEvaluator.java?rev=1089584&view=auto ============================================================================== --- tapestry/tapestry5/trunk/plastic/src/external/java/org/objectweb/asm/commons/CodeSizeEvaluator.java (added) +++ tapestry/tapestry5/trunk/plastic/src/external/java/org/objectweb/asm/commons/CodeSizeEvaluator.java Wed Apr 6 19:11:34 2011 @@ -0,0 +1,206 @@ +/*** + * ASM: a very small and fast Java bytecode manipulation framework + * Copyright (c) 2000-2007 INRIA, France Telecom + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.objectweb.asm.commons; + +import org.objectweb.asm.Label; +import org.objectweb.asm.MethodAdapter; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; + +/** + * A {@link MethodAdapter} that can be used to approximate method size. + * + * @author Eugene Kuleshov + */ +public class CodeSizeEvaluator extends MethodAdapter implements Opcodes { + + private int minSize; + + private int maxSize; + + public CodeSizeEvaluator(final MethodVisitor mv) { + super(mv); + } + + public int getMinSize() { + return this.minSize; + } + + public int getMaxSize() { + return this.maxSize; + } + + public void visitInsn(final int opcode) { + minSize += 1; + maxSize += 1; + if (mv != null) { + mv.visitInsn(opcode); + } + } + + public void visitIntInsn(final int opcode, final int operand) { + if (opcode == SIPUSH) { + minSize += 3; + maxSize += 3; + } else { + minSize += 2; + maxSize += 2; + } + if (mv != null) { + mv.visitIntInsn(opcode, operand); + } + } + + public void visitVarInsn(final int opcode, final int var) { + if (var < 4 && opcode != RET) { + minSize += 1; + maxSize += 1; + } else if (var >= 256) { + minSize += 4; + maxSize += 4; + } else { + minSize += 2; + maxSize += 2; + } + if (mv != null) { + mv.visitVarInsn(opcode, var); + } + } + + public void visitTypeInsn(final int opcode, final String type) { + minSize += 3; + maxSize += 3; + if (mv != null) { + mv.visitTypeInsn(opcode, type); + } + } + + public void visitFieldInsn( + final int opcode, + final String owner, + final String name, + final String desc) + { + minSize += 3; + maxSize += 3; + if (mv != null) { + mv.visitFieldInsn(opcode, owner, name, desc); + } + } + + public void visitMethodInsn( + final int opcode, + final String owner, + final String name, + final String desc) + { + if (opcode == INVOKEINTERFACE || opcode == INVOKEDYNAMIC) { + minSize += 5; + maxSize += 5; + } else { + minSize += 3; + maxSize += 3; + } + if (mv != null) { + mv.visitMethodInsn(opcode, owner, name, desc); + } + } + + public void visitJumpInsn(final int opcode, final Label label) { + minSize += 3; + if (opcode == GOTO || opcode == JSR) { + maxSize += 5; + } else { + maxSize += 8; + } + if (mv != null) { + mv.visitJumpInsn(opcode, label); + } + } + + public void visitLdcInsn(final Object cst) { + if (cst instanceof Long || cst instanceof Double) { + minSize += 3; + maxSize += 3; + } else { + minSize += 2; + maxSize += 3; + } + if (mv != null) { + mv.visitLdcInsn(cst); + } + } + + public void visitIincInsn(final int var, final int increment) { + if (var > 255 || increment > 127 || increment < -128) { + minSize += 6; + maxSize += 6; + } else { + minSize += 3; + maxSize += 3; + } + if (mv != null) { + mv.visitIincInsn(var, increment); + } + } + + public void visitTableSwitchInsn( + final int min, + final int max, + final Label dflt, + final Label[] labels) + { + minSize += 13 + labels.length * 4; + maxSize += 16 + labels.length * 4; + if (mv != null) { + mv.visitTableSwitchInsn(min, max, dflt, labels); + } + } + + public void visitLookupSwitchInsn( + final Label dflt, + final int[] keys, + final Label[] labels) + { + minSize += 9 + keys.length * 8; + maxSize += 12 + keys.length * 8; + if (mv != null) { + mv.visitLookupSwitchInsn(dflt, keys, labels); + } + } + + public void visitMultiANewArrayInsn(final String desc, final int dims) { + minSize += 4; + maxSize += 4; + if (mv != null) { + mv.visitMultiANewArrayInsn(desc, dims); + } + } +} Added: tapestry/tapestry5/trunk/plastic/src/external/java/org/objectweb/asm/commons/EmptyVisitor.java URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/plastic/src/external/java/org/objectweb/asm/commons/EmptyVisitor.java?rev=1089584&view=auto ============================================================================== --- tapestry/tapestry5/trunk/plastic/src/external/java/org/objectweb/asm/commons/EmptyVisitor.java (added) +++ tapestry/tapestry5/trunk/plastic/src/external/java/org/objectweb/asm/commons/EmptyVisitor.java Wed Apr 6 19:11:34 2011 @@ -0,0 +1,238 @@ +/*** + * ASM: a very small and fast Java bytecode manipulation framework + * Copyright (c) 2000-2007 INRIA, France Telecom + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.objectweb.asm.commons; + +import org.objectweb.asm.AnnotationVisitor; +import org.objectweb.asm.Attribute; +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.FieldVisitor; +import org.objectweb.asm.Label; +import org.objectweb.asm.MethodVisitor; + +/** + * An empty implementation of the ASM visitor interfaces. + * + * @author Eric Bruneton + */ +public class EmptyVisitor implements + ClassVisitor, + FieldVisitor, + MethodVisitor, + AnnotationVisitor +{ + + public void visit( + final int version, + final int access, + final String name, + final String signature, + final String superName, + final String[] interfaces) + { + } + + public void visitSource(final String source, final String debug) { + } + + public void visitOuterClass( + final String owner, + final String name, + final String desc) + { + } + + public AnnotationVisitor visitAnnotation( + final String desc, + final boolean visible) + { + return this; + } + + public void visitAttribute(final Attribute attr) { + } + + public void visitInnerClass( + final String name, + final String outerName, + final String innerName, + final int access) + { + } + + public FieldVisitor visitField( + final int access, + final String name, + final String desc, + final String signature, + final Object value) + { + return this; + } + + public MethodVisitor visitMethod( + final int access, + final String name, + final String desc, + final String signature, + final String[] exceptions) + { + return this; + } + + public void visitEnd() { + } + + public AnnotationVisitor visitAnnotationDefault() { + return this; + } + + public AnnotationVisitor visitParameterAnnotation( + final int parameter, + final String desc, + final boolean visible) + { + return this; + } + + public void visitCode() { + } + + public void visitFrame( + final int type, + final int nLocal, + final Object[] local, + final int nStack, + final Object[] stack) + { + } + + public void visitInsn(final int opcode) { + } + + public void visitIntInsn(final int opcode, final int operand) { + } + + public void visitVarInsn(final int opcode, final int var) { + } + + public void visitTypeInsn(final int opcode, final String type) { + } + + public void visitFieldInsn( + final int opcode, + final String owner, + final String name, + final String desc) + { + } + + public void visitMethodInsn( + final int opcode, + final String owner, + final String name, + final String desc) + { + } + + public void visitJumpInsn(final int opcode, final Label label) { + } + + public void visitLabel(final Label label) { + } + + public void visitLdcInsn(final Object cst) { + } + + public void visitIincInsn(final int var, final int increment) { + } + + public void visitTableSwitchInsn( + final int min, + final int max, + final Label dflt, + final Label[] labels) + { + } + + public void visitLookupSwitchInsn( + final Label dflt, + final int[] keys, + final Label[] labels) + { + } + + public void visitMultiANewArrayInsn(final String desc, final int dims) { + } + + public void visitTryCatchBlock( + final Label start, + final Label end, + final Label handler, + final String type) + { + } + + public void visitLocalVariable( + final String name, + final String desc, + final String signature, + final Label start, + final Label end, + final int index) + { + } + + public void visitLineNumber(final int line, final Label start) { + } + + public void visitMaxs(final int maxStack, final int maxLocals) { + } + + public void visit(final String name, final Object value) { + } + + public void visitEnum( + final String name, + final String desc, + final String value) + { + } + + public AnnotationVisitor visitAnnotation( + final String name, + final String desc) + { + return this; + } + + public AnnotationVisitor visitArray(final String name) { + return this; + } +}
