http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/commons/RemappingSignatureAdapter.java ---------------------------------------------------------------------- diff --git a/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/commons/RemappingSignatureAdapter.java b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/commons/RemappingSignatureAdapter.java new file mode 100644 index 0000000..678d501 --- /dev/null +++ b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/commons/RemappingSignatureAdapter.java @@ -0,0 +1,155 @@ +/*** + * 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.commons; + +import org.apache.tajo.org.objectweb.asm.Opcodes; +import org.apache.tajo.org.objectweb.asm.signature.SignatureVisitor; + +/** + * A {@link SignatureVisitor} adapter for type mapping. + * + * @author Eugene Kuleshov + */ +public class RemappingSignatureAdapter extends SignatureVisitor { + + private final SignatureVisitor v; + + private final Remapper remapper; + + private String className; + + public RemappingSignatureAdapter(final SignatureVisitor v, + final Remapper remapper) { + this(Opcodes.ASM4, v, remapper); + } + + protected RemappingSignatureAdapter(final int api, + final SignatureVisitor v, final Remapper remapper) { + super(api); + this.v = v; + this.remapper = remapper; + } + + @Override + public void visitClassType(String name) { + className = name; + v.visitClassType(remapper.mapType(name)); + } + + @Override + public void visitInnerClassType(String name) { + String remappedOuter = remapper.mapType(className) + '$'; + className = className + '$' + name; + String remappedName = remapper.mapType(className); + int index = remappedName.startsWith(remappedOuter) ? remappedOuter + .length() : remappedName.lastIndexOf('$') + 1; + v.visitInnerClassType(remappedName.substring(index)); + } + + @Override + public void visitFormalTypeParameter(String name) { + v.visitFormalTypeParameter(name); + } + + @Override + public void visitTypeVariable(String name) { + v.visitTypeVariable(name); + } + + @Override + public SignatureVisitor visitArrayType() { + v.visitArrayType(); + return this; + } + + @Override + public void visitBaseType(char descriptor) { + v.visitBaseType(descriptor); + } + + @Override + public SignatureVisitor visitClassBound() { + v.visitClassBound(); + return this; + } + + @Override + public SignatureVisitor visitExceptionType() { + v.visitExceptionType(); + return this; + } + + @Override + public SignatureVisitor visitInterface() { + v.visitInterface(); + return this; + } + + @Override + public SignatureVisitor visitInterfaceBound() { + v.visitInterfaceBound(); + return this; + } + + @Override + public SignatureVisitor visitParameterType() { + v.visitParameterType(); + return this; + } + + @Override + public SignatureVisitor visitReturnType() { + v.visitReturnType(); + return this; + } + + @Override + public SignatureVisitor visitSuperclass() { + v.visitSuperclass(); + return this; + } + + @Override + public void visitTypeArgument() { + v.visitTypeArgument(); + } + + @Override + public SignatureVisitor visitTypeArgument(char wildcard) { + v.visitTypeArgument(wildcard); + return this; + } + + @Override + public void visitEnd() { + v.visitEnd(); + } +}
http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/commons/SerialVersionUIDAdder.java ---------------------------------------------------------------------- diff --git a/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/commons/SerialVersionUIDAdder.java b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/commons/SerialVersionUIDAdder.java new file mode 100644 index 0000000..4056b2f --- /dev/null +++ b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/commons/SerialVersionUIDAdder.java @@ -0,0 +1,533 @@ +/*** + * 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.commons; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutput; +import java.io.DataOutputStream; +import java.io.IOException; +import java.security.MessageDigest; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; + +import org.apache.tajo.org.objectweb.asm.FieldVisitor; +import org.apache.tajo.org.objectweb.asm.MethodVisitor; +import org.apache.tajo.org.objectweb.asm.ClassVisitor; +import org.apache.tajo.org.objectweb.asm.Opcodes; + +/** + * A {@link ClassVisitor} that adds a serial version unique identifier to a + * class if missing. Here is typical usage of this class: + * + * <pre> + * ClassWriter cw = new ClassWriter(...); + * ClassVisitor sv = new SerialVersionUIDAdder(cw); + * ClassVisitor ca = new MyClassAdapter(sv); + * new ClassReader(orginalClass).accept(ca, false); + * </pre> + * + * The SVUID algorithm can be found <a href= + * "http://java.sun.com/j2se/1.4.2/docs/guide/serialization/spec/class.html" + * >http://java.sun.com/j2se/1.4.2/docs/guide/serialization/spec/class.html</a>: + * + * <pre> + * The serialVersionUID is computed using the signature of a stream of bytes + * that reflect the class definition. The National Institute of Standards and + * Technology (NIST) Secure Hash Algorithm (SHA-1) is used to compute a + * signature for the stream. The first two 32-bit quantities are used to form a + * 64-bit hash. A java.lang.DataOutputStream is used to convert primitive data + * types to a sequence of bytes. The values input to the stream are defined by + * the Java Virtual Machine (VM) specification for classes. + * + * The sequence of items in the stream is as follows: + * + * 1. The class name written using UTF encoding. + * 2. The class modifiers written as a 32-bit integer. + * 3. The name of each interface sorted by name written using UTF encoding. + * 4. For each field of the class sorted by field name (except private static + * and private transient fields): + * 1. The name of the field in UTF encoding. + * 2. The modifiers of the field written as a 32-bit integer. + * 3. The descriptor of the field in UTF encoding + * 5. If a class initializer exists, write out the following: + * 1. The name of the method, <clinit>, in UTF encoding. + * 2. The modifier of the method, java.lang.reflect.Modifier.STATIC, + * written as a 32-bit integer. + * 3. The descriptor of the method, ()V, in UTF encoding. + * 6. For each non-private constructor sorted by method name and signature: + * 1. The name of the method, <init>, in UTF encoding. + * 2. The modifiers of the method written as a 32-bit integer. + * 3. The descriptor of the method in UTF encoding. + * 7. For each non-private method sorted by method name and signature: + * 1. The name of the method in UTF encoding. + * 2. The modifiers of the method written as a 32-bit integer. + * 3. The descriptor of the method in UTF encoding. + * 8. The SHA-1 algorithm is executed on the stream of bytes produced by + * DataOutputStream and produces five 32-bit values sha[0..4]. + * + * 9. The hash value is assembled from the first and second 32-bit values of + * the SHA-1 message digest. If the result of the message digest, the five + * 32-bit words H0 H1 H2 H3 H4, is in an array of five int values named + * sha, the hash value would be computed as follows: + * + * long hash = ((sha[0] >>> 24) & 0xFF) | + * ((sha[0] >>> 16) & 0xFF) << 8 | + * ((sha[0] >>> 8) & 0xFF) << 16 | + * ((sha[0] >>> 0) & 0xFF) << 24 | + * ((sha[1] >>> 24) & 0xFF) << 32 | + * ((sha[1] >>> 16) & 0xFF) << 40 | + * ((sha[1] >>> 8) & 0xFF) << 48 | + * ((sha[1] >>> 0) & 0xFF) << 56; + * </pre> + * + * @author Rajendra Inamdar, Vishal Vishnoi + */ +public class SerialVersionUIDAdder extends ClassVisitor { + + /** + * Flag that indicates if we need to compute SVUID. + */ + private boolean computeSVUID; + + /** + * Set to true if the class already has SVUID. + */ + private boolean hasSVUID; + + /** + * Classes access flags. + */ + private int access; + + /** + * Internal name of the class + */ + private String name; + + /** + * Interfaces implemented by the class. + */ + private String[] interfaces; + + /** + * Collection of fields. (except private static and private transient + * fields) + */ + private Collection<Item> svuidFields; + + /** + * Set to true if the class has static initializer. + */ + private boolean hasStaticInitializer; + + /** + * Collection of non-private constructors. + */ + private Collection<Item> svuidConstructors; + + /** + * Collection of non-private methods. + */ + private Collection<Item> svuidMethods; + + /** + * Creates a new {@link SerialVersionUIDAdder}. <i>Subclasses must not use + * this constructor</i>. Instead, they must use the + * {@link #SerialVersionUIDAdder(int, ClassVisitor)} version. + * + * @param cv + * a {@link ClassVisitor} to which this visitor will delegate + * calls. + */ + public SerialVersionUIDAdder(final ClassVisitor cv) { + this(Opcodes.ASM4, cv); + } + + /** + * Creates a new {@link SerialVersionUIDAdder}. + * + * @param api + * the ASM API version implemented by this visitor. Must be one + * of {@link Opcodes#ASM4}. + * @param cv + * a {@link ClassVisitor} to which this visitor will delegate + * calls. + */ + protected SerialVersionUIDAdder(final int api, final ClassVisitor cv) { + super(api, cv); + svuidFields = new ArrayList<Item>(); + svuidConstructors = new ArrayList<Item>(); + svuidMethods = new ArrayList<Item>(); + } + + // ------------------------------------------------------------------------ + // Overriden methods + // ------------------------------------------------------------------------ + + /* + * Visit class header and get class name, access , and interfaces + * information (step 1,2, and 3) for SVUID computation. + */ + @Override + public void visit(final int version, final int access, final String name, + final String signature, final String superName, + final String[] interfaces) { + computeSVUID = (access & Opcodes.ACC_INTERFACE) == 0; + + if (computeSVUID) { + this.name = name; + this.access = access; + this.interfaces = interfaces; + } + + super.visit(version, access, name, signature, superName, interfaces); + } + + /* + * Visit the methods and get constructor and method information (step 5 and + * 7). Also determine if there is a class initializer (step 6). + */ + @Override + public MethodVisitor visitMethod(final int access, final String name, + final String desc, final String signature, final String[] exceptions) { + if (computeSVUID) { + if ("<clinit>".equals(name)) { + hasStaticInitializer = true; + } + /* + * Remembers non private constructors and methods for SVUID + * computation For constructor and method modifiers, only the + * ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL, + * ACC_SYNCHRONIZED, ACC_NATIVE, ACC_ABSTRACT and ACC_STRICT flags + * are used. + */ + int mods = access + & (Opcodes.ACC_PUBLIC | Opcodes.ACC_PRIVATE + | Opcodes.ACC_PROTECTED | Opcodes.ACC_STATIC + | Opcodes.ACC_FINAL | Opcodes.ACC_SYNCHRONIZED + | Opcodes.ACC_NATIVE | Opcodes.ACC_ABSTRACT | Opcodes.ACC_STRICT); + + // all non private methods + if ((access & Opcodes.ACC_PRIVATE) == 0) { + if ("<init>".equals(name)) { + svuidConstructors.add(new Item(name, mods, desc)); + } else if (!"<clinit>".equals(name)) { + svuidMethods.add(new Item(name, mods, desc)); + } + } + } + + return super.visitMethod(access, name, desc, signature, exceptions); + } + + /* + * Gets class field information for step 4 of the algorithm. Also determines + * if the class already has a SVUID. + */ + @Override + public FieldVisitor visitField(final int access, final String name, + final String desc, final String signature, final Object value) { + if (computeSVUID) { + if ("serialVersionUID".equals(name)) { + // since the class already has SVUID, we won't be computing it. + computeSVUID = false; + hasSVUID = true; + } + /* + * Remember field for SVUID computation For field modifiers, only + * the ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, + * ACC_FINAL, ACC_VOLATILE, and ACC_TRANSIENT flags are used when + * computing serialVersionUID values. + */ + if ((access & Opcodes.ACC_PRIVATE) == 0 + || (access & (Opcodes.ACC_STATIC | Opcodes.ACC_TRANSIENT)) == 0) { + int mods = access + & (Opcodes.ACC_PUBLIC | Opcodes.ACC_PRIVATE + | Opcodes.ACC_PROTECTED | Opcodes.ACC_STATIC + | Opcodes.ACC_FINAL | Opcodes.ACC_VOLATILE | Opcodes.ACC_TRANSIENT); + svuidFields.add(new Item(name, mods, desc)); + } + } + + return super.visitField(access, name, desc, signature, value); + } + + /** + * Handle a bizarre special case. Nested classes (static classes declared + * inside another class) that are protected have their access bit set to + * public in their class files to deal with some odd reflection situation. + * Our SVUID computation must do as the JVM does and ignore access bits in + * the class file in favor of the access bits InnerClass attribute. + */ + @Override + public void visitInnerClass(final String aname, final String outerName, + final String innerName, final int attr_access) { + if ((name != null) && name.equals(aname)) { + this.access = attr_access; + } + super.visitInnerClass(aname, outerName, innerName, attr_access); + } + + /* + * Add the SVUID if class doesn't have one + */ + @Override + public void visitEnd() { + // compute SVUID and add it to the class + if (computeSVUID && !hasSVUID) { + try { + addSVUID(computeSVUID()); + } catch (Throwable e) { + throw new RuntimeException("Error while computing SVUID for " + + name, e); + } + } + + super.visitEnd(); + } + + // ------------------------------------------------------------------------ + // Utility methods + // ------------------------------------------------------------------------ + + /** + * Returns true if the class already has a SVUID field. The result of this + * method is only valid when visitEnd is or has been called. + * + * @return true if the class already has a SVUID field. + */ + public boolean hasSVUID() { + return hasSVUID; + } + + protected void addSVUID(long svuid) { + FieldVisitor fv = super.visitField(Opcodes.ACC_FINAL + + Opcodes.ACC_STATIC, "serialVersionUID", "J", null, new Long( + svuid)); + if (fv != null) { + fv.visitEnd(); + } + } + + /** + * Computes and returns the value of SVUID. + * + * @return Returns the serial version UID + * @throws IOException + * if an I/O error occurs + */ + protected long computeSVUID() throws IOException { + ByteArrayOutputStream bos; + DataOutputStream dos = null; + long svuid = 0; + + try { + bos = new ByteArrayOutputStream(); + dos = new DataOutputStream(bos); + + /* + * 1. The class name written using UTF encoding. + */ + dos.writeUTF(name.replace('/', '.')); + + /* + * 2. The class modifiers written as a 32-bit integer. + */ + dos.writeInt(access + & (Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL + | Opcodes.ACC_INTERFACE | Opcodes.ACC_ABSTRACT)); + + /* + * 3. The name of each interface sorted by name written using UTF + * encoding. + */ + Arrays.sort(interfaces); + for (int i = 0; i < interfaces.length; i++) { + dos.writeUTF(interfaces[i].replace('/', '.')); + } + + /* + * 4. For each field of the class sorted by field name (except + * private static and private transient fields): + * + * 1. The name of the field in UTF encoding. 2. The modifiers of the + * field written as a 32-bit integer. 3. The descriptor of the field + * in UTF encoding + * + * Note that field signatures are not dot separated. Method and + * constructor signatures are dot separated. Go figure... + */ + writeItems(svuidFields, dos, false); + + /* + * 5. If a class initializer exists, write out the following: 1. The + * name of the method, <clinit>, in UTF encoding. 2. The modifier of + * the method, java.lang.reflect.Modifier.STATIC, written as a + * 32-bit integer. 3. The descriptor of the method, ()V, in UTF + * encoding. + */ + if (hasStaticInitializer) { + dos.writeUTF("<clinit>"); + dos.writeInt(Opcodes.ACC_STATIC); + dos.writeUTF("()V"); + } // if.. + + /* + * 6. For each non-private constructor sorted by method name and + * signature: 1. The name of the method, <init>, in UTF encoding. 2. + * The modifiers of the method written as a 32-bit integer. 3. The + * descriptor of the method in UTF encoding. + */ + writeItems(svuidConstructors, dos, true); + + /* + * 7. For each non-private method sorted by method name and + * signature: 1. The name of the method in UTF encoding. 2. The + * modifiers of the method written as a 32-bit integer. 3. The + * descriptor of the method in UTF encoding. + */ + writeItems(svuidMethods, dos, true); + + dos.flush(); + + /* + * 8. The SHA-1 algorithm is executed on the stream of bytes + * produced by DataOutputStream and produces five 32-bit values + * sha[0..4]. + */ + byte[] hashBytes = computeSHAdigest(bos.toByteArray()); + + /* + * 9. The hash value is assembled from the first and second 32-bit + * values of the SHA-1 message digest. If the result of the message + * digest, the five 32-bit words H0 H1 H2 H3 H4, is in an array of + * five int values named sha, the hash value would be computed as + * follows: + * + * long hash = ((sha[0] >>> 24) & 0xFF) | ((sha[0] >>> 16) & 0xFF) + * << 8 | ((sha[0] >>> 8) & 0xFF) << 16 | ((sha[0] >>> 0) & 0xFF) << + * 24 | ((sha[1] >>> 24) & 0xFF) << 32 | ((sha[1] >>> 16) & 0xFF) << + * 40 | ((sha[1] >>> 8) & 0xFF) << 48 | ((sha[1] >>> 0) & 0xFF) << + * 56; + */ + for (int i = Math.min(hashBytes.length, 8) - 1; i >= 0; i--) { + svuid = (svuid << 8) | (hashBytes[i] & 0xFF); + } + } finally { + // close the stream (if open) + if (dos != null) { + dos.close(); + } + } + + return svuid; + } + + /** + * Returns the SHA-1 message digest of the given value. + * + * @param value + * the value whose SHA message digest must be computed. + * @return the SHA-1 message digest of the given value. + */ + protected byte[] computeSHAdigest(final byte[] value) { + try { + return MessageDigest.getInstance("SHA").digest(value); + } catch (Exception e) { + throw new UnsupportedOperationException(e.toString()); + } + } + + /** + * Sorts the items in the collection and writes it to the data output stream + * + * @param itemCollection + * collection of items + * @param dos + * a <code>DataOutputStream</code> value + * @param dotted + * a <code>boolean</code> value + * @exception IOException + * if an error occurs + */ + private static void writeItems(final Collection<Item> itemCollection, + final DataOutput dos, final boolean dotted) throws IOException { + int size = itemCollection.size(); + Item[] items = itemCollection.toArray(new Item[size]); + Arrays.sort(items); + for (int i = 0; i < size; i++) { + dos.writeUTF(items[i].name); + dos.writeInt(items[i].access); + dos.writeUTF(dotted ? items[i].desc.replace('/', '.') + : items[i].desc); + } + } + + // ------------------------------------------------------------------------ + // Inner classes + // ------------------------------------------------------------------------ + + private static class Item implements Comparable<Item> { + + final String name; + + final int access; + + final String desc; + + Item(final String name, final int access, final String desc) { + this.name = name; + this.access = access; + this.desc = desc; + } + + public int compareTo(final Item other) { + int retVal = name.compareTo(other.name); + if (retVal == 0) { + retVal = desc.compareTo(other.desc); + } + return retVal; + } + + @Override + public boolean equals(final Object o) { + if (o instanceof Item) { + return compareTo((Item) o) == 0; + } + return false; + } + + @Override + public int hashCode() { + return (name + desc).hashCode(); + } + } +} http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/commons/SimpleRemapper.java ---------------------------------------------------------------------- diff --git a/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/commons/SimpleRemapper.java b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/commons/SimpleRemapper.java new file mode 100644 index 0000000..32d1d81 --- /dev/null +++ b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/commons/SimpleRemapper.java @@ -0,0 +1,69 @@ +/*** + * 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.commons; + +import java.util.Collections; +import java.util.Map; + +/** + * A {@link Remapper} using a {@link Map} to define its mapping. + * + * @author Eugene Kuleshov + */ +public class SimpleRemapper extends Remapper { + + private final Map<String, String> mapping; + + public SimpleRemapper(Map<String, String> mapping) { + this.mapping = mapping; + } + + public SimpleRemapper(String oldName, String newName) { + this.mapping = Collections.singletonMap(oldName, newName); + } + + @Override + public String mapMethodName(String owner, String name, String desc) { + String s = map(owner + '.' + name + desc); + return s == null ? name : s; + } + + @Override + public String mapFieldName(String owner, String name, String desc) { + String s = map(owner + '.' + name); + return s == null ? name : s; + } + + @Override + public String map(String key) { + return mapping.get(key); + } +} http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/commons/StaticInitMerger.java ---------------------------------------------------------------------- diff --git a/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/commons/StaticInitMerger.java b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/commons/StaticInitMerger.java new file mode 100644 index 0000000..886a799 --- /dev/null +++ b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/commons/StaticInitMerger.java @@ -0,0 +1,96 @@ +/*** + * 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.commons; + +import org.apache.tajo.org.objectweb.asm.ClassVisitor; +import org.apache.tajo.org.objectweb.asm.MethodVisitor; +import org.apache.tajo.org.objectweb.asm.Opcodes; + +/** + * A {@link ClassVisitor} that merges clinit methods into a single one. + * + * @author Eric Bruneton + */ +public class StaticInitMerger extends ClassVisitor { + + private String name; + + private MethodVisitor clinit; + + private final String prefix; + + private int counter; + + public StaticInitMerger(final String prefix, final ClassVisitor cv) { + this(Opcodes.ASM4, prefix, cv); + } + + protected StaticInitMerger(final int api, final String prefix, + final ClassVisitor cv) { + super(api, cv); + this.prefix = prefix; + } + + @Override + public void visit(final int version, final int access, final String name, + final String signature, final String superName, + final String[] interfaces) { + cv.visit(version, access, name, signature, superName, interfaces); + this.name = name; + } + + @Override + public MethodVisitor visitMethod(final int access, final String name, + final String desc, final String signature, final String[] exceptions) { + MethodVisitor mv; + if ("<clinit>".equals(name)) { + int a = Opcodes.ACC_PRIVATE + Opcodes.ACC_STATIC; + String n = prefix + counter++; + mv = cv.visitMethod(a, n, desc, signature, exceptions); + + if (clinit == null) { + clinit = cv.visitMethod(a, name, desc, null, null); + } + clinit.visitMethodInsn(Opcodes.INVOKESTATIC, this.name, n, desc); + } else { + mv = cv.visitMethod(access, name, desc, signature, exceptions); + } + return mv; + } + + @Override + public void visitEnd() { + if (clinit != null) { + clinit.visitInsn(Opcodes.RETURN); + clinit.visitMaxs(0, 0); + } + cv.visitEnd(); + } +} http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/commons/TableSwitchGenerator.java ---------------------------------------------------------------------- diff --git a/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/commons/TableSwitchGenerator.java b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/commons/TableSwitchGenerator.java new file mode 100644 index 0000000..6e71d8d --- /dev/null +++ b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/commons/TableSwitchGenerator.java @@ -0,0 +1,57 @@ +/*** + * 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.commons; + +import org.apache.tajo.org.objectweb.asm.Label; + +/** + * A code generator for switch statements. + * + * @author Juozas Baliuka + * @author Chris Nokleberg + * @author Eric Bruneton + */ +public interface TableSwitchGenerator { + + /** + * Generates the code for a switch case. + * + * @param key + * the switch case key. + * @param end + * a label that corresponds to the end of the switch statement. + */ + void generateCase(int key, Label end); + + /** + * Generates the code for the default switch case. + */ + void generateDefault(); +} http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/commons/TryCatchBlockSorter.java ---------------------------------------------------------------------- diff --git a/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/commons/TryCatchBlockSorter.java b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/commons/TryCatchBlockSorter.java new file mode 100644 index 0000000..54924e4 --- /dev/null +++ b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/commons/TryCatchBlockSorter.java @@ -0,0 +1,92 @@ +/*** + * 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.commons; + +import java.util.Collections; +import java.util.Comparator; + +import org.apache.tajo.org.objectweb.asm.MethodVisitor; +import org.apache.tajo.org.objectweb.asm.Opcodes; +import org.apache.tajo.org.objectweb.asm.tree.MethodNode; +import org.apache.tajo.org.objectweb.asm.tree.TryCatchBlockNode; + +/** + * A {@link MethodVisitor} adapter to sort the exception handlers. The handlers + * are sorted in a method innermost-to-outermost. This allows the programmer to + * add handlers without worrying about ordering them correctly with respect to + * existing, in-code handlers. + * + * Behavior is only defined for properly-nested handlers. If any "try" blocks + * overlap (something that isn't possible in Java code) then this may not do + * what you want. In fact, this adapter just sorts by the length of the "try" + * block, taking advantage of the fact that a given try block must be larger + * than any block it contains). + * + * @author Adrian Sampson + */ +public class TryCatchBlockSorter extends MethodNode { + + public TryCatchBlockSorter(final MethodVisitor mv, final int access, + final String name, final String desc, final String signature, + final String[] exceptions) { + this(Opcodes.ASM4, mv, access, name, desc, signature, exceptions); + } + + protected TryCatchBlockSorter(final int api, final MethodVisitor mv, + final int access, final String name, final String desc, + final String signature, final String[] exceptions) { + super(api, access, name, desc, signature, exceptions); + this.mv = mv; + } + + @Override + public void visitEnd() { + // Compares TryCatchBlockNodes by the length of their "try" block. + Comparator<TryCatchBlockNode> comp = new Comparator<TryCatchBlockNode>() { + + public int compare(TryCatchBlockNode t1, TryCatchBlockNode t2) { + int len1 = blockLength(t1); + int len2 = blockLength(t2); + return len1 - len2; + } + + private int blockLength(TryCatchBlockNode block) { + int startidx = instructions.indexOf(block.start); + int endidx = instructions.indexOf(block.end); + return endidx - startidx; + } + }; + Collections.sort(tryCatchBlocks, comp); + if (mv != null) { + accept(mv); + } + } +} http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/commons/package.html ---------------------------------------------------------------------- diff --git a/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/commons/package.html b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/commons/package.html new file mode 100644 index 0000000..28b7cc2 --- /dev/null +++ b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/commons/package.html @@ -0,0 +1,66 @@ +<!--~ + ~ 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> +Provides some useful class and method adapters. <i>The preferred way of using +these adapters is by chaining them together and to custom adapters (instead of +inheriting from them)</i>. Indeed this approach provides more combination +possibilities than inheritance. For instance, suppose you want to implement an +adapter MyAdapter than needs sorted local variables and intermediate stack map +frame values taking into account the local variables sort. By using inheritance, +this would require MyAdapter to extend AnalyzerAdapter, itself extending +LocalVariablesSorter. But AnalyzerAdapter is not a subclass of +LocalVariablesSorter, so this is not possible. On the contrary, by using +delegation, you can make LocalVariablesSorter delegate to AnalyzerAdapter, +itself delegating to MyAdapter. In this case AnalyzerAdapter computes +intermediate frames based on the output of LocalVariablesSorter, and MyAdapter +can add new locals by calling the newLocal method on LocalVariablesSorter, and +can get the stack map frame state before each instruction by reading the locals +and stack fields in AnalyzerAdapter (this requires references from MyAdapter +back to LocalVariablesSorter and AnalyzerAdapter). +</body> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/optimizer/AnnotationConstantsCollector.java ---------------------------------------------------------------------- diff --git a/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/optimizer/AnnotationConstantsCollector.java b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/optimizer/AnnotationConstantsCollector.java new file mode 100644 index 0000000..8bb50f9 --- /dev/null +++ b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/optimizer/AnnotationConstantsCollector.java @@ -0,0 +1,147 @@ +/*** + * 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.optimizer; + +import org.apache.tajo.org.objectweb.asm.AnnotationVisitor; +import org.apache.tajo.org.objectweb.asm.Type; +import org.apache.tajo.org.objectweb.asm.Opcodes; + +/** + * An {@link org.apache.tajo.org.objectweb.asm.AnnotationVisitor} that collects the {@link Constant}s of the + * annotations it visits. + * + * @author Eric Bruneton + */ +public class AnnotationConstantsCollector extends AnnotationVisitor { + + private final ConstantPool cp; + + public AnnotationConstantsCollector(final AnnotationVisitor av, + final ConstantPool cp) { + super(Opcodes.ASM4, av); + this.cp = cp; + } + + @Override + public void visit(final String name, final Object value) { + if (name != null) { + cp.newUTF8(name); + } + if (value instanceof Byte) { + cp.newInteger(((Byte) value).byteValue()); + } else if (value instanceof Boolean) { + cp.newInteger(((Boolean) value).booleanValue() ? 1 : 0); + } else if (value instanceof Character) { + cp.newInteger(((Character) value).charValue()); + } else if (value instanceof Short) { + cp.newInteger(((Short) value).shortValue()); + } else if (value instanceof Type) { + cp.newUTF8(((Type) value).getDescriptor()); + } else if (value instanceof byte[]) { + byte[] v = (byte[]) value; + for (int i = 0; i < v.length; i++) { + cp.newInteger(v[i]); + } + } else if (value instanceof boolean[]) { + boolean[] v = (boolean[]) value; + for (int i = 0; i < v.length; i++) { + cp.newInteger(v[i] ? 1 : 0); + } + } else if (value instanceof short[]) { + short[] v = (short[]) value; + for (int i = 0; i < v.length; i++) { + cp.newInteger(v[i]); + } + } else if (value instanceof char[]) { + char[] v = (char[]) value; + for (int i = 0; i < v.length; i++) { + cp.newInteger(v[i]); + } + } else if (value instanceof int[]) { + int[] v = (int[]) value; + for (int i = 0; i < v.length; i++) { + cp.newInteger(v[i]); + } + } else if (value instanceof long[]) { + long[] v = (long[]) value; + for (int i = 0; i < v.length; i++) { + cp.newLong(v[i]); + } + } else if (value instanceof float[]) { + float[] v = (float[]) value; + for (int i = 0; i < v.length; i++) { + cp.newFloat(v[i]); + } + } else if (value instanceof double[]) { + double[] v = (double[]) value; + for (int i = 0; i < v.length; i++) { + cp.newDouble(v[i]); + } + } else { + cp.newConst(value); + } + av.visit(name, value); + } + + @Override + public void visitEnum(final String name, final String desc, + final String value) { + if (name != null) { + cp.newUTF8(name); + } + cp.newUTF8(desc); + cp.newUTF8(value); + av.visitEnum(name, desc, value); + } + + @Override + public AnnotationVisitor visitAnnotation(final String name, + final String desc) { + if (name != null) { + cp.newUTF8(name); + } + cp.newUTF8(desc); + return new AnnotationConstantsCollector(av.visitAnnotation(name, desc), + cp); + } + + @Override + public AnnotationVisitor visitArray(final String name) { + if (name != null) { + cp.newUTF8(name); + } + return new AnnotationConstantsCollector(av.visitArray(name), cp); + } + + @Override + public void visitEnd() { + av.visitEnd(); + } +} http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/optimizer/ClassConstantsCollector.java ---------------------------------------------------------------------- diff --git a/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/optimizer/ClassConstantsCollector.java b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/optimizer/ClassConstantsCollector.java new file mode 100644 index 0000000..aeee5a7 --- /dev/null +++ b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/optimizer/ClassConstantsCollector.java @@ -0,0 +1,184 @@ +/*** + * 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.optimizer; + +import org.apache.tajo.org.objectweb.asm.AnnotationVisitor; +import org.apache.tajo.org.objectweb.asm.Attribute; +import org.apache.tajo.org.objectweb.asm.ClassVisitor; +import org.apache.tajo.org.objectweb.asm.FieldVisitor; +import org.apache.tajo.org.objectweb.asm.MethodVisitor; +import org.apache.tajo.org.objectweb.asm.Opcodes; + +/** + * A {@link ClassVisitor} that collects the {@link Constant}s of the classes it + * visits. + * + * @author Eric Bruneton + */ +public class ClassConstantsCollector extends ClassVisitor { + + private final ConstantPool cp; + + public ClassConstantsCollector(final ClassVisitor cv, final ConstantPool cp) { + super(Opcodes.ASM4, cv); + this.cp = cp; + } + + @Override + public void visit(final int version, final int access, final String name, + final String signature, final String superName, + final String[] interfaces) { + if ((access & Opcodes.ACC_DEPRECATED) != 0) { + cp.newUTF8("Deprecated"); + } + if ((access & Opcodes.ACC_SYNTHETIC) != 0) { + cp.newUTF8("Synthetic"); + } + cp.newClass(name); + if (signature != null) { + cp.newUTF8("Signature"); + cp.newUTF8(signature); + } + if (superName != null) { + cp.newClass(superName); + } + if (interfaces != null) { + for (int i = 0; i < interfaces.length; ++i) { + cp.newClass(interfaces[i]); + } + } + cv.visit(version, access, name, signature, superName, interfaces); + } + + @Override + public void visitSource(final String source, final String debug) { + if (source != null) { + cp.newUTF8("SourceFile"); + cp.newUTF8(source); + } + if (debug != null) { + cp.newUTF8("SourceDebugExtension"); + } + cv.visitSource(source, debug); + } + + @Override + public void visitOuterClass(final String owner, final String name, + final String desc) { + cp.newUTF8("EnclosingMethod"); + cp.newClass(owner); + if (name != null && desc != null) { + cp.newNameType(name, desc); + } + cv.visitOuterClass(owner, name, desc); + } + + @Override + public AnnotationVisitor visitAnnotation(final String desc, + final boolean visible) { + cp.newUTF8(desc); + if (visible) { + cp.newUTF8("RuntimeVisibleAnnotations"); + } else { + cp.newUTF8("RuntimeInvisibleAnnotations"); + } + return new AnnotationConstantsCollector(cv.visitAnnotation(desc, + visible), cp); + } + + @Override + public void visitAttribute(final Attribute attr) { + // can do nothing + cv.visitAttribute(attr); + } + + @Override + public void visitInnerClass(final String name, final String outerName, + final String innerName, final int access) { + cp.newUTF8("InnerClasses"); + if (name != null) { + cp.newClass(name); + } + if (outerName != null) { + cp.newClass(outerName); + } + if (innerName != null) { + cp.newUTF8(innerName); + } + cv.visitInnerClass(name, outerName, innerName, access); + } + + @Override + public FieldVisitor visitField(final int access, final String name, + final String desc, final String signature, final Object value) { + if ((access & Opcodes.ACC_SYNTHETIC) != 0) { + cp.newUTF8("Synthetic"); + } + if ((access & Opcodes.ACC_DEPRECATED) != 0) { + cp.newUTF8("Deprecated"); + } + cp.newUTF8(name); + cp.newUTF8(desc); + if (signature != null) { + cp.newUTF8("Signature"); + cp.newUTF8(signature); + } + if (value != null) { + cp.newConst(value); + } + return new FieldConstantsCollector(cv.visitField(access, name, desc, + signature, value), cp); + } + + @Override + public MethodVisitor visitMethod(final int access, final String name, + final String desc, final String signature, final String[] exceptions) { + if ((access & Opcodes.ACC_SYNTHETIC) != 0) { + cp.newUTF8("Synthetic"); + } + if ((access & Opcodes.ACC_DEPRECATED) != 0) { + cp.newUTF8("Deprecated"); + } + cp.newUTF8(name); + cp.newUTF8(desc); + if (signature != null) { + cp.newUTF8("Signature"); + cp.newUTF8(signature); + } + if (exceptions != null) { + cp.newUTF8("Exceptions"); + for (int i = 0; i < exceptions.length; ++i) { + cp.newClass(exceptions[i]); + } + } + return new MethodConstantsCollector(cv.visitMethod(access, name, desc, + signature, exceptions), cp); + } +} http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/optimizer/ClassOptimizer.java ---------------------------------------------------------------------- diff --git a/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/optimizer/ClassOptimizer.java b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/optimizer/ClassOptimizer.java new file mode 100644 index 0000000..56d97f9 --- /dev/null +++ b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/optimizer/ClassOptimizer.java @@ -0,0 +1,167 @@ +/*** + * 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.optimizer; + +import org.apache.tajo.org.objectweb.asm.AnnotationVisitor; +import org.apache.tajo.org.objectweb.asm.Attribute; +import org.apache.tajo.org.objectweb.asm.ClassVisitor; +import org.apache.tajo.org.objectweb.asm.FieldVisitor; +import org.apache.tajo.org.objectweb.asm.MethodVisitor; +import org.apache.tajo.org.objectweb.asm.Opcodes; +import org.apache.tajo.org.objectweb.asm.commons.Remapper; +import org.apache.tajo.org.objectweb.asm.commons.RemappingClassAdapter; + +/** + * A {@link ClassVisitor} that renames fields and methods, and removes debug + * info. + * + * @author Eric Bruneton + * @author Eugene Kuleshov + */ +public class ClassOptimizer extends RemappingClassAdapter { + + private String pkgName; + String clsName; + boolean class$; + + public ClassOptimizer(final ClassVisitor cv, final Remapper remapper) { + super(cv, remapper); + } + + FieldVisitor syntheticFieldVisitor(final int access, final String name, + final String desc) { + return super.visitField(access, name, desc, null, null); + } + + // ------------------------------------------------------------------------ + // Overridden methods + // ------------------------------------------------------------------------ + + @Override + public void visit(final int version, final int access, final String name, + final String signature, final String superName, + final String[] interfaces) { + super.visit(Opcodes.V1_2, access, name, null, superName, interfaces); + clsName = name; + int index = name.lastIndexOf('/'); + if (index > 0) { + pkgName = name.substring(0, index); + } else { + pkgName = ""; + } + } + + @Override + public void visitSource(final String source, final String debug) { + // remove debug info + } + + @Override + public void visitOuterClass(final String owner, final String name, + final String desc) { + // remove debug info + } + + @Override + public AnnotationVisitor visitAnnotation(final String desc, + final boolean visible) { + // remove annotations + return null; + } + + @Override + public void visitAttribute(final Attribute attr) { + // remove non standard attributes + } + + @Override + public void visitInnerClass(final String name, final String outerName, + final String innerName, final int access) { + // remove debug info + } + + @Override + public FieldVisitor visitField(final int access, final String name, + final String desc, final String signature, final Object value) { + String s = remapper.mapFieldName(className, name, desc); + if ("-".equals(s)) { + return null; + } + if ((access & (Opcodes.ACC_PUBLIC | Opcodes.ACC_PROTECTED)) == 0) { + if ((access & Opcodes.ACC_FINAL) != 0 + && (access & Opcodes.ACC_STATIC) != 0 && desc.length() == 1) { + return null; + } + if ("org/apache/tajo/org/objectweb".equals(pkgName) && s.equals(name)) { + System.out.println("INFO: " + clsName + "." + s + + " could be renamed"); + } + super.visitField(access, name, desc, null, value); + } else { + if (!s.equals(name)) { + throw new RuntimeException("The public or protected field " + + className + '.' + name + " must not be renamed."); + } + super.visitField(access, name, desc, null, value); + } + return null; // remove debug info + } + + @Override + public MethodVisitor visitMethod(final int access, final String name, + final String desc, final String signature, final String[] exceptions) { + String s = remapper.mapMethodName(className, name, desc); + if ("-".equals(s)) { + return null; + } + + if ((access & (Opcodes.ACC_PUBLIC | Opcodes.ACC_PROTECTED)) == 0) { + if ("org/apache/tajo/org/objectweb".equals(pkgName) && !name.startsWith("<") + && s.equals(name)) { + System.out.println("INFO: " + clsName + "." + s + + " could be renamed"); + } + return super.visitMethod(access, name, desc, null, exceptions); + } else { + if (!s.equals(name)) { + throw new RuntimeException("The public or protected method " + + className + '.' + name + desc + + " must not be renamed."); + } + return super.visitMethod(access, name, desc, null, exceptions); + } + } + + @Override + protected MethodVisitor createRemappingMethodAdapter(int access, + String newDesc, MethodVisitor mv) { + return new MethodOptimizer(this, access, newDesc, mv, remapper); + } +} http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/optimizer/Constant.java ---------------------------------------------------------------------- diff --git a/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/optimizer/Constant.java b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/optimizer/Constant.java new file mode 100644 index 0000000..11b9390 --- /dev/null +++ b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/optimizer/Constant.java @@ -0,0 +1,323 @@ +/*** + * 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.optimizer; + +import java.util.Arrays; + +import org.apache.tajo.org.objectweb.asm.ClassWriter; +import org.apache.tajo.org.objectweb.asm.Handle; + +/** + * A constant pool item. + * + * @author Eric Bruneton + */ +class Constant { + + /** + * 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 I, J, F, D, S, s, C, T, G, M, N, y, + * t, [h..p] (for Constant Integer, Long, Float, Double, STR, UTF8, Class, + * NameType, Fieldref, Methodref, InterfaceMethodref, InvokeDynamic, + * MethodType and MethodHandle constant pool items respectively). + * + * The 9 variable of MethodHandle constants are stored between h and p. + */ + char type; + + /** + * Value of this item, for an integer item. + */ + int intVal; + + /** + * Value of this item, for a long item. + */ + long longVal; + + /** + * Value of this item, for a float item. + */ + float floatVal; + + /** + * Value of this item, for a double item. + */ + double doubleVal; + + /** + * 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. + */ + Object objVal3; + + /** + * InvokeDynamic's constant values. + */ + Object[] objVals; + + /** + * The hash code value of this constant pool item. + */ + int hashCode; + + Constant() { + } + + Constant(final Constant i) { + type = i.type; + intVal = i.intVal; + longVal = i.longVal; + floatVal = i.floatVal; + doubleVal = i.doubleVal; + strVal1 = i.strVal1; + strVal2 = i.strVal2; + objVal3 = i.objVal3; + objVals = i.objVals; + hashCode = i.hashCode; + } + + /** + * Sets this item to an integer item. + * + * @param intVal + * the value of this item. + */ + void set(final int intVal) { + this.type = 'I'; + 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 = 'J'; + 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 = 'F'; + this.floatVal = 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 = 'D'; + this.doubleVal = 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 char type, final String strVal1, final String strVal2, + final String strVal3) { + this.type = type; + this.strVal1 = strVal1; + this.strVal2 = strVal2; + this.objVal3 = strVal3; + switch (type) { + case 's': + case 'S': + case 'C': + case 't': + hashCode = 0x7FFFFFFF & (type + strVal1.hashCode()); + return; + case 'T': + hashCode = 0x7FFFFFFF & (type + strVal1.hashCode() + * strVal2.hashCode()); + return; + // case 'G': + // case 'M': + // case 'N': + // case 'h' ... 'p': + default: + hashCode = 0x7FFFFFFF & (type + strVal1.hashCode() + * strVal2.hashCode() * strVal3.hashCode()); + } + } + + /** + * Set this item to an InvokeDynamic item. + * + * @param name + * invokedynamic's name. + * @param desc + * invokedynamic's descriptor. + * @param bsm + * bootstrap method. + * @param bsmArgs + * bootstrap method constant arguments. + */ + void set(final String name, final String desc, final Handle bsm, + final Object[] bsmArgs) { + this.type = 'y'; + this.strVal1 = name; + this.strVal2 = desc; + this.objVal3 = bsm; + this.objVals = bsmArgs; + + int hashCode = 'y' + name.hashCode() * desc.hashCode() * bsm.hashCode(); + for (int i = 0; i < bsmArgs.length; i++) { + hashCode *= bsmArgs[i].hashCode(); + } + this.hashCode = 0x7FFFFFFF & hashCode; + } + + void write(final ClassWriter cw) { + switch (type) { + case 'I': + cw.newConst(new Integer(intVal)); + break; + case 'J': + cw.newConst(new Long(longVal)); + break; + case 'F': + cw.newConst(new Float(floatVal)); + break; + case 'D': + cw.newConst(new Double(doubleVal)); + break; + case 'S': + cw.newConst(strVal1); + break; + case 's': + cw.newUTF8(strVal1); + break; + case 'C': + cw.newClass(strVal1); + break; + case 'T': + cw.newNameType(strVal1, strVal2); + break; + case 'G': + cw.newField(strVal1, strVal2, (String) objVal3); + break; + case 'M': + cw.newMethod(strVal1, strVal2, (String) objVal3, false); + break; + case 'N': + cw.newMethod(strVal1, strVal2, (String) objVal3, true); + break; + case 'y': + cw.newInvokeDynamic(strVal1, strVal2, (Handle) objVal3, objVals); + break; + case 't': + cw.newMethodType(strVal1); + break; + default: // 'h' ... 'p': handle + cw.newHandle(type - 'h' + 1, strVal1, strVal2, (String) objVal3); + } + } + + @Override + public boolean equals(final Object o) { + if (!(o instanceof Constant)) { + return false; + } + Constant c = (Constant) o; + if (c.type == type) { + switch (type) { + case 'I': + return c.intVal == intVal; + case 'J': + return c.longVal == longVal; + case 'F': + return Float.compare(c.floatVal, floatVal) == 0; + case 'D': + return Double.compare(c.doubleVal, doubleVal) == 0; + case 's': + case 'S': + case 'C': + case 't': + return c.strVal1.equals(strVal1); + case 'T': + return c.strVal1.equals(strVal1) && c.strVal2.equals(strVal2); + case 'y': + return c.strVal1.equals(strVal1) && c.strVal2.equals(strVal2) + && c.objVal3.equals(objVal3) + && Arrays.equals(c.objVals, objVals); + // case 'G': + // case 'M': + // case 'N': + // case 'h' ... 'p': + default: + return c.strVal1.equals(strVal1) && c.strVal2.equals(strVal2) + && c.objVal3.equals(objVal3); + } + } + return false; + } + + @Override + public int hashCode() { + return hashCode; + } +} http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/optimizer/ConstantPool.java ---------------------------------------------------------------------- diff --git a/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/optimizer/ConstantPool.java b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/optimizer/ConstantPool.java new file mode 100644 index 0000000..e23487c --- /dev/null +++ b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/optimizer/ConstantPool.java @@ -0,0 +1,249 @@ +/*** + * 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.optimizer; + +import java.util.HashMap; + +import org.apache.tajo.org.objectweb.asm.Handle; +import org.apache.tajo.org.objectweb.asm.Opcodes; +import org.apache.tajo.org.objectweb.asm.Type; + +/** + * A constant pool. + * + * @author Eric Bruneton + */ +public class ConstantPool extends HashMap<Constant, Constant> { + + private final Constant key1 = new Constant(); + + private final Constant key2 = new Constant(); + + private final Constant key3 = new Constant(); + + private final Constant key4 = new Constant(); + + private final Constant key5 = new Constant(); + + public Constant newInteger(final int value) { + key1.set(value); + Constant result = get(key1); + if (result == null) { + result = new Constant(key1); + put(result); + } + return result; + } + + public Constant newFloat(final float value) { + key1.set(value); + Constant result = get(key1); + if (result == null) { + result = new Constant(key1); + put(result); + } + return result; + } + + public Constant newLong(final long value) { + key1.set(value); + Constant result = get(key1); + if (result == null) { + result = new Constant(key1); + put(result); + } + return result; + } + + public Constant newDouble(final double value) { + key1.set(value); + Constant result = get(key1); + if (result == null) { + result = new Constant(key1); + put(result); + } + return result; + } + + public Constant newUTF8(final String value) { + key1.set('s', value, null, null); + Constant result = get(key1); + if (result == null) { + result = new Constant(key1); + put(result); + } + return result; + } + + private Constant newString(final String value) { + key2.set('S', value, null, null); + Constant result = get(key2); + if (result == null) { + newUTF8(value); + result = new Constant(key2); + put(result); + } + return result; + } + + public Constant newClass(final String value) { + key2.set('C', value, null, null); + Constant result = get(key2); + if (result == null) { + newUTF8(value); + result = new Constant(key2); + put(result); + } + return result; + } + + public Constant newMethodType(final String methodDescriptor) { + key2.set('t', methodDescriptor, null, null); + Constant result = get(key2); + if (result == null) { + newUTF8(methodDescriptor); + result = new Constant(key2); + put(result); + } + return result; + } + + public Constant newHandle(final int tag, final String owner, + final String name, final String desc) { + key4.set((char) ('h' - 1 + tag), owner, name, desc); + Constant result = get(key4); + if (result == null) { + if (tag <= Opcodes.H_PUTSTATIC) { + newField(owner, name, desc); + } else { + newMethod(owner, name, desc, tag == Opcodes.H_INVOKEINTERFACE); + } + result = new Constant(key4); + put(result); + } + return result; + } + + public Constant newConst(final Object cst) { + if (cst instanceof Integer) { + int val = ((Integer) cst).intValue(); + return newInteger(val); + } else if (cst instanceof Float) { + float val = ((Float) cst).floatValue(); + return newFloat(val); + } else if (cst instanceof Long) { + long val = ((Long) cst).longValue(); + return newLong(val); + } else if (cst instanceof Double) { + double val = ((Double) cst).doubleValue(); + return newDouble(val); + } else if (cst instanceof String) { + return newString((String) cst); + } else if (cst instanceof Type) { + Type t = (Type) cst; + int s = t.getSort(); + if (s == Type.OBJECT) { + return newClass(t.getInternalName()); + } else if (s == Type.METHOD) { + return newMethodType(t.getDescriptor()); + } else { // s == primitive type or array + return newClass(t.getDescriptor()); + } + } else if (cst instanceof Handle) { + Handle h = (Handle) cst; + return newHandle(h.getTag(), h.getOwner(), h.getName(), h.getDesc()); + } else { + throw new IllegalArgumentException("value " + cst); + } + } + + public Constant newField(final String owner, final String name, + final String desc) { + key3.set('G', owner, name, desc); + Constant result = get(key3); + if (result == null) { + newClass(owner); + newNameType(name, desc); + result = new Constant(key3); + put(result); + } + return result; + } + + public Constant newMethod(final String owner, final String name, + final String desc, final boolean itf) { + key3.set(itf ? 'N' : 'M', owner, name, desc); + Constant result = get(key3); + if (result == null) { + newClass(owner); + newNameType(name, desc); + result = new Constant(key3); + put(result); + } + return result; + } + + public Constant newInvokeDynamic(String name, String desc, Handle bsm, + Object... bsmArgs) { + key5.set(name, desc, bsm, bsmArgs); + Constant result = get(key5); + if (result == null) { + newNameType(name, desc); + newHandle(bsm.getTag(), bsm.getOwner(), bsm.getName(), + bsm.getDesc()); + for (int i = 0; i < bsmArgs.length; i++) { + newConst(bsmArgs[i]); + } + result = new Constant(key5); + put(result); + } + return result; + } + + public Constant newNameType(final String name, final String desc) { + key2.set('T', name, desc, null); + Constant result = get(key2); + if (result == null) { + newUTF8(name); + newUTF8(desc); + result = new Constant(key2); + put(result); + } + return result; + } + + private Constant get(final Constant key) { + return get((Object) key); + } + + private void put(final Constant cst) { + put(cst, cst); + } +}
