You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tajo.apache.org by hy...@apache.org on 2014/08/23 19:37:55 UTC

[06/25] TAJO-906: Runtime code generation for evaluating expression trees.

http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/tree/analysis/Frame.java
----------------------------------------------------------------------
diff --git a/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/tree/analysis/Frame.java b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/tree/analysis/Frame.java
new file mode 100644
index 0000000..c7ff4fb
--- /dev/null
+++ b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/tree/analysis/Frame.java
@@ -0,0 +1,729 @@
+/***
+ * 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.tree.analysis;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.tajo.org.objectweb.asm.Type;
+import org.apache.tajo.org.objectweb.asm.tree.MultiANewArrayInsnNode;
+import org.apache.tajo.org.objectweb.asm.Opcodes;
+import org.apache.tajo.org.objectweb.asm.tree.AbstractInsnNode;
+import org.apache.tajo.org.objectweb.asm.tree.IincInsnNode;
+import org.apache.tajo.org.objectweb.asm.tree.InvokeDynamicInsnNode;
+import org.apache.tajo.org.objectweb.asm.tree.MethodInsnNode;
+import org.apache.tajo.org.objectweb.asm.tree.VarInsnNode;
+
+/**
+ * A symbolic execution stack frame. A stack frame contains a set of local
+ * variable slots, and an operand stack. Warning: long and double values are
+ * represented by <i>two</i> slots in local variables, and by <i>one</i> slot in
+ * the operand stack.
+ * 
+ * @param <V>
+ *            type of the Value used for the analysis.
+ * 
+ * @author Eric Bruneton
+ */
+public class Frame<V extends Value> {
+
+    /**
+     * The expected return type of the analyzed method, or <tt>null</tt> if the
+     * method returns void.
+     */
+    private V returnValue;
+
+    /**
+     * The local variables and operand stack of this frame.
+     */
+    private V[] values;
+
+    /**
+     * The number of local variables of this frame.
+     */
+    private int locals;
+
+    /**
+     * The number of elements in the operand stack.
+     */
+    private int top;
+
+    /**
+     * Constructs a new frame with the given size.
+     * 
+     * @param nLocals
+     *            the maximum number of local variables of the frame.
+     * @param nStack
+     *            the maximum stack size of the frame.
+     */
+    public Frame(final int nLocals, final int nStack) {
+        this.values = (V[]) new Value[nLocals + nStack];
+        this.locals = nLocals;
+    }
+
+    /**
+     * Constructs a new frame that is identical to the given frame.
+     * 
+     * @param src
+     *            a frame.
+     */
+    public Frame(final Frame<? extends V> src) {
+        this(src.locals, src.values.length - src.locals);
+        init(src);
+    }
+
+    /**
+     * Copies the state of the given frame into this frame.
+     * 
+     * @param src
+     *            a frame.
+     * @return this frame.
+     */
+    public Frame<V> init(final Frame<? extends V> src) {
+        returnValue = src.returnValue;
+        System.arraycopy(src.values, 0, values, 0, values.length);
+        top = src.top;
+        return this;
+    }
+
+    /**
+     * Sets the expected return type of the analyzed method.
+     * 
+     * @param v
+     *            the expected return type of the analyzed method, or
+     *            <tt>null</tt> if the method returns void.
+     */
+    public void setReturn(final V v) {
+        returnValue = v;
+    }
+
+    /**
+     * Returns the maximum number of local variables of this frame.
+     * 
+     * @return the maximum number of local variables of this frame.
+     */
+    public int getLocals() {
+        return locals;
+    }
+
+    /**
+     * Returns the value of the given local variable.
+     * 
+     * @param i
+     *            a local variable index.
+     * @return the value of the given local variable.
+     * @throws IndexOutOfBoundsException
+     *             if the variable does not exist.
+     */
+    public V getLocal(final int i) throws IndexOutOfBoundsException {
+        if (i >= locals) {
+            throw new IndexOutOfBoundsException(
+                    "Trying to access an inexistant local variable");
+        }
+        return values[i];
+    }
+
+    /**
+     * Sets the value of the given local variable.
+     * 
+     * @param i
+     *            a local variable index.
+     * @param value
+     *            the new value of this local variable.
+     * @throws IndexOutOfBoundsException
+     *             if the variable does not exist.
+     */
+    public void setLocal(final int i, final V value)
+            throws IndexOutOfBoundsException {
+        if (i >= locals) {
+            throw new IndexOutOfBoundsException(
+                    "Trying to access an inexistant local variable " + i);
+        }
+        values[i] = value;
+    }
+
+    /**
+     * Returns the number of values in the operand stack of this frame. Long and
+     * double values are treated as single values.
+     * 
+     * @return the number of values in the operand stack of this frame.
+     */
+    public int getStackSize() {
+        return top;
+    }
+
+    /**
+     * Returns the value of the given operand stack slot.
+     * 
+     * @param i
+     *            the index of an operand stack slot.
+     * @return the value of the given operand stack slot.
+     * @throws IndexOutOfBoundsException
+     *             if the operand stack slot does not exist.
+     */
+    public V getStack(final int i) throws IndexOutOfBoundsException {
+        return values[i + locals];
+    }
+
+    /**
+     * Clears the operand stack of this frame.
+     */
+    public void clearStack() {
+        top = 0;
+    }
+
+    /**
+     * Pops a value from the operand stack of this frame.
+     * 
+     * @return the value that has been popped from the stack.
+     * @throws IndexOutOfBoundsException
+     *             if the operand stack is empty.
+     */
+    public V pop() throws IndexOutOfBoundsException {
+        if (top == 0) {
+            throw new IndexOutOfBoundsException(
+                    "Cannot pop operand off an empty stack.");
+        }
+        return values[--top + locals];
+    }
+
+    /**
+     * Pushes a value into the operand stack of this frame.
+     * 
+     * @param value
+     *            the value that must be pushed into the stack.
+     * @throws IndexOutOfBoundsException
+     *             if the operand stack is full.
+     */
+    public void push(final V value) throws IndexOutOfBoundsException {
+        if (top + locals >= values.length) {
+            throw new IndexOutOfBoundsException(
+                    "Insufficient maximum stack size.");
+        }
+        values[top++ + locals] = value;
+    }
+
+    public void execute(final AbstractInsnNode insn,
+            final Interpreter<V> interpreter) throws AnalyzerException {
+        V value1, value2, value3, value4;
+        List<V> values;
+        int var;
+
+        switch (insn.getOpcode()) {
+        case Opcodes.NOP:
+            break;
+        case Opcodes.ACONST_NULL:
+        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.LCONST_0:
+        case Opcodes.LCONST_1:
+        case Opcodes.FCONST_0:
+        case Opcodes.FCONST_1:
+        case Opcodes.FCONST_2:
+        case Opcodes.DCONST_0:
+        case Opcodes.DCONST_1:
+        case Opcodes.BIPUSH:
+        case Opcodes.SIPUSH:
+        case Opcodes.LDC:
+            push(interpreter.newOperation(insn));
+            break;
+        case Opcodes.ILOAD:
+        case Opcodes.LLOAD:
+        case Opcodes.FLOAD:
+        case Opcodes.DLOAD:
+        case Opcodes.ALOAD:
+            push(interpreter.copyOperation(insn,
+                    getLocal(((VarInsnNode) insn).var)));
+            break;
+        case Opcodes.IALOAD:
+        case Opcodes.LALOAD:
+        case Opcodes.FALOAD:
+        case Opcodes.DALOAD:
+        case Opcodes.AALOAD:
+        case Opcodes.BALOAD:
+        case Opcodes.CALOAD:
+        case Opcodes.SALOAD:
+            value2 = pop();
+            value1 = pop();
+            push(interpreter.binaryOperation(insn, value1, value2));
+            break;
+        case Opcodes.ISTORE:
+        case Opcodes.LSTORE:
+        case Opcodes.FSTORE:
+        case Opcodes.DSTORE:
+        case Opcodes.ASTORE:
+            value1 = interpreter.copyOperation(insn, pop());
+            var = ((VarInsnNode) insn).var;
+            setLocal(var, value1);
+            if (value1.getSize() == 2) {
+                setLocal(var + 1, interpreter.newValue(null));
+            }
+            if (var > 0) {
+                Value local = getLocal(var - 1);
+                if (local != null && local.getSize() == 2) {
+                    setLocal(var - 1, interpreter.newValue(null));
+                }
+            }
+            break;
+        case Opcodes.IASTORE:
+        case Opcodes.LASTORE:
+        case Opcodes.FASTORE:
+        case Opcodes.DASTORE:
+        case Opcodes.AASTORE:
+        case Opcodes.BASTORE:
+        case Opcodes.CASTORE:
+        case Opcodes.SASTORE:
+            value3 = pop();
+            value2 = pop();
+            value1 = pop();
+            interpreter.ternaryOperation(insn, value1, value2, value3);
+            break;
+        case Opcodes.POP:
+            if (pop().getSize() == 2) {
+                throw new AnalyzerException(insn, "Illegal use of POP");
+            }
+            break;
+        case Opcodes.POP2:
+            if (pop().getSize() == 1) {
+                if (pop().getSize() != 1) {
+                    throw new AnalyzerException(insn, "Illegal use of POP2");
+                }
+            }
+            break;
+        case Opcodes.DUP:
+            value1 = pop();
+            if (value1.getSize() != 1) {
+                throw new AnalyzerException(insn, "Illegal use of DUP");
+            }
+            push(value1);
+            push(interpreter.copyOperation(insn, value1));
+            break;
+        case Opcodes.DUP_X1:
+            value1 = pop();
+            value2 = pop();
+            if (value1.getSize() != 1 || value2.getSize() != 1) {
+                throw new AnalyzerException(insn, "Illegal use of DUP_X1");
+            }
+            push(interpreter.copyOperation(insn, value1));
+            push(value2);
+            push(value1);
+            break;
+        case Opcodes.DUP_X2:
+            value1 = pop();
+            if (value1.getSize() == 1) {
+                value2 = pop();
+                if (value2.getSize() == 1) {
+                    value3 = pop();
+                    if (value3.getSize() == 1) {
+                        push(interpreter.copyOperation(insn, value1));
+                        push(value3);
+                        push(value2);
+                        push(value1);
+                        break;
+                    }
+                } else {
+                    push(interpreter.copyOperation(insn, value1));
+                    push(value2);
+                    push(value1);
+                    break;
+                }
+            }
+            throw new AnalyzerException(insn, "Illegal use of DUP_X2");
+        case Opcodes.DUP2:
+            value1 = pop();
+            if (value1.getSize() == 1) {
+                value2 = pop();
+                if (value2.getSize() == 1) {
+                    push(value2);
+                    push(value1);
+                    push(interpreter.copyOperation(insn, value2));
+                    push(interpreter.copyOperation(insn, value1));
+                    break;
+                }
+            } else {
+                push(value1);
+                push(interpreter.copyOperation(insn, value1));
+                break;
+            }
+            throw new AnalyzerException(insn, "Illegal use of DUP2");
+        case Opcodes.DUP2_X1:
+            value1 = pop();
+            if (value1.getSize() == 1) {
+                value2 = pop();
+                if (value2.getSize() == 1) {
+                    value3 = pop();
+                    if (value3.getSize() == 1) {
+                        push(interpreter.copyOperation(insn, value2));
+                        push(interpreter.copyOperation(insn, value1));
+                        push(value3);
+                        push(value2);
+                        push(value1);
+                        break;
+                    }
+                }
+            } else {
+                value2 = pop();
+                if (value2.getSize() == 1) {
+                    push(interpreter.copyOperation(insn, value1));
+                    push(value2);
+                    push(value1);
+                    break;
+                }
+            }
+            throw new AnalyzerException(insn, "Illegal use of DUP2_X1");
+        case Opcodes.DUP2_X2:
+            value1 = pop();
+            if (value1.getSize() == 1) {
+                value2 = pop();
+                if (value2.getSize() == 1) {
+                    value3 = pop();
+                    if (value3.getSize() == 1) {
+                        value4 = pop();
+                        if (value4.getSize() == 1) {
+                            push(interpreter.copyOperation(insn, value2));
+                            push(interpreter.copyOperation(insn, value1));
+                            push(value4);
+                            push(value3);
+                            push(value2);
+                            push(value1);
+                            break;
+                        }
+                    } else {
+                        push(interpreter.copyOperation(insn, value2));
+                        push(interpreter.copyOperation(insn, value1));
+                        push(value3);
+                        push(value2);
+                        push(value1);
+                        break;
+                    }
+                }
+            } else {
+                value2 = pop();
+                if (value2.getSize() == 1) {
+                    value3 = pop();
+                    if (value3.getSize() == 1) {
+                        push(interpreter.copyOperation(insn, value1));
+                        push(value3);
+                        push(value2);
+                        push(value1);
+                        break;
+                    }
+                } else {
+                    push(interpreter.copyOperation(insn, value1));
+                    push(value2);
+                    push(value1);
+                    break;
+                }
+            }
+            throw new AnalyzerException(insn, "Illegal use of DUP2_X2");
+        case Opcodes.SWAP:
+            value2 = pop();
+            value1 = pop();
+            if (value1.getSize() != 1 || value2.getSize() != 1) {
+                throw new AnalyzerException(insn, "Illegal use of SWAP");
+            }
+            push(interpreter.copyOperation(insn, value2));
+            push(interpreter.copyOperation(insn, value1));
+            break;
+        case Opcodes.IADD:
+        case Opcodes.LADD:
+        case Opcodes.FADD:
+        case Opcodes.DADD:
+        case Opcodes.ISUB:
+        case Opcodes.LSUB:
+        case Opcodes.FSUB:
+        case Opcodes.DSUB:
+        case Opcodes.IMUL:
+        case Opcodes.LMUL:
+        case Opcodes.FMUL:
+        case Opcodes.DMUL:
+        case Opcodes.IDIV:
+        case Opcodes.LDIV:
+        case Opcodes.FDIV:
+        case Opcodes.DDIV:
+        case Opcodes.IREM:
+        case Opcodes.LREM:
+        case Opcodes.FREM:
+        case Opcodes.DREM:
+            value2 = pop();
+            value1 = pop();
+            push(interpreter.binaryOperation(insn, value1, value2));
+            break;
+        case Opcodes.INEG:
+        case Opcodes.LNEG:
+        case Opcodes.FNEG:
+        case Opcodes.DNEG:
+            push(interpreter.unaryOperation(insn, pop()));
+            break;
+        case Opcodes.ISHL:
+        case Opcodes.LSHL:
+        case Opcodes.ISHR:
+        case Opcodes.LSHR:
+        case Opcodes.IUSHR:
+        case Opcodes.LUSHR:
+        case Opcodes.IAND:
+        case Opcodes.LAND:
+        case Opcodes.IOR:
+        case Opcodes.LOR:
+        case Opcodes.IXOR:
+        case Opcodes.LXOR:
+            value2 = pop();
+            value1 = pop();
+            push(interpreter.binaryOperation(insn, value1, value2));
+            break;
+        case Opcodes.IINC:
+            var = ((IincInsnNode) insn).var;
+            setLocal(var, interpreter.unaryOperation(insn, getLocal(var)));
+            break;
+        case Opcodes.I2L:
+        case Opcodes.I2F:
+        case Opcodes.I2D:
+        case Opcodes.L2I:
+        case Opcodes.L2F:
+        case Opcodes.L2D:
+        case Opcodes.F2I:
+        case Opcodes.F2L:
+        case Opcodes.F2D:
+        case Opcodes.D2I:
+        case Opcodes.D2L:
+        case Opcodes.D2F:
+        case Opcodes.I2B:
+        case Opcodes.I2C:
+        case Opcodes.I2S:
+            push(interpreter.unaryOperation(insn, pop()));
+            break;
+        case Opcodes.LCMP:
+        case Opcodes.FCMPL:
+        case Opcodes.FCMPG:
+        case Opcodes.DCMPL:
+        case Opcodes.DCMPG:
+            value2 = pop();
+            value1 = pop();
+            push(interpreter.binaryOperation(insn, value1, value2));
+            break;
+        case Opcodes.IFEQ:
+        case Opcodes.IFNE:
+        case Opcodes.IFLT:
+        case Opcodes.IFGE:
+        case Opcodes.IFGT:
+        case Opcodes.IFLE:
+            interpreter.unaryOperation(insn, pop());
+            break;
+        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:
+            value2 = pop();
+            value1 = pop();
+            interpreter.binaryOperation(insn, value1, value2);
+            break;
+        case Opcodes.GOTO:
+            break;
+        case Opcodes.JSR:
+            push(interpreter.newOperation(insn));
+            break;
+        case Opcodes.RET:
+            break;
+        case Opcodes.TABLESWITCH:
+        case Opcodes.LOOKUPSWITCH:
+            interpreter.unaryOperation(insn, pop());
+            break;
+        case Opcodes.IRETURN:
+        case Opcodes.LRETURN:
+        case Opcodes.FRETURN:
+        case Opcodes.DRETURN:
+        case Opcodes.ARETURN:
+            value1 = pop();
+            interpreter.unaryOperation(insn, value1);
+            interpreter.returnOperation(insn, value1, returnValue);
+            break;
+        case Opcodes.RETURN:
+            if (returnValue != null) {
+                throw new AnalyzerException(insn, "Incompatible return type");
+            }
+            break;
+        case Opcodes.GETSTATIC:
+            push(interpreter.newOperation(insn));
+            break;
+        case Opcodes.PUTSTATIC:
+            interpreter.unaryOperation(insn, pop());
+            break;
+        case Opcodes.GETFIELD:
+            push(interpreter.unaryOperation(insn, pop()));
+            break;
+        case Opcodes.PUTFIELD:
+            value2 = pop();
+            value1 = pop();
+            interpreter.binaryOperation(insn, value1, value2);
+            break;
+        case Opcodes.INVOKEVIRTUAL:
+        case Opcodes.INVOKESPECIAL:
+        case Opcodes.INVOKESTATIC:
+        case Opcodes.INVOKEINTERFACE: {
+            values = new ArrayList<V>();
+            String desc = ((MethodInsnNode) insn).desc;
+            for (int i = Type.getArgumentTypes(desc).length; i > 0; --i) {
+                values.add(0, pop());
+            }
+            if (insn.getOpcode() != Opcodes.INVOKESTATIC) {
+                values.add(0, pop());
+            }
+            if (Type.getReturnType(desc) == Type.VOID_TYPE) {
+                interpreter.naryOperation(insn, values);
+            } else {
+                push(interpreter.naryOperation(insn, values));
+            }
+            break;
+        }
+        case Opcodes.INVOKEDYNAMIC: {
+            values = new ArrayList<V>();
+            String desc = ((InvokeDynamicInsnNode) insn).desc;
+            for (int i = Type.getArgumentTypes(desc).length; i > 0; --i) {
+                values.add(0, pop());
+            }
+            if (Type.getReturnType(desc) == Type.VOID_TYPE) {
+                interpreter.naryOperation(insn, values);
+            } else {
+                push(interpreter.naryOperation(insn, values));
+            }
+            break;
+        }
+        case Opcodes.NEW:
+            push(interpreter.newOperation(insn));
+            break;
+        case Opcodes.NEWARRAY:
+        case Opcodes.ANEWARRAY:
+        case Opcodes.ARRAYLENGTH:
+            push(interpreter.unaryOperation(insn, pop()));
+            break;
+        case Opcodes.ATHROW:
+            interpreter.unaryOperation(insn, pop());
+            break;
+        case Opcodes.CHECKCAST:
+        case Opcodes.INSTANCEOF:
+            push(interpreter.unaryOperation(insn, pop()));
+            break;
+        case Opcodes.MONITORENTER:
+        case Opcodes.MONITOREXIT:
+            interpreter.unaryOperation(insn, pop());
+            break;
+        case Opcodes.MULTIANEWARRAY:
+            values = new ArrayList<V>();
+            for (int i = ((MultiANewArrayInsnNode) insn).dims; i > 0; --i) {
+                values.add(0, pop());
+            }
+            push(interpreter.naryOperation(insn, values));
+            break;
+        case Opcodes.IFNULL:
+        case Opcodes.IFNONNULL:
+            interpreter.unaryOperation(insn, pop());
+            break;
+        default:
+            throw new RuntimeException("Illegal opcode " + insn.getOpcode());
+        }
+    }
+
+    /**
+     * Merges this frame with the given frame.
+     * 
+     * @param frame
+     *            a frame.
+     * @param interpreter
+     *            the interpreter used to merge values.
+     * @return <tt>true</tt> if this frame has been changed as a result of the
+     *         merge operation, or <tt>false</tt> otherwise.
+     * @throws AnalyzerException
+     *             if the frames have incompatible sizes.
+     */
+    public boolean merge(final Frame<? extends V> frame,
+            final Interpreter<V> interpreter) throws AnalyzerException {
+        if (top != frame.top) {
+            throw new AnalyzerException(null, "Incompatible stack heights");
+        }
+        boolean changes = false;
+        for (int i = 0; i < locals + top; ++i) {
+            V v = interpreter.merge(values[i], frame.values[i]);
+            if (!v.equals(values[i])) {
+                values[i] = v;
+                changes = true;
+            }
+        }
+        return changes;
+    }
+
+    /**
+     * Merges this frame with the given frame (case of a RET instruction).
+     * 
+     * @param frame
+     *            a frame
+     * @param access
+     *            the local variables that have been accessed by the subroutine
+     *            to which the RET instruction corresponds.
+     * @return <tt>true</tt> if this frame has been changed as a result of the
+     *         merge operation, or <tt>false</tt> otherwise.
+     */
+    public boolean merge(final Frame<? extends V> frame, final boolean[] access) {
+        boolean changes = false;
+        for (int i = 0; i < locals; ++i) {
+            if (!access[i] && !values[i].equals(frame.values[i])) {
+                values[i] = frame.values[i];
+                changes = true;
+            }
+        }
+        return changes;
+    }
+
+    /**
+     * Returns a string representation of this frame.
+     * 
+     * @return a string representation of this frame.
+     */
+    @Override
+    public String toString() {
+        StringBuffer b = new StringBuffer();
+        for (int i = 0; i < getLocals(); ++i) {
+            b.append(getLocal(i));
+        }
+        b.append(' ');
+        for (int i = 0; i < getStackSize(); ++i) {
+            b.append(getStack(i).toString());
+        }
+        return b.toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/tree/analysis/Interpreter.java
----------------------------------------------------------------------
diff --git a/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/tree/analysis/Interpreter.java b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/tree/analysis/Interpreter.java
new file mode 100644
index 0000000..5e90560
--- /dev/null
+++ b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/tree/analysis/Interpreter.java
@@ -0,0 +1,226 @@
+/***
+ * 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.tree.analysis;
+
+import java.util.List;
+
+import org.apache.tajo.org.objectweb.asm.Type;
+import org.apache.tajo.org.objectweb.asm.tree.AbstractInsnNode;
+
+/**
+ * A semantic bytecode interpreter. More precisely, this interpreter only
+ * manages the computation of values from other values: it does not manage the
+ * transfer of values to or from the stack, and to or from the local variables.
+ * This separation allows a generic bytecode {@link Analyzer} to work with
+ * various semantic interpreters, without needing to duplicate the code to
+ * simulate the transfer of values.
+ * 
+ * @param <V>
+ *            type of the Value used for the analysis.
+ * 
+ * @author Eric Bruneton
+ */
+public abstract class Interpreter<V extends Value> {
+
+    protected final int api;
+
+    protected Interpreter(final int api) {
+        this.api = api;
+    }
+
+    /**
+     * Creates a new value that represents the given type.
+     * 
+     * Called for method parameters (including <code>this</code>), exception
+     * handler variable and with <code>null</code> type for variables reserved
+     * by long and double types.
+     * 
+     * @param type
+     *            a primitive or reference type, or <tt>null</tt> to represent
+     *            an uninitialized value.
+     * @return a value that represents the given type. The size of the returned
+     *         value must be equal to the size of the given type.
+     */
+    public abstract V newValue(Type type);
+
+    /**
+     * Interprets a bytecode instruction without arguments. This method is
+     * called for the following opcodes:
+     * 
+     * ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4,
+     * ICONST_5, LCONST_0, LCONST_1, FCONST_0, FCONST_1, FCONST_2, DCONST_0,
+     * DCONST_1, BIPUSH, SIPUSH, LDC, JSR, GETSTATIC, NEW
+     * 
+     * @param insn
+     *            the bytecode instruction to be interpreted.
+     * @return the result of the interpretation of the given instruction.
+     * @throws AnalyzerException
+     *             if an error occured during the interpretation.
+     */
+    public abstract V newOperation(AbstractInsnNode insn)
+            throws AnalyzerException;
+
+    /**
+     * Interprets a bytecode instruction that moves a value on the stack or to
+     * or from local variables. This method is called for the following opcodes:
+     * 
+     * ILOAD, LLOAD, FLOAD, DLOAD, ALOAD, ISTORE, LSTORE, FSTORE, DSTORE,
+     * ASTORE, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1, DUP2_X2, SWAP
+     * 
+     * @param insn
+     *            the bytecode instruction to be interpreted.
+     * @param value
+     *            the value that must be moved by the instruction.
+     * @return the result of the interpretation of the given instruction. The
+     *         returned value must be <tt>equal</tt> to the given value.
+     * @throws AnalyzerException
+     *             if an error occured during the interpretation.
+     */
+    public abstract V copyOperation(AbstractInsnNode insn, V value)
+            throws AnalyzerException;
+
+    /**
+     * Interprets a bytecode instruction with a single argument. This method is
+     * called for the following opcodes:
+     * 
+     * INEG, LNEG, FNEG, DNEG, IINC, I2L, I2F, I2D, L2I, L2F, L2D, F2I, F2L,
+     * F2D, D2I, D2L, D2F, I2B, I2C, I2S, IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE,
+     * TABLESWITCH, LOOKUPSWITCH, IRETURN, LRETURN, FRETURN, DRETURN, ARETURN,
+     * PUTSTATIC, GETFIELD, NEWARRAY, ANEWARRAY, ARRAYLENGTH, ATHROW, CHECKCAST,
+     * INSTANCEOF, MONITORENTER, MONITOREXIT, IFNULL, IFNONNULL
+     * 
+     * @param insn
+     *            the bytecode instruction to be interpreted.
+     * @param value
+     *            the argument of the instruction to be interpreted.
+     * @return the result of the interpretation of the given instruction.
+     * @throws AnalyzerException
+     *             if an error occured during the interpretation.
+     */
+    public abstract V unaryOperation(AbstractInsnNode insn, V value)
+            throws AnalyzerException;
+
+    /**
+     * Interprets a bytecode instruction with two arguments. This method is
+     * called for the following opcodes:
+     * 
+     * IALOAD, LALOAD, FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, SALOAD, IADD,
+     * LADD, FADD, DADD, ISUB, LSUB, FSUB, DSUB, IMUL, LMUL, FMUL, DMUL, IDIV,
+     * LDIV, FDIV, DDIV, IREM, LREM, FREM, DREM, ISHL, LSHL, ISHR, LSHR, IUSHR,
+     * LUSHR, IAND, LAND, IOR, LOR, IXOR, LXOR, LCMP, FCMPL, FCMPG, DCMPL,
+     * DCMPG, IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE,
+     * IF_ACMPEQ, IF_ACMPNE, PUTFIELD
+     * 
+     * @param insn
+     *            the bytecode instruction to be interpreted.
+     * @param value1
+     *            the first argument of the instruction to be interpreted.
+     * @param value2
+     *            the second argument of the instruction to be interpreted.
+     * @return the result of the interpretation of the given instruction.
+     * @throws AnalyzerException
+     *             if an error occured during the interpretation.
+     */
+    public abstract V binaryOperation(AbstractInsnNode insn, V value1, V value2)
+            throws AnalyzerException;
+
+    /**
+     * Interprets a bytecode instruction with three arguments. This method is
+     * called for the following opcodes:
+     * 
+     * IASTORE, LASTORE, FASTORE, DASTORE, AASTORE, BASTORE, CASTORE, SASTORE
+     * 
+     * @param insn
+     *            the bytecode instruction to be interpreted.
+     * @param value1
+     *            the first argument of the instruction to be interpreted.
+     * @param value2
+     *            the second argument of the instruction to be interpreted.
+     * @param value3
+     *            the third argument of the instruction to be interpreted.
+     * @return the result of the interpretation of the given instruction.
+     * @throws AnalyzerException
+     *             if an error occured during the interpretation.
+     */
+    public abstract V ternaryOperation(AbstractInsnNode insn, V value1,
+            V value2, V value3) throws AnalyzerException;
+
+    /**
+     * Interprets a bytecode instruction with a variable number of arguments.
+     * This method is called for the following opcodes:
+     * 
+     * INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC, INVOKEINTERFACE,
+     * MULTIANEWARRAY and INVOKEDYNAMIC
+     * 
+     * @param insn
+     *            the bytecode instruction to be interpreted.
+     * @param values
+     *            the arguments of the instruction to be interpreted.
+     * @return the result of the interpretation of the given instruction.
+     * @throws AnalyzerException
+     *             if an error occured during the interpretation.
+     */
+    public abstract V naryOperation(AbstractInsnNode insn,
+            List<? extends V> values) throws AnalyzerException;
+
+    /**
+     * Interprets a bytecode return instruction. This method is called for the
+     * following opcodes:
+     * 
+     * IRETURN, LRETURN, FRETURN, DRETURN, ARETURN
+     * 
+     * @param insn
+     *            the bytecode instruction to be interpreted.
+     * @param value
+     *            the argument of the instruction to be interpreted.
+     * @param expected
+     *            the expected return type of the analyzed method.
+     * @throws AnalyzerException
+     *             if an error occured during the interpretation.
+     */
+    public abstract void returnOperation(AbstractInsnNode insn, V value,
+            V expected) throws AnalyzerException;
+
+    /**
+     * Merges two values. The merge operation must return a value that
+     * represents both values (for instance, if the two values are two types,
+     * the merged value must be a common super type of the two types. If the two
+     * values are integer intervals, the merged value must be an interval that
+     * contains the previous ones. Likewise for other types of values).
+     * 
+     * @param v
+     *            a value.
+     * @param w
+     *            another value.
+     * @return the merged value. If the merged value is equal to <tt>v</tt>,
+     *         this method <i>must</i> return <tt>v</tt>.
+     */
+    public abstract V merge(V v, V w);
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/tree/analysis/SimpleVerifier.java
----------------------------------------------------------------------
diff --git a/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/tree/analysis/SimpleVerifier.java b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/tree/analysis/SimpleVerifier.java
new file mode 100644
index 0000000..ac4971c
--- /dev/null
+++ b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/tree/analysis/SimpleVerifier.java
@@ -0,0 +1,320 @@
+/***
+ * 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.tree.analysis;
+
+import java.util.List;
+
+import org.apache.tajo.org.objectweb.asm.Type;
+
+/**
+ * An extended {@link BasicVerifier} that performs more precise verifications.
+ * This verifier computes exact class types, instead of using a single "object
+ * reference" type (as done in the {@link BasicVerifier}).
+ * 
+ * @author Eric Bruneton
+ * @author Bing Ran
+ */
+public class SimpleVerifier extends BasicVerifier {
+
+    /**
+     * The class that is verified.
+     */
+    private final Type currentClass;
+
+    /**
+     * The super class of the class that is verified.
+     */
+    private final Type currentSuperClass;
+
+    /**
+     * The interfaces implemented by the class that is verified.
+     */
+    private final List<Type> currentClassInterfaces;
+
+    /**
+     * If the class that is verified is an interface.
+     */
+    private final boolean isInterface;
+
+    /**
+     * The loader to use for referenced classes.
+     */
+    private ClassLoader loader = getClass().getClassLoader();
+
+    /**
+     * Constructs a new {@link SimpleVerifier}.
+     */
+    public SimpleVerifier() {
+        this(null, null, false);
+    }
+
+    /**
+     * Constructs a new {@link SimpleVerifier} to verify a specific class. This
+     * class will not be loaded into the JVM since it may be incorrect.
+     * 
+     * @param currentClass
+     *            the class that is verified.
+     * @param currentSuperClass
+     *            the super class of the class that is verified.
+     * @param isInterface
+     *            if the class that is verified is an interface.
+     */
+    public SimpleVerifier(final Type currentClass,
+            final Type currentSuperClass, final boolean isInterface) {
+        this(currentClass, currentSuperClass, null, isInterface);
+    }
+
+    /**
+     * Constructs a new {@link SimpleVerifier} to verify a specific class. This
+     * class will not be loaded into the JVM since it may be incorrect.
+     * 
+     * @param currentClass
+     *            the class that is verified.
+     * @param currentSuperClass
+     *            the super class of the class that is verified.
+     * @param currentClassInterfaces
+     *            the interfaces implemented by the class that is verified.
+     * @param isInterface
+     *            if the class that is verified is an interface.
+     */
+    public SimpleVerifier(final Type currentClass,
+            final Type currentSuperClass,
+            final List<Type> currentClassInterfaces, final boolean isInterface) {
+        this(ASM4, currentClass, currentSuperClass, currentClassInterfaces,
+                isInterface);
+    }
+
+    protected SimpleVerifier(final int api, final Type currentClass,
+            final Type currentSuperClass,
+            final List<Type> currentClassInterfaces, final boolean isInterface) {
+        super(api);
+        this.currentClass = currentClass;
+        this.currentSuperClass = currentSuperClass;
+        this.currentClassInterfaces = currentClassInterfaces;
+        this.isInterface = isInterface;
+    }
+
+    /**
+     * Set the <code>ClassLoader</code> which will be used to load referenced
+     * classes. This is useful if you are verifying multiple interdependent
+     * classes.
+     * 
+     * @param loader
+     *            a <code>ClassLoader</code> to use
+     */
+    public void setClassLoader(final ClassLoader loader) {
+        this.loader = loader;
+    }
+
+    @Override
+    public BasicValue newValue(final Type type) {
+        if (type == null) {
+            return BasicValue.UNINITIALIZED_VALUE;
+        }
+
+        boolean isArray = type.getSort() == Type.ARRAY;
+        if (isArray) {
+            switch (type.getElementType().getSort()) {
+            case Type.BOOLEAN:
+            case Type.CHAR:
+            case Type.BYTE:
+            case Type.SHORT:
+                return new BasicValue(type);
+            }
+        }
+
+        BasicValue v = super.newValue(type);
+        if (BasicValue.REFERENCE_VALUE.equals(v)) {
+            if (isArray) {
+                v = newValue(type.getElementType());
+                String desc = v.getType().getDescriptor();
+                for (int i = 0; i < type.getDimensions(); ++i) {
+                    desc = '[' + desc;
+                }
+                v = new BasicValue(Type.getType(desc));
+            } else {
+                v = new BasicValue(type);
+            }
+        }
+        return v;
+    }
+
+    @Override
+    protected boolean isArrayValue(final BasicValue value) {
+        Type t = value.getType();
+        return t != null
+                && ("Lnull;".equals(t.getDescriptor()) || t.getSort() == Type.ARRAY);
+    }
+
+    @Override
+    protected BasicValue getElementValue(final BasicValue objectArrayValue)
+            throws AnalyzerException {
+        Type arrayType = objectArrayValue.getType();
+        if (arrayType != null) {
+            if (arrayType.getSort() == Type.ARRAY) {
+                return newValue(Type.getType(arrayType.getDescriptor()
+                        .substring(1)));
+            } else if ("Lnull;".equals(arrayType.getDescriptor())) {
+                return objectArrayValue;
+            }
+        }
+        throw new Error("Internal error");
+    }
+
+    @Override
+    protected boolean isSubTypeOf(final BasicValue value,
+            final BasicValue expected) {
+        Type expectedType = expected.getType();
+        Type type = value.getType();
+        switch (expectedType.getSort()) {
+        case Type.INT:
+        case Type.FLOAT:
+        case Type.LONG:
+        case Type.DOUBLE:
+            return type.equals(expectedType);
+        case Type.ARRAY:
+        case Type.OBJECT:
+            if ("Lnull;".equals(type.getDescriptor())) {
+                return true;
+            } else if (type.getSort() == Type.OBJECT
+                    || type.getSort() == Type.ARRAY) {
+                return isAssignableFrom(expectedType, type);
+            } else {
+                return false;
+            }
+        default:
+            throw new Error("Internal error");
+        }
+    }
+
+    @Override
+    public BasicValue merge(final BasicValue v, final BasicValue w) {
+        if (!v.equals(w)) {
+            Type t = v.getType();
+            Type u = w.getType();
+            if (t != null
+                    && (t.getSort() == Type.OBJECT || t.getSort() == Type.ARRAY)) {
+                if (u != null
+                        && (u.getSort() == Type.OBJECT || u.getSort() == Type.ARRAY)) {
+                    if ("Lnull;".equals(t.getDescriptor())) {
+                        return w;
+                    }
+                    if ("Lnull;".equals(u.getDescriptor())) {
+                        return v;
+                    }
+                    if (isAssignableFrom(t, u)) {
+                        return v;
+                    }
+                    if (isAssignableFrom(u, t)) {
+                        return w;
+                    }
+                    // TODO case of array classes of the same dimension
+                    // TODO should we look also for a common super interface?
+                    // problem: there may be several possible common super
+                    // interfaces
+                    do {
+                        if (t == null || isInterface(t)) {
+                            return BasicValue.REFERENCE_VALUE;
+                        }
+                        t = getSuperClass(t);
+                        if (isAssignableFrom(t, u)) {
+                            return newValue(t);
+                        }
+                    } while (true);
+                }
+            }
+            return BasicValue.UNINITIALIZED_VALUE;
+        }
+        return v;
+    }
+
+    protected boolean isInterface(final Type t) {
+        if (currentClass != null && t.equals(currentClass)) {
+            return isInterface;
+        }
+        return getClass(t).isInterface();
+    }
+
+    protected Type getSuperClass(final Type t) {
+        if (currentClass != null && t.equals(currentClass)) {
+            return currentSuperClass;
+        }
+        Class<?> c = getClass(t).getSuperclass();
+        return c == null ? null : Type.getType(c);
+    }
+
+    protected boolean isAssignableFrom(final Type t, final Type u) {
+        if (t.equals(u)) {
+            return true;
+        }
+        if (currentClass != null && t.equals(currentClass)) {
+            if (getSuperClass(u) == null) {
+                return false;
+            } else {
+                if (isInterface) {
+                    return u.getSort() == Type.OBJECT
+                            || u.getSort() == Type.ARRAY;
+                }
+                return isAssignableFrom(t, getSuperClass(u));
+            }
+        }
+        if (currentClass != null && u.equals(currentClass)) {
+            if (isAssignableFrom(t, currentSuperClass)) {
+                return true;
+            }
+            if (currentClassInterfaces != null) {
+                for (int i = 0; i < currentClassInterfaces.size(); ++i) {
+                    Type v = currentClassInterfaces.get(i);
+                    if (isAssignableFrom(t, v)) {
+                        return true;
+                    }
+                }
+            }
+            return false;
+        }
+        Class<?> tc = getClass(t);
+        if (tc.isInterface()) {
+            tc = Object.class;
+        }
+        return tc.isAssignableFrom(getClass(u));
+    }
+
+    protected Class<?> getClass(final Type t) {
+        try {
+            if (t.getSort() == Type.ARRAY) {
+                return Class.forName(t.getDescriptor().replace('/', '.'),
+                        false, loader);
+            }
+            return Class.forName(t.getClassName(), false, loader);
+        } catch (ClassNotFoundException e) {
+            throw new RuntimeException(e.toString());
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/tree/analysis/SmallSet.java
----------------------------------------------------------------------
diff --git a/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/tree/analysis/SmallSet.java b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/tree/analysis/SmallSet.java
new file mode 100644
index 0000000..cf92e28
--- /dev/null
+++ b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/tree/analysis/SmallSet.java
@@ -0,0 +1,134 @@
+/***
+ * 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.tree.analysis;
+
+import java.util.AbstractSet;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.Set;
+
+/**
+ * A set of at most two elements.
+ * 
+ * @author Eric Bruneton
+ */
+class SmallSet<E> extends AbstractSet<E> implements Iterator<E> {
+
+    // if e1 is null, e2 must be null; otherwise e2 must be different from e1
+
+    E e1, e2;
+
+    static final <T> Set<T> emptySet() {
+        return new SmallSet<T>(null, null);
+    }
+
+    SmallSet(final E e1, final E e2) {
+        this.e1 = e1;
+        this.e2 = e2;
+    }
+
+    // -------------------------------------------------------------------------
+    // Implementation of inherited abstract methods
+    // -------------------------------------------------------------------------
+
+    @Override
+    public Iterator<E> iterator() {
+        return new SmallSet<E>(e1, e2);
+    }
+
+    @Override
+    public int size() {
+        return e1 == null ? 0 : (e2 == null ? 1 : 2);
+    }
+
+    // -------------------------------------------------------------------------
+    // Implementation of the Iterator interface
+    // -------------------------------------------------------------------------
+
+    public boolean hasNext() {
+        return e1 != null;
+    }
+
+    public E next() {
+        if (e1 == null) {
+            throw new NoSuchElementException();
+        }
+        E e = e1;
+        e1 = e2;
+        e2 = null;
+        return e;
+    }
+
+    public void remove() {
+    }
+
+    // -------------------------------------------------------------------------
+    // Utility methods
+    // -------------------------------------------------------------------------
+
+    Set<E> union(final SmallSet<E> s) {
+        if ((s.e1 == e1 && s.e2 == e2) || (s.e1 == e2 && s.e2 == e1)) {
+            return this; // if the two sets are equal, return this
+        }
+        if (s.e1 == null) {
+            return this; // if s is empty, return this
+        }
+        if (e1 == null) {
+            return s; // if this is empty, return s
+        }
+        if (s.e2 == null) { // s contains exactly one element
+            if (e2 == null) {
+                return new SmallSet<E>(e1, s.e1); // necessarily e1 != s.e1
+            } else if (s.e1 == e1 || s.e1 == e2) { // s is included in this
+                return this;
+            }
+        }
+        if (e2 == null) { // this contains exactly one element
+            // if (s.e2 == null) { // cannot happen
+            // return new SmallSet(e1, s.e1); // necessarily e1 != s.e1
+            // } else
+            if (e1 == s.e1 || e1 == s.e2) { // this in included in s
+                return s;
+            }
+        }
+        // here we know that there are at least 3 distinct elements
+        HashSet<E> r = new HashSet<E>(4);
+        r.add(e1);
+        if (e2 != null) {
+            r.add(e2);
+        }
+        r.add(s.e1);
+        if (s.e2 != null) {
+            r.add(s.e2);
+        }
+        return r;
+    }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/tree/analysis/SourceInterpreter.java
----------------------------------------------------------------------
diff --git a/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/tree/analysis/SourceInterpreter.java b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/tree/analysis/SourceInterpreter.java
new file mode 100644
index 0000000..4054dc6
--- /dev/null
+++ b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/tree/analysis/SourceInterpreter.java
@@ -0,0 +1,198 @@
+/***
+ * 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.tree.analysis;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.tajo.org.objectweb.asm.Type;
+import org.apache.tajo.org.objectweb.asm.Opcodes;
+import org.apache.tajo.org.objectweb.asm.tree.AbstractInsnNode;
+import org.apache.tajo.org.objectweb.asm.tree.FieldInsnNode;
+import org.apache.tajo.org.objectweb.asm.tree.InvokeDynamicInsnNode;
+import org.apache.tajo.org.objectweb.asm.tree.LdcInsnNode;
+import org.apache.tajo.org.objectweb.asm.tree.MethodInsnNode;
+
+/**
+ * An {@link Interpreter} for {@link SourceValue} values.
+ * 
+ * @author Eric Bruneton
+ */
+public class SourceInterpreter extends Interpreter<SourceValue> implements
+        Opcodes {
+
+    public SourceInterpreter() {
+        super(ASM4);
+    }
+
+    protected SourceInterpreter(final int api) {
+        super(api);
+    }
+
+    @Override
+    public SourceValue newValue(final Type type) {
+        if (type == Type.VOID_TYPE) {
+            return null;
+        }
+        return new SourceValue(type == null ? 1 : type.getSize());
+    }
+
+    @Override
+    public SourceValue newOperation(final AbstractInsnNode insn) {
+        int size;
+        switch (insn.getOpcode()) {
+        case LCONST_0:
+        case LCONST_1:
+        case DCONST_0:
+        case DCONST_1:
+            size = 2;
+            break;
+        case LDC:
+            Object cst = ((LdcInsnNode) insn).cst;
+            size = cst instanceof Long || cst instanceof Double ? 2 : 1;
+            break;
+        case GETSTATIC:
+            size = Type.getType(((FieldInsnNode) insn).desc).getSize();
+            break;
+        default:
+            size = 1;
+        }
+        return new SourceValue(size, insn);
+    }
+
+    @Override
+    public SourceValue copyOperation(final AbstractInsnNode insn,
+            final SourceValue value) {
+        return new SourceValue(value.getSize(), insn);
+    }
+
+    @Override
+    public SourceValue unaryOperation(final AbstractInsnNode insn,
+            final SourceValue value) {
+        int size;
+        switch (insn.getOpcode()) {
+        case LNEG:
+        case DNEG:
+        case I2L:
+        case I2D:
+        case L2D:
+        case F2L:
+        case F2D:
+        case D2L:
+            size = 2;
+            break;
+        case GETFIELD:
+            size = Type.getType(((FieldInsnNode) insn).desc).getSize();
+            break;
+        default:
+            size = 1;
+        }
+        return new SourceValue(size, insn);
+    }
+
+    @Override
+    public SourceValue binaryOperation(final AbstractInsnNode insn,
+            final SourceValue value1, final SourceValue value2) {
+        int size;
+        switch (insn.getOpcode()) {
+        case LALOAD:
+        case DALOAD:
+        case LADD:
+        case DADD:
+        case LSUB:
+        case DSUB:
+        case LMUL:
+        case DMUL:
+        case LDIV:
+        case DDIV:
+        case LREM:
+        case DREM:
+        case LSHL:
+        case LSHR:
+        case LUSHR:
+        case LAND:
+        case LOR:
+        case LXOR:
+            size = 2;
+            break;
+        default:
+            size = 1;
+        }
+        return new SourceValue(size, insn);
+    }
+
+    @Override
+    public SourceValue ternaryOperation(final AbstractInsnNode insn,
+            final SourceValue value1, final SourceValue value2,
+            final SourceValue value3) {
+        return new SourceValue(1, insn);
+    }
+
+    @Override
+    public SourceValue naryOperation(final AbstractInsnNode insn,
+            final List<? extends SourceValue> values) {
+        int size;
+        int opcode = insn.getOpcode();
+        if (opcode == MULTIANEWARRAY) {
+            size = 1;
+        } else {
+            String desc = (opcode == INVOKEDYNAMIC) ? ((InvokeDynamicInsnNode) insn).desc
+                    : ((MethodInsnNode) insn).desc;
+            size = Type.getReturnType(desc).getSize();
+        }
+        return new SourceValue(size, insn);
+    }
+
+    @Override
+    public void returnOperation(final AbstractInsnNode insn,
+            final SourceValue value, final SourceValue expected) {
+    }
+
+    @Override
+    public SourceValue merge(final SourceValue d, final SourceValue w) {
+        if (d.insns instanceof SmallSet && w.insns instanceof SmallSet) {
+            Set<AbstractInsnNode> s = ((SmallSet<AbstractInsnNode>) d.insns)
+                    .union((SmallSet<AbstractInsnNode>) w.insns);
+            if (s == d.insns && d.size == w.size) {
+                return d;
+            } else {
+                return new SourceValue(Math.min(d.size, w.size), s);
+            }
+        }
+        if (d.size != w.size || !d.insns.containsAll(w.insns)) {
+            HashSet<AbstractInsnNode> s = new HashSet<AbstractInsnNode>();
+            s.addAll(d.insns);
+            s.addAll(w.insns);
+            return new SourceValue(Math.min(d.size, w.size), s);
+        }
+        return d;
+    }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/tree/analysis/SourceValue.java
----------------------------------------------------------------------
diff --git a/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/tree/analysis/SourceValue.java b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/tree/analysis/SourceValue.java
new file mode 100644
index 0000000..aa42478
--- /dev/null
+++ b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/tree/analysis/SourceValue.java
@@ -0,0 +1,97 @@
+/***
+ * 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.tree.analysis;
+
+import java.util.Set;
+
+import org.apache.tajo.org.objectweb.asm.tree.AbstractInsnNode;
+
+/**
+ * A {@link Value} that is represented by its type in a two types type system.
+ * This type system distinguishes the ONEWORD and TWOWORDS types.
+ * 
+ * @author Eric Bruneton
+ */
+public class SourceValue implements Value {
+
+    /**
+     * The size of this value.
+     */
+    public final int size;
+
+    /**
+     * The instructions that can produce this value. For example, for the Java
+     * code below, the instructions that can produce the value of <tt>i</tt> at
+     * line 5 are the txo ISTORE instructions at line 1 and 3:
+     * 
+     * <pre>
+     * 1: i = 0;
+     * 2: if (...) {
+     * 3:   i = 1;
+     * 4: }
+     * 5: return i;
+     * </pre>
+     * 
+     * This field is a set of {@link org.apache.tajo.org.objectweb.asm.tree.AbstractInsnNode} objects.
+     */
+    public final Set<AbstractInsnNode> insns;
+
+    public SourceValue(final int size) {
+        this(size, SmallSet.<AbstractInsnNode> emptySet());
+    }
+
+    public SourceValue(final int size, final AbstractInsnNode insn) {
+        this.size = size;
+        this.insns = new SmallSet<AbstractInsnNode>(insn, null);
+    }
+
+    public SourceValue(final int size, final Set<AbstractInsnNode> insns) {
+        this.size = size;
+        this.insns = insns;
+    }
+
+    public int getSize() {
+        return size;
+    }
+
+    @Override
+    public boolean equals(final Object value) {
+        if (!(value instanceof SourceValue)) {
+            return false;
+        }
+        SourceValue v = (SourceValue) value;
+        return size == v.size && insns.equals(v.insns);
+    }
+
+    @Override
+    public int hashCode() {
+        return insns.hashCode();
+    }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/tree/analysis/Subroutine.java
----------------------------------------------------------------------
diff --git a/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/tree/analysis/Subroutine.java b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/tree/analysis/Subroutine.java
new file mode 100644
index 0000000..19cb36f
--- /dev/null
+++ b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/tree/analysis/Subroutine.java
@@ -0,0 +1,90 @@
+/***
+ * 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.tree.analysis;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.tajo.org.objectweb.asm.tree.JumpInsnNode;
+import org.apache.tajo.org.objectweb.asm.tree.LabelNode;
+
+/**
+ * A method subroutine (corresponds to a JSR instruction).
+ * 
+ * @author Eric Bruneton
+ */
+class Subroutine {
+
+    LabelNode start;
+
+    boolean[] access;
+
+    List<JumpInsnNode> callers;
+
+    private Subroutine() {
+    }
+
+    Subroutine(final LabelNode start, final int maxLocals,
+            final JumpInsnNode caller) {
+        this.start = start;
+        this.access = new boolean[maxLocals];
+        this.callers = new ArrayList<JumpInsnNode>();
+        callers.add(caller);
+    }
+
+    public Subroutine copy() {
+        Subroutine result = new Subroutine();
+        result.start = start;
+        result.access = new boolean[access.length];
+        System.arraycopy(access, 0, result.access, 0, access.length);
+        result.callers = new ArrayList<JumpInsnNode>(callers);
+        return result;
+    }
+
+    public boolean merge(final Subroutine subroutine) throws AnalyzerException {
+        boolean changes = false;
+        for (int i = 0; i < access.length; ++i) {
+            if (subroutine.access[i] && !access[i]) {
+                access[i] = true;
+                changes = true;
+            }
+        }
+        if (subroutine.start == start) {
+            for (int i = 0; i < subroutine.callers.size(); ++i) {
+                JumpInsnNode caller = subroutine.callers.get(i);
+                if (!callers.contains(caller)) {
+                    callers.add(caller);
+                    changes = true;
+                }
+            }
+        }
+        return changes;
+    }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/tree/analysis/Value.java
----------------------------------------------------------------------
diff --git a/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/tree/analysis/Value.java b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/tree/analysis/Value.java
new file mode 100644
index 0000000..6a2887a
--- /dev/null
+++ b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/tree/analysis/Value.java
@@ -0,0 +1,45 @@
+/***
+ * 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.tree.analysis;
+
+/**
+ * An immutable symbolic value for semantic interpretation of bytecode.
+ * 
+ * @author Eric Bruneton
+ */
+public interface Value {
+
+    /**
+     * Returns the size of this value in words.
+     * 
+     * @return either 1 or 2.
+     */
+    int getSize();
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/tree/analysis/package.html
----------------------------------------------------------------------
diff --git a/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/tree/analysis/package.html b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/tree/analysis/package.html
new file mode 100644
index 0000000..57345a8
--- /dev/null
+++ b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/tree/analysis/package.html
@@ -0,0 +1,85 @@
+<!--~
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements.  See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership.  The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License.  You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<html>
+<!--
+ * 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.
+-->
+<body>
+
+<p>
+Provides a framework for static code analysis based on the asm.tree package.
+</p>
+
+<p>
+Basic usage:
+</p>
+
+<pre>
+ClassReader cr = new ClassReader(bytecode);
+ClassNode cn = new ClassNode();
+cr.accept(cn, ClassReader.SKIP_DEBUG);
+
+List methods = cn.methods;
+for (int i = 0; i < methods.size(); ++i) {
+    MethodNode method = (MethodNode) methods.get(i);
+    if (method.instructions.size() > 0) {
+        Analyzer a = new Analyzer(new BasicInterpreter());
+        a.analyze(cn.name, method);
+        Frame[] frames = a.getFrames();
+        // Elements of the frames arrray now contains info for each instruction
+        // from the analyzed method. BasicInterpreter creates BasicValue, that
+        // is using simplified type system that distinguishes the UNINITIALZED,
+        // INT, FLOAT, LONG, DOUBLE, REFERENCE and RETURNADDRESS types.
+        ...
+    }
+}
+</pre>
+
+<p>
+@since ASM 1.4.3
+</p>
+
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/tree/package.html
----------------------------------------------------------------------
diff --git a/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/tree/package.html b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/tree/package.html
new file mode 100644
index 0000000..733f2ff
--- /dev/null
+++ b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/tree/package.html
@@ -0,0 +1,210 @@
+<!--~
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements.  See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership.  The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License.  You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<html>
+<!--
+ * 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.
+-->
+<body>
+
+<p>
+Provides an ASM visitor that constructs a tree representation of the
+classes it visits. This class adapter can be useful to implement "complex"
+class manipulation operations, i.e., operations that would be very hard to
+implement without using a tree representation (such as optimizing the number
+of local variables used by a method).
+</p>
+
+<p>
+However, this class adapter has a cost: it makes ASM bigger and slower. Indeed
+it requires more than twenty new classes, and multiplies the time needed to
+transform a class by almost two (it is almost two times faster to read, "modify"
+and write a class with a ClassVisitor than with a ClassNode). This is why
+this package is bundled in an optional <tt>asm-tree.jar</tt> library that
+is separated from (but requires) the <tt>asm.jar</tt> library, which contains
+the core ASM framework. This is also why <i><font color="red">it is recommended
+not to use this class adapter when it is possible</font></i>.
+</p>
+
+<p>
+The root class is the ClassNode, that can be created from existing bytecode. For example:
+</p>
+
+<pre>
+  ClassReader cr = new ClassReader(source);
+  ClassNode cn = new ClassNode();
+  cr.accept(cn, true);
+</pre>
+
+<p>
+Now the content of ClassNode can be modified and then
+serialized back into bytecode:
+</p>
+
+<pre>
+  ClassWriter cw = new ClassWriter(true);
+  cn.accept(cw);
+</pre>
+
+<p>
+Using a simple ClassVisitor it is possible to create MethodNode instances per-method.
+In this example MethodNode is acting as a buffer that is flushed out at visitEnd() call:
+</p>
+
+<pre>
+  ClassReader cr = new ClassReader(source);
+  ClassWriter cw = new ClassWriter();
+  ClassVisitor cv = new ClassVisitor(cw) {
+    public MethodVisitor visitMethod(int access, String name,
+        String desc, String signature, String[] exceptions) {
+      final MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
+      MethodNode mn = new MethodNode(access, name, desc, signature, exceptions) {
+        public void visitEnd() {
+          // transform or analyze method code using tree API
+          accept(mv);
+        }
+      };
+    }
+  };
+  cr.accept(cv, true);
+</pre>
+
+<p>
+Several strategies can be used to construct method code from scratch. The first
+option is to create a MethodNode, and then create XxxInsnNode instances and
+add them to the instructions list:
+</p>
+
+<pre>
+MethodNode m = new MethodNode(...);
+m.instructions.add(new VarInsnNode(ALOAD, 0));
+...
+</pre>
+
+<p>
+Alternatively, you can use the fact that MethodNode is a MethodVisitor, and use
+that to create the XxxInsnNode and add them to the instructions list through
+the standard MethodVisitor methods:
+</p>
+
+<pre>
+MethodNode m = new MethodNode(...);
+m.visitVarInsn(ALOAD, 0);
+...
+</pre>
+
+<p>
+If you cannot generate all the instructions in sequential order, i.e. if you
+need to save some pointer in the instruction list and then insert instructions
+at that place after other instructions have been generated, you can use InsnList
+methods insert() and insertBefore() to insert instructions at a saved pointer.
+</p>
+
+<pre>
+MethodNode m = new MethodNode(...);
+m.visitVarInsn(ALOAD, 0);
+AbstractInsnNode ptr = m.instructions.getLast();
+m.visitVarInsn(ALOAD, 1);
+// inserts an instruction between ALOAD 0 and ALOAD 1
+m.instructions.insert(ptr, new VarInsnNode(ALOAD, 0));
+...
+</pre>
+
+<p>
+If you need to insert instructions while iterating over an existing instruction
+list, you can also use several strategies. The first one is to use a
+ListIterator over the instruction list:
+</p>
+
+<pre>
+ListIterator it = m.instructions.iterator();
+while (it.hasNext()) {
+    AbstractInsnNode n = (AbstractInsnNode) it.next();
+    if (...) {
+        it.add(new VarInsnNode(ALOAD, 0));
+    }
+}
+</pre>
+
+<p>
+It is also possible to convert an instruction list into an array and iterate trough
+array elements:
+</p>
+
+<pre>
+AbstractInsnNode[] insns = m.instructions.toArray();
+for(int i = 0; i&lt;insns.length; i++) {
+    AbstractInsnNode n = insns[i];
+    if (...) {
+        m.instructions.insert(n, new VarInsnNode(ALOAD, 0));
+    }
+}
+</pre>
+
+<p>
+If you want to insert these instructions through the MethodVisitor methods,
+you can use another instance of MethodNode as a MethodVisitor and then
+insert instructions collected by that instance into the instruction list.
+For example:
+</p>
+
+<pre>
+AbstractInsnNode[] insns = m.instructions.toArray();
+for(int i = 0; i&lt;insns.length; i++) {
+    AbstractInsnNode n = insns[i];
+    if (...) {
+        MethodNode mn = new MethodNode();
+        mn.visitVarInsn(ALOAD, 0);
+        mn.visitVarInsn(ALOAD, 1);
+        m.instructions.insert(n, mn.instructions);
+    }
+}
+</pre>
+
+<p>
+@since ASM 1.3.3
+</p>
+
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/util/ASMifiable.java
----------------------------------------------------------------------
diff --git a/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/util/ASMifiable.java b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/util/ASMifiable.java
new file mode 100644
index 0000000..b2381c1
--- /dev/null
+++ b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/util/ASMifiable.java
@@ -0,0 +1,56 @@
+/**
+ * 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.util;
+
+import java.util.Map;
+
+import org.apache.tajo.org.objectweb.asm.Label;
+
+/**
+ * An {@link org.apache.tajo.org.objectweb.asm.Attribute Attribute} that can print the ASM code
+ * to create an equivalent attribute.
+ * 
+ * @author Eugene Kuleshov
+ */
+public interface ASMifiable {
+
+    /**
+     * Prints the ASM code to create an attribute equal to this attribute.
+     * 
+     * @param buf
+     *            a buffer used for printing Java code.
+     * @param varName
+     *            name of the variable in a printed code used to store attribute
+     *            instance.
+     * @param labelNames
+     *            map of label instances to their names.
+     */
+    void asmify(StringBuffer buf, String varName, Map<Label, String> labelNames);
+}