mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-14 12:25:21 +00:00
8037221: [asm] refresh internal ASM version
Reviewed-by: psandoz, sundar
This commit is contained in:
parent
1afb74429d
commit
47e00453cc
@ -259,41 +259,68 @@ public class ByteVector {
|
||||
if (c >= '\001' && c <= '\177') {
|
||||
data[len++] = (byte) c;
|
||||
} else {
|
||||
int byteLength = i;
|
||||
for (int j = i; j < charLength; ++j) {
|
||||
c = s.charAt(j);
|
||||
if (c >= '\001' && c <= '\177') {
|
||||
byteLength++;
|
||||
} else if (c > '\u07FF') {
|
||||
byteLength += 3;
|
||||
} else {
|
||||
byteLength += 2;
|
||||
}
|
||||
}
|
||||
if (byteLength > 65535) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
data[length] = (byte) (byteLength >>> 8);
|
||||
data[length + 1] = (byte) byteLength;
|
||||
if (length + 2 + byteLength > data.length) {
|
||||
length = len;
|
||||
enlarge(2 + byteLength);
|
||||
data = this.data;
|
||||
}
|
||||
for (int j = i; j < charLength; ++j) {
|
||||
c = s.charAt(j);
|
||||
if (c >= '\001' && c <= '\177') {
|
||||
data[len++] = (byte) c;
|
||||
} else if (c > '\u07FF') {
|
||||
data[len++] = (byte) (0xE0 | c >> 12 & 0xF);
|
||||
data[len++] = (byte) (0x80 | c >> 6 & 0x3F);
|
||||
data[len++] = (byte) (0x80 | c & 0x3F);
|
||||
} else {
|
||||
data[len++] = (byte) (0xC0 | c >> 6 & 0x1F);
|
||||
data[len++] = (byte) (0x80 | c & 0x3F);
|
||||
}
|
||||
}
|
||||
break;
|
||||
length = len;
|
||||
return encodeUTF8(s, i, 65535);
|
||||
}
|
||||
}
|
||||
length = len;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts an UTF8 string into this byte vector. The byte vector is
|
||||
* automatically enlarged if necessary. The string length is encoded in two
|
||||
* bytes before the encoded characters, if there is space for that (i.e. if
|
||||
* this.length - i - 2 >= 0).
|
||||
*
|
||||
* @param s
|
||||
* the String to encode.
|
||||
* @param i
|
||||
* the index of the first character to encode. The previous
|
||||
* characters are supposed to have already been encoded, using
|
||||
* only one byte per character.
|
||||
* @param maxByteLength
|
||||
* the maximum byte length of the encoded string, including the
|
||||
* already encoded characters.
|
||||
* @return this byte vector.
|
||||
*/
|
||||
ByteVector encodeUTF8(final String s, int i, int maxByteLength) {
|
||||
int charLength = s.length();
|
||||
int byteLength = i;
|
||||
char c;
|
||||
for (int j = i; j < charLength; ++j) {
|
||||
c = s.charAt(j);
|
||||
if (c >= '\001' && c <= '\177') {
|
||||
byteLength++;
|
||||
} else if (c > '\u07FF') {
|
||||
byteLength += 3;
|
||||
} else {
|
||||
byteLength += 2;
|
||||
}
|
||||
}
|
||||
if (byteLength > maxByteLength) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
int start = length - i - 2;
|
||||
if (start >= 0) {
|
||||
data[start] = (byte) (byteLength >>> 8);
|
||||
data[start + 1] = (byte) byteLength;
|
||||
}
|
||||
if (length + byteLength - i > data.length) {
|
||||
enlarge(byteLength - i);
|
||||
}
|
||||
int len = length;
|
||||
for (int j = i; j < charLength; ++j) {
|
||||
c = s.charAt(j);
|
||||
if (c >= '\001' && c <= '\177') {
|
||||
data[len++] = (byte) c;
|
||||
} else if (c > '\u07FF') {
|
||||
data[len++] = (byte) (0xE0 | c >> 12 & 0xF);
|
||||
data[len++] = (byte) (0x80 | c >> 6 & 0x3F);
|
||||
data[len++] = (byte) (0x80 | c & 0x3F);
|
||||
} else {
|
||||
data[len++] = (byte) (0xC0 | c >> 6 & 0x1F);
|
||||
data[len++] = (byte) (0x80 | c & 0x3F);
|
||||
}
|
||||
}
|
||||
length = len;
|
||||
|
||||
@ -716,7 +716,8 @@ public class ClassWriter extends ClassVisitor {
|
||||
sourceFile = newUTF8(file);
|
||||
}
|
||||
if (debug != null) {
|
||||
sourceDebug = new ByteVector().putUTF8(debug);
|
||||
sourceDebug = new ByteVector().encodeUTF8(debug, 0,
|
||||
Integer.MAX_VALUE);
|
||||
}
|
||||
}
|
||||
|
||||
@ -857,7 +858,7 @@ public class ClassWriter extends ClassVisitor {
|
||||
}
|
||||
if (sourceDebug != null) {
|
||||
++attributeCount;
|
||||
size += sourceDebug.length + 4;
|
||||
size += sourceDebug.length + 6;
|
||||
newUTF8("SourceDebugExtension");
|
||||
}
|
||||
if (enclosingMethodOwner != 0) {
|
||||
@ -946,9 +947,9 @@ public class ClassWriter extends ClassVisitor {
|
||||
out.putShort(newUTF8("SourceFile")).putInt(2).putShort(sourceFile);
|
||||
}
|
||||
if (sourceDebug != null) {
|
||||
int len = sourceDebug.length - 2;
|
||||
int len = sourceDebug.length;
|
||||
out.putShort(newUTF8("SourceDebugExtension")).putInt(len);
|
||||
out.putByteArray(sourceDebug.data, 2, len);
|
||||
out.putByteArray(sourceDebug.data, 0, len);
|
||||
}
|
||||
if (enclosingMethodOwner != 0) {
|
||||
out.putShort(newUTF8("EnclosingMethod")).putInt(4);
|
||||
|
||||
@ -99,8 +99,8 @@ final class Frame {
|
||||
* stack types. VALUE depends on KIND. For LOCAL types, it is an index in
|
||||
* the input local variable types. For STACK types, it is a position
|
||||
* relatively to the top of input frame stack. For BASE types, it is either
|
||||
* one of the constants defined in FrameVisitor, or for OBJECT and
|
||||
* UNINITIALIZED types, a tag and an index in the type table.
|
||||
* one of the constants defined below, or for OBJECT and UNINITIALIZED
|
||||
* types, a tag and an index in the type table.
|
||||
*
|
||||
* Output frames can contain types of any kind and with a positive or
|
||||
* negative dimension (and even unassigned types, represented by 0 - which
|
||||
@ -537,7 +537,7 @@ final class Frame {
|
||||
/**
|
||||
* The types that are initialized in the basic block. A constructor
|
||||
* invocation on an UNINITIALIZED or UNINITIALIZED_THIS type must replace
|
||||
* <i>every occurrence</i> of this type in the local variables and in the
|
||||
* <i>every occurence</i> of this type in the local variables and in the
|
||||
* operand stack. This cannot be done during the first phase of the
|
||||
* algorithm since, during this phase, the local variables and the operand
|
||||
* stack are not completely computed. It is therefore necessary to store the
|
||||
@ -1446,6 +1446,7 @@ final class Frame {
|
||||
// if t is the NULL type, merge(u,t)=u, so there is no change
|
||||
return false;
|
||||
} else if ((t & (DIM | BASE_KIND)) == (u & (DIM | BASE_KIND))) {
|
||||
// if t and u have the same dimension and same base kind
|
||||
if ((u & BASE_KIND) == OBJECT) {
|
||||
// if t is also a reference type, and if u and t have the
|
||||
// same dimension merge(u,t) = dim(t) | common parent of the
|
||||
@ -1458,9 +1459,13 @@ final class Frame {
|
||||
v = OBJECT | cw.addType("java/lang/Object");
|
||||
}
|
||||
} else if ((t & BASE_KIND) == OBJECT || (t & DIM) != 0) {
|
||||
// if t is any other reference or array type,
|
||||
// merge(u,t)=java/lang/Object
|
||||
v = OBJECT | cw.addType("java/lang/Object");
|
||||
// if t is any other reference or array type, the merged type
|
||||
// is Object, or min(dim(u), dim(t)) | java/lang/Object is u
|
||||
// and t have different array dimensions
|
||||
int tdim = t & DIM;
|
||||
int udim = u & DIM;
|
||||
v = (udim != tdim ? Math.min(tdim, udim) : 0) | OBJECT
|
||||
| cw.addType("java/lang/Object");
|
||||
} else {
|
||||
// if t is any other type, merge(u,t)=TOP
|
||||
v = TOP;
|
||||
|
||||
@ -240,6 +240,7 @@ public class AnalyzerAdapter extends MethodVisitor {
|
||||
locals.add(types[i].getInternalName());
|
||||
}
|
||||
}
|
||||
maxLocals = locals.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -519,12 +520,12 @@ public class AnalyzerAdapter extends MethodVisitor {
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
private Object get(final int local) {
|
||||
maxLocals = Math.max(maxLocals, local);
|
||||
maxLocals = Math.max(maxLocals, local + 1);
|
||||
return local < locals.size() ? locals.get(local) : Opcodes.TOP;
|
||||
}
|
||||
|
||||
private void set(final int local, final Object type) {
|
||||
maxLocals = Math.max(maxLocals, local);
|
||||
maxLocals = Math.max(maxLocals, local + 1);
|
||||
while (local >= locals.size()) {
|
||||
locals.add(Opcodes.TOP);
|
||||
}
|
||||
|
||||
@ -556,6 +556,8 @@ public class InsnList {
|
||||
|
||||
AbstractInsnNode prev;
|
||||
|
||||
AbstractInsnNode remove;
|
||||
|
||||
InsnListIterator(int index) {
|
||||
if (index == size()) {
|
||||
next = null;
|
||||
@ -577,12 +579,22 @@ public class InsnList {
|
||||
AbstractInsnNode result = next;
|
||||
prev = result;
|
||||
next = result.next;
|
||||
remove = result;
|
||||
return result;
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
InsnList.this.remove(prev);
|
||||
prev = prev.prev;
|
||||
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() {
|
||||
@ -593,6 +605,7 @@ public class InsnList {
|
||||
AbstractInsnNode result = prev;
|
||||
next = result;
|
||||
prev = result.prev;
|
||||
remove = result;
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -619,6 +632,7 @@ public class InsnList {
|
||||
public void add(Object o) {
|
||||
InsnList.this.insertBefore(next, (AbstractInsnNode) o);
|
||||
prev = (AbstractInsnNode) o;
|
||||
remove = null;
|
||||
}
|
||||
|
||||
public void set(Object o) {
|
||||
|
||||
@ -351,7 +351,6 @@ public class MethodNode extends MethodVisitor {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("serial") // Anonymous class
|
||||
public AnnotationVisitor visitAnnotationDefault() {
|
||||
return new AnnotationNode(new ArrayList<Object>(0) {
|
||||
@Override
|
||||
|
||||
@ -404,7 +404,7 @@ public class Analyzer<V extends Value> implements Opcodes {
|
||||
* 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 occurred during the analysis of
|
||||
* cannot be reached, or if an error occured during the analysis of
|
||||
* the method.
|
||||
*/
|
||||
public Frame<V>[] getFrames() {
|
||||
|
||||
@ -66,7 +66,6 @@ import jdk.internal.org.objectweb.asm.tree.AbstractInsnNode;
|
||||
* @author Bing Ran
|
||||
* @author Eric Bruneton
|
||||
*/
|
||||
@SuppressWarnings("serial") // JDK-implementation class
|
||||
public class AnalyzerException extends Exception {
|
||||
|
||||
public final AbstractInsnNode node;
|
||||
|
||||
@ -111,7 +111,7 @@ public abstract class Interpreter<V extends Value> {
|
||||
* the bytecode instruction to be interpreted.
|
||||
* @return the result of the interpretation of the given instruction.
|
||||
* @throws AnalyzerException
|
||||
* if an error occurred during the interpretation.
|
||||
* if an error occured during the interpretation.
|
||||
*/
|
||||
public abstract V newOperation(AbstractInsnNode insn)
|
||||
throws AnalyzerException;
|
||||
@ -130,7 +130,7 @@ public abstract class Interpreter<V extends Value> {
|
||||
* @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 occurred during the interpretation.
|
||||
* if an error occured during the interpretation.
|
||||
*/
|
||||
public abstract V copyOperation(AbstractInsnNode insn, V value)
|
||||
throws AnalyzerException;
|
||||
@ -151,7 +151,7 @@ public abstract class Interpreter<V extends Value> {
|
||||
* the argument of the instruction to be interpreted.
|
||||
* @return the result of the interpretation of the given instruction.
|
||||
* @throws AnalyzerException
|
||||
* if an error occurred during the interpretation.
|
||||
* if an error occured during the interpretation.
|
||||
*/
|
||||
public abstract V unaryOperation(AbstractInsnNode insn, V value)
|
||||
throws AnalyzerException;
|
||||
@ -175,7 +175,7 @@ public abstract class Interpreter<V extends Value> {
|
||||
* the second argument of the instruction to be interpreted.
|
||||
* @return the result of the interpretation of the given instruction.
|
||||
* @throws AnalyzerException
|
||||
* if an error occurred during the interpretation.
|
||||
* if an error occured during the interpretation.
|
||||
*/
|
||||
public abstract V binaryOperation(AbstractInsnNode insn, V value1, V value2)
|
||||
throws AnalyzerException;
|
||||
@ -196,7 +196,7 @@ public abstract class Interpreter<V extends Value> {
|
||||
* the third argument of the instruction to be interpreted.
|
||||
* @return the result of the interpretation of the given instruction.
|
||||
* @throws AnalyzerException
|
||||
* if an error occurred during the interpretation.
|
||||
* if an error occured during the interpretation.
|
||||
*/
|
||||
public abstract V ternaryOperation(AbstractInsnNode insn, V value1,
|
||||
V value2, V value3) throws AnalyzerException;
|
||||
@ -214,7 +214,7 @@ public abstract class Interpreter<V extends Value> {
|
||||
* the arguments of the instruction to be interpreted.
|
||||
* @return the result of the interpretation of the given instruction.
|
||||
* @throws AnalyzerException
|
||||
* if an error occurred during the interpretation.
|
||||
* if an error occured during the interpretation.
|
||||
*/
|
||||
public abstract V naryOperation(AbstractInsnNode insn,
|
||||
List<? extends V> values) throws AnalyzerException;
|
||||
@ -232,7 +232,7 @@ public abstract class Interpreter<V extends Value> {
|
||||
* @param expected
|
||||
* the expected return type of the analyzed method.
|
||||
* @throws AnalyzerException
|
||||
* if an error occurred during the interpretation.
|
||||
* if an error occured during the interpretation.
|
||||
*/
|
||||
public abstract void returnOperation(AbstractInsnNode insn, V value,
|
||||
V expected) throws AnalyzerException;
|
||||
|
||||
@ -99,7 +99,7 @@ public class CheckAnnotationAdapter extends AnnotationVisitor {
|
||||
}
|
||||
if (value instanceof Type) {
|
||||
int sort = ((Type) value).getSort();
|
||||
if (sort != Type.OBJECT && sort != Type.ARRAY) {
|
||||
if (sort == Type.METHOD) {
|
||||
throw new IllegalArgumentException("Invalid annotation value");
|
||||
}
|
||||
}
|
||||
|
||||
@ -166,6 +166,11 @@ public class Textifier extends Printer {
|
||||
*/
|
||||
protected Map<Label, String> labelNames;
|
||||
|
||||
/**
|
||||
* Class access flags
|
||||
*/
|
||||
private int access;
|
||||
|
||||
private int valueNumber = 0;
|
||||
|
||||
/**
|
||||
@ -245,6 +250,7 @@ public class Textifier extends Printer {
|
||||
public void visit(final int version, final int access, final String name,
|
||||
final String signature, final String superName,
|
||||
final String[] interfaces) {
|
||||
this.access = access;
|
||||
int major = version & 0xFFFF;
|
||||
int minor = version >>> 16;
|
||||
buf.setLength(0);
|
||||
@ -447,6 +453,11 @@ public class Textifier extends Printer {
|
||||
if ((access & Opcodes.ACC_BRIDGE) != 0) {
|
||||
buf.append("bridge ");
|
||||
}
|
||||
if ((this.access & Opcodes.ACC_INTERFACE) != 0
|
||||
&& (access & Opcodes.ACC_ABSTRACT) == 0
|
||||
&& (access & Opcodes.ACC_STATIC) == 0) {
|
||||
buf.append("default ");
|
||||
}
|
||||
|
||||
buf.append(name);
|
||||
appendDescriptor(METHOD_DESCRIPTOR, desc);
|
||||
@ -856,7 +867,6 @@ public class Textifier extends Printer {
|
||||
appendDescriptor(INTERNAL_NAME, owner);
|
||||
buf.append('.').append(name).append(' ');
|
||||
appendDescriptor(METHOD_DESCRIPTOR, desc);
|
||||
buf.append(' ').append(itf ? "itf" : "");
|
||||
buf.append('\n');
|
||||
text.add(buf.toString());
|
||||
}
|
||||
@ -869,26 +879,35 @@ public class Textifier extends Printer {
|
||||
buf.append(name);
|
||||
appendDescriptor(METHOD_DESCRIPTOR, desc);
|
||||
buf.append(" [");
|
||||
buf.append('\n');
|
||||
buf.append(tab3);
|
||||
appendHandle(bsm);
|
||||
buf.append('\n');
|
||||
buf.append(tab3).append("// arguments:");
|
||||
if (bsmArgs.length == 0) {
|
||||
buf.append(" none");
|
||||
} else {
|
||||
buf.append('\n').append(tab3);
|
||||
buf.append('\n');
|
||||
for (int i = 0; i < bsmArgs.length; i++) {
|
||||
buf.append(tab3);
|
||||
Object cst = bsmArgs[i];
|
||||
if (cst instanceof String) {
|
||||
Printer.appendString(buf, (String) cst);
|
||||
} else if (cst instanceof Type) {
|
||||
buf.append(((Type) cst).getDescriptor()).append(".class");
|
||||
Type type = (Type) cst;
|
||||
if(type.getSort() == Type.METHOD){
|
||||
appendDescriptor(METHOD_DESCRIPTOR, type.getDescriptor());
|
||||
} else {
|
||||
buf.append(type.getDescriptor()).append(".class");
|
||||
}
|
||||
} else if (cst instanceof Handle) {
|
||||
appendHandle((Handle) cst);
|
||||
} else {
|
||||
buf.append(cst);
|
||||
}
|
||||
buf.append(", ");
|
||||
buf.append(", \n");
|
||||
}
|
||||
buf.setLength(buf.length() - 2);
|
||||
buf.setLength(buf.length() - 3);
|
||||
}
|
||||
buf.append('\n');
|
||||
buf.append(tab2).append("]\n");
|
||||
@ -1234,10 +1253,10 @@ public class Textifier extends Printer {
|
||||
* a handle, non null.
|
||||
*/
|
||||
protected void appendHandle(final Handle h) {
|
||||
buf.append('\n').append(tab3);
|
||||
int tag = h.getTag();
|
||||
buf.append("// handle kind 0x").append(Integer.toHexString(tag))
|
||||
.append(" : ");
|
||||
boolean isMethodHandle = false;
|
||||
switch (tag) {
|
||||
case Opcodes.H_GETFIELD:
|
||||
buf.append("GETFIELD");
|
||||
@ -1253,18 +1272,23 @@ public class Textifier extends Printer {
|
||||
break;
|
||||
case Opcodes.H_INVOKEINTERFACE:
|
||||
buf.append("INVOKEINTERFACE");
|
||||
isMethodHandle = true;
|
||||
break;
|
||||
case Opcodes.H_INVOKESPECIAL:
|
||||
buf.append("INVOKESPECIAL");
|
||||
isMethodHandle = true;
|
||||
break;
|
||||
case Opcodes.H_INVOKESTATIC:
|
||||
buf.append("INVOKESTATIC");
|
||||
isMethodHandle = true;
|
||||
break;
|
||||
case Opcodes.H_INVOKEVIRTUAL:
|
||||
buf.append("INVOKEVIRTUAL");
|
||||
isMethodHandle = true;
|
||||
break;
|
||||
case Opcodes.H_NEWINVOKESPECIAL:
|
||||
buf.append("NEWINVOKESPECIAL");
|
||||
isMethodHandle = true;
|
||||
break;
|
||||
}
|
||||
buf.append('\n');
|
||||
@ -1272,9 +1296,13 @@ public class Textifier extends Printer {
|
||||
appendDescriptor(INTERNAL_NAME, h.getOwner());
|
||||
buf.append('.');
|
||||
buf.append(h.getName());
|
||||
buf.append('(');
|
||||
if(!isMethodHandle){
|
||||
buf.append('(');
|
||||
}
|
||||
appendDescriptor(HANDLE_DESCRIPTOR, h.getDesc());
|
||||
buf.append(')').append('\n');
|
||||
if(!isMethodHandle){
|
||||
buf.append(')');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
Path: .
|
||||
Working Copy Root Path: /hudson/jobs/objectweb-pull/workspace/ASM_5_0_BETA
|
||||
URL: svn://svn.forge.objectweb.org/svnroot/asm/trunk/asm
|
||||
Repository Root: svn://svn.forge.objectweb.org/svnroot/asm
|
||||
Working Copy Root Path: /hudson/jobs/objectweb-pull/workspace/asm-svn-2014-03-12
|
||||
URL: file:///svnroot/asm/trunk/asm
|
||||
Repository Root: file:///svnroot/asm
|
||||
Repository UUID: 271bd773-ee82-43a6-9b2b-1890ed8ce7f9
|
||||
Revision: 1700
|
||||
Revision: 1721
|
||||
Node Kind: directory
|
||||
Schedule: normal
|
||||
Last Changed Author: ebruneton
|
||||
Last Changed Rev: 1700
|
||||
Last Changed Date: 2013-10-29 20:22:52 +0100 (Tue, 29 Oct 2013)
|
||||
Last Changed Rev: 1721
|
||||
Last Changed Date: 2014-03-02 17:25:35 +0100 (Sun, 02 Mar 2014)
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user