| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,62 @@ | ||
| ; Copyright (c) Rich Hickey. All rights reserved. | ||
| ; The use and distribution terms for this software are covered by the | ||
| ; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) | ||
| ; which can be found in the file epl-v10.html at the root of this distribution. | ||
| ; By using this software in any fashion, you are agreeing to be bound by | ||
| ; the terms of this license. | ||
| ; You must not remove this notice, or any other, from this software. | ||
|
|
||
| (ns ^{:doc "Functions to turn objects into data. Alpha, subject to change"} | ||
| clojure.datafy | ||
| (:require [clojure.core.protocols :as p])) | ||
|
|
||
| (set! *warn-on-reflection* true) | ||
|
|
||
| (defn datafy | ||
| "Attempts to return x as data. | ||
| datafy will return the value of clojure.core.protocols/datafy. If | ||
| the value has been transformed and the result supports | ||
| metadata, :clojure.datafy/obj will be set on the metadata to the | ||
| original value of x, and :clojure.datafy/class to the name of the | ||
| class of x, as a symbol." | ||
| [x] | ||
| (let [v (p/datafy x)] | ||
| (if (identical? v x) | ||
| v | ||
| (if (instance? clojure.lang.IObj v) | ||
| (vary-meta v assoc ::obj x ::class (-> x class .getName symbol)) | ||
| v)))) | ||
|
|
||
| (defn nav | ||
| "Returns (possibly transformed) v in the context of coll and k (a | ||
| key/index or nil). Callers should attempt to provide the key/index | ||
| context k for Indexed/Associative/ILookup colls if possible, but not | ||
| to fabricate one e.g. for sequences (pass nil). nav returns the | ||
| value of clojure.core.protocols/nav." | ||
| [coll k v] | ||
| (p/nav coll k v)) | ||
|
|
||
| (defn- sortmap [m] | ||
| (into (sorted-map) m)) | ||
|
|
||
| (extend-protocol p/Datafiable | ||
| Throwable | ||
| (datafy [x] | ||
| (Throwable->map x)) | ||
|
|
||
| clojure.lang.IRef | ||
| (datafy [r] | ||
| (with-meta [(deref r)] (meta r))) | ||
|
|
||
| clojure.lang.Namespace | ||
| (datafy [n] | ||
| (with-meta {:name (.getName n) | ||
| :publics (-> n ns-publics sortmap) | ||
| :imports (-> n ns-imports sortmap) | ||
| :interns (-> n ns-interns sortmap)} | ||
| (meta n))) | ||
|
|
||
| java.lang.Class | ||
| (datafy [c] | ||
| (let [{:keys [members] :as ret} ((requiring-resolve 'clojure.reflect/reflect) c)] | ||
| (assoc ret :name (-> c .getName symbol) :members (->> members (group-by :name) sortmap))))) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,169 +1,150 @@ | ||
| // 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 clojure.asm; | ||
|
|
||
| /** | ||
| * A visitor to visit a Java annotation. The methods of this class must be called in the following | ||
| * order: ( <tt>visit</tt> | <tt>visitEnum</tt> | <tt>visitAnnotation</tt> | <tt>visitArray</tt> )* | ||
| * <tt>visitEnd</tt>. | ||
| * | ||
| * @author Eric Bruneton | ||
| * @author Eugene Kuleshov | ||
| */ | ||
| public abstract class AnnotationVisitor { | ||
|
|
||
| /** | ||
| * The ASM API version implemented by this visitor. The value of this field must be one of {@link | ||
| * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7_EXPERIMENTAL}. | ||
| */ | ||
| protected final int api; | ||
|
|
||
| /** The annotation visitor to which this visitor must delegate method calls. May be null. */ | ||
| protected AnnotationVisitor av; | ||
|
|
||
| /** | ||
| * Constructs a new {@link AnnotationVisitor}. | ||
| * | ||
| * @param api the ASM API version implemented by this visitor. Must be one of {@link | ||
| * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link | ||
| * Opcodes#ASM7_EXPERIMENTAL}. | ||
| */ | ||
| public AnnotationVisitor(final int api) { | ||
| this(api, null); | ||
| } | ||
|
|
||
| /** | ||
| * Constructs a new {@link AnnotationVisitor}. | ||
| * | ||
| * @param api the ASM API version implemented by this visitor. Must be one of {@link | ||
| * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link | ||
| * Opcodes#ASM7_EXPERIMENTAL}. | ||
| * @param annotationVisitor the annotation visitor to which this visitor must delegate method | ||
| * calls. May be null. | ||
| */ | ||
| public AnnotationVisitor(final int api, final AnnotationVisitor annotationVisitor) { | ||
| if (api != Opcodes.ASM6 | ||
| && api != Opcodes.ASM5 | ||
| && api != Opcodes.ASM4 | ||
| && api != Opcodes.ASM7_EXPERIMENTAL) { | ||
| throw new IllegalArgumentException(); | ||
| } | ||
| this.api = api; | ||
| this.av = annotationVisitor; | ||
| } | ||
|
|
||
| /** | ||
| * Visits a primitive value of the annotation. | ||
| * | ||
| * @param name the value name. | ||
| * @param value the actual value, whose type must be {@link Byte}, {@link Boolean}, {@link | ||
| * Character}, {@link Short}, {@link Integer} , {@link Long}, {@link Float}, {@link Double}, | ||
| * {@link String} or {@link Type} of {@link Type#OBJECT} or {@link Type#ARRAY} sort. This | ||
| * value can also be an array of byte, boolean, short, char, int, long, float or double values | ||
| * (this is equivalent to using {@link #visitArray} and visiting each array element in turn, | ||
| * but is more convenient). | ||
| */ | ||
| public void visit(final String name, final Object value) { | ||
| if (av != null) { | ||
| av.visit(name, value); | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Visits an enumeration value of the annotation. | ||
| * | ||
| * @param name the value name. | ||
| * @param descriptor the class descriptor of the enumeration class. | ||
| * @param value the actual enumeration value. | ||
| */ | ||
| public void visitEnum(final String name, final String descriptor, final String value) { | ||
| if (av != null) { | ||
| av.visitEnum(name, descriptor, value); | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Visits a nested annotation value of the annotation. | ||
| * | ||
| * @param name the value name. | ||
| * @param descriptor the class descriptor of the nested annotation class. | ||
| * @return a visitor to visit the actual nested annotation value, or <tt>null</tt> if this visitor | ||
| * is not interested in visiting this nested annotation. <i>The nested annotation value must | ||
| * be fully visited before calling other methods on this annotation visitor</i>. | ||
| */ | ||
| public AnnotationVisitor visitAnnotation(final String name, final String descriptor) { | ||
| if (av != null) { | ||
| return av.visitAnnotation(name, descriptor); | ||
| } | ||
| return null; | ||
| } | ||
|
|
||
| /** | ||
| * Visits an array value of the annotation. Note that arrays of primitive types (such as byte, | ||
| * boolean, short, char, int, long, float or double) can be passed as value to {@link #visit | ||
| * visit}. This is what {@link ClassReader} does. | ||
| * | ||
| * @param name the value name. | ||
| * @return a visitor to visit the actual array value elements, or <tt>null</tt> if this visitor is | ||
| * not interested in visiting these values. The 'name' parameters passed to the methods of | ||
| * this visitor are ignored. <i>All the array values must be visited before calling other | ||
| * methods on this annotation visitor</i>. | ||
| */ | ||
| public AnnotationVisitor visitArray(final String name) { | ||
| if (av != null) { | ||
| return av.visitArray(name); | ||
| } | ||
| return null; | ||
| } | ||
|
|
||
| /** Visits the end of the annotation. */ | ||
| public void visitEnd() { | ||
| if (av != null) { | ||
| av.visitEnd(); | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 clojure.asm; | ||
|
|
||
| import java.util.Arrays; | ||
|
|
||
| /** | ||
| * A constant whose value is computed at runtime, with a bootstrap method. | ||
| * | ||
| * @author Remi Forax | ||
| * @deprecated This API is experimental. | ||
| */ | ||
| @Deprecated | ||
| public final class ConstantDynamic { | ||
|
|
||
| /** The constant name (can be arbitrary). */ | ||
| private final String name; | ||
|
|
||
| /** The constant type (must be a field descriptor). */ | ||
| private final String descriptor; | ||
|
|
||
| /** The bootstrap method to use to compute the constant value at runtime. */ | ||
| private final Handle bootstrapMethod; | ||
|
|
||
| /** | ||
| * The arguments to pass to the bootstrap method, in order to compute the constant value at | ||
| * runtime. | ||
| */ | ||
| private final Object[] bootstrapMethodArguments; | ||
|
|
||
| /** | ||
| * Constructs a new {@link ConstantDynamic}. | ||
| * | ||
| * @param name the constant name (can be arbitrary). | ||
| * @param descriptor the constant type (must be a field descriptor). | ||
| * @param bootstrapMethod the bootstrap method to use to compute the constant value at runtime. | ||
| * @param bootstrapMethodArguments the arguments to pass to the bootstrap method, in order to | ||
| * compute the constant value at runtime. | ||
| */ | ||
| public ConstantDynamic( | ||
| final String name, | ||
| final String descriptor, | ||
| final Handle bootstrapMethod, | ||
| final Object... bootstrapMethodArguments) { | ||
| this.name = name; | ||
| this.descriptor = descriptor; | ||
| this.bootstrapMethod = bootstrapMethod; | ||
| this.bootstrapMethodArguments = bootstrapMethodArguments; | ||
| } | ||
|
|
||
| /** | ||
| * Returns the name of this constant. | ||
| * | ||
| * @return the name of this constant. | ||
| */ | ||
| public String getName() { | ||
| return name; | ||
| } | ||
|
|
||
| /** | ||
| * Returns the type of this constant. | ||
| * | ||
| * @return the type of this constant, as a field descriptor. | ||
| */ | ||
| public String getDescriptor() { | ||
| return descriptor; | ||
| } | ||
|
|
||
| /** | ||
| * Returns the bootstrap method used to compute the value of this constant. | ||
| * | ||
| * @return the bootstrap method used to compute the value of this constant. | ||
| */ | ||
| public Handle getBootstrapMethod() { | ||
| return bootstrapMethod; | ||
| } | ||
|
|
||
| /** | ||
| * Returns the arguments to pass to the bootstrap method, in order to compute the value of this | ||
| * constant. | ||
| * | ||
| * @return the arguments to pass to the bootstrap method, in order to compute the value of this | ||
| * constant. | ||
| */ | ||
| public Object[] getBootstrapMethodArguments() { | ||
| return bootstrapMethodArguments; | ||
| } | ||
|
|
||
| @Override | ||
| public boolean equals(final Object object) { | ||
| if (object == this) { | ||
| return true; | ||
| } | ||
| if (!(object instanceof ConstantDynamic)) { | ||
| return false; | ||
| } | ||
| ConstantDynamic constantDynamic = (ConstantDynamic) object; | ||
| return name.equals(constantDynamic.name) | ||
| && descriptor.equals(constantDynamic.descriptor) | ||
| && bootstrapMethod.equals(constantDynamic.bootstrapMethod) | ||
| && Arrays.equals(bootstrapMethodArguments, constantDynamic.bootstrapMethodArguments); | ||
| } | ||
|
|
||
| @Override | ||
| public int hashCode() { | ||
| return name.hashCode() | ||
| ^ Integer.rotateLeft(descriptor.hashCode(), 8) | ||
| ^ Integer.rotateLeft(bootstrapMethod.hashCode(), 16) | ||
| ^ Integer.rotateLeft(Arrays.hashCode(bootstrapMethodArguments), 24); | ||
| } | ||
|
|
||
| @Override | ||
| public String toString() { | ||
| return name | ||
| + " : " | ||
| + descriptor | ||
| + ' ' | ||
| + bootstrapMethod | ||
| + ' ' | ||
| + Arrays.toString(bootstrapMethodArguments); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,177 @@ | ||
| // 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 clojure.asm; | ||
|
|
||
| /** | ||
| * Defines additional JVM opcodes, access flags and constants which are not part of the ASM public | ||
| * API. | ||
| * | ||
| * @see <a href="https://docs.oracle.com/javase/specs/jvms/se11/html/jvms-6.html">JVMS 6</a> | ||
| * @author Eric Bruneton | ||
| */ | ||
| final class Constants implements Opcodes { | ||
|
|
||
| private Constants() {} | ||
|
|
||
| // The ClassFile attribute names, in the order they are defined in | ||
| // https://docs.oracle.com/javase/specs/jvms/se11/html/jvms-4.html#jvms-4.7-300. | ||
|
|
||
| static final String CONSTANT_VALUE = "ConstantValue"; | ||
| static final String CODE = "Code"; | ||
| static final String STACK_MAP_TABLE = "StackMapTable"; | ||
| static final String EXCEPTIONS = "Exceptions"; | ||
| static final String INNER_CLASSES = "InnerClasses"; | ||
| static final String ENCLOSING_METHOD = "EnclosingMethod"; | ||
| static final String SYNTHETIC = "Synthetic"; | ||
| static final String SIGNATURE = "Signature"; | ||
| static final String SOURCE_FILE = "SourceFile"; | ||
| static final String SOURCE_DEBUG_EXTENSION = "SourceDebugExtension"; | ||
| static final String LINE_NUMBER_TABLE = "LineNumberTable"; | ||
| static final String LOCAL_VARIABLE_TABLE = "LocalVariableTable"; | ||
| static final String LOCAL_VARIABLE_TYPE_TABLE = "LocalVariableTypeTable"; | ||
| static final String DEPRECATED = "Deprecated"; | ||
| static final String RUNTIME_VISIBLE_ANNOTATIONS = "RuntimeVisibleAnnotations"; | ||
| static final String RUNTIME_INVISIBLE_ANNOTATIONS = "RuntimeInvisibleAnnotations"; | ||
| static final String RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS = "RuntimeVisibleParameterAnnotations"; | ||
| static final String RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS = | ||
| "RuntimeInvisibleParameterAnnotations"; | ||
| static final String RUNTIME_VISIBLE_TYPE_ANNOTATIONS = "RuntimeVisibleTypeAnnotations"; | ||
| static final String RUNTIME_INVISIBLE_TYPE_ANNOTATIONS = "RuntimeInvisibleTypeAnnotations"; | ||
| static final String ANNOTATION_DEFAULT = "AnnotationDefault"; | ||
| static final String BOOTSTRAP_METHODS = "BootstrapMethods"; | ||
| static final String METHOD_PARAMETERS = "MethodParameters"; | ||
| static final String MODULE = "Module"; | ||
| static final String MODULE_PACKAGES = "ModulePackages"; | ||
| static final String MODULE_MAIN_CLASS = "ModuleMainClass"; | ||
| static final String NEST_HOST = "NestHost"; | ||
| static final String NEST_MEMBERS = "NestMembers"; | ||
|
|
||
| // ASM specific access flags. | ||
| // WARNING: the 16 least significant bits must NOT be used, to avoid conflicts with standard | ||
| // access flags, and also to make sure that these flags are automatically filtered out when | ||
| // written in class files (because access flags are stored using 16 bits only). | ||
|
|
||
| static final int ACC_CONSTRUCTOR = 0x40000; // method access flag. | ||
|
|
||
| // ASM specific stack map frame types, used in {@link ClassVisitor#visitFrame}. | ||
|
|
||
| /** | ||
| * A frame inserted between already existing frames. This internal stack map frame type (in | ||
| * addition to the ones declared in {@link Opcodes}) can only be used if the frame content can be | ||
| * computed from the previous existing frame and from the instructions between this existing frame | ||
| * and the inserted one, without any knowledge of the type hierarchy. This kind of frame is only | ||
| * used when an unconditional jump is inserted in a method while expanding an ASM specific | ||
| * instruction. Keep in sync with Opcodes.java. | ||
| */ | ||
| static final int F_INSERT = 256; | ||
|
|
||
| // The JVM opcode values which are not part of the ASM public API. | ||
| // See https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-6.html. | ||
|
|
||
| static final int LDC_W = 19; | ||
| static final int LDC2_W = 20; | ||
| static final int ILOAD_0 = 26; | ||
| static final int ILOAD_1 = 27; | ||
| static final int ILOAD_2 = 28; | ||
| static final int ILOAD_3 = 29; | ||
| static final int LLOAD_0 = 30; | ||
| static final int LLOAD_1 = 31; | ||
| static final int LLOAD_2 = 32; | ||
| static final int LLOAD_3 = 33; | ||
| static final int FLOAD_0 = 34; | ||
| static final int FLOAD_1 = 35; | ||
| static final int FLOAD_2 = 36; | ||
| static final int FLOAD_3 = 37; | ||
| static final int DLOAD_0 = 38; | ||
| static final int DLOAD_1 = 39; | ||
| static final int DLOAD_2 = 40; | ||
| static final int DLOAD_3 = 41; | ||
| static final int ALOAD_0 = 42; | ||
| static final int ALOAD_1 = 43; | ||
| static final int ALOAD_2 = 44; | ||
| static final int ALOAD_3 = 45; | ||
| static final int ISTORE_0 = 59; | ||
| static final int ISTORE_1 = 60; | ||
| static final int ISTORE_2 = 61; | ||
| static final int ISTORE_3 = 62; | ||
| static final int LSTORE_0 = 63; | ||
| static final int LSTORE_1 = 64; | ||
| static final int LSTORE_2 = 65; | ||
| static final int LSTORE_3 = 66; | ||
| static final int FSTORE_0 = 67; | ||
| static final int FSTORE_1 = 68; | ||
| static final int FSTORE_2 = 69; | ||
| static final int FSTORE_3 = 70; | ||
| static final int DSTORE_0 = 71; | ||
| static final int DSTORE_1 = 72; | ||
| static final int DSTORE_2 = 73; | ||
| static final int DSTORE_3 = 74; | ||
| static final int ASTORE_0 = 75; | ||
| static final int ASTORE_1 = 76; | ||
| static final int ASTORE_2 = 77; | ||
| static final int ASTORE_3 = 78; | ||
| static final int WIDE = 196; | ||
| static final int GOTO_W = 200; | ||
| static final int JSR_W = 201; | ||
|
|
||
| // Constants to convert between normal and wide jump instructions. | ||
|
|
||
| // The delta between the GOTO_W and JSR_W opcodes and GOTO and JUMP. | ||
| static final int WIDE_JUMP_OPCODE_DELTA = GOTO_W - GOTO; | ||
|
|
||
| // Constants to convert JVM opcodes to the equivalent ASM specific opcodes, and vice versa. | ||
|
|
||
| // The delta between the ASM_IFEQ, ..., ASM_IF_ACMPNE, ASM_GOTO and ASM_JSR opcodes | ||
| // and IFEQ, ..., IF_ACMPNE, GOTO and JSR. | ||
| static final int ASM_OPCODE_DELTA = 49; | ||
|
|
||
| // The delta between the ASM_IFNULL and ASM_IFNONNULL opcodes and IFNULL and IFNONNULL. | ||
| static final int ASM_IFNULL_OPCODE_DELTA = 20; | ||
|
|
||
| // ASM specific opcodes, used for long forward jump instructions. | ||
|
|
||
| static final int ASM_IFEQ = IFEQ + ASM_OPCODE_DELTA; | ||
| static final int ASM_IFNE = IFNE + ASM_OPCODE_DELTA; | ||
| static final int ASM_IFLT = IFLT + ASM_OPCODE_DELTA; | ||
| static final int ASM_IFGE = IFGE + ASM_OPCODE_DELTA; | ||
| static final int ASM_IFGT = IFGT + ASM_OPCODE_DELTA; | ||
| static final int ASM_IFLE = IFLE + ASM_OPCODE_DELTA; | ||
| static final int ASM_IF_ICMPEQ = IF_ICMPEQ + ASM_OPCODE_DELTA; | ||
| static final int ASM_IF_ICMPNE = IF_ICMPNE + ASM_OPCODE_DELTA; | ||
| static final int ASM_IF_ICMPLT = IF_ICMPLT + ASM_OPCODE_DELTA; | ||
| static final int ASM_IF_ICMPGE = IF_ICMPGE + ASM_OPCODE_DELTA; | ||
| static final int ASM_IF_ICMPGT = IF_ICMPGT + ASM_OPCODE_DELTA; | ||
| static final int ASM_IF_ICMPLE = IF_ICMPLE + ASM_OPCODE_DELTA; | ||
| static final int ASM_IF_ACMPEQ = IF_ACMPEQ + ASM_OPCODE_DELTA; | ||
| static final int ASM_IF_ACMPNE = IF_ACMPNE + ASM_OPCODE_DELTA; | ||
| static final int ASM_GOTO = GOTO + ASM_OPCODE_DELTA; | ||
| static final int ASM_JSR = JSR + ASM_OPCODE_DELTA; | ||
| static final int ASM_IFNULL = IFNULL + ASM_IFNULL_OPCODE_DELTA; | ||
| static final int ASM_IFNONNULL = IFNONNULL + ASM_IFNULL_OPCODE_DELTA; | ||
| static final int ASM_GOTO_W = 220; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 clojure.asm; | ||
|
|
||
| /** | ||
| * Information about the input stack map frame at the "current" instruction of a method. This is | ||
| * implemented as a Frame subclass for a "basic block" containing only one instruction. | ||
| * | ||
| * @author Eric Bruneton | ||
| */ | ||
| final class CurrentFrame extends Frame { | ||
|
|
||
| CurrentFrame(final Label owner) { | ||
| super(owner); | ||
| } | ||
|
|
||
| /** | ||
| * Sets this CurrentFrame to the input stack map frame of the next "current" instruction, i.e. the | ||
| * instruction just after the given one. It is assumed that the value of this object when this | ||
| * method is called is the stack map frame status just before the given instruction is executed. | ||
| */ | ||
| @Override | ||
| void execute( | ||
| final int opcode, final int arg, final Symbol symbolArg, final SymbolTable symbolTable) { | ||
| super.execute(opcode, arg, symbolArg, symbolTable); | ||
| Frame successor = new Frame(null); | ||
| merge(symbolTable, successor, 0); | ||
| copyFrom(successor); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,75 +1,91 @@ | ||
| // 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 clojure.asm; | ||
|
|
||
| /** | ||
| * An edge in the control flow graph of a method. Each node of this graph is a basic block, | ||
| * represented with the Label corresponding to its first instruction. Each edge goes from one node | ||
| * to another, i.e. from one basic block to another (called the predecessor and successor blocks, | ||
| * respectively). An edge corresponds either to a jump or ret instruction or to an exception | ||
| * handler. | ||
| * | ||
| * @see Label | ||
| * @author Eric Bruneton | ||
| */ | ||
| final class Edge { | ||
|
|
||
| /** | ||
| * A control flow graph edge corresponding to a jump or ret instruction. Only used with {@link | ||
| * ClassWriter#COMPUTE_FRAMES}. | ||
| */ | ||
| static final int JUMP = 0; | ||
|
|
||
| /** | ||
| * A control flow graph edge corresponding to an exception handler. Only used with {@link | ||
| * ClassWriter#COMPUTE_MAXS}. | ||
| */ | ||
| static final int EXCEPTION = 0x7FFFFFFF; | ||
|
|
||
| /** | ||
| * Information about this control flow graph edge. | ||
| * | ||
| * <ul> | ||
| * <li>If {@link ClassWriter#COMPUTE_MAXS} is used, this field contains either a stack size | ||
| * delta (for an edge corresponding to a jump instruction), or the value EXCEPTION (for an | ||
| * edge corresponding to an exception handler). The stack size delta is the stack size just | ||
| * after the jump instruction, minus the stack size at the beginning of the predecessor | ||
| * basic block, i.e. the one containing the jump instruction. | ||
| * <li>If {@link ClassWriter#COMPUTE_FRAMES} is used, this field contains either the value JUMP | ||
| * (for an edge corresponding to a jump instruction), or the index, in the {@link | ||
| * ClassWriter} type table, of the exception type that is handled (for an edge corresponding | ||
| * to an exception handler). | ||
| * </ul> | ||
| */ | ||
| final int info; | ||
|
|
||
| /** The successor block of this control flow graph edge. */ | ||
| final Label successor; | ||
|
|
||
| /** | ||
| * The next edge in the list of outgoing edges of a basic block. See {@link Label#outgoingEdges}. | ||
| */ | ||
| Edge nextEdge; | ||
|
|
||
| /** | ||
| * Constructs a new Edge. | ||
| * | ||
| * @param info see {@link #info}. | ||
| * @param successor see {@link #successor}. | ||
| * @param nextEdge see {@link #nextEdge}. | ||
| */ | ||
| Edge(final int info, final Label successor, final Edge nextEdge) { | ||
| this.info = info; | ||
| this.successor = successor; | ||
| this.nextEdge = nextEdge; | ||
| } | ||
| } |