You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by jk...@apache.org on 2017/10/06 14:31:23 UTC
[8/9] tapestry-5 git commit: TAP5-2588: upgrade ASM to 6.0
TAP5-2588: upgrade ASM to 6.0
Project: http://git-wip-us.apache.org/repos/asf/tapestry-5/repo
Commit: http://git-wip-us.apache.org/repos/asf/tapestry-5/commit/74324b31
Tree: http://git-wip-us.apache.org/repos/asf/tapestry-5/tree/74324b31
Diff: http://git-wip-us.apache.org/repos/asf/tapestry-5/diff/74324b31
Branch: refs/heads/master
Commit: 74324b3130c9f74c1684a08171b7a2ca56532fe1
Parents: 95a548e
Author: Jochen Kemnade <jk...@apache.org>
Authored: Fri Oct 6 15:20:03 2017 +0200
Committer: Jochen Kemnade <jk...@apache.org>
Committed: Fri Oct 6 15:59:01 2017 +0200
----------------------------------------------------------------------
.../internal/plastic/asm/AnnotationVisitor.java | 10 +-
.../internal/plastic/asm/AnnotationWriter.java | 2 +-
.../internal/plastic/asm/ClassReader.java | 480 ++++++++---
.../internal/plastic/asm/ClassVisitor.java | 32 +-
.../internal/plastic/asm/ClassWriter.java | 295 ++++---
.../internal/plastic/asm/CurrentFrame.java | 56 ++
.../internal/plastic/asm/FieldVisitor.java | 8 +-
.../internal/plastic/asm/FieldWriter.java | 40 +-
.../tapestry5/internal/plastic/asm/Frame.java | 118 ++-
.../tapestry5/internal/plastic/asm/Handle.java | 62 +-
.../tapestry5/internal/plastic/asm/Item.java | 5 +
.../tapestry5/internal/plastic/asm/Label.java | 15 +-
.../internal/plastic/asm/MethodVisitor.java | 8 +-
.../internal/plastic/asm/MethodWriter.java | 830 ++++--------------
.../internal/plastic/asm/ModuleVisitor.java | 190 +++++
.../internal/plastic/asm/ModuleWriter.java | 293 +++++++
.../tapestry5/internal/plastic/asm/Opcodes.java | 29 +-
.../tapestry5/internal/plastic/asm/Type.java | 25 +-
.../plastic/asm/commons/AdviceAdapter.java | 16 +-
.../plastic/asm/commons/AnalyzerAdapter.java | 8 +-
.../plastic/asm/commons/AnnotationRemapper.java | 79 ++
.../plastic/asm/commons/ClassRemapper.java | 158 ++++
.../plastic/asm/commons/CodeSizeEvaluator.java | 2 +-
.../plastic/asm/commons/FieldRemapper.java | 71 ++
.../plastic/asm/commons/GeneratorAdapter.java | 6 +-
.../plastic/asm/commons/InstructionAdapter.java | 4 +-
.../plastic/asm/commons/JSRInlinerAdapter.java | 6 +-
.../asm/commons/LocalVariablesSorter.java | 20 +-
.../plastic/asm/commons/MethodRemapper.java | 225 +++++
.../asm/commons/ModuleHashesAttribute.java | 126 +++
.../plastic/asm/commons/ModuleRemapper.java | 106 +++
.../asm/commons/ModuleResolutionAttribute.java | 106 +++
.../asm/commons/ModuleTargetAttribute.java | 81 ++
.../internal/plastic/asm/commons/Remapper.java | 45 +-
.../asm/commons/RemappingAnnotationAdapter.java | 4 +-
.../asm/commons/RemappingClassAdapter.java | 10 +-
.../asm/commons/RemappingFieldAdapter.java | 4 +-
.../asm/commons/RemappingMethodAdapter.java | 28 +-
.../asm/commons/RemappingSignatureAdapter.java | 4 +-
.../asm/commons/SerialVersionUIDAdder.java | 11 +-
.../plastic/asm/commons/SignatureRemapper.java | 159 ++++
.../plastic/asm/commons/StaticInitMerger.java | 2 +-
.../asm/commons/TryCatchBlockSorter.java | 2 +-
.../optimizer/AnnotationConstantsCollector.java | 147 ----
.../asm/optimizer/ClassConstantsCollector.java | 198 -----
.../plastic/asm/optimizer/ClassOptimizer.java | 260 ------
.../plastic/asm/optimizer/Constant.java | 323 -------
.../plastic/asm/optimizer/ConstantPool.java | 251 ------
.../asm/optimizer/FieldConstantsCollector.java | 89 --
.../plastic/asm/optimizer/JarOptimizer.java | 235 -----
.../asm/optimizer/MethodConstantsCollector.java | 224 -----
.../plastic/asm/optimizer/MethodOptimizer.java | 178 ----
.../plastic/asm/optimizer/NameMapping.java | 114 ---
.../plastic/asm/optimizer/Shrinker.java | 282 ------
.../plastic/asm/optimizer/jdk1.2.2_017.txt.gz | Bin 113814 -> 0 bytes
.../plastic/asm/optimizer/jdk1.3.1_19.txt.gz | Bin 128067 -> 0 bytes
.../asm/optimizer/shrink-annotations.properties | 53 --
.../asm/optimizer/shrink-frames.properties | 62 --
.../asm/optimizer/shrink-resize.properties | 37 -
.../asm/optimizer/shrink-signatures.properties | 43 -
.../asm/optimizer/shrink-writer.properties | 66 --
.../plastic/asm/optimizer/shrink.properties | 381 ---------
.../plastic/asm/signature/SignatureReader.java | 8 +-
.../plastic/asm/signature/SignatureVisitor.java | 6 +-
.../plastic/asm/signature/SignatureWriter.java | 6 +-
.../plastic/asm/tree/AbstractInsnNode.java | 4 +-
.../plastic/asm/tree/AnnotationNode.java | 82 +-
.../internal/plastic/asm/tree/ClassNode.java | 92 +-
.../plastic/asm/tree/FieldInsnNode.java | 8 +-
.../internal/plastic/asm/tree/FieldNode.java | 28 +-
.../plastic/asm/tree/InnerClassNode.java | 8 +-
.../internal/plastic/asm/tree/InsnList.java | 23 +-
.../plastic/asm/tree/InvokeDynamicInsnNode.java | 2 +-
.../internal/plastic/asm/tree/LdcInsnNode.java | 2 +-
.../asm/tree/LocalVariableAnnotationNode.java | 6 +-
.../plastic/asm/tree/MethodInsnNode.java | 12 +-
.../internal/plastic/asm/tree/MethodNode.java | 44 +-
.../plastic/asm/tree/ModuleExportNode.java | 82 ++
.../internal/plastic/asm/tree/ModuleNode.java | 251 ++++++
.../plastic/asm/tree/ModuleOpenNode.java | 82 ++
.../plastic/asm/tree/ModuleProvideNode.java | 74 ++
.../plastic/asm/tree/ModuleRequireNode.java | 87 ++
.../asm/tree/MultiANewArrayInsnNode.java | 4 +-
.../plastic/asm/tree/ParameterNode.java | 4 +-
.../plastic/asm/tree/TryCatchBlockNode.java | 4 +-
.../plastic/asm/tree/TypeAnnotationNode.java | 4 +-
.../internal/plastic/asm/tree/TypeInsnNode.java | 4 +-
.../asm/tree/analysis/BasicInterpreter.java | 2 +-
.../asm/tree/analysis/BasicVerifier.java | 2 +-
.../asm/tree/analysis/SimpleVerifier.java | 2 +-
.../asm/tree/analysis/SourceInterpreter.java | 2 +-
.../internal/plastic/asm/util/ASMifiable.java | 2 +-
.../internal/plastic/asm/util/ASMifier.java | 226 ++++-
.../asm/util/CheckAnnotationAdapter.java | 2 +-
.../plastic/asm/util/CheckClassAdapter.java | 72 +-
.../plastic/asm/util/CheckFieldAdapter.java | 4 +-
.../plastic/asm/util/CheckMethodAdapter.java | 14 +-
.../plastic/asm/util/CheckModuleAdapter.java | 151 ++++
.../plastic/asm/util/CheckSignatureAdapter.java | 38 +-
.../internal/plastic/asm/util/Printer.java | 855 +++++++++++++++++--
.../internal/plastic/asm/util/Textifiable.java | 2 +-
.../internal/plastic/asm/util/Textifier.java | 164 +++-
.../asm/util/TraceAnnotationVisitor.java | 2 +-
.../plastic/asm/util/TraceClassVisitor.java | 27 +-
.../plastic/asm/util/TraceFieldVisitor.java | 2 +-
.../plastic/asm/util/TraceMethodVisitor.java | 2 +-
.../plastic/asm/util/TraceModuleVisitor.java | 101 +++
.../plastic/asm/util/TraceSignatureVisitor.java | 18 +-
.../plastic/asm/xml/ASMContentHandler.java | 125 ++-
.../internal/plastic/asm/xml/Processor.java | 52 +-
.../plastic/asm/xml/SAXAnnotationAdapter.java | 20 +-
.../plastic/asm/xml/SAXClassAdapter.java | 74 +-
.../plastic/asm/xml/SAXCodeAdapter.java | 8 +-
.../plastic/asm/xml/SAXFieldAdapter.java | 2 +-
.../plastic/asm/xml/SAXModuleAdapter.java | 137 +++
.../internal/plastic/asm/xml/asm-xml.dtd | 16 +-
.../plastic/AbstractAnnotationBuilder.java | 14 +-
117 files changed, 5418 insertions(+), 4371 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/74324b31/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/AnnotationVisitor.java
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/AnnotationVisitor.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/AnnotationVisitor.java
index 1102d54..a3df31b 100644
--- a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/AnnotationVisitor.java
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/AnnotationVisitor.java
@@ -41,7 +41,7 @@ public abstract class AnnotationVisitor {
/**
* The ASM API version implemented by this visitor. The value of this field
- * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
*/
protected final int api;
@@ -56,7 +56,7 @@ public abstract class AnnotationVisitor {
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
*/
public AnnotationVisitor(final int api) {
this(api, null);
@@ -67,13 +67,13 @@ public abstract class AnnotationVisitor {
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* @param av
* the annotation visitor to which this visitor must delegate
* method calls. May be null.
*/
public AnnotationVisitor(final int api, final AnnotationVisitor av) {
- if (api != Opcodes.ASM4 && api != Opcodes.ASM5) {
+ if (api < Opcodes.ASM4 || api > Opcodes.ASM6) {
throw new IllegalArgumentException();
}
this.api = api;
@@ -89,7 +89,7 @@ public abstract class AnnotationVisitor {
* the actual value, whose type must be {@link Byte},
* {@link Boolean}, {@link Character}, {@link Short},
* {@link Integer} , {@link Long}, {@link Float}, {@link Double},
- * {@link String} or {@link Type} or OBJECT or ARRAY sort. This
+ * {@link String} or {@link Type} of OBJECT or ARRAY sort. This
* value can also be an array of byte, boolean, short, char, int,
* long, float or double values (this is equivalent to using
* {@link #visitArray visitArray} and visiting each array element
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/74324b31/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/AnnotationWriter.java
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/AnnotationWriter.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/AnnotationWriter.java
index 679aa66..d0d2d4a 100644
--- a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/AnnotationWriter.java
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/AnnotationWriter.java
@@ -104,7 +104,7 @@ final class AnnotationWriter extends AnnotationVisitor {
*/
AnnotationWriter(final ClassWriter cw, final boolean named,
final ByteVector bv, final ByteVector parent, final int offset) {
- super(Opcodes.ASM5);
+ super(Opcodes.ASM6);
this.cw = cw;
this.named = named;
this.bv = bv;
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/74324b31/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/ClassReader.java
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/ClassReader.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/ClassReader.java
index c334984..6d810e0 100644
--- a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/ClassReader.java
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/ClassReader.java
@@ -44,31 +44,6 @@ import java.io.InputStream;
public class ClassReader {
/**
- * True to enable signatures support.
- */
- static final boolean SIGNATURES = true;
-
- /**
- * True to enable annotations support.
- */
- static final boolean ANNOTATIONS = true;
-
- /**
- * True to enable stack map frames support.
- */
- static final boolean FRAMES = true;
-
- /**
- * True to enable bytecode writing support.
- */
- static final boolean WRITER = true;
-
- /**
- * True to enable JSR_W and GOTO_W support.
- */
- static final boolean RESIZE = true;
-
- /**
* Flag to skip method code. If this class is set <code>CODE</code>
* attribute won't be visited. This can be used, for example, to retrieve
* annotations for methods and method parameters.
@@ -105,6 +80,21 @@ public class ClassReader {
public static final int EXPAND_FRAMES = 8;
/**
+ * Flag to expand the ASM pseudo instructions into an equivalent sequence of
+ * standard bytecode instructions. When resolving a forward jump it may
+ * happen that the signed 2 bytes offset reserved for it is not sufficient
+ * to store the bytecode offset. In this case the jump instruction is
+ * replaced with a temporary ASM pseudo instruction using an unsigned 2
+ * bytes offset (see Label#resolve). This internal flag is used to re-read
+ * classes containing such instructions, in order to replace them with
+ * standard instructions. In addition, when this flag is used, GOTO_W and
+ * JSR_W are <i>not</i> converted into GOTO and JSR, to make sure that
+ * infinite loops where a GOTO_W is replaced with a GOTO in ClassReader and
+ * converted back to a GOTO_W in ClassWriter cannot occur.
+ */
+ static final int EXPAND_ASM_INSNS = 256;
+
+ /**
* The class to be parsed. <i>The content of this array must not be
* modified. This field is intended for {@link Attribute} sub classes, and
* is normally not needed by class generators or adapters.</i>
@@ -166,7 +156,7 @@ public class ClassReader {
public ClassReader(final byte[] b, final int off, final int len) {
this.b = b;
// checks the class version
- if (readShort(off + 6) > Opcodes.V1_8) {
+ if (readShort(off + 6) > Opcodes.V9) {
throw new IllegalArgumentException();
}
// parses the constant pool
@@ -205,6 +195,8 @@ public class ClassReader {
// case ClassWriter.CLASS:
// case ClassWriter.STR:
// case ClassWriter.MTYPE
+ // case ClassWriter.PACKAGE:
+ // case ClassWriter.MODULE:
default:
size = 3;
break;
@@ -348,7 +340,9 @@ public class ClassReader {
break;
// case ClassWriter.STR:
// case ClassWriter.CLASS:
- // case ClassWriter.MTYPE
+ // case ClassWriter.MTYPE:
+ // case ClassWriter.MODULE:
+ // case ClassWriter.PACKAGE:
default:
item.set(tag, readUTF8(index, buf), null, null);
break;
@@ -555,11 +549,14 @@ public class ClassReader {
String enclosingOwner = null;
String enclosingName = null;
String enclosingDesc = null;
+ String moduleMainClass = null;
int anns = 0;
int ianns = 0;
int tanns = 0;
int itanns = 0;
int innerClasses = 0;
+ int module = 0;
+ int packages = 0;
Attribute attributes = null;
u = getAttributes();
@@ -578,13 +575,11 @@ public class ClassReader {
enclosingName = readUTF8(items[item], c);
enclosingDesc = readUTF8(items[item] + 2, c);
}
- } else if (SIGNATURES && "Signature".equals(attrName)) {
+ } else if ("Signature".equals(attrName)) {
signature = readUTF8(u + 8, c);
- } else if (ANNOTATIONS
- && "RuntimeVisibleAnnotations".equals(attrName)) {
+ } else if ("RuntimeVisibleAnnotations".equals(attrName)) {
anns = u + 8;
- } else if (ANNOTATIONS
- && "RuntimeVisibleTypeAnnotations".equals(attrName)) {
+ } else if ("RuntimeVisibleTypeAnnotations".equals(attrName)) {
tanns = u + 8;
} else if ("Deprecated".equals(attrName)) {
access |= Opcodes.ACC_DEPRECATED;
@@ -594,12 +589,16 @@ public class ClassReader {
} else if ("SourceDebugExtension".equals(attrName)) {
int len = readInt(u + 4);
sourceDebug = readUTF(u + 8, len, new char[len]);
- } else if (ANNOTATIONS
- && "RuntimeInvisibleAnnotations".equals(attrName)) {
+ } else if ("RuntimeInvisibleAnnotations".equals(attrName)) {
ianns = u + 8;
- } else if (ANNOTATIONS
- && "RuntimeInvisibleTypeAnnotations".equals(attrName)) {
+ } else if ("RuntimeInvisibleTypeAnnotations".equals(attrName)) {
itanns = u + 8;
+ } else if ("Module".equals(attrName)) {
+ module = u + 8;
+ } else if ("ModuleMainClass".equals(attrName)) {
+ moduleMainClass = readClass(u + 8, c);
+ } else if ("ModulePackages".equals(attrName)) {
+ packages = u + 10;
} else if ("BootstrapMethods".equals(attrName)) {
int[] bootstrapMethods = new int[readUnsignedShort(u + 8)];
for (int j = 0, v = u + 10; j < bootstrapMethods.length; j++) {
@@ -628,6 +627,12 @@ public class ClassReader {
classVisitor.visitSource(sourceFile, sourceDebug);
}
+ // visits the module info and associated attributes
+ if (module != 0) {
+ readModule(classVisitor, context, module,
+ moduleMainClass, packages);
+ }
+
// visits the outer class
if (enclosingOwner != null) {
classVisitor.visitOuterClass(enclosingOwner, enclosingName,
@@ -635,19 +640,19 @@ public class ClassReader {
}
// visits the class annotations and type annotations
- if (ANNOTATIONS && anns != 0) {
+ if (anns != 0) {
for (int i = readUnsignedShort(anns), v = anns + 2; i > 0; --i) {
v = readAnnotationValues(v + 2, c, true,
classVisitor.visitAnnotation(readUTF8(v, c), true));
}
}
- if (ANNOTATIONS && ianns != 0) {
+ if (ianns != 0) {
for (int i = readUnsignedShort(ianns), v = ianns + 2; i > 0; --i) {
v = readAnnotationValues(v + 2, c, true,
classVisitor.visitAnnotation(readUTF8(v, c), false));
}
}
- if (ANNOTATIONS && tanns != 0) {
+ if (tanns != 0) {
for (int i = readUnsignedShort(tanns), v = tanns + 2; i > 0; --i) {
v = readAnnotationTarget(context, v);
v = readAnnotationValues(v + 2, c, true,
@@ -655,7 +660,7 @@ public class ClassReader {
context.typePath, readUTF8(v, c), true));
}
}
- if (ANNOTATIONS && itanns != 0) {
+ if (itanns != 0) {
for (int i = readUnsignedShort(itanns), v = itanns + 2; i > 0; --i) {
v = readAnnotationTarget(context, v);
v = readAnnotationValues(v + 2, c, true,
@@ -698,6 +703,120 @@ public class ClassReader {
}
/**
+ * Reads the module attribute and visit it.
+ *
+ * @param classVisitor
+ * the current class visitor
+ * @param context
+ * information about the class being parsed.
+ * @param u
+ * start offset of the module attribute in the class file.
+ * @param mainClass
+ * name of the main class of a module or null.
+ * @param packages
+ * start offset of the concealed package attribute.
+ */
+ private void readModule(final ClassVisitor classVisitor,
+ final Context context, int u,
+ final String mainClass, int packages) {
+
+ char[] buffer = context.buffer;
+
+ // reads module name, flags and version
+ String name = readModule(u, buffer);
+ int flags = readUnsignedShort(u + 2);
+ String version = readUTF8(u + 4, buffer);
+ u += 6;
+
+ ModuleVisitor mv = classVisitor.visitModule(name, flags, version);
+ if (mv == null) {
+ return;
+ }
+
+ // module attributes (main class, packages)
+ if (mainClass != null) {
+ mv.visitMainClass(mainClass);
+ }
+
+ if (packages != 0) {
+ for (int i = readUnsignedShort(packages - 2); i > 0; --i) {
+ String packaze = readPackage(packages, buffer);
+ mv.visitPackage(packaze);
+ packages += 2;
+ }
+ }
+
+ // reads requires
+ u += 2;
+ for (int i = readUnsignedShort(u - 2); i > 0; --i) {
+ String module = readModule(u, buffer);
+ int access = readUnsignedShort(u + 2);
+ String requireVersion = readUTF8(u + 4, buffer);
+ mv.visitRequire(module, access, requireVersion);
+ u += 6;
+ }
+
+ // reads exports
+ u += 2;
+ for (int i = readUnsignedShort(u - 2); i > 0; --i) {
+ String export = readPackage(u, buffer);
+ int access = readUnsignedShort(u + 2);
+ int exportToCount = readUnsignedShort(u + 4);
+ u += 6;
+ String[] tos = null;
+ if (exportToCount != 0) {
+ tos = new String[exportToCount];
+ for (int j = 0; j < tos.length; ++j) {
+ tos[j] = readModule(u, buffer);
+ u += 2;
+ }
+ }
+ mv.visitExport(export, access, tos);
+ }
+
+ // reads opens
+ u += 2;
+ for (int i = readUnsignedShort(u - 2); i > 0; --i) {
+ String open = readPackage(u, buffer);
+ int access = readUnsignedShort(u + 2);
+ int openToCount = readUnsignedShort(u + 4);
+ u += 6;
+ String[] tos = null;
+ if (openToCount != 0) {
+ tos = new String[openToCount];
+ for (int j = 0; j < tos.length; ++j) {
+ tos[j] = readModule(u, buffer);
+ u += 2;
+ }
+ }
+ mv.visitOpen(open, access, tos);
+ }
+
+ // read uses
+ u += 2;
+ for (int i = readUnsignedShort(u - 2); i > 0; --i) {
+ mv.visitUse(readClass(u, buffer));
+ u += 2;
+ }
+
+ // read provides
+ u += 2;
+ for (int i = readUnsignedShort(u - 2); i > 0; --i) {
+ String service = readClass(u, buffer);
+ int provideWithCount = readUnsignedShort(u + 2);
+ u += 4;
+ String[] withs = new String[provideWithCount];
+ for (int j = 0; j < withs.length; ++j) {
+ withs[j] = readClass(u, buffer);
+ u += 2;
+ }
+ mv.visitProvide(service, withs);
+ }
+
+ mv.visitEnd();
+ }
+
+ /**
* Reads a field and makes the given visitor visit it.
*
* @param classVisitor
@@ -733,24 +852,20 @@ public class ClassReader {
if ("ConstantValue".equals(attrName)) {
int item = readUnsignedShort(u + 8);
value = item == 0 ? null : readConst(item, c);
- } else if (SIGNATURES && "Signature".equals(attrName)) {
+ } else if ("Signature".equals(attrName)) {
signature = readUTF8(u + 8, c);
} else if ("Deprecated".equals(attrName)) {
access |= Opcodes.ACC_DEPRECATED;
} else if ("Synthetic".equals(attrName)) {
access |= Opcodes.ACC_SYNTHETIC
| ClassWriter.ACC_SYNTHETIC_ATTRIBUTE;
- } else if (ANNOTATIONS
- && "RuntimeVisibleAnnotations".equals(attrName)) {
+ } else if ("RuntimeVisibleAnnotations".equals(attrName)) {
anns = u + 8;
- } else if (ANNOTATIONS
- && "RuntimeVisibleTypeAnnotations".equals(attrName)) {
+ } else if ("RuntimeVisibleTypeAnnotations".equals(attrName)) {
tanns = u + 8;
- } else if (ANNOTATIONS
- && "RuntimeInvisibleAnnotations".equals(attrName)) {
+ } else if ("RuntimeInvisibleAnnotations".equals(attrName)) {
ianns = u + 8;
- } else if (ANNOTATIONS
- && "RuntimeInvisibleTypeAnnotations".equals(attrName)) {
+ } else if ("RuntimeInvisibleTypeAnnotations".equals(attrName)) {
itanns = u + 8;
} else {
Attribute attr = readAttribute(context.attrs, attrName, u + 8,
@@ -772,19 +887,19 @@ public class ClassReader {
}
// visits the field annotations and type annotations
- if (ANNOTATIONS && anns != 0) {
+ if (anns != 0) {
for (int i = readUnsignedShort(anns), v = anns + 2; i > 0; --i) {
v = readAnnotationValues(v + 2, c, true,
fv.visitAnnotation(readUTF8(v, c), true));
}
}
- if (ANNOTATIONS && ianns != 0) {
+ if (ianns != 0) {
for (int i = readUnsignedShort(ianns), v = ianns + 2; i > 0; --i) {
v = readAnnotationValues(v + 2, c, true,
fv.visitAnnotation(readUTF8(v, c), false));
}
}
- if (ANNOTATIONS && tanns != 0) {
+ if (tanns != 0) {
for (int i = readUnsignedShort(tanns), v = tanns + 2; i > 0; --i) {
v = readAnnotationTarget(context, v);
v = readAnnotationValues(v + 2, c, true,
@@ -792,7 +907,7 @@ public class ClassReader {
context.typePath, readUTF8(v, c), true));
}
}
- if (ANNOTATIONS && itanns != 0) {
+ if (itanns != 0) {
for (int i = readUnsignedShort(itanns), v = itanns + 2; i > 0; --i) {
v = readAnnotationTarget(context, v);
v = readAnnotationValues(v + 2, c, true,
@@ -866,32 +981,26 @@ public class ClassReader {
exceptions[j] = readClass(exception, c);
exception += 2;
}
- } else if (SIGNATURES && "Signature".equals(attrName)) {
+ } else if ("Signature".equals(attrName)) {
signature = readUTF8(u + 8, c);
} else if ("Deprecated".equals(attrName)) {
context.access |= Opcodes.ACC_DEPRECATED;
- } else if (ANNOTATIONS
- && "RuntimeVisibleAnnotations".equals(attrName)) {
+ } else if ("RuntimeVisibleAnnotations".equals(attrName)) {
anns = u + 8;
- } else if (ANNOTATIONS
- && "RuntimeVisibleTypeAnnotations".equals(attrName)) {
+ } else if ("RuntimeVisibleTypeAnnotations".equals(attrName)) {
tanns = u + 8;
- } else if (ANNOTATIONS && "AnnotationDefault".equals(attrName)) {
+ } else if ("AnnotationDefault".equals(attrName)) {
dann = u + 8;
} else if ("Synthetic".equals(attrName)) {
context.access |= Opcodes.ACC_SYNTHETIC
| ClassWriter.ACC_SYNTHETIC_ATTRIBUTE;
- } else if (ANNOTATIONS
- && "RuntimeInvisibleAnnotations".equals(attrName)) {
+ } else if ("RuntimeInvisibleAnnotations".equals(attrName)) {
ianns = u + 8;
- } else if (ANNOTATIONS
- && "RuntimeInvisibleTypeAnnotations".equals(attrName)) {
+ } else if ("RuntimeInvisibleTypeAnnotations".equals(attrName)) {
itanns = u + 8;
- } else if (ANNOTATIONS
- && "RuntimeVisibleParameterAnnotations".equals(attrName)) {
+ } else if ("RuntimeVisibleParameterAnnotations".equals(attrName)) {
mpanns = u + 8;
- } else if (ANNOTATIONS
- && "RuntimeInvisibleParameterAnnotations".equals(attrName)) {
+ } else if ("RuntimeInvisibleParameterAnnotations".equals(attrName)) {
impanns = u + 8;
} else if ("MethodParameters".equals(attrName)) {
methodParameters = u + 8;
@@ -924,7 +1033,7 @@ public class ClassReader {
* access, name and descriptor can have been changed, this is not
* important since they are not copied as is from the reader).
*/
- if (WRITER && mv instanceof MethodWriter) {
+ if (mv instanceof MethodWriter) {
MethodWriter mw = (MethodWriter) mv;
if (mw.cw.cr == this && signature == mw.signature) {
boolean sameExceptions = false;
@@ -961,26 +1070,26 @@ public class ClassReader {
}
// visits the method annotations
- if (ANNOTATIONS && dann != 0) {
+ if (dann != 0) {
AnnotationVisitor dv = mv.visitAnnotationDefault();
readAnnotationValue(dann, c, null, dv);
if (dv != null) {
dv.visitEnd();
}
}
- if (ANNOTATIONS && anns != 0) {
+ if (anns != 0) {
for (int i = readUnsignedShort(anns), v = anns + 2; i > 0; --i) {
v = readAnnotationValues(v + 2, c, true,
mv.visitAnnotation(readUTF8(v, c), true));
}
}
- if (ANNOTATIONS && ianns != 0) {
+ if (ianns != 0) {
for (int i = readUnsignedShort(ianns), v = ianns + 2; i > 0; --i) {
v = readAnnotationValues(v + 2, c, true,
mv.visitAnnotation(readUTF8(v, c), false));
}
}
- if (ANNOTATIONS && tanns != 0) {
+ if (tanns != 0) {
for (int i = readUnsignedShort(tanns), v = tanns + 2; i > 0; --i) {
v = readAnnotationTarget(context, v);
v = readAnnotationValues(v + 2, c, true,
@@ -988,7 +1097,7 @@ public class ClassReader {
context.typePath, readUTF8(v, c), true));
}
}
- if (ANNOTATIONS && itanns != 0) {
+ if (itanns != 0) {
for (int i = readUnsignedShort(itanns), v = itanns + 2; i > 0; --i) {
v = readAnnotationTarget(context, v);
v = readAnnotationValues(v + 2, c, true,
@@ -996,10 +1105,10 @@ public class ClassReader {
context.typePath, readUTF8(v, c), false));
}
}
- if (ANNOTATIONS && mpanns != 0) {
+ if (mpanns != 0) {
readParameterAnnotations(mv, context, mpanns, true);
}
- if (ANNOTATIONS && impanns != 0) {
+ if (impanns != 0) {
readParameterAnnotations(mv, context, impanns, false);
}
@@ -1046,7 +1155,7 @@ public class ClassReader {
int codeStart = u;
int codeEnd = u + codeLength;
Label[] labels = context.labels = new Label[codeLength + 2];
- readLabel(codeLength + 1, labels);
+ createLabel(codeLength + 1, labels);
while (u < codeEnd) {
int offset = u - codeStart;
int opcode = b[u] & 0xFF;
@@ -1056,11 +1165,16 @@ public class ClassReader {
u += 1;
break;
case ClassWriter.LABEL_INSN:
- readLabel(offset + readShort(u + 1), labels);
+ createLabel(offset + readShort(u + 1), labels);
+ u += 3;
+ break;
+ case ClassWriter.ASM_LABEL_INSN:
+ createLabel(offset + readUnsignedShort(u + 1), labels);
u += 3;
break;
case ClassWriter.LABELW_INSN:
- readLabel(offset + readInt(u + 1), labels);
+ case ClassWriter.ASM_LABELW_INSN:
+ createLabel(offset + readInt(u + 1), labels);
u += 5;
break;
case ClassWriter.WIDE_INSN:
@@ -1075,9 +1189,9 @@ public class ClassReader {
// skips 0 to 3 padding bytes
u = u + 4 - (offset & 3);
// reads instruction
- readLabel(offset + readInt(u), labels);
+ createLabel(offset + readInt(u), labels);
for (int i = readInt(u + 8) - readInt(u + 4) + 1; i > 0; --i) {
- readLabel(offset + readInt(u + 12), labels);
+ createLabel(offset + readInt(u + 12), labels);
u += 4;
}
u += 12;
@@ -1086,9 +1200,9 @@ public class ClassReader {
// skips 0 to 3 padding bytes
u = u + 4 - (offset & 3);
// reads instruction
- readLabel(offset + readInt(u), labels);
+ createLabel(offset + readInt(u), labels);
for (int i = readInt(u + 4); i > 0; --i) {
- readLabel(offset + readInt(u + 12), labels);
+ createLabel(offset + readInt(u + 12), labels);
u += 8;
}
u += 8;
@@ -1118,9 +1232,9 @@ public class ClassReader {
// reads the try catch entries to find the labels, and also visits them
for (int i = readUnsignedShort(u); i > 0; --i) {
- Label start = readLabel(readUnsignedShort(u + 2), labels);
- Label end = readLabel(readUnsignedShort(u + 4), labels);
- Label handler = readLabel(readUnsignedShort(u + 6), labels);
+ Label start = createLabel(readUnsignedShort(u + 2), labels);
+ Label end = createLabel(readUnsignedShort(u + 4), labels);
+ Label handler = createLabel(readUnsignedShort(u + 6), labels);
String type = readUTF8(items[readUnsignedShort(u + 8)], c);
mv.visitTryCatchBlock(start, end, handler, type);
u += 8;
@@ -1151,13 +1265,9 @@ public class ClassReader {
varTable = u + 8;
for (int j = readUnsignedShort(u + 8), v = u; j > 0; --j) {
int label = readUnsignedShort(v + 10);
- if (labels[label] == null) {
- readLabel(label, labels).status |= Label.DEBUG;
- }
+ createDebugLabel(label, labels);
label += readUnsignedShort(v + 12);
- if (labels[label] == null) {
- readLabel(label, labels).status |= Label.DEBUG;
- }
+ createDebugLabel(label, labels);
v += 10;
}
}
@@ -1167,9 +1277,7 @@ public class ClassReader {
if ((context.flags & SKIP_DEBUG) == 0) {
for (int j = readUnsignedShort(u + 8), v = u; j > 0; --j) {
int label = readUnsignedShort(v + 10);
- if (labels[label] == null) {
- readLabel(label, labels).status |= Label.DEBUG;
- }
+ createDebugLabel(label, labels);
Label l = labels[label];
while (l.line > 0) {
if (l.next == null) {
@@ -1181,17 +1289,15 @@ public class ClassReader {
v += 4;
}
}
- } else if (ANNOTATIONS
- && "RuntimeVisibleTypeAnnotations".equals(attrName)) {
+ } else if ("RuntimeVisibleTypeAnnotations".equals(attrName)) {
tanns = readTypeAnnotations(mv, context, u + 8, true);
ntoff = tanns.length == 0 || readByte(tanns[0]) < 0x43 ? -1
: readUnsignedShort(tanns[0] + 1);
- } else if (ANNOTATIONS
- && "RuntimeInvisibleTypeAnnotations".equals(attrName)) {
+ } else if ("RuntimeInvisibleTypeAnnotations".equals(attrName)) {
itanns = readTypeAnnotations(mv, context, u + 8, false);
nitoff = itanns.length == 0 || readByte(itanns[0]) < 0x43 ? -1
: readUnsignedShort(itanns[0] + 1);
- } else if (FRAMES && "StackMapTable".equals(attrName)) {
+ } else if ("StackMapTable".equals(attrName)) {
if ((context.flags & SKIP_FRAMES) == 0) {
stackMap = u + 10;
stackMapSize = readInt(u + 4);
@@ -1215,7 +1321,7 @@ public class ClassReader {
* this by parsing the stack map table without a full decoding
* (see below).
*/
- } else if (FRAMES && "StackMap".equals(attrName)) {
+ } else if ("StackMap".equals(attrName)) {
if ((context.flags & SKIP_FRAMES) == 0) {
zip = false;
stackMap = u + 10;
@@ -1244,7 +1350,7 @@ public class ClassReader {
u += 2;
// generates the first (implicit) stack map frame
- if (FRAMES && stackMap != 0) {
+ if (stackMap != 0) {
/*
* for the first explicit frame the offset is not offset_delta + 1
* but only offset_delta; setting the implicit frame offset to -1
@@ -1277,14 +1383,31 @@ public class ClassReader {
int v = readUnsignedShort(i + 1);
if (v >= 0 && v < codeLength) {
if ((b[codeStart + v] & 0xFF) == Opcodes.NEW) {
- readLabel(v, labels);
+ createLabel(v, labels);
}
}
}
}
}
+ if ((context.flags & EXPAND_ASM_INSNS) != 0
+ && (context.flags & EXPAND_FRAMES) != 0) {
+ // Expanding the ASM pseudo instructions can introduce F_INSERT
+ // frames, even if the method does not currently have any frame.
+ // Also these inserted frames must be computed by simulating the
+ // effect of the bytecode instructions one by one, starting from the
+ // first one and the last existing frame (or the implicit first
+ // one). Finally, due to the way MethodWriter computes this (with
+ // the compute = INSERTED_FRAMES option), MethodWriter needs to know
+ // maxLocals before the first instruction is visited. For all these
+ // reasons we always visit the implicit first frame in this case
+ // (passing only maxLocals - the rest can be and is computed in
+ // MethodWriter).
+ mv.visitFrame(Opcodes.F_NEW, maxLocals, null, 0, null);
+ }
// visits the instructions
+ int opcodeDelta = (context.flags & EXPAND_ASM_INSNS) == 0 ? -33 : 0;
+ boolean insertFrame = false;
u = codeStart;
while (u < codeEnd) {
int offset = u - codeStart;
@@ -1305,7 +1428,7 @@ public class ClassReader {
}
// visits the frame for this offset, if any
- while (FRAMES && frame != null
+ while (frame != null
&& (frame.offset == offset || frame.offset == -1)) {
// if there is a frame for this offset, makes the visitor visit
// it, and reads the next frame if there is one.
@@ -1317,6 +1440,9 @@ public class ClassReader {
mv.visitFrame(frame.mode, frame.localDiff, frame.local,
frame.stackCount, frame.stack);
}
+ // if there is already a frame for this offset, there is no
+ // need to insert a new one.
+ insertFrame = false;
}
if (frameCount > 0) {
stackMap = readFrame(stackMap, zip, unzip, frame);
@@ -1325,6 +1451,13 @@ public class ClassReader {
frame = null;
}
}
+ // inserts a frame for this offset, if requested by setting
+ // insertFrame to true during the previous iteration. The actual
+ // frame content will be computed in MethodWriter.
+ if (insertFrame) {
+ mv.visitFrame(ClassWriter.F_INSERT, 0, null, 0, null);
+ insertFrame = false;
+ }
// visits the instruction at this offset
int opcode = b[u] & 0xFF;
@@ -1349,9 +1482,47 @@ public class ClassReader {
u += 3;
break;
case ClassWriter.LABELW_INSN:
- mv.visitJumpInsn(opcode - 33, labels[offset + readInt(u + 1)]);
+ mv.visitJumpInsn(opcode + opcodeDelta, labels[offset
+ + readInt(u + 1)]);
u += 5;
break;
+ case ClassWriter.ASM_LABEL_INSN: {
+ // changes temporary opcodes 202 to 217 (inclusive), 218
+ // and 219 to IFEQ ... JSR (inclusive), IFNULL and
+ // IFNONNULL
+ opcode = opcode < 218 ? opcode - 49 : opcode - 20;
+ Label target = labels[offset + readUnsignedShort(u + 1)];
+ // replaces GOTO with GOTO_W, JSR with JSR_W and IFxxx
+ // <l> with IFNOTxxx <L> GOTO_W <l> L:..., where IFNOTxxx is
+ // the "opposite" opcode of IFxxx (i.e., IFNE for IFEQ)
+ // and where <L> designates the instruction just after
+ // the GOTO_W.
+ if (opcode == Opcodes.GOTO || opcode == Opcodes.JSR) {
+ mv.visitJumpInsn(opcode + 33, target);
+ } else {
+ opcode = opcode <= 166 ? ((opcode + 1) ^ 1) - 1
+ : opcode ^ 1;
+ Label endif = createLabel(offset + 3, labels);
+ mv.visitJumpInsn(opcode, endif);
+ mv.visitJumpInsn(200, target); // GOTO_W
+ // endif designates the instruction just after GOTO_W,
+ // and is visited as part of the next instruction. Since
+ // it is a jump target, we need to insert a frame here.
+ insertFrame = true;
+ }
+ u += 3;
+ break;
+ }
+ case ClassWriter.ASM_LABELW_INSN: {
+ // replaces the pseudo GOTO_W instruction with a real one.
+ mv.visitJumpInsn(200, labels[offset + readInt(u + 1)]);
+ // The instruction just after is a jump target (because pseudo
+ // GOTO_W are used in patterns IFNOTxxx <L> GOTO_W <l> L:...,
+ // see MethodWriter), so we need to insert a frame here.
+ insertFrame = true;
+ u += 5;
+ break;
+ }
case ClassWriter.WIDE_INSN:
opcode = b[u + 1] & 0xFF;
if (opcode == Opcodes.IINC) {
@@ -1607,8 +1778,8 @@ public class ClassReader {
for (int j = readUnsignedShort(u + 1); j > 0; --j) {
int start = readUnsignedShort(u + 3);
int length = readUnsignedShort(u + 5);
- readLabel(start, context.labels);
- readLabel(start + length, context.labels);
+ createLabel(start, context.labels);
+ createLabel(start + length, context.labels);
u += 6;
}
u += 3;
@@ -1687,8 +1858,8 @@ public class ClassReader {
for (int i = 0; i < n; ++i) {
int start = readUnsignedShort(u);
int length = readUnsignedShort(u + 2);
- context.start[i] = readLabel(start, context.labels);
- context.end[i] = readLabel(start + length, context.labels);
+ context.start[i] = createLabel(start, context.labels);
+ context.end[i] = createLabel(start + length, context.labels);
context.index[i] = readUnsignedShort(u + 4);
u += 6;
}
@@ -2108,7 +2279,7 @@ public class ClassReader {
}
}
frame.offset += delta + 1;
- readLabel(frame.offset, labels);
+ createLabel(frame.offset, labels);
return stackMap;
}
@@ -2161,7 +2332,7 @@ public class ClassReader {
v += 2;
break;
default: // Uninitialized
- frame[index] = readLabel(readUnsignedShort(v), labels);
+ frame[index] = createLabel(readUnsignedShort(v), labels);
v += 2;
}
return v;
@@ -2188,6 +2359,39 @@ public class ClassReader {
}
/**
+ * Creates a label without the Label.DEBUG flag set, for the given offset.
+ * The label is created with a call to {@link #readLabel} and its
+ * Label.DEBUG flag is cleared.
+ *
+ * @param offset
+ * a bytecode offset in a method.
+ * @param labels
+ * the already created labels, indexed by their offset.
+ * @return a Label without the Label.DEBUG flag set.
+ */
+ private Label createLabel(int offset, Label[] labels) {
+ Label label = readLabel(offset, labels);
+ label.status &= ~Label.DEBUG;
+ return label;
+ }
+
+ /**
+ * Creates a label with the Label.DEBUG flag set, if there is no already
+ * existing label for the given offset (otherwise does nothing). The label
+ * is created with a call to {@link #readLabel}.
+ *
+ * @param offset
+ * a bytecode offset in a method.
+ * @param labels
+ * the already created labels, indexed by their offset.
+ */
+ private void createDebugLabel(int offset, Label[] labels) {
+ if (labels[offset] == null) {
+ readLabel(offset, labels).status |= Label.DEBUG;
+ }
+ }
+
+ /**
* Returns the start index of the attribute_info structure of this class.
*
* @return the start index of the attribute_info structure of this class.
@@ -2442,6 +2646,20 @@ public class ClassReader {
}
/**
+ * Read a stringish constant item (CONSTANT_Class, CONSTANT_String,
+ * CONSTANT_MethodType, CONSTANT_Module or CONSTANT_Package
+ * @param index
+ * @param buf
+ * @return
+ */
+ private String readStringish(final int index, final char[] buf) {
+ // computes the start index of the item in b
+ // and reads the CONSTANT_Utf8 item designated by
+ // the first two bytes of this item
+ return readUTF8(items[readUnsignedShort(index)], buf);
+ }
+
+ /**
* Reads a class constant pool item in {@link #b b}. <i>This method is
* intended for {@link Attribute} sub classes, and is normally not needed by
* class generators or adapters.</i>
@@ -2455,10 +2673,41 @@ public class ClassReader {
* @return the String corresponding to the specified class item.
*/
public String readClass(final int index, final char[] buf) {
- // computes the start index of the CONSTANT_Class item in b
- // and reads the CONSTANT_Utf8 item designated by
- // the first two bytes of this CONSTANT_Class item
- return readUTF8(items[readUnsignedShort(index)], buf);
+ return readStringish(index, buf);
+ }
+
+ /**
+ * Reads a module constant pool item in {@link #b b}. <i>This method is
+ * intended for {@link Attribute} sub classes, and is normally not needed by
+ * class generators or adapters.</i>
+ *
+ * @param index
+ * the start index of an unsigned short value in {@link #b b},
+ * whose value is the index of a module constant pool item.
+ * @param buf
+ * buffer to be used to read the item. This buffer must be
+ * sufficiently large. It is not automatically resized.
+ * @return the String corresponding to the specified module item.
+ */
+ public String readModule(final int index, final char[] buf) {
+ return readStringish(index, buf);
+ }
+
+ /**
+ * Reads a module constant pool item in {@link #b b}. <i>This method is
+ * intended for {@link Attribute} sub classes, and is normally not needed by
+ * class generators or adapters.</i>
+ *
+ * @param index
+ * the start index of an unsigned short value in {@link #b b},
+ * whose value is the index of a module constant pool item.
+ * @param buf
+ * buffer to be used to read the item. This buffer must be
+ * sufficiently large. It is not automatically resized.
+ * @return the String corresponding to the specified module item.
+ */
+ public String readPackage(final int index, final char[] buf) {
+ return readStringish(index, buf);
}
/**
@@ -2496,11 +2745,12 @@ public class ClassReader {
int tag = readByte(index);
int[] items = this.items;
int cpIndex = items[readUnsignedShort(index + 1)];
+ boolean itf = b[cpIndex - 1] == ClassWriter.IMETH;
String owner = readClass(cpIndex, buf);
cpIndex = items[readUnsignedShort(cpIndex + 2)];
String name = readUTF8(cpIndex, buf);
String desc = readUTF8(cpIndex + 2, buf);
- return new Handle(tag, owner, name, desc);
+ return new Handle(tag, owner, name, desc, itf);
}
}
}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/74324b31/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/ClassVisitor.java
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/ClassVisitor.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/ClassVisitor.java
index 8c8e29b..b5751d4 100644
--- a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/ClassVisitor.java
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/ClassVisitor.java
@@ -32,7 +32,7 @@ package org.apache.tapestry5.internal.plastic.asm;
/**
* A visitor to visit a Java class. The methods of this class must be called in
* the following order: <tt>visit</tt> [ <tt>visitSource</tt> ] [
- * <tt>visitOuterClass</tt> ] ( <tt>visitAnnotation</tt> |
+ * <tt>visitModule</tt> ][ <tt>visitOuterClass</tt> ] ( <tt>visitAnnotation</tt> |
* <tt>visitTypeAnnotation</tt> | <tt>visitAttribute</tt> )* (
* <tt>visitInnerClass</tt> | <tt>visitField</tt> | <tt>visitMethod</tt> )*
* <tt>visitEnd</tt>.
@@ -43,7 +43,7 @@ public abstract class ClassVisitor {
/**
* The ASM API version implemented by this visitor. The value of this field
- * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
*/
protected final int api;
@@ -58,7 +58,7 @@ public abstract class ClassVisitor {
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
*/
public ClassVisitor(final int api) {
this(api, null);
@@ -69,13 +69,13 @@ public abstract class ClassVisitor {
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* @param cv
* the class visitor to which this visitor must delegate method
* calls. May be null.
*/
public ClassVisitor(final int api, final ClassVisitor cv) {
- if (api != Opcodes.ASM4 && api != Opcodes.ASM5) {
+ if (api < Opcodes.ASM4 || api > Opcodes.ASM6) {
throw new IllegalArgumentException();
}
this.api = api;
@@ -130,6 +130,28 @@ public abstract class ClassVisitor {
cv.visitSource(source, debug);
}
}
+
+ /**
+ * Visit the module corresponding to the class.
+ * @param name
+ * module name
+ * @param access
+ * module flags, among {@code ACC_OPEN}, {@code ACC_SYNTHETIC}
+ * and {@code ACC_MANDATED}.
+ * @param version
+ * module version or null.
+ * @return a visitor to visit the module values, or <tt>null</tt> if
+ * this visitor is not interested in visiting this module.
+ */
+ public ModuleVisitor visitModule(String name, int access, String version) {
+ if (api < Opcodes.ASM6) {
+ throw new RuntimeException();
+ }
+ if (cv != null) {
+ return cv.visitModule(name, access, version);
+ }
+ return null;
+ }
/**
* Visits the enclosing class of the class. This method must be called only
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/74324b31/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/ClassWriter.java
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/ClassWriter.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/ClassWriter.java
index da87f36..fa40875 100644
--- a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/ClassWriter.java
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/ClassWriter.java
@@ -58,8 +58,8 @@ public class ClassWriter extends ClassVisitor {
* {@link MethodVisitor#visitFrame} method are ignored, and the stack map
* frames are recomputed from the methods bytecode. The arguments of the
* {@link MethodVisitor#visitMaxs visitMaxs} method are also ignored and
- * recomputed from the bytecode. In other words, computeFrames implies
- * computeMaxs.
+ * recomputed from the bytecode. In other words, COMPUTE_FRAMES implies
+ * COMPUTE_MAXS.
*
* @see #ClassWriter(int)
*/
@@ -168,6 +168,27 @@ public class ClassWriter extends ClassVisitor {
static final int WIDE_INSN = 17;
/**
+ * The type of the ASM pseudo instructions with an unsigned 2 bytes offset
+ * label (see Label#resolve).
+ */
+ static final int ASM_LABEL_INSN = 18;
+
+ /**
+ * The type of the ASM pseudo instructions with a 4 bytes offset label.
+ */
+ static final int ASM_LABELW_INSN = 19;
+
+ /**
+ * Represents a frame inserted between already existing frames. This kind of
+ * frame can only be used if the frame content can be computed from the
+ * previous existing frame and from the instructions between this existing
+ * frame and the inserted one, without any knowledge of the type hierarchy.
+ * This kind of frame is only used when an unconditional jump is inserted in
+ * a method while expanding an ASM pseudo instruction (see ClassReader).
+ */
+ static final int F_INSERT = 256;
+
+ /**
* The instruction types of all JVM opcodes.
*/
static final byte[] TYPE;
@@ -243,9 +264,19 @@ public class ClassWriter extends ClassVisitor {
static final int INDY = 18;
/**
+ * The type of CONSTANT_Module constant pool items.
+ */
+ static final int MODULE = 19;
+
+ /**
+ * The type of CONSTANT_Package constant pool items.
+ */
+ static final int PACKAGE = 20;
+
+ /**
* The base value for all CONSTANT_MethodHandle constant pool items.
* Internally, ASM store the 9 variations of CONSTANT_MethodHandle into 9
- * different items.
+ * different items (from 21 to 29).
*/
static final int HANDLE_BASE = 20;
@@ -395,6 +426,11 @@ public class ClassWriter extends ClassVisitor {
private ByteVector sourceDebug;
/**
+ * The module attribute of this class.
+ */
+ private ModuleWriter moduleWriter;
+
+ /**
* The constant pool item that contains the name of the enclosing class of
* this class.
*/
@@ -484,25 +520,19 @@ public class ClassWriter extends ClassVisitor {
MethodWriter lastMethod;
/**
- * <tt>true</tt> if the maximum stack size and number of local variables
- * must be automatically computed.
- */
- private boolean computeMaxs;
-
- /**
- * <tt>true</tt> if the stack map frames must be recomputed from scratch.
+ * Indicates what must be automatically computed.
+ *
+ * @see MethodWriter#compute
*/
- private boolean computeFrames;
+ private int compute;
/**
- * <tt>true</tt> if the stack map tables of this class are invalid. The
- * {@link MethodWriter#resizeInstructions} method cannot transform existing
- * stack map tables, and so produces potentially invalid classes when it is
- * executed. In this case the class is reread and rewritten with the
- * {@link #COMPUTE_FRAMES} option (the resizeInstructions method can resize
- * stack map tables when this option is used).
+ * <tt>true</tt> if some methods have wide forward jumps using ASM pseudo
+ * instructions, which need to be expanded into sequences of standard
+ * bytecode instructions. In this case the class is re-read and re-written
+ * with a ClassReader -> ClassWriter chain to perform this transformation.
*/
- boolean invalidFrames;
+ boolean hasAsmInsns;
// ------------------------------------------------------------------------
// Static initializer
@@ -513,11 +543,11 @@ public class ClassWriter extends ClassVisitor {
*/
static {
int i;
- byte[] b = new byte[220];
+ byte[] b = new byte[221];
String s = "AAAAAAAAAAAAAAAABCLMMDDDDDEEEEEEEEEEEEEEEEEEEEAAAAAAAADD"
+ "DDDEEEEEEEEEEEEEEEEEEEEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+ "AAAAAAAAAAAAAAAAANAAAAAAAAAAAAAAAAAAAAJJJJJJJJJJJJJJJJDOPAA"
- + "AAAAGGGGGGGHIFBFAAFFAARQJJKKJJJJJJJJJJJJJJJJJJ";
+ + "AAAAGGGGGGGHIFBFAAFFAARQJJKKSSSSSSSSSSSSSSSSSST";
for (i = 0; i < b.length; ++i) {
b[i] = (byte) (s.charAt(i) - 'A');
}
@@ -571,8 +601,9 @@ public class ClassWriter extends ClassVisitor {
// // temporary opcodes used internally by ASM - see Label and
// MethodWriter
// for (i = 202; i < 220; ++i) {
- // b[i] = LABEL_INSN;
+ // b[i] = ASM_LABEL_INSN;
// }
+ // b[220] = ASM_LABELW_INSN;
//
// // LDC(_W) instructions
// b[Constants.LDC] = LDC_INSN;
@@ -605,7 +636,7 @@ public class ClassWriter extends ClassVisitor {
* {@link #COMPUTE_FRAMES}.
*/
public ClassWriter(final int flags) {
- super(Opcodes.ASM5);
+ super(Opcodes.ASM6);
index = 1;
pool = new ByteVector();
items = new Item[256];
@@ -614,8 +645,9 @@ public class ClassWriter extends ClassVisitor {
key2 = new Item();
key3 = new Item();
key4 = new Item();
- this.computeMaxs = (flags & COMPUTE_MAXS) != 0;
- this.computeFrames = (flags & COMPUTE_FRAMES) != 0;
+ this.compute = (flags & COMPUTE_FRAMES) != 0 ? MethodWriter.FRAMES
+ : ((flags & COMPUTE_MAXS) != 0 ? MethodWriter.MAXS
+ : MethodWriter.NOTHING);
}
/**
@@ -645,9 +677,9 @@ public class ClassWriter extends ClassVisitor {
* @param flags
* option flags that can be used to modify the default behavior
* of this class. <i>These option flags do not affect methods
- * that are copied as is in the new class. This means that the
- * maximum stack size nor the stack frames will be computed for
- * these methods</i>. See {@link #COMPUTE_MAXS},
+ * that are copied as is in the new class. This means that
+ * neither the maximum stack size nor the stack frames will be
+ * computed for these methods</i>. See {@link #COMPUTE_MAXS},
* {@link #COMPUTE_FRAMES}.
*/
public ClassWriter(final ClassReader classReader, final int flags) {
@@ -668,7 +700,7 @@ public class ClassWriter extends ClassVisitor {
this.access = access;
this.name = newClass(name);
thisName = name;
- if (ClassReader.SIGNATURES && signature != null) {
+ if (signature != null) {
this.signature = newUTF8(signature);
}
this.superName = superName == null ? 0 : newClass(superName);
@@ -693,6 +725,14 @@ public class ClassWriter extends ClassVisitor {
}
@Override
+ public final ModuleVisitor visitModule(final String name,
+ final int access, final String version) {
+ return moduleWriter = new ModuleWriter(this,
+ newModule(name), access,
+ version == null ? 0 : newUTF8(version));
+ }
+
+ @Override
public final void visitOuterClass(final String owner, final String name,
final String desc) {
enclosingMethodOwner = newClass(owner);
@@ -704,9 +744,6 @@ public class ClassWriter extends ClassVisitor {
@Override
public final AnnotationVisitor visitAnnotation(final String desc,
final boolean visible) {
- if (!ClassReader.ANNOTATIONS) {
- return null;
- }
ByteVector bv = new ByteVector();
// write type, and reserve space for values count
bv.putShort(newUTF8(desc)).putShort(0);
@@ -724,9 +761,6 @@ public class ClassWriter extends ClassVisitor {
@Override
public final AnnotationVisitor visitTypeAnnotation(int typeRef,
TypePath typePath, final String desc, final boolean visible) {
- if (!ClassReader.ANNOTATIONS) {
- return null;
- }
ByteVector bv = new ByteVector();
// write target_type and target_info
AnnotationWriter.putTarget(typeRef, typePath, bv);
@@ -766,7 +800,7 @@ public class ClassWriter extends ClassVisitor {
// and equality tests). If so we store the index of this inner class
// entry (plus one) in intVal. This hack allows duplicate detection in
// O(1) time.
- Item nameItem = newClassItem(name);
+ Item nameItem = newStringishItem(CLASS, name);
if (nameItem.intVal == 0) {
++innerClassesCount;
innerClasses.putShort(nameItem.index);
@@ -791,7 +825,7 @@ public class ClassWriter extends ClassVisitor {
public final MethodVisitor visitMethod(final int access, final String name,
final String desc, final String signature, final String[] exceptions) {
return new MethodWriter(this, access, name, desc, signature,
- exceptions, computeMaxs, computeFrames);
+ exceptions, compute);
}
@Override
@@ -835,7 +869,7 @@ public class ClassWriter extends ClassVisitor {
size += 8 + bootstrapMethods.length;
newUTF8("BootstrapMethods");
}
- if (ClassReader.SIGNATURES && signature != 0) {
+ if (signature != 0) {
++attributeCount;
size += 8;
newUTF8("Signature");
@@ -873,26 +907,31 @@ public class ClassWriter extends ClassVisitor {
size += 8 + innerClasses.length;
newUTF8("InnerClasses");
}
- if (ClassReader.ANNOTATIONS && anns != null) {
+ if (anns != null) {
++attributeCount;
size += 8 + anns.getSize();
newUTF8("RuntimeVisibleAnnotations");
}
- if (ClassReader.ANNOTATIONS && ianns != null) {
+ if (ianns != null) {
++attributeCount;
size += 8 + ianns.getSize();
newUTF8("RuntimeInvisibleAnnotations");
}
- if (ClassReader.ANNOTATIONS && tanns != null) {
+ if (tanns != null) {
++attributeCount;
size += 8 + tanns.getSize();
newUTF8("RuntimeVisibleTypeAnnotations");
}
- if (ClassReader.ANNOTATIONS && itanns != null) {
+ if (itanns != null) {
++attributeCount;
size += 8 + itanns.getSize();
newUTF8("RuntimeInvisibleTypeAnnotations");
}
+ if (moduleWriter != null) {
+ attributeCount += 1 + moduleWriter.attributeCount;
+ size += 6 + moduleWriter.size + moduleWriter.attributesSize;
+ newUTF8("Module");
+ }
if (attrs != null) {
attributeCount += attrs.getCount();
size += attrs.getSize(this, null, 0, -1, -1);
@@ -929,7 +968,7 @@ public class ClassWriter extends ClassVisitor {
bootstrapMethodsCount);
out.putByteArray(bootstrapMethods.data, 0, bootstrapMethods.length);
}
- if (ClassReader.SIGNATURES && signature != 0) {
+ if (signature != 0) {
out.putShort(newUTF8("Signature")).putInt(2).putShort(signature);
}
if (sourceFile != 0) {
@@ -940,6 +979,11 @@ public class ClassWriter extends ClassVisitor {
out.putShort(newUTF8("SourceDebugExtension")).putInt(len);
out.putByteArray(sourceDebug.data, 0, len);
}
+ if (moduleWriter != null) {
+ out.putShort(newUTF8("Module"));
+ moduleWriter.put(out);
+ moduleWriter.putAttributes(out);
+ }
if (enclosingMethodOwner != 0) {
out.putShort(newUTF8("EnclosingMethod")).putInt(4);
out.putShort(enclosingMethodOwner).putShort(enclosingMethod);
@@ -958,41 +1002,46 @@ public class ClassWriter extends ClassVisitor {
out.putInt(innerClasses.length + 2).putShort(innerClassesCount);
out.putByteArray(innerClasses.data, 0, innerClasses.length);
}
- if (ClassReader.ANNOTATIONS && anns != null) {
+ if (anns != null) {
out.putShort(newUTF8("RuntimeVisibleAnnotations"));
anns.put(out);
}
- if (ClassReader.ANNOTATIONS && ianns != null) {
+ if (ianns != null) {
out.putShort(newUTF8("RuntimeInvisibleAnnotations"));
ianns.put(out);
}
- if (ClassReader.ANNOTATIONS && tanns != null) {
+ if (tanns != null) {
out.putShort(newUTF8("RuntimeVisibleTypeAnnotations"));
tanns.put(out);
}
- if (ClassReader.ANNOTATIONS && itanns != null) {
+ if (itanns != null) {
out.putShort(newUTF8("RuntimeInvisibleTypeAnnotations"));
itanns.put(out);
}
if (attrs != null) {
attrs.put(this, null, 0, -1, -1, out);
}
- if (invalidFrames) {
+ if (hasAsmInsns) {
+ boolean hasFrames = false;
+ mb = firstMethod;
+ while (mb != null) {
+ hasFrames |= mb.frameCount > 0;
+ mb = (MethodWriter) mb.mv;
+ }
anns = null;
ianns = null;
attrs = null;
- innerClassesCount = 0;
- innerClasses = null;
- bootstrapMethodsCount = 0;
- bootstrapMethods = null;
+ moduleWriter = null;
firstField = null;
lastField = null;
firstMethod = null;
lastMethod = null;
- computeMaxs = false;
- computeFrames = true;
- invalidFrames = false;
- new ClassReader(out.data).accept(this, ClassReader.SKIP_FRAMES);
+ compute =
+ hasFrames ? MethodWriter.INSERTED_FRAMES : MethodWriter.NOTHING;
+ hasAsmInsns = false;
+ new ClassReader(out.data).accept(this,
+ (hasFrames ? ClassReader.EXPAND_FRAMES : 0)
+ | ClassReader.EXPAND_ASM_INSNS);
return toByteArray();
}
return out.data;
@@ -1039,20 +1088,20 @@ public class ClassWriter extends ClassVisitor {
double val = ((Double) cst).doubleValue();
return newDouble(val);
} else if (cst instanceof String) {
- return newString((String) cst);
+ return newStringishItem(STR, (String) cst);
} else if (cst instanceof Type) {
Type t = (Type) cst;
int s = t.getSort();
if (s == Type.OBJECT) {
- return newClassItem(t.getInternalName());
+ return newStringishItem(CLASS, t.getInternalName());
} else if (s == Type.METHOD) {
- return newMethodTypeItem(t.getDescriptor());
+ return newStringishItem(MTYPE, t.getDescriptor());
} else { // s == primitive type or array
- return newClassItem(t.getDescriptor());
+ return newStringishItem(CLASS, t.getDescriptor());
}
} else if (cst instanceof Handle) {
Handle h = (Handle) cst;
- return newHandleItem(h.tag, h.owner, h.name, h.desc);
+ return newHandleItem(h.tag, h.owner, h.name, h.desc, h.itf);
} else {
throw new IllegalArgumentException("value " + cst);
}
@@ -1097,20 +1146,21 @@ public class ClassWriter extends ClassVisitor {
}
/**
- * Adds a class reference to the constant pool of the class being build.
+ * Adds a string reference, a class reference, a method type, a module
+ * or a package to the constant pool of the class being build.
* Does nothing if the constant pool already contains a similar item.
- * <i>This method is intended for {@link Attribute} sub classes, and is
- * normally not needed by class generators or adapters.</i>
*
+ * @param type
+ * a type among STR, CLASS, MTYPE, MODULE or PACKAGE
* @param value
- * the internal name of the class.
- * @return a new or already existing class reference item.
+ * string value of the reference.
+ * @return a new or already existing reference item.
*/
- Item newClassItem(final String value) {
- key2.set(CLASS, value, null, null);
+ Item newStringishItem(final int type, final String value) {
+ key2.set(type, value, null, null);
Item result = get(key2);
if (result == null) {
- pool.put12(CLASS, newUTF8(value));
+ pool.put12(type, newUTF8(value));
result = new Item(index++, key2);
put(result);
}
@@ -1128,7 +1178,7 @@ public class ClassWriter extends ClassVisitor {
* @return the index of a new or already existing class reference item.
*/
public int newClass(final String value) {
- return newClassItem(value).index;
+ return newStringishItem(CLASS, value).index;
}
/**
@@ -1139,32 +1189,41 @@ public class ClassWriter extends ClassVisitor {
*
* @param methodDesc
* method descriptor of the method type.
- * @return a new or already existing method type reference item.
+ * @return the index of a new or already existing method type reference
+ * item.
*/
- Item newMethodTypeItem(final String methodDesc) {
- key2.set(MTYPE, methodDesc, null, null);
- Item result = get(key2);
- if (result == null) {
- pool.put12(MTYPE, newUTF8(methodDesc));
- result = new Item(index++, key2);
- put(result);
- }
- return result;
+ public int newMethodType(final String methodDesc) {
+ return newStringishItem(MTYPE, methodDesc).index;
}
-
+
/**
- * Adds a method type reference to the constant pool of the class being
+ * Adds a module reference to the constant pool of the class being
* build. Does nothing if the constant pool already contains a similar item.
* <i>This method is intended for {@link Attribute} sub classes, and is
* normally not needed by class generators or adapters.</i>
*
- * @param methodDesc
- * method descriptor of the method type.
- * @return the index of a new or already existing method type reference
+ * @param moduleName
+ * name of the module.
+ * @return the index of a new or already existing module reference
* item.
*/
- public int newMethodType(final String methodDesc) {
- return newMethodTypeItem(methodDesc).index;
+ public int newModule(final String moduleName) {
+ return newStringishItem(MODULE, moduleName).index;
+ }
+
+ /**
+ * Adds a package reference to the constant pool of the class being
+ * build. Does nothing if the constant pool already contains a similar item.
+ * <i>This method is intended for {@link Attribute} sub classes, and is
+ * normally not needed by class generators or adapters.</i>
+ *
+ * @param packageName
+ * name of the package in its internal form.
+ * @return the index of a new or already existing module reference
+ * item.
+ */
+ public int newPackage(final String packageName) {
+ return newStringishItem(PACKAGE, packageName).index;
}
/**
@@ -1187,10 +1246,12 @@ public class ClassWriter extends ClassVisitor {
* the name of the field or method.
* @param desc
* the descriptor of the field or method.
+ * @param itf
+ * true if the owner is an interface.
* @return a new or an already existing method type reference item.
*/
Item newHandleItem(final int tag, final String owner, final String name,
- final String desc) {
+ final String desc, final boolean itf) {
key4.set(HANDLE_BASE + tag, owner, name, desc);
Item result = get(key4);
if (result == null) {
@@ -1199,8 +1260,7 @@ public class ClassWriter extends ClassVisitor {
} else {
put112(HANDLE,
tag,
- newMethod(owner, name, desc,
- tag == Opcodes.H_INVOKEINTERFACE));
+ newMethod(owner, name, desc, itf));
}
result = new Item(index++, key4);
put(result);
@@ -1230,13 +1290,47 @@ public class ClassWriter extends ClassVisitor {
* the descriptor of the field or method.
* @return the index of a new or already existing method type reference
* item.
+ *
+ * @deprecated this method is superseded by
+ * {@link #newHandle(int, String, String, String, boolean)}.
*/
+ @Deprecated
public int newHandle(final int tag, final String owner, final String name,
final String desc) {
- return newHandleItem(tag, owner, name, desc).index;
+ return newHandle(tag, owner, name, desc, tag == Opcodes.H_INVOKEINTERFACE);
}
/**
+ * Adds a handle to the constant pool of the class being build. Does nothing
+ * if the constant pool already contains a similar item. <i>This method is
+ * intended for {@link Attribute} sub classes, and is normally not needed by
+ * class generators or adapters.</i>
+ *
+ * @param tag
+ * the kind of this handle. Must be {@link Opcodes#H_GETFIELD},
+ * {@link Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD},
+ * {@link Opcodes#H_PUTSTATIC}, {@link Opcodes#H_INVOKEVIRTUAL},
+ * {@link Opcodes#H_INVOKESTATIC},
+ * {@link Opcodes#H_INVOKESPECIAL},
+ * {@link Opcodes#H_NEWINVOKESPECIAL} or
+ * {@link Opcodes#H_INVOKEINTERFACE}.
+ * @param owner
+ * the internal name of the field or method owner class.
+ * @param name
+ * the name of the field or method.
+ * @param desc
+ * the descriptor of the field or method.
+ * @param itf
+ * true if the owner is an interface.
+ * @return the index of a new or already existing method type reference
+ * item.
+ */
+ public int newHandle(final int tag, final String owner, final String name,
+ final String desc, final boolean itf) {
+ return newHandleItem(tag, owner, name, desc, itf).index;
+ }
+
+ /**
* Adds an invokedynamic reference to the constant pool of the class being
* build. Does nothing if the constant pool already contains a similar item.
* <i>This method is intended for {@link Attribute} sub classes, and is
@@ -1265,7 +1359,7 @@ public class ClassWriter extends ClassVisitor {
int hashCode = bsm.hashCode();
bootstrapMethods.putShort(newHandle(bsm.tag, bsm.owner, bsm.name,
- bsm.desc));
+ bsm.desc, bsm.isInterface()));
int argsLength = bsmArgs.length;
bootstrapMethods.putShort(argsLength);
@@ -1511,25 +1605,6 @@ public class ClassWriter extends ClassVisitor {
}
/**
- * Adds a string to the constant pool of the class being build. Does nothing
- * if the constant pool already contains a similar item.
- *
- * @param value
- * the String value.
- * @return a new or already existing string item.
- */
- private Item newString(final String value) {
- key2.set(STR, value, null, null);
- Item result = get(key2);
- if (result == null) {
- pool.put12(STR, newUTF8(value));
- result = new Item(index++, key2);
- put(result);
- }
- return result;
- }
-
- /**
* Adds a name and type to the constant pool of the class being build. Does
* nothing if the constant pool already contains a similar item. <i>This
* method is intended for {@link Attribute} sub classes, and is normally not
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/74324b31/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/CurrentFrame.java
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/CurrentFrame.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/CurrentFrame.java
new file mode 100644
index 0000000..457a4eb
--- /dev/null
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/CurrentFrame.java
@@ -0,0 +1,56 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.apache.tapestry5.internal.plastic.asm;
+
+/**
+ * Information about the input stack map frame at the "current" instruction of a
+ * method. This is implemented as a Frame subclass for a "basic block"
+ * containing only one instruction.
+ *
+ * @author Eric Bruneton
+ */
+class CurrentFrame extends Frame {
+
+ /**
+ * Sets this CurrentFrame to the input stack map frame of the next "current"
+ * instruction, i.e. the instruction just after the given one. It is assumed
+ * that the value of this object when this method is called is the stack map
+ * frame status just before the given instruction is executed.
+ */
+ @Override
+ void execute(int opcode, int arg, ClassWriter cw, Item item) {
+ super.execute(opcode, arg, cw, item);
+ Frame successor = new Frame();
+ merge(cw, successor, 0);
+ set(successor);
+ owner.inputStackTop = 0;
+ }
+}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/74324b31/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/FieldVisitor.java
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/FieldVisitor.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/FieldVisitor.java
index 107af8f..9dbca0b 100644
--- a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/FieldVisitor.java
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/FieldVisitor.java
@@ -40,7 +40,7 @@ public abstract class FieldVisitor {
/**
* The ASM API version implemented by this visitor. The value of this field
- * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
*/
protected final int api;
@@ -55,7 +55,7 @@ public abstract class FieldVisitor {
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
*/
public FieldVisitor(final int api) {
this(api, null);
@@ -66,13 +66,13 @@ public abstract class FieldVisitor {
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* @param fv
* the field visitor to which this visitor must delegate method
* calls. May be null.
*/
public FieldVisitor(final int api, final FieldVisitor fv) {
- if (api != Opcodes.ASM4 && api != Opcodes.ASM5) {
+ if (api < Opcodes.ASM4 || api > Opcodes.ASM6) {
throw new IllegalArgumentException();
}
this.api = api;