tapestry-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jkemn...@apache.org
Subject [7/9] tapestry-5 git commit: TAP5-2588: upgrade ASM to 6.0
Date Fri, 06 Oct 2017 14:31:22 GMT
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/74324b31/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/FieldWriter.java
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/FieldWriter.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/FieldWriter.java
index 4a5f406..f7bbe98 100644
--- a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/FieldWriter.java
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/FieldWriter.java
@@ -118,7 +118,7 @@ final class FieldWriter extends FieldVisitor {
      */
     FieldWriter(final ClassWriter cw, final int access, final String name,
             final String desc, final String signature, final Object value) {
-        super(Opcodes.ASM5);
+        super(Opcodes.ASM6);
         if (cw.firstField == null) {
             cw.firstField = this;
         } else {
@@ -129,7 +129,7 @@ final class FieldWriter extends FieldVisitor {
         this.access = access;
         this.name = cw.newUTF8(name);
         this.desc = cw.newUTF8(desc);
-        if (ClassReader.SIGNATURES && signature != null) {
+        if (signature != null) {
             this.signature = cw.newUTF8(signature);
         }
         if (value != null) {
@@ -144,9 +144,6 @@ final class FieldWriter extends FieldVisitor {
     @Override
     public AnnotationVisitor visitAnnotation(final String desc,
             final boolean visible) {
-        if (!ClassReader.ANNOTATIONS) {
-            return null;
-        }
         ByteVector bv = new ByteVector();
         // write type, and reserve space for values count
         bv.putShort(cw.newUTF8(desc)).putShort(0);
@@ -164,9 +161,6 @@ final class FieldWriter extends FieldVisitor {
     @Override
     public AnnotationVisitor visitTypeAnnotation(final int typeRef,
             final TypePath typePath, final String desc, final boolean visible) {
-        if (!ClassReader.ANNOTATIONS) {
-            return null;
-        }
         ByteVector bv = new ByteVector();
         // write target_type and target_info
         AnnotationWriter.putTarget(typeRef, typePath, bv);
@@ -220,23 +214,23 @@ final class FieldWriter extends FieldVisitor {
             cw.newUTF8("Deprecated");
             size += 6;
         }
-        if (ClassReader.SIGNATURES && signature != 0) {
+        if (signature != 0) {
             cw.newUTF8("Signature");
             size += 8;
         }
-        if (ClassReader.ANNOTATIONS && anns != null) {
+        if (anns != null) {
             cw.newUTF8("RuntimeVisibleAnnotations");
             size += 8 + anns.getSize();
         }
-        if (ClassReader.ANNOTATIONS && ianns != null) {
+        if (ianns != null) {
             cw.newUTF8("RuntimeInvisibleAnnotations");
             size += 8 + ianns.getSize();
         }
-        if (ClassReader.ANNOTATIONS && tanns != null) {
+        if (tanns != null) {
             cw.newUTF8("RuntimeVisibleTypeAnnotations");
             size += 8 + tanns.getSize();
         }
-        if (ClassReader.ANNOTATIONS && itanns != null) {
+        if (itanns != null) {
             cw.newUTF8("RuntimeInvisibleTypeAnnotations");
             size += 8 + itanns.getSize();
         }
@@ -270,19 +264,19 @@ final class FieldWriter extends FieldVisitor {
         if ((access & Opcodes.ACC_DEPRECATED) != 0) {
             ++attributeCount;
         }
-        if (ClassReader.SIGNATURES && signature != 0) {
+        if (signature != 0) {
             ++attributeCount;
         }
-        if (ClassReader.ANNOTATIONS && anns != null) {
+        if (anns != null) {
             ++attributeCount;
         }
-        if (ClassReader.ANNOTATIONS && ianns != null) {
+        if (ianns != null) {
             ++attributeCount;
         }
-        if (ClassReader.ANNOTATIONS && tanns != null) {
+        if (tanns != null) {
             ++attributeCount;
         }
-        if (ClassReader.ANNOTATIONS && itanns != null) {
+        if (itanns != null) {
             ++attributeCount;
         }
         if (attrs != null) {
@@ -302,23 +296,23 @@ final class FieldWriter extends FieldVisitor {
         if ((access & Opcodes.ACC_DEPRECATED) != 0) {
             out.putShort(cw.newUTF8("Deprecated")).putInt(0);
         }
-        if (ClassReader.SIGNATURES && signature != 0) {
+        if (signature != 0) {
             out.putShort(cw.newUTF8("Signature"));
             out.putInt(2).putShort(signature);
         }
-        if (ClassReader.ANNOTATIONS && anns != null) {
+        if (anns != null) {
             out.putShort(cw.newUTF8("RuntimeVisibleAnnotations"));
             anns.put(out);
         }
-        if (ClassReader.ANNOTATIONS && ianns != null) {
+        if (ianns != null) {
             out.putShort(cw.newUTF8("RuntimeInvisibleAnnotations"));
             ianns.put(out);
         }
-        if (ClassReader.ANNOTATIONS && tanns != null) {
+        if (tanns != null) {
             out.putShort(cw.newUTF8("RuntimeVisibleTypeAnnotations"));
             tanns.put(out);
         }
-        if (ClassReader.ANNOTATIONS && itanns != null) {
+        if (itanns != null) {
             out.putShort(cw.newUTF8("RuntimeInvisibleTypeAnnotations"));
             itanns.put(out);
         }

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/74324b31/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/Frame.java
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/Frame.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/Frame.java
index e0aa35c..de81b55 100644
--- a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/Frame.java
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/Frame.java
@@ -34,7 +34,7 @@ package org.apache.tapestry5.internal.plastic.asm;
  * 
  * @author Eric Bruneton
  */
-final class Frame {
+class Frame {
 
     /*
      * Frames are computed in a two steps process: during the visit of each
@@ -496,7 +496,7 @@ final class Frame {
      * When the stack map frames are completely computed, this field is the
      * actual number of types in {@link #outputStack}.
      */
-    private int outputStackTop;
+    int outputStackTop;
 
     /**
      * Number of types that are initialized in the basic block.
@@ -521,6 +521,110 @@ final class Frame {
     private int[] initializations;
 
     /**
+     * Sets this frame to the given value.
+     * 
+     * @param cw
+     *            the ClassWriter to which this label belongs.
+     * @param nLocal
+     *            the number of local variables.
+     * @param local
+     *            the local variable types. 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 single element). 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).
+     * @param nStack
+     *            the number of operand stack elements.
+     * @param stack
+     *            the operand stack types (same format as the "local" array).
+     */
+    final void set(ClassWriter cw, final int nLocal, final Object[] local,
+            final int nStack, final Object[] stack) {
+        int i = convert(cw, nLocal, local, inputLocals);
+        while (i < local.length) {
+            inputLocals[i++] = TOP;
+        }
+        int nStackTop = 0;
+        for (int j = 0; j < nStack; ++j) {
+            if (stack[j] == Opcodes.LONG || stack[j] == Opcodes.DOUBLE) {
+                ++nStackTop;
+            }
+        }
+        inputStack = new int[nStack + nStackTop];
+        convert(cw, nStack, stack, inputStack);
+        outputStackTop = 0;
+        initializationCount = 0;
+    }
+
+    /**
+     * Converts types from the MethodWriter.visitFrame() format to the Frame
+     * format.
+     * 
+     * @param cw
+     *            the ClassWriter to which this label belongs.
+     * @param nInput
+     *            the number of types to convert.
+     * @param input
+     *            the types to convert. 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 single element). 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).
+     * @param output
+     *            where to store the converted types.
+     * @return the number of output elements.
+     */
+    private static int convert(ClassWriter cw, int nInput, Object[] input,
+            int[] output) {
+        int i = 0;
+        for (int j = 0; j < nInput; ++j) {
+            if (input[j] instanceof Integer) {
+                output[i++] = BASE | ((Integer) input[j]).intValue();
+                if (input[j] == Opcodes.LONG || input[j] == Opcodes.DOUBLE) {
+                    output[i++] = TOP;
+                }
+            } else if (input[j] instanceof String) {
+                output[i++] = type(cw, Type.getObjectType((String) input[j])
+                        .getDescriptor());
+            } else {
+                output[i++] = UNINITIALIZED
+                        | cw.addUninitializedType("",
+                                ((Label) input[j]).position);
+            }
+        }
+        return i;
+    }
+
+    /**
+     * Sets this frame to the value of the given frame. WARNING: after this
+     * method is called the two frames share the same data structures. It is
+     * recommended to discard the given frame f to avoid unexpected side
+     * effects.
+     * 
+     * @param f
+     *            The new frame value.
+     */
+    final void set(final Frame f) {
+        inputLocals = f.inputLocals;
+        inputStack = f.inputStack;
+        outputLocals = f.outputLocals;
+        outputStack = f.outputStack;
+        outputStackTop = f.outputStackTop;
+        initializationCount = f.initializationCount;
+        initializations = f.initializations;
+    }
+
+    /**
      * Returns the output frame local variable type at the given index.
      * 
      * @param local
@@ -585,7 +689,7 @@ final class Frame {
         }
         // pushes the type on the output stack
         outputStack[outputStackTop++] = type;
-        // updates the maximun height reached by the output stack, if needed
+        // updates the maximum height reached by the output stack, if needed
         int top = owner.inputStackTop + outputStackTop;
         if (top > owner.outputStackMax) {
             owner.outputStackMax = top;
@@ -621,7 +725,7 @@ final class Frame {
      *            a type descriptor.
      * @return the int encoding of the given type.
      */
-    private static int type(final ClassWriter cw, final String desc) {
+    static int type(final ClassWriter cw, final String desc) {
         String t;
         int index = desc.charAt(0) == '(' ? desc.indexOf(')') + 1 : 0;
         switch (desc.charAt(index)) {
@@ -809,7 +913,7 @@ final class Frame {
      * @param maxLocals
      *            the maximum number of local variables of this method.
      */
-    void initInputFrame(final ClassWriter cw, final int access,
+    final void initInputFrame(final ClassWriter cw, final int access,
             final Type[] args, final int maxLocals) {
         inputLocals = new int[maxLocals];
         inputStack = new int[0];
@@ -952,7 +1056,7 @@ final class Frame {
         case Opcodes.AALOAD:
             pop(1);
             t1 = pop();
-            push(ELEMENT_OF + t1);
+            push(t1 == NULL ? t1 : ELEMENT_OF + t1);
             break;
         case Opcodes.ISTORE:
         case Opcodes.FSTORE:
@@ -1283,7 +1387,7 @@ final class Frame {
      * @return <tt>true</tt> if the input frame of the given label has been
      *         changed by this operation.
      */
-    boolean merge(final ClassWriter cw, final Frame frame, final int edge) {
+    final boolean merge(final ClassWriter cw, final Frame frame, final int edge) {
         boolean changed = false;
         int i, s, dim, kind, t;
 

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/74324b31/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/Handle.java
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/Handle.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/Handle.java
index e01fd40..c7f377c 100644
--- a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/Handle.java
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/Handle.java
@@ -63,6 +63,12 @@ public final class Handle {
      * The descriptor of the field or method designated by this handle.
      */
     final String desc;
+    
+    
+    /**
+     * Indicate if the owner is an interface or not.
+     */
+    final boolean itf;
 
     /**
      * Constructs a new field or method handle.
@@ -84,14 +90,46 @@ public final class Handle {
      * @param desc
      *            the descriptor of the field or method designated by this
      *            handle.
+     *            
+     * @deprecated this constructor has been superseded
+     *             by {@link #Handle(int, String, String, String, boolean)}.
      */
+    @Deprecated
     public Handle(int tag, String owner, String name, String desc) {
+        this(tag, owner, name, desc, tag == Opcodes.H_INVOKEINTERFACE);
+    }
+
+    /**
+     * Constructs a new field or method handle.
+     * 
+     * @param tag
+     *            the kind of field or method designated by this Handle. Must be
+     *            {@link Opcodes#H_GETFIELD}, {@link Opcodes#H_GETSTATIC},
+     *            {@link Opcodes#H_PUTFIELD}, {@link Opcodes#H_PUTSTATIC},
+     *            {@link Opcodes#H_INVOKEVIRTUAL},
+     *            {@link Opcodes#H_INVOKESTATIC},
+     *            {@link Opcodes#H_INVOKESPECIAL},
+     *            {@link Opcodes#H_NEWINVOKESPECIAL} or
+     *            {@link Opcodes#H_INVOKEINTERFACE}.
+     * @param owner
+     *            the internal name of the class that owns the field or method
+     *            designated by this handle.
+     * @param name
+     *            the name of the field or method designated by this handle.
+     * @param desc
+     *            the descriptor of the field or method designated by this
+     *            handle.
+     * @param itf
+     *            true if the owner is an interface.
+     */
+    public Handle(int tag, String owner, String name, String desc, boolean itf) {
         this.tag = tag;
         this.owner = owner;
         this.name = name;
         this.desc = desc;
+        this.itf = itf;
     }
-
+    
     /**
      * Returns the kind of field or method designated by this handle.
      * 
@@ -134,6 +172,17 @@ public final class Handle {
     public String getDesc() {
         return desc;
     }
+    
+    /**
+     * Returns true if the owner of the field or method designated
+     * by this handle is an interface.
+     * 
+     * @return true if the owner of the field or method designated
+     *         by this handle is an interface.
+     */
+    public boolean isInterface() {
+        return itf;
+    }
 
     @Override
     public boolean equals(Object obj) {
@@ -144,13 +193,13 @@ public final class Handle {
             return false;
         }
         Handle h = (Handle) obj;
-        return tag == h.tag && owner.equals(h.owner) && name.equals(h.name)
-                && desc.equals(h.desc);
+        return tag == h.tag && itf == h.itf && owner.equals(h.owner)
+                && name.equals(h.name) && desc.equals(h.desc);
     }
 
     @Override
     public int hashCode() {
-        return tag + owner.hashCode() * name.hashCode() * desc.hashCode();
+        return tag + (itf? 64: 0) + owner.hashCode() * name.hashCode() * desc.hashCode();
     }
 
     /**
@@ -158,13 +207,16 @@ public final class Handle {
      * representation is:
      * 
      * <pre>
+     * for a reference to a class:
      * owner '.' name desc ' ' '(' tag ')'
+     * for a reference to an interface:
+     * owner '.' name desc ' ' '(' tag ' ' itf ')'
      * </pre>
      * 
      * . As this format is unambiguous, it can be parsed if necessary.
      */
     @Override
     public String toString() {
-        return owner + '.' + name + desc + " (" + tag + ')';
+        return owner + '.' + name + desc + " (" + tag + (itf? " itf": "") + ')';
     }
 }

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/74324b31/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/Item.java
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/Item.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/Item.java
index 037a45a..d47a7c0 100644
--- a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/Item.java
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/Item.java
@@ -51,6 +51,7 @@ final class Item {
      * {@link ClassWriter#STR}, {@link ClassWriter#CLASS},
      * {@link ClassWriter#NAME_TYPE}, {@link ClassWriter#FIELD},
      * {@link ClassWriter#METH}, {@link ClassWriter#IMETH},
+     * {@link ClassWriter#MODULE}, {@link ClassWriter#PACKAGE},
      * {@link ClassWriter#MTYPE}, {@link ClassWriter#INDY}.
      * 
      * MethodHandle constant 9 variations are stored using a range of 9 values
@@ -214,6 +215,8 @@ final class Item {
         case ClassWriter.UTF8:
         case ClassWriter.STR:
         case ClassWriter.MTYPE:
+        case ClassWriter.MODULE:
+        case ClassWriter.PACKAGE:
         case ClassWriter.TYPE_NORMAL:
             hashCode = 0x7FFFFFFF & (type + strVal1.hashCode());
             return;
@@ -282,6 +285,8 @@ final class Item {
         case ClassWriter.UTF8:
         case ClassWriter.STR:
         case ClassWriter.CLASS:
+        case ClassWriter.MODULE:
+        case ClassWriter.PACKAGE:
         case ClassWriter.MTYPE:
         case ClassWriter.TYPE_NORMAL:
             return i.strVal1.equals(strVal1);

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/74324b31/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/Label.java
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/Label.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/Label.java
index c135dac..57d771c 100644
--- a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/Label.java
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/Label.java
@@ -111,7 +111,7 @@ public class Label {
      * Field used to associate user information to a label. Warning: this field
      * is used by the ASM tree package. In order to use it with the ASM tree
      * package you must override the
-     * {@link org.apache.tapestry5.internal.plastic.asm.tree.MethodNode#getLabelNode} method.
+     * {@link org.objectweb.asm.tree.MethodNode#getLabelNode} method.
      */
     public Object info;
 
@@ -243,8 +243,8 @@ public class Label {
      * The next basic block in the basic block stack. This stack is used in the
      * main loop of the fix point algorithm used in the second step of the
      * control flow analysis algorithms. It is also used in
-     * {@link #visitSubroutine} to avoid using a recursive method, and in 
-     * ClassReader to temporarily store multiple source lines for a label. 
+     * {@link #visitSubroutine} to avoid using a recursive method, and in
+     * ClassReader to temporarily store multiple source lines for a label.
      * 
      * @see MethodWriter#visitMaxs
      */
@@ -360,13 +360,12 @@ public class Label {
      *            the position of this label in the bytecode.
      * @param data
      *            the bytecode of the method.
-     * @return <tt>true</tt> if a blank that was left for this label was to
+     * @return <tt>true</tt> if a blank that was left for this label was too
      *         small to store the offset. In such a case the corresponding jump
      *         instruction is replaced with a pseudo instruction (using unused
      *         opcodes) using an unsigned two bytes offset. These pseudo
-     *         instructions will need to be replaced with true instructions with
-     *         wider offsets (4 bytes instead of 2). This is done in
-     *         {@link MethodWriter#resizeInstructions}.
+     *         instructions will be replaced with standard bytecode instructions
+     *         with wider offsets (4 bytes instead of 2), in ClassReader.
      * @throws IllegalArgumentException
      *             if this label has already been resolved, or if it has not
      *             been created by the given code writer.
@@ -425,7 +424,7 @@ public class Label {
      * @return the first label of the series to which this label belongs.
      */
     Label getFirst() {
-        return !ClassReader.FRAMES || frame == null ? this : frame.owner;
+        return frame == null ? this : frame.owner;
     }
 
     // ------------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/74324b31/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/MethodVisitor.java
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/MethodVisitor.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/MethodVisitor.java
index 6de577a..ed5d751 100644
--- a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/MethodVisitor.java
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/MethodVisitor.java
@@ -57,7 +57,7 @@ public abstract class MethodVisitor {
 
     /**
      * The ASM API version implemented by this visitor. The value of this field
-     * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     * must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      */
     protected final int api;
 
@@ -72,7 +72,7 @@ public abstract class MethodVisitor {
      * 
      * @param api
      *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      */
     public MethodVisitor(final int api) {
         this(api, null);
@@ -83,13 +83,13 @@ public abstract class MethodVisitor {
      * 
      * @param api
      *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      * @param mv
      *            the method visitor to which this visitor must delegate method
      *            calls. May be null.
      */
     public MethodVisitor(final int api, final MethodVisitor mv) {
-        if (api != Opcodes.ASM4 && api != Opcodes.ASM5) {
+        if (api < Opcodes.ASM4 || api > Opcodes.ASM6) {
             throw new IllegalArgumentException();
         }
         this.api = api;

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/74324b31/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/MethodWriter.java
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/MethodWriter.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/MethodWriter.java
index ef572b9..eaae447 100644
--- a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/MethodWriter.java
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/MethodWriter.java
@@ -99,7 +99,19 @@ class MethodWriter extends MethodVisitor {
      * 
      * @see #compute
      */
-    private static final int FRAMES = 0;
+    static final int FRAMES = 0;
+
+    /**
+     * Indicates that the stack map frames of type F_INSERT must be computed.
+     * The other frames are not (re)computed. They should all be of type F_NEW
+     * and should be sufficient to compute the content of the F_INSERT frames,
+     * together with the bytecode instructions between a F_NEW and a F_INSERT
+     * frame - and without any knowledge of the type hierarchy (by definition of
+     * F_INSERT).
+     * 
+     * @see #compute
+     */
+    static final int INSERTED_FRAMES = 1;
 
     /**
      * Indicates that the maximum stack size and number of local variables must
@@ -107,14 +119,14 @@ class MethodWriter extends MethodVisitor {
      * 
      * @see #compute
      */
-    private static final int MAXS = 1;
+    static final int MAXS = 2;
 
     /**
      * Indicates that nothing must be automatically computed.
      * 
      * @see #compute
      */
-    private static final int NOTHING = 2;
+    static final int NOTHING = 3;
 
     /**
      * The class writer to which this method must be added.
@@ -248,7 +260,7 @@ class MethodWriter extends MethodVisitor {
     /**
      * Number of stack map frames in the StackMapTable attribute.
      */
-    private int frameCount;
+    int frameCount;
 
     /**
      * The StackMapTable attribute.
@@ -355,11 +367,6 @@ class MethodWriter extends MethodVisitor {
     private Attribute cattrs;
 
     /**
-     * Indicates if some jump instructions are too small and need to be resized.
-     */
-    private boolean resize;
-
-    /**
      * The number of subroutines in this method.
      */
     private int subroutines;
@@ -380,6 +387,7 @@ class MethodWriter extends MethodVisitor {
      * Indicates what must be automatically computed.
      * 
      * @see #FRAMES
+     * @see #INSERTED_FRAMES
      * @see #MAXS
      * @see #NOTHING
      */
@@ -442,18 +450,13 @@ class MethodWriter extends MethodVisitor {
      * @param exceptions
      *            the internal names of the method's exceptions. May be
      *            <tt>null</tt>.
-     * @param computeMaxs
-     *            <tt>true</tt> if the maximum stack size and number of local
-     *            variables must be automatically computed.
-     * @param computeFrames
-     *            <tt>true</tt> if the stack map tables must be recomputed from
-     *            scratch.
+     * @param compute
+     *            Indicates what must be automatically computed (see #compute).
      */
     MethodWriter(final ClassWriter cw, final int access, final String name,
             final String desc, final String signature,
-            final String[] exceptions, final boolean computeMaxs,
-            final boolean computeFrames) {
-        super(Opcodes.ASM5);
+            final String[] exceptions, final int compute) {
+        super(Opcodes.ASM6);
         if (cw.firstMethod == null) {
             cw.firstMethod = this;
         } else {
@@ -468,9 +471,7 @@ class MethodWriter extends MethodVisitor {
         this.name = cw.newUTF8(name);
         this.desc = cw.newUTF8(desc);
         this.descriptor = desc;
-        if (ClassReader.SIGNATURES) {
-            this.signature = signature;
-        }
+        this.signature = signature;
         if (exceptions != null && exceptions.length > 0) {
             exceptionCount = exceptions.length;
             this.exceptions = new int[exceptionCount];
@@ -478,8 +479,8 @@ class MethodWriter extends MethodVisitor {
                 this.exceptions[i] = cw.newClass(exceptions[i]);
             }
         }
-        this.compute = computeFrames ? FRAMES : (computeMaxs ? MAXS : NOTHING);
-        if (computeMaxs || computeFrames) {
+        this.compute = compute;
+        if (compute != NOTHING) {
             // updates maxLocals
             int size = Type.getArgumentsAndReturnSizes(descriptor) >> 2;
             if ((access & Opcodes.ACC_STATIC) != 0) {
@@ -510,9 +511,6 @@ class MethodWriter extends MethodVisitor {
 
     @Override
     public AnnotationVisitor visitAnnotationDefault() {
-        if (!ClassReader.ANNOTATIONS) {
-            return null;
-        }
         annd = new ByteVector();
         return new AnnotationWriter(cw, false, annd, null, 0);
     }
@@ -520,9 +518,6 @@ class MethodWriter extends MethodVisitor {
     @Override
     public AnnotationVisitor visitAnnotation(final String desc,
             final boolean visible) {
-        if (!ClassReader.ANNOTATIONS) {
-            return null;
-        }
         ByteVector bv = new ByteVector();
         // write type, and reserve space for values count
         bv.putShort(cw.newUTF8(desc)).putShort(0);
@@ -540,9 +535,6 @@ class MethodWriter extends MethodVisitor {
     @Override
     public AnnotationVisitor visitTypeAnnotation(final int typeRef,
             final TypePath typePath, final String desc, final boolean visible) {
-        if (!ClassReader.ANNOTATIONS) {
-            return null;
-        }
         ByteVector bv = new ByteVector();
         // write target_type and target_info
         AnnotationWriter.putTarget(typeRef, typePath, bv);
@@ -563,9 +555,6 @@ class MethodWriter extends MethodVisitor {
     @Override
     public AnnotationVisitor visitParameterAnnotation(final int parameter,
             final String desc, final boolean visible) {
-        if (!ClassReader.ANNOTATIONS) {
-            return null;
-        }
         ByteVector bv = new ByteVector();
         if ("Ljava/lang/Synthetic;".equals(desc)) {
             // workaround for a bug in javac with synthetic parameters
@@ -610,11 +599,33 @@ class MethodWriter extends MethodVisitor {
     @Override
     public void visitFrame(final int type, final int nLocal,
             final Object[] local, final int nStack, final Object[] stack) {
-        if (!ClassReader.FRAMES || compute == FRAMES) {
+        if (compute == FRAMES) {
             return;
         }
 
-        if (type == Opcodes.F_NEW) {
+        if (compute == INSERTED_FRAMES) {
+            if (currentBlock.frame == null) {
+                // This should happen only once, for the implicit first frame
+                // (which is explicitly visited in ClassReader if the
+                // EXPAND_ASM_INSNS option is used).
+                currentBlock.frame = new CurrentFrame();
+                currentBlock.frame.owner = currentBlock;
+                currentBlock.frame.initInputFrame(cw, access,
+                        Type.getArgumentTypes(descriptor), nLocal);
+                visitImplicitFirstFrame();
+            } else {
+                if (type == Opcodes.F_NEW) {
+                    currentBlock.frame.set(cw, nLocal, local, nStack, stack);
+                } else {
+                    // In this case type is equal to F_INSERT by hypothesis, and
+                    // currentBlock.frame contains the stack map frame at the
+                    // current instruction, computed from the last F_NEW frame
+                    // and the bytecode instructions in between (via calls to
+                    // CurrentFrame#execute).
+                }
+                visitFrame(currentBlock.frame);
+            }
+        } else if (type == Opcodes.F_NEW) {
             if (previousFrame == null) {
                 visitImplicitFirstFrame();
             }
@@ -622,10 +633,10 @@ class MethodWriter extends MethodVisitor {
             int frameIndex = startFrame(code.length, nLocal, nStack);
             for (int i = 0; i < nLocal; ++i) {
                 if (local[i] instanceof String) {
-                    frame[frameIndex++] = Frame.OBJECT
-                            | cw.addType((String) local[i]);
+                    String desc = Type.getObjectType((String) local[i]).getDescriptor();
+                    frame[frameIndex++] = Frame.type(cw, desc);
                 } else if (local[i] instanceof Integer) {
-                    frame[frameIndex++] = ((Integer) local[i]).intValue();
+                    frame[frameIndex++] = Frame.BASE | ((Integer) local[i]).intValue();
                 } else {
                     frame[frameIndex++] = Frame.UNINITIALIZED
                             | cw.addUninitializedType("",
@@ -634,10 +645,10 @@ class MethodWriter extends MethodVisitor {
             }
             for (int i = 0; i < nStack; ++i) {
                 if (stack[i] instanceof String) {
-                    frame[frameIndex++] = Frame.OBJECT
-                            | cw.addType((String) stack[i]);
+                    String desc = Type.getObjectType((String) stack[i]).getDescriptor();
+                    frame[frameIndex++] = Frame.type(cw, desc);
                 } else if (stack[i] instanceof Integer) {
-                    frame[frameIndex++] = ((Integer) stack[i]).intValue();
+                    frame[frameIndex++] = Frame.BASE | ((Integer) stack[i]).intValue();
                 } else {
                     frame[frameIndex++] = Frame.UNINITIALIZED
                             | cw.addUninitializedType("",
@@ -718,7 +729,7 @@ class MethodWriter extends MethodVisitor {
         // update currentBlock
         // Label currentBlock = this.currentBlock;
         if (currentBlock != null) {
-            if (compute == FRAMES) {
+            if (compute == FRAMES || compute == INSERTED_FRAMES) {
                 currentBlock.frame.execute(opcode, 0, null, null);
             } else {
                 // updates current and max stack sizes
@@ -741,7 +752,7 @@ class MethodWriter extends MethodVisitor {
         lastCodeOffset = code.length;
         // Label currentBlock = this.currentBlock;
         if (currentBlock != null) {
-            if (compute == FRAMES) {
+            if (compute == FRAMES || compute == INSERTED_FRAMES) {
                 currentBlock.frame.execute(opcode, operand, null, null);
             } else if (opcode != Opcodes.NEWARRAY) {
                 // updates current and max stack sizes only for NEWARRAY
@@ -766,7 +777,7 @@ class MethodWriter extends MethodVisitor {
         lastCodeOffset = code.length;
         // Label currentBlock = this.currentBlock;
         if (currentBlock != null) {
-            if (compute == FRAMES) {
+            if (compute == FRAMES || compute == INSERTED_FRAMES) {
                 currentBlock.frame.execute(opcode, var, null, null);
             } else {
                 // updates current and max stack sizes
@@ -823,10 +834,10 @@ class MethodWriter extends MethodVisitor {
     @Override
     public void visitTypeInsn(final int opcode, final String type) {
         lastCodeOffset = code.length;
-        Item i = cw.newClassItem(type);
+        Item i = cw.newStringishItem(ClassWriter.CLASS, type);
         // Label currentBlock = this.currentBlock;
         if (currentBlock != null) {
-            if (compute == FRAMES) {
+            if (compute == FRAMES || compute == INSERTED_FRAMES) {
                 currentBlock.frame.execute(opcode, code.length, cw, i);
             } else if (opcode == Opcodes.NEW) {
                 // updates current and max stack sizes only if opcode == NEW
@@ -849,7 +860,7 @@ class MethodWriter extends MethodVisitor {
         Item i = cw.newFieldItem(owner, name, desc);
         // Label currentBlock = this.currentBlock;
         if (currentBlock != null) {
-            if (compute == FRAMES) {
+            if (compute == FRAMES || compute == INSERTED_FRAMES) {
                 currentBlock.frame.execute(opcode, 0, cw, i);
             } else {
                 int size;
@@ -889,7 +900,7 @@ class MethodWriter extends MethodVisitor {
         int argSize = i.intVal;
         // Label currentBlock = this.currentBlock;
         if (currentBlock != null) {
-            if (compute == FRAMES) {
+            if (compute == FRAMES || compute == INSERTED_FRAMES) {
                 currentBlock.frame.execute(opcode, 0, cw, i);
             } else {
                 /*
@@ -941,7 +952,7 @@ class MethodWriter extends MethodVisitor {
         int argSize = i.intVal;
         // Label currentBlock = this.currentBlock;
         if (currentBlock != null) {
-            if (compute == FRAMES) {
+            if (compute == FRAMES || compute == INSERTED_FRAMES) {
                 currentBlock.frame.execute(Opcodes.INVOKEDYNAMIC, 0, cw, i);
             } else {
                 /*
@@ -975,7 +986,9 @@ class MethodWriter extends MethodVisitor {
     }
 
     @Override
-    public void visitJumpInsn(final int opcode, final Label label) {
+    public void visitJumpInsn(int opcode, final Label label) {
+        boolean isWide = opcode >= 200; // GOTO_W
+        opcode = isWide ? opcode - 33 : opcode;
         lastCodeOffset = code.length;
         Label nextInsn = null;
         // Label currentBlock = this.currentBlock;
@@ -990,6 +1003,8 @@ class MethodWriter extends MethodVisitor {
                     // creates a Label for the next basic block
                     nextInsn = new Label();
                 }
+            } else if (compute == INSERTED_FRAMES) {
+                currentBlock.frame.execute(opcode, 0, null, null);
             } else {
                 if (opcode == Opcodes.JSR) {
                     if ((label.status & Label.SUBROUTINE) == 0) {
@@ -1021,8 +1036,8 @@ class MethodWriter extends MethodVisitor {
             /*
              * case of a backward jump with an offset < -32768. In this case we
              * automatically replace GOTO with GOTO_W, JSR with JSR_W and IFxxx
-             * <l> with IFNOTxxx <l'> GOTO_W <l>, where IFNOTxxx is the
-             * "opposite" opcode of IFxxx (i.e., IFNE for IFEQ) and where <l'>
+             * <l> with IFNOTxxx <L> GOTO_W <l> L:..., where IFNOTxxx is the
+             * "opposite" opcode of IFxxx (i.e., IFNE for IFEQ) and where <L>
              * designates the instruction just after the GOTO_W.
              */
             if (opcode == Opcodes.GOTO) {
@@ -1038,9 +1053,21 @@ class MethodWriter extends MethodVisitor {
                 code.putByte(opcode <= 166 ? ((opcode + 1) ^ 1) - 1
                         : opcode ^ 1);
                 code.putShort(8); // jump offset
-                code.putByte(200); // GOTO_W
+                // ASM pseudo GOTO_W insn, see ClassReader. We don't use a real
+                // GOTO_W because we might need to insert a frame just after (as
+                // the target of the IFNOTxxx jump instruction).
+                code.putByte(220);
+                cw.hasAsmInsns = true; 
             }
             label.put(this, code, code.length - 1, true);
+        } else if (isWide) {
+            /*
+             * case of a GOTO_W or JSR_W specified by the user (normally
+             * ClassReader when used to resize instructions). In this case we
+             * keep the original instruction.
+             */
+            code.putByte(opcode + 33);
+            label.put(this, code, code.length - 1, true);
         } else {
             /*
              * case of a backward jump with an offset >= -32768, or of a forward
@@ -1068,7 +1095,7 @@ class MethodWriter extends MethodVisitor {
     @Override
     public void visitLabel(final Label label) {
         // resolves previous forward references to label, if any
-        resize |= label.resolve(this, code.length, code.data);
+        cw.hasAsmInsns |= label.resolve(this, code.length, code.data);
         // updates currentBlock
         if ((label.status & Label.DEBUG) != 0) {
             return;
@@ -1101,6 +1128,18 @@ class MethodWriter extends MethodVisitor {
                 previousBlock.successor = label;
             }
             previousBlock = label;
+        } else if (compute == INSERTED_FRAMES) {
+            if (currentBlock == null) {
+                // This case should happen only once, for the visitLabel call in
+                // the constructor. Indeed, if compute is equal to
+                // INSERTED_FRAMES currentBlock can not be set back to null (see
+                // #noSuccessor).
+                currentBlock = label;
+            } else {
+                // Updates the frame owner so that a correct frame offset is
+                // computed in visitFrame(Frame).
+                currentBlock.frame.owner = label;
+            }
         } else if (compute == MAXS) {
             if (currentBlock != null) {
                 // ends current block (with one new successor)
@@ -1126,7 +1165,7 @@ class MethodWriter extends MethodVisitor {
         Item i = cw.newConstItem(cst);
         // Label currentBlock = this.currentBlock;
         if (currentBlock != null) {
-            if (compute == FRAMES) {
+            if (compute == FRAMES || compute == INSERTED_FRAMES) {
                 currentBlock.frame.execute(Opcodes.LDC, 0, cw, i);
             } else {
                 int size;
@@ -1158,7 +1197,7 @@ class MethodWriter extends MethodVisitor {
     public void visitIincInsn(final int var, final int increment) {
         lastCodeOffset = code.length;
         if (currentBlock != null) {
-            if (compute == FRAMES) {
+            if (compute == FRAMES || compute == INSERTED_FRAMES) {
                 currentBlock.frame.execute(Opcodes.IINC, var, null, null);
             }
         }
@@ -1242,10 +1281,10 @@ class MethodWriter extends MethodVisitor {
     @Override
     public void visitMultiANewArrayInsn(final String desc, final int dims) {
         lastCodeOffset = code.length;
-        Item i = cw.newClassItem(desc);
+        Item i = cw.newStringishItem(ClassWriter.CLASS, desc);
         // Label currentBlock = this.currentBlock;
         if (currentBlock != null) {
-            if (compute == FRAMES) {
+            if (compute == FRAMES || compute == INSERTED_FRAMES) {
                 currentBlock.frame.execute(Opcodes.MULTIANEWARRAY, dims, cw, i);
             } else {
                 // updates current stack size (max stack size unchanged because
@@ -1260,9 +1299,6 @@ class MethodWriter extends MethodVisitor {
     @Override
     public AnnotationVisitor visitInsnAnnotation(int typeRef,
             TypePath typePath, String desc, boolean visible) {
-        if (!ClassReader.ANNOTATIONS) {
-            return null;
-        }
         ByteVector bv = new ByteVector();
         // write target_type and target_info
         typeRef = (typeRef & 0xFF0000FF) | (lastCodeOffset << 8);
@@ -1302,9 +1338,6 @@ class MethodWriter extends MethodVisitor {
     @Override
     public AnnotationVisitor visitTryCatchAnnotation(int typeRef,
             TypePath typePath, String desc, boolean visible) {
-        if (!ClassReader.ANNOTATIONS) {
-            return null;
-        }
         ByteVector bv = new ByteVector();
         // write target_type and target_info
         AnnotationWriter.putTarget(typeRef, typePath, bv);
@@ -1358,9 +1391,6 @@ class MethodWriter extends MethodVisitor {
     public AnnotationVisitor visitLocalVariableAnnotation(int typeRef,
             TypePath typePath, Label[] start, Label[] end, int[] index,
             String desc, boolean visible) {
-        if (!ClassReader.ANNOTATIONS) {
-            return null;
-        }
         ByteVector bv = new ByteVector();
         // write target_type and target_info
         bv.putByte(typeRef >>> 24).putShort(start.length);
@@ -1401,15 +1431,7 @@ class MethodWriter extends MethodVisitor {
 
     @Override
     public void visitMaxs(final int maxStack, final int maxLocals) {
-        if (resize) {
-            // replaces the temporary jump opcodes introduced by Label.resolve.
-            if (ClassReader.RESIZE) {
-                resizeInstructions();
-            } else {
-                throw new RuntimeException("Method code too large!");
-            }
-        }
-        if (ClassReader.FRAMES && compute == FRAMES) {
+        if (compute == FRAMES) {
             // completes the control flow graph with exception handler blocks
             Handler handler = firstHandler;
             while (handler != null) {
@@ -1439,8 +1461,8 @@ class MethodWriter extends MethodVisitor {
 
             // creates and visits the first (implicit) frame
             Frame f = labels.frame;
-            Type[] args = Type.getArgumentTypes(descriptor);
-            f.initInputFrame(cw, access, args, this.maxLocals);
+            f.initInputFrame(cw, access, Type.getArgumentTypes(descriptor),
+                    this.maxLocals);
             visitFrame(f);
 
             /*
@@ -1688,7 +1710,9 @@ class MethodWriter extends MethodVisitor {
         } else {
             currentBlock.outputStackMax = maxStackSize;
         }
-        currentBlock = null;
+        if (compute != INSERTED_FRAMES) {
+            currentBlock = null;
+        }
     }
 
     // ------------------------------------------------------------------------
@@ -1760,7 +1784,7 @@ class MethodWriter extends MethodVisitor {
             if ((access & ACC_CONSTRUCTOR) == 0) {
                 frame[frameIndex++] = Frame.OBJECT | cw.addType(cw.thisName);
             } else {
-                frame[frameIndex++] = 6; // Opcodes.UNINITIALIZED_THIS;
+                frame[frameIndex++] = Frame.UNINITIALIZED_THIS;
             }
         }
         int i = 1;
@@ -1772,16 +1796,16 @@ class MethodWriter extends MethodVisitor {
             case 'B':
             case 'S':
             case 'I':
-                frame[frameIndex++] = 1; // Opcodes.INTEGER;
+                frame[frameIndex++] = Frame.INTEGER;
                 break;
             case 'F':
-                frame[frameIndex++] = 2; // Opcodes.FLOAT;
+                frame[frameIndex++] = Frame.FLOAT;
                 break;
             case 'J':
-                frame[frameIndex++] = 4; // Opcodes.LONG;
+                frame[frameIndex++] = Frame.LONG;
                 break;
             case 'D':
-                frame[frameIndex++] = 3; // Opcodes.DOUBLE;
+                frame[frameIndex++] = Frame.DOUBLE;
                 break;
             case '[':
                 while (descriptor.charAt(i) == '[') {
@@ -1793,8 +1817,7 @@ class MethodWriter extends MethodVisitor {
                         ++i;
                     }
                 }
-                frame[frameIndex++] = Frame.OBJECT
-                        | cw.addType(descriptor.substring(j, ++i));
+                frame[frameIndex++] = Frame.type(cw, descriptor.substring(j, ++i));
                 break;
             case 'L':
                 while (descriptor.charAt(i) != ';') {
@@ -2032,7 +2055,7 @@ class MethodWriter extends MethodVisitor {
         }
         int size = 8;
         if (code.length > 0) {
-            if (code.length > 65536) {
+            if (code.length > 65535) {
                 throw new RuntimeException("Method code too large!");
             }
             cw.newUTF8("Code");
@@ -2054,11 +2077,11 @@ class MethodWriter extends MethodVisitor {
                 cw.newUTF8(zip ? "StackMapTable" : "StackMap");
                 size += 8 + stackMap.length;
             }
-            if (ClassReader.ANNOTATIONS && ctanns != null) {
+            if (ctanns != null) {
                 cw.newUTF8("RuntimeVisibleTypeAnnotations");
                 size += 8 + ctanns.getSize();
             }
-            if (ClassReader.ANNOTATIONS && ictanns != null) {
+            if (ictanns != null) {
                 cw.newUTF8("RuntimeInvisibleTypeAnnotations");
                 size += 8 + ictanns.getSize();
             }
@@ -2082,7 +2105,7 @@ class MethodWriter extends MethodVisitor {
             cw.newUTF8("Deprecated");
             size += 6;
         }
-        if (ClassReader.SIGNATURES && signature != null) {
+        if (signature != null) {
             cw.newUTF8("Signature");
             cw.newUTF8(signature);
             size += 8;
@@ -2091,34 +2114,34 @@ class MethodWriter extends MethodVisitor {
             cw.newUTF8("MethodParameters");
             size += 7 + methodParameters.length;
         }
-        if (ClassReader.ANNOTATIONS && annd != null) {
+        if (annd != null) {
             cw.newUTF8("AnnotationDefault");
             size += 6 + annd.length;
         }
-        if (ClassReader.ANNOTATIONS && anns != null) {
+        if (anns != null) {
             cw.newUTF8("RuntimeVisibleAnnotations");
             size += 8 + anns.getSize();
         }
-        if (ClassReader.ANNOTATIONS && ianns != null) {
+        if (ianns != null) {
             cw.newUTF8("RuntimeInvisibleAnnotations");
             size += 8 + ianns.getSize();
         }
-        if (ClassReader.ANNOTATIONS && tanns != null) {
+        if (tanns != null) {
             cw.newUTF8("RuntimeVisibleTypeAnnotations");
             size += 8 + tanns.getSize();
         }
-        if (ClassReader.ANNOTATIONS && itanns != null) {
+        if (itanns != null) {
             cw.newUTF8("RuntimeInvisibleTypeAnnotations");
             size += 8 + itanns.getSize();
         }
-        if (ClassReader.ANNOTATIONS && panns != null) {
+        if (panns != null) {
             cw.newUTF8("RuntimeVisibleParameterAnnotations");
             size += 7 + 2 * (panns.length - synthetics);
             for (int i = panns.length - 1; i >= synthetics; --i) {
                 size += panns[i] == null ? 0 : panns[i].getSize();
             }
         }
-        if (ClassReader.ANNOTATIONS && ipanns != null) {
+        if (ipanns != null) {
             cw.newUTF8("RuntimeInvisibleParameterAnnotations");
             size += 7 + 2 * (ipanns.length - synthetics);
             for (int i = ipanns.length - 1; i >= synthetics; --i) {
@@ -2164,31 +2187,31 @@ class MethodWriter extends MethodVisitor {
         if ((access & Opcodes.ACC_DEPRECATED) != 0) {
             ++attributeCount;
         }
-        if (ClassReader.SIGNATURES && signature != null) {
+        if (signature != null) {
             ++attributeCount;
         }
         if (methodParameters != null) {
             ++attributeCount;
         }
-        if (ClassReader.ANNOTATIONS && annd != null) {
+        if (annd != null) {
             ++attributeCount;
         }
-        if (ClassReader.ANNOTATIONS && anns != null) {
+        if (anns != null) {
             ++attributeCount;
         }
-        if (ClassReader.ANNOTATIONS && ianns != null) {
+        if (ianns != null) {
             ++attributeCount;
         }
-        if (ClassReader.ANNOTATIONS && tanns != null) {
+        if (tanns != null) {
             ++attributeCount;
         }
-        if (ClassReader.ANNOTATIONS && itanns != null) {
+        if (itanns != null) {
             ++attributeCount;
         }
-        if (ClassReader.ANNOTATIONS && panns != null) {
+        if (panns != null) {
             ++attributeCount;
         }
-        if (ClassReader.ANNOTATIONS && ipanns != null) {
+        if (ipanns != null) {
             ++attributeCount;
         }
         if (attrs != null) {
@@ -2209,10 +2232,10 @@ class MethodWriter extends MethodVisitor {
             if (stackMap != null) {
                 size += 8 + stackMap.length;
             }
-            if (ClassReader.ANNOTATIONS && ctanns != null) {
+            if (ctanns != null) {
                 size += 8 + ctanns.getSize();
             }
-            if (ClassReader.ANNOTATIONS && ictanns != null) {
+            if (ictanns != null) {
                 size += 8 + ictanns.getSize();
             }
             if (cattrs != null) {
@@ -2244,10 +2267,10 @@ class MethodWriter extends MethodVisitor {
             if (stackMap != null) {
                 ++attributeCount;
             }
-            if (ClassReader.ANNOTATIONS && ctanns != null) {
+            if (ctanns != null) {
                 ++attributeCount;
             }
-            if (ClassReader.ANNOTATIONS && ictanns != null) {
+            if (ictanns != null) {
                 ++attributeCount;
             }
             if (cattrs != null) {
@@ -2275,11 +2298,11 @@ class MethodWriter extends MethodVisitor {
                 out.putInt(stackMap.length + 2).putShort(frameCount);
                 out.putByteArray(stackMap.data, 0, stackMap.length);
             }
-            if (ClassReader.ANNOTATIONS && ctanns != null) {
+            if (ctanns != null) {
                 out.putShort(cw.newUTF8("RuntimeVisibleTypeAnnotations"));
                 ctanns.put(out);
             }
-            if (ClassReader.ANNOTATIONS && ictanns != null) {
+            if (ictanns != null) {
                 out.putShort(cw.newUTF8("RuntimeInvisibleTypeAnnotations"));
                 ictanns.put(out);
             }
@@ -2304,7 +2327,7 @@ class MethodWriter extends MethodVisitor {
         if ((access & Opcodes.ACC_DEPRECATED) != 0) {
             out.putShort(cw.newUTF8("Deprecated")).putInt(0);
         }
-        if (ClassReader.SIGNATURES && signature != null) {
+        if (signature != null) {
             out.putShort(cw.newUTF8("Signature")).putInt(2)
                     .putShort(cw.newUTF8(signature));
         }
@@ -2314,32 +2337,32 @@ class MethodWriter extends MethodVisitor {
                     methodParametersCount);
             out.putByteArray(methodParameters.data, 0, methodParameters.length);
         }
-        if (ClassReader.ANNOTATIONS && annd != null) {
+        if (annd != null) {
             out.putShort(cw.newUTF8("AnnotationDefault"));
             out.putInt(annd.length);
             out.putByteArray(annd.data, 0, annd.length);
         }
-        if (ClassReader.ANNOTATIONS && anns != null) {
+        if (anns != null) {
             out.putShort(cw.newUTF8("RuntimeVisibleAnnotations"));
             anns.put(out);
         }
-        if (ClassReader.ANNOTATIONS && ianns != null) {
+        if (ianns != null) {
             out.putShort(cw.newUTF8("RuntimeInvisibleAnnotations"));
             ianns.put(out);
         }
-        if (ClassReader.ANNOTATIONS && tanns != null) {
+        if (tanns != null) {
             out.putShort(cw.newUTF8("RuntimeVisibleTypeAnnotations"));
             tanns.put(out);
         }
-        if (ClassReader.ANNOTATIONS && itanns != null) {
+        if (itanns != null) {
             out.putShort(cw.newUTF8("RuntimeInvisibleTypeAnnotations"));
             itanns.put(out);
         }
-        if (ClassReader.ANNOTATIONS && panns != null) {
+        if (panns != null) {
             out.putShort(cw.newUTF8("RuntimeVisibleParameterAnnotations"));
             AnnotationWriter.put(panns, synthetics, out);
         }
-        if (ClassReader.ANNOTATIONS && ipanns != null) {
+        if (ipanns != null) {
             out.putShort(cw.newUTF8("RuntimeInvisibleParameterAnnotations"));
             AnnotationWriter.put(ipanns, synthetics, out);
         }
@@ -2347,569 +2370,4 @@ class MethodWriter extends MethodVisitor {
             attrs.put(cw, null, 0, -1, -1, out);
         }
     }
-
-    // ------------------------------------------------------------------------
-    // Utility methods: instruction resizing (used to handle GOTO_W and JSR_W)
-    // ------------------------------------------------------------------------
-
-    /**
-     * Resizes and replaces the temporary instructions inserted by
-     * {@link Label#resolve} for wide forward jumps, while keeping jump offsets
-     * and instruction addresses consistent. This may require to resize other
-     * existing instructions, or even to introduce new instructions: for
-     * example, increasing the size of an instruction by 2 at the middle of a
-     * method can increases the offset of an IFEQ instruction from 32766 to
-     * 32768, in which case IFEQ 32766 must be replaced with IFNEQ 8 GOTO_W
-     * 32765. This, in turn, may require to increase the size of another jump
-     * instruction, and so on... All these operations are handled automatically
-     * by this method.
-     *
-     * <i>This method must be called after all the method that is being built
-     * has been visited</i>. In particular, the {@link Label Label} objects used
-     * to construct the method are no longer valid after this method has been
-     * called.
-     */
-    private void resizeInstructions() {
-        byte[] b = code.data; // bytecode of the method
-        int u, v, label; // indexes in b
-        int i, j; // loop indexes
-        /*
-         * 1st step: As explained above, resizing an instruction may require to
-         * resize another one, which may require to resize yet another one, and
-         * so on. The first step of the algorithm consists in finding all the
-         * instructions that need to be resized, without modifying the code.
-         * This is done by the following "fix point" algorithm:
-         * 
-         * Parse the code to find the jump instructions whose offset will need
-         * more than 2 bytes to be stored (the future offset is computed from
-         * the current offset and from the number of bytes that will be inserted
-         * or removed between the source and target instructions). For each such
-         * instruction, adds an entry in (a copy of) the indexes and sizes
-         * arrays (if this has not already been done in a previous iteration!).
-         * 
-         * If at least one entry has been added during the previous step, go
-         * back to the beginning, otherwise stop.
-         * 
-         * In fact the real algorithm is complicated by the fact that the size
-         * of TABLESWITCH and LOOKUPSWITCH instructions depends on their
-         * position in the bytecode (because of padding). In order to ensure the
-         * convergence of the algorithm, the number of bytes to be added or
-         * removed from these instructions is over estimated during the previous
-         * loop, and computed exactly only after the loop is finished (this
-         * requires another pass to parse the bytecode of the method).
-         */
-        int[] allIndexes = new int[0]; // copy of indexes
-        int[] allSizes = new int[0]; // copy of sizes
-        boolean[] resize; // instructions to be resized
-        int newOffset; // future offset of a jump instruction
-
-        resize = new boolean[code.length];
-
-        // 3 = loop again, 2 = loop ended, 1 = last pass, 0 = done
-        int state = 3;
-        do {
-            if (state == 3) {
-                state = 2;
-            }
-            u = 0;
-            while (u < b.length) {
-                int opcode = b[u] & 0xFF; // opcode of current instruction
-                int insert = 0; // bytes to be added after this instruction
-
-                switch (ClassWriter.TYPE[opcode]) {
-                case ClassWriter.NOARG_INSN:
-                case ClassWriter.IMPLVAR_INSN:
-                    u += 1;
-                    break;
-                case ClassWriter.LABEL_INSN:
-                    if (opcode > 201) {
-                        // converts temporary opcodes 202 to 217, 218 and
-                        // 219 to IFEQ ... JSR (inclusive), IFNULL and
-                        // IFNONNULL
-                        opcode = opcode < 218 ? opcode - 49 : opcode - 20;
-                        label = u + readUnsignedShort(b, u + 1);
-                    } else {
-                        label = u + readShort(b, u + 1);
-                    }
-                    newOffset = getNewOffset(allIndexes, allSizes, u, label);
-                    if (newOffset < Short.MIN_VALUE
-                            || newOffset > Short.MAX_VALUE) {
-                        if (!resize[u]) {
-                            if (opcode == Opcodes.GOTO || opcode == Opcodes.JSR) {
-                                // two additional bytes will be required to
-                                // replace this GOTO or JSR instruction with
-                                // a GOTO_W or a JSR_W
-                                insert = 2;
-                            } else {
-                                // five additional bytes will be required to
-                                // replace this IFxxx <l> instruction with
-                                // IFNOTxxx <l'> GOTO_W <l>, where IFNOTxxx
-                                // is the "opposite" opcode of IFxxx (i.e.,
-                                // IFNE for IFEQ) and where <l'> designates
-                                // the instruction just after the GOTO_W.
-                                insert = 5;
-                            }
-                            resize[u] = true;
-                        }
-                    }
-                    u += 3;
-                    break;
-                case ClassWriter.LABELW_INSN:
-                    u += 5;
-                    break;
-                case ClassWriter.TABL_INSN:
-                    if (state == 1) {
-                        // true number of bytes to be added (or removed)
-                        // from this instruction = (future number of padding
-                        // bytes - current number of padding byte) -
-                        // previously over estimated variation =
-                        // = ((3 - newOffset%4) - (3 - u%4)) - u%4
-                        // = (-newOffset%4 + u%4) - u%4
-                        // = -(newOffset & 3)
-                        newOffset = getNewOffset(allIndexes, allSizes, 0, u);
-                        insert = -(newOffset & 3);
-                    } else if (!resize[u]) {
-                        // over estimation of the number of bytes to be
-                        // added to this instruction = 3 - current number
-                        // of padding bytes = 3 - (3 - u%4) = u%4 = u & 3
-                        insert = u & 3;
-                        resize[u] = true;
-                    }
-                    // skips instruction
-                    u = u + 4 - (u & 3);
-                    u += 4 * (readInt(b, u + 8) - readInt(b, u + 4) + 1) + 12;
-                    break;
-                case ClassWriter.LOOK_INSN:
-                    if (state == 1) {
-                        // like TABL_INSN
-                        newOffset = getNewOffset(allIndexes, allSizes, 0, u);
-                        insert = -(newOffset & 3);
-                    } else if (!resize[u]) {
-                        // like TABL_INSN
-                        insert = u & 3;
-                        resize[u] = true;
-                    }
-                    // skips instruction
-                    u = u + 4 - (u & 3);
-                    u += 8 * readInt(b, u + 4) + 8;
-                    break;
-                case ClassWriter.WIDE_INSN:
-                    opcode = b[u + 1] & 0xFF;
-                    if (opcode == Opcodes.IINC) {
-                        u += 6;
-                    } else {
-                        u += 4;
-                    }
-                    break;
-                case ClassWriter.VAR_INSN:
-                case ClassWriter.SBYTE_INSN:
-                case ClassWriter.LDC_INSN:
-                    u += 2;
-                    break;
-                case ClassWriter.SHORT_INSN:
-                case ClassWriter.LDCW_INSN:
-                case ClassWriter.FIELDORMETH_INSN:
-                case ClassWriter.TYPE_INSN:
-                case ClassWriter.IINC_INSN:
-                    u += 3;
-                    break;
-                case ClassWriter.ITFMETH_INSN:
-                case ClassWriter.INDYMETH_INSN:
-                    u += 5;
-                    break;
-                // case ClassWriter.MANA_INSN:
-                default:
-                    u += 4;
-                    break;
-                }
-                if (insert != 0) {
-                    // adds a new (u, insert) entry in the allIndexes and
-                    // allSizes arrays
-                    int[] newIndexes = new int[allIndexes.length + 1];
-                    int[] newSizes = new int[allSizes.length + 1];
-                    System.arraycopy(allIndexes, 0, newIndexes, 0,
-                            allIndexes.length);
-                    System.arraycopy(allSizes, 0, newSizes, 0, allSizes.length);
-                    newIndexes[allIndexes.length] = u;
-                    newSizes[allSizes.length] = insert;
-                    allIndexes = newIndexes;
-                    allSizes = newSizes;
-                    if (insert > 0) {
-                        state = 3;
-                    }
-                }
-            }
-            if (state < 3) {
-                --state;
-            }
-        } while (state != 0);
-
-        // 2nd step:
-        // copies the bytecode of the method into a new bytevector, updates the
-        // offsets, and inserts (or removes) bytes as requested.
-
-        ByteVector newCode = new ByteVector(code.length);
-
-        u = 0;
-        while (u < code.length) {
-            int opcode = b[u] & 0xFF;
-            switch (ClassWriter.TYPE[opcode]) {
-            case ClassWriter.NOARG_INSN:
-            case ClassWriter.IMPLVAR_INSN:
-                newCode.putByte(opcode);
-                u += 1;
-                break;
-            case ClassWriter.LABEL_INSN:
-                if (opcode > 201) {
-                    // changes temporary opcodes 202 to 217 (inclusive), 218
-                    // and 219 to IFEQ ... JSR (inclusive), IFNULL and
-                    // IFNONNULL
-                    opcode = opcode < 218 ? opcode - 49 : opcode - 20;
-                    label = u + readUnsignedShort(b, u + 1);
-                } else {
-                    label = u + readShort(b, u + 1);
-                }
-                newOffset = getNewOffset(allIndexes, allSizes, u, label);
-                if (resize[u]) {
-                    // replaces GOTO with GOTO_W, JSR with JSR_W and IFxxx
-                    // <l> with IFNOTxxx <l'> GOTO_W <l>, where IFNOTxxx is
-                    // the "opposite" opcode of IFxxx (i.e., IFNE for IFEQ)
-                    // and where <l'> designates the instruction just after
-                    // the GOTO_W.
-                    if (opcode == Opcodes.GOTO) {
-                        newCode.putByte(200); // GOTO_W
-                    } else if (opcode == Opcodes.JSR) {
-                        newCode.putByte(201); // JSR_W
-                    } else {
-                        newCode.putByte(opcode <= 166 ? ((opcode + 1) ^ 1) - 1
-                                : opcode ^ 1);
-                        newCode.putShort(8); // jump offset
-                        newCode.putByte(200); // GOTO_W
-                        // newOffset now computed from start of GOTO_W
-                        newOffset -= 3;
-                    }
-                    newCode.putInt(newOffset);
-                } else {
-                    newCode.putByte(opcode);
-                    newCode.putShort(newOffset);
-                }
-                u += 3;
-                break;
-            case ClassWriter.LABELW_INSN:
-                label = u + readInt(b, u + 1);
-                newOffset = getNewOffset(allIndexes, allSizes, u, label);
-                newCode.putByte(opcode);
-                newCode.putInt(newOffset);
-                u += 5;
-                break;
-            case ClassWriter.TABL_INSN:
-                // skips 0 to 3 padding bytes
-                v = u;
-                u = u + 4 - (v & 3);
-                // reads and copies instruction
-                newCode.putByte(Opcodes.TABLESWITCH);
-                newCode.putByteArray(null, 0, (4 - newCode.length % 4) % 4);
-                label = v + readInt(b, u);
-                u += 4;
-                newOffset = getNewOffset(allIndexes, allSizes, v, label);
-                newCode.putInt(newOffset);
-                j = readInt(b, u);
-                u += 4;
-                newCode.putInt(j);
-                j = readInt(b, u) - j + 1;
-                u += 4;
-                newCode.putInt(readInt(b, u - 4));
-                for (; j > 0; --j) {
-                    label = v + readInt(b, u);
-                    u += 4;
-                    newOffset = getNewOffset(allIndexes, allSizes, v, label);
-                    newCode.putInt(newOffset);
-                }
-                break;
-            case ClassWriter.LOOK_INSN:
-                // skips 0 to 3 padding bytes
-                v = u;
-                u = u + 4 - (v & 3);
-                // reads and copies instruction
-                newCode.putByte(Opcodes.LOOKUPSWITCH);
-                newCode.putByteArray(null, 0, (4 - newCode.length % 4) % 4);
-                label = v + readInt(b, u);
-                u += 4;
-                newOffset = getNewOffset(allIndexes, allSizes, v, label);
-                newCode.putInt(newOffset);
-                j = readInt(b, u);
-                u += 4;
-                newCode.putInt(j);
-                for (; j > 0; --j) {
-                    newCode.putInt(readInt(b, u));
-                    u += 4;
-                    label = v + readInt(b, u);
-                    u += 4;
-                    newOffset = getNewOffset(allIndexes, allSizes, v, label);
-                    newCode.putInt(newOffset);
-                }
-                break;
-            case ClassWriter.WIDE_INSN:
-                opcode = b[u + 1] & 0xFF;
-                if (opcode == Opcodes.IINC) {
-                    newCode.putByteArray(b, u, 6);
-                    u += 6;
-                } else {
-                    newCode.putByteArray(b, u, 4);
-                    u += 4;
-                }
-                break;
-            case ClassWriter.VAR_INSN:
-            case ClassWriter.SBYTE_INSN:
-            case ClassWriter.LDC_INSN:
-                newCode.putByteArray(b, u, 2);
-                u += 2;
-                break;
-            case ClassWriter.SHORT_INSN:
-            case ClassWriter.LDCW_INSN:
-            case ClassWriter.FIELDORMETH_INSN:
-            case ClassWriter.TYPE_INSN:
-            case ClassWriter.IINC_INSN:
-                newCode.putByteArray(b, u, 3);
-                u += 3;
-                break;
-            case ClassWriter.ITFMETH_INSN:
-            case ClassWriter.INDYMETH_INSN:
-                newCode.putByteArray(b, u, 5);
-                u += 5;
-                break;
-            // case MANA_INSN:
-            default:
-                newCode.putByteArray(b, u, 4);
-                u += 4;
-                break;
-            }
-        }
-
-        // updates the stack map frame labels
-        if (compute == FRAMES) {
-            Label l = labels;
-            while (l != null) {
-                /*
-                 * Detects the labels that are just after an IF instruction that
-                 * has been resized with the IFNOT GOTO_W pattern. These labels
-                 * are now the target of a jump instruction (the IFNOT
-                 * instruction). Note that we need the original label position
-                 * here. getNewOffset must therefore never have been called for
-                 * this label.
-                 */
-                u = l.position - 3;
-                if (u >= 0 && resize[u]) {
-                    l.status |= Label.TARGET;
-                }
-                getNewOffset(allIndexes, allSizes, l);
-                l = l.successor;
-            }
-            // Update the offsets in the uninitialized types
-            if (cw.typeTable != null) {
-                for (i = 0; i < cw.typeTable.length; ++i) {
-                    Item item = cw.typeTable[i];
-                    if (item != null && item.type == ClassWriter.TYPE_UNINIT) {
-                        item.intVal = getNewOffset(allIndexes, allSizes, 0,
-                                item.intVal);
-                    }
-                }
-            }
-            // The stack map frames are not serialized yet, so we don't need
-            // to update them. They will be serialized in visitMaxs.
-        } else if (frameCount > 0) {
-            /*
-             * Resizing an existing stack map frame table is really hard. Not
-             * only the table must be parsed to update the offets, but new
-             * frames may be needed for jump instructions that were inserted by
-             * this method. And updating the offsets or inserting frames can
-             * change the format of the following frames, in case of packed
-             * frames. In practice the whole table must be recomputed. For this
-             * the frames are marked as potentially invalid. This will cause the
-             * whole class to be reread and rewritten with the COMPUTE_FRAMES
-             * option (see the ClassWriter.toByteArray method). This is not very
-             * efficient but is much easier and requires much less code than any
-             * other method I can think of.
-             */
-            cw.invalidFrames = true;
-        }
-        // updates the exception handler block labels
-        Handler h = firstHandler;
-        while (h != null) {
-            getNewOffset(allIndexes, allSizes, h.start);
-            getNewOffset(allIndexes, allSizes, h.end);
-            getNewOffset(allIndexes, allSizes, h.handler);
-            h = h.next;
-        }
-        // updates the instructions addresses in the
-        // local var and line number tables
-        for (i = 0; i < 2; ++i) {
-            ByteVector bv = i == 0 ? localVar : localVarType;
-            if (bv != null) {
-                b = bv.data;
-                u = 0;
-                while (u < bv.length) {
-                    label = readUnsignedShort(b, u);
-                    newOffset = getNewOffset(allIndexes, allSizes, 0, label);
-                    writeShort(b, u, newOffset);
-                    label += readUnsignedShort(b, u + 2);
-                    newOffset = getNewOffset(allIndexes, allSizes, 0, label)
-                            - newOffset;
-                    writeShort(b, u + 2, newOffset);
-                    u += 10;
-                }
-            }
-        }
-        if (lineNumber != null) {
-            b = lineNumber.data;
-            u = 0;
-            while (u < lineNumber.length) {
-                writeShort(
-                        b,
-                        u,
-                        getNewOffset(allIndexes, allSizes, 0,
-                                readUnsignedShort(b, u)));
-                u += 4;
-            }
-        }
-        // updates the labels of the other attributes
-        Attribute attr = cattrs;
-        while (attr != null) {
-            Label[] labels = attr.getLabels();
-            if (labels != null) {
-                for (i = labels.length - 1; i >= 0; --i) {
-                    getNewOffset(allIndexes, allSizes, labels[i]);
-                }
-            }
-            attr = attr.next;
-        }
-
-        // replaces old bytecodes with new ones
-        code = newCode;
-    }
-
-    /**
-     * Reads an unsigned short value in the given byte array.
-     * 
-     * @param b
-     *            a byte array.
-     * @param index
-     *            the start index of the value to be read.
-     * @return the read value.
-     */
-    static int readUnsignedShort(final byte[] b, final int index) {
-        return ((b[index] & 0xFF) << 8) | (b[index + 1] & 0xFF);
-    }
-
-    /**
-     * Reads a signed short value in the given byte array.
-     * 
-     * @param b
-     *            a byte array.
-     * @param index
-     *            the start index of the value to be read.
-     * @return the read value.
-     */
-    static short readShort(final byte[] b, final int index) {
-        return (short) (((b[index] & 0xFF) << 8) | (b[index + 1] & 0xFF));
-    }
-
-    /**
-     * Reads a signed int value in the given byte array.
-     * 
-     * @param b
-     *            a byte array.
-     * @param index
-     *            the start index of the value to be read.
-     * @return the read value.
-     */
-    static int readInt(final byte[] b, final int index) {
-        return ((b[index] & 0xFF) << 24) | ((b[index + 1] & 0xFF) << 16)
-                | ((b[index + 2] & 0xFF) << 8) | (b[index + 3] & 0xFF);
-    }
-
-    /**
-     * Writes a short value in the given byte array.
-     * 
-     * @param b
-     *            a byte array.
-     * @param index
-     *            where the first byte of the short value must be written.
-     * @param s
-     *            the value to be written in the given byte array.
-     */
-    static void writeShort(final byte[] b, final int index, final int s) {
-        b[index] = (byte) (s >>> 8);
-        b[index + 1] = (byte) s;
-    }
-
-    /**
-     * Computes the future value of a bytecode offset.
-     *
-     * Note: it is possible to have several entries for the same instruction in
-     * the <tt>indexes</tt> and <tt>sizes</tt>: two entries (index=a,size=b) and
-     * (index=a,size=b') are equivalent to a single entry (index=a,size=b+b').
-     * 
-     * @param indexes
-     *            current positions of the instructions to be resized. Each
-     *            instruction must be designated by the index of its <i>last</i>
-     *            byte, plus one (or, in other words, by the index of the
-     *            <i>first</i> byte of the <i>next</i> instruction).
-     * @param sizes
-     *            the number of bytes to be <i>added</i> to the above
-     *            instructions. More precisely, for each i < <tt>len</tt>,
-     *            <tt>sizes</tt>[i] bytes will be added at the end of the
-     *            instruction designated by <tt>indexes</tt>[i] or, if
-     *            <tt>sizes</tt>[i] is negative, the <i>last</i> |
-     *            <tt>sizes[i]</tt>| bytes of the instruction will be removed
-     *            (the instruction size <i>must not</i> become negative or
-     *            null).
-     * @param begin
-     *            index of the first byte of the source instruction.
-     * @param end
-     *            index of the first byte of the target instruction.
-     * @return the future value of the given bytecode offset.
-     */
-    static int getNewOffset(final int[] indexes, final int[] sizes,
-            final int begin, final int end) {
-        int offset = end - begin;
-        for (int i = 0; i < indexes.length; ++i) {
-            if (begin < indexes[i] && indexes[i] <= end) {
-                // forward jump
-                offset += sizes[i];
-            } else if (end < indexes[i] && indexes[i] <= begin) {
-                // backward jump
-                offset -= sizes[i];
-            }
-        }
-        return offset;
-    }
-
-    /**
-     * Updates the offset of the given label.
-     * 
-     * @param indexes
-     *            current positions of the instructions to be resized. Each
-     *            instruction must be designated by the index of its <i>last</i>
-     *            byte, plus one (or, in other words, by the index of the
-     *            <i>first</i> byte of the <i>next</i> instruction).
-     * @param sizes
-     *            the number of bytes to be <i>added</i> to the above
-     *            instructions. More precisely, for each i < <tt>len</tt>,
-     *            <tt>sizes</tt>[i] bytes will be added at the end of the
-     *            instruction designated by <tt>indexes</tt>[i] or, if
-     *            <tt>sizes</tt>[i] is negative, the <i>last</i> |
-     *            <tt>sizes[i]</tt>| bytes of the instruction will be removed
-     *            (the instruction size <i>must not</i> become negative or
-     *            null).
-     * @param label
-     *            the label whose offset must be updated.
-     */
-    static void getNewOffset(final int[] indexes, final int[] sizes,
-            final Label label) {
-        if ((label.status & Label.RESIZED) == 0) {
-            label.position = getNewOffset(indexes, sizes, 0, label.position);
-            label.status |= Label.RESIZED;
-        }
-    }
 }

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/74324b31/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/ModuleVisitor.java
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/ModuleVisitor.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/ModuleVisitor.java
new file mode 100644
index 0000000..c3a2aac
--- /dev/null
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/ModuleVisitor.java
@@ -0,0 +1,190 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 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.apache.tapestry5.internal.plastic.asm;
+
+/**
+ * A visitor to visit a Java module. The methods of this class must be called in
+ * the following order: <tt>visitMainClass</tt> | ( <tt>visitPackage</tt> |
+ * <tt>visitRequire</tt> | <tt>visitExport</tt> | <tt>visitOpen</tt> |
+ * <tt>visitUse</tt> | <tt>visitProvide</tt> )* <tt>visitEnd</tt>.
+ * 
+ * The methods {@link #visitRequire(String, int, String)}, {@link #visitExport(String, int, String...)},
+ * {@link #visitOpen(String, int, String...)} and {@link #visitPackage(String)}
+ * take as parameter a package name or a module name. Unlike the other names which are internal names
+ * (names separated by slash), module and package names are qualified names (names separated by dot).
+ * 
+ * @author Remi Forax
+ */
+public abstract class ModuleVisitor {
+    /**
+     * The ASM API version implemented by this visitor. The value of this field
+     * must be {@link Opcodes#ASM6}.
+     */
+    protected final int api;
+    
+    /**
+     * The module visitor to which this visitor must delegate method calls. May
+     * be null.
+     */
+    protected ModuleVisitor mv;
+    
+    /**
+     * Constructs a new {@link ModuleVisitor}.
+     * 
+     * @param api
+     *            the ASM API version implemented by this visitor. Must be {@link Opcodes#ASM6}.
+     */
+    public ModuleVisitor(final int api) {
+        this(api, null);
+    }
+
+    /**
+     * Constructs a new {@link ModuleVisitor}.
+     * 
+     * @param api
+     *            the ASM API version implemented by this visitor. Must be {@link Opcodes#ASM6}.
+     * @param mv
+     *            the module visitor to which this visitor must delegate method
+     *            calls. May be null.
+     */
+    public ModuleVisitor(final int api, final ModuleVisitor mv) {
+        if (api != Opcodes.ASM6) {
+            throw new IllegalArgumentException();
+        }
+        this.api = api;
+        this.mv = mv;
+    }
+    
+    /**
+     * Visit the main class of the current module.
+     * 
+     * @param mainClass the internal name of the main class of the current module.
+     */
+    public void visitMainClass(String mainClass) {
+        if (mv != null) {
+            mv.visitMainClass(mainClass);
+        }
+    }
+    
+    /**
+     * Visit a package of the current module.
+     * 
+     * @param packaze the qualified name of a package.
+     */
+    public void visitPackage(String packaze) {
+        if (mv != null) {
+            mv.visitPackage(packaze);
+        }
+    }
+    
+    /**
+     * Visits a dependence of the current module.
+     * 
+     * @param module the qualified name of the dependence.
+     * @param access the access flag of the dependence among
+     *        ACC_TRANSITIVE, ACC_STATIC_PHASE, ACC_SYNTHETIC
+     *        and ACC_MANDATED.
+     * @param version the module version at compile time or null.
+     */
+    public void visitRequire(String module, int access, String version) {
+        if (mv != null) {
+            mv.visitRequire(module, access, version);
+        }
+    }
+    
+    /**
+     * Visit an exported package of the current module.
+     * 
+     * @param packaze the qualified name of the exported package.
+     * @param access the access flag of the exported package,
+     *        valid values are among {@code ACC_SYNTHETIC} and
+     *        {@code ACC_MANDATED}.
+     * @param modules the qualified names of the modules that can access to
+     *        the public classes of the exported package or
+     *        <tt>null</tt>.
+     */
+    public void visitExport(String packaze, int access, String... modules) {
+        if (mv != null) {
+            mv.visitExport(packaze, access, modules);
+        }
+    }
+    
+    /**
+     * Visit an open package of the current module.
+     * 
+     * @param packaze the qualified name of the opened package.
+     * @param access the access flag of the opened package,
+     *        valid values are among {@code ACC_SYNTHETIC} and
+     *        {@code ACC_MANDATED}.
+     * @param modules the qualified names of the modules that can use deep
+     *        reflection to the classes of the open package or
+     *        <tt>null</tt>.
+     */
+    public void visitOpen(String packaze, int access, String... modules) {
+        if (mv != null) {
+            mv.visitOpen(packaze, access, modules);
+        }
+    }
+    
+    /**
+     * Visit a service used by the current module.
+     * The name must be the internal name of an interface or a class.
+     * 
+     * @param service the internal name of the service.
+     */
+    public void visitUse(String service) {
+        if (mv != null) {
+            mv.visitUse(service);
+        }
+    }
+    
+    /**
+     * Visit an implementation of a service.
+     * 
+     * @param service the internal name of the service
+     * @param providers the internal names of the implementations
+     *        of the service (there is at least one provider).
+     */
+    public void visitProvide(String service, String... providers) {
+        if (mv != null) {
+            mv.visitProvide(service, providers);
+        }
+    }
+    
+    /**
+     * Visits the end of the module. This method, which is the last one to be
+     * called, is used to inform the visitor that everything have been visited.
+     */
+    public void visitEnd() {
+        if (mv != null) {
+            mv.visitEnd();
+        }
+    }
+}


Mime
View raw message