feat(jdk8): move files to new folder to avoid resources compiled.

This commit is contained in:
2025-09-07 15:25:52 +08:00
parent 3f0047bf6f
commit 8c35cfb1c0
17415 changed files with 217 additions and 213 deletions

View File

@@ -0,0 +1,355 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* 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 jdk.internal.org.objectweb.asm.tree;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import jdk.internal.org.objectweb.asm.MethodVisitor;
/**
* A node that represents a bytecode instruction. <i>An instruction can appear
* at most once in at most one {@link InsnList} at a time</i>.
*
* @author Eric Bruneton
*/
public abstract class AbstractInsnNode {
/**
* The type of {@link InsnNode} instructions.
*/
public static final int INSN = 0;
/**
* The type of {@link IntInsnNode} instructions.
*/
public static final int INT_INSN = 1;
/**
* The type of {@link VarInsnNode} instructions.
*/
public static final int VAR_INSN = 2;
/**
* The type of {@link TypeInsnNode} instructions.
*/
public static final int TYPE_INSN = 3;
/**
* The type of {@link FieldInsnNode} instructions.
*/
public static final int FIELD_INSN = 4;
/**
* The type of {@link MethodInsnNode} instructions.
*/
public static final int METHOD_INSN = 5;
/**
* The type of {@link InvokeDynamicInsnNode} instructions.
*/
public static final int INVOKE_DYNAMIC_INSN = 6;
/**
* The type of {@link JumpInsnNode} instructions.
*/
public static final int JUMP_INSN = 7;
/**
* The type of {@link LabelNode} "instructions".
*/
public static final int LABEL = 8;
/**
* The type of {@link LdcInsnNode} instructions.
*/
public static final int LDC_INSN = 9;
/**
* The type of {@link IincInsnNode} instructions.
*/
public static final int IINC_INSN = 10;
/**
* The type of {@link TableSwitchInsnNode} instructions.
*/
public static final int TABLESWITCH_INSN = 11;
/**
* The type of {@link LookupSwitchInsnNode} instructions.
*/
public static final int LOOKUPSWITCH_INSN = 12;
/**
* The type of {@link MultiANewArrayInsnNode} instructions.
*/
public static final int MULTIANEWARRAY_INSN = 13;
/**
* The type of {@link FrameNode} "instructions".
*/
public static final int FRAME = 14;
/**
* The type of {@link LineNumberNode} "instructions".
*/
public static final int LINE = 15;
/**
* The opcode of this instruction.
*/
protected int opcode;
/**
* The runtime visible type annotations of this instruction. This field is
* only used for real instructions (i.e. not for labels, frames, or line
* number nodes). This list is a list of {@link TypeAnnotationNode} objects.
* May be <tt>null</tt>.
*
* @associates jdk.internal.org.objectweb.asm.tree.TypeAnnotationNode
* @label visible
*/
public List<TypeAnnotationNode> visibleTypeAnnotations;
/**
* The runtime invisible type annotations of this instruction. This field is
* only used for real instructions (i.e. not for labels, frames, or line
* number nodes). This list is a list of {@link TypeAnnotationNode} objects.
* May be <tt>null</tt>.
*
* @associates jdk.internal.org.objectweb.asm.tree.TypeAnnotationNode
* @label invisible
*/
public List<TypeAnnotationNode> invisibleTypeAnnotations;
/**
* Previous instruction in the list to which this instruction belongs.
*/
AbstractInsnNode prev;
/**
* Next instruction in the list to which this instruction belongs.
*/
AbstractInsnNode next;
/**
* Index of this instruction in the list to which it belongs. The value of
* this field is correct only when {@link InsnList#cache} is not null. A
* value of -1 indicates that this instruction does not belong to any
* {@link InsnList}.
*/
int index;
/**
* Constructs a new {@link AbstractInsnNode}.
*
* @param opcode
* the opcode of the instruction to be constructed.
*/
protected AbstractInsnNode(final int opcode) {
this.opcode = opcode;
this.index = -1;
}
/**
* Returns the opcode of this instruction.
*
* @return the opcode of this instruction.
*/
public int getOpcode() {
return opcode;
}
/**
* Returns the type of this instruction.
*
* @return the type of this instruction, i.e. one the constants defined in
* this class.
*/
public abstract int getType();
/**
* Returns the previous instruction in the list to which this instruction
* belongs, if any.
*
* @return the previous instruction in the list to which this instruction
* belongs, if any. May be <tt>null</tt>.
*/
public AbstractInsnNode getPrevious() {
return prev;
}
/**
* Returns the next instruction in the list to which this instruction
* belongs, if any.
*
* @return the next instruction in the list to which this instruction
* belongs, if any. May be <tt>null</tt>.
*/
public AbstractInsnNode getNext() {
return next;
}
/**
* Makes the given code visitor visit this instruction.
*
* @param cv
* a code visitor.
*/
public abstract void accept(final MethodVisitor cv);
/**
* Makes the given visitor visit the annotations of this instruction.
*
* @param mv
* a method visitor.
*/
protected final void acceptAnnotations(final MethodVisitor mv) {
int n = visibleTypeAnnotations == null ? 0 : visibleTypeAnnotations
.size();
for (int i = 0; i < n; ++i) {
TypeAnnotationNode an = visibleTypeAnnotations.get(i);
an.accept(mv.visitInsnAnnotation(an.typeRef, an.typePath, an.desc,
true));
}
n = invisibleTypeAnnotations == null ? 0 : invisibleTypeAnnotations
.size();
for (int i = 0; i < n; ++i) {
TypeAnnotationNode an = invisibleTypeAnnotations.get(i);
an.accept(mv.visitInsnAnnotation(an.typeRef, an.typePath, an.desc,
false));
}
}
/**
* Returns a copy of this instruction.
*
* @param labels
* a map from LabelNodes to cloned LabelNodes.
* @return a copy of this instruction. The returned instruction does not
* belong to any {@link InsnList}.
*/
public abstract AbstractInsnNode clone(
final Map<LabelNode, LabelNode> labels);
/**
* Returns the clone of the given label.
*
* @param label
* a label.
* @param map
* a map from LabelNodes to cloned LabelNodes.
* @return the clone of the given label.
*/
static LabelNode clone(final LabelNode label,
final Map<LabelNode, LabelNode> map) {
return map.get(label);
}
/**
* Returns the clones of the given labels.
*
* @param labels
* a list of labels.
* @param map
* a map from LabelNodes to cloned LabelNodes.
* @return the clones of the given labels.
*/
static LabelNode[] clone(final List<LabelNode> labels,
final Map<LabelNode, LabelNode> map) {
LabelNode[] clones = new LabelNode[labels.size()];
for (int i = 0; i < clones.length; ++i) {
clones[i] = map.get(labels.get(i));
}
return clones;
}
/**
* Clones the annotations of the given instruction into this instruction.
*
* @param insn
* the source instruction.
* @return this instruction.
*/
protected final AbstractInsnNode cloneAnnotations(
final AbstractInsnNode insn) {
if (insn.visibleTypeAnnotations != null) {
this.visibleTypeAnnotations = new ArrayList<TypeAnnotationNode>();
for (int i = 0; i < insn.visibleTypeAnnotations.size(); ++i) {
TypeAnnotationNode src = insn.visibleTypeAnnotations.get(i);
TypeAnnotationNode ann = new TypeAnnotationNode(src.typeRef,
src.typePath, src.desc);
src.accept(ann);
this.visibleTypeAnnotations.add(ann);
}
}
if (insn.invisibleTypeAnnotations != null) {
this.invisibleTypeAnnotations = new ArrayList<TypeAnnotationNode>();
for (int i = 0; i < insn.invisibleTypeAnnotations.size(); ++i) {
TypeAnnotationNode src = insn.invisibleTypeAnnotations.get(i);
TypeAnnotationNode ann = new TypeAnnotationNode(src.typeRef,
src.typePath, src.desc);
src.accept(ann);
this.invisibleTypeAnnotations.add(ann);
}
}
return this;
}
}

View File

@@ -0,0 +1,262 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* 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 jdk.internal.org.objectweb.asm.tree;
import java.util.ArrayList;
import java.util.List;
import jdk.internal.org.objectweb.asm.AnnotationVisitor;
import jdk.internal.org.objectweb.asm.Opcodes;
/**
* A node that represents an annotationn.
*
* @author Eric Bruneton
*/
public class AnnotationNode extends AnnotationVisitor {
/**
* The class descriptor of the annotation class.
*/
public String desc;
/**
* The name value pairs of this annotation. Each name value pair is stored
* as two consecutive elements in the list. The name is a {@link String},
* and the value may be a {@link Byte}, {@link Boolean}, {@link Character},
* {@link Short}, {@link Integer}, {@link Long}, {@link Float},
* {@link Double}, {@link String} or {@link jdk.internal.org.objectweb.asm.Type}, or an
* two elements String array (for enumeration values), a
* {@link AnnotationNode}, or a {@link List} of values of one of the
* preceding types. The list may be <tt>null</tt> if there is no name value
* pair.
*/
public List<Object> values;
/**
* Constructs a new {@link AnnotationNode}. <i>Subclasses must not use this
* constructor</i>. Instead, they must use the
* {@link #AnnotationNode(int, String)} version.
*
* @param desc
* the class descriptor of the annotation class.
* @throws IllegalStateException
* If a subclass calls this constructor.
*/
public AnnotationNode(final String desc) {
this(Opcodes.ASM5, desc);
if (getClass() != AnnotationNode.class) {
throw new IllegalStateException();
}
}
/**
* Constructs a new {@link AnnotationNode}.
*
* @param api
* the ASM API version implemented by this visitor. Must be one
* of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
* @param desc
* the class descriptor of the annotation class.
*/
public AnnotationNode(final int api, final String desc) {
super(api);
this.desc = desc;
}
/**
* Constructs a new {@link AnnotationNode} to visit an array value.
*
* @param values
* where the visited values must be stored.
*/
AnnotationNode(final List<Object> values) {
super(Opcodes.ASM5);
this.values = values;
}
// ------------------------------------------------------------------------
// Implementation of the AnnotationVisitor abstract class
// ------------------------------------------------------------------------
@Override
public void visit(final String name, final Object value) {
if (values == null) {
values = new ArrayList<Object>(this.desc != null ? 2 : 1);
}
if (this.desc != null) {
values.add(name);
}
values.add(value);
}
@Override
public void visitEnum(final String name, final String desc,
final String value) {
if (values == null) {
values = new ArrayList<Object>(this.desc != null ? 2 : 1);
}
if (this.desc != null) {
values.add(name);
}
values.add(new String[] { desc, value });
}
@Override
public AnnotationVisitor visitAnnotation(final String name,
final String desc) {
if (values == null) {
values = new ArrayList<Object>(this.desc != null ? 2 : 1);
}
if (this.desc != null) {
values.add(name);
}
AnnotationNode annotation = new AnnotationNode(desc);
values.add(annotation);
return annotation;
}
@Override
public AnnotationVisitor visitArray(final String name) {
if (values == null) {
values = new ArrayList<Object>(this.desc != null ? 2 : 1);
}
if (this.desc != null) {
values.add(name);
}
List<Object> array = new ArrayList<Object>();
values.add(array);
return new AnnotationNode(array);
}
@Override
public void visitEnd() {
}
// ------------------------------------------------------------------------
// Accept methods
// ------------------------------------------------------------------------
/**
* Checks that this annotation node is compatible with the given ASM API
* version. This methods checks that this node, and all its nodes
* recursively, do not contain elements that were introduced in more recent
* versions of the ASM API than the given version.
*
* @param api
* an ASM API version. Must be one of {@link Opcodes#ASM4} or
* {@link Opcodes#ASM5}.
*/
public void check(final int api) {
// nothing to do
}
/**
* Makes the given visitor visit this annotation.
*
* @param av
* an annotation visitor. Maybe <tt>null</tt>.
*/
public void accept(final AnnotationVisitor av) {
if (av != null) {
if (values != null) {
for (int i = 0; i < values.size(); i += 2) {
String name = (String) values.get(i);
Object value = values.get(i + 1);
accept(av, name, value);
}
}
av.visitEnd();
}
}
/**
* Makes the given visitor visit a given annotation value.
*
* @param av
* an annotation visitor. Maybe <tt>null</tt>.
* @param name
* the value name.
* @param value
* the actual value.
*/
static void accept(final AnnotationVisitor av, final String name,
final Object value) {
if (av != null) {
if (value instanceof String[]) {
String[] typeconst = (String[]) value;
av.visitEnum(name, typeconst[0], typeconst[1]);
} else if (value instanceof AnnotationNode) {
AnnotationNode an = (AnnotationNode) value;
an.accept(av.visitAnnotation(name, an.desc));
} else if (value instanceof List) {
AnnotationVisitor v = av.visitArray(name);
if (v != null) {
List<?> array = (List<?>) value;
for (int j = 0; j < array.size(); ++j) {
accept(v, null, array.get(j));
}
v.visitEnd();
}
} else {
av.visit(name, value);
}
}
}
}

View File

@@ -0,0 +1,446 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* 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 jdk.internal.org.objectweb.asm.tree;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import jdk.internal.org.objectweb.asm.AnnotationVisitor;
import jdk.internal.org.objectweb.asm.Attribute;
import jdk.internal.org.objectweb.asm.ClassVisitor;
import jdk.internal.org.objectweb.asm.FieldVisitor;
import jdk.internal.org.objectweb.asm.MethodVisitor;
import jdk.internal.org.objectweb.asm.Opcodes;
import jdk.internal.org.objectweb.asm.TypePath;
/**
* A node that represents a class.
*
* @author Eric Bruneton
*/
public class ClassNode extends ClassVisitor {
/**
* The class version.
*/
public int version;
/**
* The class's access flags (see {@link jdk.internal.org.objectweb.asm.Opcodes}). This
* field also indicates if the class is deprecated.
*/
public int access;
/**
* The internal name of the class (see
* {@link jdk.internal.org.objectweb.asm.Type#getInternalName() getInternalName}).
*/
public String name;
/**
* The signature of the class. May be <tt>null</tt>.
*/
public String signature;
/**
* The internal of name of the super class (see
* {@link jdk.internal.org.objectweb.asm.Type#getInternalName() getInternalName}). For
* interfaces, the super class is {@link Object}. May be <tt>null</tt>, but
* only for the {@link Object} class.
*/
public String superName;
/**
* The internal names of the class's interfaces (see
* {@link jdk.internal.org.objectweb.asm.Type#getInternalName() getInternalName}). This
* list is a list of {@link String} objects.
*/
public List<String> interfaces;
/**
* The name of the source file from which this class was compiled. May be
* <tt>null</tt>.
*/
public String sourceFile;
/**
* Debug information to compute the correspondence between source and
* compiled elements of the class. May be <tt>null</tt>.
*/
public String sourceDebug;
/**
* The internal name of the enclosing class of the class. May be
* <tt>null</tt>.
*/
public String outerClass;
/**
* The name of the method that contains the class, or <tt>null</tt> if the
* class is not enclosed in a method.
*/
public String outerMethod;
/**
* The descriptor of the method that contains the class, or <tt>null</tt> if
* the class is not enclosed in a method.
*/
public String outerMethodDesc;
/**
* The runtime visible annotations of this class. This list is a list of
* {@link AnnotationNode} objects. May be <tt>null</tt>.
*
* @associates jdk.internal.org.objectweb.asm.tree.AnnotationNode
* @label visible
*/
public List<AnnotationNode> visibleAnnotations;
/**
* The runtime invisible annotations of this class. This list is a list of
* {@link AnnotationNode} objects. May be <tt>null</tt>.
*
* @associates jdk.internal.org.objectweb.asm.tree.AnnotationNode
* @label invisible
*/
public List<AnnotationNode> invisibleAnnotations;
/**
* The runtime visible type annotations of this class. This list is a list
* of {@link TypeAnnotationNode} objects. May be <tt>null</tt>.
*
* @associates jdk.internal.org.objectweb.asm.tree.TypeAnnotationNode
* @label visible
*/
public List<TypeAnnotationNode> visibleTypeAnnotations;
/**
* The runtime invisible type annotations of this class. This list is a list
* of {@link TypeAnnotationNode} objects. May be <tt>null</tt>.
*
* @associates jdk.internal.org.objectweb.asm.tree.TypeAnnotationNode
* @label invisible
*/
public List<TypeAnnotationNode> invisibleTypeAnnotations;
/**
* The non standard attributes of this class. This list is a list of
* {@link Attribute} objects. May be <tt>null</tt>.
*
* @associates jdk.internal.org.objectweb.asm.Attribute
*/
public List<Attribute> attrs;
/**
* Informations about the inner classes of this class. This list is a list
* of {@link InnerClassNode} objects.
*
* @associates jdk.internal.org.objectweb.asm.tree.InnerClassNode
*/
public List<InnerClassNode> innerClasses;
/**
* The fields of this class. This list is a list of {@link FieldNode}
* objects.
*
* @associates jdk.internal.org.objectweb.asm.tree.FieldNode
*/
public List<FieldNode> fields;
/**
* The methods of this class. This list is a list of {@link MethodNode}
* objects.
*
* @associates jdk.internal.org.objectweb.asm.tree.MethodNode
*/
public List<MethodNode> methods;
/**
* Constructs a new {@link ClassNode}. <i>Subclasses must not use this
* constructor</i>. Instead, they must use the {@link #ClassNode(int)}
* version.
*
* @throws IllegalStateException
* If a subclass calls this constructor.
*/
public ClassNode() {
this(Opcodes.ASM5);
if (getClass() != ClassNode.class) {
throw new IllegalStateException();
}
}
/**
* Constructs a new {@link ClassNode}.
*
* @param api
* the ASM API version implemented by this visitor. Must be one
* of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
*/
public ClassNode(final int api) {
super(api);
this.interfaces = new ArrayList<String>();
this.innerClasses = new ArrayList<InnerClassNode>();
this.fields = new ArrayList<FieldNode>();
this.methods = new ArrayList<MethodNode>();
}
// ------------------------------------------------------------------------
// Implementation of the ClassVisitor abstract class
// ------------------------------------------------------------------------
@Override
public void visit(final int version, final int access, final String name,
final String signature, final String superName,
final String[] interfaces) {
this.version = version;
this.access = access;
this.name = name;
this.signature = signature;
this.superName = superName;
if (interfaces != null) {
this.interfaces.addAll(Arrays.asList(interfaces));
}
}
@Override
public void visitSource(final String file, final String debug) {
sourceFile = file;
sourceDebug = debug;
}
@Override
public void visitOuterClass(final String owner, final String name,
final String desc) {
outerClass = owner;
outerMethod = name;
outerMethodDesc = desc;
}
@Override
public AnnotationVisitor visitAnnotation(final String desc,
final boolean visible) {
AnnotationNode an = new AnnotationNode(desc);
if (visible) {
if (visibleAnnotations == null) {
visibleAnnotations = new ArrayList<AnnotationNode>(1);
}
visibleAnnotations.add(an);
} else {
if (invisibleAnnotations == null) {
invisibleAnnotations = new ArrayList<AnnotationNode>(1);
}
invisibleAnnotations.add(an);
}
return an;
}
@Override
public AnnotationVisitor visitTypeAnnotation(int typeRef,
TypePath typePath, String desc, boolean visible) {
TypeAnnotationNode an = new TypeAnnotationNode(typeRef, typePath, desc);
if (visible) {
if (visibleTypeAnnotations == null) {
visibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(1);
}
visibleTypeAnnotations.add(an);
} else {
if (invisibleTypeAnnotations == null) {
invisibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(1);
}
invisibleTypeAnnotations.add(an);
}
return an;
}
@Override
public void visitAttribute(final Attribute attr) {
if (attrs == null) {
attrs = new ArrayList<Attribute>(1);
}
attrs.add(attr);
}
@Override
public void visitInnerClass(final String name, final String outerName,
final String innerName, final int access) {
InnerClassNode icn = new InnerClassNode(name, outerName, innerName,
access);
innerClasses.add(icn);
}
@Override
public FieldVisitor visitField(final int access, final String name,
final String desc, final String signature, final Object value) {
FieldNode fn = new FieldNode(access, name, desc, signature, value);
fields.add(fn);
return fn;
}
@Override
public MethodVisitor visitMethod(final int access, final String name,
final String desc, final String signature, final String[] exceptions) {
MethodNode mn = new MethodNode(access, name, desc, signature,
exceptions);
methods.add(mn);
return mn;
}
@Override
public void visitEnd() {
}
// ------------------------------------------------------------------------
// Accept method
// ------------------------------------------------------------------------
/**
* Checks that this class node is compatible with the given ASM API version.
* This methods checks that this node, and all its nodes recursively, do not
* contain elements that were introduced in more recent versions of the ASM
* API than the given version.
*
* @param api
* an ASM API version. Must be one of {@link Opcodes#ASM4} or
* {@link Opcodes#ASM5}.
*/
public void check(final int api) {
if (api == Opcodes.ASM4) {
if (visibleTypeAnnotations != null
&& visibleTypeAnnotations.size() > 0) {
throw new RuntimeException();
}
if (invisibleTypeAnnotations != null
&& invisibleTypeAnnotations.size() > 0) {
throw new RuntimeException();
}
for (FieldNode f : fields) {
f.check(api);
}
for (MethodNode m : methods) {
m.check(api);
}
}
}
/**
* Makes the given class visitor visit this class.
*
* @param cv
* a class visitor.
*/
public void accept(final ClassVisitor cv) {
// visits header
String[] interfaces = new String[this.interfaces.size()];
this.interfaces.toArray(interfaces);
cv.visit(version, access, name, signature, superName, interfaces);
// visits source
if (sourceFile != null || sourceDebug != null) {
cv.visitSource(sourceFile, sourceDebug);
}
// visits outer class
if (outerClass != null) {
cv.visitOuterClass(outerClass, outerMethod, outerMethodDesc);
}
// visits attributes
int i, n;
n = visibleAnnotations == null ? 0 : visibleAnnotations.size();
for (i = 0; i < n; ++i) {
AnnotationNode an = visibleAnnotations.get(i);
an.accept(cv.visitAnnotation(an.desc, true));
}
n = invisibleAnnotations == null ? 0 : invisibleAnnotations.size();
for (i = 0; i < n; ++i) {
AnnotationNode an = invisibleAnnotations.get(i);
an.accept(cv.visitAnnotation(an.desc, false));
}
n = visibleTypeAnnotations == null ? 0 : visibleTypeAnnotations.size();
for (i = 0; i < n; ++i) {
TypeAnnotationNode an = visibleTypeAnnotations.get(i);
an.accept(cv.visitTypeAnnotation(an.typeRef, an.typePath, an.desc,
true));
}
n = invisibleTypeAnnotations == null ? 0 : invisibleTypeAnnotations
.size();
for (i = 0; i < n; ++i) {
TypeAnnotationNode an = invisibleTypeAnnotations.get(i);
an.accept(cv.visitTypeAnnotation(an.typeRef, an.typePath, an.desc,
false));
}
n = attrs == null ? 0 : attrs.size();
for (i = 0; i < n; ++i) {
cv.visitAttribute(attrs.get(i));
}
// visits inner classes
for (i = 0; i < innerClasses.size(); ++i) {
innerClasses.get(i).accept(cv);
}
// visits fields
for (i = 0; i < fields.size(); ++i) {
fields.get(i).accept(cv);
}
// visits methods
for (i = 0; i < methods.size(); ++i) {
methods.get(i).accept(cv);
}
// visits end
cv.visitEnd();
}
}

View File

@@ -0,0 +1,139 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* 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 jdk.internal.org.objectweb.asm.tree;
import java.util.Map;
import jdk.internal.org.objectweb.asm.MethodVisitor;
/**
* A node that represents a field instruction. A field instruction is an
* instruction that loads or stores the value of a field of an object.
*
* @author Eric Bruneton
*/
public class FieldInsnNode extends AbstractInsnNode {
/**
* The internal name of the field's owner class (see
* {@link jdk.internal.org.objectweb.asm.Type#getInternalName() getInternalName}).
*/
public String owner;
/**
* The field's name.
*/
public String name;
/**
* The field's descriptor (see {@link jdk.internal.org.objectweb.asm.Type}).
*/
public String desc;
/**
* Constructs a new {@link FieldInsnNode}.
*
* @param opcode
* the opcode of the type instruction to be constructed. This
* opcode must be GETSTATIC, PUTSTATIC, GETFIELD or PUTFIELD.
* @param owner
* the internal name of the field's owner class (see
* {@link jdk.internal.org.objectweb.asm.Type#getInternalName()
* getInternalName}).
* @param name
* the field's name.
* @param desc
* the field's descriptor (see {@link jdk.internal.org.objectweb.asm.Type}).
*/
public FieldInsnNode(final int opcode, final String owner,
final String name, final String desc) {
super(opcode);
this.owner = owner;
this.name = name;
this.desc = desc;
}
/**
* Sets the opcode of this instruction.
*
* @param opcode
* the new instruction opcode. This opcode must be GETSTATIC,
* PUTSTATIC, GETFIELD or PUTFIELD.
*/
public void setOpcode(final int opcode) {
this.opcode = opcode;
}
@Override
public int getType() {
return FIELD_INSN;
}
@Override
public void accept(final MethodVisitor mv) {
mv.visitFieldInsn(opcode, owner, name, desc);
acceptAnnotations(mv);
}
@Override
public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
return new FieldInsnNode(opcode, owner, name, desc)
.cloneAnnotations(this);
}
}

View File

@@ -0,0 +1,336 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* 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 jdk.internal.org.objectweb.asm.tree;
import java.util.ArrayList;
import java.util.List;
import jdk.internal.org.objectweb.asm.AnnotationVisitor;
import jdk.internal.org.objectweb.asm.Attribute;
import jdk.internal.org.objectweb.asm.ClassVisitor;
import jdk.internal.org.objectweb.asm.FieldVisitor;
import jdk.internal.org.objectweb.asm.Opcodes;
import jdk.internal.org.objectweb.asm.TypePath;
/**
* A node that represents a field.
*
* @author Eric Bruneton
*/
public class FieldNode extends FieldVisitor {
/**
* The field's access flags (see {@link jdk.internal.org.objectweb.asm.Opcodes}). This
* field also indicates if the field is synthetic and/or deprecated.
*/
public int access;
/**
* The field's name.
*/
public String name;
/**
* The field's descriptor (see {@link jdk.internal.org.objectweb.asm.Type}).
*/
public String desc;
/**
* The field's signature. May be <tt>null</tt>.
*/
public String signature;
/**
* The field's initial value. This field, which may be <tt>null</tt> if the
* field does not have an initial value, must be an {@link Integer}, a
* {@link Float}, a {@link Long}, a {@link Double} or a {@link String}.
*/
public Object value;
/**
* The runtime visible annotations of this field. This list is a list of
* {@link AnnotationNode} objects. May be <tt>null</tt>.
*
* @associates jdk.internal.org.objectweb.asm.tree.AnnotationNode
* @label visible
*/
public List<AnnotationNode> visibleAnnotations;
/**
* The runtime invisible annotations of this field. This list is a list of
* {@link AnnotationNode} objects. May be <tt>null</tt>.
*
* @associates jdk.internal.org.objectweb.asm.tree.AnnotationNode
* @label invisible
*/
public List<AnnotationNode> invisibleAnnotations;
/**
* The runtime visible type annotations of this field. This list is a list
* of {@link TypeAnnotationNode} objects. May be <tt>null</tt>.
*
* @associates jdk.internal.org.objectweb.asm.tree.TypeAnnotationNode
* @label visible
*/
public List<TypeAnnotationNode> visibleTypeAnnotations;
/**
* The runtime invisible type annotations of this field. This list is a list
* of {@link TypeAnnotationNode} objects. May be <tt>null</tt>.
*
* @associates jdk.internal.org.objectweb.asm.tree.TypeAnnotationNode
* @label invisible
*/
public List<TypeAnnotationNode> invisibleTypeAnnotations;
/**
* The non standard attributes of this field. This list is a list of
* {@link Attribute} objects. May be <tt>null</tt>.
*
* @associates jdk.internal.org.objectweb.asm.Attribute
*/
public List<Attribute> attrs;
/**
* Constructs a new {@link FieldNode}. <i>Subclasses must not use this
* constructor</i>. Instead, they must use the
* {@link #FieldNode(int, int, String, String, String, Object)} version.
*
* @param access
* the field's access flags (see
* {@link jdk.internal.org.objectweb.asm.Opcodes}). This parameter also
* indicates if the field is synthetic and/or deprecated.
* @param name
* the field's name.
* @param desc
* the field's descriptor (see {@link jdk.internal.org.objectweb.asm.Type
* Type}).
* @param signature
* the field's signature.
* @param value
* the field's initial value. This parameter, which may be
* <tt>null</tt> if the field does not have an initial value,
* must be an {@link Integer}, a {@link Float}, a {@link Long}, a
* {@link Double} or a {@link String}.
* @throws IllegalStateException
* If a subclass calls this constructor.
*/
public FieldNode(final int access, final String name, final String desc,
final String signature, final Object value) {
this(Opcodes.ASM5, access, name, desc, signature, value);
if (getClass() != FieldNode.class) {
throw new IllegalStateException();
}
}
/**
* Constructs a new {@link FieldNode}. <i>Subclasses must not use this
* constructor</i>.
*
* @param api
* the ASM API version implemented by this visitor. Must be one
* of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
* @param access
* the field's access flags (see
* {@link jdk.internal.org.objectweb.asm.Opcodes}). This parameter also
* indicates if the field is synthetic and/or deprecated.
* @param name
* the field's name.
* @param desc
* the field's descriptor (see {@link jdk.internal.org.objectweb.asm.Type
* Type}).
* @param signature
* the field's signature.
* @param value
* the field's initial value. This parameter, which may be
* <tt>null</tt> if the field does not have an initial value,
* must be an {@link Integer}, a {@link Float}, a {@link Long}, a
* {@link Double} or a {@link String}.
*/
public FieldNode(final int api, final int access, final String name,
final String desc, final String signature, final Object value) {
super(api);
this.access = access;
this.name = name;
this.desc = desc;
this.signature = signature;
this.value = value;
}
// ------------------------------------------------------------------------
// Implementation of the FieldVisitor abstract class
// ------------------------------------------------------------------------
@Override
public AnnotationVisitor visitAnnotation(final String desc,
final boolean visible) {
AnnotationNode an = new AnnotationNode(desc);
if (visible) {
if (visibleAnnotations == null) {
visibleAnnotations = new ArrayList<AnnotationNode>(1);
}
visibleAnnotations.add(an);
} else {
if (invisibleAnnotations == null) {
invisibleAnnotations = new ArrayList<AnnotationNode>(1);
}
invisibleAnnotations.add(an);
}
return an;
}
@Override
public AnnotationVisitor visitTypeAnnotation(int typeRef,
TypePath typePath, String desc, boolean visible) {
TypeAnnotationNode an = new TypeAnnotationNode(typeRef, typePath, desc);
if (visible) {
if (visibleTypeAnnotations == null) {
visibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(1);
}
visibleTypeAnnotations.add(an);
} else {
if (invisibleTypeAnnotations == null) {
invisibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(1);
}
invisibleTypeAnnotations.add(an);
}
return an;
}
@Override
public void visitAttribute(final Attribute attr) {
if (attrs == null) {
attrs = new ArrayList<Attribute>(1);
}
attrs.add(attr);
}
@Override
public void visitEnd() {
}
// ------------------------------------------------------------------------
// Accept methods
// ------------------------------------------------------------------------
/**
* Checks that this field node is compatible with the given ASM API version.
* This methods checks that this node, and all its nodes recursively, do not
* contain elements that were introduced in more recent versions of the ASM
* API than the given version.
*
* @param api
* an ASM API version. Must be one of {@link Opcodes#ASM4} or
* {@link Opcodes#ASM5}.
*/
public void check(final int api) {
if (api == Opcodes.ASM4) {
if (visibleTypeAnnotations != null
&& visibleTypeAnnotations.size() > 0) {
throw new RuntimeException();
}
if (invisibleTypeAnnotations != null
&& invisibleTypeAnnotations.size() > 0) {
throw new RuntimeException();
}
}
}
/**
* Makes the given class visitor visit this field.
*
* @param cv
* a class visitor.
*/
public void accept(final ClassVisitor cv) {
FieldVisitor fv = cv.visitField(access, name, desc, signature, value);
if (fv == null) {
return;
}
int i, n;
n = visibleAnnotations == null ? 0 : visibleAnnotations.size();
for (i = 0; i < n; ++i) {
AnnotationNode an = visibleAnnotations.get(i);
an.accept(fv.visitAnnotation(an.desc, true));
}
n = invisibleAnnotations == null ? 0 : invisibleAnnotations.size();
for (i = 0; i < n; ++i) {
AnnotationNode an = invisibleAnnotations.get(i);
an.accept(fv.visitAnnotation(an.desc, false));
}
n = visibleTypeAnnotations == null ? 0 : visibleTypeAnnotations.size();
for (i = 0; i < n; ++i) {
TypeAnnotationNode an = visibleTypeAnnotations.get(i);
an.accept(fv.visitTypeAnnotation(an.typeRef, an.typePath, an.desc,
true));
}
n = invisibleTypeAnnotations == null ? 0 : invisibleTypeAnnotations
.size();
for (i = 0; i < n; ++i) {
TypeAnnotationNode an = invisibleTypeAnnotations.get(i);
an.accept(fv.visitTypeAnnotation(an.typeRef, an.typePath, an.desc,
false));
}
n = attrs == null ? 0 : attrs.size();
for (i = 0; i < n; ++i) {
fv.visitAttribute(attrs.get(i));
}
fv.visitEnd();
}
}

View File

@@ -0,0 +1,239 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* 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 jdk.internal.org.objectweb.asm.tree;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import jdk.internal.org.objectweb.asm.MethodVisitor;
import jdk.internal.org.objectweb.asm.Opcodes;
/**
* A node that represents a stack map frame. These nodes are pseudo instruction
* nodes in order to be inserted in an instruction list. In fact these nodes
* must(*) be inserted <i>just before</i> any instruction node <b>i</b> that
* follows an unconditionnal branch instruction such as GOTO or THROW, that is
* the target of a jump instruction, or that starts an exception handler block.
* The stack map frame types must describe the values of the local variables and
* of the operand stack elements <i>just before</i> <b>i</b> is executed. <br>
* <br>
* (*) this is mandatory only for classes whose version is greater than or equal
* to {@link Opcodes#V1_6 V1_6}.
*
* @author Eric Bruneton
*/
public class FrameNode extends AbstractInsnNode {
/**
* The type of this frame. Must be {@link Opcodes#F_NEW} for expanded
* frames, or {@link Opcodes#F_FULL}, {@link Opcodes#F_APPEND},
* {@link Opcodes#F_CHOP}, {@link Opcodes#F_SAME} or
* {@link Opcodes#F_APPEND}, {@link Opcodes#F_SAME1} for compressed frames.
*/
public int type;
/**
* The types of the local variables of this stack map frame. Elements of
* this list can be Integer, String or LabelNode objects (for primitive,
* reference and uninitialized types respectively - see
* {@link MethodVisitor}).
*/
public List<Object> local;
/**
* The types of the operand stack elements of this stack map frame. Elements
* of this list can be Integer, String or LabelNode objects (for primitive,
* reference and uninitialized types respectively - see
* {@link MethodVisitor}).
*/
public List<Object> stack;
private FrameNode() {
super(-1);
}
/**
* Constructs a new {@link FrameNode}.
*
* @param type
* the type of this frame. Must be {@link Opcodes#F_NEW} for
* expanded frames, or {@link Opcodes#F_FULL},
* {@link Opcodes#F_APPEND}, {@link Opcodes#F_CHOP},
* {@link Opcodes#F_SAME} or {@link Opcodes#F_APPEND},
* {@link Opcodes#F_SAME1} for compressed frames.
* @param nLocal
* number of local variables of this stack map frame.
* @param local
* the types of the local variables of this stack map frame.
* Elements of this list can be Integer, String or LabelNode
* objects (for primitive, reference and uninitialized types
* respectively - see {@link MethodVisitor}).
* @param nStack
* number of operand stack elements of this stack map frame.
* @param stack
* the types of the operand stack elements of this stack map
* frame. Elements of this list can be Integer, String or
* LabelNode objects (for primitive, reference and uninitialized
* types respectively - see {@link MethodVisitor}).
*/
public FrameNode(final int type, final int nLocal, final Object[] local,
final int nStack, final Object[] stack) {
super(-1);
this.type = type;
switch (type) {
case Opcodes.F_NEW:
case Opcodes.F_FULL:
this.local = asList(nLocal, local);
this.stack = asList(nStack, stack);
break;
case Opcodes.F_APPEND:
this.local = asList(nLocal, local);
break;
case Opcodes.F_CHOP:
this.local = Arrays.asList(new Object[nLocal]);
break;
case Opcodes.F_SAME:
break;
case Opcodes.F_SAME1:
this.stack = asList(1, stack);
break;
}
}
@Override
public int getType() {
return FRAME;
}
/**
* Makes the given visitor visit this stack map frame.
*
* @param mv
* a method visitor.
*/
@Override
public void accept(final MethodVisitor mv) {
switch (type) {
case Opcodes.F_NEW:
case Opcodes.F_FULL:
mv.visitFrame(type, local.size(), asArray(local), stack.size(),
asArray(stack));
break;
case Opcodes.F_APPEND:
mv.visitFrame(type, local.size(), asArray(local), 0, null);
break;
case Opcodes.F_CHOP:
mv.visitFrame(type, local.size(), null, 0, null);
break;
case Opcodes.F_SAME:
mv.visitFrame(type, 0, null, 0, null);
break;
case Opcodes.F_SAME1:
mv.visitFrame(type, 0, null, 1, asArray(stack));
break;
}
}
@Override
public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
FrameNode clone = new FrameNode();
clone.type = type;
if (local != null) {
clone.local = new ArrayList<Object>();
for (int i = 0; i < local.size(); ++i) {
Object l = local.get(i);
if (l instanceof LabelNode) {
l = labels.get(l);
}
clone.local.add(l);
}
}
if (stack != null) {
clone.stack = new ArrayList<Object>();
for (int i = 0; i < stack.size(); ++i) {
Object s = stack.get(i);
if (s instanceof LabelNode) {
s = labels.get(s);
}
clone.stack.add(s);
}
}
return clone;
}
// ------------------------------------------------------------------------
private static List<Object> asList(final int n, final Object[] o) {
return Arrays.asList(o).subList(0, n);
}
private static Object[] asArray(final List<Object> l) {
Object[] objs = new Object[l.size()];
for (int i = 0; i < objs.length; ++i) {
Object o = l.get(i);
if (o instanceof LabelNode) {
o = ((LabelNode) o).getLabel();
}
objs[i] = o;
}
return objs;
}
}

View File

@@ -0,0 +1,112 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* 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 jdk.internal.org.objectweb.asm.tree;
import java.util.Map;
import jdk.internal.org.objectweb.asm.MethodVisitor;
import jdk.internal.org.objectweb.asm.Opcodes;
/**
* A node that represents an IINC instruction.
*
* @author Eric Bruneton
*/
public class IincInsnNode extends AbstractInsnNode {
/**
* Index of the local variable to be incremented.
*/
public int var;
/**
* Amount to increment the local variable by.
*/
public int incr;
/**
* Constructs a new {@link IincInsnNode}.
*
* @param var
* index of the local variable to be incremented.
* @param incr
* increment amount to increment the local variable by.
*/
public IincInsnNode(final int var, final int incr) {
super(Opcodes.IINC);
this.var = var;
this.incr = incr;
}
@Override
public int getType() {
return IINC_INSN;
}
@Override
public void accept(final MethodVisitor mv) {
mv.visitIincInsn(var, incr);
acceptAnnotations(mv);
}
@Override
public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
return new IincInsnNode(var, incr).cloneAnnotations(this);
}
}

View File

@@ -0,0 +1,130 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* 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 jdk.internal.org.objectweb.asm.tree;
import jdk.internal.org.objectweb.asm.ClassVisitor;
/**
* A node that represents an inner class.
*
* @author Eric Bruneton
*/
public class InnerClassNode {
/**
* The internal name of an inner class (see
* {@link jdk.internal.org.objectweb.asm.Type#getInternalName() getInternalName}).
*/
public String name;
/**
* The internal name of the class to which the inner class belongs (see
* {@link jdk.internal.org.objectweb.asm.Type#getInternalName() getInternalName}). May be
* <tt>null</tt>.
*/
public String outerName;
/**
* The (simple) name of the inner class inside its enclosing class. May be
* <tt>null</tt> for anonymous inner classes.
*/
public String innerName;
/**
* The access flags of the inner class as originally declared in the
* enclosing class.
*/
public int access;
/**
* Constructs a new {@link InnerClassNode}.
*
* @param name
* the internal name of an inner class (see
* {@link jdk.internal.org.objectweb.asm.Type#getInternalName()
* getInternalName}).
* @param outerName
* the internal name of the class to which the inner class
* belongs (see {@link jdk.internal.org.objectweb.asm.Type#getInternalName()
* getInternalName}). May be <tt>null</tt>.
* @param innerName
* the (simple) name of the inner class inside its enclosing
* class. May be <tt>null</tt> for anonymous inner classes.
* @param access
* the access flags of the inner class as originally declared in
* the enclosing class.
*/
public InnerClassNode(final String name, final String outerName,
final String innerName, final int access) {
this.name = name;
this.outerName = outerName;
this.innerName = innerName;
this.access = access;
}
/**
* Makes the given class visitor visit this inner class.
*
* @param cv
* a class visitor.
*/
public void accept(final ClassVisitor cv) {
cv.visitInnerClass(name, outerName, innerName, access);
}
}

View File

@@ -0,0 +1,644 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* 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 jdk.internal.org.objectweb.asm.tree;
import java.util.ListIterator;
import java.util.NoSuchElementException;
import jdk.internal.org.objectweb.asm.MethodVisitor;
/**
* A doubly linked list of {@link AbstractInsnNode} objects. <i>This
* implementation is not thread safe</i>.
*/
public class InsnList {
/**
* The number of instructions in this list.
*/
private int size;
/**
* The first instruction in this list. May be <tt>null</tt>.
*/
private AbstractInsnNode first;
/**
* The last instruction in this list. May be <tt>null</tt>.
*/
private AbstractInsnNode last;
/**
* A cache of the instructions of this list. This cache is used to improve
* the performance of the {@link #get} method.
*/
AbstractInsnNode[] cache;
/**
* Returns the number of instructions in this list.
*
* @return the number of instructions in this list.
*/
public int size() {
return size;
}
/**
* Returns the first instruction in this list.
*
* @return the first instruction in this list, or <tt>null</tt> if the list
* is empty.
*/
public AbstractInsnNode getFirst() {
return first;
}
/**
* Returns the last instruction in this list.
*
* @return the last instruction in this list, or <tt>null</tt> if the list
* is empty.
*/
public AbstractInsnNode getLast() {
return last;
}
/**
* Returns the instruction whose index is given. This method builds a cache
* of the instructions in this list to avoid scanning the whole list each
* time it is called. Once the cache is built, this method run in constant
* time. This cache is invalidated by all the methods that modify the list.
*
* @param index
* the index of the instruction that must be returned.
* @return the instruction whose index is given.
* @throws IndexOutOfBoundsException
* if (index &lt; 0 || index &gt;= size()).
*/
public AbstractInsnNode get(final int index) {
if (index < 0 || index >= size) {
throw new IndexOutOfBoundsException();
}
if (cache == null) {
cache = toArray();
}
return cache[index];
}
/**
* Returns <tt>true</tt> if the given instruction belongs to this list. This
* method always scans the instructions of this list until it finds the
* given instruction or reaches the end of the list.
*
* @param insn
* an instruction.
* @return <tt>true</tt> if the given instruction belongs to this list.
*/
public boolean contains(final AbstractInsnNode insn) {
AbstractInsnNode i = first;
while (i != null && i != insn) {
i = i.next;
}
return i != null;
}
/**
* Returns the index of the given instruction in this list. This method
* builds a cache of the instruction indexes to avoid scanning the whole
* list each time it is called. Once the cache is built, this method run in
* constant time. The cache is invalidated by all the methods that modify
* the list.
*
* @param insn
* an instruction <i>of this list</i>.
* @return the index of the given instruction in this list. <i>The result of
* this method is undefined if the given instruction does not belong
* to this list</i>. Use {@link #contains contains} to test if an
* instruction belongs to an instruction list or not.
*/
public int indexOf(final AbstractInsnNode insn) {
if (cache == null) {
cache = toArray();
}
return insn.index;
}
/**
* Makes the given visitor visit all of the instructions in this list.
*
* @param mv
* the method visitor that must visit the instructions.
*/
public void accept(final MethodVisitor mv) {
AbstractInsnNode insn = first;
while (insn != null) {
insn.accept(mv);
insn = insn.next;
}
}
/**
* Returns an iterator over the instructions in this list.
*
* @return an iterator over the instructions in this list.
*/
public ListIterator<AbstractInsnNode> iterator() {
return iterator(0);
}
/**
* Returns an iterator over the instructions in this list.
*
* @return an iterator over the instructions in this list.
*/
@SuppressWarnings("unchecked")
public ListIterator<AbstractInsnNode> iterator(int index) {
return new InsnListIterator(index);
}
/**
* Returns an array containing all of the instructions in this list.
*
* @return an array containing all of the instructions in this list.
*/
public AbstractInsnNode[] toArray() {
int i = 0;
AbstractInsnNode elem = first;
AbstractInsnNode[] insns = new AbstractInsnNode[size];
while (elem != null) {
insns[i] = elem;
elem.index = i++;
elem = elem.next;
}
return insns;
}
/**
* Replaces an instruction of this list with another instruction.
*
* @param location
* an instruction <i>of this list</i>.
* @param insn
* another instruction, <i>which must not belong to any
* {@link InsnList}</i>.
*/
public void set(final AbstractInsnNode location, final AbstractInsnNode insn) {
AbstractInsnNode next = location.next;
insn.next = next;
if (next != null) {
next.prev = insn;
} else {
last = insn;
}
AbstractInsnNode prev = location.prev;
insn.prev = prev;
if (prev != null) {
prev.next = insn;
} else {
first = insn;
}
if (cache != null) {
int index = location.index;
cache[index] = insn;
insn.index = index;
} else {
insn.index = 0; // insn now belongs to an InsnList
}
location.index = -1; // i no longer belongs to an InsnList
location.prev = null;
location.next = null;
}
/**
* Adds the given instruction to the end of this list.
*
* @param insn
* an instruction, <i>which must not belong to any
* {@link InsnList}</i>.
*/
public void add(final AbstractInsnNode insn) {
++size;
if (last == null) {
first = insn;
last = insn;
} else {
last.next = insn;
insn.prev = last;
}
last = insn;
cache = null;
insn.index = 0; // insn now belongs to an InsnList
}
/**
* Adds the given instructions to the end of this list.
*
* @param insns
* an instruction list, which is cleared during the process. This
* list must be different from 'this'.
*/
public void add(final InsnList insns) {
if (insns.size == 0) {
return;
}
size += insns.size;
if (last == null) {
first = insns.first;
last = insns.last;
} else {
AbstractInsnNode elem = insns.first;
last.next = elem;
elem.prev = last;
last = insns.last;
}
cache = null;
insns.removeAll(false);
}
/**
* Inserts the given instruction at the begining of this list.
*
* @param insn
* an instruction, <i>which must not belong to any
* {@link InsnList}</i>.
*/
public void insert(final AbstractInsnNode insn) {
++size;
if (first == null) {
first = insn;
last = insn;
} else {
first.prev = insn;
insn.next = first;
}
first = insn;
cache = null;
insn.index = 0; // insn now belongs to an InsnList
}
/**
* Inserts the given instructions at the begining of this list.
*
* @param insns
* an instruction list, which is cleared during the process. This
* list must be different from 'this'.
*/
public void insert(final InsnList insns) {
if (insns.size == 0) {
return;
}
size += insns.size;
if (first == null) {
first = insns.first;
last = insns.last;
} else {
AbstractInsnNode elem = insns.last;
first.prev = elem;
elem.next = first;
first = insns.first;
}
cache = null;
insns.removeAll(false);
}
/**
* Inserts the given instruction after the specified instruction.
*
* @param location
* an instruction <i>of this list</i> after which insn must be
* inserted.
* @param insn
* the instruction to be inserted, <i>which must not belong to
* any {@link InsnList}</i>.
*/
public void insert(final AbstractInsnNode location,
final AbstractInsnNode insn) {
++size;
AbstractInsnNode next = location.next;
if (next == null) {
last = insn;
} else {
next.prev = insn;
}
location.next = insn;
insn.next = next;
insn.prev = location;
cache = null;
insn.index = 0; // insn now belongs to an InsnList
}
/**
* Inserts the given instructions after the specified instruction.
*
* @param location
* an instruction <i>of this list</i> after which the
* instructions must be inserted.
* @param insns
* the instruction list to be inserted, which is cleared during
* the process. This list must be different from 'this'.
*/
public void insert(final AbstractInsnNode location, final InsnList insns) {
if (insns.size == 0) {
return;
}
size += insns.size;
AbstractInsnNode ifirst = insns.first;
AbstractInsnNode ilast = insns.last;
AbstractInsnNode next = location.next;
if (next == null) {
last = ilast;
} else {
next.prev = ilast;
}
location.next = ifirst;
ilast.next = next;
ifirst.prev = location;
cache = null;
insns.removeAll(false);
}
/**
* Inserts the given instruction before the specified instruction.
*
* @param location
* an instruction <i>of this list</i> before which insn must be
* inserted.
* @param insn
* the instruction to be inserted, <i>which must not belong to
* any {@link InsnList}</i>.
*/
public void insertBefore(final AbstractInsnNode location,
final AbstractInsnNode insn) {
++size;
AbstractInsnNode prev = location.prev;
if (prev == null) {
first = insn;
} else {
prev.next = insn;
}
location.prev = insn;
insn.next = location;
insn.prev = prev;
cache = null;
insn.index = 0; // insn now belongs to an InsnList
}
/**
* Inserts the given instructions before the specified instruction.
*
* @param location
* an instruction <i>of this list</i> before which the
* instructions must be inserted.
* @param insns
* the instruction list to be inserted, which is cleared during
* the process. This list must be different from 'this'.
*/
public void insertBefore(final AbstractInsnNode location,
final InsnList insns) {
if (insns.size == 0) {
return;
}
size += insns.size;
AbstractInsnNode ifirst = insns.first;
AbstractInsnNode ilast = insns.last;
AbstractInsnNode prev = location.prev;
if (prev == null) {
first = ifirst;
} else {
prev.next = ifirst;
}
location.prev = ilast;
ilast.next = location;
ifirst.prev = prev;
cache = null;
insns.removeAll(false);
}
/**
* Removes the given instruction from this list.
*
* @param insn
* the instruction <i>of this list</i> that must be removed.
*/
public void remove(final AbstractInsnNode insn) {
--size;
AbstractInsnNode next = insn.next;
AbstractInsnNode prev = insn.prev;
if (next == null) {
if (prev == null) {
first = null;
last = null;
} else {
prev.next = null;
last = prev;
}
} else {
if (prev == null) {
first = next;
next.prev = null;
} else {
prev.next = next;
next.prev = prev;
}
}
cache = null;
insn.index = -1; // insn no longer belongs to an InsnList
insn.prev = null;
insn.next = null;
}
/**
* Removes all of the instructions of this list.
*
* @param mark
* if the instructions must be marked as no longer belonging to
* any {@link InsnList}.
*/
void removeAll(final boolean mark) {
if (mark) {
AbstractInsnNode insn = first;
while (insn != null) {
AbstractInsnNode next = insn.next;
insn.index = -1; // insn no longer belongs to an InsnList
insn.prev = null;
insn.next = null;
insn = next;
}
}
size = 0;
first = null;
last = null;
cache = null;
}
/**
* Removes all of the instructions of this list.
*/
public void clear() {
removeAll(false);
}
/**
* Reset all labels in the instruction list. This method should be called
* before reusing same instructions list between several
* <code>ClassWriter</code>s.
*/
public void resetLabels() {
AbstractInsnNode insn = first;
while (insn != null) {
if (insn instanceof LabelNode) {
((LabelNode) insn).resetLabel();
}
insn = insn.next;
}
}
// this class is not generified because it will create bridges
@SuppressWarnings("rawtypes")
private final class InsnListIterator implements ListIterator {
AbstractInsnNode next;
AbstractInsnNode prev;
AbstractInsnNode remove;
InsnListIterator(int index) {
if (index == size()) {
next = null;
prev = getLast();
} else {
next = get(index);
prev = next.prev;
}
}
public boolean hasNext() {
return next != null;
}
public Object next() {
if (next == null) {
throw new NoSuchElementException();
}
AbstractInsnNode result = next;
prev = result;
next = result.next;
remove = result;
return result;
}
public void remove() {
if (remove != null) {
if (remove == next) {
next = next.next;
} else {
prev = prev.prev;
}
InsnList.this.remove(remove);
remove = null;
} else {
throw new IllegalStateException();
}
}
public boolean hasPrevious() {
return prev != null;
}
public Object previous() {
AbstractInsnNode result = prev;
next = result;
prev = result.prev;
remove = result;
return result;
}
public int nextIndex() {
if (next == null) {
return size();
}
if (cache == null) {
cache = toArray();
}
return next.index;
}
public int previousIndex() {
if (prev == null) {
return -1;
}
if (cache == null) {
cache = toArray();
}
return prev.index;
}
public void add(Object o) {
InsnList.this.insertBefore(next, (AbstractInsnNode) o);
prev = (AbstractInsnNode) o;
remove = null;
}
public void set(Object o) {
InsnList.this.set(next.prev, (AbstractInsnNode) o);
prev = (AbstractInsnNode) o;
}
}
}

View File

@@ -0,0 +1,117 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* 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 jdk.internal.org.objectweb.asm.tree;
import java.util.Map;
import jdk.internal.org.objectweb.asm.MethodVisitor;
/**
* A node that represents a zero operand instruction.
*
* @author Eric Bruneton
*/
public class InsnNode extends AbstractInsnNode {
/**
* Constructs a new {@link InsnNode}.
*
* @param opcode
* the opcode of the instruction to be constructed. This opcode
* must be NOP, ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1,
* ICONST_2, ICONST_3, ICONST_4, ICONST_5, LCONST_0, LCONST_1,
* FCONST_0, FCONST_1, FCONST_2, DCONST_0, DCONST_1, IALOAD,
* LALOAD, FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, SALOAD,
* IASTORE, LASTORE, FASTORE, DASTORE, AASTORE, BASTORE, CASTORE,
* SASTORE, POP, POP2, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1,
* DUP2_X2, SWAP, IADD, LADD, FADD, DADD, ISUB, LSUB, FSUB, DSUB,
* IMUL, LMUL, FMUL, DMUL, IDIV, LDIV, FDIV, DDIV, IREM, LREM,
* FREM, DREM, INEG, LNEG, FNEG, DNEG, ISHL, LSHL, ISHR, LSHR,
* IUSHR, LUSHR, IAND, LAND, IOR, LOR, IXOR, LXOR, I2L, I2F, I2D,
* L2I, L2F, L2D, F2I, F2L, F2D, D2I, D2L, D2F, I2B, I2C, I2S,
* LCMP, FCMPL, FCMPG, DCMPL, DCMPG, IRETURN, LRETURN, FRETURN,
* DRETURN, ARETURN, RETURN, ARRAYLENGTH, ATHROW, MONITORENTER,
* or MONITOREXIT.
*/
public InsnNode(final int opcode) {
super(opcode);
}
@Override
public int getType() {
return INSN;
}
/**
* Makes the given visitor visit this instruction.
*
* @param mv
* a method visitor.
*/
@Override
public void accept(final MethodVisitor mv) {
mv.visitInsn(opcode);
acceptAnnotations(mv);
}
@Override
public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
return new InsnNode(opcode).cloneAnnotations(this);
}
}

View File

@@ -0,0 +1,117 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* 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 jdk.internal.org.objectweb.asm.tree;
import java.util.Map;
import jdk.internal.org.objectweb.asm.MethodVisitor;
/**
* A node that represents an instruction with a single int operand.
*
* @author Eric Bruneton
*/
public class IntInsnNode extends AbstractInsnNode {
/**
* The operand of this instruction.
*/
public int operand;
/**
* Constructs a new {@link IntInsnNode}.
*
* @param opcode
* the opcode of the instruction to be constructed. This opcode
* must be BIPUSH, SIPUSH or NEWARRAY.
* @param operand
* the operand of the instruction to be constructed.
*/
public IntInsnNode(final int opcode, final int operand) {
super(opcode);
this.operand = operand;
}
/**
* Sets the opcode of this instruction.
*
* @param opcode
* the new instruction opcode. This opcode must be BIPUSH, SIPUSH
* or NEWARRAY.
*/
public void setOpcode(final int opcode) {
this.opcode = opcode;
}
@Override
public int getType() {
return INT_INSN;
}
@Override
public void accept(final MethodVisitor mv) {
mv.visitIntInsn(opcode, operand);
acceptAnnotations(mv);
}
@Override
public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
return new IntInsnNode(opcode, operand).cloneAnnotations(this);
}
}

View File

@@ -0,0 +1,131 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* 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 jdk.internal.org.objectweb.asm.tree;
import java.util.Map;
import jdk.internal.org.objectweb.asm.Handle;
import jdk.internal.org.objectweb.asm.MethodVisitor;
import jdk.internal.org.objectweb.asm.Opcodes;
/**
* A node that represents an invokedynamic instruction.
*
* @author Remi Forax
*/
public class InvokeDynamicInsnNode extends AbstractInsnNode {
/**
* Invokedynamic name.
*/
public String name;
/**
* Invokedynamic descriptor.
*/
public String desc;
/**
* Bootstrap method
*/
public Handle bsm;
/**
* Bootstrap constant arguments
*/
public Object[] bsmArgs;
/**
* Constructs a new {@link InvokeDynamicInsnNode}.
*
* @param name
* invokedynamic name.
* @param desc
* invokedynamic descriptor (see {@link jdk.internal.org.objectweb.asm.Type}).
* @param bsm
* the bootstrap method.
* @param bsmArgs
* the boostrap constant arguments.
*/
public InvokeDynamicInsnNode(final String name, final String desc,
final Handle bsm, final Object... bsmArgs) {
super(Opcodes.INVOKEDYNAMIC);
this.name = name;
this.desc = desc;
this.bsm = bsm;
this.bsmArgs = bsmArgs;
}
@Override
public int getType() {
return INVOKE_DYNAMIC_INSN;
}
@Override
public void accept(final MethodVisitor mv) {
mv.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
acceptAnnotations(mv);
}
@Override
public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
return new InvokeDynamicInsnNode(name, desc, bsm, bsmArgs)
.cloneAnnotations(this);
}
}

View File

@@ -0,0 +1,126 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* 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 jdk.internal.org.objectweb.asm.tree;
import java.util.Map;
import jdk.internal.org.objectweb.asm.MethodVisitor;
/**
* A node that represents a jump instruction. A jump instruction is an
* instruction that may jump to another instruction.
*
* @author Eric Bruneton
*/
public class JumpInsnNode extends AbstractInsnNode {
/**
* The operand of this instruction. This operand is a label that designates
* the instruction to which this instruction may jump.
*/
public LabelNode label;
/**
* Constructs a new {@link JumpInsnNode}.
*
* @param opcode
* the opcode of the type instruction to be constructed. This
* opcode must be IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ,
* IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE,
* IF_ACMPEQ, IF_ACMPNE, GOTO, JSR, IFNULL or IFNONNULL.
* @param label
* the operand of the instruction to be constructed. This operand
* is a label that designates the instruction to which the jump
* instruction may jump.
*/
public JumpInsnNode(final int opcode, final LabelNode label) {
super(opcode);
this.label = label;
}
/**
* Sets the opcode of this instruction.
*
* @param opcode
* the new instruction opcode. This opcode must be IFEQ, IFNE,
* IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT,
* IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ACMPEQ, IF_ACMPNE, GOTO,
* JSR, IFNULL or IFNONNULL.
*/
public void setOpcode(final int opcode) {
this.opcode = opcode;
}
@Override
public int getType() {
return JUMP_INSN;
}
@Override
public void accept(final MethodVisitor mv) {
mv.visitJumpInsn(opcode, label.getLabel());
acceptAnnotations(mv);
}
@Override
public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
return new JumpInsnNode(opcode, clone(label, labels))
.cloneAnnotations(this);
}
}

View File

@@ -0,0 +1,107 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* 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 jdk.internal.org.objectweb.asm.tree;
import java.util.Map;
import jdk.internal.org.objectweb.asm.Label;
import jdk.internal.org.objectweb.asm.MethodVisitor;
/**
* An {@link AbstractInsnNode} that encapsulates a {@link Label}.
*/
public class LabelNode extends AbstractInsnNode {
private Label label;
public LabelNode() {
super(-1);
}
public LabelNode(final Label label) {
super(-1);
this.label = label;
}
@Override
public int getType() {
return LABEL;
}
public Label getLabel() {
if (label == null) {
label = new Label();
}
return label;
}
@Override
public void accept(final MethodVisitor cv) {
cv.visitLabel(getLabel());
}
@Override
public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
return labels.get(this);
}
public void resetLabel() {
label = null;
}
}

View File

@@ -0,0 +1,108 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* 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 jdk.internal.org.objectweb.asm.tree;
import java.util.Map;
import jdk.internal.org.objectweb.asm.MethodVisitor;
import jdk.internal.org.objectweb.asm.Opcodes;
/**
* A node that represents an LDC instruction.
*
* @author Eric Bruneton
*/
public class LdcInsnNode extends AbstractInsnNode {
/**
* The constant to be loaded on the stack. This parameter must be a non null
* {@link Integer}, a {@link Float}, a {@link Long}, a {@link Double}, a
* {@link String} or a {@link jdk.internal.org.objectweb.asm.Type}.
*/
public Object cst;
/**
* Constructs a new {@link LdcInsnNode}.
*
* @param cst
* the constant to be loaded on the stack. This parameter must be
* a non null {@link Integer}, a {@link Float}, a {@link Long}, a
* {@link Double} or a {@link String}.
*/
public LdcInsnNode(final Object cst) {
super(Opcodes.LDC);
this.cst = cst;
}
@Override
public int getType() {
return LDC_INSN;
}
@Override
public void accept(final MethodVisitor mv) {
mv.visitLdcInsn(cst);
acceptAnnotations(mv);
}
@Override
public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
return new LdcInsnNode(cst).cloneAnnotations(this);
}
}

View File

@@ -0,0 +1,113 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* 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 jdk.internal.org.objectweb.asm.tree;
import java.util.Map;
import jdk.internal.org.objectweb.asm.MethodVisitor;
/**
* A node that represents a line number declaration. These nodes are pseudo
* instruction nodes in order to be inserted in an instruction list.
*
* @author Eric Bruneton
*/
public class LineNumberNode extends AbstractInsnNode {
/**
* A line number. This number refers to the source file from which the class
* was compiled.
*/
public int line;
/**
* The first instruction corresponding to this line number.
*/
public LabelNode start;
/**
* Constructs a new {@link LineNumberNode}.
*
* @param line
* a line number. This number refers to the source file from
* which the class was compiled.
* @param start
* the first instruction corresponding to this line number.
*/
public LineNumberNode(final int line, final LabelNode start) {
super(-1);
this.line = line;
this.start = start;
}
@Override
public int getType() {
return LINE;
}
@Override
public void accept(final MethodVisitor mv) {
mv.visitLineNumber(line, start.getLabel());
}
@Override
public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
return new LineNumberNode(line, clone(start, labels));
}
}

View File

@@ -0,0 +1,186 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* 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 jdk.internal.org.objectweb.asm.tree;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import jdk.internal.org.objectweb.asm.Label;
import jdk.internal.org.objectweb.asm.MethodVisitor;
import jdk.internal.org.objectweb.asm.Opcodes;
import jdk.internal.org.objectweb.asm.TypePath;
import jdk.internal.org.objectweb.asm.TypeReference;
/**
* A node that represents a type annotation on a local or resource variable.
*
* @author Eric Bruneton
*/
public class LocalVariableAnnotationNode extends TypeAnnotationNode {
/**
* The fist instructions corresponding to the continuous ranges that make
* the scope of this local variable (inclusive). Must not be <tt>null</tt>.
*/
public List<LabelNode> start;
/**
* The last instructions corresponding to the continuous ranges that make
* the scope of this local variable (exclusive). This list must have the
* same size as the 'start' list. Must not be <tt>null</tt>.
*/
public List<LabelNode> end;
/**
* The local variable's index in each range. This list must have the same
* size as the 'start' list. Must not be <tt>null</tt>.
*/
public List<Integer> index;
/**
* Constructs a new {@link LocalVariableAnnotationNode}. <i>Subclasses must
* not use this constructor</i>. Instead, they must use the
* {@link #LocalVariableAnnotationNode(int, TypePath, LabelNode[], LabelNode[], int[], String)}
* version.
*
* @param typeRef
* a reference to the annotated type. See {@link TypeReference}.
* @param typePath
* the path to the annotated type argument, wildcard bound, array
* element type, or static inner type within 'typeRef'. May be
* <tt>null</tt> if the annotation targets 'typeRef' as a whole.
* @param start
* the fist instructions corresponding to the continuous ranges
* that make the scope of this local variable (inclusive).
* @param end
* the last instructions corresponding to the continuous ranges
* that make the scope of this local variable (exclusive). This
* array must have the same size as the 'start' array.
* @param index
* the local variable's index in each range. This array must have
* the same size as the 'start' array.
* @param desc
* the class descriptor of the annotation class.
*/
public LocalVariableAnnotationNode(int typeRef, TypePath typePath,
LabelNode[] start, LabelNode[] end, int[] index, String desc) {
this(Opcodes.ASM5, typeRef, typePath, start, end, index, desc);
}
/**
* Constructs a new {@link LocalVariableAnnotationNode}.
*
* @param api
* the ASM API version implemented by this visitor. Must be one
* of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
* @param typeRef
* a reference to the annotated type. See {@link TypeReference}.
* @param start
* the fist instructions corresponding to the continuous ranges
* that make the scope of this local variable (inclusive).
* @param end
* the last instructions corresponding to the continuous ranges
* that make the scope of this local variable (exclusive). This
* array must have the same size as the 'start' array.
* @param index
* the local variable's index in each range. This array must have
* the same size as the 'start' array.
* @param typePath
* the path to the annotated type argument, wildcard bound, array
* element type, or static inner type within 'typeRef'. May be
* <tt>null</tt> if the annotation targets 'typeRef' as a whole.
* @param desc
* the class descriptor of the annotation class.
*/
public LocalVariableAnnotationNode(int api, int typeRef, TypePath typePath,
LabelNode[] start, LabelNode[] end, int[] index, String desc) {
super(api, typeRef, typePath, desc);
this.start = new ArrayList<LabelNode>(start.length);
this.start.addAll(Arrays.asList(start));
this.end = new ArrayList<LabelNode>(end.length);
this.end.addAll(Arrays.asList(end));
this.index = new ArrayList<Integer>(index.length);
for (int i : index) {
this.index.add(i);
}
}
/**
* Makes the given visitor visit this type annotation.
*
* @param mv
* the visitor that must visit this annotation.
* @param visible
* <tt>true</tt> if the annotation is visible at runtime.
*/
public void accept(final MethodVisitor mv, boolean visible) {
Label[] start = new Label[this.start.size()];
Label[] end = new Label[this.end.size()];
int[] index = new int[this.index.size()];
for (int i = 0; i < start.length; ++i) {
start[i] = this.start.get(i).getLabel();
end[i] = this.end.get(i).getLabel();
index[i] = this.index.get(i);
}
accept(mv.visitLocalVariableAnnotation(typeRef, typePath, start, end,
index, desc, true));
}
}

View File

@@ -0,0 +1,141 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* 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 jdk.internal.org.objectweb.asm.tree;
import jdk.internal.org.objectweb.asm.MethodVisitor;
/**
* A node that represents a local variable declaration.
*
* @author Eric Bruneton
*/
public class LocalVariableNode {
/**
* The name of a local variable.
*/
public String name;
/**
* The type descriptor of this local variable.
*/
public String desc;
/**
* The signature of this local variable. May be <tt>null</tt>.
*/
public String signature;
/**
* The first instruction corresponding to the scope of this local variable
* (inclusive).
*/
public LabelNode start;
/**
* The last instruction corresponding to the scope of this local variable
* (exclusive).
*/
public LabelNode end;
/**
* The local variable's index.
*/
public int index;
/**
* Constructs a new {@link LocalVariableNode}.
*
* @param name
* the name of a local variable.
* @param desc
* the type descriptor of this local variable.
* @param signature
* the signature of this local variable. May be <tt>null</tt>.
* @param start
* the first instruction corresponding to the scope of this local
* variable (inclusive).
* @param end
* the last instruction corresponding to the scope of this local
* variable (exclusive).
* @param index
* the local variable's index.
*/
public LocalVariableNode(final String name, final String desc,
final String signature, final LabelNode start, final LabelNode end,
final int index) {
this.name = name;
this.desc = desc;
this.signature = signature;
this.start = start;
this.end = end;
this.index = index;
}
/**
* Makes the given visitor visit this local variable declaration.
*
* @param mv
* a method visitor.
*/
public void accept(final MethodVisitor mv) {
mv.visitLocalVariable(name, desc, signature, start.getLabel(),
end.getLabel(), index);
}
}

View File

@@ -0,0 +1,147 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* 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 jdk.internal.org.objectweb.asm.tree;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import jdk.internal.org.objectweb.asm.Label;
import jdk.internal.org.objectweb.asm.MethodVisitor;
import jdk.internal.org.objectweb.asm.Opcodes;
/**
* A node that represents a LOOKUPSWITCH instruction.
*
* @author Eric Bruneton
*/
public class LookupSwitchInsnNode extends AbstractInsnNode {
/**
* Beginning of the default handler block.
*/
public LabelNode dflt;
/**
* The values of the keys. This list is a list of {@link Integer} objects.
*/
public List<Integer> keys;
/**
* Beginnings of the handler blocks. This list is a list of
* {@link LabelNode} objects.
*/
public List<LabelNode> labels;
/**
* Constructs a new {@link LookupSwitchInsnNode}.
*
* @param dflt
* beginning of the default handler block.
* @param keys
* the values of the keys.
* @param labels
* beginnings of the handler blocks. <tt>labels[i]</tt> is the
* beginning of the handler block for the <tt>keys[i]</tt> key.
*/
public LookupSwitchInsnNode(final LabelNode dflt, final int[] keys,
final LabelNode[] labels) {
super(Opcodes.LOOKUPSWITCH);
this.dflt = dflt;
this.keys = new ArrayList<Integer>(keys == null ? 0 : keys.length);
this.labels = new ArrayList<LabelNode>(labels == null ? 0
: labels.length);
if (keys != null) {
for (int i = 0; i < keys.length; ++i) {
this.keys.add(keys[i]);
}
}
if (labels != null) {
this.labels.addAll(Arrays.asList(labels));
}
}
@Override
public int getType() {
return LOOKUPSWITCH_INSN;
}
@Override
public void accept(final MethodVisitor mv) {
int[] keys = new int[this.keys.size()];
for (int i = 0; i < keys.length; ++i) {
keys[i] = this.keys.get(i).intValue();
}
Label[] labels = new Label[this.labels.size()];
for (int i = 0; i < labels.length; ++i) {
labels[i] = this.labels.get(i).getLabel();
}
mv.visitLookupSwitchInsn(dflt.getLabel(), keys, labels);
acceptAnnotations(mv);
}
@Override
public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
LookupSwitchInsnNode clone = new LookupSwitchInsnNode(clone(dflt,
labels), null, clone(this.labels, labels));
clone.keys.addAll(keys);
return clone.cloneAnnotations(this);
}
}

View File

@@ -0,0 +1,170 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* 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 jdk.internal.org.objectweb.asm.tree;
import java.util.Map;
import jdk.internal.org.objectweb.asm.MethodVisitor;
import jdk.internal.org.objectweb.asm.Opcodes;
/**
* A node that represents a method instruction. A method instruction is an
* instruction that invokes a method.
*
* @author Eric Bruneton
*/
public class MethodInsnNode extends AbstractInsnNode {
/**
* The internal name of the method's owner class (see
* {@link jdk.internal.org.objectweb.asm.Type#getInternalName() getInternalName}).
*/
public String owner;
/**
* The method's name.
*/
public String name;
/**
* The method's descriptor (see {@link jdk.internal.org.objectweb.asm.Type}).
*/
public String desc;
/**
* If the method's owner class if an interface.
*/
public boolean itf;
/**
* Constructs a new {@link MethodInsnNode}.
*
* @param opcode
* the opcode of the type instruction to be constructed. This
* opcode must be INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or
* INVOKEINTERFACE.
* @param owner
* the internal name of the method's owner class (see
* {@link jdk.internal.org.objectweb.asm.Type#getInternalName()
* getInternalName}).
* @param name
* the method's name.
* @param desc
* the method's descriptor (see {@link jdk.internal.org.objectweb.asm.Type}).
*/
@Deprecated
public MethodInsnNode(final int opcode, final String owner,
final String name, final String desc) {
this(opcode, owner, name, desc, opcode == Opcodes.INVOKEINTERFACE);
}
/**
* Constructs a new {@link MethodInsnNode}.
*
* @param opcode
* the opcode of the type instruction to be constructed. This
* opcode must be INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or
* INVOKEINTERFACE.
* @param owner
* the internal name of the method's owner class (see
* {@link jdk.internal.org.objectweb.asm.Type#getInternalName()
* getInternalName}).
* @param name
* the method's name.
* @param desc
* the method's descriptor (see {@link jdk.internal.org.objectweb.asm.Type}).
* @param itf
* if the method's owner class is an interface.
*/
public MethodInsnNode(final int opcode, final String owner,
final String name, final String desc, final boolean itf) {
super(opcode);
this.owner = owner;
this.name = name;
this.desc = desc;
this.itf = itf;
}
/**
* Sets the opcode of this instruction.
*
* @param opcode
* the new instruction opcode. This opcode must be INVOKEVIRTUAL,
* INVOKESPECIAL, INVOKESTATIC or INVOKEINTERFACE.
*/
public void setOpcode(final int opcode) {
this.opcode = opcode;
}
@Override
public int getType() {
return METHOD_INSN;
}
@Override
public void accept(final MethodVisitor mv) {
mv.visitMethodInsn(opcode, owner, name, desc, itf);
acceptAnnotations(mv);
}
@Override
public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
return new MethodInsnNode(opcode, owner, name, desc, itf);
}
}

View File

@@ -0,0 +1,869 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* 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 jdk.internal.org.objectweb.asm.tree;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import jdk.internal.org.objectweb.asm.AnnotationVisitor;
import jdk.internal.org.objectweb.asm.Attribute;
import jdk.internal.org.objectweb.asm.ClassVisitor;
import jdk.internal.org.objectweb.asm.Handle;
import jdk.internal.org.objectweb.asm.Label;
import jdk.internal.org.objectweb.asm.MethodVisitor;
import jdk.internal.org.objectweb.asm.Opcodes;
import jdk.internal.org.objectweb.asm.Type;
import jdk.internal.org.objectweb.asm.TypePath;
/**
* A node that represents a method.
*
* @author Eric Bruneton
*/
public class MethodNode extends MethodVisitor {
/**
* The method's access flags (see {@link Opcodes}). This field also
* indicates if the method is synthetic and/or deprecated.
*/
public int access;
/**
* The method's name.
*/
public String name;
/**
* The method's descriptor (see {@link Type}).
*/
public String desc;
/**
* The method's signature. May be <tt>null</tt>.
*/
public String signature;
/**
* The internal names of the method's exception classes (see
* {@link Type#getInternalName() getInternalName}). This list is a list of
* {@link String} objects.
*/
public List<String> exceptions;
/**
* The method parameter info (access flags and name)
*/
public List<ParameterNode> parameters;
/**
* The runtime visible annotations of this method. This list is a list of
* {@link AnnotationNode} objects. May be <tt>null</tt>.
*
* @associates jdk.internal.org.objectweb.asm.tree.AnnotationNode
* @label visible
*/
public List<AnnotationNode> visibleAnnotations;
/**
* The runtime invisible annotations of this method. This list is a list of
* {@link AnnotationNode} objects. May be <tt>null</tt>.
*
* @associates jdk.internal.org.objectweb.asm.tree.AnnotationNode
* @label invisible
*/
public List<AnnotationNode> invisibleAnnotations;
/**
* The runtime visible type annotations of this method. This list is a list
* of {@link TypeAnnotationNode} objects. May be <tt>null</tt>.
*
* @associates jdk.internal.org.objectweb.asm.tree.TypeAnnotationNode
* @label visible
*/
public List<TypeAnnotationNode> visibleTypeAnnotations;
/**
* The runtime invisible type annotations of this method. This list is a
* list of {@link TypeAnnotationNode} objects. May be <tt>null</tt>.
*
* @associates jdk.internal.org.objectweb.asm.tree.TypeAnnotationNode
* @label invisible
*/
public List<TypeAnnotationNode> invisibleTypeAnnotations;
/**
* The non standard attributes of this method. This list is a list of
* {@link Attribute} objects. May be <tt>null</tt>.
*
* @associates jdk.internal.org.objectweb.asm.Attribute
*/
public List<Attribute> attrs;
/**
* The default value of this annotation interface method. This field must be
* a {@link Byte}, {@link Boolean}, {@link Character}, {@link Short},
* {@link Integer}, {@link Long}, {@link Float}, {@link Double},
* {@link String} or {@link Type}, or an two elements String array (for
* enumeration values), a {@link AnnotationNode}, or a {@link List} of
* values of one of the preceding types. May be <tt>null</tt>.
*/
public Object annotationDefault;
/**
* The runtime visible parameter annotations of this method. These lists are
* lists of {@link AnnotationNode} objects. May be <tt>null</tt>.
*
* @associates jdk.internal.org.objectweb.asm.tree.AnnotationNode
* @label invisible parameters
*/
public List<AnnotationNode>[] visibleParameterAnnotations;
/**
* The runtime invisible parameter annotations of this method. These lists
* are lists of {@link AnnotationNode} objects. May be <tt>null</tt>.
*
* @associates jdk.internal.org.objectweb.asm.tree.AnnotationNode
* @label visible parameters
*/
public List<AnnotationNode>[] invisibleParameterAnnotations;
/**
* The instructions of this method. This list is a list of
* {@link AbstractInsnNode} objects.
*
* @associates jdk.internal.org.objectweb.asm.tree.AbstractInsnNode
* @label instructions
*/
public InsnList instructions;
/**
* The try catch blocks of this method. This list is a list of
* {@link TryCatchBlockNode} objects.
*
* @associates jdk.internal.org.objectweb.asm.tree.TryCatchBlockNode
*/
public List<TryCatchBlockNode> tryCatchBlocks;
/**
* The maximum stack size of this method.
*/
public int maxStack;
/**
* The maximum number of local variables of this method.
*/
public int maxLocals;
/**
* The local variables of this method. This list is a list of
* {@link LocalVariableNode} objects. May be <tt>null</tt>
*
* @associates jdk.internal.org.objectweb.asm.tree.LocalVariableNode
*/
public List<LocalVariableNode> localVariables;
/**
* The visible local variable annotations of this method. This list is a
* list of {@link LocalVariableAnnotationNode} objects. May be <tt>null</tt>
*
* @associates jdk.internal.org.objectweb.asm.tree.LocalVariableAnnotationNode
*/
public List<LocalVariableAnnotationNode> visibleLocalVariableAnnotations;
/**
* The invisible local variable annotations of this method. This list is a
* list of {@link LocalVariableAnnotationNode} objects. May be <tt>null</tt>
*
* @associates jdk.internal.org.objectweb.asm.tree.LocalVariableAnnotationNode
*/
public List<LocalVariableAnnotationNode> invisibleLocalVariableAnnotations;
/**
* If the accept method has been called on this object.
*/
private boolean visited;
/**
* Constructs an uninitialized {@link MethodNode}. <i>Subclasses must not
* use this constructor</i>. Instead, they must use the
* {@link #MethodNode(int)} version.
*
* @throws IllegalStateException
* If a subclass calls this constructor.
*/
public MethodNode() {
this(Opcodes.ASM5);
if (getClass() != MethodNode.class) {
throw new IllegalStateException();
}
}
/**
* Constructs an uninitialized {@link MethodNode}.
*
* @param api
* the ASM API version implemented by this visitor. Must be one
* of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
*/
public MethodNode(final int api) {
super(api);
this.instructions = new InsnList();
}
/**
* Constructs a new {@link MethodNode}. <i>Subclasses must not use this
* constructor</i>. Instead, they must use the
* {@link #MethodNode(int, int, String, String, String, String[])} version.
*
* @param access
* the method's access flags (see {@link Opcodes}). This
* parameter also indicates if the method is synthetic and/or
* deprecated.
* @param name
* the method's name.
* @param desc
* the method's descriptor (see {@link Type}).
* @param signature
* the method's signature. May be <tt>null</tt>.
* @param exceptions
* the internal names of the method's exception classes (see
* {@link Type#getInternalName() getInternalName}). May be
* <tt>null</tt>.
* @throws IllegalStateException
* If a subclass calls this constructor.
*/
public MethodNode(final int access, final String name, final String desc,
final String signature, final String[] exceptions) {
this(Opcodes.ASM5, access, name, desc, signature, exceptions);
if (getClass() != MethodNode.class) {
throw new IllegalStateException();
}
}
/**
* Constructs a new {@link MethodNode}.
*
* @param api
* the ASM API version implemented by this visitor. Must be one
* of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
* @param access
* the method's access flags (see {@link Opcodes}). This
* parameter also indicates if the method is synthetic and/or
* deprecated.
* @param name
* the method's name.
* @param desc
* the method's descriptor (see {@link Type}).
* @param signature
* the method's signature. May be <tt>null</tt>.
* @param exceptions
* the internal names of the method's exception classes (see
* {@link Type#getInternalName() getInternalName}). May be
* <tt>null</tt>.
*/
public MethodNode(final int api, final int access, final String name,
final String desc, final String signature, final String[] exceptions) {
super(api);
this.access = access;
this.name = name;
this.desc = desc;
this.signature = signature;
this.exceptions = new ArrayList<String>(exceptions == null ? 0
: exceptions.length);
boolean isAbstract = (access & Opcodes.ACC_ABSTRACT) != 0;
if (!isAbstract) {
this.localVariables = new ArrayList<LocalVariableNode>(5);
}
this.tryCatchBlocks = new ArrayList<TryCatchBlockNode>();
if (exceptions != null) {
this.exceptions.addAll(Arrays.asList(exceptions));
}
this.instructions = new InsnList();
}
// ------------------------------------------------------------------------
// Implementation of the MethodVisitor abstract class
// ------------------------------------------------------------------------
@Override
public void visitParameter(String name, int access) {
if (parameters == null) {
parameters = new ArrayList<ParameterNode>(5);
}
parameters.add(new ParameterNode(name, access));
}
@Override
@SuppressWarnings("serial")
public AnnotationVisitor visitAnnotationDefault() {
return new AnnotationNode(new ArrayList<Object>(0) {
@Override
public boolean add(final Object o) {
annotationDefault = o;
return super.add(o);
}
});
}
@Override
public AnnotationVisitor visitAnnotation(final String desc,
final boolean visible) {
AnnotationNode an = new AnnotationNode(desc);
if (visible) {
if (visibleAnnotations == null) {
visibleAnnotations = new ArrayList<AnnotationNode>(1);
}
visibleAnnotations.add(an);
} else {
if (invisibleAnnotations == null) {
invisibleAnnotations = new ArrayList<AnnotationNode>(1);
}
invisibleAnnotations.add(an);
}
return an;
}
@Override
public AnnotationVisitor visitTypeAnnotation(int typeRef,
TypePath typePath, String desc, boolean visible) {
TypeAnnotationNode an = new TypeAnnotationNode(typeRef, typePath, desc);
if (visible) {
if (visibleTypeAnnotations == null) {
visibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(1);
}
visibleTypeAnnotations.add(an);
} else {
if (invisibleTypeAnnotations == null) {
invisibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(1);
}
invisibleTypeAnnotations.add(an);
}
return an;
}
@Override
@SuppressWarnings("unchecked")
public AnnotationVisitor visitParameterAnnotation(final int parameter,
final String desc, final boolean visible) {
AnnotationNode an = new AnnotationNode(desc);
if (visible) {
if (visibleParameterAnnotations == null) {
int params = Type.getArgumentTypes(this.desc).length;
visibleParameterAnnotations = (List<AnnotationNode>[]) new List<?>[params];
}
if (visibleParameterAnnotations[parameter] == null) {
visibleParameterAnnotations[parameter] = new ArrayList<AnnotationNode>(
1);
}
visibleParameterAnnotations[parameter].add(an);
} else {
if (invisibleParameterAnnotations == null) {
int params = Type.getArgumentTypes(this.desc).length;
invisibleParameterAnnotations = (List<AnnotationNode>[]) new List<?>[params];
}
if (invisibleParameterAnnotations[parameter] == null) {
invisibleParameterAnnotations[parameter] = new ArrayList<AnnotationNode>(
1);
}
invisibleParameterAnnotations[parameter].add(an);
}
return an;
}
@Override
public void visitAttribute(final Attribute attr) {
if (attrs == null) {
attrs = new ArrayList<Attribute>(1);
}
attrs.add(attr);
}
@Override
public void visitCode() {
}
@Override
public void visitFrame(final int type, final int nLocal,
final Object[] local, final int nStack, final Object[] stack) {
instructions.add(new FrameNode(type, nLocal, local == null ? null
: getLabelNodes(local), nStack, stack == null ? null
: getLabelNodes(stack)));
}
@Override
public void visitInsn(final int opcode) {
instructions.add(new InsnNode(opcode));
}
@Override
public void visitIntInsn(final int opcode, final int operand) {
instructions.add(new IntInsnNode(opcode, operand));
}
@Override
public void visitVarInsn(final int opcode, final int var) {
instructions.add(new VarInsnNode(opcode, var));
}
@Override
public void visitTypeInsn(final int opcode, final String type) {
instructions.add(new TypeInsnNode(opcode, type));
}
@Override
public void visitFieldInsn(final int opcode, final String owner,
final String name, final String desc) {
instructions.add(new FieldInsnNode(opcode, owner, name, desc));
}
@Deprecated
@Override
public void visitMethodInsn(int opcode, String owner, String name,
String desc) {
if (api >= Opcodes.ASM5) {
super.visitMethodInsn(opcode, owner, name, desc);
return;
}
instructions.add(new MethodInsnNode(opcode, owner, name, desc));
}
@Override
public void visitMethodInsn(int opcode, String owner, String name,
String desc, boolean itf) {
if (api < Opcodes.ASM5) {
super.visitMethodInsn(opcode, owner, name, desc, itf);
return;
}
instructions.add(new MethodInsnNode(opcode, owner, name, desc, itf));
}
@Override
public void visitInvokeDynamicInsn(String name, String desc, Handle bsm,
Object... bsmArgs) {
instructions.add(new InvokeDynamicInsnNode(name, desc, bsm, bsmArgs));
}
@Override
public void visitJumpInsn(final int opcode, final Label label) {
instructions.add(new JumpInsnNode(opcode, getLabelNode(label)));
}
@Override
public void visitLabel(final Label label) {
instructions.add(getLabelNode(label));
}
@Override
public void visitLdcInsn(final Object cst) {
instructions.add(new LdcInsnNode(cst));
}
@Override
public void visitIincInsn(final int var, final int increment) {
instructions.add(new IincInsnNode(var, increment));
}
@Override
public void visitTableSwitchInsn(final int min, final int max,
final Label dflt, final Label... labels) {
instructions.add(new TableSwitchInsnNode(min, max, getLabelNode(dflt),
getLabelNodes(labels)));
}
@Override
public void visitLookupSwitchInsn(final Label dflt, final int[] keys,
final Label[] labels) {
instructions.add(new LookupSwitchInsnNode(getLabelNode(dflt), keys,
getLabelNodes(labels)));
}
@Override
public void visitMultiANewArrayInsn(final String desc, final int dims) {
instructions.add(new MultiANewArrayInsnNode(desc, dims));
}
@Override
public AnnotationVisitor visitInsnAnnotation(int typeRef,
TypePath typePath, String desc, boolean visible) {
// Finds the last real instruction, i.e. the instruction targeted by
// this annotation.
AbstractInsnNode insn = instructions.getLast();
while (insn.getOpcode() == -1) {
insn = insn.getPrevious();
}
// Adds the annotation to this instruction.
TypeAnnotationNode an = new TypeAnnotationNode(typeRef, typePath, desc);
if (visible) {
if (insn.visibleTypeAnnotations == null) {
insn.visibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(
1);
}
insn.visibleTypeAnnotations.add(an);
} else {
if (insn.invisibleTypeAnnotations == null) {
insn.invisibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(
1);
}
insn.invisibleTypeAnnotations.add(an);
}
return an;
}
@Override
public void visitTryCatchBlock(final Label start, final Label end,
final Label handler, final String type) {
tryCatchBlocks.add(new TryCatchBlockNode(getLabelNode(start),
getLabelNode(end), getLabelNode(handler), type));
}
@Override
public AnnotationVisitor visitTryCatchAnnotation(int typeRef,
TypePath typePath, String desc, boolean visible) {
TryCatchBlockNode tcb = tryCatchBlocks.get((typeRef & 0x00FFFF00) >> 8);
TypeAnnotationNode an = new TypeAnnotationNode(typeRef, typePath, desc);
if (visible) {
if (tcb.visibleTypeAnnotations == null) {
tcb.visibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(
1);
}
tcb.visibleTypeAnnotations.add(an);
} else {
if (tcb.invisibleTypeAnnotations == null) {
tcb.invisibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(
1);
}
tcb.invisibleTypeAnnotations.add(an);
}
return an;
}
@Override
public void visitLocalVariable(final String name, final String desc,
final String signature, final Label start, final Label end,
final int index) {
localVariables.add(new LocalVariableNode(name, desc, signature,
getLabelNode(start), getLabelNode(end), index));
}
@Override
public AnnotationVisitor visitLocalVariableAnnotation(int typeRef,
TypePath typePath, Label[] start, Label[] end, int[] index,
String desc, boolean visible) {
LocalVariableAnnotationNode an = new LocalVariableAnnotationNode(
typeRef, typePath, getLabelNodes(start), getLabelNodes(end),
index, desc);
if (visible) {
if (visibleLocalVariableAnnotations == null) {
visibleLocalVariableAnnotations = new ArrayList<LocalVariableAnnotationNode>(
1);
}
visibleLocalVariableAnnotations.add(an);
} else {
if (invisibleLocalVariableAnnotations == null) {
invisibleLocalVariableAnnotations = new ArrayList<LocalVariableAnnotationNode>(
1);
}
invisibleLocalVariableAnnotations.add(an);
}
return an;
}
@Override
public void visitLineNumber(final int line, final Label start) {
instructions.add(new LineNumberNode(line, getLabelNode(start)));
}
@Override
public void visitMaxs(final int maxStack, final int maxLocals) {
this.maxStack = maxStack;
this.maxLocals = maxLocals;
}
@Override
public void visitEnd() {
}
/**
* Returns the LabelNode corresponding to the given Label. Creates a new
* LabelNode if necessary. The default implementation of this method uses
* the {@link Label#info} field to store associations between labels and
* label nodes.
*
* @param l
* a Label.
* @return the LabelNode corresponding to l.
*/
protected LabelNode getLabelNode(final Label l) {
if (!(l.info instanceof LabelNode)) {
l.info = new LabelNode();
}
return (LabelNode) l.info;
}
private LabelNode[] getLabelNodes(final Label[] l) {
LabelNode[] nodes = new LabelNode[l.length];
for (int i = 0; i < l.length; ++i) {
nodes[i] = getLabelNode(l[i]);
}
return nodes;
}
private Object[] getLabelNodes(final Object[] objs) {
Object[] nodes = new Object[objs.length];
for (int i = 0; i < objs.length; ++i) {
Object o = objs[i];
if (o instanceof Label) {
o = getLabelNode((Label) o);
}
nodes[i] = o;
}
return nodes;
}
// ------------------------------------------------------------------------
// Accept method
// ------------------------------------------------------------------------
/**
* Checks that this method node is compatible with the given ASM API
* version. This methods checks that this node, and all its nodes
* recursively, do not contain elements that were introduced in more recent
* versions of the ASM API than the given version.
*
* @param api
* an ASM API version. Must be one of {@link Opcodes#ASM4} or
* {@link Opcodes#ASM5}.
*/
public void check(final int api) {
if (api == Opcodes.ASM4) {
if (visibleTypeAnnotations != null
&& visibleTypeAnnotations.size() > 0) {
throw new RuntimeException();
}
if (invisibleTypeAnnotations != null
&& invisibleTypeAnnotations.size() > 0) {
throw new RuntimeException();
}
int n = tryCatchBlocks == null ? 0 : tryCatchBlocks.size();
for (int i = 0; i < n; ++i) {
TryCatchBlockNode tcb = tryCatchBlocks.get(i);
if (tcb.visibleTypeAnnotations != null
&& tcb.visibleTypeAnnotations.size() > 0) {
throw new RuntimeException();
}
if (tcb.invisibleTypeAnnotations != null
&& tcb.invisibleTypeAnnotations.size() > 0) {
throw new RuntimeException();
}
}
for (int i = 0; i < instructions.size(); ++i) {
AbstractInsnNode insn = instructions.get(i);
if (insn.visibleTypeAnnotations != null
&& insn.visibleTypeAnnotations.size() > 0) {
throw new RuntimeException();
}
if (insn.invisibleTypeAnnotations != null
&& insn.invisibleTypeAnnotations.size() > 0) {
throw new RuntimeException();
}
if (insn instanceof MethodInsnNode) {
boolean itf = ((MethodInsnNode) insn).itf;
if (itf != (insn.opcode == Opcodes.INVOKEINTERFACE)) {
throw new RuntimeException();
}
}
}
if (visibleLocalVariableAnnotations != null
&& visibleLocalVariableAnnotations.size() > 0) {
throw new RuntimeException();
}
if (invisibleLocalVariableAnnotations != null
&& invisibleLocalVariableAnnotations.size() > 0) {
throw new RuntimeException();
}
}
}
/**
* Makes the given class visitor visit this method.
*
* @param cv
* a class visitor.
*/
public void accept(final ClassVisitor cv) {
String[] exceptions = new String[this.exceptions.size()];
this.exceptions.toArray(exceptions);
MethodVisitor mv = cv.visitMethod(access, name, desc, signature,
exceptions);
if (mv != null) {
accept(mv);
}
}
/**
* Makes the given method visitor visit this method.
*
* @param mv
* a method visitor.
*/
public void accept(final MethodVisitor mv) {
// visits the method parameters
int i, j, n;
n = parameters == null ? 0 : parameters.size();
for (i = 0; i < n; i++) {
ParameterNode parameter = parameters.get(i);
mv.visitParameter(parameter.name, parameter.access);
}
// visits the method attributes
if (annotationDefault != null) {
AnnotationVisitor av = mv.visitAnnotationDefault();
AnnotationNode.accept(av, null, annotationDefault);
if (av != null) {
av.visitEnd();
}
}
n = visibleAnnotations == null ? 0 : visibleAnnotations.size();
for (i = 0; i < n; ++i) {
AnnotationNode an = visibleAnnotations.get(i);
an.accept(mv.visitAnnotation(an.desc, true));
}
n = invisibleAnnotations == null ? 0 : invisibleAnnotations.size();
for (i = 0; i < n; ++i) {
AnnotationNode an = invisibleAnnotations.get(i);
an.accept(mv.visitAnnotation(an.desc, false));
}
n = visibleTypeAnnotations == null ? 0 : visibleTypeAnnotations.size();
for (i = 0; i < n; ++i) {
TypeAnnotationNode an = visibleTypeAnnotations.get(i);
an.accept(mv.visitTypeAnnotation(an.typeRef, an.typePath, an.desc,
true));
}
n = invisibleTypeAnnotations == null ? 0 : invisibleTypeAnnotations
.size();
for (i = 0; i < n; ++i) {
TypeAnnotationNode an = invisibleTypeAnnotations.get(i);
an.accept(mv.visitTypeAnnotation(an.typeRef, an.typePath, an.desc,
false));
}
n = visibleParameterAnnotations == null ? 0
: visibleParameterAnnotations.length;
for (i = 0; i < n; ++i) {
List<?> l = visibleParameterAnnotations[i];
if (l == null) {
continue;
}
for (j = 0; j < l.size(); ++j) {
AnnotationNode an = (AnnotationNode) l.get(j);
an.accept(mv.visitParameterAnnotation(i, an.desc, true));
}
}
n = invisibleParameterAnnotations == null ? 0
: invisibleParameterAnnotations.length;
for (i = 0; i < n; ++i) {
List<?> l = invisibleParameterAnnotations[i];
if (l == null) {
continue;
}
for (j = 0; j < l.size(); ++j) {
AnnotationNode an = (AnnotationNode) l.get(j);
an.accept(mv.visitParameterAnnotation(i, an.desc, false));
}
}
if (visited) {
instructions.resetLabels();
}
n = attrs == null ? 0 : attrs.size();
for (i = 0; i < n; ++i) {
mv.visitAttribute(attrs.get(i));
}
// visits the method's code
if (instructions.size() > 0) {
mv.visitCode();
// visits try catch blocks
n = tryCatchBlocks == null ? 0 : tryCatchBlocks.size();
for (i = 0; i < n; ++i) {
tryCatchBlocks.get(i).updateIndex(i);
tryCatchBlocks.get(i).accept(mv);
}
// visits instructions
instructions.accept(mv);
// visits local variables
n = localVariables == null ? 0 : localVariables.size();
for (i = 0; i < n; ++i) {
localVariables.get(i).accept(mv);
}
// visits local variable annotations
n = visibleLocalVariableAnnotations == null ? 0
: visibleLocalVariableAnnotations.size();
for (i = 0; i < n; ++i) {
visibleLocalVariableAnnotations.get(i).accept(mv, true);
}
n = invisibleLocalVariableAnnotations == null ? 0
: invisibleLocalVariableAnnotations.size();
for (i = 0; i < n; ++i) {
invisibleLocalVariableAnnotations.get(i).accept(mv, false);
}
// visits maxs
mv.visitMaxs(maxStack, maxLocals);
visited = true;
}
mv.visitEnd();
}
}

View File

@@ -0,0 +1,113 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* 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 jdk.internal.org.objectweb.asm.tree;
import java.util.Map;
import jdk.internal.org.objectweb.asm.MethodVisitor;
import jdk.internal.org.objectweb.asm.Opcodes;
/**
* A node that represents a MULTIANEWARRAY instruction.
*
* @author Eric Bruneton
*/
public class MultiANewArrayInsnNode extends AbstractInsnNode {
/**
* An array type descriptor (see {@link jdk.internal.org.objectweb.asm.Type}).
*/
public String desc;
/**
* Number of dimensions of the array to allocate.
*/
public int dims;
/**
* Constructs a new {@link MultiANewArrayInsnNode}.
*
* @param desc
* an array type descriptor (see {@link jdk.internal.org.objectweb.asm.Type}).
* @param dims
* number of dimensions of the array to allocate.
*/
public MultiANewArrayInsnNode(final String desc, final int dims) {
super(Opcodes.MULTIANEWARRAY);
this.desc = desc;
this.dims = dims;
}
@Override
public int getType() {
return MULTIANEWARRAY_INSN;
}
@Override
public void accept(final MethodVisitor mv) {
mv.visitMultiANewArrayInsn(desc, dims);
acceptAnnotations(mv);
}
@Override
public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
return new MultiANewArrayInsnNode(desc, dims).cloneAnnotations(this);
}
}

View File

@@ -0,0 +1,105 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* 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 jdk.internal.org.objectweb.asm.tree;
import jdk.internal.org.objectweb.asm.MethodVisitor;
/**
* A node that represents a parameter access and name.
*
* @author Remi Forax
*/
public class ParameterNode {
/**
* The parameter's name.
*/
public String name;
/**
* The parameter's access flags (see {@link jdk.internal.org.objectweb.asm.Opcodes}).
* Valid values are <tt>ACC_FINAL</tt>, <tt>ACC_SYNTHETIC</tt> and
* <tt>ACC_MANDATED</tt>.
*/
public int access;
/**
* Constructs a new {@link ParameterNode}.
*
* @param access
* The parameter's access flags. Valid values are
* <tt>ACC_FINAL</tt>, <tt>ACC_SYNTHETIC</tt> or/and
* <tt>ACC_MANDATED</tt> (see {@link jdk.internal.org.objectweb.asm.Opcodes}).
* @param name
* the parameter's name.
*/
public ParameterNode(final String name, final int access) {
this.name = name;
this.access = access;
}
/**
* Makes the given visitor visit this parameter declaration.
*
* @param mv
* a method visitor.
*/
public void accept(final MethodVisitor mv) {
mv.visitParameter(name, access);
}
}

View File

@@ -0,0 +1,143 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* 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 jdk.internal.org.objectweb.asm.tree;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import jdk.internal.org.objectweb.asm.Label;
import jdk.internal.org.objectweb.asm.MethodVisitor;
import jdk.internal.org.objectweb.asm.Opcodes;
/**
* A node that represents a TABLESWITCH instruction.
*
* @author Eric Bruneton
*/
public class TableSwitchInsnNode extends AbstractInsnNode {
/**
* The minimum key value.
*/
public int min;
/**
* The maximum key value.
*/
public int max;
/**
* Beginning of the default handler block.
*/
public LabelNode dflt;
/**
* Beginnings of the handler blocks. This list is a list of
* {@link LabelNode} objects.
*/
public List<LabelNode> labels;
/**
* Constructs a new {@link TableSwitchInsnNode}.
*
* @param min
* the minimum key value.
* @param max
* the maximum key value.
* @param dflt
* beginning of the default handler block.
* @param labels
* beginnings of the handler blocks. <tt>labels[i]</tt> is the
* beginning of the handler block for the <tt>min + i</tt> key.
*/
public TableSwitchInsnNode(final int min, final int max,
final LabelNode dflt, final LabelNode... labels) {
super(Opcodes.TABLESWITCH);
this.min = min;
this.max = max;
this.dflt = dflt;
this.labels = new ArrayList<LabelNode>();
if (labels != null) {
this.labels.addAll(Arrays.asList(labels));
}
}
@Override
public int getType() {
return TABLESWITCH_INSN;
}
@Override
public void accept(final MethodVisitor mv) {
Label[] labels = new Label[this.labels.size()];
for (int i = 0; i < labels.length; ++i) {
labels[i] = this.labels.get(i).getLabel();
}
mv.visitTableSwitchInsn(min, max, dflt.getLabel(), labels);
acceptAnnotations(mv);
}
@Override
public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
return new TableSwitchInsnNode(min, max, clone(dflt, labels), clone(
this.labels, labels)).cloneAnnotations(this);
}
}

View File

@@ -0,0 +1,182 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* 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 jdk.internal.org.objectweb.asm.tree;
import java.util.List;
import jdk.internal.org.objectweb.asm.MethodVisitor;
/**
* A node that represents a try catch block.
*
* @author Eric Bruneton
*/
public class TryCatchBlockNode {
/**
* Beginning of the exception handler's scope (inclusive).
*/
public LabelNode start;
/**
* End of the exception handler's scope (exclusive).
*/
public LabelNode end;
/**
* Beginning of the exception handler's code.
*/
public LabelNode handler;
/**
* Internal name of the type of exceptions handled by the handler. May be
* <tt>null</tt> to catch any exceptions (for "finally" blocks).
*/
public String type;
/**
* The runtime visible type annotations on the exception handler type. This
* list is a list of {@link TypeAnnotationNode} objects. May be
* <tt>null</tt>.
*
* @associates jdk.internal.org.objectweb.asm.tree.TypeAnnotationNode
* @label visible
*/
public List<TypeAnnotationNode> visibleTypeAnnotations;
/**
* The runtime invisible type annotations on the exception handler type.
* This list is a list of {@link TypeAnnotationNode} objects. May be
* <tt>null</tt>.
*
* @associates jdk.internal.org.objectweb.asm.tree.TypeAnnotationNode
* @label invisible
*/
public List<TypeAnnotationNode> invisibleTypeAnnotations;
/**
* Constructs a new {@link TryCatchBlockNode}.
*
* @param start
* beginning of the exception handler's scope (inclusive).
* @param end
* end of the exception handler's scope (exclusive).
* @param handler
* beginning of the exception handler's code.
* @param type
* internal name of the type of exceptions handled by the
* handler, or <tt>null</tt> to catch any exceptions (for
* "finally" blocks).
*/
public TryCatchBlockNode(final LabelNode start, final LabelNode end,
final LabelNode handler, final String type) {
this.start = start;
this.end = end;
this.handler = handler;
this.type = type;
}
/**
* Updates the index of this try catch block in the method's list of try
* catch block nodes. This index maybe stored in the 'target' field of the
* type annotations of this block.
*
* @param index
* the new index of this try catch block in the method's list of
* try catch block nodes.
*/
public void updateIndex(final int index) {
int newTypeRef = 0x42000000 | (index << 8);
if (visibleTypeAnnotations != null) {
for (TypeAnnotationNode tan : visibleTypeAnnotations) {
tan.typeRef = newTypeRef;
}
}
if (invisibleTypeAnnotations != null) {
for (TypeAnnotationNode tan : invisibleTypeAnnotations) {
tan.typeRef = newTypeRef;
}
}
}
/**
* Makes the given visitor visit this try catch block.
*
* @param mv
* a method visitor.
*/
public void accept(final MethodVisitor mv) {
mv.visitTryCatchBlock(start.getLabel(), end.getLabel(),
handler == null ? null : handler.getLabel(), type);
int n = visibleTypeAnnotations == null ? 0 : visibleTypeAnnotations
.size();
for (int i = 0; i < n; ++i) {
TypeAnnotationNode an = visibleTypeAnnotations.get(i);
an.accept(mv.visitTryCatchAnnotation(an.typeRef, an.typePath,
an.desc, true));
}
n = invisibleTypeAnnotations == null ? 0 : invisibleTypeAnnotations
.size();
for (int i = 0; i < n; ++i) {
TypeAnnotationNode an = invisibleTypeAnnotations.get(i);
an.accept(mv.visitTryCatchAnnotation(an.typeRef, an.typePath,
an.desc, false));
}
}
}

View File

@@ -0,0 +1,129 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* 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 jdk.internal.org.objectweb.asm.tree;
import jdk.internal.org.objectweb.asm.Opcodes;
import jdk.internal.org.objectweb.asm.TypePath;
import jdk.internal.org.objectweb.asm.TypeReference;
/**
* A node that represents a type annotationn.
*
* @author Eric Bruneton
*/
public class TypeAnnotationNode extends AnnotationNode {
/**
* A reference to the annotated type. See {@link TypeReference}.
*/
public int typeRef;
/**
* The path to the annotated type argument, wildcard bound, array element
* type, or static outer type within the referenced type. May be
* <tt>null</tt> if the annotation targets 'typeRef' as a whole.
*/
public TypePath typePath;
/**
* Constructs a new {@link AnnotationNode}. <i>Subclasses must not use this
* constructor</i>. Instead, they must use the
* {@link #TypeAnnotationNode(int, int, TypePath, String)} version.
*
* @param typeRef
* a reference to the annotated type. See {@link TypeReference}.
* @param typePath
* the path to the annotated type argument, wildcard bound, array
* element type, or static inner type within 'typeRef'. May be
* <tt>null</tt> if the annotation targets 'typeRef' as a whole.
* @param desc
* the class descriptor of the annotation class.
* @throws IllegalStateException
* If a subclass calls this constructor.
*/
public TypeAnnotationNode(final int typeRef, final TypePath typePath,
final String desc) {
this(Opcodes.ASM5, typeRef, typePath, desc);
if (getClass() != TypeAnnotationNode.class) {
throw new IllegalStateException();
}
}
/**
* Constructs a new {@link AnnotationNode}.
*
* @param api
* the ASM API version implemented by this visitor. Must be one
* of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
* @param typeRef
* a reference to the annotated type. See {@link TypeReference}.
* @param typePath
* the path to the annotated type argument, wildcard bound, array
* element type, or static inner type within 'typeRef'. May be
* <tt>null</tt> if the annotation targets 'typeRef' as a whole.
* @param desc
* the class descriptor of the annotation class.
*/
public TypeAnnotationNode(final int api, final int typeRef,
final TypePath typePath, final String desc) {
super(api, desc);
this.typeRef = typeRef;
this.typePath = typePath;
}
}

View File

@@ -0,0 +1,120 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* 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 jdk.internal.org.objectweb.asm.tree;
import java.util.Map;
import jdk.internal.org.objectweb.asm.MethodVisitor;
/**
* A node that represents a type instruction. A type instruction is an
* instruction that takes a type descriptor as parameter.
*
* @author Eric Bruneton
*/
public class TypeInsnNode extends AbstractInsnNode {
/**
* The operand of this instruction. This operand is an internal name (see
* {@link jdk.internal.org.objectweb.asm.Type}).
*/
public String desc;
/**
* Constructs a new {@link TypeInsnNode}.
*
* @param opcode
* the opcode of the type instruction to be constructed. This
* opcode must be NEW, ANEWARRAY, CHECKCAST or INSTANCEOF.
* @param desc
* the operand of the instruction to be constructed. This operand
* is an internal name (see {@link jdk.internal.org.objectweb.asm.Type}).
*/
public TypeInsnNode(final int opcode, final String desc) {
super(opcode);
this.desc = desc;
}
/**
* Sets the opcode of this instruction.
*
* @param opcode
* the new instruction opcode. This opcode must be NEW,
* ANEWARRAY, CHECKCAST or INSTANCEOF.
*/
public void setOpcode(final int opcode) {
this.opcode = opcode;
}
@Override
public int getType() {
return TYPE_INSN;
}
@Override
public void accept(final MethodVisitor mv) {
mv.visitTypeInsn(opcode, desc);
acceptAnnotations(mv);
}
@Override
public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
return new TypeInsnNode(opcode, desc).cloneAnnotations(this);
}
}

View File

@@ -0,0 +1,123 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* 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 jdk.internal.org.objectweb.asm.tree;
import java.util.Map;
import jdk.internal.org.objectweb.asm.MethodVisitor;
/**
* A node that represents a local variable instruction. A local variable
* instruction is an instruction that loads or stores the value of a local
* variable.
*
* @author Eric Bruneton
*/
public class VarInsnNode extends AbstractInsnNode {
/**
* The operand of this instruction. This operand is the index of a local
* variable.
*/
public int var;
/**
* Constructs a new {@link VarInsnNode}.
*
* @param opcode
* the opcode of the local variable instruction to be
* constructed. This opcode must be ILOAD, LLOAD, FLOAD, DLOAD,
* ALOAD, ISTORE, LSTORE, FSTORE, DSTORE, ASTORE or RET.
* @param var
* the operand of the instruction to be constructed. This operand
* is the index of a local variable.
*/
public VarInsnNode(final int opcode, final int var) {
super(opcode);
this.var = var;
}
/**
* Sets the opcode of this instruction.
*
* @param opcode
* the new instruction opcode. This opcode must be ILOAD, LLOAD,
* FLOAD, DLOAD, ALOAD, ISTORE, LSTORE, FSTORE, DSTORE, ASTORE or
* RET.
*/
public void setOpcode(final int opcode) {
this.opcode = opcode;
}
@Override
public int getType() {
return VAR_INSN;
}
@Override
public void accept(final MethodVisitor mv) {
mv.visitVarInsn(opcode, var);
acceptAnnotations(mv);
}
@Override
public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
return new VarInsnNode(opcode, var).cloneAnnotations(this);
}
}

View File

@@ -0,0 +1,579 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* 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 jdk.internal.org.objectweb.asm.tree.analysis;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import jdk.internal.org.objectweb.asm.Opcodes;
import jdk.internal.org.objectweb.asm.Type;
import jdk.internal.org.objectweb.asm.tree.AbstractInsnNode;
import jdk.internal.org.objectweb.asm.tree.IincInsnNode;
import jdk.internal.org.objectweb.asm.tree.InsnList;
import jdk.internal.org.objectweb.asm.tree.JumpInsnNode;
import jdk.internal.org.objectweb.asm.tree.LabelNode;
import jdk.internal.org.objectweb.asm.tree.LookupSwitchInsnNode;
import jdk.internal.org.objectweb.asm.tree.MethodNode;
import jdk.internal.org.objectweb.asm.tree.TableSwitchInsnNode;
import jdk.internal.org.objectweb.asm.tree.TryCatchBlockNode;
import jdk.internal.org.objectweb.asm.tree.VarInsnNode;
/**
* A semantic bytecode analyzer. <i>This class does not fully check that JSR and
* RET instructions are valid.</i>
*
* @param <V>
* type of the Value used for the analysis.
*
* @author Eric Bruneton
*/
public class Analyzer<V extends Value> implements Opcodes {
private final Interpreter<V> interpreter;
private int n;
private InsnList insns;
private List<TryCatchBlockNode>[] handlers;
private Frame<V>[] frames;
private Subroutine[] subroutines;
private boolean[] queued;
private int[] queue;
private int top;
/**
* Constructs a new {@link Analyzer}.
*
* @param interpreter
* the interpreter to be used to symbolically interpret the
* bytecode instructions.
*/
public Analyzer(final Interpreter<V> interpreter) {
this.interpreter = interpreter;
}
/**
* Analyzes the given method.
*
* @param owner
* the internal name of the class to which the method belongs.
* @param m
* the method to be analyzed.
* @return the symbolic state of the execution stack frame at each bytecode
* instruction of the method. The size of the returned array is
* equal to the number of instructions (and labels) of the method. A
* given frame is <tt>null</tt> if and only if the corresponding
* instruction cannot be reached (dead code).
* @throws AnalyzerException
* if a problem occurs during the analysis.
*/
@SuppressWarnings("unchecked")
public Frame<V>[] analyze(final String owner, final MethodNode m)
throws AnalyzerException {
if ((m.access & (ACC_ABSTRACT | ACC_NATIVE)) != 0) {
frames = (Frame<V>[]) new Frame<?>[0];
return frames;
}
n = m.instructions.size();
insns = m.instructions;
handlers = (List<TryCatchBlockNode>[]) new List<?>[n];
frames = (Frame<V>[]) new Frame<?>[n];
subroutines = new Subroutine[n];
queued = new boolean[n];
queue = new int[n];
top = 0;
// computes exception handlers for each instruction
for (int i = 0; i < m.tryCatchBlocks.size(); ++i) {
TryCatchBlockNode tcb = m.tryCatchBlocks.get(i);
int begin = insns.indexOf(tcb.start);
int end = insns.indexOf(tcb.end);
for (int j = begin; j < end; ++j) {
List<TryCatchBlockNode> insnHandlers = handlers[j];
if (insnHandlers == null) {
insnHandlers = new ArrayList<TryCatchBlockNode>();
handlers[j] = insnHandlers;
}
insnHandlers.add(tcb);
}
}
// computes the subroutine for each instruction:
Subroutine main = new Subroutine(null, m.maxLocals, null);
List<AbstractInsnNode> subroutineCalls = new ArrayList<AbstractInsnNode>();
Map<LabelNode, Subroutine> subroutineHeads = new HashMap<LabelNode, Subroutine>();
findSubroutine(0, main, subroutineCalls);
while (!subroutineCalls.isEmpty()) {
JumpInsnNode jsr = (JumpInsnNode) subroutineCalls.remove(0);
Subroutine sub = subroutineHeads.get(jsr.label);
if (sub == null) {
sub = new Subroutine(jsr.label, m.maxLocals, jsr);
subroutineHeads.put(jsr.label, sub);
findSubroutine(insns.indexOf(jsr.label), sub, subroutineCalls);
} else {
sub.callers.add(jsr);
}
}
for (int i = 0; i < n; ++i) {
if (subroutines[i] != null && subroutines[i].start == null) {
subroutines[i] = null;
}
}
// initializes the data structures for the control flow analysis
Frame<V> current = newFrame(m.maxLocals, m.maxStack);
Frame<V> handler = newFrame(m.maxLocals, m.maxStack);
current.setReturn(interpreter.newValue(Type.getReturnType(m.desc)));
Type[] args = Type.getArgumentTypes(m.desc);
int local = 0;
if ((m.access & ACC_STATIC) == 0) {
Type ctype = Type.getObjectType(owner);
current.setLocal(local++, interpreter.newValue(ctype));
}
for (int i = 0; i < args.length; ++i) {
current.setLocal(local++, interpreter.newValue(args[i]));
if (args[i].getSize() == 2) {
current.setLocal(local++, interpreter.newValue(null));
}
}
while (local < m.maxLocals) {
current.setLocal(local++, interpreter.newValue(null));
}
merge(0, current, null);
init(owner, m);
// control flow analysis
while (top > 0) {
int insn = queue[--top];
Frame<V> f = frames[insn];
Subroutine subroutine = subroutines[insn];
queued[insn] = false;
AbstractInsnNode insnNode = null;
try {
insnNode = m.instructions.get(insn);
int insnOpcode = insnNode.getOpcode();
int insnType = insnNode.getType();
if (insnType == AbstractInsnNode.LABEL
|| insnType == AbstractInsnNode.LINE
|| insnType == AbstractInsnNode.FRAME) {
merge(insn + 1, f, subroutine);
newControlFlowEdge(insn, insn + 1);
} else {
current.init(f).execute(insnNode, interpreter);
subroutine = subroutine == null ? null : subroutine.copy();
if (insnNode instanceof JumpInsnNode) {
JumpInsnNode j = (JumpInsnNode) insnNode;
if (insnOpcode != GOTO && insnOpcode != JSR) {
merge(insn + 1, current, subroutine);
newControlFlowEdge(insn, insn + 1);
}
int jump = insns.indexOf(j.label);
if (insnOpcode == JSR) {
merge(jump, current, new Subroutine(j.label,
m.maxLocals, j));
} else {
merge(jump, current, subroutine);
}
newControlFlowEdge(insn, jump);
} else if (insnNode instanceof LookupSwitchInsnNode) {
LookupSwitchInsnNode lsi = (LookupSwitchInsnNode) insnNode;
int jump = insns.indexOf(lsi.dflt);
merge(jump, current, subroutine);
newControlFlowEdge(insn, jump);
for (int j = 0; j < lsi.labels.size(); ++j) {
LabelNode label = lsi.labels.get(j);
jump = insns.indexOf(label);
merge(jump, current, subroutine);
newControlFlowEdge(insn, jump);
}
} else if (insnNode instanceof TableSwitchInsnNode) {
TableSwitchInsnNode tsi = (TableSwitchInsnNode) insnNode;
int jump = insns.indexOf(tsi.dflt);
merge(jump, current, subroutine);
newControlFlowEdge(insn, jump);
for (int j = 0; j < tsi.labels.size(); ++j) {
LabelNode label = tsi.labels.get(j);
jump = insns.indexOf(label);
merge(jump, current, subroutine);
newControlFlowEdge(insn, jump);
}
} else if (insnOpcode == RET) {
if (subroutine == null) {
throw new AnalyzerException(insnNode,
"RET instruction outside of a sub routine");
}
for (int i = 0; i < subroutine.callers.size(); ++i) {
JumpInsnNode caller = subroutine.callers.get(i);
int call = insns.indexOf(caller);
if (frames[call] != null) {
merge(call + 1, frames[call], current,
subroutines[call], subroutine.access);
newControlFlowEdge(insn, call + 1);
}
}
} else if (insnOpcode != ATHROW
&& (insnOpcode < IRETURN || insnOpcode > RETURN)) {
if (subroutine != null) {
if (insnNode instanceof VarInsnNode) {
int var = ((VarInsnNode) insnNode).var;
subroutine.access[var] = true;
if (insnOpcode == LLOAD || insnOpcode == DLOAD
|| insnOpcode == LSTORE
|| insnOpcode == DSTORE) {
subroutine.access[var + 1] = true;
}
} else if (insnNode instanceof IincInsnNode) {
int var = ((IincInsnNode) insnNode).var;
subroutine.access[var] = true;
}
}
merge(insn + 1, current, subroutine);
newControlFlowEdge(insn, insn + 1);
}
}
List<TryCatchBlockNode> insnHandlers = handlers[insn];
if (insnHandlers != null) {
for (int i = 0; i < insnHandlers.size(); ++i) {
TryCatchBlockNode tcb = insnHandlers.get(i);
Type type;
if (tcb.type == null) {
type = Type.getObjectType("java/lang/Throwable");
} else {
type = Type.getObjectType(tcb.type);
}
int jump = insns.indexOf(tcb.handler);
if (newControlFlowExceptionEdge(insn, tcb)) {
handler.init(f);
handler.clearStack();
handler.push(interpreter.newValue(type));
merge(jump, handler, subroutine);
}
}
}
} catch (AnalyzerException e) {
throw new AnalyzerException(e.node, "Error at instruction "
+ insn + ": " + e.getMessage(), e);
} catch (Exception e) {
throw new AnalyzerException(insnNode, "Error at instruction "
+ insn + ": " + e.getMessage(), e);
}
}
return frames;
}
private void findSubroutine(int insn, final Subroutine sub,
final List<AbstractInsnNode> calls) throws AnalyzerException {
while (true) {
if (insn < 0 || insn >= n) {
throw new AnalyzerException(null,
"Execution can fall off end of the code");
}
if (subroutines[insn] != null) {
return;
}
subroutines[insn] = sub.copy();
AbstractInsnNode node = insns.get(insn);
// calls findSubroutine recursively on normal successors
if (node instanceof JumpInsnNode) {
if (node.getOpcode() == JSR) {
// do not follow a JSR, it leads to another subroutine!
calls.add(node);
} else {
JumpInsnNode jnode = (JumpInsnNode) node;
findSubroutine(insns.indexOf(jnode.label), sub, calls);
}
} else if (node instanceof TableSwitchInsnNode) {
TableSwitchInsnNode tsnode = (TableSwitchInsnNode) node;
findSubroutine(insns.indexOf(tsnode.dflt), sub, calls);
for (int i = tsnode.labels.size() - 1; i >= 0; --i) {
LabelNode l = tsnode.labels.get(i);
findSubroutine(insns.indexOf(l), sub, calls);
}
} else if (node instanceof LookupSwitchInsnNode) {
LookupSwitchInsnNode lsnode = (LookupSwitchInsnNode) node;
findSubroutine(insns.indexOf(lsnode.dflt), sub, calls);
for (int i = lsnode.labels.size() - 1; i >= 0; --i) {
LabelNode l = lsnode.labels.get(i);
findSubroutine(insns.indexOf(l), sub, calls);
}
}
// calls findSubroutine recursively on exception handler successors
List<TryCatchBlockNode> insnHandlers = handlers[insn];
if (insnHandlers != null) {
for (int i = 0; i < insnHandlers.size(); ++i) {
TryCatchBlockNode tcb = insnHandlers.get(i);
findSubroutine(insns.indexOf(tcb.handler), sub, calls);
}
}
// if insn does not falls through to the next instruction, return.
switch (node.getOpcode()) {
case GOTO:
case RET:
case TABLESWITCH:
case LOOKUPSWITCH:
case IRETURN:
case LRETURN:
case FRETURN:
case DRETURN:
case ARETURN:
case RETURN:
case ATHROW:
return;
}
insn++;
}
}
/**
* Returns the symbolic stack frame for each instruction of the last
* recently analyzed method.
*
* @return the symbolic state of the execution stack frame at each bytecode
* instruction of the method. The size of the returned array is
* equal to the number of instructions (and labels) of the method. A
* given frame is <tt>null</tt> if the corresponding instruction
* cannot be reached, or if an error occured during the analysis of
* the method.
*/
public Frame<V>[] getFrames() {
return frames;
}
/**
* Returns the exception handlers for the given instruction.
*
* @param insn
* the index of an instruction of the last recently analyzed
* method.
* @return a list of {@link TryCatchBlockNode} objects.
*/
public List<TryCatchBlockNode> getHandlers(final int insn) {
return handlers[insn];
}
/**
* Initializes this analyzer. This method is called just before the
* execution of control flow analysis loop in #analyze. The default
* implementation of this method does nothing.
*
* @param owner
* the internal name of the class to which the method belongs.
* @param m
* the method to be analyzed.
* @throws AnalyzerException
* if a problem occurs.
*/
protected void init(String owner, MethodNode m) throws AnalyzerException {
}
/**
* Constructs a new frame with the given size.
*
* @param nLocals
* the maximum number of local variables of the frame.
* @param nStack
* the maximum stack size of the frame.
* @return the created frame.
*/
protected Frame<V> newFrame(final int nLocals, final int nStack) {
return new Frame<V>(nLocals, nStack);
}
/**
* Constructs a new frame that is identical to the given frame.
*
* @param src
* a frame.
* @return the created frame.
*/
protected Frame<V> newFrame(final Frame<? extends V> src) {
return new Frame<V>(src);
}
/**
* Creates a control flow graph edge. The default implementation of this
* method does nothing. It can be overriden in order to construct the
* control flow graph of a method (this method is called by the
* {@link #analyze analyze} method during its visit of the method's code).
*
* @param insn
* an instruction index.
* @param successor
* index of a successor instruction.
*/
protected void newControlFlowEdge(final int insn, final int successor) {
}
/**
* Creates a control flow graph edge corresponding to an exception handler.
* The default implementation of this method does nothing. It can be
* overridden in order to construct the control flow graph of a method (this
* method is called by the {@link #analyze analyze} method during its visit
* of the method's code).
*
* @param insn
* an instruction index.
* @param successor
* index of a successor instruction.
* @return true if this edge must be considered in the data flow analysis
* performed by this analyzer, or false otherwise. The default
* implementation of this method always returns true.
*/
protected boolean newControlFlowExceptionEdge(final int insn,
final int successor) {
return true;
}
/**
* Creates a control flow graph edge corresponding to an exception handler.
* The default implementation of this method delegates to
* {@link #newControlFlowExceptionEdge(int, int)
* newControlFlowExceptionEdge(int, int)}. It can be overridden in order to
* construct the control flow graph of a method (this method is called by
* the {@link #analyze analyze} method during its visit of the method's
* code).
*
* @param insn
* an instruction index.
* @param tcb
* TryCatchBlockNode corresponding to this edge.
* @return true if this edge must be considered in the data flow analysis
* performed by this analyzer, or false otherwise. The default
* implementation of this method delegates to
* {@link #newControlFlowExceptionEdge(int, int)
* newControlFlowExceptionEdge(int, int)}.
*/
protected boolean newControlFlowExceptionEdge(final int insn,
final TryCatchBlockNode tcb) {
return newControlFlowExceptionEdge(insn, insns.indexOf(tcb.handler));
}
// -------------------------------------------------------------------------
private void merge(final int insn, final Frame<V> frame,
final Subroutine subroutine) throws AnalyzerException {
Frame<V> oldFrame = frames[insn];
Subroutine oldSubroutine = subroutines[insn];
boolean changes;
if (oldFrame == null) {
frames[insn] = newFrame(frame);
changes = true;
} else {
changes = oldFrame.merge(frame, interpreter);
}
if (oldSubroutine == null) {
if (subroutine != null) {
subroutines[insn] = subroutine.copy();
changes = true;
}
} else {
if (subroutine != null) {
changes |= oldSubroutine.merge(subroutine);
}
}
if (changes && !queued[insn]) {
queued[insn] = true;
queue[top++] = insn;
}
}
private void merge(final int insn, final Frame<V> beforeJSR,
final Frame<V> afterRET, final Subroutine subroutineBeforeJSR,
final boolean[] access) throws AnalyzerException {
Frame<V> oldFrame = frames[insn];
Subroutine oldSubroutine = subroutines[insn];
boolean changes;
afterRET.merge(beforeJSR, access);
if (oldFrame == null) {
frames[insn] = newFrame(afterRET);
changes = true;
} else {
changes = oldFrame.merge(afterRET, interpreter);
}
if (oldSubroutine != null && subroutineBeforeJSR != null) {
changes |= oldSubroutine.merge(subroutineBeforeJSR);
}
if (changes && !queued[insn]) {
queued[insn] = true;
queue[top++] = insn;
}
}
}

View File

@@ -0,0 +1,91 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* 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 jdk.internal.org.objectweb.asm.tree.analysis;
import jdk.internal.org.objectweb.asm.tree.AbstractInsnNode;
/**
* Thrown if a problem occurs during the analysis of a method.
*
* @author Bing Ran
* @author Eric Bruneton
*/
@SuppressWarnings("serial")
public class AnalyzerException extends Exception {
public final AbstractInsnNode node;
public AnalyzerException(final AbstractInsnNode node, final String msg) {
super(msg);
this.node = node;
}
public AnalyzerException(final AbstractInsnNode node, final String msg,
final Throwable exception) {
super(msg, exception);
this.node = node;
}
public AnalyzerException(final AbstractInsnNode node, final String msg,
final Object expected, final Value encountered) {
super((msg == null ? "Expected " : msg + ": expected ") + expected
+ ", but found " + encountered);
this.node = node;
}
}

View File

@@ -0,0 +1,387 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* 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 jdk.internal.org.objectweb.asm.tree.analysis;
import java.util.List;
import jdk.internal.org.objectweb.asm.Handle;
import jdk.internal.org.objectweb.asm.Opcodes;
import jdk.internal.org.objectweb.asm.Type;
import jdk.internal.org.objectweb.asm.tree.AbstractInsnNode;
import jdk.internal.org.objectweb.asm.tree.FieldInsnNode;
import jdk.internal.org.objectweb.asm.tree.IntInsnNode;
import jdk.internal.org.objectweb.asm.tree.InvokeDynamicInsnNode;
import jdk.internal.org.objectweb.asm.tree.LdcInsnNode;
import jdk.internal.org.objectweb.asm.tree.MethodInsnNode;
import jdk.internal.org.objectweb.asm.tree.MultiANewArrayInsnNode;
import jdk.internal.org.objectweb.asm.tree.TypeInsnNode;
/**
* An {@link Interpreter} for {@link BasicValue} values.
*
* @author Eric Bruneton
* @author Bing Ran
*/
public class BasicInterpreter extends Interpreter<BasicValue> implements
Opcodes {
public BasicInterpreter() {
super(ASM5);
}
protected BasicInterpreter(final int api) {
super(api);
}
@Override
public BasicValue newValue(final Type type) {
if (type == null) {
return BasicValue.UNINITIALIZED_VALUE;
}
switch (type.getSort()) {
case Type.VOID:
return null;
case Type.BOOLEAN:
case Type.CHAR:
case Type.BYTE:
case Type.SHORT:
case Type.INT:
return BasicValue.INT_VALUE;
case Type.FLOAT:
return BasicValue.FLOAT_VALUE;
case Type.LONG:
return BasicValue.LONG_VALUE;
case Type.DOUBLE:
return BasicValue.DOUBLE_VALUE;
case Type.ARRAY:
case Type.OBJECT:
return BasicValue.REFERENCE_VALUE;
default:
throw new Error("Internal error");
}
}
@Override
public BasicValue newOperation(final AbstractInsnNode insn)
throws AnalyzerException {
switch (insn.getOpcode()) {
case ACONST_NULL:
return newValue(Type.getObjectType("null"));
case ICONST_M1:
case ICONST_0:
case ICONST_1:
case ICONST_2:
case ICONST_3:
case ICONST_4:
case ICONST_5:
return BasicValue.INT_VALUE;
case LCONST_0:
case LCONST_1:
return BasicValue.LONG_VALUE;
case FCONST_0:
case FCONST_1:
case FCONST_2:
return BasicValue.FLOAT_VALUE;
case DCONST_0:
case DCONST_1:
return BasicValue.DOUBLE_VALUE;
case BIPUSH:
case SIPUSH:
return BasicValue.INT_VALUE;
case LDC:
Object cst = ((LdcInsnNode) insn).cst;
if (cst instanceof Integer) {
return BasicValue.INT_VALUE;
} else if (cst instanceof Float) {
return BasicValue.FLOAT_VALUE;
} else if (cst instanceof Long) {
return BasicValue.LONG_VALUE;
} else if (cst instanceof Double) {
return BasicValue.DOUBLE_VALUE;
} else if (cst instanceof String) {
return newValue(Type.getObjectType("java/lang/String"));
} else if (cst instanceof Type) {
int sort = ((Type) cst).getSort();
if (sort == Type.OBJECT || sort == Type.ARRAY) {
return newValue(Type.getObjectType("java/lang/Class"));
} else if (sort == Type.METHOD) {
return newValue(Type
.getObjectType("java/lang/invoke/MethodType"));
} else {
throw new IllegalArgumentException("Illegal LDC constant "
+ cst);
}
} else if (cst instanceof Handle) {
return newValue(Type
.getObjectType("java/lang/invoke/MethodHandle"));
} else {
throw new IllegalArgumentException("Illegal LDC constant "
+ cst);
}
case JSR:
return BasicValue.RETURNADDRESS_VALUE;
case GETSTATIC:
return newValue(Type.getType(((FieldInsnNode) insn).desc));
case NEW:
return newValue(Type.getObjectType(((TypeInsnNode) insn).desc));
default:
throw new Error("Internal error.");
}
}
@Override
public BasicValue copyOperation(final AbstractInsnNode insn,
final BasicValue value) throws AnalyzerException {
return value;
}
@Override
public BasicValue unaryOperation(final AbstractInsnNode insn,
final BasicValue value) throws AnalyzerException {
switch (insn.getOpcode()) {
case INEG:
case IINC:
case L2I:
case F2I:
case D2I:
case I2B:
case I2C:
case I2S:
return BasicValue.INT_VALUE;
case FNEG:
case I2F:
case L2F:
case D2F:
return BasicValue.FLOAT_VALUE;
case LNEG:
case I2L:
case F2L:
case D2L:
return BasicValue.LONG_VALUE;
case DNEG:
case I2D:
case L2D:
case F2D:
return BasicValue.DOUBLE_VALUE;
case IFEQ:
case IFNE:
case IFLT:
case IFGE:
case IFGT:
case IFLE:
case TABLESWITCH:
case LOOKUPSWITCH:
case IRETURN:
case LRETURN:
case FRETURN:
case DRETURN:
case ARETURN:
case PUTSTATIC:
return null;
case GETFIELD:
return newValue(Type.getType(((FieldInsnNode) insn).desc));
case NEWARRAY:
switch (((IntInsnNode) insn).operand) {
case T_BOOLEAN:
return newValue(Type.getType("[Z"));
case T_CHAR:
return newValue(Type.getType("[C"));
case T_BYTE:
return newValue(Type.getType("[B"));
case T_SHORT:
return newValue(Type.getType("[S"));
case T_INT:
return newValue(Type.getType("[I"));
case T_FLOAT:
return newValue(Type.getType("[F"));
case T_DOUBLE:
return newValue(Type.getType("[D"));
case T_LONG:
return newValue(Type.getType("[J"));
default:
throw new AnalyzerException(insn, "Invalid array type");
}
case ANEWARRAY:
String desc = ((TypeInsnNode) insn).desc;
return newValue(Type.getType("[" + Type.getObjectType(desc)));
case ARRAYLENGTH:
return BasicValue.INT_VALUE;
case ATHROW:
return null;
case CHECKCAST:
desc = ((TypeInsnNode) insn).desc;
return newValue(Type.getObjectType(desc));
case INSTANCEOF:
return BasicValue.INT_VALUE;
case MONITORENTER:
case MONITOREXIT:
case IFNULL:
case IFNONNULL:
return null;
default:
throw new Error("Internal error.");
}
}
@Override
public BasicValue binaryOperation(final AbstractInsnNode insn,
final BasicValue value1, final BasicValue value2)
throws AnalyzerException {
switch (insn.getOpcode()) {
case IALOAD:
case BALOAD:
case CALOAD:
case SALOAD:
case IADD:
case ISUB:
case IMUL:
case IDIV:
case IREM:
case ISHL:
case ISHR:
case IUSHR:
case IAND:
case IOR:
case IXOR:
return BasicValue.INT_VALUE;
case FALOAD:
case FADD:
case FSUB:
case FMUL:
case FDIV:
case FREM:
return BasicValue.FLOAT_VALUE;
case LALOAD:
case LADD:
case LSUB:
case LMUL:
case LDIV:
case LREM:
case LSHL:
case LSHR:
case LUSHR:
case LAND:
case LOR:
case LXOR:
return BasicValue.LONG_VALUE;
case DALOAD:
case DADD:
case DSUB:
case DMUL:
case DDIV:
case DREM:
return BasicValue.DOUBLE_VALUE;
case AALOAD:
return BasicValue.REFERENCE_VALUE;
case LCMP:
case FCMPL:
case FCMPG:
case DCMPL:
case DCMPG:
return BasicValue.INT_VALUE;
case IF_ICMPEQ:
case IF_ICMPNE:
case IF_ICMPLT:
case IF_ICMPGE:
case IF_ICMPGT:
case IF_ICMPLE:
case IF_ACMPEQ:
case IF_ACMPNE:
case PUTFIELD:
return null;
default:
throw new Error("Internal error.");
}
}
@Override
public BasicValue ternaryOperation(final AbstractInsnNode insn,
final BasicValue value1, final BasicValue value2,
final BasicValue value3) throws AnalyzerException {
return null;
}
@Override
public BasicValue naryOperation(final AbstractInsnNode insn,
final List<? extends BasicValue> values) throws AnalyzerException {
int opcode = insn.getOpcode();
if (opcode == MULTIANEWARRAY) {
return newValue(Type.getType(((MultiANewArrayInsnNode) insn).desc));
} else if (opcode == INVOKEDYNAMIC) {
return newValue(Type
.getReturnType(((InvokeDynamicInsnNode) insn).desc));
} else {
return newValue(Type.getReturnType(((MethodInsnNode) insn).desc));
}
}
@Override
public void returnOperation(final AbstractInsnNode insn,
final BasicValue value, final BasicValue expected)
throws AnalyzerException {
}
@Override
public BasicValue merge(final BasicValue v, final BasicValue w) {
if (!v.equals(w)) {
return BasicValue.UNINITIALIZED_VALUE;
}
return v;
}
}

View File

@@ -0,0 +1,140 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* 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 jdk.internal.org.objectweb.asm.tree.analysis;
import jdk.internal.org.objectweb.asm.Type;
/**
* A {@link Value} that is represented by its type in a seven types type system.
* This type system distinguishes the UNINITIALZED, INT, FLOAT, LONG, DOUBLE,
* REFERENCE and RETURNADDRESS types.
*
* @author Eric Bruneton
*/
public class BasicValue implements Value {
public static final BasicValue UNINITIALIZED_VALUE = new BasicValue(null);
public static final BasicValue INT_VALUE = new BasicValue(Type.INT_TYPE);
public static final BasicValue FLOAT_VALUE = new BasicValue(Type.FLOAT_TYPE);
public static final BasicValue LONG_VALUE = new BasicValue(Type.LONG_TYPE);
public static final BasicValue DOUBLE_VALUE = new BasicValue(
Type.DOUBLE_TYPE);
public static final BasicValue REFERENCE_VALUE = new BasicValue(
Type.getObjectType("java/lang/Object"));
public static final BasicValue RETURNADDRESS_VALUE = new BasicValue(
Type.VOID_TYPE);
private final Type type;
public BasicValue(final Type type) {
this.type = type;
}
public Type getType() {
return type;
}
public int getSize() {
return type == Type.LONG_TYPE || type == Type.DOUBLE_TYPE ? 2 : 1;
}
public boolean isReference() {
return type != null
&& (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY);
}
@Override
public boolean equals(final Object value) {
if (value == this) {
return true;
} else if (value instanceof BasicValue) {
if (type == null) {
return ((BasicValue) value).type == null;
} else {
return type.equals(((BasicValue) value).type);
}
} else {
return false;
}
}
@Override
public int hashCode() {
return type == null ? 0 : type.hashCode();
}
@Override
public String toString() {
if (this == UNINITIALIZED_VALUE) {
return ".";
} else if (this == RETURNADDRESS_VALUE) {
return "A";
} else if (this == REFERENCE_VALUE) {
return "R";
} else {
return type.getDescriptor();
}
}
}

View File

@@ -0,0 +1,462 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* 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 jdk.internal.org.objectweb.asm.tree.analysis;
import java.util.List;
import jdk.internal.org.objectweb.asm.Type;
import jdk.internal.org.objectweb.asm.tree.AbstractInsnNode;
import jdk.internal.org.objectweb.asm.tree.FieldInsnNode;
import jdk.internal.org.objectweb.asm.tree.InvokeDynamicInsnNode;
import jdk.internal.org.objectweb.asm.tree.MethodInsnNode;
/**
* An extended {@link BasicInterpreter} that checks that bytecode instructions
* are correctly used.
*
* @author Eric Bruneton
* @author Bing Ran
*/
public class BasicVerifier extends BasicInterpreter {
public BasicVerifier() {
super(ASM5);
}
protected BasicVerifier(final int api) {
super(api);
}
@Override
public BasicValue copyOperation(final AbstractInsnNode insn,
final BasicValue value) throws AnalyzerException {
Value expected;
switch (insn.getOpcode()) {
case ILOAD:
case ISTORE:
expected = BasicValue.INT_VALUE;
break;
case FLOAD:
case FSTORE:
expected = BasicValue.FLOAT_VALUE;
break;
case LLOAD:
case LSTORE:
expected = BasicValue.LONG_VALUE;
break;
case DLOAD:
case DSTORE:
expected = BasicValue.DOUBLE_VALUE;
break;
case ALOAD:
if (!value.isReference()) {
throw new AnalyzerException(insn, null, "an object reference",
value);
}
return value;
case ASTORE:
if (!value.isReference()
&& !BasicValue.RETURNADDRESS_VALUE.equals(value)) {
throw new AnalyzerException(insn, null,
"an object reference or a return address", value);
}
return value;
default:
return value;
}
if (!expected.equals(value)) {
throw new AnalyzerException(insn, null, expected, value);
}
return value;
}
@Override
public BasicValue unaryOperation(final AbstractInsnNode insn,
final BasicValue value) throws AnalyzerException {
BasicValue expected;
switch (insn.getOpcode()) {
case INEG:
case IINC:
case I2F:
case I2L:
case I2D:
case I2B:
case I2C:
case I2S:
case IFEQ:
case IFNE:
case IFLT:
case IFGE:
case IFGT:
case IFLE:
case TABLESWITCH:
case LOOKUPSWITCH:
case IRETURN:
case NEWARRAY:
case ANEWARRAY:
expected = BasicValue.INT_VALUE;
break;
case FNEG:
case F2I:
case F2L:
case F2D:
case FRETURN:
expected = BasicValue.FLOAT_VALUE;
break;
case LNEG:
case L2I:
case L2F:
case L2D:
case LRETURN:
expected = BasicValue.LONG_VALUE;
break;
case DNEG:
case D2I:
case D2F:
case D2L:
case DRETURN:
expected = BasicValue.DOUBLE_VALUE;
break;
case GETFIELD:
expected = newValue(Type
.getObjectType(((FieldInsnNode) insn).owner));
break;
case CHECKCAST:
if (!value.isReference()) {
throw new AnalyzerException(insn, null, "an object reference",
value);
}
return super.unaryOperation(insn, value);
case ARRAYLENGTH:
if (!isArrayValue(value)) {
throw new AnalyzerException(insn, null, "an array reference",
value);
}
return super.unaryOperation(insn, value);
case ARETURN:
case ATHROW:
case INSTANCEOF:
case MONITORENTER:
case MONITOREXIT:
case IFNULL:
case IFNONNULL:
if (!value.isReference()) {
throw new AnalyzerException(insn, null, "an object reference",
value);
}
return super.unaryOperation(insn, value);
case PUTSTATIC:
expected = newValue(Type.getType(((FieldInsnNode) insn).desc));
break;
default:
throw new Error("Internal error.");
}
if (!isSubTypeOf(value, expected)) {
throw new AnalyzerException(insn, null, expected, value);
}
return super.unaryOperation(insn, value);
}
@Override
public BasicValue binaryOperation(final AbstractInsnNode insn,
final BasicValue value1, final BasicValue value2)
throws AnalyzerException {
BasicValue expected1;
BasicValue expected2;
switch (insn.getOpcode()) {
case IALOAD:
expected1 = newValue(Type.getType("[I"));
expected2 = BasicValue.INT_VALUE;
break;
case BALOAD:
if (isSubTypeOf(value1, newValue(Type.getType("[Z")))) {
expected1 = newValue(Type.getType("[Z"));
} else {
expected1 = newValue(Type.getType("[B"));
}
expected2 = BasicValue.INT_VALUE;
break;
case CALOAD:
expected1 = newValue(Type.getType("[C"));
expected2 = BasicValue.INT_VALUE;
break;
case SALOAD:
expected1 = newValue(Type.getType("[S"));
expected2 = BasicValue.INT_VALUE;
break;
case LALOAD:
expected1 = newValue(Type.getType("[J"));
expected2 = BasicValue.INT_VALUE;
break;
case FALOAD:
expected1 = newValue(Type.getType("[F"));
expected2 = BasicValue.INT_VALUE;
break;
case DALOAD:
expected1 = newValue(Type.getType("[D"));
expected2 = BasicValue.INT_VALUE;
break;
case AALOAD:
expected1 = newValue(Type.getType("[Ljava/lang/Object;"));
expected2 = BasicValue.INT_VALUE;
break;
case IADD:
case ISUB:
case IMUL:
case IDIV:
case IREM:
case ISHL:
case ISHR:
case IUSHR:
case IAND:
case IOR:
case IXOR:
case IF_ICMPEQ:
case IF_ICMPNE:
case IF_ICMPLT:
case IF_ICMPGE:
case IF_ICMPGT:
case IF_ICMPLE:
expected1 = BasicValue.INT_VALUE;
expected2 = BasicValue.INT_VALUE;
break;
case FADD:
case FSUB:
case FMUL:
case FDIV:
case FREM:
case FCMPL:
case FCMPG:
expected1 = BasicValue.FLOAT_VALUE;
expected2 = BasicValue.FLOAT_VALUE;
break;
case LADD:
case LSUB:
case LMUL:
case LDIV:
case LREM:
case LAND:
case LOR:
case LXOR:
case LCMP:
expected1 = BasicValue.LONG_VALUE;
expected2 = BasicValue.LONG_VALUE;
break;
case LSHL:
case LSHR:
case LUSHR:
expected1 = BasicValue.LONG_VALUE;
expected2 = BasicValue.INT_VALUE;
break;
case DADD:
case DSUB:
case DMUL:
case DDIV:
case DREM:
case DCMPL:
case DCMPG:
expected1 = BasicValue.DOUBLE_VALUE;
expected2 = BasicValue.DOUBLE_VALUE;
break;
case IF_ACMPEQ:
case IF_ACMPNE:
expected1 = BasicValue.REFERENCE_VALUE;
expected2 = BasicValue.REFERENCE_VALUE;
break;
case PUTFIELD:
FieldInsnNode fin = (FieldInsnNode) insn;
expected1 = newValue(Type.getObjectType(fin.owner));
expected2 = newValue(Type.getType(fin.desc));
break;
default:
throw new Error("Internal error.");
}
if (!isSubTypeOf(value1, expected1)) {
throw new AnalyzerException(insn, "First argument", expected1,
value1);
} else if (!isSubTypeOf(value2, expected2)) {
throw new AnalyzerException(insn, "Second argument", expected2,
value2);
}
if (insn.getOpcode() == AALOAD) {
return getElementValue(value1);
} else {
return super.binaryOperation(insn, value1, value2);
}
}
@Override
public BasicValue ternaryOperation(final AbstractInsnNode insn,
final BasicValue value1, final BasicValue value2,
final BasicValue value3) throws AnalyzerException {
BasicValue expected1;
BasicValue expected3;
switch (insn.getOpcode()) {
case IASTORE:
expected1 = newValue(Type.getType("[I"));
expected3 = BasicValue.INT_VALUE;
break;
case BASTORE:
if (isSubTypeOf(value1, newValue(Type.getType("[Z")))) {
expected1 = newValue(Type.getType("[Z"));
} else {
expected1 = newValue(Type.getType("[B"));
}
expected3 = BasicValue.INT_VALUE;
break;
case CASTORE:
expected1 = newValue(Type.getType("[C"));
expected3 = BasicValue.INT_VALUE;
break;
case SASTORE:
expected1 = newValue(Type.getType("[S"));
expected3 = BasicValue.INT_VALUE;
break;
case LASTORE:
expected1 = newValue(Type.getType("[J"));
expected3 = BasicValue.LONG_VALUE;
break;
case FASTORE:
expected1 = newValue(Type.getType("[F"));
expected3 = BasicValue.FLOAT_VALUE;
break;
case DASTORE:
expected1 = newValue(Type.getType("[D"));
expected3 = BasicValue.DOUBLE_VALUE;
break;
case AASTORE:
expected1 = value1;
expected3 = BasicValue.REFERENCE_VALUE;
break;
default:
throw new Error("Internal error.");
}
if (!isSubTypeOf(value1, expected1)) {
throw new AnalyzerException(insn, "First argument", "a "
+ expected1 + " array reference", value1);
} else if (!BasicValue.INT_VALUE.equals(value2)) {
throw new AnalyzerException(insn, "Second argument",
BasicValue.INT_VALUE, value2);
} else if (!isSubTypeOf(value3, expected3)) {
throw new AnalyzerException(insn, "Third argument", expected3,
value3);
}
return null;
}
@Override
public BasicValue naryOperation(final AbstractInsnNode insn,
final List<? extends BasicValue> values) throws AnalyzerException {
int opcode = insn.getOpcode();
if (opcode == MULTIANEWARRAY) {
for (int i = 0; i < values.size(); ++i) {
if (!BasicValue.INT_VALUE.equals(values.get(i))) {
throw new AnalyzerException(insn, null,
BasicValue.INT_VALUE, values.get(i));
}
}
} else {
int i = 0;
int j = 0;
if (opcode != INVOKESTATIC && opcode != INVOKEDYNAMIC) {
Type owner = Type.getObjectType(((MethodInsnNode) insn).owner);
if (!isSubTypeOf(values.get(i++), newValue(owner))) {
throw new AnalyzerException(insn, "Method owner",
newValue(owner), values.get(0));
}
}
String desc = (opcode == INVOKEDYNAMIC) ? ((InvokeDynamicInsnNode) insn).desc
: ((MethodInsnNode) insn).desc;
Type[] args = Type.getArgumentTypes(desc);
while (i < values.size()) {
BasicValue expected = newValue(args[j++]);
BasicValue encountered = values.get(i++);
if (!isSubTypeOf(encountered, expected)) {
throw new AnalyzerException(insn, "Argument " + j,
expected, encountered);
}
}
}
return super.naryOperation(insn, values);
}
@Override
public void returnOperation(final AbstractInsnNode insn,
final BasicValue value, final BasicValue expected)
throws AnalyzerException {
if (!isSubTypeOf(value, expected)) {
throw new AnalyzerException(insn, "Incompatible return type",
expected, value);
}
}
protected boolean isArrayValue(final BasicValue value) {
return value.isReference();
}
protected BasicValue getElementValue(final BasicValue objectArrayValue)
throws AnalyzerException {
return BasicValue.REFERENCE_VALUE;
}
protected boolean isSubTypeOf(final BasicValue value,
final BasicValue expected) {
return value.equals(expected);
}
}

View File

@@ -0,0 +1,768 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* 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 jdk.internal.org.objectweb.asm.tree.analysis;
import java.util.ArrayList;
import java.util.List;
import jdk.internal.org.objectweb.asm.Opcodes;
import jdk.internal.org.objectweb.asm.Type;
import jdk.internal.org.objectweb.asm.tree.AbstractInsnNode;
import jdk.internal.org.objectweb.asm.tree.IincInsnNode;
import jdk.internal.org.objectweb.asm.tree.InvokeDynamicInsnNode;
import jdk.internal.org.objectweb.asm.tree.MethodInsnNode;
import jdk.internal.org.objectweb.asm.tree.MultiANewArrayInsnNode;
import jdk.internal.org.objectweb.asm.tree.VarInsnNode;
/**
* A symbolic execution stack frame. A stack frame contains a set of local
* variable slots, and an operand stack. Warning: long and double values are
* represented by <i>two</i> slots in local variables, and by <i>one</i> slot in
* the operand stack.
*
* @param <V>
* type of the Value used for the analysis.
*
* @author Eric Bruneton
*/
public class Frame<V extends Value> {
/**
* The expected return type of the analyzed method, or <tt>null</tt> if the
* method returns void.
*/
private V returnValue;
/**
* The local variables and operand stack of this frame.
*/
private V[] values;
/**
* The number of local variables of this frame.
*/
private int locals;
/**
* The number of elements in the operand stack.
*/
private int top;
/**
* Constructs a new frame with the given size.
*
* @param nLocals
* the maximum number of local variables of the frame.
* @param nStack
* the maximum stack size of the frame.
*/
@SuppressWarnings("unchecked")
public Frame(final int nLocals, final int nStack) {
this.values = (V[]) new Value[nLocals + nStack];
this.locals = nLocals;
}
/**
* Constructs a new frame that is identical to the given frame.
*
* @param src
* a frame.
*/
public Frame(final Frame<? extends V> src) {
this(src.locals, src.values.length - src.locals);
init(src);
}
/**
* Copies the state of the given frame into this frame.
*
* @param src
* a frame.
* @return this frame.
*/
public Frame<V> init(final Frame<? extends V> src) {
returnValue = src.returnValue;
System.arraycopy(src.values, 0, values, 0, values.length);
top = src.top;
return this;
}
/**
* Sets the expected return type of the analyzed method.
*
* @param v
* the expected return type of the analyzed method, or
* <tt>null</tt> if the method returns void.
*/
public void setReturn(final V v) {
returnValue = v;
}
/**
* Returns the maximum number of local variables of this frame.
*
* @return the maximum number of local variables of this frame.
*/
public int getLocals() {
return locals;
}
/**
* Returns the maximum stack size of this frame.
*
* @return the maximum stack size of this frame.
*/
public int getMaxStackSize() {
return values.length - locals;
}
/**
* Returns the value of the given local variable.
*
* @param i
* a local variable index.
* @return the value of the given local variable.
* @throws IndexOutOfBoundsException
* if the variable does not exist.
*/
public V getLocal(final int i) throws IndexOutOfBoundsException {
if (i >= locals) {
throw new IndexOutOfBoundsException(
"Trying to access an inexistant local variable");
}
return values[i];
}
/**
* Sets the value of the given local variable.
*
* @param i
* a local variable index.
* @param value
* the new value of this local variable.
* @throws IndexOutOfBoundsException
* if the variable does not exist.
*/
public void setLocal(final int i, final V value)
throws IndexOutOfBoundsException {
if (i >= locals) {
throw new IndexOutOfBoundsException(
"Trying to access an inexistant local variable " + i);
}
values[i] = value;
}
/**
* Returns the number of values in the operand stack of this frame. Long and
* double values are treated as single values.
*
* @return the number of values in the operand stack of this frame.
*/
public int getStackSize() {
return top;
}
/**
* Returns the value of the given operand stack slot.
*
* @param i
* the index of an operand stack slot.
* @return the value of the given operand stack slot.
* @throws IndexOutOfBoundsException
* if the operand stack slot does not exist.
*/
public V getStack(final int i) throws IndexOutOfBoundsException {
return values[i + locals];
}
/**
* Clears the operand stack of this frame.
*/
public void clearStack() {
top = 0;
}
/**
* Pops a value from the operand stack of this frame.
*
* @return the value that has been popped from the stack.
* @throws IndexOutOfBoundsException
* if the operand stack is empty.
*/
public V pop() throws IndexOutOfBoundsException {
if (top == 0) {
throw new IndexOutOfBoundsException(
"Cannot pop operand off an empty stack.");
}
return values[--top + locals];
}
/**
* Pushes a value into the operand stack of this frame.
*
* @param value
* the value that must be pushed into the stack.
* @throws IndexOutOfBoundsException
* if the operand stack is full.
*/
public void push(final V value) throws IndexOutOfBoundsException {
if (top + locals >= values.length) {
throw new IndexOutOfBoundsException(
"Insufficient maximum stack size.");
}
values[top++ + locals] = value;
}
public void execute(final AbstractInsnNode insn,
final Interpreter<V> interpreter) throws AnalyzerException {
V value1, value2, value3, value4;
List<V> values;
int var;
switch (insn.getOpcode()) {
case Opcodes.NOP:
break;
case Opcodes.ACONST_NULL:
case Opcodes.ICONST_M1:
case Opcodes.ICONST_0:
case Opcodes.ICONST_1:
case Opcodes.ICONST_2:
case Opcodes.ICONST_3:
case Opcodes.ICONST_4:
case Opcodes.ICONST_5:
case Opcodes.LCONST_0:
case Opcodes.LCONST_1:
case Opcodes.FCONST_0:
case Opcodes.FCONST_1:
case Opcodes.FCONST_2:
case Opcodes.DCONST_0:
case Opcodes.DCONST_1:
case Opcodes.BIPUSH:
case Opcodes.SIPUSH:
case Opcodes.LDC:
push(interpreter.newOperation(insn));
break;
case Opcodes.ILOAD:
case Opcodes.LLOAD:
case Opcodes.FLOAD:
case Opcodes.DLOAD:
case Opcodes.ALOAD:
push(interpreter.copyOperation(insn,
getLocal(((VarInsnNode) insn).var)));
break;
case Opcodes.IALOAD:
case Opcodes.LALOAD:
case Opcodes.FALOAD:
case Opcodes.DALOAD:
case Opcodes.AALOAD:
case Opcodes.BALOAD:
case Opcodes.CALOAD:
case Opcodes.SALOAD:
value2 = pop();
value1 = pop();
push(interpreter.binaryOperation(insn, value1, value2));
break;
case Opcodes.ISTORE:
case Opcodes.LSTORE:
case Opcodes.FSTORE:
case Opcodes.DSTORE:
case Opcodes.ASTORE:
value1 = interpreter.copyOperation(insn, pop());
var = ((VarInsnNode) insn).var;
setLocal(var, value1);
if (value1.getSize() == 2) {
setLocal(var + 1, interpreter.newValue(null));
}
if (var > 0) {
Value local = getLocal(var - 1);
if (local != null && local.getSize() == 2) {
setLocal(var - 1, interpreter.newValue(null));
}
}
break;
case Opcodes.IASTORE:
case Opcodes.LASTORE:
case Opcodes.FASTORE:
case Opcodes.DASTORE:
case Opcodes.AASTORE:
case Opcodes.BASTORE:
case Opcodes.CASTORE:
case Opcodes.SASTORE:
value3 = pop();
value2 = pop();
value1 = pop();
interpreter.ternaryOperation(insn, value1, value2, value3);
break;
case Opcodes.POP:
if (pop().getSize() == 2) {
throw new AnalyzerException(insn, "Illegal use of POP");
}
break;
case Opcodes.POP2:
if (pop().getSize() == 1) {
if (pop().getSize() != 1) {
throw new AnalyzerException(insn, "Illegal use of POP2");
}
}
break;
case Opcodes.DUP:
value1 = pop();
if (value1.getSize() != 1) {
throw new AnalyzerException(insn, "Illegal use of DUP");
}
push(value1);
push(interpreter.copyOperation(insn, value1));
break;
case Opcodes.DUP_X1:
value1 = pop();
value2 = pop();
if (value1.getSize() != 1 || value2.getSize() != 1) {
throw new AnalyzerException(insn, "Illegal use of DUP_X1");
}
push(interpreter.copyOperation(insn, value1));
push(value2);
push(value1);
break;
case Opcodes.DUP_X2:
value1 = pop();
if (value1.getSize() == 1) {
value2 = pop();
if (value2.getSize() == 1) {
value3 = pop();
if (value3.getSize() == 1) {
push(interpreter.copyOperation(insn, value1));
push(value3);
push(value2);
push(value1);
break;
}
} else {
push(interpreter.copyOperation(insn, value1));
push(value2);
push(value1);
break;
}
}
throw new AnalyzerException(insn, "Illegal use of DUP_X2");
case Opcodes.DUP2:
value1 = pop();
if (value1.getSize() == 1) {
value2 = pop();
if (value2.getSize() == 1) {
push(value2);
push(value1);
push(interpreter.copyOperation(insn, value2));
push(interpreter.copyOperation(insn, value1));
break;
}
} else {
push(value1);
push(interpreter.copyOperation(insn, value1));
break;
}
throw new AnalyzerException(insn, "Illegal use of DUP2");
case Opcodes.DUP2_X1:
value1 = pop();
if (value1.getSize() == 1) {
value2 = pop();
if (value2.getSize() == 1) {
value3 = pop();
if (value3.getSize() == 1) {
push(interpreter.copyOperation(insn, value2));
push(interpreter.copyOperation(insn, value1));
push(value3);
push(value2);
push(value1);
break;
}
}
} else {
value2 = pop();
if (value2.getSize() == 1) {
push(interpreter.copyOperation(insn, value1));
push(value2);
push(value1);
break;
}
}
throw new AnalyzerException(insn, "Illegal use of DUP2_X1");
case Opcodes.DUP2_X2:
value1 = pop();
if (value1.getSize() == 1) {
value2 = pop();
if (value2.getSize() == 1) {
value3 = pop();
if (value3.getSize() == 1) {
value4 = pop();
if (value4.getSize() == 1) {
push(interpreter.copyOperation(insn, value2));
push(interpreter.copyOperation(insn, value1));
push(value4);
push(value3);
push(value2);
push(value1);
break;
}
} else {
push(interpreter.copyOperation(insn, value2));
push(interpreter.copyOperation(insn, value1));
push(value3);
push(value2);
push(value1);
break;
}
}
} else {
value2 = pop();
if (value2.getSize() == 1) {
value3 = pop();
if (value3.getSize() == 1) {
push(interpreter.copyOperation(insn, value1));
push(value3);
push(value2);
push(value1);
break;
}
} else {
push(interpreter.copyOperation(insn, value1));
push(value2);
push(value1);
break;
}
}
throw new AnalyzerException(insn, "Illegal use of DUP2_X2");
case Opcodes.SWAP:
value2 = pop();
value1 = pop();
if (value1.getSize() != 1 || value2.getSize() != 1) {
throw new AnalyzerException(insn, "Illegal use of SWAP");
}
push(interpreter.copyOperation(insn, value2));
push(interpreter.copyOperation(insn, value1));
break;
case Opcodes.IADD:
case Opcodes.LADD:
case Opcodes.FADD:
case Opcodes.DADD:
case Opcodes.ISUB:
case Opcodes.LSUB:
case Opcodes.FSUB:
case Opcodes.DSUB:
case Opcodes.IMUL:
case Opcodes.LMUL:
case Opcodes.FMUL:
case Opcodes.DMUL:
case Opcodes.IDIV:
case Opcodes.LDIV:
case Opcodes.FDIV:
case Opcodes.DDIV:
case Opcodes.IREM:
case Opcodes.LREM:
case Opcodes.FREM:
case Opcodes.DREM:
value2 = pop();
value1 = pop();
push(interpreter.binaryOperation(insn, value1, value2));
break;
case Opcodes.INEG:
case Opcodes.LNEG:
case Opcodes.FNEG:
case Opcodes.DNEG:
push(interpreter.unaryOperation(insn, pop()));
break;
case Opcodes.ISHL:
case Opcodes.LSHL:
case Opcodes.ISHR:
case Opcodes.LSHR:
case Opcodes.IUSHR:
case Opcodes.LUSHR:
case Opcodes.IAND:
case Opcodes.LAND:
case Opcodes.IOR:
case Opcodes.LOR:
case Opcodes.IXOR:
case Opcodes.LXOR:
value2 = pop();
value1 = pop();
push(interpreter.binaryOperation(insn, value1, value2));
break;
case Opcodes.IINC:
var = ((IincInsnNode) insn).var;
setLocal(var, interpreter.unaryOperation(insn, getLocal(var)));
break;
case Opcodes.I2L:
case Opcodes.I2F:
case Opcodes.I2D:
case Opcodes.L2I:
case Opcodes.L2F:
case Opcodes.L2D:
case Opcodes.F2I:
case Opcodes.F2L:
case Opcodes.F2D:
case Opcodes.D2I:
case Opcodes.D2L:
case Opcodes.D2F:
case Opcodes.I2B:
case Opcodes.I2C:
case Opcodes.I2S:
push(interpreter.unaryOperation(insn, pop()));
break;
case Opcodes.LCMP:
case Opcodes.FCMPL:
case Opcodes.FCMPG:
case Opcodes.DCMPL:
case Opcodes.DCMPG:
value2 = pop();
value1 = pop();
push(interpreter.binaryOperation(insn, value1, value2));
break;
case Opcodes.IFEQ:
case Opcodes.IFNE:
case Opcodes.IFLT:
case Opcodes.IFGE:
case Opcodes.IFGT:
case Opcodes.IFLE:
interpreter.unaryOperation(insn, pop());
break;
case Opcodes.IF_ICMPEQ:
case Opcodes.IF_ICMPNE:
case Opcodes.IF_ICMPLT:
case Opcodes.IF_ICMPGE:
case Opcodes.IF_ICMPGT:
case Opcodes.IF_ICMPLE:
case Opcodes.IF_ACMPEQ:
case Opcodes.IF_ACMPNE:
value2 = pop();
value1 = pop();
interpreter.binaryOperation(insn, value1, value2);
break;
case Opcodes.GOTO:
break;
case Opcodes.JSR:
push(interpreter.newOperation(insn));
break;
case Opcodes.RET:
break;
case Opcodes.TABLESWITCH:
case Opcodes.LOOKUPSWITCH:
interpreter.unaryOperation(insn, pop());
break;
case Opcodes.IRETURN:
case Opcodes.LRETURN:
case Opcodes.FRETURN:
case Opcodes.DRETURN:
case Opcodes.ARETURN:
value1 = pop();
interpreter.unaryOperation(insn, value1);
interpreter.returnOperation(insn, value1, returnValue);
break;
case Opcodes.RETURN:
if (returnValue != null) {
throw new AnalyzerException(insn, "Incompatible return type");
}
break;
case Opcodes.GETSTATIC:
push(interpreter.newOperation(insn));
break;
case Opcodes.PUTSTATIC:
interpreter.unaryOperation(insn, pop());
break;
case Opcodes.GETFIELD:
push(interpreter.unaryOperation(insn, pop()));
break;
case Opcodes.PUTFIELD:
value2 = pop();
value1 = pop();
interpreter.binaryOperation(insn, value1, value2);
break;
case Opcodes.INVOKEVIRTUAL:
case Opcodes.INVOKESPECIAL:
case Opcodes.INVOKESTATIC:
case Opcodes.INVOKEINTERFACE: {
values = new ArrayList<V>();
String desc = ((MethodInsnNode) insn).desc;
for (int i = Type.getArgumentTypes(desc).length; i > 0; --i) {
values.add(0, pop());
}
if (insn.getOpcode() != Opcodes.INVOKESTATIC) {
values.add(0, pop());
}
if (Type.getReturnType(desc) == Type.VOID_TYPE) {
interpreter.naryOperation(insn, values);
} else {
push(interpreter.naryOperation(insn, values));
}
break;
}
case Opcodes.INVOKEDYNAMIC: {
values = new ArrayList<V>();
String desc = ((InvokeDynamicInsnNode) insn).desc;
for (int i = Type.getArgumentTypes(desc).length; i > 0; --i) {
values.add(0, pop());
}
if (Type.getReturnType(desc) == Type.VOID_TYPE) {
interpreter.naryOperation(insn, values);
} else {
push(interpreter.naryOperation(insn, values));
}
break;
}
case Opcodes.NEW:
push(interpreter.newOperation(insn));
break;
case Opcodes.NEWARRAY:
case Opcodes.ANEWARRAY:
case Opcodes.ARRAYLENGTH:
push(interpreter.unaryOperation(insn, pop()));
break;
case Opcodes.ATHROW:
interpreter.unaryOperation(insn, pop());
break;
case Opcodes.CHECKCAST:
case Opcodes.INSTANCEOF:
push(interpreter.unaryOperation(insn, pop()));
break;
case Opcodes.MONITORENTER:
case Opcodes.MONITOREXIT:
interpreter.unaryOperation(insn, pop());
break;
case Opcodes.MULTIANEWARRAY:
values = new ArrayList<V>();
for (int i = ((MultiANewArrayInsnNode) insn).dims; i > 0; --i) {
values.add(0, pop());
}
push(interpreter.naryOperation(insn, values));
break;
case Opcodes.IFNULL:
case Opcodes.IFNONNULL:
interpreter.unaryOperation(insn, pop());
break;
default:
throw new RuntimeException("Illegal opcode " + insn.getOpcode());
}
}
/**
* Merges this frame with the given frame.
*
* @param frame
* a frame.
* @param interpreter
* the interpreter used to merge values.
* @return <tt>true</tt> if this frame has been changed as a result of the
* merge operation, or <tt>false</tt> otherwise.
* @throws AnalyzerException
* if the frames have incompatible sizes.
*/
public boolean merge(final Frame<? extends V> frame,
final Interpreter<V> interpreter) throws AnalyzerException {
if (top != frame.top) {
throw new AnalyzerException(null, "Incompatible stack heights");
}
boolean changes = false;
for (int i = 0; i < locals + top; ++i) {
V v = interpreter.merge(values[i], frame.values[i]);
if (!v.equals(values[i])) {
values[i] = v;
changes = true;
}
}
return changes;
}
/**
* Merges this frame with the given frame (case of a RET instruction).
*
* @param frame
* a frame
* @param access
* the local variables that have been accessed by the subroutine
* to which the RET instruction corresponds.
* @return <tt>true</tt> if this frame has been changed as a result of the
* merge operation, or <tt>false</tt> otherwise.
*/
public boolean merge(final Frame<? extends V> frame, final boolean[] access) {
boolean changes = false;
for (int i = 0; i < locals; ++i) {
if (!access[i] && !values[i].equals(frame.values[i])) {
values[i] = frame.values[i];
changes = true;
}
}
return changes;
}
/**
* Returns a string representation of this frame.
*
* @return a string representation of this frame.
*/
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < getLocals(); ++i) {
sb.append(getLocal(i));
}
sb.append(' ');
for (int i = 0; i < getStackSize(); ++i) {
sb.append(getStack(i).toString());
}
return sb.toString();
}
}

View File

@@ -0,0 +1,255 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* 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 jdk.internal.org.objectweb.asm.tree.analysis;
import java.util.List;
import jdk.internal.org.objectweb.asm.Type;
import jdk.internal.org.objectweb.asm.tree.AbstractInsnNode;
/**
* A semantic bytecode interpreter. More precisely, this interpreter only
* manages the computation of values from other values: it does not manage the
* transfer of values to or from the stack, and to or from the local variables.
* This separation allows a generic bytecode {@link Analyzer} to work with
* various semantic interpreters, without needing to duplicate the code to
* simulate the transfer of values.
*
* @param <V>
* type of the Value used for the analysis.
*
* @author Eric Bruneton
*/
public abstract class Interpreter<V extends Value> {
protected final int api;
protected Interpreter(final int api) {
this.api = api;
}
/**
* Creates a new value that represents the given type.
*
* Called for method parameters (including <code>this</code>), exception
* handler variable and with <code>null</code> type for variables reserved
* by long and double types.
*
* @param type
* a primitive or reference type, or <tt>null</tt> to represent
* an uninitialized value.
* @return a value that represents the given type. The size of the returned
* value must be equal to the size of the given type.
*/
public abstract V newValue(Type type);
/**
* Interprets a bytecode instruction without arguments. This method is
* called for the following opcodes:
*
* ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4,
* ICONST_5, LCONST_0, LCONST_1, FCONST_0, FCONST_1, FCONST_2, DCONST_0,
* DCONST_1, BIPUSH, SIPUSH, LDC, JSR, GETSTATIC, NEW
*
* @param insn
* the bytecode instruction to be interpreted.
* @return the result of the interpretation of the given instruction.
* @throws AnalyzerException
* if an error occured during the interpretation.
*/
public abstract V newOperation(AbstractInsnNode insn)
throws AnalyzerException;
/**
* Interprets a bytecode instruction that moves a value on the stack or to
* or from local variables. This method is called for the following opcodes:
*
* ILOAD, LLOAD, FLOAD, DLOAD, ALOAD, ISTORE, LSTORE, FSTORE, DSTORE,
* ASTORE, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1, DUP2_X2, SWAP
*
* @param insn
* the bytecode instruction to be interpreted.
* @param value
* the value that must be moved by the instruction.
* @return the result of the interpretation of the given instruction. The
* returned value must be <tt>equal</tt> to the given value.
* @throws AnalyzerException
* if an error occured during the interpretation.
*/
public abstract V copyOperation(AbstractInsnNode insn, V value)
throws AnalyzerException;
/**
* Interprets a bytecode instruction with a single argument. This method is
* called for the following opcodes:
*
* INEG, LNEG, FNEG, DNEG, IINC, I2L, I2F, I2D, L2I, L2F, L2D, F2I, F2L,
* F2D, D2I, D2L, D2F, I2B, I2C, I2S, IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE,
* TABLESWITCH, LOOKUPSWITCH, IRETURN, LRETURN, FRETURN, DRETURN, ARETURN,
* PUTSTATIC, GETFIELD, NEWARRAY, ANEWARRAY, ARRAYLENGTH, ATHROW, CHECKCAST,
* INSTANCEOF, MONITORENTER, MONITOREXIT, IFNULL, IFNONNULL
*
* @param insn
* the bytecode instruction to be interpreted.
* @param value
* the argument of the instruction to be interpreted.
* @return the result of the interpretation of the given instruction.
* @throws AnalyzerException
* if an error occured during the interpretation.
*/
public abstract V unaryOperation(AbstractInsnNode insn, V value)
throws AnalyzerException;
/**
* Interprets a bytecode instruction with two arguments. This method is
* called for the following opcodes:
*
* IALOAD, LALOAD, FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, SALOAD, IADD,
* LADD, FADD, DADD, ISUB, LSUB, FSUB, DSUB, IMUL, LMUL, FMUL, DMUL, IDIV,
* LDIV, FDIV, DDIV, IREM, LREM, FREM, DREM, ISHL, LSHL, ISHR, LSHR, IUSHR,
* LUSHR, IAND, LAND, IOR, LOR, IXOR, LXOR, LCMP, FCMPL, FCMPG, DCMPL,
* DCMPG, IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE,
* IF_ACMPEQ, IF_ACMPNE, PUTFIELD
*
* @param insn
* the bytecode instruction to be interpreted.
* @param value1
* the first argument of the instruction to be interpreted.
* @param value2
* the second argument of the instruction to be interpreted.
* @return the result of the interpretation of the given instruction.
* @throws AnalyzerException
* if an error occured during the interpretation.
*/
public abstract V binaryOperation(AbstractInsnNode insn, V value1, V value2)
throws AnalyzerException;
/**
* Interprets a bytecode instruction with three arguments. This method is
* called for the following opcodes:
*
* IASTORE, LASTORE, FASTORE, DASTORE, AASTORE, BASTORE, CASTORE, SASTORE
*
* @param insn
* the bytecode instruction to be interpreted.
* @param value1
* the first argument of the instruction to be interpreted.
* @param value2
* the second argument of the instruction to be interpreted.
* @param value3
* the third argument of the instruction to be interpreted.
* @return the result of the interpretation of the given instruction.
* @throws AnalyzerException
* if an error occured during the interpretation.
*/
public abstract V ternaryOperation(AbstractInsnNode insn, V value1,
V value2, V value3) throws AnalyzerException;
/**
* Interprets a bytecode instruction with a variable number of arguments.
* This method is called for the following opcodes:
*
* INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC, INVOKEINTERFACE,
* MULTIANEWARRAY and INVOKEDYNAMIC
*
* @param insn
* the bytecode instruction to be interpreted.
* @param values
* the arguments of the instruction to be interpreted.
* @return the result of the interpretation of the given instruction.
* @throws AnalyzerException
* if an error occured during the interpretation.
*/
public abstract V naryOperation(AbstractInsnNode insn,
List<? extends V> values) throws AnalyzerException;
/**
* Interprets a bytecode return instruction. This method is called for the
* following opcodes:
*
* IRETURN, LRETURN, FRETURN, DRETURN, ARETURN
*
* @param insn
* the bytecode instruction to be interpreted.
* @param value
* the argument of the instruction to be interpreted.
* @param expected
* the expected return type of the analyzed method.
* @throws AnalyzerException
* if an error occured during the interpretation.
*/
public abstract void returnOperation(AbstractInsnNode insn, V value,
V expected) throws AnalyzerException;
/**
* Merges two values. The merge operation must return a value that
* represents both values (for instance, if the two values are two types,
* the merged value must be a common super type of the two types. If the two
* values are integer intervals, the merged value must be an interval that
* contains the previous ones. Likewise for other types of values).
*
* @param v
* a value.
* @param w
* another value.
* @return the merged value. If the merged value is equal to <tt>v</tt>,
* this method <i>must</i> return <tt>v</tt>.
*/
public abstract V merge(V v, V w);
}

View File

@@ -0,0 +1,349 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* 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 jdk.internal.org.objectweb.asm.tree.analysis;
import java.util.List;
import jdk.internal.org.objectweb.asm.Type;
/**
* An extended {@link BasicVerifier} that performs more precise verifications.
* This verifier computes exact class types, instead of using a single "object
* reference" type (as done in the {@link BasicVerifier}).
*
* @author Eric Bruneton
* @author Bing Ran
*/
public class SimpleVerifier extends BasicVerifier {
/**
* The class that is verified.
*/
private final Type currentClass;
/**
* The super class of the class that is verified.
*/
private final Type currentSuperClass;
/**
* The interfaces implemented by the class that is verified.
*/
private final List<Type> currentClassInterfaces;
/**
* If the class that is verified is an interface.
*/
private final boolean isInterface;
/**
* The loader to use for referenced classes.
*/
private ClassLoader loader = getClass().getClassLoader();
/**
* Constructs a new {@link SimpleVerifier}.
*/
public SimpleVerifier() {
this(null, null, false);
}
/**
* Constructs a new {@link SimpleVerifier} to verify a specific class. This
* class will not be loaded into the JVM since it may be incorrect.
*
* @param currentClass
* the class that is verified.
* @param currentSuperClass
* the super class of the class that is verified.
* @param isInterface
* if the class that is verified is an interface.
*/
public SimpleVerifier(final Type currentClass,
final Type currentSuperClass, final boolean isInterface) {
this(currentClass, currentSuperClass, null, isInterface);
}
/**
* Constructs a new {@link SimpleVerifier} to verify a specific class. This
* class will not be loaded into the JVM since it may be incorrect.
*
* @param currentClass
* the class that is verified.
* @param currentSuperClass
* the super class of the class that is verified.
* @param currentClassInterfaces
* the interfaces implemented by the class that is verified.
* @param isInterface
* if the class that is verified is an interface.
*/
public SimpleVerifier(final Type currentClass,
final Type currentSuperClass,
final List<Type> currentClassInterfaces, final boolean isInterface) {
this(ASM5, currentClass, currentSuperClass, currentClassInterfaces,
isInterface);
}
protected SimpleVerifier(final int api, final Type currentClass,
final Type currentSuperClass,
final List<Type> currentClassInterfaces, final boolean isInterface) {
super(api);
this.currentClass = currentClass;
this.currentSuperClass = currentSuperClass;
this.currentClassInterfaces = currentClassInterfaces;
this.isInterface = isInterface;
}
/**
* Set the <code>ClassLoader</code> which will be used to load referenced
* classes. This is useful if you are verifying multiple interdependent
* classes.
*
* @param loader
* a <code>ClassLoader</code> to use
*/
public void setClassLoader(final ClassLoader loader) {
this.loader = loader;
}
@Override
public BasicValue newValue(final Type type) {
if (type == null) {
return BasicValue.UNINITIALIZED_VALUE;
}
boolean isArray = type.getSort() == Type.ARRAY;
if (isArray) {
switch (type.getElementType().getSort()) {
case Type.BOOLEAN:
case Type.CHAR:
case Type.BYTE:
case Type.SHORT:
return new BasicValue(type);
}
}
BasicValue v = super.newValue(type);
if (BasicValue.REFERENCE_VALUE.equals(v)) {
if (isArray) {
v = newValue(type.getElementType());
String desc = v.getType().getDescriptor();
for (int i = 0; i < type.getDimensions(); ++i) {
desc = '[' + desc;
}
v = new BasicValue(Type.getType(desc));
} else {
v = new BasicValue(type);
}
}
return v;
}
@Override
protected boolean isArrayValue(final BasicValue value) {
Type t = value.getType();
return t != null
&& ("Lnull;".equals(t.getDescriptor()) || t.getSort() == Type.ARRAY);
}
@Override
protected BasicValue getElementValue(final BasicValue objectArrayValue)
throws AnalyzerException {
Type arrayType = objectArrayValue.getType();
if (arrayType != null) {
if (arrayType.getSort() == Type.ARRAY) {
return newValue(Type.getType(arrayType.getDescriptor()
.substring(1)));
} else if ("Lnull;".equals(arrayType.getDescriptor())) {
return objectArrayValue;
}
}
throw new Error("Internal error");
}
@Override
protected boolean isSubTypeOf(final BasicValue value,
final BasicValue expected) {
Type expectedType = expected.getType();
Type type = value.getType();
switch (expectedType.getSort()) {
case Type.INT:
case Type.FLOAT:
case Type.LONG:
case Type.DOUBLE:
return type.equals(expectedType);
case Type.ARRAY:
case Type.OBJECT:
if ("Lnull;".equals(type.getDescriptor())) {
return true;
} else if (type.getSort() == Type.OBJECT
|| type.getSort() == Type.ARRAY) {
return isAssignableFrom(expectedType, type);
} else {
return false;
}
default:
throw new Error("Internal error");
}
}
@Override
public BasicValue merge(final BasicValue v, final BasicValue w) {
if (!v.equals(w)) {
Type t = v.getType();
Type u = w.getType();
if (t != null
&& (t.getSort() == Type.OBJECT || t.getSort() == Type.ARRAY)) {
if (u != null
&& (u.getSort() == Type.OBJECT || u.getSort() == Type.ARRAY)) {
if ("Lnull;".equals(t.getDescriptor())) {
return w;
}
if ("Lnull;".equals(u.getDescriptor())) {
return v;
}
if (isAssignableFrom(t, u)) {
return v;
}
if (isAssignableFrom(u, t)) {
return w;
}
// TODO case of array classes of the same dimension
// TODO should we look also for a common super interface?
// problem: there may be several possible common super
// interfaces
do {
if (t == null || isInterface(t)) {
return BasicValue.REFERENCE_VALUE;
}
t = getSuperClass(t);
if (isAssignableFrom(t, u)) {
return newValue(t);
}
} while (true);
}
}
return BasicValue.UNINITIALIZED_VALUE;
}
return v;
}
protected boolean isInterface(final Type t) {
if (currentClass != null && t.equals(currentClass)) {
return isInterface;
}
return getClass(t).isInterface();
}
protected Type getSuperClass(final Type t) {
if (currentClass != null && t.equals(currentClass)) {
return currentSuperClass;
}
Class<?> c = getClass(t).getSuperclass();
return c == null ? null : Type.getType(c);
}
protected boolean isAssignableFrom(final Type t, final Type u) {
if (t.equals(u)) {
return true;
}
if (currentClass != null && t.equals(currentClass)) {
if (getSuperClass(u) == null) {
return false;
} else {
if (isInterface) {
return u.getSort() == Type.OBJECT
|| u.getSort() == Type.ARRAY;
}
return isAssignableFrom(t, getSuperClass(u));
}
}
if (currentClass != null && u.equals(currentClass)) {
if (isAssignableFrom(t, currentSuperClass)) {
return true;
}
if (currentClassInterfaces != null) {
for (int i = 0; i < currentClassInterfaces.size(); ++i) {
Type v = currentClassInterfaces.get(i);
if (isAssignableFrom(t, v)) {
return true;
}
}
}
return false;
}
Class<?> tc = getClass(t);
if (tc.isInterface()) {
tc = Object.class;
}
return tc.isAssignableFrom(getClass(u));
}
protected Class<?> getClass(final Type t) {
try {
if (t.getSort() == Type.ARRAY) {
return Class.forName(t.getDescriptor().replace('/', '.'),
false, loader);
}
return Class.forName(t.getClassName(), false, loader);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e.toString());
}
}
}

View File

@@ -0,0 +1,163 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* 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 jdk.internal.org.objectweb.asm.tree.analysis;
import java.util.AbstractSet;
import java.util.HashSet;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Set;
/**
* A set of at most two elements.
*
* @author Eric Bruneton
*/
class SmallSet<E> extends AbstractSet<E> implements Iterator<E> {
// if e1 is null, e2 must be null; otherwise e2 must be different from e1
E e1, e2;
static final <T> Set<T> emptySet() {
return new SmallSet<T>(null, null);
}
SmallSet(final E e1, final E e2) {
this.e1 = e1;
this.e2 = e2;
}
// -------------------------------------------------------------------------
// Implementation of inherited abstract methods
// -------------------------------------------------------------------------
@Override
public Iterator<E> iterator() {
return new SmallSet<E>(e1, e2);
}
@Override
public int size() {
return e1 == null ? 0 : (e2 == null ? 1 : 2);
}
// -------------------------------------------------------------------------
// Implementation of the Iterator interface
// -------------------------------------------------------------------------
public boolean hasNext() {
return e1 != null;
}
public E next() {
if (e1 == null) {
throw new NoSuchElementException();
}
E e = e1;
e1 = e2;
e2 = null;
return e;
}
public void remove() {
}
// -------------------------------------------------------------------------
// Utility methods
// -------------------------------------------------------------------------
Set<E> union(final SmallSet<E> s) {
if ((s.e1 == e1 && s.e2 == e2) || (s.e1 == e2 && s.e2 == e1)) {
return this; // if the two sets are equal, return this
}
if (s.e1 == null) {
return this; // if s is empty, return this
}
if (e1 == null) {
return s; // if this is empty, return s
}
if (s.e2 == null) { // s contains exactly one element
if (e2 == null) {
return new SmallSet<E>(e1, s.e1); // necessarily e1 != s.e1
} else if (s.e1 == e1 || s.e1 == e2) { // s is included in this
return this;
}
}
if (e2 == null) { // this contains exactly one element
// if (s.e2 == null) { // cannot happen
// return new SmallSet(e1, s.e1); // necessarily e1 != s.e1
// } else
if (e1 == s.e1 || e1 == s.e2) { // this in included in s
return s;
}
}
// here we know that there are at least 3 distinct elements
HashSet<E> r = new HashSet<E>(4);
r.add(e1);
if (e2 != null) {
r.add(e2);
}
r.add(s.e1);
if (s.e2 != null) {
r.add(s.e2);
}
return r;
}
}

View File

@@ -0,0 +1,227 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* 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 jdk.internal.org.objectweb.asm.tree.analysis;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import jdk.internal.org.objectweb.asm.Opcodes;
import jdk.internal.org.objectweb.asm.Type;
import jdk.internal.org.objectweb.asm.tree.AbstractInsnNode;
import jdk.internal.org.objectweb.asm.tree.FieldInsnNode;
import jdk.internal.org.objectweb.asm.tree.InvokeDynamicInsnNode;
import jdk.internal.org.objectweb.asm.tree.LdcInsnNode;
import jdk.internal.org.objectweb.asm.tree.MethodInsnNode;
/**
* An {@link Interpreter} for {@link SourceValue} values.
*
* @author Eric Bruneton
*/
public class SourceInterpreter extends Interpreter<SourceValue> implements
Opcodes {
public SourceInterpreter() {
super(ASM5);
}
protected SourceInterpreter(final int api) {
super(api);
}
@Override
public SourceValue newValue(final Type type) {
if (type == Type.VOID_TYPE) {
return null;
}
return new SourceValue(type == null ? 1 : type.getSize());
}
@Override
public SourceValue newOperation(final AbstractInsnNode insn) {
int size;
switch (insn.getOpcode()) {
case LCONST_0:
case LCONST_1:
case DCONST_0:
case DCONST_1:
size = 2;
break;
case LDC:
Object cst = ((LdcInsnNode) insn).cst;
size = cst instanceof Long || cst instanceof Double ? 2 : 1;
break;
case GETSTATIC:
size = Type.getType(((FieldInsnNode) insn).desc).getSize();
break;
default:
size = 1;
}
return new SourceValue(size, insn);
}
@Override
public SourceValue copyOperation(final AbstractInsnNode insn,
final SourceValue value) {
return new SourceValue(value.getSize(), insn);
}
@Override
public SourceValue unaryOperation(final AbstractInsnNode insn,
final SourceValue value) {
int size;
switch (insn.getOpcode()) {
case LNEG:
case DNEG:
case I2L:
case I2D:
case L2D:
case F2L:
case F2D:
case D2L:
size = 2;
break;
case GETFIELD:
size = Type.getType(((FieldInsnNode) insn).desc).getSize();
break;
default:
size = 1;
}
return new SourceValue(size, insn);
}
@Override
public SourceValue binaryOperation(final AbstractInsnNode insn,
final SourceValue value1, final SourceValue value2) {
int size;
switch (insn.getOpcode()) {
case LALOAD:
case DALOAD:
case LADD:
case DADD:
case LSUB:
case DSUB:
case LMUL:
case DMUL:
case LDIV:
case DDIV:
case LREM:
case DREM:
case LSHL:
case LSHR:
case LUSHR:
case LAND:
case LOR:
case LXOR:
size = 2;
break;
default:
size = 1;
}
return new SourceValue(size, insn);
}
@Override
public SourceValue ternaryOperation(final AbstractInsnNode insn,
final SourceValue value1, final SourceValue value2,
final SourceValue value3) {
return new SourceValue(1, insn);
}
@Override
public SourceValue naryOperation(final AbstractInsnNode insn,
final List<? extends SourceValue> values) {
int size;
int opcode = insn.getOpcode();
if (opcode == MULTIANEWARRAY) {
size = 1;
} else {
String desc = (opcode == INVOKEDYNAMIC) ? ((InvokeDynamicInsnNode) insn).desc
: ((MethodInsnNode) insn).desc;
size = Type.getReturnType(desc).getSize();
}
return new SourceValue(size, insn);
}
@Override
public void returnOperation(final AbstractInsnNode insn,
final SourceValue value, final SourceValue expected) {
}
@Override
public SourceValue merge(final SourceValue d, final SourceValue w) {
if (d.insns instanceof SmallSet && w.insns instanceof SmallSet) {
Set<AbstractInsnNode> s = ((SmallSet<AbstractInsnNode>) d.insns)
.union((SmallSet<AbstractInsnNode>) w.insns);
if (s == d.insns && d.size == w.size) {
return d;
} else {
return new SourceValue(Math.min(d.size, w.size), s);
}
}
if (d.size != w.size || !d.insns.containsAll(w.insns)) {
HashSet<AbstractInsnNode> s = new HashSet<AbstractInsnNode>();
s.addAll(d.insns);
s.addAll(w.insns);
return new SourceValue(Math.min(d.size, w.size), s);
}
return d;
}
}

View File

@@ -0,0 +1,126 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* 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 jdk.internal.org.objectweb.asm.tree.analysis;
import java.util.Set;
import jdk.internal.org.objectweb.asm.tree.AbstractInsnNode;
/**
* A {@link Value} that is represented by its type in a two types type system.
* This type system distinguishes the ONEWORD and TWOWORDS types.
*
* @author Eric Bruneton
*/
public class SourceValue implements Value {
/**
* The size of this value.
*/
public final int size;
/**
* The instructions that can produce this value. For example, for the Java
* code below, the instructions that can produce the value of <tt>i</tt> at
* line 5 are the txo ISTORE instructions at line 1 and 3:
*
* <pre>
* 1: i = 0;
* 2: if (...) {
* 3: i = 1;
* 4: }
* 5: return i;
* </pre>
*
* This field is a set of {@link AbstractInsnNode} objects.
*/
public final Set<AbstractInsnNode> insns;
public SourceValue(final int size) {
this(size, SmallSet.<AbstractInsnNode> emptySet());
}
public SourceValue(final int size, final AbstractInsnNode insn) {
this.size = size;
this.insns = new SmallSet<AbstractInsnNode>(insn, null);
}
public SourceValue(final int size, final Set<AbstractInsnNode> insns) {
this.size = size;
this.insns = insns;
}
public int getSize() {
return size;
}
@Override
public boolean equals(final Object value) {
if (!(value instanceof SourceValue)) {
return false;
}
SourceValue v = (SourceValue) value;
return size == v.size && insns.equals(v.insns);
}
@Override
public int hashCode() {
return insns.hashCode();
}
}

View File

@@ -0,0 +1,119 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* 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 jdk.internal.org.objectweb.asm.tree.analysis;
import java.util.ArrayList;
import java.util.List;
import jdk.internal.org.objectweb.asm.tree.JumpInsnNode;
import jdk.internal.org.objectweb.asm.tree.LabelNode;
/**
* A method subroutine (corresponds to a JSR instruction).
*
* @author Eric Bruneton
*/
class Subroutine {
LabelNode start;
boolean[] access;
List<JumpInsnNode> callers;
private Subroutine() {
}
Subroutine(final LabelNode start, final int maxLocals,
final JumpInsnNode caller) {
this.start = start;
this.access = new boolean[maxLocals];
this.callers = new ArrayList<JumpInsnNode>();
callers.add(caller);
}
public Subroutine copy() {
Subroutine result = new Subroutine();
result.start = start;
result.access = new boolean[access.length];
System.arraycopy(access, 0, result.access, 0, access.length);
result.callers = new ArrayList<JumpInsnNode>(callers);
return result;
}
public boolean merge(final Subroutine subroutine) throws AnalyzerException {
boolean changes = false;
for (int i = 0; i < access.length; ++i) {
if (subroutine.access[i] && !access[i]) {
access[i] = true;
changes = true;
}
}
if (subroutine.start == start) {
for (int i = 0; i < subroutine.callers.size(); ++i) {
JumpInsnNode caller = subroutine.callers.get(i);
if (!callers.contains(caller)) {
callers.add(caller);
changes = true;
}
}
}
return changes;
}
}

View File

@@ -0,0 +1,74 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* 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 jdk.internal.org.objectweb.asm.tree.analysis;
/**
* An immutable symbolic value for semantic interpretation of bytecode.
*
* @author Eric Bruneton
*/
public interface Value {
/**
* Returns the size of this value in words.
*
* @return either 1 or 2.
*/
int getSize();
}