tajo-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From hyun...@apache.org
Subject [18/25] TAJO-906: Runtime code generation for evaluating expression trees.
Date Sat, 23 Aug 2014 17:38:07 GMT
http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/FieldWriter.java
----------------------------------------------------------------------
diff --git a/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/FieldWriter.java b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/FieldWriter.java
new file mode 100644
index 0000000..f3437e3
--- /dev/null
+++ b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/FieldWriter.java
@@ -0,0 +1,273 @@
+/***
+ * 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.tajo.org.objectweb.asm;
+
+/**
+ * An {@link FieldVisitor} that generates Java fields in bytecode form.
+ * 
+ * @author Eric Bruneton
+ */
+final class FieldWriter extends FieldVisitor {
+
+    /**
+     * The class writer to which this field must be added.
+     */
+    private final ClassWriter cw;
+
+    /**
+     * Access flags of this field.
+     */
+    private final int access;
+
+    /**
+     * The index of the constant pool item that contains the name of this
+     * method.
+     */
+    private final int name;
+
+    /**
+     * The index of the constant pool item that contains the descriptor of this
+     * field.
+     */
+    private final int desc;
+
+    /**
+     * The index of the constant pool item that contains the signature of this
+     * field.
+     */
+    private int signature;
+
+    /**
+     * The index of the constant pool item that contains the constant value of
+     * this field.
+     */
+    private int value;
+
+    /**
+     * The runtime visible annotations of this field. May be <tt>null</tt>.
+     */
+    private AnnotationWriter anns;
+
+    /**
+     * The runtime invisible annotations of this field. May be <tt>null</tt>.
+     */
+    private AnnotationWriter ianns;
+
+    /**
+     * The non standard attributes of this field. May be <tt>null</tt>.
+     */
+    private Attribute attrs;
+
+    // ------------------------------------------------------------------------
+    // Constructor
+    // ------------------------------------------------------------------------
+
+    /**
+     * Constructs a new {@link FieldWriter}.
+     * 
+     * @param cw
+     *            the class writer to which this field must be added.
+     * @param access
+     *            the field's access flags (see {@link Opcodes}).
+     * @param name
+     *            the field's name.
+     * @param desc
+     *            the field's descriptor (see {@link Type}).
+     * @param signature
+     *            the field's signature. May be <tt>null</tt>.
+     * @param value
+     *            the field's constant value. May be <tt>null</tt>.
+     */
+    FieldWriter(final ClassWriter cw, final int access, final String name,
+            final String desc, final String signature, final Object value) {
+        super(Opcodes.ASM4);
+        if (cw.firstField == null) {
+            cw.firstField = this;
+        } else {
+            cw.lastField.fv = this;
+        }
+        cw.lastField = this;
+        this.cw = cw;
+        this.access = access;
+        this.name = cw.newUTF8(name);
+        this.desc = cw.newUTF8(desc);
+        if (ClassReader.SIGNATURES && signature != null) {
+            this.signature = cw.newUTF8(signature);
+        }
+        if (value != null) {
+            this.value = cw.newConstItem(value).index;
+        }
+    }
+
+    // ------------------------------------------------------------------------
+    // Implementation of the FieldVisitor abstract class
+    // ------------------------------------------------------------------------
+
+    @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);
+        AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv, 2);
+        if (visible) {
+            aw.next = anns;
+            anns = aw;
+        } else {
+            aw.next = ianns;
+            ianns = aw;
+        }
+        return aw;
+    }
+
+    @Override
+    public void visitAttribute(final Attribute attr) {
+        attr.next = attrs;
+        attrs = attr;
+    }
+
+    @Override
+    public void visitEnd() {
+    }
+
+    // ------------------------------------------------------------------------
+    // Utility methods
+    // ------------------------------------------------------------------------
+
+    /**
+     * Returns the size of this field.
+     * 
+     * @return the size of this field.
+     */
+    int getSize() {
+        int size = 8;
+        if (value != 0) {
+            cw.newUTF8("ConstantValue");
+            size += 8;
+        }
+        if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
+            if ((cw.version & 0xFFFF) < Opcodes.V1_5
+                    || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) {
+                cw.newUTF8("Synthetic");
+                size += 6;
+            }
+        }
+        if ((access & Opcodes.ACC_DEPRECATED) != 0) {
+            cw.newUTF8("Deprecated");
+            size += 6;
+        }
+        if (ClassReader.SIGNATURES && signature != 0) {
+            cw.newUTF8("Signature");
+            size += 8;
+        }
+        if (ClassReader.ANNOTATIONS && anns != null) {
+            cw.newUTF8("RuntimeVisibleAnnotations");
+            size += 8 + anns.getSize();
+        }
+        if (ClassReader.ANNOTATIONS && ianns != null) {
+            cw.newUTF8("RuntimeInvisibleAnnotations");
+            size += 8 + ianns.getSize();
+        }
+        if (attrs != null) {
+            size += attrs.getSize(cw, null, 0, -1, -1);
+        }
+        return size;
+    }
+
+    /**
+     * Puts the content of this field into the given byte vector.
+     * 
+     * @param out
+     *            where the content of this field must be put.
+     */
+    void put(final ByteVector out) {
+        final int FACTOR = ClassWriter.TO_ACC_SYNTHETIC;
+        int mask = Opcodes.ACC_DEPRECATED | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE
+                | ((access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) / FACTOR);
+        out.putShort(access & ~mask).putShort(name).putShort(desc);
+        int attributeCount = 0;
+        if (value != 0) {
+            ++attributeCount;
+        }
+        if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
+            if ((cw.version & 0xFFFF) < Opcodes.V1_5
+                    || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) {
+                ++attributeCount;
+            }
+        }
+        if ((access & Opcodes.ACC_DEPRECATED) != 0) {
+            ++attributeCount;
+        }
+        if (ClassReader.SIGNATURES && signature != 0) {
+            ++attributeCount;
+        }
+        if (ClassReader.ANNOTATIONS && anns != null) {
+            ++attributeCount;
+        }
+        if (ClassReader.ANNOTATIONS && ianns != null) {
+            ++attributeCount;
+        }
+        if (attrs != null) {
+            attributeCount += attrs.getCount();
+        }
+        out.putShort(attributeCount);
+        if (value != 0) {
+            out.putShort(cw.newUTF8("ConstantValue"));
+            out.putInt(2).putShort(value);
+        }
+        if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
+            if ((cw.version & 0xFFFF) < Opcodes.V1_5
+                    || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) {
+                out.putShort(cw.newUTF8("Synthetic")).putInt(0);
+            }
+        }
+        if ((access & Opcodes.ACC_DEPRECATED) != 0) {
+            out.putShort(cw.newUTF8("Deprecated")).putInt(0);
+        }
+        if (ClassReader.SIGNATURES && signature != 0) {
+            out.putShort(cw.newUTF8("Signature"));
+            out.putInt(2).putShort(signature);
+        }
+        if (ClassReader.ANNOTATIONS && anns != null) {
+            out.putShort(cw.newUTF8("RuntimeVisibleAnnotations"));
+            anns.put(out);
+        }
+        if (ClassReader.ANNOTATIONS && ianns != null) {
+            out.putShort(cw.newUTF8("RuntimeInvisibleAnnotations"));
+            ianns.put(out);
+        }
+        if (attrs != null) {
+            attrs.put(cw, null, 0, -1, -1, out);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/Frame.java
----------------------------------------------------------------------
diff --git a/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/Frame.java b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/Frame.java
new file mode 100644
index 0000000..73d00d9
--- /dev/null
+++ b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/Frame.java
@@ -0,0 +1,1453 @@
+/***
+ * 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.tajo.org.objectweb.asm;
+
+/**
+ * Information about the input and output stack map frames of a basic block.
+ * 
+ * @author Eric Bruneton
+ */
+final class Frame {
+
+    /*
+     * Frames are computed in a two steps process: during the visit of each
+     * instruction, the state of the frame at the end of current basic block is
+     * updated by simulating the action of the instruction on the previous state
+     * of this so called "output frame". In visitMaxs, a fix point algorithm is
+     * used to compute the "input frame" of each basic block, i.e. the stack map
+     * frame at the beginning of the basic block, starting from the input frame
+     * of the first basic block (which is computed from the method descriptor),
+     * and by using the previously computed output frames to compute the input
+     * state of the other blocks.
+     * 
+     * All output and input frames are stored as arrays of integers. Reference
+     * and array types are represented by an index into a type table (which is
+     * not the same as the constant pool of the class, in order to avoid adding
+     * unnecessary constants in the pool - not all computed frames will end up
+     * being stored in the stack map table). This allows very fast type
+     * comparisons.
+     * 
+     * Output stack map frames are computed relatively to the input frame of the
+     * basic block, which is not yet known when output frames are computed. It
+     * is therefore necessary to be able to represent abstract types such as
+     * "the type at position x in the input frame locals" or "the type at
+     * position x from the top of the input frame stack" or even "the type at
+     * position x in the input frame, with y more (or less) array dimensions".
+     * This explains the rather complicated type format used in output frames.
+     * 
+     * This format is the following: DIM KIND VALUE (4, 4 and 24 bits). DIM is a
+     * signed number of array dimensions (from -8 to 7). KIND is either BASE,
+     * LOCAL or STACK. BASE is used for types that are not relative to the input
+     * frame. LOCAL is used for types that are relative to the input local
+     * variable types. STACK is used for types that are relative to the input
+     * stack types. VALUE depends on KIND. For LOCAL types, it is an index in
+     * the input local variable types. For STACK types, it is a position
+     * relatively to the top of input frame stack. For BASE types, it is either
+     * one of the constants defined in FrameVisitor, or for OBJECT and
+     * UNINITIALIZED types, a tag and an index in the type table.
+     * 
+     * Output frames can contain types of any kind and with a positive or
+     * negative dimension (and even unassigned types, represented by 0 - which
+     * does not correspond to any valid type value). Input frames can only
+     * contain BASE types of positive or null dimension. In all cases the type
+     * table contains only internal type names (array type descriptors are
+     * forbidden - dimensions must be represented through the DIM field).
+     * 
+     * The LONG and DOUBLE types are always represented by using two slots (LONG
+     * + TOP or DOUBLE + TOP), for local variable types as well as in the
+     * operand stack. This is necessary to be able to simulate DUPx_y
+     * instructions, whose effect would be dependent on the actual type values
+     * if types were always represented by a single slot in the stack (and this
+     * is not possible, since actual type values are not always known - cf LOCAL
+     * and STACK type kinds).
+     */
+
+    /**
+     * Mask to get the dimension of a frame type. This dimension is a signed
+     * integer between -8 and 7.
+     */
+    static final int DIM = 0xF0000000;
+
+    /**
+     * Constant to be added to a type to get a type with one more dimension.
+     */
+    static final int ARRAY_OF = 0x10000000;
+
+    /**
+     * Constant to be added to a type to get a type with one less dimension.
+     */
+    static final int ELEMENT_OF = 0xF0000000;
+
+    /**
+     * Mask to get the kind of a frame type.
+     * 
+     * @see #BASE
+     * @see #LOCAL
+     * @see #STACK
+     */
+    static final int KIND = 0xF000000;
+
+    /**
+     * Flag used for LOCAL and STACK types. Indicates that if this type happens
+     * to be a long or double type (during the computations of input frames),
+     * then it must be set to TOP because the second word of this value has been
+     * reused to store other data in the basic block. Hence the first word no
+     * longer stores a valid long or double value.
+     */
+    static final int TOP_IF_LONG_OR_DOUBLE = 0x800000;
+
+    /**
+     * Mask to get the value of a frame type.
+     */
+    static final int VALUE = 0x7FFFFF;
+
+    /**
+     * Mask to get the kind of base types.
+     */
+    static final int BASE_KIND = 0xFF00000;
+
+    /**
+     * Mask to get the value of base types.
+     */
+    static final int BASE_VALUE = 0xFFFFF;
+
+    /**
+     * Kind of the types that are not relative to an input stack map frame.
+     */
+    static final int BASE = 0x1000000;
+
+    /**
+     * Base kind of the base reference types. The BASE_VALUE of such types is an
+     * index into the type table.
+     */
+    static final int OBJECT = BASE | 0x700000;
+
+    /**
+     * Base kind of the uninitialized base types. The BASE_VALUE of such types
+     * in an index into the type table (the Item at that index contains both an
+     * instruction offset and an internal class name).
+     */
+    static final int UNINITIALIZED = BASE | 0x800000;
+
+    /**
+     * Kind of the types that are relative to the local variable types of an
+     * input stack map frame. The value of such types is a local variable index.
+     */
+    private static final int LOCAL = 0x2000000;
+
+    /**
+     * Kind of the the types that are relative to the stack of an input stack
+     * map frame. The value of such types is a position relatively to the top of
+     * this stack.
+     */
+    private static final int STACK = 0x3000000;
+
+    /**
+     * The TOP type. This is a BASE type.
+     */
+    static final int TOP = BASE | 0;
+
+    /**
+     * The BOOLEAN type. This is a BASE type mainly used for array types.
+     */
+    static final int BOOLEAN = BASE | 9;
+
+    /**
+     * The BYTE type. This is a BASE type mainly used for array types.
+     */
+    static final int BYTE = BASE | 10;
+
+    /**
+     * The CHAR type. This is a BASE type mainly used for array types.
+     */
+    static final int CHAR = BASE | 11;
+
+    /**
+     * The SHORT type. This is a BASE type mainly used for array types.
+     */
+    static final int SHORT = BASE | 12;
+
+    /**
+     * The INTEGER type. This is a BASE type.
+     */
+    static final int INTEGER = BASE | 1;
+
+    /**
+     * The FLOAT type. This is a BASE type.
+     */
+    static final int FLOAT = BASE | 2;
+
+    /**
+     * The DOUBLE type. This is a BASE type.
+     */
+    static final int DOUBLE = BASE | 3;
+
+    /**
+     * The LONG type. This is a BASE type.
+     */
+    static final int LONG = BASE | 4;
+
+    /**
+     * The NULL type. This is a BASE type.
+     */
+    static final int NULL = BASE | 5;
+
+    /**
+     * The UNINITIALIZED_THIS type. This is a BASE type.
+     */
+    static final int UNINITIALIZED_THIS = BASE | 6;
+
+    /**
+     * The stack size variation corresponding to each JVM instruction. This
+     * stack variation is equal to the size of the values produced by an
+     * instruction, minus the size of the values consumed by this instruction.
+     */
+    static final int[] SIZE;
+
+    /**
+     * Computes the stack size variation corresponding to each JVM instruction.
+     */
+    static {
+        int i;
+        int[] b = new int[202];
+        String s = "EFFFFFFFFGGFFFGGFFFEEFGFGFEEEEEEEEEEEEEEEEEEEEDEDEDDDDD"
+                + "CDCDEEEEEEEEEEEEEEEEEEEEBABABBBBDCFFFGGGEDCDCDCDCDCDCDCDCD"
+                + "CDCEEEEDDDDDDDCDCDCEFEFDDEEFFDEDEEEBDDBBDDDDDDCCCCCCCCEFED"
+                + "DDCDCDEEEEEEEEEEFEEEEEEDDEEDDEE";
+        for (i = 0; i < b.length; ++i) {
+            b[i] = s.charAt(i) - 'E';
+        }
+        SIZE = b;
+
+        // code to generate the above string
+        //
+        // int NA = 0; // not applicable (unused opcode or variable size opcode)
+        //
+        // b = new int[] {
+        // 0, //NOP, // visitInsn
+        // 1, //ACONST_NULL, // -
+        // 1, //ICONST_M1, // -
+        // 1, //ICONST_0, // -
+        // 1, //ICONST_1, // -
+        // 1, //ICONST_2, // -
+        // 1, //ICONST_3, // -
+        // 1, //ICONST_4, // -
+        // 1, //ICONST_5, // -
+        // 2, //LCONST_0, // -
+        // 2, //LCONST_1, // -
+        // 1, //FCONST_0, // -
+        // 1, //FCONST_1, // -
+        // 1, //FCONST_2, // -
+        // 2, //DCONST_0, // -
+        // 2, //DCONST_1, // -
+        // 1, //BIPUSH, // visitIntInsn
+        // 1, //SIPUSH, // -
+        // 1, //LDC, // visitLdcInsn
+        // NA, //LDC_W, // -
+        // NA, //LDC2_W, // -
+        // 1, //ILOAD, // visitVarInsn
+        // 2, //LLOAD, // -
+        // 1, //FLOAD, // -
+        // 2, //DLOAD, // -
+        // 1, //ALOAD, // -
+        // NA, //ILOAD_0, // -
+        // NA, //ILOAD_1, // -
+        // NA, //ILOAD_2, // -
+        // NA, //ILOAD_3, // -
+        // NA, //LLOAD_0, // -
+        // NA, //LLOAD_1, // -
+        // NA, //LLOAD_2, // -
+        // NA, //LLOAD_3, // -
+        // NA, //FLOAD_0, // -
+        // NA, //FLOAD_1, // -
+        // NA, //FLOAD_2, // -
+        // NA, //FLOAD_3, // -
+        // NA, //DLOAD_0, // -
+        // NA, //DLOAD_1, // -
+        // NA, //DLOAD_2, // -
+        // NA, //DLOAD_3, // -
+        // NA, //ALOAD_0, // -
+        // NA, //ALOAD_1, // -
+        // NA, //ALOAD_2, // -
+        // NA, //ALOAD_3, // -
+        // -1, //IALOAD, // visitInsn
+        // 0, //LALOAD, // -
+        // -1, //FALOAD, // -
+        // 0, //DALOAD, // -
+        // -1, //AALOAD, // -
+        // -1, //BALOAD, // -
+        // -1, //CALOAD, // -
+        // -1, //SALOAD, // -
+        // -1, //ISTORE, // visitVarInsn
+        // -2, //LSTORE, // -
+        // -1, //FSTORE, // -
+        // -2, //DSTORE, // -
+        // -1, //ASTORE, // -
+        // NA, //ISTORE_0, // -
+        // NA, //ISTORE_1, // -
+        // NA, //ISTORE_2, // -
+        // NA, //ISTORE_3, // -
+        // NA, //LSTORE_0, // -
+        // NA, //LSTORE_1, // -
+        // NA, //LSTORE_2, // -
+        // NA, //LSTORE_3, // -
+        // NA, //FSTORE_0, // -
+        // NA, //FSTORE_1, // -
+        // NA, //FSTORE_2, // -
+        // NA, //FSTORE_3, // -
+        // NA, //DSTORE_0, // -
+        // NA, //DSTORE_1, // -
+        // NA, //DSTORE_2, // -
+        // NA, //DSTORE_3, // -
+        // NA, //ASTORE_0, // -
+        // NA, //ASTORE_1, // -
+        // NA, //ASTORE_2, // -
+        // NA, //ASTORE_3, // -
+        // -3, //IASTORE, // visitInsn
+        // -4, //LASTORE, // -
+        // -3, //FASTORE, // -
+        // -4, //DASTORE, // -
+        // -3, //AASTORE, // -
+        // -3, //BASTORE, // -
+        // -3, //CASTORE, // -
+        // -3, //SASTORE, // -
+        // -1, //POP, // -
+        // -2, //POP2, // -
+        // 1, //DUP, // -
+        // 1, //DUP_X1, // -
+        // 1, //DUP_X2, // -
+        // 2, //DUP2, // -
+        // 2, //DUP2_X1, // -
+        // 2, //DUP2_X2, // -
+        // 0, //SWAP, // -
+        // -1, //IADD, // -
+        // -2, //LADD, // -
+        // -1, //FADD, // -
+        // -2, //DADD, // -
+        // -1, //ISUB, // -
+        // -2, //LSUB, // -
+        // -1, //FSUB, // -
+        // -2, //DSUB, // -
+        // -1, //IMUL, // -
+        // -2, //LMUL, // -
+        // -1, //FMUL, // -
+        // -2, //DMUL, // -
+        // -1, //IDIV, // -
+        // -2, //LDIV, // -
+        // -1, //FDIV, // -
+        // -2, //DDIV, // -
+        // -1, //IREM, // -
+        // -2, //LREM, // -
+        // -1, //FREM, // -
+        // -2, //DREM, // -
+        // 0, //INEG, // -
+        // 0, //LNEG, // -
+        // 0, //FNEG, // -
+        // 0, //DNEG, // -
+        // -1, //ISHL, // -
+        // -1, //LSHL, // -
+        // -1, //ISHR, // -
+        // -1, //LSHR, // -
+        // -1, //IUSHR, // -
+        // -1, //LUSHR, // -
+        // -1, //IAND, // -
+        // -2, //LAND, // -
+        // -1, //IOR, // -
+        // -2, //LOR, // -
+        // -1, //IXOR, // -
+        // -2, //LXOR, // -
+        // 0, //IINC, // visitIincInsn
+        // 1, //I2L, // visitInsn
+        // 0, //I2F, // -
+        // 1, //I2D, // -
+        // -1, //L2I, // -
+        // -1, //L2F, // -
+        // 0, //L2D, // -
+        // 0, //F2I, // -
+        // 1, //F2L, // -
+        // 1, //F2D, // -
+        // -1, //D2I, // -
+        // 0, //D2L, // -
+        // -1, //D2F, // -
+        // 0, //I2B, // -
+        // 0, //I2C, // -
+        // 0, //I2S, // -
+        // -3, //LCMP, // -
+        // -1, //FCMPL, // -
+        // -1, //FCMPG, // -
+        // -3, //DCMPL, // -
+        // -3, //DCMPG, // -
+        // -1, //IFEQ, // visitJumpInsn
+        // -1, //IFNE, // -
+        // -1, //IFLT, // -
+        // -1, //IFGE, // -
+        // -1, //IFGT, // -
+        // -1, //IFLE, // -
+        // -2, //IF_ICMPEQ, // -
+        // -2, //IF_ICMPNE, // -
+        // -2, //IF_ICMPLT, // -
+        // -2, //IF_ICMPGE, // -
+        // -2, //IF_ICMPGT, // -
+        // -2, //IF_ICMPLE, // -
+        // -2, //IF_ACMPEQ, // -
+        // -2, //IF_ACMPNE, // -
+        // 0, //GOTO, // -
+        // 1, //JSR, // -
+        // 0, //RET, // visitVarInsn
+        // -1, //TABLESWITCH, // visiTableSwitchInsn
+        // -1, //LOOKUPSWITCH, // visitLookupSwitch
+        // -1, //IRETURN, // visitInsn
+        // -2, //LRETURN, // -
+        // -1, //FRETURN, // -
+        // -2, //DRETURN, // -
+        // -1, //ARETURN, // -
+        // 0, //RETURN, // -
+        // NA, //GETSTATIC, // visitFieldInsn
+        // NA, //PUTSTATIC, // -
+        // NA, //GETFIELD, // -
+        // NA, //PUTFIELD, // -
+        // NA, //INVOKEVIRTUAL, // visitMethodInsn
+        // NA, //INVOKESPECIAL, // -
+        // NA, //INVOKESTATIC, // -
+        // NA, //INVOKEINTERFACE, // -
+        // NA, //INVOKEDYNAMIC, // visitInvokeDynamicInsn
+        // 1, //NEW, // visitTypeInsn
+        // 0, //NEWARRAY, // visitIntInsn
+        // 0, //ANEWARRAY, // visitTypeInsn
+        // 0, //ARRAYLENGTH, // visitInsn
+        // NA, //ATHROW, // -
+        // 0, //CHECKCAST, // visitTypeInsn
+        // 0, //INSTANCEOF, // -
+        // -1, //MONITORENTER, // visitInsn
+        // -1, //MONITOREXIT, // -
+        // NA, //WIDE, // NOT VISITED
+        // NA, //MULTIANEWARRAY, // visitMultiANewArrayInsn
+        // -1, //IFNULL, // visitJumpInsn
+        // -1, //IFNONNULL, // -
+        // NA, //GOTO_W, // -
+        // NA, //JSR_W, // -
+        // };
+        // for (i = 0; i < b.length; ++i) {
+        // System.err.print((char)('E' + b[i]));
+        // }
+        // System.err.println();
+    }
+
+    /**
+     * The label (i.e. basic block) to which these input and output stack map
+     * frames correspond.
+     */
+    Label owner;
+
+    /**
+     * The input stack map frame locals.
+     */
+    int[] inputLocals;
+
+    /**
+     * The input stack map frame stack.
+     */
+    int[] inputStack;
+
+    /**
+     * The output stack map frame locals.
+     */
+    private int[] outputLocals;
+
+    /**
+     * The output stack map frame stack.
+     */
+    private int[] outputStack;
+
+    /**
+     * Relative size of the output stack. The exact semantics of this field
+     * depends on the algorithm that is used.
+     * 
+     * When only the maximum stack size is computed, this field is the size of
+     * the output stack relatively to the top of the input stack.
+     * 
+     * When the stack map frames are completely computed, this field is the
+     * actual number of types in {@link #outputStack}.
+     */
+    private int outputStackTop;
+
+    /**
+     * Number of types that are initialized in the basic block.
+     * 
+     * @see #initializations
+     */
+    private int initializationCount;
+
+    /**
+     * The types that are initialized in the basic block. A constructor
+     * invocation on an UNINITIALIZED or UNINITIALIZED_THIS type must replace
+     * <i>every occurence</i> of this type in the local variables and in the
+     * operand stack. This cannot be done during the first phase of the
+     * algorithm since, during this phase, the local variables and the operand
+     * stack are not completely computed. It is therefore necessary to store the
+     * types on which constructors are invoked in the basic block, in order to
+     * do this replacement during the second phase of the algorithm, where the
+     * frames are fully computed. Note that this array can contain types that
+     * are relative to input locals or to the input stack (see below for the
+     * description of the algorithm).
+     */
+    private int[] initializations;
+
+    /**
+     * Returns the output frame local variable type at the given index.
+     * 
+     * @param local
+     *            the index of the local that must be returned.
+     * @return the output frame local variable type at the given index.
+     */
+    private int get(final int local) {
+        if (outputLocals == null || local >= outputLocals.length) {
+            // this local has never been assigned in this basic block,
+            // so it is still equal to its value in the input frame
+            return LOCAL | local;
+        } else {
+            int type = outputLocals[local];
+            if (type == 0) {
+                // this local has never been assigned in this basic block,
+                // so it is still equal to its value in the input frame
+                type = outputLocals[local] = LOCAL | local;
+            }
+            return type;
+        }
+    }
+
+    /**
+     * Sets the output frame local variable type at the given index.
+     * 
+     * @param local
+     *            the index of the local that must be set.
+     * @param type
+     *            the value of the local that must be set.
+     */
+    private void set(final int local, final int type) {
+        // creates and/or resizes the output local variables array if necessary
+        if (outputLocals == null) {
+            outputLocals = new int[10];
+        }
+        int n = outputLocals.length;
+        if (local >= n) {
+            int[] t = new int[Math.max(local + 1, 2 * n)];
+            System.arraycopy(outputLocals, 0, t, 0, n);
+            outputLocals = t;
+        }
+        // sets the local variable
+        outputLocals[local] = type;
+    }
+
+    /**
+     * Pushes a new type onto the output frame stack.
+     * 
+     * @param type
+     *            the type that must be pushed.
+     */
+    private void push(final int type) {
+        // creates and/or resizes the output stack array if necessary
+        if (outputStack == null) {
+            outputStack = new int[10];
+        }
+        int n = outputStack.length;
+        if (outputStackTop >= n) {
+            int[] t = new int[Math.max(outputStackTop + 1, 2 * n)];
+            System.arraycopy(outputStack, 0, t, 0, n);
+            outputStack = t;
+        }
+        // pushes the type on the output stack
+        outputStack[outputStackTop++] = type;
+        // updates the maximun height reached by the output stack, if needed
+        int top = owner.inputStackTop + outputStackTop;
+        if (top > owner.outputStackMax) {
+            owner.outputStackMax = top;
+        }
+    }
+
+    /**
+     * Pushes a new type onto the output frame stack.
+     * 
+     * @param cw
+     *            the ClassWriter to which this label belongs.
+     * @param desc
+     *            the descriptor of the type to be pushed. Can also be a method
+     *            descriptor (in this case this method pushes its return type
+     *            onto the output frame stack).
+     */
+    private void push(final ClassWriter cw, final String desc) {
+        int type = type(cw, desc);
+        if (type != 0) {
+            push(type);
+            if (type == LONG || type == DOUBLE) {
+                push(TOP);
+            }
+        }
+    }
+
+    /**
+     * Returns the int encoding of the given type.
+     * 
+     * @param cw
+     *            the ClassWriter to which this label belongs.
+     * @param desc
+     *            a type descriptor.
+     * @return the int encoding of the given type.
+     */
+    private static int type(final ClassWriter cw, final String desc) {
+        String t;
+        int index = desc.charAt(0) == '(' ? desc.indexOf(')') + 1 : 0;
+        switch (desc.charAt(index)) {
+        case 'V':
+            return 0;
+        case 'Z':
+        case 'C':
+        case 'B':
+        case 'S':
+        case 'I':
+            return INTEGER;
+        case 'F':
+            return FLOAT;
+        case 'J':
+            return LONG;
+        case 'D':
+            return DOUBLE;
+        case 'L':
+            // stores the internal name, not the descriptor!
+            t = desc.substring(index + 1, desc.length() - 1);
+            return OBJECT | cw.addType(t);
+            // case '[':
+        default:
+            // extracts the dimensions and the element type
+            int data;
+            int dims = index + 1;
+            while (desc.charAt(dims) == '[') {
+                ++dims;
+            }
+            switch (desc.charAt(dims)) {
+            case 'Z':
+                data = BOOLEAN;
+                break;
+            case 'C':
+                data = CHAR;
+                break;
+            case 'B':
+                data = BYTE;
+                break;
+            case 'S':
+                data = SHORT;
+                break;
+            case 'I':
+                data = INTEGER;
+                break;
+            case 'F':
+                data = FLOAT;
+                break;
+            case 'J':
+                data = LONG;
+                break;
+            case 'D':
+                data = DOUBLE;
+                break;
+            // case 'L':
+            default:
+                // stores the internal name, not the descriptor
+                t = desc.substring(dims + 1, desc.length() - 1);
+                data = OBJECT | cw.addType(t);
+            }
+            return (dims - index) << 28 | data;
+        }
+    }
+
+    /**
+     * Pops a type from the output frame stack and returns its value.
+     * 
+     * @return the type that has been popped from the output frame stack.
+     */
+    private int pop() {
+        if (outputStackTop > 0) {
+            return outputStack[--outputStackTop];
+        } else {
+            // if the output frame stack is empty, pops from the input stack
+            return STACK | -(--owner.inputStackTop);
+        }
+    }
+
+    /**
+     * Pops the given number of types from the output frame stack.
+     * 
+     * @param elements
+     *            the number of types that must be popped.
+     */
+    private void pop(final int elements) {
+        if (outputStackTop >= elements) {
+            outputStackTop -= elements;
+        } else {
+            // if the number of elements to be popped is greater than the number
+            // of elements in the output stack, clear it, and pops the remaining
+            // elements from the input stack.
+            owner.inputStackTop -= elements - outputStackTop;
+            outputStackTop = 0;
+        }
+    }
+
+    /**
+     * Pops a type from the output frame stack.
+     * 
+     * @param desc
+     *            the descriptor of the type to be popped. Can also be a method
+     *            descriptor (in this case this method pops the types
+     *            corresponding to the method arguments).
+     */
+    private void pop(final String desc) {
+        char c = desc.charAt(0);
+        if (c == '(') {
+            pop((Type.getArgumentsAndReturnSizes(desc) >> 2) - 1);
+        } else if (c == 'J' || c == 'D') {
+            pop(2);
+        } else {
+            pop(1);
+        }
+    }
+
+    /**
+     * Adds a new type to the list of types on which a constructor is invoked in
+     * the basic block.
+     * 
+     * @param var
+     *            a type on a which a constructor is invoked.
+     */
+    private void init(final int var) {
+        // creates and/or resizes the initializations array if necessary
+        if (initializations == null) {
+            initializations = new int[2];
+        }
+        int n = initializations.length;
+        if (initializationCount >= n) {
+            int[] t = new int[Math.max(initializationCount + 1, 2 * n)];
+            System.arraycopy(initializations, 0, t, 0, n);
+            initializations = t;
+        }
+        // stores the type to be initialized
+        initializations[initializationCount++] = var;
+    }
+
+    /**
+     * Replaces the given type with the appropriate type if it is one of the
+     * types on which a constructor is invoked in the basic block.
+     * 
+     * @param cw
+     *            the ClassWriter to which this label belongs.
+     * @param t
+     *            a type
+     * @return t or, if t is one of the types on which a constructor is invoked
+     *         in the basic block, the type corresponding to this constructor.
+     */
+    private int init(final ClassWriter cw, final int t) {
+        int s;
+        if (t == UNINITIALIZED_THIS) {
+            s = OBJECT | cw.addType(cw.thisName);
+        } else if ((t & (DIM | BASE_KIND)) == UNINITIALIZED) {
+            String type = cw.typeTable[t & BASE_VALUE].strVal1;
+            s = OBJECT | cw.addType(type);
+        } else {
+            return t;
+        }
+        for (int j = 0; j < initializationCount; ++j) {
+            int u = initializations[j];
+            int dim = u & DIM;
+            int kind = u & KIND;
+            if (kind == LOCAL) {
+                u = dim + inputLocals[u & VALUE];
+            } else if (kind == STACK) {
+                u = dim + inputStack[inputStack.length - (u & VALUE)];
+            }
+            if (t == u) {
+                return s;
+            }
+        }
+        return t;
+    }
+
+    /**
+     * Initializes the input frame of the first basic block from the method
+     * descriptor.
+     * 
+     * @param cw
+     *            the ClassWriter to which this label belongs.
+     * @param access
+     *            the access flags of the method to which this label belongs.
+     * @param args
+     *            the formal parameter types of this method.
+     * @param maxLocals
+     *            the maximum number of local variables of this method.
+     */
+    void initInputFrame(final ClassWriter cw, final int access,
+            final Type[] args, final int maxLocals) {
+        inputLocals = new int[maxLocals];
+        inputStack = new int[0];
+        int i = 0;
+        if ((access & Opcodes.ACC_STATIC) == 0) {
+            if ((access & MethodWriter.ACC_CONSTRUCTOR) == 0) {
+                inputLocals[i++] = OBJECT | cw.addType(cw.thisName);
+            } else {
+                inputLocals[i++] = UNINITIALIZED_THIS;
+            }
+        }
+        for (int j = 0; j < args.length; ++j) {
+            int t = type(cw, args[j].getDescriptor());
+            inputLocals[i++] = t;
+            if (t == LONG || t == DOUBLE) {
+                inputLocals[i++] = TOP;
+            }
+        }
+        while (i < maxLocals) {
+            inputLocals[i++] = TOP;
+        }
+    }
+
+    /**
+     * Simulates the action of the given instruction on the output stack frame.
+     * 
+     * @param opcode
+     *            the opcode of the instruction.
+     * @param arg
+     *            the operand of the instruction, if any.
+     * @param cw
+     *            the class writer to which this label belongs.
+     * @param item
+     *            the operand of the instructions, if any.
+     */
+    void execute(final int opcode, final int arg, final ClassWriter cw,
+            final Item item) {
+        int 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(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:
+        case Opcodes.ILOAD:
+            push(INTEGER);
+            break;
+        case Opcodes.LCONST_0:
+        case Opcodes.LCONST_1:
+        case Opcodes.LLOAD:
+            push(LONG);
+            push(TOP);
+            break;
+        case Opcodes.FCONST_0:
+        case Opcodes.FCONST_1:
+        case Opcodes.FCONST_2:
+        case Opcodes.FLOAD:
+            push(FLOAT);
+            break;
+        case Opcodes.DCONST_0:
+        case Opcodes.DCONST_1:
+        case Opcodes.DLOAD:
+            push(DOUBLE);
+            push(TOP);
+            break;
+        case Opcodes.LDC:
+            switch (item.type) {
+            case ClassWriter.INT:
+                push(INTEGER);
+                break;
+            case ClassWriter.LONG:
+                push(LONG);
+                push(TOP);
+                break;
+            case ClassWriter.FLOAT:
+                push(FLOAT);
+                break;
+            case ClassWriter.DOUBLE:
+                push(DOUBLE);
+                push(TOP);
+                break;
+            case ClassWriter.CLASS:
+                push(OBJECT | cw.addType("java/lang/Class"));
+                break;
+            case ClassWriter.STR:
+                push(OBJECT | cw.addType("java/lang/String"));
+                break;
+            case ClassWriter.MTYPE:
+                push(OBJECT | cw.addType("java/lang/invoke/MethodType"));
+                break;
+            // case ClassWriter.HANDLE_BASE + [1..9]:
+            default:
+                push(OBJECT | cw.addType("java/lang/invoke/MethodHandle"));
+            }
+            break;
+        case Opcodes.ALOAD:
+            push(get(arg));
+            break;
+        case Opcodes.IALOAD:
+        case Opcodes.BALOAD:
+        case Opcodes.CALOAD:
+        case Opcodes.SALOAD:
+            pop(2);
+            push(INTEGER);
+            break;
+        case Opcodes.LALOAD:
+        case Opcodes.D2L:
+            pop(2);
+            push(LONG);
+            push(TOP);
+            break;
+        case Opcodes.FALOAD:
+            pop(2);
+            push(FLOAT);
+            break;
+        case Opcodes.DALOAD:
+        case Opcodes.L2D:
+            pop(2);
+            push(DOUBLE);
+            push(TOP);
+            break;
+        case Opcodes.AALOAD:
+            pop(1);
+            t1 = pop();
+            push(ELEMENT_OF + t1);
+            break;
+        case Opcodes.ISTORE:
+        case Opcodes.FSTORE:
+        case Opcodes.ASTORE:
+            t1 = pop();
+            set(arg, t1);
+            if (arg > 0) {
+                t2 = get(arg - 1);
+                // if t2 is of kind STACK or LOCAL we cannot know its size!
+                if (t2 == LONG || t2 == DOUBLE) {
+                    set(arg - 1, TOP);
+                } else if ((t2 & KIND) != BASE) {
+                    set(arg - 1, t2 | TOP_IF_LONG_OR_DOUBLE);
+                }
+            }
+            break;
+        case Opcodes.LSTORE:
+        case Opcodes.DSTORE:
+            pop(1);
+            t1 = pop();
+            set(arg, t1);
+            set(arg + 1, TOP);
+            if (arg > 0) {
+                t2 = get(arg - 1);
+                // if t2 is of kind STACK or LOCAL we cannot know its size!
+                if (t2 == LONG || t2 == DOUBLE) {
+                    set(arg - 1, TOP);
+                } else if ((t2 & KIND) != BASE) {
+                    set(arg - 1, t2 | TOP_IF_LONG_OR_DOUBLE);
+                }
+            }
+            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(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(LONG);
+            push(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(FLOAT);
+            break;
+        case Opcodes.DADD:
+        case Opcodes.DSUB:
+        case Opcodes.DMUL:
+        case Opcodes.DDIV:
+        case Opcodes.DREM:
+            pop(4);
+            push(DOUBLE);
+            push(TOP);
+            break;
+        case Opcodes.LSHL:
+        case Opcodes.LSHR:
+        case Opcodes.LUSHR:
+            pop(3);
+            push(LONG);
+            push(TOP);
+            break;
+        case Opcodes.IINC:
+            set(arg, INTEGER);
+            break;
+        case Opcodes.I2L:
+        case Opcodes.F2L:
+            pop(1);
+            push(LONG);
+            push(TOP);
+            break;
+        case Opcodes.I2F:
+            pop(1);
+            push(FLOAT);
+            break;
+        case Opcodes.I2D:
+        case Opcodes.F2D:
+            pop(1);
+            push(DOUBLE);
+            push(TOP);
+            break;
+        case Opcodes.F2I:
+        case Opcodes.ARRAYLENGTH:
+        case Opcodes.INSTANCEOF:
+            pop(1);
+            push(INTEGER);
+            break;
+        case Opcodes.LCMP:
+        case Opcodes.DCMPL:
+        case Opcodes.DCMPG:
+            pop(4);
+            push(INTEGER);
+            break;
+        case Opcodes.JSR:
+        case Opcodes.RET:
+            throw new RuntimeException(
+                    "JSR/RET are not supported with computeFrames option");
+        case Opcodes.GETSTATIC:
+            push(cw, item.strVal3);
+            break;
+        case Opcodes.PUTSTATIC:
+            pop(item.strVal3);
+            break;
+        case Opcodes.GETFIELD:
+            pop(1);
+            push(cw, item.strVal3);
+            break;
+        case Opcodes.PUTFIELD:
+            pop(item.strVal3);
+            pop();
+            break;
+        case Opcodes.INVOKEVIRTUAL:
+        case Opcodes.INVOKESPECIAL:
+        case Opcodes.INVOKESTATIC:
+        case Opcodes.INVOKEINTERFACE:
+            pop(item.strVal3);
+            if (opcode != Opcodes.INVOKESTATIC) {
+                t1 = pop();
+                if (opcode == Opcodes.INVOKESPECIAL
+                        && item.strVal2.charAt(0) == '<') {
+                    init(t1);
+                }
+            }
+            push(cw, item.strVal3);
+            break;
+        case Opcodes.INVOKEDYNAMIC:
+            pop(item.strVal2);
+            push(cw, item.strVal2);
+            break;
+        case Opcodes.NEW:
+            push(UNINITIALIZED | cw.addUninitializedType(item.strVal1, arg));
+            break;
+        case Opcodes.NEWARRAY:
+            pop();
+            switch (arg) {
+            case Opcodes.T_BOOLEAN:
+                push(ARRAY_OF | BOOLEAN);
+                break;
+            case Opcodes.T_CHAR:
+                push(ARRAY_OF | CHAR);
+                break;
+            case Opcodes.T_BYTE:
+                push(ARRAY_OF | BYTE);
+                break;
+            case Opcodes.T_SHORT:
+                push(ARRAY_OF | SHORT);
+                break;
+            case Opcodes.T_INT:
+                push(ARRAY_OF | INTEGER);
+                break;
+            case Opcodes.T_FLOAT:
+                push(ARRAY_OF | FLOAT);
+                break;
+            case Opcodes.T_DOUBLE:
+                push(ARRAY_OF | DOUBLE);
+                break;
+            // case Opcodes.T_LONG:
+            default:
+                push(ARRAY_OF | LONG);
+                break;
+            }
+            break;
+        case Opcodes.ANEWARRAY:
+            String s = item.strVal1;
+            pop();
+            if (s.charAt(0) == '[') {
+                push(cw, '[' + s);
+            } else {
+                push(ARRAY_OF | OBJECT | cw.addType(s));
+            }
+            break;
+        case Opcodes.CHECKCAST:
+            s = item.strVal1;
+            pop();
+            if (s.charAt(0) == '[') {
+                push(cw, s);
+            } else {
+                push(OBJECT | cw.addType(s));
+            }
+            break;
+        // case Opcodes.MULTIANEWARRAY:
+        default:
+            pop(arg);
+            push(cw, item.strVal1);
+            break;
+        }
+    }
+
+    /**
+     * Merges the input frame of the given basic block with the input and output
+     * frames of this basic block. Returns <tt>true</tt> if the input frame of
+     * the given label has been changed by this operation.
+     * 
+     * @param cw
+     *            the ClassWriter to which this label belongs.
+     * @param frame
+     *            the basic block whose input frame must be updated.
+     * @param edge
+     *            the kind of the {@link Edge} between this label and 'label'.
+     *            See {@link Edge#info}.
+     * @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) {
+        boolean changed = false;
+        int i, s, dim, kind, t;
+
+        int nLocal = inputLocals.length;
+        int nStack = inputStack.length;
+        if (frame.inputLocals == null) {
+            frame.inputLocals = new int[nLocal];
+            changed = true;
+        }
+
+        for (i = 0; i < nLocal; ++i) {
+            if (outputLocals != null && i < outputLocals.length) {
+                s = outputLocals[i];
+                if (s == 0) {
+                    t = inputLocals[i];
+                } else {
+                    dim = s & DIM;
+                    kind = s & KIND;
+                    if (kind == BASE) {
+                        t = s;
+                    } else {
+                        if (kind == LOCAL) {
+                            t = dim + inputLocals[s & VALUE];
+                        } else {
+                            t = dim + inputStack[nStack - (s & VALUE)];
+                        }
+                        if ((s & TOP_IF_LONG_OR_DOUBLE) != 0
+                                && (t == LONG || t == DOUBLE)) {
+                            t = TOP;
+                        }
+                    }
+                }
+            } else {
+                t = inputLocals[i];
+            }
+            if (initializations != null) {
+                t = init(cw, t);
+            }
+            changed |= merge(cw, t, frame.inputLocals, i);
+        }
+
+        if (edge > 0) {
+            for (i = 0; i < nLocal; ++i) {
+                t = inputLocals[i];
+                changed |= merge(cw, t, frame.inputLocals, i);
+            }
+            if (frame.inputStack == null) {
+                frame.inputStack = new int[1];
+                changed = true;
+            }
+            changed |= merge(cw, edge, frame.inputStack, 0);
+            return changed;
+        }
+
+        int nInputStack = inputStack.length + owner.inputStackTop;
+        if (frame.inputStack == null) {
+            frame.inputStack = new int[nInputStack + outputStackTop];
+            changed = true;
+        }
+
+        for (i = 0; i < nInputStack; ++i) {
+            t = inputStack[i];
+            if (initializations != null) {
+                t = init(cw, t);
+            }
+            changed |= merge(cw, t, frame.inputStack, i);
+        }
+        for (i = 0; i < outputStackTop; ++i) {
+            s = outputStack[i];
+            dim = s & DIM;
+            kind = s & KIND;
+            if (kind == BASE) {
+                t = s;
+            } else {
+                if (kind == LOCAL) {
+                    t = dim + inputLocals[s & VALUE];
+                } else {
+                    t = dim + inputStack[nStack - (s & VALUE)];
+                }
+                if ((s & TOP_IF_LONG_OR_DOUBLE) != 0
+                        && (t == LONG || t == DOUBLE)) {
+                    t = TOP;
+                }
+            }
+            if (initializations != null) {
+                t = init(cw, t);
+            }
+            changed |= merge(cw, t, frame.inputStack, nInputStack + i);
+        }
+        return changed;
+    }
+
+    /**
+     * Merges the type at the given index in the given type array with the given
+     * type. Returns <tt>true</tt> if the type array has been modified by this
+     * operation.
+     * 
+     * @param cw
+     *            the ClassWriter to which this label belongs.
+     * @param t
+     *            the type with which the type array element must be merged.
+     * @param types
+     *            an array of types.
+     * @param index
+     *            the index of the type that must be merged in 'types'.
+     * @return <tt>true</tt> if the type array has been modified by this
+     *         operation.
+     */
+    private static boolean merge(final ClassWriter cw, int t,
+            final int[] types, final int index) {
+        int u = types[index];
+        if (u == t) {
+            // if the types are equal, merge(u,t)=u, so there is no change
+            return false;
+        }
+        if ((t & ~DIM) == NULL) {
+            if (u == NULL) {
+                return false;
+            }
+            t = NULL;
+        }
+        if (u == 0) {
+            // if types[index] has never been assigned, merge(u,t)=t
+            types[index] = t;
+            return true;
+        }
+        int v;
+        if ((u & BASE_KIND) == OBJECT || (u & DIM) != 0) {
+            // if u is a reference type of any dimension
+            if (t == NULL) {
+                // if t is the NULL type, merge(u,t)=u, so there is no change
+                return false;
+            } else if ((t & (DIM | BASE_KIND)) == (u & (DIM | BASE_KIND))) {
+                if ((u & BASE_KIND) == OBJECT) {
+                    // if t is also a reference type, and if u and t have the
+                    // same dimension merge(u,t) = dim(t) | common parent of the
+                    // element types of u and t
+                    v = (t & DIM) | OBJECT
+                            | cw.getMergedType(t & BASE_VALUE, u & BASE_VALUE);
+                } else {
+                    // if u and t are array types, but not with the same element
+                    // type, merge(u,t)=java/lang/Object
+                    v = OBJECT | cw.addType("java/lang/Object");
+                }
+            } else if ((t & BASE_KIND) == OBJECT || (t & DIM) != 0) {
+                // if t is any other reference or array type,
+                // merge(u,t)=java/lang/Object
+                v = OBJECT | cw.addType("java/lang/Object");
+            } else {
+                // if t is any other type, merge(u,t)=TOP
+                v = TOP;
+            }
+        } else if (u == NULL) {
+            // if u is the NULL type, merge(u,t)=t,
+            // or TOP if t is not a reference type
+            v = (t & BASE_KIND) == OBJECT || (t & DIM) != 0 ? t : TOP;
+        } else {
+            // if u is any other type, merge(u,t)=TOP whatever t
+            v = TOP;
+        }
+        if (u != v) {
+            types[index] = v;
+            return true;
+        }
+        return false;
+    }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/Handle.java
----------------------------------------------------------------------
diff --git a/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/Handle.java b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/Handle.java
new file mode 100644
index 0000000..0a91c3a
--- /dev/null
+++ b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/Handle.java
@@ -0,0 +1,170 @@
+/***
+ * 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.tajo.org.objectweb.asm;
+
+/**
+ * A reference to a field or a method.
+ * 
+ * @author Remi Forax
+ * @author Eric Bruneton
+ */
+public final class Handle {
+
+    /**
+     * The kind of field or method designated by this Handle. Should 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}.
+     */
+    final int tag;
+
+    /**
+     * The internal name of the class that owns the field or method designated
+     * by this handle.
+     */
+    final String owner;
+
+    /**
+     * The name of the field or method designated by this handle.
+     */
+    final String name;
+
+    /**
+     * The descriptor of the field or method designated by this handle.
+     */
+    final String desc;
+
+    /**
+     * 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.
+     */
+    public Handle(int tag, String owner, String name, String desc) {
+        this.tag = tag;
+        this.owner = owner;
+        this.name = name;
+        this.desc = desc;
+    }
+
+    /**
+     * Returns the kind of field or method designated by this handle.
+     * 
+     * @return {@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}.
+     */
+    public int getTag() {
+        return tag;
+    }
+
+    /**
+     * Returns the internal name of the class that owns the field or method
+     * designated by this handle.
+     * 
+     * @return the internal name of the class that owns the field or method
+     *         designated by this handle.
+     */
+    public String getOwner() {
+        return owner;
+    }
+
+    /**
+     * Returns the name of the field or method designated by this handle.
+     * 
+     * @return the name of the field or method designated by this handle.
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Returns the descriptor of the field or method designated by this handle.
+     * 
+     * @return the descriptor of the field or method designated by this handle.
+     */
+    public String getDesc() {
+        return desc;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (!(obj instanceof Handle)) {
+            return false;
+        }
+        Handle h = (Handle) obj;
+        return tag == h.tag && owner.equals(h.owner) && name.equals(h.name)
+                && desc.equals(h.desc);
+    }
+
+    @Override
+    public int hashCode() {
+        return tag + owner.hashCode() * name.hashCode() * desc.hashCode();
+    }
+
+    /**
+     * Returns the textual representation of this handle. The textual
+     * representation is:
+     * 
+     * <pre>
+     * owner '.' name desc ' ' '(' tag ')'
+     * </pre>
+     * 
+     * . As this format is unambiguous, it can be parsed if necessary.
+     */
+    @Override
+    public String toString() {
+        return owner + '.' + name + desc + " (" + tag + ')';
+    }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/Handler.java
----------------------------------------------------------------------
diff --git a/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/Handler.java b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/Handler.java
new file mode 100644
index 0000000..da2af36
--- /dev/null
+++ b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/Handler.java
@@ -0,0 +1,121 @@
+/***
+ * 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.tajo.org.objectweb.asm;
+
+/**
+ * Information about an exception handler block.
+ * 
+ * @author Eric Bruneton
+ */
+class Handler {
+
+    /**
+     * Beginning of the exception handler's scope (inclusive).
+     */
+    Label start;
+
+    /**
+     * End of the exception handler's scope (exclusive).
+     */
+    Label end;
+
+    /**
+     * Beginning of the exception handler's code.
+     */
+    Label handler;
+
+    /**
+     * Internal name of the type of exceptions handled by this handler, or
+     * <tt>null</tt> to catch any exceptions.
+     */
+    String desc;
+
+    /**
+     * Constant pool index of the internal name of the type of exceptions
+     * handled by this handler, or 0 to catch any exceptions.
+     */
+    int type;
+
+    /**
+     * Next exception handler block info.
+     */
+    Handler next;
+
+    /**
+     * Removes the range between start and end from the given exception
+     * handlers.
+     * 
+     * @param h
+     *            an exception handler list.
+     * @param start
+     *            the start of the range to be removed.
+     * @param end
+     *            the end of the range to be removed. Maybe null.
+     * @return the exception handler list with the start-end range removed.
+     */
+    static Handler remove(Handler h, Label start, Label end) {
+        if (h == null) {
+            return null;
+        } else {
+            h.next = remove(h.next, start, end);
+        }
+        int hstart = h.start.position;
+        int hend = h.end.position;
+        int s = start.position;
+        int e = end == null ? Integer.MAX_VALUE : end.position;
+        // if [hstart,hend[ and [s,e[ intervals intersect...
+        if (s < hend && e > hstart) {
+            if (s <= hstart) {
+                if (e >= hend) {
+                    // [hstart,hend[ fully included in [s,e[, h removed
+                    h = h.next;
+                } else {
+                    // [hstart,hend[ minus [s,e[ = [e,hend[
+                    h.start = end;
+                }
+            } else if (e >= hend) {
+                // [hstart,hend[ minus [s,e[ = [hstart,s[
+                h.end = start;
+            } else {
+                // [hstart,hend[ minus [s,e[ = [hstart,s[ + [e,hend[
+                Handler g = new Handler();
+                g.start = end;
+                g.end = h.end;
+                g.handler = h.handler;
+                g.desc = h.desc;
+                g.type = h.type;
+                g.next = h.next;
+                h.end = start;
+                h.next = g;
+            }
+        }
+        return h;
+    }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/Item.java
----------------------------------------------------------------------
diff --git a/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/Item.java b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/Item.java
new file mode 100644
index 0000000..58a24d3
--- /dev/null
+++ b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/Item.java
@@ -0,0 +1,311 @@
+/***
+ * 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.tajo.org.objectweb.asm;
+
+/**
+ * A constant pool item. Constant pool items can be created with the 'newXXX'
+ * methods in the {@link ClassWriter} class.
+ * 
+ * @author Eric Bruneton
+ */
+final class Item {
+
+    /**
+     * Index of this item in the constant pool.
+     */
+    int index;
+
+    /**
+     * Type of this constant pool item. A single class is used to represent all
+     * constant pool item types, in order to minimize the bytecode size of this
+     * package. The value of this field is one of {@link ClassWriter#INT},
+     * {@link ClassWriter#LONG}, {@link ClassWriter#FLOAT},
+     * {@link ClassWriter#DOUBLE}, {@link ClassWriter#UTF8},
+     * {@link ClassWriter#STR}, {@link ClassWriter#CLASS},
+     * {@link ClassWriter#NAME_TYPE}, {@link ClassWriter#FIELD},
+     * {@link ClassWriter#METH}, {@link ClassWriter#IMETH},
+     * {@link ClassWriter#MTYPE}, {@link ClassWriter#INDY}.
+     * 
+     * MethodHandle constant 9 variations are stored using a range of 9 values
+     * from {@link ClassWriter#HANDLE_BASE} + 1 to
+     * {@link ClassWriter#HANDLE_BASE} + 9.
+     * 
+     * Special Item types are used for Items that are stored in the ClassWriter
+     * {@link ClassWriter#typeTable}, instead of the constant pool, in order to
+     * avoid clashes with normal constant pool items in the ClassWriter constant
+     * pool's hash table. These special item types are
+     * {@link ClassWriter#TYPE_NORMAL}, {@link ClassWriter#TYPE_UNINIT} and
+     * {@link ClassWriter#TYPE_MERGED}.
+     */
+    int type;
+
+    /**
+     * Value of this item, for an integer item.
+     */
+    int intVal;
+
+    /**
+     * Value of this item, for a long item.
+     */
+    long longVal;
+
+    /**
+     * First part of the value of this item, for items that do not hold a
+     * primitive value.
+     */
+    String strVal1;
+
+    /**
+     * Second part of the value of this item, for items that do not hold a
+     * primitive value.
+     */
+    String strVal2;
+
+    /**
+     * Third part of the value of this item, for items that do not hold a
+     * primitive value.
+     */
+    String strVal3;
+
+    /**
+     * The hash code value of this constant pool item.
+     */
+    int hashCode;
+
+    /**
+     * Link to another constant pool item, used for collision lists in the
+     * constant pool's hash table.
+     */
+    Item next;
+
+    /**
+     * Constructs an uninitialized {@link Item}.
+     */
+    Item() {
+    }
+
+    /**
+     * Constructs an uninitialized {@link Item} for constant pool element at
+     * given position.
+     * 
+     * @param index
+     *            index of the item to be constructed.
+     */
+    Item(final int index) {
+        this.index = index;
+    }
+
+    /**
+     * Constructs a copy of the given item.
+     * 
+     * @param index
+     *            index of the item to be constructed.
+     * @param i
+     *            the item that must be copied into the item to be constructed.
+     */
+    Item(final int index, final Item i) {
+        this.index = index;
+        type = i.type;
+        intVal = i.intVal;
+        longVal = i.longVal;
+        strVal1 = i.strVal1;
+        strVal2 = i.strVal2;
+        strVal3 = i.strVal3;
+        hashCode = i.hashCode;
+    }
+
+    /**
+     * Sets this item to an integer item.
+     * 
+     * @param intVal
+     *            the value of this item.
+     */
+    void set(final int intVal) {
+        this.type = ClassWriter.INT;
+        this.intVal = intVal;
+        this.hashCode = 0x7FFFFFFF & (type + intVal);
+    }
+
+    /**
+     * Sets this item to a long item.
+     * 
+     * @param longVal
+     *            the value of this item.
+     */
+    void set(final long longVal) {
+        this.type = ClassWriter.LONG;
+        this.longVal = longVal;
+        this.hashCode = 0x7FFFFFFF & (type + (int) longVal);
+    }
+
+    /**
+     * Sets this item to a float item.
+     * 
+     * @param floatVal
+     *            the value of this item.
+     */
+    void set(final float floatVal) {
+        this.type = ClassWriter.FLOAT;
+        this.intVal = Float.floatToRawIntBits(floatVal);
+        this.hashCode = 0x7FFFFFFF & (type + (int) floatVal);
+    }
+
+    /**
+     * Sets this item to a double item.
+     * 
+     * @param doubleVal
+     *            the value of this item.
+     */
+    void set(final double doubleVal) {
+        this.type = ClassWriter.DOUBLE;
+        this.longVal = Double.doubleToRawLongBits(doubleVal);
+        this.hashCode = 0x7FFFFFFF & (type + (int) doubleVal);
+    }
+
+    /**
+     * Sets this item to an item that do not hold a primitive value.
+     * 
+     * @param type
+     *            the type of this item.
+     * @param strVal1
+     *            first part of the value of this item.
+     * @param strVal2
+     *            second part of the value of this item.
+     * @param strVal3
+     *            third part of the value of this item.
+     */
+    void set(final int type, final String strVal1, final String strVal2,
+            final String strVal3) {
+        this.type = type;
+        this.strVal1 = strVal1;
+        this.strVal2 = strVal2;
+        this.strVal3 = strVal3;
+        switch (type) {
+        case ClassWriter.UTF8:
+        case ClassWriter.STR:
+        case ClassWriter.CLASS:
+        case ClassWriter.MTYPE:
+        case ClassWriter.TYPE_NORMAL:
+            hashCode = 0x7FFFFFFF & (type + strVal1.hashCode());
+            return;
+        case ClassWriter.NAME_TYPE: {
+            hashCode = 0x7FFFFFFF & (type + strVal1.hashCode()
+                    * strVal2.hashCode());
+            return;
+        }
+        // ClassWriter.FIELD:
+        // ClassWriter.METH:
+        // ClassWriter.IMETH:
+        // ClassWriter.HANDLE_BASE + 1..9
+        default:
+            hashCode = 0x7FFFFFFF & (type + strVal1.hashCode()
+                    * strVal2.hashCode() * strVal3.hashCode());
+        }
+    }
+
+    /**
+     * Sets the item to an InvokeDynamic item.
+     * 
+     * @param name
+     *            invokedynamic's name.
+     * @param desc
+     *            invokedynamic's desc.
+     * @param bsmIndex
+     *            zero based index into the class attribute BootrapMethods.
+     */
+    void set(String name, String desc, int bsmIndex) {
+        this.type = ClassWriter.INDY;
+        this.longVal = bsmIndex;
+        this.strVal1 = name;
+        this.strVal2 = desc;
+        this.hashCode = 0x7FFFFFFF & (ClassWriter.INDY + bsmIndex
+                * strVal1.hashCode() * strVal2.hashCode());
+    }
+
+    /**
+     * Sets the item to a BootstrapMethod item.
+     * 
+     * @param position
+     *            position in byte in the class attribute BootrapMethods.
+     * @param hashCode
+     *            hashcode of the item. This hashcode is processed from the
+     *            hashcode of the bootstrap method and the hashcode of all
+     *            bootstrap arguments.
+     */
+    void set(int position, int hashCode) {
+        this.type = ClassWriter.BSM;
+        this.intVal = position;
+        this.hashCode = hashCode;
+    }
+
+    /**
+     * Indicates if the given item is equal to this one. <i>This method assumes
+     * that the two items have the same {@link #type}</i>.
+     * 
+     * @param i
+     *            the item to be compared to this one. Both items must have the
+     *            same {@link #type}.
+     * @return <tt>true</tt> if the given item if equal to this one,
+     *         <tt>false</tt> otherwise.
+     */
+    boolean isEqualTo(final Item i) {
+        switch (type) {
+        case ClassWriter.UTF8:
+        case ClassWriter.STR:
+        case ClassWriter.CLASS:
+        case ClassWriter.MTYPE:
+        case ClassWriter.TYPE_NORMAL:
+            return i.strVal1.equals(strVal1);
+        case ClassWriter.TYPE_MERGED:
+        case ClassWriter.LONG:
+        case ClassWriter.DOUBLE:
+            return i.longVal == longVal;
+        case ClassWriter.INT:
+        case ClassWriter.FLOAT:
+            return i.intVal == intVal;
+        case ClassWriter.TYPE_UNINIT:
+            return i.intVal == intVal && i.strVal1.equals(strVal1);
+        case ClassWriter.NAME_TYPE:
+            return i.strVal1.equals(strVal1) && i.strVal2.equals(strVal2);
+        case ClassWriter.INDY: {
+            return i.longVal == longVal && i.strVal1.equals(strVal1)
+                    && i.strVal2.equals(strVal2);
+        }
+        // case ClassWriter.FIELD:
+        // case ClassWriter.METH:
+        // case ClassWriter.IMETH:
+        // case ClassWriter.HANDLE_BASE + 1..9
+        default:
+            return i.strVal1.equals(strVal1) && i.strVal2.equals(strVal2)
+                    && i.strVal3.equals(strVal3);
+        }
+    }
+
+}


Mime
View raw message